⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zd1205.c

📁 GW-US54GXS_Linux_v2.15.0.0_CE zd1211原碼
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif

        ZD1211DEBUG(4, "zd1211: rx_struct->dma_addr = %x\n", (u32)rx_struct->dma_addr);

#ifndef HOST_IF_USB            
		if (!rx_struct->dma_addr)
			goto err;
#endif            


       	skb_reserve(new_skb, macp->rfd_size); //now skb->data point to RxBuffer

#ifdef HOST_IF_USB      
     	rx_struct->dma_addr = (u32)new_skb->data;
        rx_struct->UnFinishFrmLen = 0;
#endif
       
        ZEXIT(4);
		return rx_struct;
	} else {
        macp->AllocSkbFailCnt++;
        printk(KERN_DEBUG "zd1205: dev_alloc_skb fail\n");
		return NULL;
	}

err:
    printk(KERN_DEBUG "zd1205: ****** err\n");                
    dev_kfree_skb_irq(new_skb);

	return NULL;
}


/**
 * zd1205_add_skb_to_end - add an skb to the end of our rfd list

 * @macp: atapter's private data struct
 * @rx_struct: rx_list_elem with the new skb
 *
 * Adds a newly allocated skb to the end of our rfd list.
 */



void
zd1205_add_skb_to_end(struct zd1205_private *macp, struct rx_list_elem *rx_struct)
{
	zd1205_RFD_t *rfdn;	/* The new rfd */

	zd1205_RFD_t *rfd;		/* The old rfd */
	struct rx_list_elem *rx_struct_last;

    ZENTER(4);


	(rx_struct->skb)->dev = macp->device;
	rfdn = RFD_POINTER(rx_struct->skb, macp);

	rfdn->CbCommand = RFD_EL_BIT;
	wmb();
	rfdn->CbStatus = 0xffffffff;

	rfdn->ActualCount = 0;
	rfdn->MaxSize = MAX_WLAN_SIZE;

	rfdn->NextCbPhyAddrHighPart = 0;

	rfdn->NextCbPhyAddrLowPart = 0;


#ifndef HOST_IF_USB
	wmb();

	pci_dma_sync_single(macp->pdev, rx_struct->dma_addr, macp->rfd_size,
			    PCI_DMA_TODEVICE);
#endif

	if (!list_empty(&(macp->active_rx_list))) {
    	rx_struct_last = list_entry(macp->active_rx_list.prev,

					    struct rx_list_elem, list_elem);


		rfd = RFD_POINTER(rx_struct_last->skb, macp);
		ZD1211DEBUG(4, "zd1211: rfd = %x\n", (u32)rfd);
		    
#ifndef HOST_IF_USB		    
		pci_dma_sync_single(macp->pdev, rx_struct_last->dma_addr,

 				    4, PCI_DMA_FROMDEVICE);
#endif				 
   
		put_unaligned(rx_struct->dma_addr,
			      ((u32 *) (&(rfd->NextCbPhyAddrLowPart))));
#ifndef HOST_IF_USB				      
		wmb();
		pci_dma_sync_single(macp->pdev, rx_struct_last->dma_addr,
				    8, PCI_DMA_TODEVICE);

#endif
				    
		rfd->CbCommand = 0; 

		
#ifndef HOST_IF_USB			
		wmb();
		pci_dma_sync_single(macp->pdev, rx_struct_last->dma_addr,
				    4, PCI_DMA_TODEVICE);

#endif				    
	}
	
	list_add_tail(&(rx_struct->list_elem), &(macp->active_rx_list)); //add elem to active_rx_list
    ZEXIT(4);
}


void zd1205_alloc_skbs(struct zd1205_private *macp)
{
	for (; macp->skb_req > 0; macp->skb_req--) {
		struct rx_list_elem *rx_struct;

		if ((rx_struct = zd1205_alloc_skb(macp)) == NULL){
            printk(KERN_DEBUG "zd1205: zd1205_alloc_skb fail\n");
			return;

        }    
		zd1205_add_skb_to_end(macp, rx_struct);
	}

}


