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