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

📄 zd1205.c

📁 Atheros USB WiFi Card 驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:

                    }
                    
                    AccState = ACC_1;
                    macp->Acc_SQ = 0;
                    macp->Acc_Num = 0;
                    macp->Acc_SQ_OFDM = 0;
                    macp->Acc_Num_OFDM = 0;
                }

                break;

            default:
                break;
        }
    }
#endif
}


void zd1205_CollectHwTally(struct zd1205_private *macp)
{
	macp->hwTotalRxFrm += zd_readl(TotalRxFrm);
	macp->hwCRC32Cnt += zd_readl(CRC32Cnt);

 	macp->hwCRC16Cnt += zd_readl(CRC16Cnt);
	//macp->hwDecrypErr_UNI += zd_readl(DecrypErr_UNI);
	//macp->hwDecrypErr_Mul += zd_readl(DecrypErr_Mul);
	macp->hwRxFIFOOverrun += zd_readl(RxFIFOOverrun);
	macp->hwTotalTxFrm += zd_readl(TotalTxFrm);


	macp->hwUnderrunCnt += zd_readl(UnderrunCnt);
	macp->hwRetryCnt += zd_readl(RetryCnt);
}


#define	TOLERANCE		2

int zd1205_IbssPsCheck(struct zd1205_private *macp)
{
	u32 ul_BcnItvl, ul_atimwnd;
	u64 TSFTimer;
	u32 tmpvalue;

		
	// Make sure that we have passed (ATIM-Window+TOLERANCE)
	ul_BcnItvl = zd_readl(ZD_BCNInterval);
	ul_BcnItvl &= 0xffff;
			
	ul_atimwnd = zd_readl(ZD_ATIMWndPeriod);
	tmpvalue = zd_readl(ZD_TSF_LowPart);
	TSFTimer = tmpvalue;

	tmpvalue = zd_readl(ZD_TSF_HighPart);
	TSFTimer += (((u64)tmpvalue) << 32);
	TSFTimer = TSFTimer >> 10; // in unit of TU

	//printk("TSF(TU) %d \n", TSFTimer);
	//printk("BeaconInterval = %d\n", ul_BcnItvl);
	//printk("TSF mod BeaconInterval = %d\n", (TSFTimer % ul_BcnItvl));
            
	if ((do_div(TSFTimer, ul_BcnItvl)) > (ul_atimwnd + TOLERANCE)){
   		// Make sure no traffic before (ATIMWnd+TOLERANCE)
		if ((!macp->bFrmRxed1) && (macp->SuggestionMode == PS_PSM)){
			// Any frame wait for transmission.
			if (!macp->activeTxQ->count){

				//zd1205_sleep_reset(macp);
				return 1;
			}	
		}
	}
	
	return 0;
}



void zd1205_InfraPsCheck(struct zd1205_private *macp)
{	
#if ZDCONF_STA_PSM == 1
	u32 tmpvalue;

	// Now, we assure that no any power-save related operation performing.
	// That's because all power-save related operations are either 
	// Mutexed by Adapter->Lock or Notified by Adapter->Notification.
	if ((macp->SuggestionMode == PS_PSM) && (macp->PwrState == PS_CAM)){
        down(&macp->bcn_sem);
		tmpvalue = zd_readl(ZD_BCNInterval);

		tmpvalue |= POWER_MNT;


		zd_writel(tmpvalue, ZD_BCNInterval);
        up(&macp->bcn_sem);

		macp->PwrState = PS_PSM;
		zd_EventNotify(EVENT_PS_CHANGE, (U8)macp->PwrState, 0, 0);
		ZD1211DEBUG(0, "=====CAM --> PSM\n");
	}
	else if ((macp->SuggestionMode == PS_CAM) && (macp->PwrState == PS_PSM) && 
		(!dot11Obj.bDeviceInSleep)){
        down(&macp->bcn_sem);

 		tmpvalue = zd_readl(ZD_BCNInterval);
 		tmpvalue &= ~POWER_MNT;
		zd_writel(tmpvalue, ZD_BCNInterval);
        up(&macp->bcn_sem);

		macp->PwrState = PS_CAM;
		zd_EventNotify(EVENT_PS_CHANGE, (U8)macp->PwrState, 0, 0);
		ZD1211DEBUG(0, "=====PSM --> CAM\n");
	}
#endif			
	return;
}

