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