• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/rtl8192su/ieee80211/
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 "ieee80211.h"
20#include "rtl819x_HT.h"
21u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
22
23u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
24
25u16 MCS_DATA_RATE[2][2][77] =
26	{	{	{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260,
27			39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520,
28			0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195,
29			195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260,
30			286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429},
31			{14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
32			43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578,
33			0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217,
34			217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289,
35			318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477}	},
36		{	{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540,
37			81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080,
38			12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405,
39			405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540,
40			594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891},
41			{30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600,
42			90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200,
43			13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450,
44			450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600,
45			660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990}	}
46	};
47
48static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
49static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
50static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
51static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};
52static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
53static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
54static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
55static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
56static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
57static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
58static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
59static u8 NETGEAR_BROADCOM[3] = {0x00, 0x1f, 0x33};
60static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
61
62/********************************************************************************************************************
63 *function:  This function update default settings in pHTInfo structure
64 *   input:  PRT_HIGH_THROUGHPUT	pHTInfo
65 *  output:  none
66 *  return:  none
67 *  notice:  These value need be modified if any changes.
68 * *****************************************************************************************************************/
69void HTUpdateDefaultSetting(struct ieee80211_device* ieee)
70{
71	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
72
73	// ShortGI support
74	pHTInfo->bRegShortGI20MHz= 1;
75	pHTInfo->bRegShortGI40MHz= 1;
76
77	// 40MHz channel support
78	pHTInfo->bRegBW40MHz = 1;
79
80	// CCK rate support in 40MHz channel
81	if(pHTInfo->bRegBW40MHz)
82		pHTInfo->bRegSuppCCK = 1;
83	else
84		pHTInfo->bRegSuppCCK = true;
85
86	// AMSDU related
87	pHTInfo->nAMSDU_MaxSize = 7935UL;
88	pHTInfo->bAMSDU_Support = 0;
89
90	// AMPDU related
91	pHTInfo->bAMPDUEnable = 1; //YJ,test,090311
92	pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k)
93	pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec
94
95	// MIMO Power Save
96	pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.)
97	if(pHTInfo->SelfMimoPs == 2)
98		pHTInfo->SelfMimoPs = 3;
99	// 8190 only. Assign rate operation mode to firmware
100	ieee->bTxDisableRateFallBack = 0;
101	ieee->bTxUseDriverAssingedRate = 0;
102
103#ifdef 	TO_DO_LIST
104	// 8190 only. Assign duration operation mode to firmware
105	pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur;
106#endif
107	// 8190 only, Realtek proprietary aggregation mode
108	// Set MPDUDensity=2,   1: Set MPDUDensity=2(32k)  for Realtek AP and set MPDUDensity=0(8k) for others
109	pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2,   1: Set MPDUDensity=2(32k)  for Realtek AP and set MPDUDensity=0(8k) for others
110
111	// For Rx Reorder Control
112	pHTInfo->bRegRxReorderEnable = 1;//YJ,test,090311
113	pHTInfo->RxReorderWinSize = 64;
114	pHTInfo->RxReorderPendingTime = 30;
115
116
117
118}
119/********************************************************************************************************************
120 *function:  This function print out each field on HT capability IE mainly from (Beacon/ProbeRsp/AssocReq)
121 *   input:  u8*	CapIE       //Capability IE to be printed out
122 *   	     u8* 	TitleString //mainly print out caller function
123 *  output:  none
124 *  return:  none
125 *  notice:  Driver should not print out this message by default.
126 * *****************************************************************************************************************/
127void HTDebugHTCapability(u8* CapIE, u8* TitleString )
128{
129
130	static u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};	// For 11n EWC definition, 2007.07.17, by Emily
131	PHT_CAPABILITY_ELE 		pCapELE;
132
133	if(!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap)))
134	{
135		//EWC IE
136		IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
137		pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]);
138	}else
139		pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]);
140
141	IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Capability>. Called by %s\n", TitleString );
142
143	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth)?"20MHz": "20/40MHz");
144	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz)?"YES": "NO");
145	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz)?"YES": "NO");
146	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC)?"YES": "NO");
147	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize)?"3839": "7935");
148	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk)?"YES": "NO");
149	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor);
150	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMPDU Density = %d\n", pCapELE->MPDUDensity);
151	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\
152				pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]);
153	return;
154
155}
156/********************************************************************************************************************
157 *function:  This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp)
158 *   input:  u8*	InfoIE       //Capability IE to be printed out
159 *   	     u8* 	TitleString //mainly print out caller function
160 *  output:  none
161 *  return:  none
162 *  notice:  Driver should not print out this message by default.
163 * *****************************************************************************************************************/
164void HTDebugHTInfo(u8*	InfoIE, u8* TitleString)
165{
166
167	static u8	EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};	// For 11n EWC definition, 2007.07.17, by Emily
168	PHT_INFORMATION_ELE		pHTInfoEle;
169
170	if(!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
171	{
172		// Not EWC IE
173		IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
174		pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]);
175	}else
176		pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]);
177
178
179	IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Information Element>. Called by %s\n", TitleString);
180
181	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl);
182	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel =");
183	switch(pHTInfoEle->ExtChlOffset)
184	{
185		case 0:
186			IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n");
187			break;
188		case 1:
189			IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n");
190			break;
191		case 2:
192			IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n");
193			break;
194		case 3:
195			IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n");
196			break;
197	}
198	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth)?"20Mhz": "40Mhz");
199
200	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = ");
201	switch(pHTInfoEle->OptMode)
202	{
203		case 0:
204			IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n");
205			break;
206		case 1:
207			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n");
208			break;
209		case 2:
210			IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n");
211			break;
212		case 3:
213			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n");
214			break;
215	}
216
217	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\
218				pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]);
219	return;
220}
221
222/*
223*	Return:     	true if station in half n mode and AP supports 40 bw
224*/
225bool IsHTHalfNmode40Bandwidth(struct ieee80211_device* ieee)
226{
227	bool			retValue = false;
228	PRT_HIGH_THROUGHPUT	 pHTInfo = ieee->pHTInfo;
229
230	if(pHTInfo->bCurrentHTSupport == false )	// wireless is n mode
231		retValue = false;
232	else if(pHTInfo->bRegBW40MHz == false)	// station supports 40 bw
233		retValue = false;
234	else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 	// station in half n mode
235		retValue = false;
236	else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw
237		retValue = true;
238	else
239		retValue = false;
240
241	return retValue;
242}
243
244bool IsHTHalfNmodeSGI(struct ieee80211_device* ieee, bool is40MHz)
245{
246	bool			retValue = false;
247	PRT_HIGH_THROUGHPUT	 pHTInfo = ieee->pHTInfo;
248
249	if(pHTInfo->bCurrentHTSupport == false )	// wireless is n mode
250		retValue = false;
251	else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 	// station in half n mode
252		retValue = false;
253	else if(is40MHz) // ap support 40 bw
254	{
255		if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI
256			retValue = true;
257		else
258			retValue = false;
259	}
260	else
261	{
262		if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI
263			retValue = true;
264		else
265			retValue = false;
266	}
267
268	return retValue;
269}
270
271u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, 	u8	nMcsRate)
272{
273
274	u8	is40MHz;
275	u8	isShortGI;
276
277	is40MHz  =  (IsHTHalfNmode40Bandwidth(ieee))?1:0;
278	isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz))? 1:0;
279
280	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
281}
282
283
284u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate)
285{
286	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
287
288	u8	is40MHz = (pHTInfo->bCurBW40MHz)?1:0;
289	u8	isShortGI = (pHTInfo->bCurBW40MHz)?
290						((pHTInfo->bCurShortGI40MHz)?1:0):
291						((pHTInfo->bCurShortGI20MHz)?1:0);
292	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
293}
294
295/********************************************************************************************************************
296 *function:  This function returns current datarate.
297 *   input:  struct ieee80211_device* 	ieee
298 *   	     u8 			nDataRate
299 *  output:  none
300 *  return:  tx rate
301 *  notice:  quite unsure about how to use this function //wb
302 * *****************************************************************************************************************/
303u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate)
304{
305	u16		CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c};
306	u8	is40MHz = 0;
307	u8	isShortGI = 0;
308
309	if(nDataRate < 12)
310	{
311		return CCKOFDMRate[nDataRate];
312	}
313	else
314	{
315		if (nDataRate >= 0x10 && nDataRate <= 0x1f)//if(nDataRate > 11 && nDataRate < 28 )
316		{
317			is40MHz = 0;
318			isShortGI = 0;
319
320		}
321		else if(nDataRate >=0x20  && nDataRate <= 0x2f ) //(27, 44)
322		{
323			is40MHz = 1;
324			isShortGI = 0;
325
326		}
327		else if(nDataRate >= 0x30  && nDataRate <= 0x3f )  //(43, 60)
328		{
329			is40MHz = 0;
330			isShortGI = 1;
331
332		}
333		else if(nDataRate >= 0x40  && nDataRate <= 0x4f ) //(59, 76)
334		{
335			is40MHz = 1;
336			isShortGI = 1;
337
338		}
339		return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
340	}
341}
342
343
344
345bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
346{
347	bool			retValue = false;
348	struct ieee80211_network* net = &ieee->current_network;
349
350	if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
351		     (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
352		     (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
353		     (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
354		     (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
355		     (net->ralink_cap_exist))
356		retValue = true;
357	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
358    		    (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
359    		    (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
360    		    (net->broadcom_cap_exist))
361    		  retValue = true;
362	else if(net->bssht.bdRT2RTAggregation)
363		retValue = true;
364	else
365		retValue = false;
366
367	return retValue;
368}
369
370/********************************************************************************************************************
371 *function:  This function returns peer IOT.
372 *   input:  struct ieee80211_device* 	ieee
373 *  output:  none
374 *  return:
375 *  notice:
376 * *****************************************************************************************************************/
377void HTIOTPeerDetermine(struct ieee80211_device* ieee)
378{
379	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
380	struct ieee80211_network* net = &ieee->current_network;
381	if(net->bssht.bdRT2RTAggregation){
382		pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
383		if(net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_92SE){
384			pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE;
385		}
386		if(net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_SOFTAP){
387			pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP;
388		}
389	}
390	else if(net->broadcom_cap_exist)
391		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
392	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
393			(memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
394			(memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0))
395		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
396	else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
397			(memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
398			(memcmp(net->bssid, PCI_RALINK, 3)==0) ||
399			(memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
400			(memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
401			 net->ralink_cap_exist)
402		pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
403	else if((net->atheros_cap_exist )||
404		(memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0)||
405		(memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0))
406		pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
407	else if ((memcmp(net->bssid, CISCO_BROADCOM, 3)==0)||net->cisco_cap_exist)
408		pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
409	else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
410		  net->marvell_cap_exist)
411		pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL;
412	else
413		pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
414
415	IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer);
416}
417/********************************************************************************************************************
418 *function:  Check whether driver should declare received rate up to MCS13 only since some chipset is not good
419 *	     at receiving MCS14~15 frame from some AP.
420 *   input:  struct ieee80211_device* 	ieee
421 *   	     u8 *			PeerMacAddr
422 *  output:  none
423 *  return:  return 1 if driver should declare MCS13 only(otherwise return 0)
424  * *****************************************************************************************************************/
425u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
426{
427	u8 ret = 0;
428
429	return ret;
430 }
431
432
433/**
434* Function:	HTIOTActIsDisableMCS15
435*
436* Overview:	Check whether driver should declare capability of receving MCS15
437*
438* Input:
439*			PADAPTER		Adapter,
440*
441* Output:		None
442* Return:     	true if driver should disable MCS15
443* 2008.04.15	Emily
444*/
445bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee)
446{
447	bool retValue = false;
448	return retValue;
449}
450
451/**
452* Function:	HTIOTActIsDisableMCSTwoSpatialStream
453*
454* Overview:	Check whether driver should declare capability of receving All 2 ss packets
455*
456* Input:
457*		PADAPTER		Adapter,
458*
459* Output:	None
460* Return:     	true if driver should disable all two spatial stream packet
461* 2008.04.21	Emily
462*/
463bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee)
464{
465	bool retValue = false;
466#ifdef TODO
467	// Apply for 819u only
468//#if (HAL_CODE_BASE==RTL8192)
469
470	//This rule only apply to Belkin(Ralink) AP
471	if(IS_UNDER_11N_AES_MODE(Adapter))
472	{
473		if((PlatformCompareMemory(PeerMacAddr, BELKINF5D8233V1_RALINK, 3)==0) ||
474				(PlatformCompareMemory(PeerMacAddr, PCI_RALINK, 3)==0) ||
475				(PlatformCompareMemory(PeerMacAddr, EDIMAX_RALINK, 3)==0))
476		{
477			//Set True to disable this function. Disable by default, Emily, 2008.04.23
478			retValue = false;
479		}
480	}
481
482//#endif
483#endif
484       PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
485	if(ieee->is_ap_in_wep_tkip && ieee->is_ap_in_wep_tkip(ieee->dev))
486	{
487		if( (pHTInfo->IOTPeer != HT_IOT_PEER_ATHEROS) &&
488		    (pHTInfo->IOTPeer != HT_IOT_PEER_UNKNOWN) &&
489		    (pHTInfo->IOTPeer != HT_IOT_PEER_MARVELL) )
490			retValue = true;
491	}
492	return retValue;
493}
494
495/********************************************************************************************************************
496 *function:  Check whether driver should disable EDCA turbo mode
497 *   input:  struct ieee80211_device* 	ieee
498 *   	     u8* 			PeerMacAddr
499 *  output:  none
500 *  return:  return 1 if driver should disable EDCA turbo mode(otherwise return 0)
501  * *****************************************************************************************************************/
502u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device* 	ieee, u8* PeerMacAddr)
503{
504	u8	retValue = false;	// default enable EDCA Turbo mode.
505	// Set specific EDCA parameter for different AP in DM handler.
506
507	return retValue;
508}
509
510/********************************************************************************************************************
511 *function:  Check whether we need to use OFDM to sned MGNT frame for broadcom AP
512 *   input:  struct ieee80211_network *network   //current network we live
513 *  output:  none
514 *  return:  return 1 if true
515  * *****************************************************************************************************************/
516u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network)
517{
518	u8	retValue = 0;
519
520	// 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP.
521	// 2008/01/28 MH We must prevent that we select null bssid to link.
522
523	if(network->broadcom_cap_exist)
524	{
525		retValue = 1;
526	}
527
528	return retValue;
529}
530
531u8 HTIOTActIsForcedCTS2Self(struct ieee80211_network *network)
532{
533	u8 	retValue = 0;
534
535	if(network->marvell_cap_exist)
536	{
537		retValue = 1;
538	}
539
540	return retValue;
541}
542
543u8 HTIOTActIsForcedRTSCTS(struct ieee80211_device *ieee, struct ieee80211_network *network)
544{
545	u8	retValue = 0;
546	printk("============>%s(), %d\n", __FUNCTION__, network->realtek_cap_exit);
547	// Force protection
548	if(ieee->pHTInfo->bCurrentHTSupport)
549	{
550		//if(!network->realtek_cap_exit)
551		if((ieee->pHTInfo->IOTPeer != HT_IOT_PEER_REALTEK)&&
552		   (ieee->pHTInfo->IOTPeer != HT_IOT_PEER_REALTEK_92SE))
553	{
554			if((ieee->pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION) == 0)
555				retValue = 1;
556		}
557	}
558	return retValue;
559}
560
561u8
562HTIOTActIsForcedAMSDU8K(struct ieee80211_device *ieee, struct ieee80211_network *network)
563{
564	u8 retValue = 0;
565
566	return retValue;
567}
568
569u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
570{
571	u8	retValue = 0;
572	if(	(memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
573	    	(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) ||
574	    	(memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0))
575	{
576		retValue = 1;
577	}
578	return retValue;
579}
580
581/*
582  *  819xS single chip b-cut series cannot handle BAR
583  */
584u8
585HTIOCActRejcectADDBARequest(struct ieee80211_network *network)
586{
587	u8	retValue = 0;
588	//if(IS_HARDWARE_TYPE_8192SE(Adapter) ||
589	//	IS_HARDWARE_TYPE_8192SU(Adapter)
590	//)
591	{
592		// Do not reject ADDBA REQ because some of the AP may
593		// keep on sending ADDBA REQ qhich cause DHCP fail or ping loss!
594		// by HPFan, 2008/12/30
595
596		//if(pBssDesc->Vender == HT_IOT_PEER_MARVELL)
597		//	return FALSE;
598
599	}
600
601	return retValue;
602
603}
604
605/*
606  *  EDCA parameters bias on downlink
607  */
608  u8
609  HTIOTActIsEDCABiasRx(struct ieee80211_device* ieee,struct ieee80211_network *network)
610{
611	u8	retValue = 0;
612	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
613	{
614		if(pHTInfo->IOTPeer==HT_IOT_PEER_ATHEROS ||
615		   pHTInfo->IOTPeer==HT_IOT_PEER_BROADCOM ||
616		   pHTInfo->IOTPeer==HT_IOT_PEER_RALINK)
617			return 1;
618
619	}
620	return retValue;
621}
622
623u8
624HTIOTActDisableShortGI(struct ieee80211_device* ieee,struct ieee80211_network *network)
625{
626	u8	retValue = 0;
627	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
628
629	if(pHTInfo->IOTPeer==HT_IOT_PEER_RALINK)
630	{
631			retValue = 1;
632	}
633
634	return retValue;
635}
636
637u8
638HTIOTActDisableHighPower(struct ieee80211_device* ieee,struct ieee80211_network *network)
639{
640	u8	retValue = 0;
641	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
642
643	if(pHTInfo->IOTPeer==HT_IOT_PEER_RALINK ||
644		pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK ||
645		pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK_92SE)
646	{
647			retValue = 1;
648	}
649
650	return retValue;
651}
652
653void
654HTIOTActDetermineRaFunc(struct ieee80211_device* ieee,	bool	bPeerRx2ss)
655{
656	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
657	pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL;
658
659	if(pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss)
660		pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R;
661
662	if(pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
663		pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU;
664
665	printk("!!!!!!!!!!!!!!!!!!!!!!!!!!!IOTRaFunc = %8.8x\n", pHTInfo->IOTRaFunc);
666}
667
668
669u8
670HTIOTActIsDisableTx40MHz(struct ieee80211_device* ieee,struct ieee80211_network *network)
671{
672	u8	retValue = 0;
673
674	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
675	if(	(KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
676		(KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
677		(KEY_TYPE_WEP104 == ieee->group_key_type) ||
678		(KEY_TYPE_WEP40 == ieee->group_key_type) ||
679		(KEY_TYPE_TKIP == ieee->pairwise_key_type) )
680	{
681		if((pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK) && (network->bssht.bdSupportHT))
682			retValue = 1;
683	}
684
685	return retValue;
686}
687
688u8
689HTIOTActIsTxNoAggregation(struct ieee80211_device* ieee,struct ieee80211_network *network)
690{
691	u8 retValue = 0;
692
693	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
694	if(	(KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
695		(KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
696		(KEY_TYPE_WEP104 == ieee->group_key_type) ||
697		(KEY_TYPE_WEP40 == ieee->group_key_type) ||
698		(KEY_TYPE_TKIP == ieee->pairwise_key_type) )
699	{
700		if(pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK)
701			retValue = 1;
702	}
703
704	return retValue;
705}
706
707
708u8
709HTIOTActIsDisableTx2SS(struct ieee80211_device* ieee,struct ieee80211_network *network)
710{
711	u8	retValue = 0;
712
713	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
714	if(	(KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
715		(KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
716		(KEY_TYPE_WEP104 == ieee->group_key_type) ||
717		(KEY_TYPE_WEP40 == ieee->group_key_type) ||
718		(KEY_TYPE_TKIP == ieee->pairwise_key_type) )
719	{
720		if((pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK) && (network->bssht.bdSupportHT))
721			retValue = 1;
722	}
723
724	return retValue;
725}
726
727
728bool HTIOCActAllowPeerAggOnePacket(struct ieee80211_device* ieee,struct ieee80211_network *network)
729{
730	bool 	retValue = false;
731	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
732	if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
733	{
734		if((memcmp(network->bssid, NETGEAR_BROADCOM, 3)==0)
735			&& (network->bssht.bdBandWidth == HT_CHANNEL_WIDTH_20_40))
736			return true;
737	}
738	return retValue;
739}
740
741void HTResetIOTSetting(
742	PRT_HIGH_THROUGHPUT		pHTInfo
743)
744{
745	pHTInfo->IOTAction = 0;
746	pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
747	pHTInfo->IOTRaFunc = 0;
748}
749
750
751/********************************************************************************************************************
752 *function:  Construct Capablility Element in Beacon... if HTEnable is turned on
753 *   input:  struct ieee80211_device* 	ieee
754 *   	     u8* 			posHTCap //pointer to store Capability Ele
755 *   	     u8*			len //store length of CE
756 *   	     u8				IsEncrypt //whether encrypt, needed further
757 *  output:  none
758 *  return:  none
759 *  notice:  posHTCap can't be null and should be initialized before.
760  * *****************************************************************************************************************/
761void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 IsEncrypt)
762{
763	PRT_HIGH_THROUGHPUT	pHT = ieee->pHTInfo;
764	PHT_CAPABILITY_ELE 	pCapELE = NULL;
765
766	if ((posHTCap == NULL) || (pHT == NULL))
767	{
768		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n");
769		return;
770	}
771	memset(posHTCap, 0, *len);
772	if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
773	{
774		u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};	// For 11n EWC definition, 2007.07.17, by Emily
775		memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
776		pCapELE = (PHT_CAPABILITY_ELE)&(posHTCap[4]);
777	}else
778	{
779		pCapELE = (PHT_CAPABILITY_ELE)posHTCap;
780	}
781
782
783	//HT capability info
784	pCapELE->AdvCoding 		= 0; // This feature is not supported now!!
785	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
786	{
787		pCapELE->ChlWidth = 0;
788	}
789	else
790	{
791		pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0);
792	}
793
794	pCapELE->MimoPwrSave 		= pHT->SelfMimoPs;
795	pCapELE->GreenField		= 0; // This feature is not supported now!!
796	pCapELE->ShortGI20Mhz		= 1; // We can receive Short GI!!
797	pCapELE->ShortGI40Mhz		= 1; // We can receive Short GI!!
798
799	pCapELE->TxSTBC 		= 1;
800	pCapELE->RxSTBC 		= 0;
801	pCapELE->DelayBA		= 0;	// Do not support now!!
802	pCapELE->MaxAMSDUSize	= (MAX_RECEIVE_BUFFER_SIZE>=7935)?1:0;
803	pCapELE->DssCCk 		= ((pHT->bRegBW40MHz)?(pHT->bRegSuppCCK?1:0):0);
804	pCapELE->PSMP			= 0; // Do not support now!!
805	pCapELE->LSigTxopProtect	= 0; // Do not support now!!
806
807
808	//MAC HT parameters info
809        // TODO: Nedd to take care of this part
810	IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
811
812	if( IsEncrypt)
813	{
814		pCapELE->MPDUDensity 	= 7; // 8us
815		pCapELE->MaxRxAMPDUFactor 	= 2; // 2 is for 32 K and 3 is 64K
816	}
817	else
818	{
819		pCapELE->MaxRxAMPDUFactor 	= 3; // 2 is for 32 K and 3 is 64K
820		pCapELE->MPDUDensity 	= 0; // no density
821	}
822
823	//Supported MCS set
824	memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
825	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
826		pCapELE->MCS[1] &= 0x7f;
827
828	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
829		pCapELE->MCS[1] &= 0xbf;
830
831	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
832		pCapELE->MCS[1] &= 0x00;
833
834	// 2008.06.12
835	// For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7.
836	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
837	{
838		int i;
839		for(i = 1; i< 16; i++)
840			pCapELE->MCS[i] = 0;
841	}
842
843	//Extended HT Capability Info
844	memset(&pCapELE->ExtHTCapInfo, 0, 2);
845
846
847	//TXBF Capabilities
848	memset(pCapELE->TxBFCap, 0, 4);
849
850	//Antenna Selection Capabilities
851	pCapELE->ASCap = 0;
852//add 2 to give space for element ID and len when construct frames
853	if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
854		*len = 30 + 2;
855	else
856		*len = 26 + 2;
857
858	return;
859
860}
861/********************************************************************************************************************
862 *function:  Construct  Information Element in Beacon... if HTEnable is turned on
863 *   input:  struct ieee80211_device* 	ieee
864 *   	     u8* 			posHTCap //pointer to store Information Ele
865 *   	     u8*			len   //store len of
866 *   	     u8				IsEncrypt //whether encrypt, needed further
867 *  output:  none
868 *  return:  none
869 *  notice:  posHTCap can't be null and be initialized before. only AP and IBSS sta should do this
870  * *****************************************************************************************************************/
871void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 IsEncrypt)
872{
873	PRT_HIGH_THROUGHPUT	pHT = ieee->pHTInfo;
874	PHT_INFORMATION_ELE		pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo;
875	if ((posHTInfo == NULL) || (pHTInfoEle == NULL))
876	{
877		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n");
878		return;
879	}
880
881	memset(posHTInfo, 0, *len);
882	if ( (ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) //ap mode is not currently supported
883	{
884		pHTInfoEle->ControlChl 			= ieee->current_network.channel;
885		pHTInfoEle->ExtChlOffset 			= ((pHT->bRegBW40MHz == false)?HT_EXTCHNL_OFFSET_NO_EXT:
886											(ieee->current_network.channel<=6)?
887												HT_EXTCHNL_OFFSET_UPPER:HT_EXTCHNL_OFFSET_LOWER);
888		pHTInfoEle->RecommemdedTxWidth	= pHT->bRegBW40MHz;
889		pHTInfoEle->RIFS 					= 0;
890		pHTInfoEle->PSMPAccessOnly		= 0;
891		pHTInfoEle->SrvIntGranularity		= 0;
892		pHTInfoEle->OptMode				= pHT->CurrentOpMode;
893		pHTInfoEle->NonGFDevPresent		= 0;
894		pHTInfoEle->DualBeacon			= 0;
895		pHTInfoEle->SecondaryBeacon		= 0;
896		pHTInfoEle->LSigTxopProtectFull		= 0;
897		pHTInfoEle->PcoActive				= 0;
898		pHTInfoEle->PcoPhase				= 0;
899
900		memset(pHTInfoEle->BasicMSC, 0, 16);
901
902
903		*len = 22 + 2; //same above
904
905	}
906	else
907	{
908		//STA should not generate High Throughput Information Element
909		*len = 0;
910	}
911	return;
912}
913
914/*
915  *  According to experiment, Realtek AP to STA (based on rtl8190) may achieve best performance
916  *  if both STA and AP set limitation of aggregation size to 32K, that is, set AMPDU density to 2
917  *  (Ref: IEEE 11n specification). However, if Realtek STA associates to other AP, STA should set
918  *  limitation of aggregation size to 8K, otherwise, performance of traffic stream from STA to AP
919  *  will be much less than the traffic stream from AP to STA if both of the stream runs concurrently
920  *  at the same time.
921  *
922  *  Frame Format
923  *  Element ID		Length		OUI			Type1		Reserved
924  *  1 byte			1 byte		3 bytes		1 byte		1 byte
925  *
926  *  OUI 		= 0x00, 0xe0, 0x4c,
927  *  Type 	= 0x02
928  *  Reserved 	= 0x00
929  *
930  *  2007.8.21 by Emily
931*/
932/********************************************************************************************************************
933 *function:  Construct  Information Element in Beacon... in RT2RT condition
934 *   input:  struct ieee80211_device* 	ieee
935 *   	     u8* 			posRT2RTAgg //pointer to store Information Ele
936 *   	     u8*			len   //store len
937 *  output:  none
938 *  return:  none
939 *  notice:
940  * *****************************************************************************************************************/
941void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len)
942{
943	if (posRT2RTAgg == NULL) {
944		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n");
945		return;
946	}
947	memset(posRT2RTAgg, 0, *len);
948	*posRT2RTAgg++ = 0x00;
949	*posRT2RTAgg++ = 0xe0;
950	*posRT2RTAgg++ = 0x4c;
951	*posRT2RTAgg++ = 0x02;
952	*posRT2RTAgg++ = 0x01;
953	*posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02;
954
955	if(ieee->bSupportRemoteWakeUp) {
956		*posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW;
957	}
958
959	*len = 6 + 2;
960	return;
961#ifdef TODO
962#if(HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE)
963	/*
964	//Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this
965	   section of code.
966	if(IS_UNDER_11N_AES_MODE(Adapter))
967	{
968		posRT2RTAgg->Octet[5] |=RT_HT_CAP_USE_AMPDU;
969	}else
970	{
971		posRT2RTAgg->Octet[5] &= 0xfb;
972	}
973	*/
974
975#else
976#endif
977
978	posRT2RTAgg->Length = 6;
979#endif
980
981
982
983
984}
985
986
987/********************************************************************************************************************
988 *function:  Pick the right Rate Adaptive table to use
989 *   input:  struct ieee80211_device* 	ieee
990 *   	     u8* 			pOperateMCS //A pointer to MCS rate bitmap
991 *  return:  always we return true
992 *  notice:
993  * *****************************************************************************************************************/
994u8 HT_PickMCSRate(struct ieee80211_device* ieee, u8* pOperateMCS)
995{
996	u8					i;
997	if (pOperateMCS == NULL)
998	{
999		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pOperateMCS can't be null in HT_PickMCSRate()\n");
1000		return false;
1001	}
1002
1003	switch(ieee->mode)
1004	{
1005	case IEEE_A:
1006	case IEEE_B:
1007	case IEEE_G:
1008			//legacy rate routine handled at selectedrate
1009
1010			//no MCS rate
1011			for(i=0;i<=15;i++){
1012				pOperateMCS[i] = 0;
1013			}
1014			break;
1015
1016	case IEEE_N_24G:	//assume CCK rate ok
1017	case IEEE_N_5G:
1018			// Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G.
1019			// Legacy part shall be handled at SelectRateSet().
1020
1021			//HT part
1022			// TODO: may be different if we have different number of antenna
1023			pOperateMCS[0] &=RATE_ADPT_1SS_MASK;	//support MCS 0~7
1024			pOperateMCS[1] &=RATE_ADPT_2SS_MASK;
1025			pOperateMCS[3] &=RATE_ADPT_MCS32_MASK;
1026			break;
1027
1028	//should never reach here
1029	default:
1030
1031			break;
1032
1033	}
1034
1035	return true;
1036}
1037
1038/*
1039*	Description:
1040*		This function will get the highest speed rate in input MCS set.
1041*
1042*	/param 	Adapter			Pionter to Adapter entity
1043*			pMCSRateSet		Pointer to MCS rate bitmap
1044*			pMCSFilter		Pointer to MCS rate filter
1045*
1046*	/return	Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter.
1047*
1048*/
1049/********************************************************************************************************************
1050 *function:  This function will get the highest speed rate in input MCS set.
1051 *   input:  struct ieee80211_device* 	ieee
1052 *   	     u8* 			pMCSRateSet //Pointer to MCS rate bitmap
1053 *   	     u8*			pMCSFilter //Pointer to MCS rate filter
1054 *  return:  Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter
1055 *  notice:
1056  * *****************************************************************************************************************/
1057u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter)
1058{
1059	u8		i, j;
1060	u8		bitMap;
1061	u8		mcsRate = 0;
1062	u8		availableMcsRate[16];
1063	if (pMCSRateSet == NULL || pMCSFilter == NULL)
1064	{
1065		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n");
1066		return false;
1067	}
1068	for(i=0; i<16; i++)
1069		availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
1070
1071	for(i = 0; i < 16; i++)
1072	{
1073		if(availableMcsRate[i] != 0)
1074			break;
1075	}
1076	if(i == 16)
1077		return false;
1078
1079	for(i = 0; i < 16; i++)
1080	{
1081		if(availableMcsRate[i] != 0)
1082		{
1083			bitMap = availableMcsRate[i];
1084			for(j = 0; j < 8; j++)
1085			{
1086				if((bitMap%2) != 0)
1087				{
1088					if(HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate))
1089						mcsRate = (8*i+j);
1090				}
1091				bitMap = bitMap>>1;
1092			}
1093		}
1094	}
1095	return (mcsRate|0x80);
1096}
1097
1098
1099
1100/*
1101**
1102**1.Filter our operation rate set with AP's rate set
1103**2.shall reference channel bandwidth, STBC, Antenna number
1104**3.generate rate adative table for firmware
1105**David 20060906
1106**
1107** \pHTSupportedCap: the connected STA's supported rate Capability element
1108*/
1109u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperateMCS)
1110{
1111
1112	u8 i=0;
1113
1114	// filter out operational rate set not supported by AP, the lenth of it is 16
1115	for(i=0;i<=15;i++){
1116		pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i];
1117	}
1118
1119
1120	// TODO: adjust our operational rate set  according to our channel bandwidth, STBC and Antenna number
1121
1122	// TODO: fill suggested rate adaptive rate index and give firmware info using Tx command packet
1123	// we also shall suggested the first start rate set according to our singal strength
1124	HT_PickMCSRate(ieee, pOperateMCS);
1125
1126	// For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
1127	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
1128		pOperateMCS[1] = 0;
1129
1130	//
1131	// For RTL819X, we support only MCS0~15.
1132	// And also, we do not know how to use MCS32 now.
1133	//
1134	for(i=2; i<=15; i++)
1135		pOperateMCS[i] = 0;
1136
1137	return true;
1138}
1139void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset);
1140
1141void HTOnAssocRsp(struct ieee80211_device *ieee)
1142{
1143	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
1144	PHT_CAPABILITY_ELE		pPeerHTCap = NULL;
1145	PHT_INFORMATION_ELE		pPeerHTInfo = NULL;
1146	u16	nMaxAMSDUSize = 0;
1147	u8*	pMcsFilter = NULL;
1148
1149	static u8				EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};		// For 11n EWC definition, 2007.07.17, by Emily
1150	static u8				EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};	// For 11n EWC definition, 2007.07.17, by Emily
1151
1152	if( pHTInfo->bCurrentHTSupport == false )
1153	{
1154		IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n");
1155		return;
1156	}
1157	IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
1158
1159	if(!memcmp(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap)))
1160		pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]);
1161	else
1162		pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf);
1163
1164	if(!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
1165		pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]);
1166	else
1167		pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf);
1168
1169
1170	////////////////////////////////////////////////////////
1171	// Configurations:
1172	////////////////////////////////////////////////////////
1173	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE));
1174
1175	HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset));
1176
1177	if(pHTInfo->bCurBW40MHz == true)
1178		pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false);
1179
1180	//
1181	// Update short GI/ long GI setting
1182	//
1183	// TODO:
1184	pHTInfo->bCurShortGI20MHz=
1185		((pHTInfo->bRegShortGI20MHz)?((pPeerHTCap->ShortGI20Mhz==1)?true:false):false);
1186	pHTInfo->bCurShortGI40MHz=
1187		((pHTInfo->bRegShortGI40MHz)?((pPeerHTCap->ShortGI40Mhz==1)?true:false):false);
1188
1189	//
1190	// Config TX STBC setting
1191	//
1192	// TODO:
1193
1194	//
1195	// Config DSSS/CCK  mode in 40MHz mode
1196	//
1197	// TODO:
1198	pHTInfo->bCurSuppCCK =
1199		((pHTInfo->bRegSuppCCK)?((pPeerHTCap->DssCCk==1)?true:false):false);
1200
1201
1202	//
1203	// Config and configure A-MSDU setting
1204	//
1205	pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
1206
1207	nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
1208
1209	if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize )
1210		pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
1211	else
1212		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
1213
1214	//
1215	// Config A-MPDU setting
1216	//
1217	pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
1218	if(ieee->is_ap_in_wep_tkip && ieee->is_ap_in_wep_tkip(ieee->dev))
1219	{
1220		if( (pHTInfo->IOTPeer== HT_IOT_PEER_ATHEROS) ||
1221				(pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN) )
1222			pHTInfo->bCurrentAMPDUEnable = false;
1223	}
1224
1225	// <1> Decide AMPDU Factor
1226
1227	// By Emily
1228	if(!pHTInfo->bRegRT2RTAggregation)
1229	{
1230		// Decide AMPDU Factor according to protocol handshake
1231		if(pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
1232			pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
1233		else
1234			pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
1235
1236	}else
1237	{
1238		// Set MPDU density to 2 to Realtek AP, and set it to 0 for others
1239		// Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily
1240		if (ieee->current_network.bssht.bdRT2RTAggregation)
1241		{
1242			if( ieee->pairwise_key_type != KEY_TYPE_NA)
1243				// Realtek may set 32k in security mode and 64k for others
1244				pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
1245			else
1246				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
1247		}else
1248		{
1249			if(pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
1250				pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
1251			else
1252				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
1253		}
1254	}
1255
1256	// <2> Set AMPDU Minimum MPDU Start Spacing
1257	// 802.11n 3.0 section 9.7d.3
1258	if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
1259		pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
1260	else
1261		pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
1262	// Force TX AMSDU
1263
1264	// Lanhsin: mark for tmp to avoid deauth by ap from  s3
1265	//if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0)
1266	if(pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K)
1267		{
1268
1269			pHTInfo->bCurrentAMPDUEnable = false;
1270			pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
1271			pHTInfo->ForcedAMSDUMaxSize = 7935;
1272	}
1273
1274	// Rx Reorder Setting
1275	pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
1276
1277	//
1278	// Filter out unsupported HT rate for this AP
1279	// Update RATR table
1280	// This is only for 8190 ,8192 or later product which using firmware to handle rate adaptive mechanism.
1281	//
1282
1283	// Handle Ralink AP bad MCS rate set condition. Joseph.
1284	// This fix the bug of Ralink AP. This may be removed in the future.
1285	if(pPeerHTCap->MCS[0] == 0)
1286		pPeerHTCap->MCS[0] = 0xff;
1287
1288	// Joseph test //LZM ADD 090318
1289	HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1])!=0));
1290
1291	HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
1292
1293	//
1294	// Config MIMO Power Save setting
1295	//
1296	pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
1297	if(pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
1298		pMcsFilter = MCS_FILTER_1SS;
1299	else
1300		pMcsFilter = MCS_FILTER_ALL;
1301	//WB add for MCS8 bug
1302//	pMcsFilter = MCS_FILTER_1SS;
1303	ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter);
1304	ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
1305
1306	//
1307	// Config current operation mode.
1308	//
1309	pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
1310
1311
1312
1313}
1314
1315void HTSetConnectBwModeCallback(struct ieee80211_device* ieee);
1316/********************************************************************************************************************
1317 *function:  initialize HT info(struct PRT_HIGH_THROUGHPUT)
1318 *   input:  struct ieee80211_device* 	ieee
1319 *  output:  none
1320 *  return:  none
1321 *  notice: This function is called when *  (1) MPInitialization Phase *  (2) Receiving of Deauthentication from AP
1322********************************************************************************************************************/
1323// TODO: Should this funciton be called when receiving of Disassociation?
1324void HTInitializeHTInfo(struct ieee80211_device* ieee)
1325{
1326	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1327
1328	//
1329	// These parameters will be reset when receiving deauthentication packet
1330	//
1331	IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __FUNCTION__);
1332	pHTInfo->bCurrentHTSupport = false;
1333
1334	// 40MHz channel support
1335	pHTInfo->bCurBW40MHz = false;
1336	pHTInfo->bCurTxBW40MHz = false;
1337
1338	// Short GI support
1339	pHTInfo->bCurShortGI20MHz = false;
1340	pHTInfo->bCurShortGI40MHz = false;
1341	pHTInfo->bForcedShortGI = false;
1342
1343	// CCK rate support
1344	// This flag is set to true to support CCK rate by default.
1345	// It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to
1346	// 11N BSS.
1347	pHTInfo->bCurSuppCCK = true;
1348
1349	// AMSDU related
1350	pHTInfo->bCurrent_AMSDU_Support = false;
1351	pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
1352
1353	// AMPUD related
1354	pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
1355	pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
1356
1357
1358
1359	// Initialize all of the parameters related to 11n
1360	memset((void*)(&(pHTInfo->SelfHTCap)), 0, sizeof(pHTInfo->SelfHTCap));
1361	memset((void*)(&(pHTInfo->SelfHTInfo)), 0, sizeof(pHTInfo->SelfHTInfo));
1362	memset((void*)(&(pHTInfo->PeerHTCapBuf)), 0, sizeof(pHTInfo->PeerHTCapBuf));
1363	memset((void*)(&(pHTInfo->PeerHTInfoBuf)), 0, sizeof(pHTInfo->PeerHTInfoBuf));
1364
1365	pHTInfo->bSwBwInProgress = false;
1366	pHTInfo->ChnlOp = CHNLOP_NONE;
1367
1368	// Set default IEEE spec for Draft N
1369	pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
1370
1371	// Realtek proprietary aggregation mode
1372	pHTInfo->bCurrentRT2RTAggregation = false;
1373	pHTInfo->bCurrentRT2RTLongSlotTime = false;
1374	pHTInfo->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
1375
1376	pHTInfo->IOTPeer = 0;
1377	pHTInfo->IOTAction = 0;
1378	pHTInfo->IOTRaFunc = 0;
1379
1380	//MCS rate initialized here
1381	{
1382		u8* RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
1383		RegHTSuppRateSets[0] = 0xFF;	//support MCS 0~7
1384		RegHTSuppRateSets[1] = 0xFF;	//support MCS 8~15
1385		RegHTSuppRateSets[4] = 0x01;	//support MCS 32
1386	}
1387}
1388/********************************************************************************************************************
1389 *function:  initialize Bss HT structure(struct PBSS_HT)
1390 *   input:  PBSS_HT pBssHT //to be initialized
1391 *  output:  none
1392 *  return:  none
1393 *  notice: This function is called when initialize network structure
1394********************************************************************************************************************/
1395void HTInitializeBssDesc(PBSS_HT pBssHT)
1396{
1397
1398	pBssHT->bdSupportHT = false;
1399	memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf));
1400	pBssHT->bdHTCapLen = 0;
1401	memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf));
1402	pBssHT->bdHTInfoLen = 0;
1403
1404	pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE;
1405
1406	pBssHT->bdRT2RTAggregation = false;
1407	pBssHT->bdRT2RTLongSlotTime = false;
1408	pBssHT->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
1409}
1410
1411/********************************************************************************************************************
1412 *function:  initialize Bss HT structure(struct PBSS_HT)
1413 *   input:  struct ieee80211_device 	*ieee
1414 *   	     struct ieee80211_network 	*pNetwork //usually current network we are live in
1415 *  output:  none
1416 *  return:  none
1417 *  notice: This function should ONLY be called before association
1418********************************************************************************************************************/
1419void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, 	struct ieee80211_network * pNetwork)
1420{
1421	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
1422//	u16						nMaxAMSDUSize;
1423//	PHT_CAPABILITY_ELE		pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
1424//	PHT_INFORMATION_ELE		pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
1425//	u8*	pMcsFilter;
1426	u8	bIOTAction = 0;
1427
1428	//
1429	//  Save Peer Setting before Association
1430	//
1431	IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __FUNCTION__);
1432	/*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/
1433//	if( pHTInfo->bEnableHT &&  pNetwork->bssht.bdSupportHT)
1434	if (pNetwork->bssht.bdSupportHT)
1435	{
1436		pHTInfo->bCurrentHTSupport = true;
1437		pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer;
1438
1439		// Save HTCap and HTInfo information Element
1440		if(pNetwork->bssht.bdHTCapLen > 0 && 	pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf))
1441			memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen);
1442
1443		if(pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf))
1444			memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen);
1445
1446		// Check whether RT to RT aggregation mode is enabled
1447		if(pHTInfo->bRegRT2RTAggregation)
1448		{
1449			pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation;
1450			pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime;
1451			pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.RT2RT_HT_Mode;
1452		}
1453		else
1454		{
1455			pHTInfo->bCurrentRT2RTAggregation = false;
1456			pHTInfo->bCurrentRT2RTLongSlotTime = false;
1457			pHTInfo->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
1458		}
1459
1460		// Determine the IOT Peer Vendor.
1461		HTIOTPeerDetermine(ieee);
1462
1463		// Decide IOT Action
1464		// Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided
1465		pHTInfo->IOTAction = 0;
1466		bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
1467		if(bIOTAction)
1468			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
1469
1470		bIOTAction = HTIOTActIsDisableMCS15(ieee);
1471		if(bIOTAction)
1472			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
1473
1474		bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee);
1475		if(bIOTAction)
1476			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
1477
1478
1479		bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
1480		if(bIOTAction)
1481			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
1482
1483		bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork);
1484		if(bIOTAction)
1485			pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
1486
1487		bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid);
1488		if(bIOTAction)
1489			pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
1490
1491		bIOTAction = HTIOTActIsForcedCTS2Self(pNetwork);
1492		if(bIOTAction)
1493			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
1494
1495		//bIOTAction = HTIOTActIsForcedRTSCTS(ieee, pNetwork);
1496		//if(bIOTAction)
1497		//	pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_RTS;
1498
1499		bIOTAction = HTIOCActRejcectADDBARequest(pNetwork);
1500		if(bIOTAction)
1501			pHTInfo->IOTAction |= HT_IOT_ACT_REJECT_ADDBA_REQ;
1502
1503		bIOTAction = HTIOCActAllowPeerAggOnePacket(ieee, pNetwork);
1504		if(bIOTAction)
1505			pHTInfo->IOTAction |= HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT;
1506
1507		bIOTAction = HTIOTActIsEDCABiasRx(ieee, pNetwork);
1508		if(bIOTAction)
1509			pHTInfo->IOTAction |= HT_IOT_ACT_EDCA_BIAS_ON_RX;
1510
1511		bIOTAction = HTIOTActDisableShortGI(ieee, pNetwork);
1512		if(bIOTAction)
1513			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_SHORT_GI;
1514
1515		bIOTAction = HTIOTActDisableHighPower(ieee, pNetwork);
1516		if(bIOTAction)
1517			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_HIGH_POWER;
1518
1519		bIOTAction = HTIOTActIsForcedAMSDU8K(ieee, pNetwork);
1520		if(bIOTAction)
1521			pHTInfo->IOTAction |= HT_IOT_ACT_TX_USE_AMSDU_8K;
1522
1523		bIOTAction = HTIOTActIsTxNoAggregation(ieee, pNetwork);
1524		if(bIOTAction)
1525			pHTInfo->IOTAction |= HT_IOT_ACT_TX_NO_AGGREGATION;
1526
1527		bIOTAction = HTIOTActIsDisableTx40MHz(ieee, pNetwork);
1528		if(bIOTAction)
1529			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_TX_40_MHZ;
1530
1531		bIOTAction = HTIOTActIsDisableTx2SS(ieee, pNetwork);
1532		if(bIOTAction)
1533			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_TX_2SS;
1534		//must after HT_IOT_ACT_TX_NO_AGGREGATION
1535		bIOTAction = HTIOTActIsForcedRTSCTS(ieee, pNetwork);
1536		if(bIOTAction)
1537			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_RTS;
1538
1539		printk("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!IOTAction = %8.8x\n", pHTInfo->IOTAction);
1540	}
1541	else
1542	{
1543		pHTInfo->bCurrentHTSupport = false;
1544		pHTInfo->bCurrentRT2RTAggregation = false;
1545		pHTInfo->bCurrentRT2RTLongSlotTime = false;
1546		pHTInfo->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
1547
1548		pHTInfo->IOTAction = 0;
1549		pHTInfo->IOTRaFunc = 0;
1550	}
1551
1552}
1553
1554void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, 	struct ieee80211_network * pNetwork)
1555{
1556	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
1557//	PHT_CAPABILITY_ELE		pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
1558	PHT_INFORMATION_ELE		pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
1559
1560	if(pHTInfo->bCurrentHTSupport)
1561	{
1562		//
1563		// Config current operation mode.
1564		//
1565		if(pNetwork->bssht.bdHTInfoLen != 0)
1566			pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
1567
1568		//
1569		// <TODO: Config according to OBSS non-HT STA present!!>
1570		//
1571	}
1572}
1573
1574void HTUseDefaultSetting(struct ieee80211_device* ieee)
1575{
1576	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1577//	u8	regBwOpMode;
1578
1579	if(pHTInfo->bEnableHT)
1580	{
1581		pHTInfo->bCurrentHTSupport = true;
1582
1583		pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK;
1584
1585		pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz;
1586
1587		pHTInfo->bCurShortGI20MHz= pHTInfo->bRegShortGI20MHz;
1588
1589		pHTInfo->bCurShortGI40MHz= pHTInfo->bRegShortGI40MHz;
1590
1591		pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
1592
1593		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
1594
1595		pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
1596
1597		pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
1598
1599		pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
1600
1601		// Set BWOpMode register
1602
1603		//update RATR index0
1604		HTFilterMCSRate(ieee, ieee->Regdot11HTOperationalRateSet, ieee->dot11HTOperationalRateSet);
1605	//function below is not implemented at all. WB
1606#ifdef TODO
1607		Adapter->HalFunc.InitHalRATRTableHandler( Adapter, &pMgntInfo->dot11OperationalRateSet, pMgntInfo->dot11HTOperationalRateSet);
1608#endif
1609		ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, MCS_FILTER_ALL);
1610		ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
1611
1612	}
1613	else
1614	{
1615		pHTInfo->bCurrentHTSupport = false;
1616	}
1617	return;
1618}
1619/********************************************************************************************************************
1620 *function:  check whether HT control field exists
1621 *   input:  struct ieee80211_device 	*ieee
1622 *   	     u8*			pFrame //coming skb->data
1623 *  output:  none
1624 *  return:  return true if HT control field exists(false otherwise)
1625 *  notice:
1626********************************************************************************************************************/
1627u8 HTCCheck(struct ieee80211_device* ieee, u8*	pFrame)
1628{
1629	if(ieee->pHTInfo->bCurrentHTSupport)
1630	{
1631		if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1)
1632		{
1633			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n");
1634			return true;
1635		}
1636	}
1637	return false;
1638}
1639
1640//
1641// This function set bandwidth mode in protocol layer.
1642//
1643void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset)
1644{
1645	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1646//	u32 flags = 0;
1647
1648	if(pHTInfo->bRegBW40MHz == false)
1649		return;
1650
1651
1652
1653	// To reduce dummy operation
1654//	if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) ||
1655//	   (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset))
1656//		return;
1657
1658//	spin_lock_irqsave(&(ieee->bw_spinlock), flags);
1659	if(pHTInfo->bSwBwInProgress) {
1660//		spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
1661		return;
1662	}
1663	//if in half N mode, set to 20M bandwidth please 09.08.2008 WB.
1664	if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)))
1665	 {
1666	 		// Handle Illegal extention channel offset!!
1667		if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER)
1668			Offset = HT_EXTCHNL_OFFSET_NO_EXT;
1669		if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) {
1670			pHTInfo->bCurBW40MHz = true;
1671			pHTInfo->CurSTAExtChnlOffset = Offset;
1672		} else {
1673			pHTInfo->bCurBW40MHz = false;
1674			pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
1675		}
1676	} else {
1677		pHTInfo->bCurBW40MHz = false;
1678		pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
1679	}
1680
1681	pHTInfo->bSwBwInProgress = true;
1682
1683	// TODO: 2007.7.13 by Emily Wait 2000ms  in order to garantee that switching
1684	//   bandwidth is executed after scan is finished. It is a temporal solution
1685	//   because software should ganrantee the last operation of switching bandwidth
1686	//   is executed properlly.
1687	HTSetConnectBwModeCallback(ieee);
1688
1689//	spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
1690}
1691
1692void HTSetConnectBwModeCallback(struct ieee80211_device* ieee)
1693{
1694	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1695
1696	IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __FUNCTION__);
1697	if(pHTInfo->bCurBW40MHz)
1698	{
1699		if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER)
1700			ieee->set_chan(ieee->dev, ieee->current_network.channel+2);
1701		else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER)
1702			ieee->set_chan(ieee->dev, ieee->current_network.channel-2);
1703		else
1704			ieee->set_chan(ieee->dev, ieee->current_network.channel);
1705
1706		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset);
1707	} else {
1708		ieee->set_chan(ieee->dev, ieee->current_network.channel);
1709		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1710	}
1711
1712	pHTInfo->bSwBwInProgress = false;
1713}
1714