//Normally, house keeping routine is run every 100ms.
void zd1205_house_keeping(struct zd1205_private *macp)
{

   	//u32	tmpvalue;
	static u32 loop = 0;
	card_Setting_t *pSetting = &macp->cardSetting;
	u8 BssType = pSetting->BssType;
	u8 bAssoc = macp->bAssoc;
        extern void PHY_UW_IF_Synthesizer(zd_80211Obj_t *pObj, U16 ChannelNo, U8 Mode);


#if 0
	if (dot11Obj.QueueFlag & TX_QUEUE_SET){
		macp->txQueSetCnt++;
		//tasklet_schedule(&macp->zd1205_tx_tasklet);
		zd_CleanupTxQ();
	}
#endif
 	loop++; 

#ifndef HOST_IF_USB     
	while (dot11Obj.bDeviceInSleep){
		// If device is in sleep, do not access device register often to
		// prevent host from slowing down.
		wait_ms(10);
	}
#else
	if (dot11Obj.bDeviceInSleep)
		return;
#endif    

	// Software Antenna Diversity Mechanism
	if (macp->bEnableSwAntennaDiv){
		zd1205_SwAntennaDiv(macp);
	}

#if ZDCONF_ADHOC_SUPPORT == 1
	// IBSS power-save monitor
	if ((BssType == INDEPENDENT_BSS) && (bAssoc)){
		if ((!dot11Obj.bChScanning) && macp->bPSMSupported){
			if (zd1205_IbssPsCheck(macp))
				return;
		}
	}
#endif

	#if 0
	// Infrasture AP mode beacon generation
	if (BssType == AP_BSS) {
		down(&macp->bcn_sem);
        printk("EVENT_TBCN(1)\n");
		zd_EventNotify(EVENT_TBCN, 0, 0, 0);
		up(&macp->bcn_sem);

		if (macp->dtimCount == 0)
			macp->dtimCount = macp->cardSetting.DtimPeriod;
		macp->dtimCount--;
	}
	#endif
#if ZDCONF_RF_UW2453_SUPPORT == 1
    if (dot11Obj.UW2453CCKSetFlag == 2) // OFDM
    {
        PHY_UW_IF_Synthesizer(&dot11Obj, dot11Obj.Channel, 0);
        dot11Obj.UW2453CCKSetFlag = 0;
    }
    else if (dot11Obj.UW2453CCKSetFlag == 3) //CCK
    {
        PHY_UW_IF_Synthesizer(&dot11Obj, dot11Obj.Channel, 1);
        dot11Obj.UW2453CCKSetFlag = 1;
    }
#endif
	//++ Recovery mechanism for ZD1202 ASIC Phy-Bus arbitration fault.
	//   We combined tx-power-tracking/Sw Antenna diversity code here to
	//   reduce the frequence of
 	//   calling ReleaseCtrOfPhyReg. It's harmful to throughput.

	if ((loop % 1) == 0){ //every 100 ms
		//Collect HW Tally
		//zd1205_CollectHwTally(macp);  //This will make us lose CfgNextBcn interrupt

#ifdef HOST_IF_USB

		//tmpvalue = zd_readl(0x6e4);
		//macp->REG_6e4_Add += tmpvalue;
		//printk(KERN_ERR "Detect Strong Signal:%lu\n",jiffies);
		zd1211_StrongSignalDect(macp);
#endif

		// Infrastructure Power-State momitor

		if ((!dot11Obj.bChScanning) && (BssType == INFRASTRUCTURE_BSS) && (bAssoc) &&  (macp->bPSMSupported)){
			zd1205_InfraPsCheck(macp);
		}
	}

#ifdef HOST_IF_USB
	#ifndef ZD1211B
		zd1211_TxCalibration(macp);
	#endif
	//if(dot11Obj.rfMode == UW2453_RF)
	//    PHY_UWTxPower(&dot11Obj, mRfChannel);
#if ZDCONF_EXTRA_FIX_IPC == 1
	zd1211_CheckWithIPC(macp);
#endif
#endif
    	 
}    

