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