📄 zd1205.c
字号:
}
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 + -