void HKeepingCB(struct net_device *dev)
{
	struct zd1205_private *macp = dev->priv;
    static U32 loop = 0;
    int FORCED=FALSE;
    loop++;

#ifdef HOST_IF_USB
	defer_kevent(macp, KEVENT_HOUSE_KEEPING);
	mod_timer(&(macp->tm_hking_id), jiffies+ (1*HZ)/10);
#else
	zd1205_house_keeping(macp);
	mod_timer(&(macp->tm_hking_id), jiffies+ (1*HZ)/10);
#endif

    if (!macp->bFixedRate)
    {
#if ZDCONF_RATE_DEGRADE == 1
        if(loop % 50 == 0) FORCED =TRUE;
#endif
        if(!(loop & BIT_0))
            zd_RateAdaption(FORCED);

    }

}
#if ZDCONF_LP_SUPPORT == 1
void zd1205_lp_poll_cb(struct net_device *dev)
{
    struct zd1205_private *macp = dev->priv;

/*
    if (macp->cardStatus == 0x1234)
    {
        ZD1211DEBUG(0, "mgt_mon_cb: card was closed\n");
        return;
    }
*/
	if(!dot11Obj.LP_MODE)
		return;
    PollFragInfo.msgID = 254;
    dot11Obj.SetupNextSend(&PollFragInfo);
    mod_timer(&(macp->tm_lp_poll_id), jiffies+(1*HZ)/20);
	// 1ms
}
#endif

#if ZDCONF_AP_SUPPORT == 1
void zd1205_CollectBssInfo(struct zd1205_private *macp, plcp_wla_Header_t *pWlanHdr, u8 *pMacBody, u32 bodyLen)
{
	u8 bssidmatched = 0;
	u8 i, j;
	u8 *pBssid;
	u8 *pByte;
	u32 currPos = 0;
	u8 elemId, elemLen;
    U16 loopCheck = 0;

	if ((*(pMacBody+CAP_OFFSET)) & BIT_1) //IBSS
		pBssid = pWlanHdr->Address3; 
	else 
		pBssid = pWlanHdr->Address2; 	

	for (i=0; i<macp->bss_index; i++){
		for (j=0; j<6; j++){
			if (macp->BSSInfo[i].bssid[j] != pBssid[j]){
				break;
			}
		}

		if (j==6){
			bssidmatched = 1;
			break;
		}
	}
		
	if (bssidmatched)
		return;
		
	//get bssid
	for (i=0; i<6; i++){
		macp->BSSInfo[macp->bss_index].bssid[i] = pBssid[i];
	}	
	

	//get beacon interval
	pByte = pMacBody+BCN_INTERVAL_OFFSET;
	macp->BSSInfo[macp->bss_index].beaconInterval = ((*pByte) + ((u16)(*(pByte+1))<<8));
	
	//get capability
	pByte = pMacBody+CAP_OFFSET;
	macp->BSSInfo[macp->bss_index].cap = ((*pByte) + ((u16)(*(pByte+1))<<8) );
	
	//get element
	pByte = pMacBody+SSID_OFFSET;
	currPos = SSID_OFFSET;

	while(currPos < bodyLen){
        // To prevent incorrect elemId length (ex. 0) 
        if(loopCheck++ > 100)
        {
            printk("infinite loop occurs in %s\n", __FUNCTION__);
            break;
        }
		elemId = *pByte;
		elemLen = *(pByte+1);

		switch(elemId){
			case ELEID_SSID: //ssid
				for (i=0; i<elemLen+2; i++){
					macp->BSSInfo[macp->bss_index].ssid[i] = *pByte;
					pByte++;
				}	
				break;

			case ELEID_SUPRATES: //supported rateS

				for (i=0; i<elemLen+2; i++){
					macp->BSSInfo[macp->bss_index].supRates[i] = *pByte;
					pByte++;
				}	
				break;	

				
			case ELEID_DSPARMS: //ds parameter
				macp->BSSInfo[macp->bss_index].channel = *(pByte+2);
				pByte += (elemLen+2); 
				break;

			case ELEID_EXT_RATES:

				pByte += (elemLen+2); 
				break;	

			default:

				pByte += (elemLen+2); 	
				break;
		}

		currPos += elemLen+2;
	}	

	macp->BSSInfo[macp->bss_index].signalStrength = macp->rxSignalStrength;
	macp->BSSInfo[macp->bss_index].signalQuality = macp->rxSignalQuality;
	
	if (macp->bss_index < (BSS_INFO_NUM-1)){
		macp->bss_index ++;
	}

	return;	
}	
#endif

