1/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 *
4 * This program is distributed in the hope that it will be useful, but WITHOUT
5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
7 * more details.
8 *
9 * You should have received a copy of the GNU General Public License along with
10 * this program; if not, write to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
12 *
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
15 *
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
18******************************************************************************/
19#include "rtllib.h"
20#include "rtl819x_HT.h"
21u8 MCS_FILTER_ALL[16] = {
22	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
23	0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
24};
25
26u8 MCS_FILTER_1SS[16] = {
27	0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
28	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
29;
30
31u16 MCS_DATA_RATE[2][2][77] = {
32	{{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234,
33	 260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416,
34	 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
35	 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
36	 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
37	 312, 351, 312, 351, 390, 390, 429},
38	{14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
39	 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
40	 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
41	 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
42	 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
43	 433, 433, 477} },
44	{{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
45	 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
46	 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
47	 378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324,
48	 378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648,
49	 729, 648, 729, 810, 810, 891},
50	{30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
51	 600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720,
52	 960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360,
53	 420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360,
54	 420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720,
55	 810, 720, 810, 900, 900, 990} }
56};
57
58static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
59
60static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
61
62static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
63
64static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};
65
66static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
67
68static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
69
70static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
71
72static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
73
74static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
75
76static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
77
78static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
79
80static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
81
82void HTUpdateDefaultSetting(struct rtllib_device *ieee)
83{
84	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
85
86	pHTInfo->bAcceptAddbaReq = 1;
87
88	pHTInfo->bRegShortGI20MHz = 1;
89	pHTInfo->bRegShortGI40MHz = 1;
90
91	pHTInfo->bRegBW40MHz = 1;
92
93	if (pHTInfo->bRegBW40MHz)
94		pHTInfo->bRegSuppCCK = 1;
95	else
96		pHTInfo->bRegSuppCCK = true;
97
98	pHTInfo->nAMSDU_MaxSize = 7935UL;
99	pHTInfo->bAMSDU_Support = 0;
100
101	pHTInfo->bAMPDUEnable = 1;
102	pHTInfo->AMPDU_Factor = 2;
103	pHTInfo->MPDU_Density = 0;
104
105	pHTInfo->SelfMimoPs = 3;
106	if (pHTInfo->SelfMimoPs == 2)
107		pHTInfo->SelfMimoPs = 3;
108	ieee->bTxDisableRateFallBack = 0;
109	ieee->bTxUseDriverAssingedRate = 0;
110
111	ieee->bTxEnableFwCalcDur = 1;
112
113	pHTInfo->bRegRT2RTAggregation = 1;
114
115	pHTInfo->bRegRxReorderEnable = 1;
116	pHTInfo->RxReorderWinSize = 64;
117	pHTInfo->RxReorderPendingTime = 30;
118}
119
120u16 HTMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate)
121{
122	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
123
124	u8	is40MHz = (pHTInfo->bCurBW40MHz) ? 1 : 0;
125	u8	isShortGI = (pHTInfo->bCurBW40MHz) ?
126			    ((pHTInfo->bCurShortGI40MHz) ? 1 : 0) :
127			    ((pHTInfo->bCurShortGI20MHz) ? 1 : 0);
128	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)];
129}
130
131u16  TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate)
132{
133	u16	CCKOFDMRate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18,
134				   0x24, 0x30, 0x48, 0x60, 0x6c};
135	u8	is40MHz = 0;
136	u8	isShortGI = 0;
137
138	if (nDataRate < 12)
139		return CCKOFDMRate[nDataRate];
140	if (nDataRate >= 0x10 && nDataRate <= 0x1f) {
141		is40MHz = 0;
142		isShortGI = 0;
143	} else if (nDataRate >= 0x20  && nDataRate <= 0x2f) {
144		is40MHz = 1;
145		isShortGI = 0;
146	} else if (nDataRate >= 0x30  && nDataRate <= 0x3f) {
147		is40MHz = 0;
148		isShortGI = 1;
149	} else if (nDataRate >= 0x40  && nDataRate <= 0x4f) {
150		is40MHz = 1;
151		isShortGI = 1;
152	}
153	return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
154}
155
156bool IsHTHalfNmodeAPs(struct rtllib_device *ieee)
157{
158	bool			retValue = false;
159	struct rtllib_network *net = &ieee->current_network;
160
161	if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
162	    (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
163	    (memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
164	    (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
165	    (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
166	    (net->ralink_cap_exist))
167		retValue = true;
168	else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
169		!memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
170		!memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ||
171		(net->broadcom_cap_exist))
172		retValue = true;
173	else if (net->bssht.bdRT2RTAggregation)
174		retValue = true;
175	else
176		retValue = false;
177
178	return retValue;
179}
180
181static void HTIOTPeerDetermine(struct rtllib_device *ieee)
182{
183	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
184	struct rtllib_network *net = &ieee->current_network;
185
186	if (net->bssht.bdRT2RTAggregation) {
187		pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
188		if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_92SE)
189			pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE;
190		if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_SOFTAP)
191			pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP;
192	} else if (net->broadcom_cap_exist)
193		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
194	else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
195		 !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
196		 !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3))
197		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
198	else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
199		 (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
200		 (memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
201		 (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
202		 (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
203		  net->ralink_cap_exist)
204		pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
205	else if ((net->atheros_cap_exist) ||
206		(memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) ||
207		(memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0))
208		pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
209	else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) ||
210		  net->cisco_cap_exist)
211		pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
212	else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
213		  net->marvell_cap_exist)
214		pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL;
215	else if (net->airgo_cap_exist)
216		pHTInfo->IOTPeer = HT_IOT_PEER_AIRGO;
217	else
218		pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
219
220	RTLLIB_DEBUG(RTLLIB_DL_IOT, "Joseph debug!! IOTPEER: %x\n",
221		     pHTInfo->IOTPeer);
222}
223
224static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr)
225{
226	return 0;
227}
228
229
230static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee)
231{
232	return false;
233}
234
235static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee)
236{
237	return false;
238}
239
240static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, u8 *PeerMacAddr)
241{
242	return false;
243}
244
245static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee,
246				 struct rtllib_network *network)
247{
248	u8	retValue = 0;
249
250
251	if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
252		retValue = 1;
253
254	return retValue;
255}
256
257static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee)
258{
259	u8	retValue = 0;
260
261	if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
262		retValue = 1;
263	return retValue;
264}
265
266static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss)
267{
268	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
269
270	pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL;
271
272	if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss)
273		pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R;
274
275	if (pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
276		pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU;
277
278}
279
280void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo)
281{
282	pHTInfo->IOTAction = 0;
283	pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
284	pHTInfo->IOTRaFunc = 0;
285}
286
287void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap,
288				  u8 *len, u8 IsEncrypt, bool bAssoc)
289{
290	struct rt_hi_throughput *pHT = ieee->pHTInfo;
291	struct ht_capab_ele *pCapELE = NULL;
292
293	if ((posHTCap == NULL) || (pHT == NULL)) {
294		RTLLIB_DEBUG(RTLLIB_DL_ERR,
295			     "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n");
296		return;
297	}
298	memset(posHTCap, 0, *len);
299
300	if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) {
301		u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
302
303		memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
304		pCapELE = (struct ht_capab_ele *)&(posHTCap[4]);
305		*len = 30 + 2;
306	} else {
307		pCapELE = (struct ht_capab_ele *)posHTCap;
308		*len = 26 + 2;
309	}
310
311	pCapELE->AdvCoding		= 0;
312	if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
313		pCapELE->ChlWidth = 0;
314	else
315		pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0);
316
317	pCapELE->MimoPwrSave		= pHT->SelfMimoPs;
318	pCapELE->GreenField		= 0;
319	pCapELE->ShortGI20Mhz		= 1;
320	pCapELE->ShortGI40Mhz		= 1;
321
322	pCapELE->TxSTBC			= 1;
323	pCapELE->RxSTBC			= 0;
324	pCapELE->DelayBA		= 0;
325	pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0;
326	pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0);
327	pCapELE->PSMP = 0;
328	pCapELE->LSigTxopProtect = 0;
329
330
331	RTLLIB_DEBUG(RTLLIB_DL_HT,
332		     "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n",
333		     pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
334
335	if (IsEncrypt) {
336		pCapELE->MPDUDensity	= 7;
337		pCapELE->MaxRxAMPDUFactor	= 2;
338	} else {
339		pCapELE->MaxRxAMPDUFactor	= 3;
340		pCapELE->MPDUDensity	= 0;
341	}
342
343	memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
344	memset(&pCapELE->ExtHTCapInfo, 0, 2);
345	memset(pCapELE->TxBFCap, 0, 4);
346
347	pCapELE->ASCap = 0;
348
349	if (bAssoc) {
350		if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
351			pCapELE->MCS[1] &= 0x7f;
352
353		if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
354			pCapELE->MCS[1] &= 0xbf;
355
356		if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
357			pCapELE->MCS[1] &= 0x00;
358
359		if (pHT->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI)
360			pCapELE->ShortGI40Mhz		= 0;
361
362		if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) {
363			pCapELE->ChlWidth = 0;
364			pCapELE->MCS[1] = 0;
365		}
366	}
367}
368
369void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo,
370			    u8 *len, u8 IsEncrypt)
371{
372	struct rt_hi_throughput *pHT = ieee->pHTInfo;
373	struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo;
374
375	if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) {
376		RTLLIB_DEBUG(RTLLIB_DL_ERR,
377			     "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n");
378		return;
379	}
380
381	memset(posHTInfo, 0, *len);
382	if ((ieee->iw_mode == IW_MODE_ADHOC) ||
383	    (ieee->iw_mode == IW_MODE_MASTER)) {
384		pHTInfoEle->ControlChl	= ieee->current_network.channel;
385		pHTInfoEle->ExtChlOffset = ((pHT->bRegBW40MHz == false) ?
386					    HT_EXTCHNL_OFFSET_NO_EXT :
387					    (ieee->current_network.channel <= 6)
388					    ? HT_EXTCHNL_OFFSET_UPPER :
389					    HT_EXTCHNL_OFFSET_LOWER);
390		pHTInfoEle->RecommemdedTxWidth	= pHT->bRegBW40MHz;
391		pHTInfoEle->RIFS			= 0;
392		pHTInfoEle->PSMPAccessOnly		= 0;
393		pHTInfoEle->SrvIntGranularity		= 0;
394		pHTInfoEle->OptMode			= pHT->CurrentOpMode;
395		pHTInfoEle->NonGFDevPresent		= 0;
396		pHTInfoEle->DualBeacon			= 0;
397		pHTInfoEle->SecondaryBeacon		= 0;
398		pHTInfoEle->LSigTxopProtectFull		= 0;
399		pHTInfoEle->PcoActive			= 0;
400		pHTInfoEle->PcoPhase			= 0;
401
402		memset(pHTInfoEle->BasicMSC, 0, 16);
403
404
405		*len = 22 + 2;
406
407	} else {
408		*len = 0;
409	}
410}
411
412void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg,
413				u8 *len)
414{
415	if (posRT2RTAgg == NULL) {
416		RTLLIB_DEBUG(RTLLIB_DL_ERR,
417			     "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n");
418		return;
419	}
420	memset(posRT2RTAgg, 0, *len);
421	*posRT2RTAgg++ = 0x00;
422	*posRT2RTAgg++ = 0xe0;
423	*posRT2RTAgg++ = 0x4c;
424	*posRT2RTAgg++ = 0x02;
425	*posRT2RTAgg++ = 0x01;
426
427	*posRT2RTAgg = 0x30;
428
429	if (ieee->bSupportRemoteWakeUp)
430		*posRT2RTAgg |= RT_HT_CAP_USE_WOW;
431
432	*len = 6 + 2;
433}
434
435static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS)
436{
437	u8 i;
438
439	if (pOperateMCS == NULL) {
440		RTLLIB_DEBUG(RTLLIB_DL_ERR,
441			     "pOperateMCS can't be null in HT_PickMCSRate()\n");
442		return false;
443	}
444
445	switch (ieee->mode) {
446	case IEEE_A:
447	case IEEE_B:
448	case IEEE_G:
449		for (i = 0; i <= 15; i++)
450			pOperateMCS[i] = 0;
451		break;
452	case IEEE_N_24G:
453	case IEEE_N_5G:
454		pOperateMCS[0] &= RATE_ADPT_1SS_MASK;
455		pOperateMCS[1] &= RATE_ADPT_2SS_MASK;
456		pOperateMCS[3] &= RATE_ADPT_MCS32_MASK;
457		break;
458	default:
459		break;
460
461	}
462
463	return true;
464}
465
466u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet,
467		       u8 *pMCSFilter)
468{
469	u8		i, j;
470	u8		bitMap;
471	u8		mcsRate = 0;
472	u8		availableMcsRate[16];
473
474	if (pMCSRateSet == NULL || pMCSFilter == NULL) {
475		RTLLIB_DEBUG(RTLLIB_DL_ERR,
476			     "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n");
477		return false;
478	}
479	for (i = 0; i < 16; i++)
480		availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
481
482	for (i = 0; i < 16; i++) {
483		if (availableMcsRate[i] != 0)
484			break;
485	}
486	if (i == 16)
487		return false;
488
489	for (i = 0; i < 16; i++) {
490		if (availableMcsRate[i] != 0) {
491			bitMap = availableMcsRate[i];
492			for (j = 0; j < 8; j++) {
493				if ((bitMap%2) != 0) {
494					if (HTMcsToDataRate(ieee, (8*i+j)) >
495					    HTMcsToDataRate(ieee, mcsRate))
496						mcsRate = (8*i+j);
497				}
498				bitMap >>= 1;
499			}
500		}
501	}
502	return mcsRate | 0x80;
503}
504
505u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS, u8 *pOperateMCS)
506{
507
508	u8 i;
509
510	for (i = 0; i <= 15; i++)
511		pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] &
512				 pSupportMCS[i];
513
514	HT_PickMCSRate(ieee, pOperateMCS);
515
516	if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
517		pOperateMCS[1] = 0;
518
519	for (i = 2; i <= 15; i++)
520		pOperateMCS[i] = 0;
521
522	return true;
523}
524
525void HTSetConnectBwMode(struct rtllib_device *ieee,
526			enum ht_channel_width Bandwidth,
527			enum ht_extchnl_offset Offset);
528
529void HTOnAssocRsp(struct rtllib_device *ieee)
530{
531	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
532	struct ht_capab_ele *pPeerHTCap = NULL;
533	struct ht_info_ele *pPeerHTInfo = NULL;
534	u16 nMaxAMSDUSize = 0;
535	u8 *pMcsFilter = NULL;
536
537	static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
538	static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};
539
540	if (pHTInfo->bCurrentHTSupport == false) {
541		RTLLIB_DEBUG(RTLLIB_DL_ERR,
542			     "<=== HTOnAssocRsp(): HT_DISABLE\n");
543		return;
544	}
545	RTLLIB_DEBUG(RTLLIB_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
546
547	if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap)))
548		pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]);
549	else
550		pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf);
551
552	if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
553		pPeerHTInfo = (struct ht_info_ele *)
554			     (&pHTInfo->PeerHTInfoBuf[4]);
555	else
556		pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf);
557
558	RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA | RTLLIB_DL_HT, pPeerHTCap,
559			  sizeof(struct ht_capab_ele));
560	HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth),
561			  (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset));
562	pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ?
563				 true : false);
564
565	pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ?
566				    ((pPeerHTCap->ShortGI20Mhz == 1) ?
567				    true : false) : false);
568	pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ?
569				     ((pPeerHTCap->ShortGI40Mhz == 1) ?
570				     true : false) : false);
571
572	pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ?
573			       ((pPeerHTCap->DssCCk == 1) ? true :
574			       false) : false);
575
576
577	pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
578
579	nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935;
580
581	if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize)
582		pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
583	else
584		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
585
586	pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
587	if (ieee->rtllib_ap_sec_type &&
588	   (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) {
589		if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) ||
590				(pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN))
591			pHTInfo->bCurrentAMPDUEnable = false;
592	}
593
594	if (!pHTInfo->bRegRT2RTAggregation) {
595		if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
596			pHTInfo->CurrentAMPDUFactor =
597						 pPeerHTCap->MaxRxAMPDUFactor;
598		else
599			pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
600
601	} else {
602		if (ieee->current_network.bssht.bdRT2RTAggregation) {
603			if (ieee->pairwise_key_type != KEY_TYPE_NA)
604				pHTInfo->CurrentAMPDUFactor =
605						 pPeerHTCap->MaxRxAMPDUFactor;
606			else
607				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
608		} else {
609			if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
610				pHTInfo->CurrentAMPDUFactor =
611						 pPeerHTCap->MaxRxAMPDUFactor;
612			else
613				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
614		}
615	}
616	if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
617		pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
618	else
619		pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
620	if (pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K) {
621		pHTInfo->bCurrentAMPDUEnable = false;
622		pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
623		pHTInfo->ForcedAMSDUMaxSize = 7935;
624	}
625	pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
626
627	if (pPeerHTCap->MCS[0] == 0)
628		pPeerHTCap->MCS[0] = 0xff;
629
630	HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0));
631
632	HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
633
634	pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
635	if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
636		pMcsFilter = MCS_FILTER_1SS;
637	else
638		pMcsFilter = MCS_FILTER_ALL;
639	ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee,
640				   ieee->dot11HTOperationalRateSet, pMcsFilter);
641	ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
642
643	pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
644}
645
646void HTInitializeHTInfo(struct rtllib_device *ieee)
647{
648	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
649
650	RTLLIB_DEBUG(RTLLIB_DL_HT, "===========>%s()\n", __func__);
651	pHTInfo->bCurrentHTSupport = false;
652
653	pHTInfo->bCurBW40MHz = false;
654	pHTInfo->bCurTxBW40MHz = false;
655
656	pHTInfo->bCurShortGI20MHz = false;
657	pHTInfo->bCurShortGI40MHz = false;
658	pHTInfo->bForcedShortGI = false;
659
660	pHTInfo->bCurSuppCCK = true;
661
662	pHTInfo->bCurrent_AMSDU_Support = false;
663	pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
664	pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
665	pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
666
667	memset((void *)(&(pHTInfo->SelfHTCap)), 0,
668		sizeof(pHTInfo->SelfHTCap));
669	memset((void *)(&(pHTInfo->SelfHTInfo)), 0,
670		sizeof(pHTInfo->SelfHTInfo));
671	memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0,
672		sizeof(pHTInfo->PeerHTCapBuf));
673	memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0,
674		sizeof(pHTInfo->PeerHTInfoBuf));
675
676	pHTInfo->bSwBwInProgress = false;
677	pHTInfo->ChnlOp = CHNLOP_NONE;
678
679	pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
680
681	pHTInfo->bCurrentRT2RTAggregation = false;
682	pHTInfo->bCurrentRT2RTLongSlotTime = false;
683	pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
684
685	pHTInfo->IOTPeer = 0;
686	pHTInfo->IOTAction = 0;
687	pHTInfo->IOTRaFunc = 0;
688
689	{
690		u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
691
692		RegHTSuppRateSets[0] = 0xFF;
693		RegHTSuppRateSets[1] = 0xFF;
694		RegHTSuppRateSets[4] = 0x01;
695	}
696}
697
698void HTInitializeBssDesc(struct bss_ht *pBssHT)
699{
700
701	pBssHT->bdSupportHT = false;
702	memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf));
703	pBssHT->bdHTCapLen = 0;
704	memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf));
705	pBssHT->bdHTInfoLen = 0;
706
707	pBssHT->bdHTSpecVer = HT_SPEC_VER_IEEE;
708
709	pBssHT->bdRT2RTAggregation = false;
710	pBssHT->bdRT2RTLongSlotTime = false;
711	pBssHT->RT2RT_HT_Mode = (enum rt_ht_capability)0;
712}
713
714void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee,
715				   struct rtllib_network *pNetwork)
716{
717	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
718	u8	bIOTAction = 0;
719
720	RTLLIB_DEBUG(RTLLIB_DL_HT, "==============>%s()\n", __func__);
721	/* unmark bEnableHT flag here is the same reason why unmarked in
722	 * function rtllib_softmac_new_net. WB 2008.09.10
723	 */
724	if (pNetwork->bssht.bdSupportHT) {
725		pHTInfo->bCurrentHTSupport = true;
726		pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer;
727
728		if (pNetwork->bssht.bdHTCapLen > 0 &&
729		    pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf))
730			memcpy(pHTInfo->PeerHTCapBuf,
731			       pNetwork->bssht.bdHTCapBuf,
732			       pNetwork->bssht.bdHTCapLen);
733
734		if (pNetwork->bssht.bdHTInfoLen > 0 &&
735		    pNetwork->bssht.bdHTInfoLen <=
736		    sizeof(pHTInfo->PeerHTInfoBuf))
737			memcpy(pHTInfo->PeerHTInfoBuf,
738			       pNetwork->bssht.bdHTInfoBuf,
739			       pNetwork->bssht.bdHTInfoLen);
740
741		if (pHTInfo->bRegRT2RTAggregation) {
742			pHTInfo->bCurrentRT2RTAggregation =
743				 pNetwork->bssht.bdRT2RTAggregation;
744			pHTInfo->bCurrentRT2RTLongSlotTime =
745				 pNetwork->bssht.bdRT2RTLongSlotTime;
746			pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.RT2RT_HT_Mode;
747		} else {
748			pHTInfo->bCurrentRT2RTAggregation = false;
749			pHTInfo->bCurrentRT2RTLongSlotTime = false;
750			pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
751		}
752
753		HTIOTPeerDetermine(ieee);
754
755		pHTInfo->IOTAction = 0;
756		bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
757		if (bIOTAction)
758			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
759
760		bIOTAction = HTIOTActIsDisableMCS15(ieee);
761		if (bIOTAction)
762			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
763
764		bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee);
765		if (bIOTAction)
766			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
767
768
769		bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
770		if (bIOTAction)
771			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
772
773		bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork);
774		if (bIOTAction)
775			pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
776		bIOTAction = HTIOTActIsCCDFsync(ieee);
777		if (bIOTAction)
778			pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
779	} else {
780		pHTInfo->bCurrentHTSupport = false;
781		pHTInfo->bCurrentRT2RTAggregation = false;
782		pHTInfo->bCurrentRT2RTLongSlotTime = false;
783		pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
784
785		pHTInfo->IOTAction = 0;
786		pHTInfo->IOTRaFunc = 0;
787	}
788}
789
790void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
791				     struct rtllib_network *pNetwork)
792{
793	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
794	struct ht_info_ele *pPeerHTInfo =
795		 (struct ht_info_ele *)pNetwork->bssht.bdHTInfoBuf;
796
797	if (pHTInfo->bCurrentHTSupport) {
798		if (pNetwork->bssht.bdHTInfoLen != 0)
799			pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
800	}
801}
802EXPORT_SYMBOL(HT_update_self_and_peer_setting);
803
804void HTUseDefaultSetting(struct rtllib_device *ieee)
805{
806	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
807
808	if (pHTInfo->bEnableHT) {
809		pHTInfo->bCurrentHTSupport = true;
810		pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK;
811
812		pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz;
813		pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz;
814
815		pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz;
816
817		if (ieee->iw_mode == IW_MODE_ADHOC)
818			ieee->current_network.qos_data.active =
819				 ieee->current_network.qos_data.supported;
820		pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
821		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
822
823		pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
824		pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
825
826		pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
827
828		HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet,
829				ieee->dot11HTOperationalRateSet);
830		ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee,
831					   ieee->dot11HTOperationalRateSet,
832					   MCS_FILTER_ALL);
833		ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
834
835	} else {
836		pHTInfo->bCurrentHTSupport = false;
837	}
838}
839
840u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame)
841{
842	if (ieee->pHTInfo->bCurrentHTSupport) {
843		if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) {
844			RTLLIB_DEBUG(RTLLIB_DL_HT,
845				     "HT CONTROL FILED EXIST!!\n");
846			return true;
847		}
848	}
849	return false;
850}
851
852static void HTSetConnectBwModeCallback(struct rtllib_device *ieee)
853{
854	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
855
856	RTLLIB_DEBUG(RTLLIB_DL_HT, "======>%s()\n", __func__);
857	if (pHTInfo->bCurBW40MHz) {
858		if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER)
859			ieee->set_chan(ieee->dev,
860				       ieee->current_network.channel + 2);
861		else if (pHTInfo->CurSTAExtChnlOffset ==
862			 HT_EXTCHNL_OFFSET_LOWER)
863			ieee->set_chan(ieee->dev,
864				       ieee->current_network.channel - 2);
865		else
866			ieee->set_chan(ieee->dev,
867				       ieee->current_network.channel);
868
869		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40,
870				       pHTInfo->CurSTAExtChnlOffset);
871	} else {
872		ieee->set_chan(ieee->dev, ieee->current_network.channel);
873		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20,
874				       HT_EXTCHNL_OFFSET_NO_EXT);
875	}
876
877	pHTInfo->bSwBwInProgress = false;
878}
879
880void HTSetConnectBwMode(struct rtllib_device *ieee,
881			enum ht_channel_width Bandwidth,
882			enum ht_extchnl_offset Offset)
883{
884	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
885
886	if (pHTInfo->bRegBW40MHz == false)
887		return;
888
889	if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
890		Bandwidth = HT_CHANNEL_WIDTH_20;
891
892	if (pHTInfo->bSwBwInProgress) {
893		pr_info("%s: bSwBwInProgress!!\n", __func__);
894		return;
895	}
896	if (Bandwidth == HT_CHANNEL_WIDTH_20_40) {
897		if (ieee->current_network.channel < 2 &&
898		    Offset == HT_EXTCHNL_OFFSET_LOWER)
899			Offset = HT_EXTCHNL_OFFSET_NO_EXT;
900		if (Offset == HT_EXTCHNL_OFFSET_UPPER ||
901		    Offset == HT_EXTCHNL_OFFSET_LOWER) {
902			pHTInfo->bCurBW40MHz = true;
903			pHTInfo->CurSTAExtChnlOffset = Offset;
904		} else {
905			pHTInfo->bCurBW40MHz = false;
906			pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
907		}
908	} else {
909		pHTInfo->bCurBW40MHz = false;
910		pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
911	}
912
913	pr_info("%s():pHTInfo->bCurBW40MHz:%x\n", __func__,
914	       pHTInfo->bCurBW40MHz);
915
916	pHTInfo->bSwBwInProgress = true;
917
918	HTSetConnectBwModeCallback(ieee);
919}
920