void zd1205_transmit_cleanup(struct zd1205_private *macp, zd1205_SwTcb_t *sw_tcb)
{
	zd1205_HwTCB_t *hw_tcb;
	u32 tbd_cnt;
	zd1205_TBD_t *tbd_arr = sw_tcb->pFirstTbd;

	ZENTER(2);

	hw_tcb = sw_tcb->pTcb;
	tbd_cnt = hw_tcb->TxCbTbdNumber;
 	tbd_arr += 2; //CtrlSetting and MacHeader

	ZD1211DEBUG(2, "zd1211: umap tbd cnt = %x\n", tbd_cnt-2);

#ifndef HOST_IF_USB
	for (i=0; i<tbd_cnt-2; i++, tbd_arr++) {
		ZD1211DEBUG(2, "zd1211: umap body_dma = %x\n", le32_to_cpu(tbd_arr->TbdBufferAddrLowPart));
			pci_unmap_single(macp->pdev,
			le32_to_cpu(tbd_arr->TbdBufferAddrLowPart),
			le32_to_cpu(tbd_arr->TbdCount),
			PCI_DMA_TODEVICE);
	}
#endif

	ZD1211DEBUG(2, "zd1211: Free TcbPhys = %x\n", (u32)sw_tcb->TcbPhys);
	zd1205_qlast_txq(macp, macp->freeTxQ, sw_tcb);
	ZD1211DEBUG(2, "zd1211: Cnt of freeTxQ = %x\n", macp->freeTxQ->count);

	//sw_tcb->HangDur = 0;
	hw_tcb->CbStatus = 0xffffffff;
	hw_tcb->TxCbTbdNumber = 0xaaaaaaaa;	/* for debug */
	hw_tcb->CbCommand = CB_S_BIT;

	if ((netif_running(macp->device)) && (macp->bAssoc)){
	netif_carrier_on(macp->device);
		netif_wake_queue(macp->device);   //resume tx
	}
    
	ZEXIT(2);
	return;		
}

void zd1205_tx_isr(struct zd1205_private *macp)
{
    int i;
	zd1205_SwTcb_t *sw_tcb = NULL;

#ifndef HOST_IF_USB
	zd1250_SwTcb_t *next_sw_tcb;
#endif
	u16 aid;

#ifdef HOST_IF_USB
	int bRunOnce = false;
#endif

	ZD1211DEBUG(2, "***** zd1205_tx_isr enter *****\n");

	if (!macp->activeTxQ->count){
		printk(KERN_DEBUG "No element in activeQ\n");
		return;
	}	

	/* Look at the TCB at the head of the queue.  If it has been completed
	   then pop it off and place it at the tail of the completed list.
	   Repeat this process until all the completed TCBs have been moved to the
	   completed list */
	while (macp->activeTxQ->count){
		sw_tcb = macp->activeTxQ->first;

#ifdef HOST_IF_USB
		// in USB modem, only run once
		if (bRunOnce)	
			break;
		bRunOnce = true;
#endif
		// check to see if the TCB has been DMA'd

		// Workaround for hardware problem that seems leap over a TCB
		// and then fill completion token in the next TCB.
		ZD1211DEBUG(2, "zd1211: hw_tcb = %x\n", (u32)sw_tcb->pTcb);
		ZD1211DEBUG(2, "zd1211: CbStatus = %x\n", (u16)(sw_tcb->pTcb->CbStatus));

#ifndef HOST_IF_USB        
        rmb();

       	if ((u16)le32_to_cpu(sw_tcb->pTcb->CbStatus) != CB_STATUS_COMPLETE){
			next_sw_tcb = sw_tcb;

			while(1){
        		next_sw_tcb = next_sw_tcb->next;
        		if (!next_sw_tcb)
        			break;

				if ((u16)le32_to_cpu(next_sw_tcb->pTcb->CbStatus) == CB_STATUS_COMPLETE)
					break;
			}

			if (!next_sw_tcb)
				break;
		}
#endif        
	
		/* Remove the TCB from the active queue. */
		sw_tcb = zd1205_first_txq(macp, macp->activeTxQ);
		ZD1211DEBUG(2, "zd1211: Cnt of activeQ = %x\n", macp->activeTxQ->count);

		aid = sw_tcb->aid;
		zd1205_transmit_cleanup(macp, sw_tcb);
		macp->txCmpCnt++;
        
		if (!sw_tcb->LastFrag)
			continue;
        
#if ZDCONF_LP_SUPPORT == 1
        if(dot11Obj.LP_MODE && sw_tcb->LP_bucket) {
            //printk("TX_ISR Free LP_bucket\n");
            struct lp_desc *lp = (struct lp_desc *)sw_tcb->LP_bucket ;
            for(i=0;i<lp->pktCnt;i++) {
                //printk("msgID:%d\n", lp->pkt[i].msgID);
                zd_EventNotify(EVENT_TX_COMPLETE, ZD_TX_CONFIRM, (U32)lp->pkt[i].msgID, (U32)aid);
            }
            sw_tcb->LP_bucket = NULL;
            lp->pktCnt = 0;
            lp->sending = 0;
            lp->createTime = 0;
            lp->pktSize = 0;
            lp_recycle_tx_bucket(lp);
        }
        else
#endif
        {
            zd_EventNotify(EVENT_TX_COMPLETE, ZD_TX_CONFIRM, (U32)sw_tcb->MsgID, (U32)aid);
        }

		macp->SequenceNum++;
		macp->bDataTrafficLight = 1;
	}

#ifdef HOST_IF_USB
	if(sw_tcb->CalMIC[MIC_LNG] == TRUE)
		zd1211_submit_tx_urb(macp,TRUE);
	else
		zd1211_submit_tx_urb(macp,FALSE);
#endif

	ZD1211DEBUG(2, "***** zd1205_tx_isr exit *****\n");
	return;
} 