void zd1205_dump_rfds(struct zd1205_private *macp) 
{
#if ZDCONF_DBGMSG_NORMAL == 1
	struct rx_list_elem *rx_struct = NULL;
	struct list_head *entry_ptr = NULL;
	zd1205_RFD_t *rfd = 0;	
	struct sk_buff *skb;

	int i = 0;

	list_for_each(entry_ptr, &(macp->active_rx_list)){

		rx_struct = list_entry(entry_ptr, struct rx_list_elem, list_elem);
		if (!rx_struct)
			return;
#ifndef HOST_IF_USB	
		pci_dma_sync_single(macp->pdev, rx_struct->dma_addr,
			macp->rfd_size, PCI_DMA_FROMDEVICE);
#endif			
		skb = rx_struct->skb;
		rfd = RFD_POINTER(skb, macp);	/* locate RFD within skb */	
#if 0
		printk(KERN_DEBUG "zd1205: i = %x\n", i);
		printk(KERN_DEBUG "zd1205: rx_struct = %x\n", (u32)rx_struct);

		printk(KERN_DEBUG "zd1205: rx_struct->dma_addr = %x\n", (u32)rx_struct->dma_addr);
		printk(KERN_DEBUG "zd1205: rx_struct->skb = %x\n", (u32)rx_struct->skb);
		printk(KERN_DEBUG "zd1205: rfd = %x\n", (u32)rfd);
		printk(KERN_DEBUG "zd1205: CbStatus = %x\n", le32_to_cpu(rfd->CbStatus)); 		

		printk(KERN_DEBUG "zd1205: CbCommand = %x\n", le32_to_cpu(rfd->CbCommand));
		printk(KERN_DEBUG "zd1205: NextCbPhyAddrLowPart = %x\n", le32_to_cpu(rfd->NextCbPhyAddrLowPart));
		printk(KERN_DEBUG "zd1205: NextCbPhyAddrHighPart = %x\n", le32_to_cpu(rfd->NextCbPhyAddrHighPart));
#endif

		zd1205_dump_data("rfd", (u8 *)rfd, 24);
		i++;

	}
#endif

}

void zd1205_dump_data(char *info, u8 *data, u32 data_len)
{
#if ZDCONF_DBGMSG_NORMAL == 1
	int i;
	printk(KERN_DEBUG "%s data [%d]: \n", info, data_len);

	for (i=0; i<data_len; i++){
		printk(KERN_DEBUG "%02x", data[i]);
		printk(KERN_DEBUG " ");
		if ((i>0) && ((i+1)%16 == 0))
			printk(KERN_DEBUG "\n");
	}

	printk(KERN_DEBUG "\n");
#endif
}



/**
 * zd1205_get_rx_struct - retrieve cell to hold skb buff from the pool
 * @macp: atapter's private data struct

 *
 * Returns the new cell to hold sk_buff or %NULL.
 */

static struct rx_list_elem *
zd1205_get_rx_struct(struct zd1205_private *macp)

⌨️ 快捷键说明

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