rtl819x_TSProc.c revision 3b28499c5519e59fbe9c2dea49ece5a3665be787
194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/******************************************************************************
294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * This program is distributed in the hope that it will be useful, but WITHOUT
594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * more details.
894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * You should have received a copy of the GNU General Public License along with
1094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * this program; if not, write to the Free Software Foundation, Inc.,
1194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
1294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
1394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * The full GNU General Public License is included in this distribution in the
1494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * file called LICENSE.
1594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *
1694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Contact Information:
1794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * wlanfae <wlanfae@realtek.com>
1894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger******************************************************************************/
1994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "rtllib.h"
2094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include <linux/etherdevice.h>
2194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "rtl819x_TS.h"
22cb76215448947ddcc133c4b1c2ff2d4a77e851e0Mike McCormack
23ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void TsSetupTimeOut(unsigned long data)
2494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
2594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
2694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
27ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void TsInactTimeout(unsigned long data)
2894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
2994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
3094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
31ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void RxPktPendingTimeout(unsigned long data)
3294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
332c47ae282a4bbaebfdbba614fb6133db520212baLarry Finger	struct rx_ts_record *pRxTs = (struct rx_ts_record *)data;
34f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device,
35f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						  RxTsRecord[pRxTs->num]);
3694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
378cba1432cee4c88668160750f1892aa09a2ba56aLarry Finger	struct rx_reorder_entry *pReorderEntry = NULL;
3894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
3994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	unsigned long flags = 0;
4094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8 index = 0;
4194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	bool bPktInBuf = false;
4294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
4394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
44f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (pRxTs->RxTimeoutIndicateSeq != 0xffff) {
45f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		while (!list_empty(&pRxTs->RxPendingPktList)) {
46f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			pReorderEntry = (struct rx_reorder_entry *)
47f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					list_entry(pRxTs->RxPendingPktList.prev,
48f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					struct rx_reorder_entry, List);
4994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			if (index == 0)
5094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;
5194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
52f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			if (SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) ||
53f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)) {
5494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				list_del_init(&pReorderEntry->List);
5594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
56f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				if (SN_EQUAL(pReorderEntry->SeqNum,
57f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				    pRxTs->RxIndicateSeq))
58f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					pRxTs->RxIndicateSeq =
59f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					      (pRxTs->RxIndicateSeq + 1) % 4096;
6094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
61f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate"
62f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     " SeqNum: %d\n", __func__,
63f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     pReorderEntry->SeqNum);
642eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger				ieee->stats_IndicateArray[index] =
65f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger							 pReorderEntry->prxb;
6694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				index++;
6794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
68f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				list_add_tail(&pReorderEntry->List,
69f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					      &ieee->RxReorder_Unused_List);
70f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			} else {
7194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				bPktInBuf = true;
7294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				break;
7394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			}
7494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
7594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
7694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
77f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (index > 0) {
7894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pRxTs->RxTimeoutIndicateSeq = 0xffff;
7994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
80f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (index > REORDER_WIN_SIZE) {
81f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():"
82f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     " Rx Reorer struct buffer full!!\n");
83f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			spin_unlock_irqrestore(&(ieee->reorder_spinlock),
84f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					       flags);
8594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			return;
8694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
872eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger		rtllib_indicate_packets(ieee, ieee->stats_IndicateArray, index);
8894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		bPktInBuf = false;
8994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
9094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
91f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (bPktInBuf && (pRxTs->RxTimeoutIndicateSeq == 0xffff)) {
9294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
93f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		mod_timer(&pRxTs->RxPktPendingTimer,  jiffies +
94f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			  MSECS(ieee->pHTInfo->RxReorderPendingTime));
9594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
9694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
9794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
9894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
99ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void TsAddBaProcess(unsigned long data)
10094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
10160554f2bdb1579ca54631e99642025797f860eb7Larry Finger	struct tx_ts_record *pTxTs = (struct tx_ts_record *)data;
10294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8 num = pTxTs->num;
103f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device,
104f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     TxTsRecord[num]);
10594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
10694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false);
107f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	RTLLIB_DEBUG(RTLLIB_DL_BA, "TsAddBaProcess(): ADDBA Req is "
108f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		     "started!!\n");
10994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
11094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
111ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo)
11294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
11394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	memset(pTsCommonInfo->Addr, 0, 6);
114ed306e486d673a3ba4f9b0f2ab15afab0a6ba171Larry Finger	memset(&pTsCommonInfo->TSpec, 0, sizeof(union tspec_body));
115626f951d76279823711fd0f9b876fafee39c3decLarry Finger	memset(&pTsCommonInfo->TClass, 0, sizeof(union qos_tclas)*TCLAS_NUM);
11694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTsCommonInfo->TClasProc = 0;
11794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTsCommonInfo->TClasNum = 0;
11894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
11994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
120ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void ResetTxTsEntry(struct tx_ts_record *pTS)
12194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
12294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	ResetTsCommonInfo(&pTS->TsCommonInfo);
12394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTS->TxCurSeq = 0;
12494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTS->bAddBaReqInProgress = false;
12594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTS->bAddBaReqDelayed = false;
12694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTS->bUsingBa = false;
12794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTS->bDisable_AddBa = false;
12894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	ResetBaEntry(&pTS->TxAdmittedBARecord);
12994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	ResetBaEntry(&pTS->TxPendingBARecord);
13094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
13194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
132ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void ResetRxTsEntry(struct rx_ts_record *pTS)
13394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
13494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	ResetTsCommonInfo(&pTS->TsCommonInfo);
13594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTS->RxIndicateSeq = 0xffff;
13694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTS->RxTimeoutIndicateSeq = 0xffff;
13794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	ResetBaEntry(&pTS->RxAdmittedBARecord);
13894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
13994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
14094a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid TSInitialize(struct rtllib_device *ieee)
14194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
14260554f2bdb1579ca54631e99642025797f860eb7Larry Finger	struct tx_ts_record *pTxTS  = ieee->TxTsRecord;
1432c47ae282a4bbaebfdbba614fb6133db520212baLarry Finger	struct rx_ts_record *pRxTS  = ieee->RxTsRecord;
1448cba1432cee4c88668160750f1892aa09a2ba56aLarry Finger	struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry;
14594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8				count = 0;
14694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	RTLLIB_DEBUG(RTLLIB_DL_TS, "==========>%s()\n", __func__);
14794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
14894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
14994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
15094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
151f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	for (count = 0; count < TOTAL_TS_NUM; count++) {
15294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pTxTS->num = count;
15394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TsCommonInfo.SetupTimer,
15494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsSetupTimeOut,
15594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
15694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
15794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TsCommonInfo.InactTimer,
15894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsInactTimeout,
15994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
16094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
16194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TsAddBaTimer,
16294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsAddBaProcess,
16394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
16494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
16594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TxPendingBARecord.Timer,
16694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    BaSetupTimeOut,
16794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
16894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TxAdmittedBARecord.Timer,
16994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TxBaInactTimeout,
17094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
17194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
17294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		ResetTxTsEntry(pTxTS);
17394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTxTS->TsCommonInfo.List,
17494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				&ieee->Tx_TS_Unused_List);
17594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pTxTS++;
17694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
17794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
17894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
17994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
18094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
181f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	for (count = 0; count < TOTAL_TS_NUM; count++) {
18294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pRxTS->num = count;
18394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		INIT_LIST_HEAD(&pRxTS->RxPendingPktList);
18494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
18594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pRxTS->TsCommonInfo.SetupTimer,
18694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsSetupTimeOut,
18794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pRxTS);
18894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
18994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pRxTS->TsCommonInfo.InactTimer,
19094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsInactTimeout,
19194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pRxTS);
19294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
19394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pRxTS->RxAdmittedBARecord.Timer,
19494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    RxBaInactTimeout,
19594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pRxTS);
19694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
19794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pRxTS->RxPktPendingTimer,
19894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    RxPktPendingTimeout,
19994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pRxTS);
20094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
20194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		ResetRxTsEntry(pRxTS);
202f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		list_add_tail(&pRxTS->TsCommonInfo.List,
203f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			      &ieee->Rx_TS_Unused_List);
20494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pRxTS++;
20594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
20694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
207f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	for (count = 0; count < REORDER_ENTRY_NUM; count++) {
208f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		list_add_tail(&pRxReorderEntry->List,
209f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			      &ieee->RxReorder_Unused_List);
21094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (count == (REORDER_ENTRY_NUM-1))
21194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
21294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pRxReorderEntry = &ieee->RxReorderEntry[count+1];
21394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
21494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
21594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
21694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
217ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void AdmitTS(struct rtllib_device *ieee,
218ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger		    struct ts_common_info *pTsCommonInfo, u32 InactTime)
21994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
22094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	del_timer_sync(&pTsCommonInfo->SetupTimer);
22194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	del_timer_sync(&pTsCommonInfo->InactTimer);
22294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
223f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (InactTime != 0)
224f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		mod_timer(&pTsCommonInfo->InactTimer, jiffies +
225f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			  MSECS(InactTime));
22694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
22794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
228ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
229ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger						  u8 *Addr, u8 TID,
230ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger						  enum tr_select TxRxSelect)
23194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
23294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8	dir;
233ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger	bool	search_dir[4] = {0};
234f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	struct list_head *psearch_list;
23574724de1c40192d74a213e615b945df8de935ca2Larry Finger	struct ts_common_info *pRet = NULL;
236f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (ieee->iw_mode == IW_MODE_MASTER) {
237f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (TxRxSelect == TX_DIR) {
23894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			search_dir[DIR_DOWN] = true;
239f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_BI_DIR] = true;
240f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		} else {
241f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_UP] = true;
242f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_BI_DIR] = true;
24394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
244f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
24594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (TxRxSelect == TX_DIR)
246f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_UP] = true;
24794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		else
24894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			search_dir[DIR_DOWN] = true;
249f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else {
250f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (TxRxSelect == TX_DIR) {
251f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_UP] = true;
252f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_BI_DIR] = true;
253f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_DIRECT] = true;
254f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		} else {
25594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			search_dir[DIR_DOWN] = true;
256f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_BI_DIR] = true;
257f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_DIRECT] = true;
25894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
25994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
26094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
26194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (TxRxSelect == TX_DIR)
26294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		psearch_list = &ieee->Tx_TS_Admit_List;
26394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	else
26494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		psearch_list = &ieee->Rx_TS_Admit_List;
26594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
266f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	for (dir = 0; dir <= DIR_BI_DIR; dir++) {
267f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (search_dir[dir] == false)
26894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			continue;
269f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		list_for_each_entry(pRet, psearch_list, List) {
27094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			if (memcmp(pRet->Addr, Addr, 6) == 0)
27194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
27294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					if (pRet->TSpec.f.TSInfo.field.ucDirection == dir)
27394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger						break;
27494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
27594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
27694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (&pRet->List  != psearch_list)
27794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
27894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
27994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
280d7613e535e9892ff12aa31b3c62f1be839546ff9Larry Finger	if (pRet && &pRet->List  != psearch_list)
28194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return pRet ;
28294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	else
28394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return NULL;
28494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
28594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
286ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr,
287ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger			union tspec_body *pTSPEC, union qos_tclas *pTCLAS,
288ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger			u8 TCLAS_Num, u8 TCLAS_Proc)
28994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
29094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8	count;
29194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
29294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (pTsCommonInfo == NULL)
29394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return;
29494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
29594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	memcpy(pTsCommonInfo->Addr, Addr, 6);
29694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
29794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (pTSPEC != NULL)
298f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		memcpy((u8 *)(&(pTsCommonInfo->TSpec)), (u8 *)pTSPEC,
299f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			sizeof(union tspec_body));
30094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
30194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	for (count = 0; count < TCLAS_Num; count++)
302f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		memcpy((u8 *)(&(pTsCommonInfo->TClass[count])),
303f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		       (u8 *)pTCLAS, sizeof(union qos_tclas));
30494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
30594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTsCommonInfo->TClasProc = TCLAS_Proc;
30694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTsCommonInfo->TClasNum = TCLAS_Num;
30794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
30894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
309f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Fingerbool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
310f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	   u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs)
31194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
31294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8	UP = 0;
313f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr)) {
314f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! get TS for Broadcast or "
315f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			     "Multicast\n");
31694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return false;
31794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
31894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (ieee->current_network.qos_data.supported == 0) {
31994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		UP = 0;
32094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	} else {
32194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (!IsACValid(TID)) {
322f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! in %s(), TID(%d) is "
323f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "not valid\n", __func__, TID);
32494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			return false;
32594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
32694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
32794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		switch (TID) {
32894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 0:
32994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 3:
33094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			UP = 0;
33194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
33294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 1:
33394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 2:
33494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			UP = 2;
33594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
33694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 4:
33794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 5:
33894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			UP = 5;
33994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
34094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 6:
34194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 7:
34294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			UP = 7;
34394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
34494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
34594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
34694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
347f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	*ppTS = SearchAdmitTRStream(ieee, Addr, UP, TxRxSelect);
348f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (*ppTS != NULL) {
34994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return true;
350f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else {
351f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (bAddNewTs == false) {
352f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_TS, "add new TS failed"
353f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "(tid:%d)\n", UP);
35494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			return false;
355f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		} else {
356ed306e486d673a3ba4f9b0f2ab15afab0a6ba171Larry Finger			union tspec_body TSpec;
35742c53e7aaec108cf12431d6aca9ddac90b39d573Larry Finger			union qos_tsinfo *pTSInfo = &TSpec.f.TSInfo;
358f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			struct list_head *pUnusedList =
359f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(TxRxSelect == TX_DIR) ?
360f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(&ieee->Tx_TS_Unused_List) :
361f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(&ieee->Rx_TS_Unused_List);
362f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger
363f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			struct list_head *pAddmitList =
364f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(TxRxSelect == TX_DIR) ?
365f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(&ieee->Tx_TS_Admit_List) :
366f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(&ieee->Rx_TS_Admit_List);
367f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger
368f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			enum direction_value Dir =
369f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				 (ieee->iw_mode == IW_MODE_MASTER) ?
370f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				 ((TxRxSelect == TX_DIR) ? DIR_DOWN : DIR_UP) :
371f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				 ((TxRxSelect == TX_DIR) ? DIR_UP : DIR_DOWN);
37294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RTLLIB_DEBUG(RTLLIB_DL_TS, "to add Ts\n");
373f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			if (!list_empty(pUnusedList)) {
374f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(*ppTS) = list_entry(pUnusedList->next,
375f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					  struct ts_common_info, List);
37694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				list_del_init(&(*ppTS)->List);
377f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				if (TxRxSelect == TX_DIR) {
378f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					struct tx_ts_record *tmp =
379f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						container_of(*ppTS,
380f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						struct tx_ts_record,
381f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						TsCommonInfo);
38294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					ResetTxTsEntry(tmp);
383f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				} else {
384f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					struct rx_ts_record *tmp =
385f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						 container_of(*ppTS,
386f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						 struct rx_ts_record,
387f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						 TsCommonInfo);
38894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					ResetRxTsEntry(tmp);
38994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				}
39094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
391f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				RTLLIB_DEBUG(RTLLIB_DL_TS, "to init current TS"
392ac50ddaaeeca4f649c53ce31175aa68d26420138Larry Finger					     ", UP:%d, Dir:%d, addr: %pM"
393f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     " ppTs=%p\n", UP, Dir,
394ac50ddaaeeca4f649c53ce31175aa68d26420138Larry Finger					      Addr, *ppTS);
39594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucTrafficType = 0;
39694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucTSID = UP;
39794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucDirection = Dir;
39894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucAccessPolicy = 1;
39994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucAggregation = 0;
40094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucPSB = 0;
40194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucUP = UP;
40294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucTSInfoAckPolicy = 0;
40394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucSchedule = 0;
40494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
40594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
40694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				AdmitTS(ieee, *ppTS, 0);
40794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				list_add_tail(&((*ppTS)->List), pAddmitList);
40894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
40994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				return true;
410f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			} else {
411f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!in function "
412f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     "%s() There is not enough dir=%d"
413f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     "(0=up down=1) TS record to be "
414f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     "used!!", __func__, Dir);
41594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				return false;
41694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			}
41794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
41894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
41994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
42094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
421ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void RemoveTsEntry(struct rtllib_device *ieee, struct ts_common_info *pTs,
422ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger			  enum tr_select TxRxSelect)
42394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
42494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	del_timer_sync(&pTs->SetupTimer);
42594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	del_timer_sync(&pTs->InactTimer);
42694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	TsInitDelBA(ieee, pTs, TxRxSelect);
42794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
428f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (TxRxSelect == RX_DIR) {
4298cba1432cee4c88668160750f1892aa09a2ba56aLarry Finger		struct rx_reorder_entry *pRxReorderEntry;
4302c47ae282a4bbaebfdbba614fb6133db520212baLarry Finger		struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs;
43194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
43294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (timer_pending(&pRxTS->RxPktPendingTimer))
43394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			del_timer_sync(&pRxTS->RxPktPendingTimer);
43494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
435f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		while (!list_empty(&pRxTS->RxPendingPktList)) {
436f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			pRxReorderEntry = (struct rx_reorder_entry *)
437f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					list_entry(pRxTS->RxPendingPktList.prev,
438f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					struct rx_reorder_entry, List);
439f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Delete SeqNum "
440f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "%d!\n", __func__,
441f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     pRxReorderEntry->SeqNum);
44294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pRxReorderEntry->List);
44394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			{
44494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				int i = 0;
445f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				struct rtllib_rxb *prxb = pRxReorderEntry->prxb;
446f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				if (unlikely(!prxb))
44794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					return;
448f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				for (i = 0; i < prxb->nr_subframes; i++)
44994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					dev_kfree_skb(prxb->subframes[i]);
45094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				kfree(prxb);
45194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				prxb = NULL;
45294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			}
453f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			list_add_tail(&pRxReorderEntry->List,
454f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				      &ieee->RxReorder_Unused_List);
45594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
456f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else {
45760554f2bdb1579ca54631e99642025797f860eb7Larry Finger		struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs;
45894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		del_timer_sync(&pTxTS->TsAddBaTimer);
45994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
46094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
46194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
462f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Fingervoid RemovePeerTS(struct rtllib_device *ieee, u8 *Addr)
46394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
46474724de1c40192d74a213e615b945df8de935ca2Larry Finger	struct ts_common_info *pTS, *pTmpTS;
465ac50ddaaeeca4f649c53ce31175aa68d26420138Larry Finger	printk(KERN_INFO "===========>RemovePeerTS, %pM\n", Addr);
4664f6807e8d2e972393009830d305ecec2d80c0449Mike McCormack
467f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) {
468f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (memcmp(pTS->Addr, Addr, 6) == 0) {
46994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RemoveTsEntry(ieee, pTS, TX_DIR);
47094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pTS->List);
47194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
47294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
47394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
47494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
475f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) {
476f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (memcmp(pTS->Addr, Addr, 6) == 0) {
477f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			printk(KERN_INFO "====>remove Tx_TS_admin_list\n");
47894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RemoveTsEntry(ieee, pTS, TX_DIR);
47994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pTS->List);
48094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
48194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
48294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
48394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
484f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) {
485f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (memcmp(pTS->Addr, Addr, 6) == 0) {
48694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RemoveTsEntry(ieee, pTS, RX_DIR);
48794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pTS->List);
48894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
48994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
49094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
49194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
492f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) {
493f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (memcmp(pTS->Addr, Addr, 6) == 0) {
49494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RemoveTsEntry(ieee, pTS, RX_DIR);
49594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pTS->List);
49694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
49794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
49894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
49994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
5003b28499c5519e59fbe9c2dea49ece5a3665be787Sean MacLennanEXPORT_SYMBOL(RemovePeerTS);
50194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
502f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Fingervoid RemoveAllTS(struct rtllib_device *ieee)
50394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
50474724de1c40192d74a213e615b945df8de935ca2Larry Finger	struct ts_common_info *pTS, *pTmpTS;
5054f6807e8d2e972393009830d305ecec2d80c0449Mike McCormack
506f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) {
50794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		RemoveTsEntry(ieee, pTS, TX_DIR);
50894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_del_init(&pTS->List);
50994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
51094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
51194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
512f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) {
51394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		RemoveTsEntry(ieee, pTS, TX_DIR);
51494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_del_init(&pTS->List);
51594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
51694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
51794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
518f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) {
51994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		RemoveTsEntry(ieee, pTS, RX_DIR);
52094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_del_init(&pTS->List);
52194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
52294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
52394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
524f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) {
52594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		RemoveTsEntry(ieee, pTS, RX_DIR);
52694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_del_init(&pTS->List);
52794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
52894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
52994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
53094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
531f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Fingervoid TsStartAddBaProcess(struct rtllib_device *ieee, struct tx_ts_record *pTxTS)
53294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
533f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (pTxTS->bAddBaReqInProgress == false) {
53494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pTxTS->bAddBaReqInProgress = true;
5354f6807e8d2e972393009830d305ecec2d80c0449Mike McCormack
536f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (pTxTS->bAddBaReqDelayed) {
537f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_BA, "TsStartAddBaProcess(): "
538f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "Delayed Start ADDBA after 60 sec!!\n");
539f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			mod_timer(&pTxTS->TsAddBaTimer, jiffies +
540f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				  MSECS(TS_ADDBA_DELAY));
541f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		} else {
542f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_BA, "TsStartAddBaProcess(): "
543f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "Immediately Start ADDBA now!!\n");
54494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			mod_timer(&pTxTS->TsAddBaTimer, jiffies+10);
54594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
546f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else
547f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		RTLLIB_DEBUG(RTLLIB_DL_BA, "%s()==>BA timer is already added\n",
548f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			     __func__);
54994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
550