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():"
82430fb250902b7d563216077bc018108dd20cf8faMasanari Iida				     " Rx Reorder 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;
1463a6b70c3f3558a2e47d2ca82752f0aed0f3c33c6Matthew Casey
14794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	RTLLIB_DEBUG(RTLLIB_DL_TS, "==========>%s()\n", __func__);
14894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
14994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
15094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
15194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
152f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	for (count = 0; count < TOTAL_TS_NUM; count++) {
15394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pTxTS->num = count;
15494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TsCommonInfo.SetupTimer,
15594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsSetupTimeOut,
15694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
15794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
15894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TsCommonInfo.InactTimer,
15994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsInactTimeout,
16094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
16194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
16294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TsAddBaTimer,
16394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsAddBaProcess,
16494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
16594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
16694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TxPendingBARecord.Timer,
16794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    BaSetupTimeOut,
16894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
16994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pTxTS->TxAdmittedBARecord.Timer,
17094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TxBaInactTimeout,
17194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pTxTS);
17294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
17394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		ResetTxTsEntry(pTxTS);
17494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTxTS->TsCommonInfo.List,
17594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				&ieee->Tx_TS_Unused_List);
17694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pTxTS++;
17794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
17894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
17994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
18094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
18194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
182f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	for (count = 0; count < TOTAL_TS_NUM; count++) {
18394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pRxTS->num = count;
18494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		INIT_LIST_HEAD(&pRxTS->RxPendingPktList);
18594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
18694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pRxTS->TsCommonInfo.SetupTimer,
18794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsSetupTimeOut,
18894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pRxTS);
18994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
19094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pRxTS->TsCommonInfo.InactTimer,
19194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    TsInactTimeout,
19294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pRxTS);
19394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
19494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pRxTS->RxAdmittedBARecord.Timer,
19594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    RxBaInactTimeout,
19694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pRxTS);
19794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
19894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		_setup_timer(&pRxTS->RxPktPendingTimer,
19994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    RxPktPendingTimeout,
20094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			    (unsigned long) pRxTS);
20194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
20294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		ResetRxTsEntry(pRxTS);
203f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		list_add_tail(&pRxTS->TsCommonInfo.List,
204f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			      &ieee->Rx_TS_Unused_List);
20594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pRxTS++;
20694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
20794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
208f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	for (count = 0; count < REORDER_ENTRY_NUM; count++) {
209f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		list_add_tail(&pRxReorderEntry->List,
210f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			      &ieee->RxReorder_Unused_List);
21194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (count == (REORDER_ENTRY_NUM-1))
21294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
21394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pRxReorderEntry = &ieee->RxReorderEntry[count+1];
21494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
21594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
21694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
21794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
218ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void AdmitTS(struct rtllib_device *ieee,
219ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger		    struct ts_common_info *pTsCommonInfo, u32 InactTime)
22094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
22194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	del_timer_sync(&pTsCommonInfo->SetupTimer);
22294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	del_timer_sync(&pTsCommonInfo->InactTimer);
22394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
224f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (InactTime != 0)
225f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		mod_timer(&pTsCommonInfo->InactTimer, jiffies +
226f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			  MSECS(InactTime));
22794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
22894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
229ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
230ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger						  u8 *Addr, u8 TID,
231ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger						  enum tr_select TxRxSelect)
23294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
23394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8	dir;
234ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger	bool	search_dir[4] = {0};
235f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	struct list_head *psearch_list;
23674724de1c40192d74a213e615b945df8de935ca2Larry Finger	struct ts_common_info *pRet = NULL;
2373a6b70c3f3558a2e47d2ca82752f0aed0f3c33c6Matthew Casey
238f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (ieee->iw_mode == IW_MODE_MASTER) {
239f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (TxRxSelect == TX_DIR) {
24094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			search_dir[DIR_DOWN] = true;
241f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_BI_DIR] = true;
242f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		} else {
243f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_UP] = true;
244f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_BI_DIR] = true;
24594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
246f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
24794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (TxRxSelect == TX_DIR)
248f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_UP] = true;
24994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		else
25094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			search_dir[DIR_DOWN] = true;
251f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else {
252f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (TxRxSelect == TX_DIR) {
253f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_UP] = true;
254f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_BI_DIR] = true;
255f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_DIRECT] = true;
256f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		} else {
25794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			search_dir[DIR_DOWN] = true;
258f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_BI_DIR] = true;
259f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			search_dir[DIR_DIRECT] = true;
26094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
26194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
26294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
26394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (TxRxSelect == TX_DIR)
26494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		psearch_list = &ieee->Tx_TS_Admit_List;
26594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	else
26694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		psearch_list = &ieee->Rx_TS_Admit_List;
26794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
268f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	for (dir = 0; dir <= DIR_BI_DIR; dir++) {
2694bb01423ab05af02feaba04823ba6b852dbe5aa6Valentina Manea		if (!search_dir[dir])
27094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			continue;
271f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		list_for_each_entry(pRet, psearch_list, List) {
27294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			if (memcmp(pRet->Addr, Addr, 6) == 0)
27394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
27494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					if (pRet->TSpec.f.TSInfo.field.ucDirection == dir)
27594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger						break;
27694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
27794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
27894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (&pRet->List  != psearch_list)
27994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
28094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
28194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
282d7613e535e9892ff12aa31b3c62f1be839546ff9Larry Finger	if (pRet && &pRet->List  != psearch_list)
2836af197672f2330045c171aed3ea90fb93d89ecc6Mahati Chamarthy		return pRet;
28413402f7b76223e7f50ab42c82aac4788940c8277Mahati Chamarthy	return NULL;
28594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
28694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
287ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr,
288ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger			union tspec_body *pTSPEC, union qos_tclas *pTCLAS,
289ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger			u8 TCLAS_Num, u8 TCLAS_Proc)
29094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
29194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8	count;
29294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
29394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (pTsCommonInfo == NULL)
29494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return;
29594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
29694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	memcpy(pTsCommonInfo->Addr, Addr, 6);
29794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
29894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (pTSPEC != NULL)
299f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		memcpy((u8 *)(&(pTsCommonInfo->TSpec)), (u8 *)pTSPEC,
300f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			sizeof(union tspec_body));
30194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
30294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	for (count = 0; count < TCLAS_Num; count++)
303f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		memcpy((u8 *)(&(pTsCommonInfo->TClass[count])),
304f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		       (u8 *)pTCLAS, sizeof(union qos_tclas));
30594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
30694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTsCommonInfo->TClasProc = TCLAS_Proc;
30794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	pTsCommonInfo->TClasNum = TCLAS_Num;
30894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
30994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
310f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Fingerbool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
311f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	   u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs)
31294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
31394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	u8	UP = 0;
3143a6b70c3f3558a2e47d2ca82752f0aed0f3c33c6Matthew Casey
31514fc42355f10199f39bc38dd2d3e9288a31e770cJoe Perches	if (is_multicast_ether_addr(Addr)) {
316f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! get TS for Broadcast or "
317f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			     "Multicast\n");
31894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return false;
31994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
32094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	if (ieee->current_network.qos_data.supported == 0) {
32194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		UP = 0;
32294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	} else {
32394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (!IsACValid(TID)) {
324f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! in %s(), TID(%d) is "
325f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "not valid\n", __func__, TID);
32694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			return false;
32794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
32894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
32994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		switch (TID) {
33094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 0:
33194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 3:
33294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			UP = 0;
33394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
33494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 1:
33594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 2:
33694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			UP = 2;
33794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
33894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 4:
33994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 5:
34094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			UP = 5;
34194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
34294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 6:
34394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		case 7:
34494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			UP = 7;
34594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			break;
34694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
34794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
34894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
349f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	*ppTS = SearchAdmitTRStream(ieee, Addr, UP, TxRxSelect);
350f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (*ppTS != NULL) {
35194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		return true;
352f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else {
3534bb01423ab05af02feaba04823ba6b852dbe5aa6Valentina Manea		if (!bAddNewTs) {
354f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_TS, "add new TS failed"
355f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "(tid:%d)\n", UP);
35694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			return false;
357f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		} else {
358ed306e486d673a3ba4f9b0f2ab15afab0a6ba171Larry Finger			union tspec_body TSpec;
35942c53e7aaec108cf12431d6aca9ddac90b39d573Larry Finger			union qos_tsinfo *pTSInfo = &TSpec.f.TSInfo;
360f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			struct list_head *pUnusedList =
361f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(TxRxSelect == TX_DIR) ?
362f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(&ieee->Tx_TS_Unused_List) :
363f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(&ieee->Rx_TS_Unused_List);
364f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger
365f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			struct list_head *pAddmitList =
366f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(TxRxSelect == TX_DIR) ?
367f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(&ieee->Tx_TS_Admit_List) :
368f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(&ieee->Rx_TS_Admit_List);
369f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger
370f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			enum direction_value Dir =
371f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				 (ieee->iw_mode == IW_MODE_MASTER) ?
372f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				 ((TxRxSelect == TX_DIR) ? DIR_DOWN : DIR_UP) :
373f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				 ((TxRxSelect == TX_DIR) ? DIR_UP : DIR_DOWN);
37494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RTLLIB_DEBUG(RTLLIB_DL_TS, "to add Ts\n");
375f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			if (!list_empty(pUnusedList)) {
376f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				(*ppTS) = list_entry(pUnusedList->next,
377f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					  struct ts_common_info, List);
37894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				list_del_init(&(*ppTS)->List);
379f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				if (TxRxSelect == TX_DIR) {
380f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					struct tx_ts_record *tmp =
381f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						container_of(*ppTS,
382f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						struct tx_ts_record,
383f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						TsCommonInfo);
38494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					ResetTxTsEntry(tmp);
385f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				} else {
386f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					struct rx_ts_record *tmp =
387f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						 container_of(*ppTS,
388f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						 struct rx_ts_record,
389f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger						 TsCommonInfo);
39094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					ResetRxTsEntry(tmp);
39194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				}
39294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
393f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				RTLLIB_DEBUG(RTLLIB_DL_TS, "to init current TS"
394ac50ddaaeeca4f649c53ce31175aa68d26420138Larry Finger					     ", UP:%d, Dir:%d, addr: %pM"
395f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     " ppTs=%p\n", UP, Dir,
396ac50ddaaeeca4f649c53ce31175aa68d26420138Larry Finger					      Addr, *ppTS);
39794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucTrafficType = 0;
39894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucTSID = UP;
39994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucDirection = Dir;
40094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucAccessPolicy = 1;
40194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucAggregation = 0;
40294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucPSB = 0;
40394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucUP = UP;
40494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucTSInfoAckPolicy = 0;
40594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				pTSInfo->field.ucSchedule = 0;
40694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
40794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
40894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				AdmitTS(ieee, *ppTS, 0);
40994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				list_add_tail(&((*ppTS)->List), pAddmitList);
41094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
41194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				return true;
412f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			} else {
413f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!in function "
414f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     "%s() There is not enough dir=%d"
415f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     "(0=up down=1) TS record to be "
416f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					     "used!!", __func__, Dir);
41794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				return false;
41894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			}
41994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
42094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
42194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
42294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
423ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Fingerstatic void RemoveTsEntry(struct rtllib_device *ieee, struct ts_common_info *pTs,
424ec0dc6beea5436c037707dc0f501cf07878a8e2aLarry Finger			  enum tr_select TxRxSelect)
42594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
42694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	del_timer_sync(&pTs->SetupTimer);
42794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	del_timer_sync(&pTs->InactTimer);
42894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	TsInitDelBA(ieee, pTs, TxRxSelect);
42994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
430f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (TxRxSelect == RX_DIR) {
4318cba1432cee4c88668160750f1892aa09a2ba56aLarry Finger		struct rx_reorder_entry *pRxReorderEntry;
4322c47ae282a4bbaebfdbba614fb6133db520212baLarry Finger		struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs;
43394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
43494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		if (timer_pending(&pRxTS->RxPktPendingTimer))
43594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			del_timer_sync(&pRxTS->RxPktPendingTimer);
43694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
437f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		while (!list_empty(&pRxTS->RxPendingPktList)) {
438f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			pRxReorderEntry = (struct rx_reorder_entry *)
439f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					list_entry(pRxTS->RxPendingPktList.prev,
440f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger					struct rx_reorder_entry, List);
441f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Delete SeqNum "
442f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "%d!\n", __func__,
443f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     pRxReorderEntry->SeqNum);
44494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pRxReorderEntry->List);
44594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			{
44694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				int i = 0;
447f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				struct rtllib_rxb *prxb = pRxReorderEntry->prxb;
4483a6b70c3f3558a2e47d2ca82752f0aed0f3c33c6Matthew Casey
449f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				if (unlikely(!prxb))
45094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					return;
451f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				for (i = 0; i < prxb->nr_subframes; i++)
45294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger					dev_kfree_skb(prxb->subframes[i]);
45394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				kfree(prxb);
45494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger				prxb = NULL;
45594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			}
456f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			list_add_tail(&pRxReorderEntry->List,
457f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				      &ieee->RxReorder_Unused_List);
45894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
459f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else {
46060554f2bdb1579ca54631e99642025797f860eb7Larry Finger		struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs;
4613a6b70c3f3558a2e47d2ca82752f0aed0f3c33c6Matthew Casey
46294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		del_timer_sync(&pTxTS->TsAddBaTimer);
46394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
46494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
46594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
466f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Fingervoid RemovePeerTS(struct rtllib_device *ieee, u8 *Addr)
46794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
46874724de1c40192d74a213e615b945df8de935ca2Larry Finger	struct ts_common_info *pTS, *pTmpTS;
4693a6b70c3f3558a2e47d2ca82752f0aed0f3c33c6Matthew Casey
470ac50ddaaeeca4f649c53ce31175aa68d26420138Larry Finger	printk(KERN_INFO "===========>RemovePeerTS, %pM\n", Addr);
4714f6807e8d2e972393009830d305ecec2d80c0449Mike McCormack
472f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) {
473f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (memcmp(pTS->Addr, Addr, 6) == 0) {
47494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RemoveTsEntry(ieee, pTS, TX_DIR);
47594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pTS->List);
47694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
47794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
47894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
47994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
480f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) {
481f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (memcmp(pTS->Addr, Addr, 6) == 0) {
482f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			printk(KERN_INFO "====>remove Tx_TS_admin_list\n");
48394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RemoveTsEntry(ieee, pTS, TX_DIR);
48494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pTS->List);
48594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
48694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
48794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
48894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
489f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) {
490f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (memcmp(pTS->Addr, Addr, 6) == 0) {
49194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RemoveTsEntry(ieee, pTS, RX_DIR);
49294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pTS->List);
49394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
49494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
49594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
49694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
497f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) {
498f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (memcmp(pTS->Addr, Addr, 6) == 0) {
49994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			RemoveTsEntry(ieee, pTS, RX_DIR);
50094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_del_init(&pTS->List);
50194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
50294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
50394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
50494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
5053b28499c5519e59fbe9c2dea49ece5a3665be787Sean MacLennanEXPORT_SYMBOL(RemovePeerTS);
50694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
507f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Fingervoid RemoveAllTS(struct rtllib_device *ieee)
50894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
50974724de1c40192d74a213e615b945df8de935ca2Larry Finger	struct ts_common_info *pTS, *pTmpTS;
5104f6807e8d2e972393009830d305ecec2d80c0449Mike McCormack
511f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) {
51294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		RemoveTsEntry(ieee, pTS, TX_DIR);
51394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_del_init(&pTS->List);
51494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
51594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
51694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
517f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) {
51894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		RemoveTsEntry(ieee, pTS, TX_DIR);
51994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_del_init(&pTS->List);
52094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
52194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
52294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
523f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) {
52494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		RemoveTsEntry(ieee, pTS, RX_DIR);
52594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_del_init(&pTS->List);
52694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
52794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
52894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
529f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) {
53094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		RemoveTsEntry(ieee, pTS, RX_DIR);
53194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_del_init(&pTS->List);
53294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
53394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	}
53494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
53594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger
536f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Fingervoid TsStartAddBaProcess(struct rtllib_device *ieee, struct tx_ts_record *pTxTS)
53794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{
538f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	if (pTxTS->bAddBaReqInProgress == false) {
53994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		pTxTS->bAddBaReqInProgress = true;
5404f6807e8d2e972393009830d305ecec2d80c0449Mike McCormack
541f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		if (pTxTS->bAddBaReqDelayed) {
542f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_BA, "TsStartAddBaProcess(): "
543f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "Delayed Start ADDBA after 60 sec!!\n");
544f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			mod_timer(&pTxTS->TsAddBaTimer, jiffies +
545f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				  MSECS(TS_ADDBA_DELAY));
546f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		} else {
547f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			RTLLIB_DEBUG(RTLLIB_DL_BA, "TsStartAddBaProcess(): "
548f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger				     "Immediately Start ADDBA now!!\n");
54994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			mod_timer(&pTxTS->TsAddBaTimer, jiffies+10);
55094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		}
551f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger	} else
552f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger		RTLLIB_DEBUG(RTLLIB_DL_BA, "%s()==>BA timer is already added\n",
553f88ec6cbc1db3fbe5890250a37f5065506b5989cLarry Finger			     __func__);
55494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}
555