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

📄 zd1205.c

📁 ZD1211LnxDrv_2_3_1_0無線網卡ZD1211
💻 C
📖 第 1 页 / 共 5 页
字号:
	wmb();
	rfdn->CbStatus = 0xffffffff;

	rfdn->ActualCount = 0;
	rfdn->MaxSize = __constant_cpu_to_le32(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(cpu_to_le32(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 = le32_to_cpu(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 = cpu_to_le32(0xaaaaaaaa);	/* for debug */
	hw_tcb->CbCommand = cpu_to_le32(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)
{
	zd1205_SwTcb_t *sw_tcb;

#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)le32_to_cpu(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;
        
		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 BitMap
    zd_writel(macp->cardSetting.EncryMode, EncryptionType);
    macp->dtimCount = 0;

    
    /* Setup Physical Address */
	zd_writel(cpu_to_le32(*(u32 *)&macp->macAdr[0]), MACAddr_P1);
	zd_writel(cpu_to_le32(*(u32 *)&macp->macAdr[4]), MACAddr_P2);
	if (macp->cardSetting.BssType == AP_BSS){
		/* Set bssid = MacAddress */
		macp->BSSID[0] = macp->macAdr[0];
		macp->BSSID[1] = macp->macAdr[1];
		macp->BSSID[2] = macp->macAdr[2];
		macp->BSSID[3] = macp->macAdr[3];
 		macp->BSSID[4] = macp->macAdr[4];
		macp->BSSID[5] = macp->macAdr[5];
 		zd_writel(cpu_to_le32(*(u32 *)&macp->macAdr[0]), BSSID_P1);
		zd_writel(cpu_to_le32(*(u32 *)&macp->macAdr[4]), BSSID_P2);
	}
	else {
		zd_writel(STA_RX_FILTER, ZD_Rx_Filter);
	}		
	

    macp->intrMask = ZD1205_INT_MASK;

	if (macp->intrMask & DTIM_NOTIFY_EN)
 		macp->dtim_notify_en = 1;
	else 
		macp->dtim_notify_en = 0;	
	

	if (macp->intrMask & CFG_NEXT_BCN_EN)

		macp->config_next_bcn_en = 1;
	else 
		macp->config_next_bcn_en = 0;



    zd1205_ClearTupleCache(macp);
	zd1205_ArReset(macp);

	macp->bTraceSetPoint = 1;
	macp->bFixedRate = 0;
    dot11Obj.bDeviceInSleep = 0; 

   	macp->bGkInstalled = 0;
    macp->PwrState = PS_CAM;

	// Get Allowed Channel and Default Channel
	dot11Obj.AllowedChannel = zd_readl(ZD_E2P_ALLOWED_CHANNEL);
	
#ifndef HOST_IF_USB
 	dot11Obj.AllowedChannel = 0x3FFF;
#endif

	ZD1211DEBUG(0, "AllowedChannel = %08x\n", (u32)dot11Obj.AllowedChannel);
	
	if (!(dot11Obj.AllowedChannel & 0xFFFF0000)){
		dot11Obj.AllowedChannel |= 0x10000;
	}

	
#ifdef HOST_IF_USB
	tmpValue = zd_readl(E2P_SUBID);
 	macp->RegionCode = (u16)(tmpValue >> 16);

	dot11Obj.RegionCode = macp->RegionCode;
    macp->LinkLEDn = LED1;
    if (macp->RF_Mode & BIT_4){


        macp->LinkLEDn = LED2;
        ZD1211DEBUG(0, "LED2\n");
    }
    ZD1211DEBUG(0, "LinkLEDn = %x\n", macp->LinkLEDn);    

    if (macp->RF_Mode & BIT_8){

		dot11Obj.bOverWritePhyRe

⌨️ 快捷键说明

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