#ifndef HOST_IF_USB
static void zd1205_retry_failed(struct zd1205_private *macp)
{
	zd1205_SwTcb_t *sw_tcb;
	zd1205_SwTcb_t *next_sw_tcb = NULL;

    zd1205_HwTCB_t *hw_tcb;
	zd1205_Ctrl_Set_t *ctrl_set;

	u8 CurrentRate, NewRate;
	u8 ShortPreambleFg;
	u16 Len;
	u16 NextLen;
	u16 LenInUs;
	u16 NextLenInUs;
    u8 Service;
	u16 aid;

    ZD1211DEBUG(2, "+++++ zd1205_retry_failed enter +++++\n");
	
	if (!macp->activeTxQ->count){
		ZD1211DEBUG(1, "**********empty activeTxQ, got retry failed");
		sw_tcb = macp->freeTxQ->first;
		zd1205_start_download(sw_tcb->TcbPhys | BIT_0);
		return;
	}

		
	// Feature: Rate Adaption
	// - During the procedure of processing a transmitting frame, we must keep
	//   the TaRate consistent.
	// - When to fall OppositeContext.CurrentTxRate:
	//   Whenever RetryFail occurs, change OppositeContext.CurrentTxRate by a value
	//   ((Rate of this TCB) minus a degree) and modify this TCB's control-setting 
 	//   with the OppositeContext.CurrentTxRate and then Restart this TCB.
	//	 (Set RetryMAX = 2).
	//   Once the TxRate is 1M and still RetryFail, abandon this frame.
	// - When to rise TxRate:
 	//   If there are 10 frames transmitted successfully 
	//   (OppositeContext.ConsecutiveSuccessFrames >= 10), change 
	//   OppositeContext.CurrentTxRate by a value
	//   ((Rate of this TCB) plus a degree).


	// - Adjust OppositeContext.CurrentTxRate manually. (by application tool)
	sw_tcb = macp->activeTxQ->first;
	aid = sw_tcb->aid;
	ctrl_set = sw_tcb->pHwCtrlPtr;

	if (ctrl_set->CtrlSetting[11] & BIT_3){ //management frame
		goto no_rate_adaption;
	}	
	
	//CurrentRate = (ctrl_set->CtrlSetting[0] & 0x1f);

	CurrentRate = sw_tcb->Rate;

	ShortPreambleFg = (ctrl_set->CtrlSetting[0] & 0x20);
	
	if (((!ShortPreambleFg) && (CurrentRate > RATE_1M)) ||
		 ((ShortPreambleFg) && (CurrentRate > RATE_2M))){ 
		// Fall TxRate a degree

		NewRate = zd1205_RateAdaption(aid, CurrentRate, FALL_RATE);
		sw_tcb->Rate = NewRate;
 
		// Modify Control-setting
		ctrl_set->CtrlSetting[0] = (ShortPreambleFg | NewRate);
		ctrl_set->CtrlSetting[11] |= BIT_0; // Set need backoff
		
		// LenInUs, Service
		Len = (ctrl_set->CtrlSetting[1] + ((u16)ctrl_set->CtrlSetting[2] << 8));
		Cal_Us_Service(NewRate, Len, &LenInUs, &Service);
		ctrl_set->CtrlSetting[20] = (u8)LenInUs;
		ctrl_set->CtrlSetting[21] = (u8)(LenInUs >> 8);
 		ctrl_set->CtrlSetting[22] = Service;


		// NextLenInUs
#if defined(OFDM)
		NextLen = (ctrl_set->CtrlSetting[25+1] + ((u16)ctrl_set->CtrlSetting[25+2] << 8));
#else		
		NextLen = (ctrl_set->CtrlSetting[18] + ((u16)ctrl_set->CtrlSetting[19] << 8));
#endif		





		Cal_Us_Service(NewRate, NextLen, &NextLenInUs, &Service);
		ctrl_set->CtrlSetting[23] = (u8)NextLenInUs;
		ctrl_set->CtrlSetting[24] = (u8)(NextLenInUs >> 8);

#if defined(OFDM)
 		if (NewRate > RATE_11M){
			NewRate = OfdmRateTbl[NewRate];
		}
		
		macp->retryFailCnt++;

 		ctrl_set->CtrlSetting[0] = (ShortPreambleFg | NewRate);
		ctrl_set->CtrlSetting[11] |= BIT_0; // Set need backoff

#endif		
		// Re-Start Tx-Bus master with a lower Rate

		zd1205_start_download(sw_tcb->TcbPhys | BIT_0);
		return;


	}	

	/* Look at the TCB at the head of the queue.  If it has been completed

     then pop it off and place it at the tail of the completed list.
     Repeat this process until all the completed TCBs have been moved to the
     completed list */

no_rate_adaption:     
   	while (macp->activeTxQ->count){
        //ZD1211DEBUG(1, "zd1211: sw_tcb = %x\n", (u32)sw_tcb);
        ZD1211DEBUG(2, "zd1211: hw_tcb = %x\n", (u32)sw_tcb->pTcb);
	    

        /* Remove the TCB from the active queue. */
        sw_tcb = zd1205_first_txq(macp, macp->activeTxQ);

        ZD1211DEBUG(2, "zd1211: Cnt of activeQ = %x\n", macp->activeTxQ->count);
 
        zd1205_transmit_cleanup(macp, sw_tcb);
        macp->retryFailCnt++;
        if (!sw_tcb->LastFrag)
            continue;
 

 	    zd_EventNotify(EVENT_TX_COMPLETE, ZD_RETRY_FAILED, (U32)sw_tcb->MsgID, aid);
		
		if (!macp->activeTxQ->count){
			// Re-Start Tx-Bus master with an suspend TCB
			hw_tcb = (zd1205_HwTCB_t *)sw_tcb->pTcb;
			// Set BIT_0 to escape from Retry-Fail-Wait State.
 			zd1205_start_download((cpu_to_le32(hw_tcb->NextCbPhyAddrLowPart) | BIT_0));
		}else{	
			next_sw_tcb = macp->activeTxQ->first;
			// Re-Start Tx bus master
			// Set BIT_0 to escape from Retry-Fail-Wait state.

			zd1205_start_download(next_sw_tcb->TcbPhys | BIT_0);
		}	
		break;		
    }

    macp->bIBSS_Wakeup_Dest = 1;
    


    ZD1211DEBUG(2, "+++++ zd1205_retry_failed exit +++++\n");

	return;
}
#endif


static void zd1205_config(struct zd1205_private *macp)
{
	u32 tmpValue;
	int i, jj;

    ZENTER(1);
    

    // Retrieve Feature B

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -