/* ========================================================================== Description: This routine is called by APMlmePeriodicExec() every second to check if 1. any associated client in PSM. If yes, then TX MCAST/BCAST should be out in DTIM only 2. any client being idle for too long and should be aged-out from MAC table 3. garbage collect PSQ ========================================================================== */ VOID WdsTableMaintenance( IN PRTMP_ADAPTER pAd) { UCHAR idx; if (pAd->WdsTab.Mode != WDS_LAZY_MODE) return; for (idx = 0; idx < pAd->WdsTab.Size; idx++) { UCHAR wcid = pAd->WdsTab.WdsEntry[idx].MacTabMatchWCID; PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[wcid]; if(!IS_ENTRY_WDS(pEntry)) continue; NdisAcquireSpinLock(&pAd->WdsTabLock); NdisAcquireSpinLock(&pAd->MacTabLock); pEntry->NoDataIdleCount ++; NdisReleaseSpinLock(&pAd->MacTabLock); NdisReleaseSpinLock(&pAd->WdsTabLock); /* delete those MAC entry that has been idle for a long time */ if (pEntry->NoDataIdleCount >= MAC_TABLE_AGEOUT_TIME) { DBGPRINT(RT_DEBUG_TRACE, ("ageout %02x:%02x:%02x:%02x:%02x:%02x from WDS #%d after %d-sec silence\n", pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3], pEntry->Addr[4],pEntry->Addr[5], idx, MAC_TABLE_AGEOUT_TIME)); WdsEntryDel(pAd, pEntry->Addr); MacTableDeleteWDSEntry(pAd, pEntry->Aid, pEntry->Addr); } } }
INT Show_WdsTable_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { INT i; #ifdef RTMP_MAC_PCI UCHAR QueIdx=0; #endif /* RTMP_MAC_PCI */ for(i = 0; i < MAX_WDS_ENTRY; i++) { DBGPRINT(RT_DEBUG_OFF, ("IF/WDS%d-%02x:%02x:%02x:%02x:%02x:%02x(%s) ,%s, KeyId=%d\n", i, PRINT_MAC(pAd->WdsTab.WdsEntry[i].PeerWdsAddr), pAd->WdsTab.WdsEntry[i].Valid == 1 ? "Valid" : "Invalid", GetEncryptType(pAd->WdsTab.WdsEntry[i].WepStatus), pAd->WdsTab.WdsEntry[i].KeyIdx)); if (pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen > 0) hex_dump("Wds Key", pAd->WdsTab.WdsEntry[i].WdsKey.Key, pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen); } #ifdef RTMP_MAC_PCI for (QueIdx=0; QueIdx < NUM_OF_TX_RING; QueIdx++) { DBGPRINT(RT_DEBUG_OFF, ("[Tx:%d]: SwFreeIdx=%d, CpuIdx=%d, DmaIdx=%d\n", QueIdx,pAd->TxRing[QueIdx].TxSwFreeIdx, pAd->TxRing[QueIdx].TxCpuIdx, pAd->TxRing[QueIdx].TxDmaIdx)); } DBGPRINT(RT_DEBUG_OFF, ("[Rx]: SwRedIdx=%d, CpuIdx=%d, DmaIdx=%d\n", pAd->RxRing.RxSwReadIdx, pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx)); #endif /* RTMP_MAC_PCI */ DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-4s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", "MAC", "IDX", "AID", "PSM", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC")); for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++) { PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; if (IS_ENTRY_WDS(pEntry)) { DBGPRINT(RT_DEBUG_OFF, ("%02X:%02X:%02X:%02X:%02X:%02X ", PRINT_MAC(pEntry->Addr))); DBGPRINT(RT_DEBUG_OFF,("%-4d", (int)pEntry->MatchWDSTabIdx)); DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->Aid)); DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->PsMode)); DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi0)); DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi1)); DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi2)); DBGPRINT(RT_DEBUG_OFF, ("%-10s", get_phymode_str(pEntry->HTPhyMode.field.MODE))); DBGPRINT(RT_DEBUG_OFF, ("%-6s", get_bw_str(pEntry->HTPhyMode.field.BW))); DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.MCS)); DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.ShortGI)); DBGPRINT(RT_DEBUG_OFF, ("%-6d\n", pEntry->HTPhyMode.field.STBC)); } } return TRUE; }
VOID AsicUpdateWdsEncryption(RTMP_ADAPTER *pAd, UCHAR wcid) { UINT WdsIdex; PMAC_TABLE_ENTRY pEntry = NULL; RT_802_11_WDS_ENTRY *wds_entry; struct wifi_dev *wdev; do { if (wcid >= MAX_LEN_OF_MAC_TABLE) break; pEntry = &pAd->MacTab.Content[wcid]; if (pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].Valid != TRUE) break; if (!IS_ENTRY_WDS(pEntry)) break; WdsIdex = pEntry->func_tb_idx; wds_entry = &pAd->WdsTab.WdsEntry[WdsIdex]; wdev = &wds_entry->wdev; if (((wdev->WepStatus == Ndis802_11WEPEnabled) || (wdev->WepStatus == Ndis802_11TKIPEnable) || (wdev->WepStatus == Ndis802_11AESEnable)) && (wds_entry->WdsKey.KeyLen > 0)) { INT DefaultKeyId = 0; if (wdev->WepStatus == Ndis802_11WEPEnabled) DefaultKeyId = wds_entry->KeyIdx; if (!VAILD_KEY_INDEX(DefaultKeyId)) break; /* Update key into Asic Pairwise key table */ RTMP_ASIC_PAIRWISE_KEY_TABLE( pAd, pEntry->wcid, &wds_entry->WdsKey); /* update WCID attribute table and IVEIV table for this entry */ RTMP_SET_WCID_SEC_INFO( pAd, MAIN_MBSSID + MIN_NET_DEVICE_FOR_WDS, DefaultKeyId, wds_entry->WdsKey.CipherAlg, pEntry->wcid, PAIRWISEKEY); #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) CmdProcAddRemoveKey(pAd, 0, pEntry->func_tb_idx, DefaultKeyId, pEntry->wcid, PAIRWISEKEYTABLE, &wds_entry->WdsKey, pEntry->Addr); #endif /* MT_MAC */ } } while (FALSE); return; }
MAC_TABLE_ENTRY *WdsTableLookup( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr, IN BOOLEAN bResetIdelCount) { USHORT HashIdx; PMAC_TABLE_ENTRY pEntry = NULL; NdisAcquireSpinLock(&pAd->WdsTabLock); NdisAcquireSpinLock(&pAd->MacTabLock); HashIdx = MAC_ADDR_HASH_INDEX(pAddr); pEntry = pAd->MacTab.Hash[HashIdx]; while (pEntry) { if (IS_ENTRY_WDS(pEntry) && MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) { if(bResetIdelCount) pEntry->NoDataIdleCount = 0; break; } else pEntry = pEntry->pNext; } NdisReleaseSpinLock(&pAd->MacTabLock); NdisReleaseSpinLock(&pAd->WdsTabLock); return pEntry; }
/* ========================================================================== Description: This routine is called by APMlmePeriodicExec() every second to check if 1. any WDS client being idle for too long and should be aged-out from MAC table ========================================================================== */ VOID WdsTableMaintenance(RTMP_ADAPTER *pAd) { UCHAR idx; if (pAd->WdsTab.Mode != WDS_LAZY_MODE) return; for (idx = 0; idx < pAd->WdsTab.Size; idx++) { UCHAR wcid = pAd->WdsTab.WdsEntry[idx].MacTabMatchWCID; PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[wcid]; if(!IS_ENTRY_WDS(pEntry)) continue; NdisAcquireSpinLock(&pAd->WdsTabLock); NdisAcquireSpinLock(&pAd->MacTabLock); pEntry->NoDataIdleCount ++; // TODO: shiang-usw, remove upper setting becasue we need to migrate to tr_entry! pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount++; NdisReleaseSpinLock(&pAd->MacTabLock); NdisReleaseSpinLock(&pAd->WdsTabLock); /* delete those MAC entry that has been idle for a long time */ if (pEntry->NoDataIdleCount >= MAC_TABLE_AGEOUT_TIME) { DBGPRINT(RT_DEBUG_TRACE, ("ageout %02x:%02x:%02x:%02x:%02x:%02x from WDS #%d after %d-sec silence\n", PRINT_MAC(pEntry->Addr), idx, MAC_TABLE_AGEOUT_TIME)); WdsEntryDel(pAd, pEntry->Addr); MacTableDeleteWDSEntry(pAd, pEntry->wcid, pEntry->Addr); } } }
MAC_TABLE_ENTRY *WdsTableLookup(RTMP_ADAPTER *pAd, UCHAR *addr, BOOLEAN bResetIdelCount) { USHORT HashIdx; PMAC_TABLE_ENTRY pEntry = NULL; NdisAcquireSpinLock(&pAd->WdsTabLock); NdisAcquireSpinLock(&pAd->MacTabLock); HashIdx = MAC_ADDR_HASH_INDEX(addr); pEntry = pAd->MacTab.Hash[HashIdx]; while (pEntry) { if (IS_ENTRY_WDS(pEntry) && MAC_ADDR_EQUAL(pEntry->Addr, addr)) { if(bResetIdelCount) { pEntry->NoDataIdleCount = 0; // TODO: shiang-usw, remove upper setting becasue we need to migrate to tr_entry! pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; } break; } else pEntry = pEntry->pNext; } NdisReleaseSpinLock(&pAd->MacTabLock); NdisReleaseSpinLock(&pAd->WdsTabLock); return pEntry; }
VOID AsicUpdateWdsEncryption( IN PRTMP_ADAPTER pAd, IN UCHAR wcid) { UINT WdsIdex; PMAC_TABLE_ENTRY pEntry = NULL; do { if (wcid >= MAX_LEN_OF_MAC_TABLE) break; pEntry = &pAd->MacTab.Content[wcid]; if (pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].Valid != TRUE) break; if (!IS_ENTRY_WDS(pEntry)) break; WdsIdex = pEntry->MatchWDSTabIdx; if (((pAd->WdsTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption1Enabled) || (pAd->WdsTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption2Enabled) || (pAd->WdsTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption3Enabled)) && (pAd->WdsTab.WdsEntry[WdsIdex].WdsKey.KeyLen > 0)) { INT DefaultKeyId = 0; if (pAd->WdsTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption1Enabled) DefaultKeyId = pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].KeyIdx; if (!VAILD_KEY_INDEX(DefaultKeyId)) break; /* Update key into Asic Pairwise key table */ RTMP_ASIC_PAIRWISE_KEY_TABLE( pAd, pEntry->Aid, &pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsKey); /* update WCID attribute table and IVEIV table for this entry */ RTMP_SET_WCID_SEC_INFO( pAd, MAIN_MBSSID + MIN_NET_DEVICE_FOR_WDS, DefaultKeyId, pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsKey.CipherAlg, pEntry->Aid, PAIRWISEKEY); } } while (FALSE); return; }
MAC_TABLE_ENTRY *WdsTableLookupByWcid( IN PRTMP_ADAPTER pAd, IN UCHAR wcid, IN PUCHAR pAddr, IN BOOLEAN bResetIdelCount) { /*USHORT HashIdx; */ ULONG WdsIndex; PMAC_TABLE_ENTRY pCurEntry = NULL; PMAC_TABLE_ENTRY pEntry = NULL; if (wcid <=0 || wcid >= MAX_LEN_OF_MAC_TABLE ) return NULL; NdisAcquireSpinLock(&pAd->WdsTabLock); NdisAcquireSpinLock(&pAd->MacTabLock); do { /*HashIdx = MAC_ADDR_HASH_INDEX(pAddr); */ /*pCurEntry = pAd->MacTab.Hash[wcid]; */ pCurEntry = &pAd->MacTab.Content[wcid]; WdsIndex = 0xff; if ((pCurEntry) && IS_ENTRY_WDS(pCurEntry)) { WdsIndex = pCurEntry->MatchWDSTabIdx; } if (WdsIndex == 0xff) break; if (pAd->WdsTab.WdsEntry[WdsIndex].Valid != TRUE) break; if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr)) { if(bResetIdelCount) pCurEntry->NoDataIdleCount = 0; pEntry = pCurEntry; break; } } while(FALSE); NdisReleaseSpinLock(&pAd->MacTabLock); NdisReleaseSpinLock(&pAd->WdsTabLock); return pEntry; }
MAC_TABLE_ENTRY *WdsTableLookupByWcid( IN PRTMP_ADAPTER pAd, IN UCHAR wcid, IN PUCHAR pAddr, IN BOOLEAN bResetIdelCount) { ULONG WdsIndex; MAC_TABLE_ENTRY *pCurEntry = NULL, *pEntry = NULL; if (wcid <=0 || wcid >= MAX_LEN_OF_MAC_TABLE ) return NULL; NdisAcquireSpinLock(&pAd->WdsTabLock); NdisAcquireSpinLock(&pAd->MacTabLock); do { pCurEntry = &pAd->MacTab.Content[wcid]; WdsIndex = 0xff; if ((pCurEntry) && IS_ENTRY_WDS(pCurEntry)) WdsIndex = pCurEntry->func_tb_idx; if (WdsIndex == 0xff) break; if (pAd->WdsTab.WdsEntry[WdsIndex].Valid != TRUE) break; if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr)) { if(bResetIdelCount) { pCurEntry->NoDataIdleCount = 0; // TODO: shiang-usw, remove upper setting becasue we need to migrate to tr_entry! pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; } pEntry = pCurEntry; break; } } while(FALSE); NdisReleaseSpinLock(&pAd->MacTabLock); NdisReleaseSpinLock(&pAd->WdsTabLock); return pEntry; }
INT Show_WdsTable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) { INT i; for(i = 0; i < MAX_WDS_ENTRY; i++) { DBGPRINT(RT_DEBUG_OFF, ("IF/WDS%d-%02x:%02x:%02x:%02x:%02x:%02x(%s) ,%s, KeyId=%d\n", i, PRINT_MAC(pAd->WdsTab.WdsEntry[i].PeerWdsAddr), pAd->WdsTab.WdsEntry[i].Valid == 1 ? "Valid" : "Invalid", GetEncryptType(pAd->WdsTab.WdsEntry[i].wdev.WepStatus), pAd->WdsTab.WdsEntry[i].KeyIdx)); if (pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen > 0) hex_dump("Wds Key", pAd->WdsTab.WdsEntry[i].WdsKey.Key, pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen); } DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-4s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", "MAC", "IDX", "AID", "PSM", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC")); for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++) { PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; if (IS_ENTRY_WDS(pEntry)) { DBGPRINT(RT_DEBUG_OFF, ("%02X:%02X:%02X:%02X:%02X:%02X ", PRINT_MAC(pEntry->Addr))); DBGPRINT(RT_DEBUG_OFF,("%-4d", (int)pEntry->func_tb_idx)); DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->Aid)); DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->PsMode)); DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi[0])); DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi[1])); DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi[2])); DBGPRINT(RT_DEBUG_OFF, ("%-10s", get_phymode_str(pEntry->HTPhyMode.field.MODE))); DBGPRINT(RT_DEBUG_OFF, ("%-6s", get_bw_str(pEntry->HTPhyMode.field.BW))); DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.MCS)); DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.ShortGI)); DBGPRINT(RT_DEBUG_OFF, ("%-6d\n", pEntry->HTPhyMode.field.STBC)); } } return TRUE; }
INT wds_rx_pkt_allow(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk) { HEADER_802_11 *pHeader = pRxBlk->pHeader; MAC_TABLE_ENTRY *pEntry = NULL; INT hdr_len = 0; /* handle WDS */ if (VALID_WCID(pRxBlk->wcid) && IS_ENTRY_WDS(&pAd->MacTab.Content[pRxBlk->wcid])) { if (MAC_ADDR_EQUAL(pHeader->Addr1, pAd->CurrentAddress)) pEntry = FindWdsEntry(pAd, pRxBlk->wcid, pHeader->Addr2, pRxBlk->rx_rate.field.MODE); else pEntry = NULL; /* have no valid wds entry exist, then discard the incoming packet.*/ if (!(pEntry && WDS_IF_UP_CHECK(pAd, pEntry->func_tb_idx))) return FALSE; /*receive corresponding WDS packet, disable TX lock state (fix WDS jam issue) */ if(pEntry && (pEntry->LockEntryTx == TRUE)) { DBGPRINT(RT_DEBUG_TRACE, ("Receive WDS packet, disable TX lock state!\n")); pEntry->ContinueTxFailCnt = 0; pEntry->LockEntryTx = FALSE; // TODO: shiang-usw, remove upper setting because we need to mirgate to tr_entry! pAd->MacTab.tr_entry[pEntry->wcid].ContinueTxFailCnt = 0; pAd->MacTab.tr_entry[pEntry->wcid].LockEntryTx = FALSE; } RX_BLK_SET_FLAG(pRxBlk, fRX_WDS); hdr_len = LENGTH_802_11_WITH_ADDR4; return hdr_len; } return FALSE; }
INT rtmp_mac_fifo_stat_update(RTMP_ADAPTER *pAd) { TX_STA_FIFO_STRUC StaFifo; TX_STA_FIFO_EXT_STRUC StaFifoExt; MAC_TABLE_ENTRY *pEntry = NULL; UINT32 i = 0; UCHAR pid = 0, wcid = 0; INT32 reTry; UCHAR succMCS; do { #ifdef FIFO_EXT_SUPPORT if (IS_RT65XX(pAd)) { RTMP_IO_READ32(pAd, TX_STA_FIFO_EXT, &StaFifoExt.word); } #endif /* FIFO_EXT_SUPPORT */ RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word); if (StaFifo.field.bValid == 0) break; wcid = (UCHAR)StaFifo.field.wcid; #ifdef DBG_CTRL_SUPPORT #ifdef INCLUDE_DEBUG_QUEUE if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFIFO) { dbQueueEnqueue(0x73, (UCHAR *)(&StaFifo.word)); } #endif /* INCLUDE_DEBUG_QUEUE */ #endif /* DBG_CTRL_SUPPORT */ /* ignore NoACK and MGMT frame use 0xFF as WCID */ if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE)) { i++; continue; } /* PID store Tx MCS Rate */ #ifdef FIFO_EXT_SUPPORT if (IS_RT65XX(pAd)) pid = (UCHAR)StaFifoExt.field.pkt_id_65xx; else #endif /* FIFO_EXT_SUPPORT */ pid = (UCHAR)StaFifo.field.PidType; pEntry = &pAd->MacTab.Content[wcid]; if (pEntry & pAd->MacTab.tr_entry[wcid].PsDeQWaitCnt) pAd->MacTab.tr_entry[wcid].PsDeQWaitCnt = 0; pEntry->DebugFIFOCount++; #ifdef DOT11_N_SUPPORT #endif /* DOT11_N_SUPPORT */ #ifdef UAPSD_SUPPORT UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess); #endif /* UAPSD_SUPPORT */ if (!StaFifo.field.TxSuccess) { pEntry->FIFOCount++; pEntry->OneSecTxFailCount++; if (pEntry->FIFOCount >= 1) { DBGPRINT(RT_DEBUG_TRACE, ("#")); #ifdef DOT11_N_SUPPORT pEntry->NoBADataCountDown = 64; #endif /* DOT11_N_SUPPORT */ /* Update the continuous transmission counter.*/ pEntry->ContinueTxFailCnt++; // TODO: shiang-usw, remove upper setting because we need to mirgate to tr_entry! pAd->MacTab.tr_entry[pEntry->wcid].ContinueTxFailCnt++; if(pEntry->PsMode == PWR_ACTIVE) { #ifdef DOT11_N_SUPPORT int tid; for (tid=0; tid<NUM_OF_TID; tid++) BAOriSessionTearDown(pAd, pEntry->wcid, tid, FALSE, FALSE); #endif /* DOT11_N_SUPPORT */ #ifdef WDS_SUPPORT /* fix WDS Jam issue*/ if(IS_ENTRY_WDS(pEntry) && (pEntry->LockEntryTx == FALSE) && (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck)) { DBGPRINT(RT_DEBUG_TRACE, ("Entry %02x:%02x:%02x:%02x:%02x:%02x Blocked!! (Fail Cnt = %d)\n", PRINT_MAC(pEntry->Addr), pEntry->ContinueTxFailCnt )); pEntry->LockEntryTx = TRUE; // TODO: shiang-usw, remove upper setting because we need to mirgate to tr_entry! pAd->MacTab.tr_entry[pEntry->wcid].LockEntryTx = TRUE; } #endif /* WDS_SUPPORT */ } } #ifdef CONFIG_AP_SUPPORT #ifdef RTMP_MAC_PCI /* if Tx fail >= 20, then clear TXWI ack in Tx Ring*/ if (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck) ClearTxRingClientAck(pAd, pEntry); #endif /* RTMP_MAC_PCI */ #endif /* CONFIG_AP_SUPPORT */ } else { #ifdef DOT11_N_SUPPORT if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0)) { pEntry->NoBADataCountDown--; if (pEntry->NoBADataCountDown==0) { DBGPRINT(RT_DEBUG_TRACE, ("@\n")); } } #endif /* DOT11_N_SUPPORT */ pEntry->FIFOCount = 0; pEntry->OneSecTxNoRetryOkCount++; /* update NoDataIdleCount when sucessful send packet to STA.*/ pEntry->NoDataIdleCount = 0; pEntry->ContinueTxFailCnt = 0; #ifdef WDS_SUPPORT pEntry->LockEntryTx = FALSE; #endif /* WDS_SUPPORT */ // TODO: shiang-usw, remove upper setting because we need to mirgate to tr_entry! pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; pAd->MacTab.tr_entry[pEntry->wcid].ContinueTxFailCnt = 0; pAd->MacTab.tr_entry[pEntry->wcid].LockEntryTx = FALSE; } succMCS = StaFifo.field.SuccessRate & 0x7F; #ifdef DOT11N_SS3_SUPPORT if (pEntry->HTCapability.MCSSet[2] == 0xff) { if (succMCS > pid) pid = pid + 16; } #endif /* DOT11N_SS3_SUPPORT */ if (StaFifo.field.TxSuccess) { pEntry->TXMCSExpected[pid]++; if (pid == succMCS) pEntry->TXMCSSuccessful[pid]++; else pEntry->TXMCSAutoFallBack[pid][succMCS]++; } else { pEntry->TXMCSFailed[pid]++; } #ifdef DOT11N_SS3_SUPPORT if (pid >= 16 && succMCS <= 8) succMCS += (2 - (succMCS >> 3)) * 7; #endif /* DOT11N_SS3_SUPPORT */ reTry = pid - succMCS; if (reTry > 0) { /* MCS8 falls back to 0 */ if (pid>=8 && succMCS==0) reTry -= 7; else if ((pid >= 12) && succMCS <=7) reTry -= 4; pEntry->OneSecTxRetryOkCount += reTry; } i++; /* ASIC store 16 stack*/ } while ( i < (TX_RING_SIZE<<1) ); }
VOID WdsPeerBeaconProc( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN USHORT CapabilityInfo, IN UCHAR MaxSupportedRateIn500Kbps, IN UCHAR MaxSupportedRateLen, IN BOOLEAN bWmmCapable, IN ULONG ClientRalinkIe, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen) { UCHAR MaxSupportedRate = RATE_11; MaxSupportedRate = dot11_2_ra_rate(MaxSupportedRateIn500Kbps); if (pEntry && IS_ENTRY_WDS(pEntry)) { pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); pEntry->RateLen = MaxSupportedRateLen; set_entry_phy_cfg(pAd, pEntry); pEntry->MaxHTPhyMode.field.BW = BW_20; pEntry->MinHTPhyMode.field.BW = BW_20; #ifdef DOT11_N_SUPPORT pEntry->HTCapability.MCSSet[0] = 0; pEntry->HTCapability.MCSSet[1] = 0; #endif /* DOT11_N_SUPPORT */ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); pEntry->CapabilityInfo = CapabilityInfo; if (ClientRalinkIe & 0x00000004) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); } if (pAd->CommonCfg.bAggregationCapable) { if ((pAd->CommonCfg.bPiggyBackCapable) && (ClientRalinkIe & 0x00000003) == 3) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); /*RTMPSetPiggyBack(pAd, TRUE); */ } else if (ClientRalinkIe & 0x00000001) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); if ((pAd->CommonCfg.bPiggyBackCapable) && (ClientRalinkIe & 0x00000002) == 2) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); /*RTMPSetPiggyBack(pAd, TRUE); */ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC -PiggyBack2= 1\n")); } else CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } #ifdef DOT11_N_SUPPORT /* If this Entry supports 802.11n, upgrade to HT rate. */ if ((HtCapabilityLen != 0) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ht_mode_adjust(pAd, pEntry, pHtCapability, &pAd->CommonCfg.DesiredHtPhy); /* find max fixed rate */ pEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].DesiredHtPhyInfo.MCSSet[0], &pHtCapability->MCSSet[0]); if ((pEntry->MaxHTPhyMode.field.MCS > pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS) && (pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS != MCS_AUTO)) pEntry->MaxHTPhyMode.field.MCS = pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS; pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity; pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor; pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs; pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize; if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE)) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED); if (pHtCapability->HtCapInfo.ShortGIfor20) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE); if (pHtCapability->HtCapInfo.ShortGIfor40) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE); if (pHtCapability->HtCapInfo.TxSTBC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE); if (pHtCapability->HtCapInfo.RxSTBC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE); if (pHtCapability->ExtHtCapInfo.PlusHTC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE); if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); else CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE)); } else { NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE)); pAd->MacTab.fAnyStationIsLegacy = TRUE; } #endif /* DOT11_N_SUPPORT */ if (bWmmCapable #ifdef DOT11_N_SUPPORT || (pEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX) #endif /* DOT11_N_SUPPORT */ ) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } pEntry->HTPhyMode.field.MODE = pEntry->MaxHTPhyMode.field.MODE; pEntry->HTPhyMode.field.STBC = pEntry->MaxHTPhyMode.field.STBC; pEntry->HTPhyMode.field.ShortGI = pEntry->MaxHTPhyMode.field.ShortGI; pEntry->HTPhyMode.field.BW = pEntry->MaxHTPhyMode.field.BW; switch (pEntry->HTPhyMode.field.MODE) { case MODE_OFDM: /* specific OFDM mode. */ pEntry->SupportRateMode = SUPPORT_OFDM_MODE; break; case MODE_CCK: pEntry->SupportRateMode = SUPPORT_CCK_MODE; break; #ifdef DOT11_N_SUPPORT case MODE_HTMIX: case MODE_HTGREENFIELD: pEntry->SupportRateMode = (SUPPORT_HT_MODE | SUPPORT_OFDM_MODE | SUPPORT_CCK_MODE); break; #endif /* DOT11_N_SUPPORT */ default: break; } } }
VOID WdsPeerBeaconProc( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN USHORT CapabilityInfo, IN UCHAR MaxSupportedRateIn500Kbps, IN UCHAR MaxSupportedRateLen, IN BOOLEAN bWmmCapable, IN ULONG ClientRalinkIe, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen) { UCHAR MaxSupportedRate = RATE_11; switch (MaxSupportedRateIn500Kbps) { case 108: MaxSupportedRate = RATE_54; break; case 96: MaxSupportedRate = RATE_48; break; case 72: MaxSupportedRate = RATE_36; break; case 48: MaxSupportedRate = RATE_24; break; case 36: MaxSupportedRate = RATE_18; break; case 24: MaxSupportedRate = RATE_12; break; case 18: MaxSupportedRate = RATE_9; break; case 12: MaxSupportedRate = RATE_6; break; case 22: MaxSupportedRate = RATE_11; break; case 11: MaxSupportedRate = RATE_5_5; break; case 4: MaxSupportedRate = RATE_2; break; case 2: MaxSupportedRate = RATE_1; break; default: MaxSupportedRate = RATE_11; break; } if (pEntry && IS_ENTRY_WDS(pEntry)) { pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); pEntry->RateLen = MaxSupportedRateLen; if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) { pEntry->MaxHTPhyMode.field.MODE = MODE_CCK; pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate; pEntry->MinHTPhyMode.field.MODE = MODE_CCK; pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate; } else { pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM; pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; pEntry->MinHTPhyMode.field.MODE = MODE_OFDM; pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; } pEntry->MaxHTPhyMode.field.BW = BW_20; pEntry->MinHTPhyMode.field.BW = BW_20; #ifdef DOT11_N_SUPPORT pEntry->HTCapability.MCSSet[0] = 0; pEntry->HTCapability.MCSSet[1] = 0; #endif // DOT11_N_SUPPORT // CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); pEntry->CapabilityInfo = CapabilityInfo; if (ClientRalinkIe & 0x00000004) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); else CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); if (pAd->CommonCfg.bAggregationCapable) { if ((pAd->CommonCfg.bPiggyBackCapable) && (ClientRalinkIe & 0x00000003) == 3) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); //RTMPSetPiggyBack(pAd, TRUE); } else if (ClientRalinkIe & 0x00000001) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); if ((pAd->CommonCfg.bPiggyBackCapable) && (ClientRalinkIe & 0x00000002) == 2) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); //RTMPSetPiggyBack(pAd, TRUE); DBGPRINT(RT_DEBUG_TRACE, ("ASSOC -PiggyBack2= 1\n")); } else CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } #ifdef DOT11_N_SUPPORT // If this Entry supports 802.11n, upgrade to HT rate. if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { UCHAR j, bitmask;//k,bitmask; CHAR i; if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) { pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD; } else { pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; pAd->MacTab.fAnyStationNonGF = TRUE; pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1; } if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth)) { pEntry->MaxHTPhyMode.field.BW= BW_40; pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40)); } else { pEntry->MaxHTPhyMode.field.BW = BW_20; pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20)); pAd->MacTab.fAnyStation20Only = TRUE; } // find max fixed rate //for (i=15; i>=0; i--) for (i=23; i>=0; i--) { j = i/8; bitmask = (1<<(i-(j*8))); if ((pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask)) { pEntry->MaxHTPhyMode.field.MCS = i; break; } if (i==0) break; } if ((pEntry->MaxHTPhyMode.field.MCS > pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS) && (pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS != MCS_AUTO)) pEntry->MaxHTPhyMode.field.MCS = pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS; pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity; pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor; pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs; pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize; if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE)) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED); if (pHtCapability->HtCapInfo.ShortGIfor20) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE); if (pHtCapability->HtCapInfo.ShortGIfor40) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE); if (pHtCapability->HtCapInfo.TxSTBC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE); if (pHtCapability->HtCapInfo.RxSTBC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE); if (pHtCapability->ExtHtCapInfo.PlusHTC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE); if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE)); } else { pAd->MacTab.fAnyStationIsLegacy = TRUE; } #endif // DOT11_N_SUPPORT // if (bWmmCapable #ifdef DOT11_N_SUPPORT || (pEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX) #endif // DOT11_N_SUPPORT // ) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } pEntry->HTPhyMode.field.MODE = pEntry->MaxHTPhyMode.field.MODE; pEntry->HTPhyMode.field.STBC = pEntry->MaxHTPhyMode.field.STBC; pEntry->HTPhyMode.field.ShortGI = pEntry->MaxHTPhyMode.field.ShortGI; pEntry->HTPhyMode.field.BW = pEntry->MaxHTPhyMode.field.BW; } }
VOID WdsPeerBeaconProc( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN USHORT CapabilityInfo, IN UCHAR MaxSupportedRateIn500Kbps, IN UCHAR MaxSupportedRateLen, IN BOOLEAN bWmmCapable, IN ULONG ClientRalinkIe, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen) { UCHAR MaxSupportedRate = RATE_11; MaxSupportedRate = dot11_2_ra_rate(MaxSupportedRateIn500Kbps); if (pEntry && IS_ENTRY_WDS(pEntry)) { pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); pEntry->RateLen = MaxSupportedRateLen; set_entry_phy_cfg(pAd, pEntry); pEntry->MaxHTPhyMode.field.BW = BW_20; pEntry->MinHTPhyMode.field.BW = BW_20; #ifdef DOT11_N_SUPPORT pEntry->HTCapability.MCSSet[0] = 0; pEntry->HTCapability.MCSSet[1] = 0; #endif /* DOT11_N_SUPPORT */ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); pEntry->CapabilityInfo = CapabilityInfo; set_sta_ra_cap(pAd, pEntry, ClientRalinkIe); #ifdef DOT11_N_SUPPORT /* If this Entry supports 802.11n, upgrade to HT rate. */ if ((HtCapabilityLen != 0) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ht_mode_adjust(pAd, pEntry, pHtCapability, &pAd->CommonCfg.DesiredHtPhy); /* find max fixed rate */ pEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].wdev.DesiredHtPhyInfo.MCSSet[0], &pHtCapability->MCSSet[0]); if ((pEntry->MaxHTPhyMode.field.MCS > pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].wdev.HTPhyMode.field.MCS) && (pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].wdev.HTPhyMode.field.MCS != MCS_AUTO)) pEntry->MaxHTPhyMode.field.MCS = pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].wdev.HTPhyMode.field.MCS; pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity; pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor; pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs; pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize; if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE)) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED); set_sta_ht_cap(pAd, pEntry, pHtCapability); NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE)); } else { NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE)); pAd->MacTab.fAnyStationIsLegacy = TRUE; } #endif /* DOT11_N_SUPPORT */ if (bWmmCapable #ifdef DOT11_N_SUPPORT || (pEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX) #endif /* DOT11_N_SUPPORT */ ) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } pEntry->HTPhyMode.field.MODE = pEntry->MaxHTPhyMode.field.MODE; pEntry->HTPhyMode.field.STBC = pEntry->MaxHTPhyMode.field.STBC; pEntry->HTPhyMode.field.ShortGI = pEntry->MaxHTPhyMode.field.ShortGI; pEntry->HTPhyMode.field.BW = pEntry->MaxHTPhyMode.field.BW; switch (pEntry->HTPhyMode.field.MODE) { case MODE_OFDM: /* specific OFDM mode. */ pEntry->SupportRateMode = SUPPORT_OFDM_MODE; break; case MODE_CCK: pEntry->SupportRateMode = SUPPORT_CCK_MODE; break; #ifdef DOT11_N_SUPPORT case MODE_HTMIX: case MODE_HTGREENFIELD: pEntry->SupportRateMode = (SUPPORT_HT_MODE | SUPPORT_OFDM_MODE | SUPPORT_CCK_MODE); break; #endif /* DOT11_N_SUPPORT */ default: break; } } }
MAC_TABLE_ENTRY *MacTableInsertEntry( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr, IN UCHAR apidx, IN UCHAR OpMode, IN BOOLEAN CleanAll) { UCHAR HashIdx; int i, FirstWcid; MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry; /* USHORT offset;*/ /* ULONG addr;*/ BOOLEAN Cancelled; /* if FULL, return*/ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) return NULL; FirstWcid = 1; /* allocate one MAC entry*/ NdisAcquireSpinLock(&pAd->MacTabLock); for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) /* skip entry#0 so that "entry index == AID" for fast lookup*/ { /* pick up the first available vacancy*/ if (IS_ENTRY_NONE(&pAd->MacTab.Content[i])) { pEntry = &pAd->MacTab.Content[i]; /* ENTRY PREEMPTION: initialize the entry */ RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); if (CleanAll == TRUE) { pEntry->MaxSupportedRate = RATE_11; pEntry->CurrTxRate = RATE_11; NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); pEntry->PairwiseKey.KeyLen = 0; pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; } do { #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_APCLI) { SET_ENTRY_APCLI(pEntry); pEntry->isCached = FALSE; break; } #endif /* APCLI_SUPPORT */ #ifdef WDS_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_WDS) { SET_ENTRY_WDS(pEntry); pEntry->isCached = FALSE; break; } #endif /* WDS_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { /* be a regular-entry*/ if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && ((apidx < HW_BEACON_MAX_NUM)) && (pAd->ApCfg.MBSSID[apidx].MaxStaNum != 0) && (pAd->ApCfg.MBSSID[apidx].StaCount >= pAd->ApCfg.MBSSID[apidx].MaxStaNum)) { DBGPRINT(RT_DEBUG_WARN, ("%s: The connection table is full in ra%d.\n", __FUNCTION__, apidx)); NdisReleaseSpinLock(&pAd->MacTabLock); return NULL; } } #endif /* CONFIG_AP_SUPPORT */ SET_ENTRY_CLIENT(pEntry); } while (FALSE); pEntry->bIAmBadAtheros = FALSE; RTMPInitTimer(pAd, &pEntry->EnqueueStartForPSKTimer, GET_TIMER_FUNCTION(EnqueueStartForPSKExec), pEntry, FALSE); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (IS_ENTRY_CLIENT(pEntry)) /* Only Clent entry need the retry timer.*/ { RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE); /* RTMP_OS_Init_Timer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pAd);*/ } #ifdef APCLI_SUPPORT else if (IS_ENTRY_APCLI(pEntry)) { RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE); } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) RTMPInitTimer(pAd, &pEntry->eTxBfProbeTimer, GET_TIMER_FUNCTION(eTxBfProbeTimerExec), pEntry, FALSE); #endif /* TXBF_SUPPORT */ pEntry->pAd = pAd; pEntry->CMTimerRunning = FALSE; pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; pEntry->RSNIE_Len = 0; NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter)); pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; if (IS_ENTRY_MESH(pEntry)) pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH); else if (IS_ENTRY_APCLI(pEntry)) pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI); else if (IS_ENTRY_WDS(pEntry)) pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS); else pEntry->apidx = apidx; #ifdef CONFIG_AP_SUPPORT if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && (apidx < HW_BEACON_MAX_NUM)) pEntry->pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx]; else pEntry->pMbss = NULL; #endif /* CONFIG_AP_SUPPORT */ do { #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (IS_ENTRY_APCLI(pEntry)) { pEntry->AuthMode = pAd->ApCfg.ApCliTab[pEntry->apidx].AuthMode; pEntry->WepStatus = pAd->ApCfg.ApCliTab[pEntry->apidx].WepStatus; if (pEntry->AuthMode < Ndis802_11AuthModeWPA) { pEntry->WpaState = AS_NOTUSE; pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; } else { pEntry->WpaState = AS_PTKSTART; pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; } pEntry->MatchAPCLITabIdx = pEntry->apidx; break; } #endif /* APCLI_SUPPORT */ #ifdef WDS_SUPPORT if (IS_ENTRY_WDS(pEntry)) { pEntry->AuthMode = Ndis802_11AuthModeOpen; pEntry->WepStatus = Ndis802_11EncryptionDisabled; pEntry->MatchWDSTabIdx = pEntry->apidx; break; } #endif /* WDS_SUPPORT */ IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { MBSS_MR_APIDX_SANITY_CHECK(pAd, apidx); pEntry->AuthMode = pAd->ApCfg.MBSSID[apidx].AuthMode; pEntry->WepStatus = pAd->ApCfg.MBSSID[apidx].WepStatus; pEntry->GroupKeyWepStatus = pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus; if (pEntry->AuthMode < Ndis802_11AuthModeWPA) pEntry->WpaState = AS_NOTUSE; else pEntry->WpaState = AS_INITIALIZE; pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; pEntry->StaIdleTimeout = pAd->ApCfg.StaIdleTimeout; pAd->ApCfg.MBSSID[apidx].StaCount++; pAd->ApCfg.EntryClientCount++; break; } #endif /* CONFIG_AP_SUPPORT */ } while (FALSE); pEntry->GTKState = REKEY_NEGOTIATING; pEntry->PairwiseKey.KeyLen = 0; pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; COPY_MAC_ADDR(pEntry->Addr, pAddr); COPY_MAC_ADDR(pEntry->HdrAddr1, pAddr); do { #ifdef APCLI_SUPPORT if (IS_ENTRY_APCLI(pEntry)) { COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.ApCliTab[pEntry->apidx].CurrentAddress); COPY_MAC_ADDR(pEntry->HdrAddr3, pAddr); break; } #endif // APCLI_SUPPORT // #ifdef WDS_SUPPORT if (IS_ENTRY_WDS(pEntry)) { COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid); COPY_MAC_ADDR(pEntry->HdrAddr3, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid); break; } #endif // WDS_SUPPORT // #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) { COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.MBSSID[apidx].Bssid); COPY_MAC_ADDR(pEntry->HdrAddr3, pAd->ApCfg.MBSSID[apidx].Bssid); break; } #endif // CONFIG_AP_SUPPORT // } while (FALSE); pEntry->Sst = SST_NOT_AUTH; pEntry->AuthState = AS_NOT_AUTH; pEntry->Aid = (USHORT)i; /*0;*/ pEntry->CapabilityInfo = 0; pEntry->PsMode = PWR_ACTIVE; pEntry->PsQIdleCount = 0; pEntry->NoDataIdleCount = 0; pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT; pEntry->ContinueTxFailCnt = 0; #ifdef WDS_SUPPORT pEntry->LockEntryTx = FALSE; #endif /* WDS_SUPPORT */ pEntry->TimeStamp_toTxRing = 0; InitializeQueueHeader(&pEntry->PsQueue); #ifdef STREAM_MODE_SUPPORT /* Enable Stream mode for first three entries in MAC table */ #endif /* STREAM_MODE_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef UAPSD_SUPPORT if (IS_ENTRY_CLIENT(pEntry)) /* Ralink WDS doesn't support any power saving.*/ { /* init U-APSD enhancement related parameters */ UAPSD_MR_ENTRY_INIT(pEntry); } #endif /* UAPSD_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ pAd->MacTab.Size ++; /* Set the security mode of this entry as OPEN-NONE in ASIC */ RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, (UCHAR)i); /* Add this entry into ASIC RX WCID search table */ RTMP_STA_ENTRY_ADD(pAd, pEntry); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef WSC_AP_SUPPORT pEntry->bWscCapable = FALSE; pEntry->Receive_EapolStart_EapRspId = 0; #endif /* WSC_AP_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) NdisAllocateSpinLock(pAd, &pEntry->TxSndgLock); #endif /* TXBF_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size)); break; } }