📄 bssdb.c
字号:
/*+
*
* Routine Description:
* Search Node DB table to find the index of matched DstAddr
*
* Return Value:
* None
*
-*/
BOOL
BSSDBbIsSTAInNodeDB(
IN PVOID pMgmtObject,
IN PBYTE abyDstAddr,
OUT PUINT puNodeIndex
)
{
PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject;
UINT ii;
// Index = 0 reserved for AP Node
for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
if (pMgmt->sNodeDBTable[ii].bActive) {
if (IS_ETH_ADDRESS_EQUAL(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
*puNodeIndex = ii;
return TRUE;
}
}
}
return FALSE;
};
/*+
*
* Routine Description:
* Find an empty node and allocated; if no empty found,
* instand used of most inactive one.
*
* Return Value:
* None
*
-*/
VOID
BSSvCreateOneNode(
IN HANDLE hDeviceContext,
OUT PUINT puNodeIndex
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = pDevice->pMgmt;
UINT ii;
UINT BigestCount = 0;
UINT SelectIndex;
struct sk_buff *skb;
// Index = 0 reserved for AP Node (In STA mode)
// Index = 0 reserved for Broadcast/MultiCast (In AP mode)
SelectIndex = 1;
for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
if (pMgmt->sNodeDBTable[ii].bActive) {
if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) {
BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount;
SelectIndex = ii;
}
}
else {
break;
}
}
// if not found replace uInActiveCount is largest one.
if ( ii == (MAX_NODE_NUM + 1)) {
*puNodeIndex = SelectIndex;
DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
// clear ps buffer
if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) {
while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL)
dev_kfree_skb(skb);
}
}
else {
*puNodeIndex = ii;
}
memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
pMgmt->sNodeDBTable[*puNodeIndex].bActive = TRUE;
pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
// for AP mode PS queue
skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
return;
};
/*+
*
* Routine Description:
* Remove Node by NodeIndex
*
*
* Return Value:
* None
*
-*/
VOID
BSSvRemoveOneNode(
IN HANDLE hDeviceContext,
IN UINT uNodeIndex
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = pDevice->pMgmt;
BYTE byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
struct sk_buff *skb;
while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL)
dev_kfree_skb(skb);
// clear context
memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB));
// clear tx bit map
pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &= ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7];
return;
};
/*+
*
* Routine Description:
* Update AP Node content in Index 0 of KnownNodeDB
*
*
* Return Value:
* None
*
-*/
VOID
BSSvUpdateAPNode(
IN HANDLE hDeviceContext,
IN PWORD pwCapInfo,
IN PWLAN_IE_SUPP_RATES pSuppRates,
IN PWLAN_IE_SUPP_RATES pExtSuppRates
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = pDevice->pMgmt;
UINT uRateLen = WLAN_RATES_MAXLEN;
memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
pMgmt->sNodeDBTable[0].bActive = TRUE;
if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
uRateLen = WLAN_RATES_MAXLEN_11B;
}
pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
uRateLen);
pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
uRateLen);
RATEvParseMaxRate((PVOID) pDevice,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
TRUE,
&(pMgmt->sNodeDBTable[0].wMaxBasicRate),
&(pMgmt->sNodeDBTable[0].wMaxSuppRate),
&(pMgmt->sNodeDBTable[0].wSuppRate),
&(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
&(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
);
memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate;
pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo);
pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
// Auto rate fallback function initiation.
// RATEbInit(pDevice);
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
};
/*+
*
* Routine Description:
* Add Multicast Node content in Index 0 of KnownNodeDB
*
*
* Return Value:
* None
*
-*/
VOID
BSSvAddMulticastNode(
IN HANDLE hDeviceContext
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = pDevice->pMgmt;
if (!pDevice->bEnableHostWEP)
memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN);
pMgmt->sNodeDBTable[0].bActive = TRUE;
pMgmt->sNodeDBTable[0].bPSEnable = FALSE;
skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue);
RATEvParseMaxRate((PVOID) pDevice,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
TRUE,
&(pMgmt->sNodeDBTable[0].wMaxBasicRate),
&(pMgmt->sNodeDBTable[0].wMaxSuppRate),
&(pMgmt->sNodeDBTable[0].wSuppRate),
&(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
&(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
);
pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate;
pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
};
/*+
*
* Routine Description:
*
*
* Second call back function to update Node DB info & AP link status
*
*
* Return Value:
* none.
*
-*/
VOID
BSSvSecondCallBack(
IN HANDLE hDeviceContext
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = pDevice->pMgmt;
UINT ii;
PWLAN_IE_SSID pItemSSID, pCurrSSID;
UINT uSleepySTACnt = 0;
UINT uNonShortSlotSTACnt = 0;
UINT uLongPreambleSTACnt = 0;
spin_lock_irq(&pDevice->lock);
pDevice->uAssocCount = 0;
pDevice->byERPFlag &=
~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
if (pDevice->wUseProtectCntDown > 0) {
pDevice->wUseProtectCntDown --;
}
else {
// disable protect mode
pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
}
for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
if (pMgmt->sNodeDBTable[ii].bActive) {
// Increase in-activity counter
pMgmt->sNodeDBTable[ii].uInActiveCount++;
if (ii > 0) {
if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) {
BSSvRemoveOneNode(pDevice, ii);
DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO
"Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii);
continue;
}
if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) {
pDevice->uAssocCount++;
// check if Non ERP exist
if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) {
if (!pMgmt->sNodeDBTable[ii].bShortPreamble) {
pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
uLongPreambleSTACnt ++;
}
if (!pMgmt->sNodeDBTable[ii].bERPExist) {
pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
}
if (!pMgmt->sNodeDBTable[ii].bShortSlotTime)
uNonShortSlotSTACnt++;
}
}
// check if any STA in PS mode
if (pMgmt->sNodeDBTable[ii].bPSEnable)
uSleepySTACnt++;
}
// Rate fallback check
if (!pDevice->bFixRate) {
/*
if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0))
RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii]));
*/
if (ii > 0) {
// ii = 0 for multicast node (AP & Adhoc)
RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii]));
}
else {
// ii = 0 reserved for unicast AP node (Infra STA)
if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)
RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii]));
}
}
// check if pending PS queue
if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
if ((ii >0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) {
BSSvRemoveOneNode(pDevice, ii);
DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
continue;
}
}
}
}
if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) {
// on/off protect mode
if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
if (!pDevice->bProtectMode) {
MACvEnableProtectMD(pDevice->PortOffset);
pDevice->bProtectMode = TRUE;
}
}
else {
if (pDevice->bProtectMode) {
MACvDisableProtectMD(pDevice->PortOffset);
pDevice->bProtectMode = FALSE;
}
}
// on/off short slot time
if (uNonShortSlotSTACnt > 0) {
if (pDevice->bShortSlotTime) {
pDevice->bShortSlotTime = FALSE;
BBvSetShortSlotTime(pDevice);
vUpdateIFS((PVOID)pDevice);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -