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