📄 wt_stmgt.c
字号:
int MinRemainTime; // default value AIFSN[AC_BK] = AIFSN_BK; AIFSN[AC_BE] = AIFSN_BE; AIFSN[AC_VI] = AIFSN_VI; AIFSN[AC_VO] = AIFSN_VO; //AIFS[AC] = AIFSN[AC] �aSlotTime + aSIFSTime RemainTime[AC_BK] = 0; RemainTime[AC_BE] = 0; RemainTime[AC_VI] = 0; //random_data(1) & cw; RemainTime[AC_VO]= 0; //random_data(1) & cw;//cw// cw = Current_message->Message_Body.BackOff_Var.cw;// slotCnt = random_data(1) & cw; //???___________zxx//define the value of RemainTime if(!IsQueueEmpty( &Adapter->TxFrmQVO)) { if(RemainTime[AC_VO] == cw+1 || RemainTime[AC_VO] == 0) RemainTime[AC_VO] = random_data(1) & cw; //_______________________modify! } else RemainTime[AC_VO] = cw+1; if(!IsQueueEmpty( &Adapter->TxFrmQVI)) { if(RemainTime[AC_VI] == cw+1 || RemainTime[AC_VI] == 0) RemainTime[AC_VI] = random_data(1) & cw; } else RemainTime[AC_VI] = cw+1; if(!IsQueueEmpty( &Adapter->TxFrmQBE) ) { if(RemainTime[AC_BE] == cw+1 || RemainTime[AC_BE] == 0) RemainTime[AC_BE] = (random_data(1) & cw) + AIFSN_BE;//edited by wl 2005.7.26 else RemainTime[AC_BE] += AIFSN_BE; } else RemainTime[AC_BE] = cw+1; if(!IsQueueEmpty( &Adapter->TxFrmQBK)) { if(RemainTime[AC_BK] == cw+1 || RemainTime[AC_BK] == 0) RemainTime[AC_BK] = (random_data(1) & cw) + AIFSN_BK;//edited by wl 2005.7.26 else RemainTime[AC_BK] += AIFSN_BK; } else RemainTime[AC_BK] = cw+1;// compare the values of RemainTime MaxRemainTime = wt_max( wt_max( RemainTime[AC_BE], RemainTime[AC_BK] ), wt_max( RemainTime[AC_VI], RemainTime[AC_VO]) ); MinRemainTime = wt_min( wt_min(RemainTime[AC_BE], RemainTime[AC_BK]), wt_min(RemainTime[AC_VI], RemainTime[AC_VO]));//////////////////////////////////////////////////////////////////////////////////////////////////////////////#if 0// if All four up queues are empty if(MinRemainTime == cw+1) return NULL; else if(RemainTime[AC_VO] == MinRemainTime) { pEntry = RemoveHeadQueue(&Adapter->TxFrmQVO); //pWtTxBuf = CONTAINING_RECORD(pEntry, WTWLAN_TXBUF, SList); //pWtTxBuf = list_entry( pEntry, WTWLAN_TXBUF, List ); pWtTxBuf = (PWTWLAN_TXBUF)pEntry; Adapter->TxQLen[AC_VO]--; ASSERT(Adapter->TxQLen[AC_VO] >= 0); } else if(RemainTime[AC_VI] == MinRemainTime) { pEntry = RemoveHeadQueue(&Adapter->TxFrmQVI); //pWtTxBuf = CONTAINING_RECORD(pEntry, WTWLAN_TXBUF, SList); //pWtTxBuf = list_entry( pEntry, WTWLAN_TXBUF, List ); pWtTxBuf = (PWTWLAN_TXBUF)pEntry; Adapter->TxQLen[AC_VI]--; ASSERT(Adapter->TxQLen[AC_VI] >= 0); } else if(RemainTime[AC_BE] == MinRemainTime) { pEntry = RemoveHeadQueue(&Adapter->TxFrmQBE); //pWtTxBuf = CONTAINING_RECORD(pEntry, WTWLAN_TXBUF, SList); //pWtTxBuf = list_entry( pEntry, WTWLAN_TXBUF, List ); pWtTxBuf = (PWTWLAN_TXBUF)pEntry; Adapter->TxQLen[AC_BE]--; ASSERT(Adapter->TxQLen[AC_BE] >= 0); } else { pEntry = RemoveHeadQueue(&Adapter->TxFrmQBK); //pWtTxBuf = CONTAINING_RECORD(pEntry, WTWLAN_TXBUF, SList); //pWtTxBuf = list_entry( pEntry, WTWLAN_TXBUF, List ); pWtTxBuf = (PWTWLAN_TXBUF)pEntry; Adapter->TxQLen[AC_BK]--; ASSERT(Adapter->TxQLen[AC_BK] >= 0); }#endif//////////////////////////////////////////////////////////////////////////////////////////////////////////////// define the values of RemainTime if(RemainTime[AC_VO] != cw+1) RemainTime[AC_VO] -= MinRemainTime; if(RemainTime[AC_VI] != cw+1) RemainTime[AC_VI] -= MinRemainTime; if(RemainTime[AC_BE] != cw+1) { if(MinRemainTime <=AIFSN_BE) RemainTime[AC_BE] -= AIFSN_BE; else RemainTime[AC_BE] -= MinRemainTime; } if(RemainTime[AC_BK] != cw+1) { if(MinRemainTime <=AIFSN_BK) RemainTime[AC_BK] -= AIFSN_BK; else RemainTime[AC_BK] -= MinRemainTime; }return pWtTxBuf;}PWTWLAN_TXBUF AddUPToBuf( IN PWTWLAN_TXBUF pWtTxBuf )/*add the QoS Control field to Mac Header*/{ PUCHAR pDest; QOSCTRL QoSCtrField; /*set EOSP*/ QoSCtrField.EOSP = 1;/*set QueueSize*/ QoSCtrField.QueueSize = 255;/*set Reserved*/ QoSCtrField.Reserved = 0;/*set AckPolicy*//* if(ftype(pWtTxBuf->TXHwBuf.pBuffer) == 0x2c) // QoS Null (no data) -> 10_1100 PQoSCtrField->AckPolicy = 0; else if(ftype(pWtTxBuf->TXHwBuf.pBuffer) == 0x29 || ftype(pWtTxBuf->TXHwBuf.pBuffer) == 0x2d) PQoSCtrField->AckPolicy = 2; // QoS CF_Ack -> 10_1001 or 10_1101 else if(ftype(pWtTxBuf->TXHwBuf.pBuffer) == 0x2a || ftype(pWtTxBuf->TXHwBuf.pBuffer) == 0x2e || ftype(pWtTxBuf->TXHwBuf.pBuffer) == 0x2b || ftype(pWtTxBuf->TXHwBuf.pBuffer) == 0x2f ) PQoSCtrField->AckPolicy = 1; // QoS CF_Poll -> 10_1010 or 10_1110 OR QoS CF_Ack+CF_Poll -> 10_1011 or 10_1111 else PQoSCtrField->AckPolicy = 3;*/ QoSCtrField.AckPolicy = 0; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*set TID*/ //QoSCtrField.TID= (IEEE8021PPRIORITY) NDIS_PER_PACKET_INFO_FROM_PACKET(pWtTxBuf->NdisPacket, Ieee8021pPriority);//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*add the QoS control field to Mac Header*/ pDest = pWtTxBuf->TXHwBuf.pHwTxBuf->dot11Head + pWtTxBuf->TXHwBuf.pHwTxBuf->TxAUXBuf.HeadLen; #ifdef WIN_PLATFORM NdisMoveMemory( pDest, &QoSCtrField, 2); #else memmove( pDest, &QoSCtrField, 2); #endif pWtTxBuf->TXHwBuf.pHwTxBuf->TxAUXBuf.HeadLen += 2;return pWtTxBuf;}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////PWTWLAN_TXBUF QosSendProcess(IN PWT_ADAPTER Adapter){ PWTWLAN_TXBUF pWtTxBuf = NULL; PQUEUE_ENTRY pEntry; if( Adapter->MacParameter.b80211eEnable ) { pWtTxBuf = Backoff_Pre( Adapter ); pWtTxBuf = AddUPToBuf( pWtTxBuf ); } else { if( !IsQueueEmpty( &Adapter->TxFrmQBE) ) { //#if 0 pEntry = RemoveHeadQueue(&Adapter->TxFrmQBE); //pWtTxBuf = CONTAINING_RECORD(pEntry, WTWLAN_TXBUF, SList); //pWtTxBuf = list_entry( pEntry, WTWLAN_TXBUF, List ); pWtTxBuf = (PWTWLAN_TXBUF)pEntry; Adapter->TxQLen[AC_BE]--; ASSERT(Adapter->TxQLen[AC_BE] >= 0); //#endif } } return pWtTxBuf;}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /*This function is to match the fragment received with RecvList.*/#ifdef WIN_PLATFORMPWTWLAN_RXBUF DefragMatch(IN PLIST_ENTRY pRecvFragList, IN PWTWLAN_RXBUF pWtRxBuf)#elsePWTWLAN_RXBUF DefragMatch(IN struct list_head* pRecvFragList, IN PWTWLAN_RXBUF pWtRxBuf)#endif{ PWTWLAN_RXBUF pBuf; struct list_head *pEntry; p80211_hdr_t *w_hdr; p80211_hdr_t *pBuf_hdr; UINT8 *daddr = NULL; UINT8 *saddr = NULL; UINT8 *pBuf_daddr = NULL; UINT8 *pBuf_saddr = NULL; /*Get the SA of pWtRxBuf */ w_hdr = (p80211_hdr_t*)&pWtRxBuf->RXHwBuf.pHwRxBuf->dot11Head; if ((WLAN_GET_FC_TODS(pWtRxBuf->FrmCtl) == 0) && (WLAN_GET_FC_FROMDS(pWtRxBuf->FrmCtl) == 0)) { daddr = w_hdr->a3.a1; saddr = w_hdr->a3.a2; } else if ((WLAN_GET_FC_TODS(pWtRxBuf->FrmCtl) == 0) && (WLAN_GET_FC_FROMDS(pWtRxBuf->FrmCtl) == 1)) { daddr = w_hdr->a3.a1; saddr = w_hdr->a3.a3; } else if ((WLAN_GET_FC_TODS(pWtRxBuf->FrmCtl) == 1) && (WLAN_GET_FC_FROMDS(pWtRxBuf->FrmCtl) == 0)) { daddr = w_hdr->a3.a3; saddr = w_hdr->a3.a2; } else { daddr = w_hdr->a4.a3; saddr = w_hdr->a4.a4; } #ifdef WIN_PLATFORM pBuf = (PWTWLAN_RXBUF) GetListTailEntry(pRecvFragList); #else //pEntry = &(pRecvFragList->prev); pEntry = pRecvFragList->prev;//edited by wl 2005.7.28 pBuf = list_entry(pEntry, WTWLAN_RXBUF, List); #endif while(pBuf != (PWTWLAN_RXBUF)pRecvFragList)//edited by wl 2005.7.28 { /*Get the SA of pBufferHeader*/ pBuf_hdr = (p80211_hdr_t*)&pBuf->RXHwBuf.pHwRxBuf->dot11Head; if ((WLAN_GET_FC_TODS(pBuf->FrmCtl) == 0) && (WLAN_GET_FC_FROMDS(pBuf->FrmCtl) == 0)) { pBuf_daddr = pBuf_hdr->a3.a1; pBuf_saddr = pBuf_hdr->a3.a2; } else if ((WLAN_GET_FC_TODS(pBuf->FrmCtl) == 0) && (WLAN_GET_FC_FROMDS(pBuf->FrmCtl) == 1)) { pBuf_daddr = pBuf_hdr->a3.a1; pBuf_saddr = pBuf_hdr->a3.a3; } else if ((WLAN_GET_FC_TODS(pBuf->FrmCtl) == 1) && (WLAN_GET_FC_FROMDS(pBuf->FrmCtl) == 0)) { pBuf_daddr = pBuf_hdr->a3.a3; pBuf_saddr = pBuf_hdr->a3.a2; } else { pBuf_daddr = pBuf_hdr->a4.a3; pBuf_saddr = pBuf_hdr->a4.a4; } /*judge the right one*/ //the function NdisEqualMemory must be replaced !!! 2002.6.22 /////////////////////////////////////////////////////////////////// #ifdef WIN_PLATFORM if(NdisEqualMemory(pBuf_saddr, saddr, WLAN_ADDR_LEN)) #else if(0 == memcmp(pBuf_saddr, saddr, WLAN_ADDR_LEN)) #endif { break; } else { #ifdef WIN_PLATFORM pBuf = (PWTWLAN_RXBUF) GetListTailEntry((PLIST_ENTRY) pBuf); #else pBuf = (PWTWLAN_RXBUF)(&(((struct list_head*)pBuf)->prev)); //pBuf = (PWTWLAN_RXBUF)((struct list_head*)pBuf)->prev; #endif } //////////////////////////////////////////////////////////////////// } if(pBuf == NULL) { return NULL; } else { return pBuf; }}BOOL DefragProcess(IN PWT_ADAPTER Adapter, IN PWTWLAN_RXBUF *ppWtRxBuf) // FALSE ---- fragment buffered or purged , free here // TRUE ----- not fragment or last // ppWtRxBuf --- msdu need process.{ // NICReturnRxBuf( Adapter, *ppWtRxBuf); UINT DataLength; PUCHAR pSrc; //PUCHAR pDest; //ULONGLONG Interval= 0; // ULONGLONG T_last=NULL; //PWTWLAN_RXBUF pBuf; // PWTWLAN_HWRXBUF payload; PWTWLAN_FRAG_ENTRY pFragStatus; p80211_hdr_t * w_hdr; //DBGPRINT(WT_LOUD, ("------->DefragProcess\n")); w_hdr = (p80211_hdr_t *)(&(*ppWtRxBuf)->RXHwBuf.pHwRxBuf->dot11Head); pFragStatus = &((*ppWtRxBuf)->FragStatus); // payload = *ppWtRxBuf->RXHwBuf.pHwRxBuf; pSrc = (*ppWtRxBuf)->RXHwBuf.pHwRxBuf->Buffer; //initial pSrc DataLength = ieee2host16( (*ppWtRxBuf)->RXHwBuf.pHwRxBuf->RxStatus.RecvBodyLen ); /* IF the Frame isn't fragment*/ //edited by hk 2004.12.27 //WLAN_GET_FC_MOREFRAG //if( WLAN_GET_FC_MOREFRAG(w_hdr->a3.fc) == 0 ) if( (WLAN_GET_FC_MOREFRAG(ieee2host16(w_hdr->a3.fc)) == 0) && (WLAN_GET_SEQ_FRGNUM(ieee2host16(w_hdr->a3.seq)) == 0) ) { FN_ENTER; FN_EXIT(0,0); return TRUE; } else { NICReturnRxBuf( Adapter, *ppWtRxBuf); //resease the RxBuffer return FALSE; }#if 0 else if(WLAN_GET_FC_MOREFRAG(w_hdr->a3.fc) == 0)//edited by hk 2004.12.27 { Dump( (*ppWtRxBuf)->RXHwBuf.pHwRxBuf, 150, TRUE, 1 ); /*check whether the first fragment has existed*/ pBuf = DefragMatch( &Adapter->RecvFragList,*ppWtRxBuf); if( pBuf == NULL ) { //////////////////////////////////////////////////////////////////// //InsertTailList( &(Adapter->RecvFragList),(PLIST_ENTRY)*ppWtRxBuf); //////////////////////////////////////////////////////////////////// pFragStatus->TFirstRxStart = (*ppWtRxBuf)->RXHwBuf.pHwRxBuf->RxStatus.RecvStartTime; pFragStatus->TFirstRxEnd = (*ppWtRxBuf)->RXHwBuf.pHwRxBuf->RxStatus.RecvEndTime; pFragStatus->TRxStart = pFragStatus->TFirstRxStart; pFragStatus->TRxEnd = pFragStatus->TFirstRxEnd; //DBGPRINT(WT_LOUD, ("<-------DefragProcess\n")); return FALSE; } else { NICReturnRxBuf( Adapter, *ppWtRxBuf); //resease the RxBuffer //return to the first place of RecvList //InsertTailList( &(Adapter->RecvList),(PLIST_ENTRY)*ppWtRxBuf);//edited by hk 2004.12.27 //DBGPRINT(WT_LOUD, ("<-------DefragProcess\n")); return FALSE; } } /*If the fragment isn't the first one,then search the Buffer matching to it*/ else { pBuf = DefragMatch(& Adapter->RecvFragList,*ppWtRxBuf); /* whether the fragment has existed*/ if((pBuf->FragStatus.RxMask >> (pFragStatus->FragIndex-1)) & 0x00000001) //32bits ? or 64bits? { NICReturnRxBuf( Adapter, *ppWtRxBuf); //resease the RxBuffer //return to the first place of RecvList //InsertTailList(&(Adapter->RecvList),(PLIST_ENTRY)*ppWtRxBuf);//edited by hk 2004.12.27 //DBGPRINT(WT_LOUD, ("<-------DefragProcess\n")); return FALSE; } else { /*check the interval between two fragment*/ // T_last = *ppWtRxBuf->FragStatus.TFirstRxStart; Interval = (*ppWtRxBuf)->RXHwBuf.pHwRxBuf->RxStatus.RecvStartTime - pBuf->FragStatus.TRxStart; ///////////////////////////////////////////////////////////////////////////////////////////// if( Interval > Adapter->Ndis80211Parameter.dot11MaxReceiveLifetime) { #if 0 NICReturnRxBuf( Adapter, *ppWtRxBuf); //resease the RxBuffer //return to the first place of RecvList //InsertTailList( &(Adapter->RecvList), (PLIST_ENTRY)*ppWtRxBuf);//edited by hk 2004.12.27 //remove the Buffer RemoveEntryList((PLIST_ENTRY) pBuf); #endif } ///////////////////////////////////////////////////////////////////////////////////////////// else { pDest = pBuf->RXHwBuf.pHwRxBuf->Buffer + pBuf->RXHwBuf.pHwRxBuf->RxStatus.RecvBodyLen; //edited by hk 2004.12.27 ///*process the last fragment*/ //if(pFragStatus->FragIndex == pBuf->FragStatus.FragNum) //{ // NdisMoveMemory( pDest, pSrc, DataLength); // NICReturnRxBuf( Adapter, *ppWtRxBuf); //resease the RxBuffer // //return to the first place of RecvList // //InsertTailList( &(Adapter->RecvList),(PLIST_ENTRY)*ppWtRxBuf);//edited by hk 2004.12.27 // return TRUE; //} /*process the last fragment*/ if(WLAN_GET_FC_MOREFRAG(w_hdr->a3.fc) == 0) { #ifdef WIN_PLATFORM NdisMoveMemory( pDest, pSrc, DataLength); #else memmove( pDest, pSrc, DataLength); #endif NICReturnRxBuf( Adapter, *ppWtRxBuf); //resease the RxBuffer //return to the first place of RecvList //InsertTailList( &(Adapter->RecvList),(PLIST_ENTRY)*ppWtRxBuf);//edited by hk 2004.12.27 //RemoveEntryList((PLIST_ENTRY) pBuf);//added by hk 2004.12.28 //DBGPRINT(WT_LOUD, ("<-------DefragProcess\n")); return TRUE; } /*process the middle fragment*/ else { #ifdef WIN_PLATFORM NdisMoveMemory( pDest, pSrc, DataLength); #else memmove( pDest, pSrc, DataLength); #endif //added by hk 2004.12.27 pBuf->FragStatus.TRxStart = (*ppWtRxBuf)->RXHwBuf.pHwRxBuf->RxStatus.RecvStartTime; pBuf->FragStatus.TRxEnd = (*ppWtRxBuf)->RXHwBuf.pHwRxBuf->RxStatus.RecvEndTime; pBuf->RXHwBuf.pHwRxBuf->RxStatus.RecvBodyLen += (*ppWtRxBuf)->RXHwBuf.pHwRxBuf->RxStatus.RecvBodyLen; return FALSE; } } } }#endif // if 0 return TRUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -