This source file includes following definitions.
- rtw_get_bit_value_from_ieee_value
- rtw_is_cckrates_included
- rtw_is_cckratesonly_included
- rtw_check_network_type
- rtw_set_fixed_ie
- rtw_get_ie
- rtw_set_supported_rate
- rtw_get_rateset_len
- rtw_generate_ie
- rtw_get_wpa_ie
- rtw_get_wpa2_ie
- rtw_get_wpa_cipher_suite
- rtw_get_wpa2_cipher_suite
- rtw_parse_wpa_ie
- rtw_parse_wpa2_ie
- rtw_get_sec_ie
- rtw_is_wps_ie
- rtw_get_wps_ie
- rtw_get_wps_attr
- rtw_get_wps_attr_content
- rtw_ieee802_11_parse_vendor_specific
- rtw_ieee802_11_parse_elems
- rtw_macaddr_cfg
- rtw_get_cipher_info
- rtw_get_bcn_info
- rtw_mcs_rate
1
2
3
4
5
6
7 #define _IEEE80211_C
8
9 #include <linux/ieee80211.h>
10
11 #include <drv_types.h>
12 #include <osdep_intf.h>
13 #include <ieee80211.h>
14 #include <wifi.h>
15 #include <osdep_service.h>
16 #include <wlan_bssdef.h>
17
18 u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
19 u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 };
20 u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 };
21 u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 };
22 u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 };
23 u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 };
24 u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 };
25 u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 };
26 u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 };
27 u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };
28
29 u16 RSN_VERSION_BSD = 1;
30 u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 };
31 u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 };
32 u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 };
33 u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 };
34 u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 };
35 u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 };
36 u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 };
37 u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 };
38
39
40
41
42 static u8 WIFI_CCKRATES[] = {
43 IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
44 IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
45 IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
46 IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
47 };
48
49 static u8 WIFI_OFDMRATES[] = {
50 IEEE80211_OFDM_RATE_6MB,
51 IEEE80211_OFDM_RATE_9MB,
52 IEEE80211_OFDM_RATE_12MB,
53 IEEE80211_OFDM_RATE_18MB,
54 IEEE80211_OFDM_RATE_24MB,
55 IEEE80211_OFDM_RATE_36MB,
56 IEEE80211_OFDM_RATE_48MB,
57 IEEE80211_OFDM_RATE_54MB
58 };
59
60 int rtw_get_bit_value_from_ieee_value(u8 val)
61 {
62 static const unsigned char dot11_rate_table[] = {
63 2, 4, 11, 22, 12, 18, 24, 36, 48,
64 72, 96, 108, 0};
65 int i = 0;
66
67 while (dot11_rate_table[i] != 0) {
68 if (dot11_rate_table[i] == val)
69 return BIT(i);
70 i++;
71 }
72 return 0;
73 }
74
75 bool rtw_is_cckrates_included(u8 *rate)
76 {
77 while (*rate) {
78 u8 r = *rate & 0x7f;
79
80 if (r == 2 || r == 4 || r == 11 || r == 22)
81 return true;
82 rate++;
83 }
84
85 return false;
86 }
87
88 bool rtw_is_cckratesonly_included(u8 *rate)
89 {
90 while (*rate) {
91 u8 r = *rate & 0x7f;
92
93 if (r != 2 && r != 4 && r != 11 && r != 22)
94 return false;
95 rate++;
96 }
97
98 return true;
99 }
100
101 int rtw_check_network_type(unsigned char *rate, int ratelen, int channel)
102 {
103
104 if (rtw_is_cckratesonly_included(rate))
105 return WIRELESS_11B;
106 else if (rtw_is_cckrates_included(rate))
107 return WIRELESS_11BG;
108 else
109 return WIRELESS_11G;
110 }
111
112 u8 *rtw_set_fixed_ie(void *pbuf, unsigned int len, void *source,
113 unsigned int *frlen)
114 {
115 memcpy(pbuf, source, len);
116 *frlen = *frlen + len;
117 return ((u8 *)pbuf) + len;
118 }
119
120
121 u8 *rtw_set_ie
122 (
123 u8 *pbuf,
124 int index,
125 uint len,
126 u8 *source,
127 uint *frlen
128 )
129 {
130 *pbuf = (u8)index;
131
132 *(pbuf + 1) = (u8)len;
133
134 if (len > 0)
135 memcpy((void *)(pbuf + 2), (void *)source, len);
136
137 *frlen = *frlen + (len + 2);
138
139 return pbuf + len + 2;
140 }
141
142
143
144
145 u8 *rtw_get_ie(u8 *pbuf, int index, uint *len, int limit)
146 {
147 int tmp, i;
148 u8 *p;
149
150 if (limit < 1)
151 return NULL;
152
153 p = pbuf;
154 i = 0;
155 *len = 0;
156 while (1) {
157 if (*p == index) {
158 *len = *(p + 1);
159 return p;
160 } else {
161 tmp = *(p + 1);
162 p += (tmp + 2);
163 i += (tmp + 2);
164 }
165 if (i >= limit)
166 break;
167 }
168 return NULL;
169 }
170
171 void rtw_set_supported_rate(u8 *SupportedRates, uint mode)
172 {
173 memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
174
175 switch (mode) {
176 case WIRELESS_11B:
177 memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
178 break;
179 case WIRELESS_11G:
180 case WIRELESS_11A:
181 case WIRELESS_11_5N:
182 case WIRELESS_11A_5N:
183 memcpy(SupportedRates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN);
184 break;
185 case WIRELESS_11BG:
186 case WIRELESS_11G_24N:
187 case WIRELESS_11_24N:
188 case WIRELESS_11BG_24N:
189 memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
190 memcpy(SupportedRates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN);
191 break;
192 }
193 }
194
195 uint rtw_get_rateset_len(u8 *rateset)
196 {
197 uint i;
198
199 for (i = 0; i < 13; i++)
200 if (rateset[i] == 0)
201 break;
202 return i;
203 }
204
205 int rtw_generate_ie(struct registry_priv *pregistrypriv)
206 {
207 u8 wireless_mode;
208 int rateLen;
209 uint sz = 0;
210 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
211 u8 *ie = pdev_network->ies;
212
213
214 sz += 8;
215 ie += sz;
216
217
218 *(__le16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);
219 sz += 2;
220 ie += 2;
221
222
223 *(u16 *)ie = 0;
224
225 *(__le16 *)ie |= cpu_to_le16(cap_IBSS);
226
227 if (pregistrypriv->preamble == PREAMBLE_SHORT)
228 *(__le16 *)ie |= cpu_to_le16(cap_ShortPremble);
229
230 if (pdev_network->Privacy)
231 *(__le16 *)ie |= cpu_to_le16(cap_Privacy);
232
233 sz += 2;
234 ie += 2;
235
236
237 ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->ssid.ssid_length, pdev_network->ssid.ssid, &sz);
238
239
240 if (pregistrypriv->wireless_mode == WIRELESS_11ABGN) {
241 if (pdev_network->Configuration.DSConfig > 14)
242 wireless_mode = WIRELESS_11A_5N;
243 else
244 wireless_mode = WIRELESS_11BG_24N;
245 } else {
246 wireless_mode = pregistrypriv->wireless_mode;
247 }
248
249 rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode);
250
251 rateLen = rtw_get_rateset_len(pdev_network->SupportedRates);
252
253 if (rateLen > 8) {
254 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, pdev_network->SupportedRates, &sz);
255
256 } else {
257 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, pdev_network->SupportedRates, &sz);
258 }
259
260
261 ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&(pdev_network->Configuration.DSConfig), &sz);
262
263
264
265 ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz);
266
267 if (rateLen > 8)
268 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz);
269
270 return sz;
271 }
272
273 unsigned char *rtw_get_wpa_ie(unsigned char *pie, uint *wpa_ie_len, int limit)
274 {
275 uint len;
276 u16 val16;
277 __le16 le_tmp;
278 static const unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01};
279 u8 *pbuf = pie;
280 int limit_new = limit;
281
282 while (1) {
283 pbuf = rtw_get_ie(pbuf, _WPA_IE_ID_, &len, limit_new);
284
285 if (pbuf) {
286
287 if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type)))
288 goto check_next_ie;
289
290
291 memcpy((u8 *)&le_tmp, (pbuf + 6), sizeof(val16));
292
293 val16 = le16_to_cpu(le_tmp);
294 if (val16 != 0x0001)
295 goto check_next_ie;
296 *wpa_ie_len = *(pbuf + 1);
297 return pbuf;
298 } else {
299 *wpa_ie_len = 0;
300 return NULL;
301 }
302
303 check_next_ie:
304 limit_new = limit - (pbuf - pie) - 2 - len;
305 if (limit_new <= 0)
306 break;
307 pbuf += (2 + len);
308 }
309 *wpa_ie_len = 0;
310 return NULL;
311 }
312
313 unsigned char *rtw_get_wpa2_ie(unsigned char *pie, uint *rsn_ie_len, int limit)
314 {
315 return rtw_get_ie(pie, _WPA2_IE_ID_, rsn_ie_len, limit);
316 }
317
318 int rtw_get_wpa_cipher_suite(u8 *s)
319 {
320 if (!memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN))
321 return WPA_CIPHER_NONE;
322 if (!memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN))
323 return WPA_CIPHER_WEP40;
324 if (!memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN))
325 return WPA_CIPHER_TKIP;
326 if (!memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN))
327 return WPA_CIPHER_CCMP;
328 if (!memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN))
329 return WPA_CIPHER_WEP104;
330
331 return 0;
332 }
333
334 int rtw_get_wpa2_cipher_suite(u8 *s)
335 {
336 if (!memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN))
337 return WPA_CIPHER_NONE;
338 if (!memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN))
339 return WPA_CIPHER_WEP40;
340 if (!memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN))
341 return WPA_CIPHER_TKIP;
342 if (!memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN))
343 return WPA_CIPHER_CCMP;
344 if (!memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN))
345 return WPA_CIPHER_WEP104;
346
347 return 0;
348 }
349
350 int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
351 {
352 int i, ret = _SUCCESS;
353 int left, count;
354 u8 *pos;
355 u8 SUITE_1X[4] = {0x00, 0x50, 0xf2, 1};
356
357 if (wpa_ie_len <= 0) {
358
359 return _FAIL;
360 }
361
362 if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie + 1) != (u8)(wpa_ie_len - 2)) ||
363 (memcmp(wpa_ie + 2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN)))
364 return _FAIL;
365
366 pos = wpa_ie;
367
368 pos += 8;
369 left = wpa_ie_len - 8;
370
371
372 if (left >= WPA_SELECTOR_LEN) {
373 *group_cipher = rtw_get_wpa_cipher_suite(pos);
374 pos += WPA_SELECTOR_LEN;
375 left -= WPA_SELECTOR_LEN;
376 } else if (left > 0) {
377 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie length mismatch, %u too much", __func__, left));
378 return _FAIL;
379 }
380
381
382 if (left >= 2) {
383 count = get_unaligned_le16(pos);
384 pos += 2;
385 left -= 2;
386
387 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
388 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie count botch (pairwise), "
389 "count %u left %u", __func__, count, left));
390 return _FAIL;
391 }
392
393 for (i = 0; i < count; i++) {
394 *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos);
395
396 pos += WPA_SELECTOR_LEN;
397 left -= WPA_SELECTOR_LEN;
398 }
399 } else if (left == 1) {
400 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie too short (for key mgmt)", __func__));
401 return _FAIL;
402 }
403
404 if (is_8021x) {
405 if (left >= 6) {
406 pos += 2;
407 if (!memcmp(pos, SUITE_1X, 4)) {
408 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s : there has 802.1x auth\n", __func__));
409 *is_8021x = 1;
410 }
411 }
412 }
413
414 return ret;
415 }
416
417 int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
418 {
419 int i, ret = _SUCCESS;
420 int left, count;
421 u8 *pos;
422 u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01};
423
424 if (rsn_ie_len <= 0) {
425
426 return _FAIL;
427 }
428
429 if ((*rsn_ie != _WPA2_IE_ID_) || (*(rsn_ie + 1) != (u8)(rsn_ie_len - 2)))
430 return _FAIL;
431
432 pos = rsn_ie;
433 pos += 4;
434 left = rsn_ie_len - 4;
435
436
437 if (left >= RSN_SELECTOR_LEN) {
438 *group_cipher = rtw_get_wpa2_cipher_suite(pos);
439
440 pos += RSN_SELECTOR_LEN;
441 left -= RSN_SELECTOR_LEN;
442
443 } else if (left > 0) {
444 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie length mismatch, %u too much", __func__, left));
445 return _FAIL;
446 }
447
448
449 if (left >= 2) {
450 count = get_unaligned_le16(pos);
451 pos += 2;
452 left -= 2;
453
454 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
455 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie count botch (pairwise), "
456 "count %u left %u", __func__, count, left));
457 return _FAIL;
458 }
459
460 for (i = 0; i < count; i++) {
461 *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos);
462
463 pos += RSN_SELECTOR_LEN;
464 left -= RSN_SELECTOR_LEN;
465 }
466
467 } else if (left == 1) {
468 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie too short (for key mgmt)", __func__));
469
470 return _FAIL;
471 }
472
473 if (is_8021x) {
474 if (left >= 6) {
475 pos += 2;
476 if (!memcmp(pos, SUITE_1X, 4)) {
477 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s (): there has 802.1x auth\n", __func__));
478 *is_8021x = 1;
479 }
480 }
481 }
482 return ret;
483 }
484
485 void rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len)
486 {
487 u8 authmode, sec_idx, i;
488 u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
489 uint cnt;
490
491
492
493 cnt = _TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_;
494
495 sec_idx = 0;
496
497 while (cnt < in_len) {
498 authmode = in_ie[cnt];
499
500 if ((authmode == _WPA_IE_ID_) && (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
501 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
502 ("\n rtw_get_wpa_ie: sec_idx =%d in_ie[cnt+1]+2 =%d\n",
503 sec_idx, in_ie[cnt + 1] + 2));
504
505 if (wpa_ie) {
506 memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
507
508 for (i = 0; i < (in_ie[cnt + 1] + 2); i += 8) {
509 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
510 ("\n %2x,%2x,%2x,%2x,%2x,%2x,%2x,%2x\n",
511 wpa_ie[i], wpa_ie[i + 1], wpa_ie[i + 2], wpa_ie[i + 3], wpa_ie[i + 4],
512 wpa_ie[i + 5], wpa_ie[i + 6], wpa_ie[i + 7]));
513 }
514 }
515
516 *wpa_len = in_ie[cnt + 1] + 2;
517 cnt += in_ie[cnt + 1] + 2;
518 } else {
519 if (authmode == _WPA2_IE_ID_) {
520 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
521 ("\n get_rsn_ie: sec_idx =%d in_ie[cnt+1]+2 =%d\n",
522 sec_idx, in_ie[cnt + 1] + 2));
523
524 if (rsn_ie) {
525 memcpy(rsn_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
526
527 for (i = 0; i < (in_ie[cnt + 1] + 2); i += 8) {
528 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
529 ("\n %2x,%2x,%2x,%2x,%2x,%2x,%2x,%2x\n",
530 rsn_ie[i], rsn_ie[i + 1], rsn_ie[i + 2], rsn_ie[i + 3], rsn_ie[i + 4],
531 rsn_ie[i + 5], rsn_ie[i + 6], rsn_ie[i + 7]));
532 }
533 }
534
535 *rsn_len = in_ie[cnt + 1] + 2;
536 cnt += in_ie[cnt + 1] + 2;
537 } else {
538 cnt += in_ie[cnt + 1] + 2;
539 }
540 }
541 }
542 }
543
544 u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen)
545 {
546 u8 match = false;
547 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
548
549 if (!ie_ptr)
550 return match;
551
552 eid = ie_ptr[0];
553
554 if ((eid == _WPA_IE_ID_) && (!memcmp(&ie_ptr[2], wps_oui, 4))) {
555 *wps_ielen = ie_ptr[1] + 2;
556 match = true;
557 }
558 return match;
559 }
560
561
562
563
564
565
566
567
568
569
570 u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)
571 {
572 uint cnt;
573 u8 *wpsie_ptr = NULL;
574 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
575
576 if (wps_ielen)
577 *wps_ielen = 0;
578
579 if (!in_ie || in_len <= 0)
580 return wpsie_ptr;
581
582 cnt = 0;
583
584 while (cnt < in_len) {
585 eid = in_ie[cnt];
586
587 if ((eid == _WPA_IE_ID_) && (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) {
588 wpsie_ptr = &in_ie[cnt];
589
590 if (wps_ie)
591 memcpy(wps_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
592
593 if (wps_ielen)
594 *wps_ielen = in_ie[cnt + 1] + 2;
595
596 cnt += in_ie[cnt + 1] + 2;
597
598 break;
599 } else {
600 cnt += in_ie[cnt + 1] + 2;
601 }
602 }
603 return wpsie_ptr;
604 }
605
606
607
608
609
610
611
612
613
614
615
616 u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attr, u32 *len_attr)
617 {
618 u8 *attr_ptr = NULL;
619 u8 *target_attr_ptr = NULL;
620 u8 wps_oui[4] = {0x00, 0x50, 0xF2, 0x04};
621
622 if (len_attr)
623 *len_attr = 0;
624
625 if ((wps_ie[0] != _VENDOR_SPECIFIC_IE_) ||
626 (memcmp(wps_ie + 2, wps_oui, 4)))
627 return attr_ptr;
628
629
630 attr_ptr = wps_ie + 6;
631
632 while (attr_ptr - wps_ie < wps_ielen) {
633
634 u16 attr_id = get_unaligned_be16(attr_ptr);
635 u16 attr_data_len = get_unaligned_be16(attr_ptr + 2);
636 u16 attr_len = attr_data_len + 4;
637
638 if (attr_id == target_attr_id) {
639 target_attr_ptr = attr_ptr;
640 if (buf_attr)
641 memcpy(buf_attr, attr_ptr, attr_len);
642 if (len_attr)
643 *len_attr = attr_len;
644 break;
645 } else {
646 attr_ptr += attr_len;
647 }
648 }
649 return target_attr_ptr;
650 }
651
652
653
654
655
656
657
658
659
660
661
662 u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_content, uint *len_content)
663 {
664 u8 *attr_ptr;
665 u32 attr_len;
666
667 if (len_content)
668 *len_content = 0;
669
670 attr_ptr = rtw_get_wps_attr(wps_ie, wps_ielen, target_attr_id, NULL, &attr_len);
671
672 if (attr_ptr && attr_len) {
673 if (buf_content)
674 memcpy(buf_content, attr_ptr + 4, attr_len - 4);
675
676 if (len_content)
677 *len_content = attr_len - 4;
678
679 return attr_ptr + 4;
680 }
681
682 return NULL;
683 }
684
685 static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen,
686 struct rtw_ieee802_11_elems *elems,
687 int show_errors)
688 {
689 unsigned int oui;
690
691
692
693
694 if (elen < 4) {
695 if (show_errors) {
696 DBG_88E("short vendor specific information element ignored (len=%lu)\n",
697 (unsigned long)elen);
698 }
699 return -1;
700 }
701
702 oui = RTW_GET_BE24(pos);
703 switch (oui) {
704 case OUI_MICROSOFT:
705
706
707 switch (pos[3]) {
708 case 1:
709
710
711 elems->wpa_ie = pos;
712 elems->wpa_ie_len = elen;
713 break;
714 case WME_OUI_TYPE:
715 if (elen < 5) {
716 DBG_88E("short WME information element ignored (len=%lu)\n",
717 (unsigned long)elen);
718 return -1;
719 }
720 switch (pos[4]) {
721 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
722 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
723 elems->wme = pos;
724 elems->wme_len = elen;
725 break;
726 case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
727 elems->wme_tspec = pos;
728 elems->wme_tspec_len = elen;
729 break;
730 default:
731 DBG_88E("unknown WME information element ignored (subtype=%d len=%lu)\n",
732 pos[4], (unsigned long)elen);
733 return -1;
734 }
735 break;
736 case 4:
737
738 elems->wps_ie = pos;
739 elems->wps_ie_len = elen;
740 break;
741 default:
742 DBG_88E("Unknown Microsoft information element ignored (type=%d len=%lu)\n",
743 pos[3], (unsigned long)elen);
744 return -1;
745 }
746 break;
747
748 case OUI_BROADCOM:
749 switch (pos[3]) {
750 case VENDOR_HT_CAPAB_OUI_TYPE:
751 elems->vendor_ht_cap = pos;
752 elems->vendor_ht_cap_len = elen;
753 break;
754 default:
755 DBG_88E("Unknown Broadcom information element ignored (type=%d len=%lu)\n",
756 pos[3], (unsigned long)elen);
757 return -1;
758 }
759 break;
760 default:
761 DBG_88E("unknown vendor specific information element ignored (vendor OUI %3phC len=%lu)\n",
762 pos, (unsigned long)elen);
763 return -1;
764 }
765 return 0;
766 }
767
768
769
770
771
772
773
774
775
776 enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len,
777 struct rtw_ieee802_11_elems *elems,
778 int show_errors)
779 {
780 uint left = len;
781 u8 *pos = start;
782 int unknown = 0;
783
784 memset(elems, 0, sizeof(*elems));
785
786 while (left >= 2) {
787 u8 id, elen;
788
789 id = *pos++;
790 elen = *pos++;
791 left -= 2;
792
793 if (elen > left) {
794 if (show_errors) {
795 DBG_88E("IEEE 802.11 element parse failed (id=%d elen=%d left=%lu)\n",
796 id, elen, (unsigned long)left);
797 }
798 return ParseFailed;
799 }
800
801 switch (id) {
802 case WLAN_EID_SSID:
803 elems->ssid = pos;
804 elems->ssid_len = elen;
805 break;
806 case WLAN_EID_SUPP_RATES:
807 elems->supp_rates = pos;
808 elems->supp_rates_len = elen;
809 break;
810 case WLAN_EID_FH_PARAMS:
811 elems->fh_params = pos;
812 elems->fh_params_len = elen;
813 break;
814 case WLAN_EID_DS_PARAMS:
815 elems->ds_params = pos;
816 elems->ds_params_len = elen;
817 break;
818 case WLAN_EID_CF_PARAMS:
819 elems->cf_params = pos;
820 elems->cf_params_len = elen;
821 break;
822 case WLAN_EID_TIM:
823 elems->tim = pos;
824 elems->tim_len = elen;
825 break;
826 case WLAN_EID_IBSS_PARAMS:
827 elems->ibss_params = pos;
828 elems->ibss_params_len = elen;
829 break;
830 case WLAN_EID_CHALLENGE:
831 elems->challenge = pos;
832 elems->challenge_len = elen;
833 break;
834 case WLAN_EID_ERP_INFO:
835 elems->erp_info = pos;
836 elems->erp_info_len = elen;
837 break;
838 case WLAN_EID_EXT_SUPP_RATES:
839 elems->ext_supp_rates = pos;
840 elems->ext_supp_rates_len = elen;
841 break;
842 case WLAN_EID_VENDOR_SPECIFIC:
843 if (rtw_ieee802_11_parse_vendor_specific(pos, elen, elems, show_errors))
844 unknown++;
845 break;
846 case WLAN_EID_RSN:
847 elems->rsn_ie = pos;
848 elems->rsn_ie_len = elen;
849 break;
850 case WLAN_EID_PWR_CAPABILITY:
851 elems->power_cap = pos;
852 elems->power_cap_len = elen;
853 break;
854 case WLAN_EID_SUPPORTED_CHANNELS:
855 elems->supp_channels = pos;
856 elems->supp_channels_len = elen;
857 break;
858 case WLAN_EID_MOBILITY_DOMAIN:
859 elems->mdie = pos;
860 elems->mdie_len = elen;
861 break;
862 case WLAN_EID_FAST_BSS_TRANSITION:
863 elems->ftie = pos;
864 elems->ftie_len = elen;
865 break;
866 case WLAN_EID_TIMEOUT_INTERVAL:
867 elems->timeout_int = pos;
868 elems->timeout_int_len = elen;
869 break;
870 case WLAN_EID_HT_CAPABILITY:
871 elems->ht_capabilities = pos;
872 elems->ht_capabilities_len = elen;
873 break;
874 case WLAN_EID_HT_OPERATION:
875 elems->ht_operation = pos;
876 elems->ht_operation_len = elen;
877 break;
878 default:
879 unknown++;
880 if (!show_errors)
881 break;
882 DBG_88E("IEEE 802.11 element parse ignored unknown element (id=%d elen=%d)\n",
883 id, elen);
884 break;
885 }
886 left -= elen;
887 pos += elen;
888 }
889 if (left)
890 return ParseFailed;
891 return unknown ? ParseUnknown : ParseOK;
892 }
893
894 void rtw_macaddr_cfg(u8 *mac_addr)
895 {
896 u8 mac[ETH_ALEN];
897
898 if (!mac_addr)
899 return;
900
901 if (rtw_initmac && mac_pton(rtw_initmac, mac)) {
902
903 ether_addr_copy(mac_addr, mac);
904 } else {
905
906 ether_addr_copy(mac, mac_addr);
907 }
908
909 if (is_broadcast_ether_addr(mac) || is_zero_ether_addr(mac)) {
910 eth_random_addr(mac_addr);
911 DBG_88E("MAC Address from efuse error, assign random one !!!\n");
912 }
913
914 DBG_88E("%s MAC Address = %pM\n", __func__, mac_addr);
915 }
916
917 static int rtw_get_cipher_info(struct wlan_network *pnetwork)
918 {
919 uint wpa_ielen;
920 unsigned char *pbuf;
921 int group_cipher = 0, pairwise_cipher = 0, is8021x = 0;
922 int ret = _FAIL;
923
924 pbuf = rtw_get_wpa_ie(&pnetwork->network.ies[12], &wpa_ielen, pnetwork->network.ie_length - 12);
925
926 if (pbuf && (wpa_ielen > 0)) {
927 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_ielen: %d", __func__, wpa_ielen));
928 if (rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) {
929 pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher;
930 pnetwork->BcnInfo.group_cipher = group_cipher;
931 pnetwork->BcnInfo.is_8021x = is8021x;
932 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: pnetwork->pairwise_cipher: %d, is_8021x is %d",
933 __func__, pnetwork->BcnInfo.pairwise_cipher, pnetwork->BcnInfo.is_8021x));
934 ret = _SUCCESS;
935 }
936 } else {
937 pbuf = rtw_get_wpa2_ie(&pnetwork->network.ies[12], &wpa_ielen, pnetwork->network.ie_length - 12);
938
939 if (pbuf && (wpa_ielen > 0)) {
940 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("get RSN IE\n"));
941 if (rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) {
942 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("get RSN IE OK!!!\n"));
943 pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher;
944 pnetwork->BcnInfo.group_cipher = group_cipher;
945 pnetwork->BcnInfo.is_8021x = is8021x;
946 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: pnetwork->pairwise_cipher: %d,"
947 "pnetwork->group_cipher is %d, is_8021x is %d", __func__, pnetwork->BcnInfo.pairwise_cipher,
948 pnetwork->BcnInfo.group_cipher, pnetwork->BcnInfo.is_8021x));
949 ret = _SUCCESS;
950 }
951 }
952 }
953
954 return ret;
955 }
956
957 void rtw_get_bcn_info(struct wlan_network *pnetwork)
958 {
959 unsigned short cap = 0;
960 u8 bencrypt = 0;
961 __le16 le_tmp;
962 u16 wpa_len = 0, rsn_len = 0;
963 struct HT_info_element *pht_info = NULL;
964 uint len;
965 unsigned char *p;
966
967 memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.ies), 2);
968 cap = le16_to_cpu(le_tmp);
969 if (cap & WLAN_CAPABILITY_PRIVACY) {
970 bencrypt = 1;
971 pnetwork->network.Privacy = 1;
972 } else {
973 pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS;
974 }
975 rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, NULL, &rsn_len, NULL, &wpa_len);
976 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.ssid.ssid));
977 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_len =%d rsn_len =%d\n", __func__, wpa_len, rsn_len));
978 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.ssid.ssid));
979 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_len =%d rsn_len =%d\n", __func__, wpa_len, rsn_len));
980
981 if (rsn_len > 0) {
982 pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2;
983 } else if (wpa_len > 0) {
984 pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA;
985 } else {
986 if (bencrypt)
987 pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP;
988 }
989 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_get_bcn_info: pnetwork->encryp_protocol is %x\n",
990 pnetwork->BcnInfo.encryp_protocol));
991 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_get_bcn_info: pnetwork->encryp_protocol is %x\n",
992 pnetwork->BcnInfo.encryp_protocol));
993 rtw_get_cipher_info(pnetwork);
994
995
996
997 p = rtw_get_ie(pnetwork->network.ies + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pnetwork->network.ie_length - _FIXED_IE_LENGTH_);
998 if (p && len > 0) {
999 struct ieee80211_ht_cap *ht_cap =
1000 (struct ieee80211_ht_cap *)(p + 2);
1001
1002 pnetwork->BcnInfo.ht_cap_info = le16_to_cpu(ht_cap->cap_info);
1003 } else {
1004 pnetwork->BcnInfo.ht_cap_info = 0;
1005 }
1006
1007 p = rtw_get_ie(pnetwork->network.ies + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, pnetwork->network.ie_length - _FIXED_IE_LENGTH_);
1008 if (p && len > 0) {
1009 pht_info = (struct HT_info_element *)(p + 2);
1010 pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0];
1011 } else {
1012 pnetwork->BcnInfo.ht_info_infos_0 = 0;
1013 }
1014 }
1015
1016
1017 u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char *MCS_rate)
1018 {
1019 u16 max_rate = 0;
1020
1021 if (rf_type == RF_1T1R) {
1022 if (MCS_rate[0] & BIT(7))
1023 max_rate = (bw_40MHz) ? ((short_GI_40) ? 1500 : 1350) : ((short_GI_20) ? 722 : 650);
1024 else if (MCS_rate[0] & BIT(6))
1025 max_rate = (bw_40MHz) ? ((short_GI_40) ? 1350 : 1215) : ((short_GI_20) ? 650 : 585);
1026 else if (MCS_rate[0] & BIT(5))
1027 max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520);
1028 else if (MCS_rate[0] & BIT(4))
1029 max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390);
1030 else if (MCS_rate[0] & BIT(3))
1031 max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260);
1032 else if (MCS_rate[0] & BIT(2))
1033 max_rate = (bw_40MHz) ? ((short_GI_40) ? 450 : 405) : ((short_GI_20) ? 217 : 195);
1034 else if (MCS_rate[0] & BIT(1))
1035 max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130);
1036 else if (MCS_rate[0] & BIT(0))
1037 max_rate = (bw_40MHz) ? ((short_GI_40) ? 150 : 135) : ((short_GI_20) ? 72 : 65);
1038 } else {
1039 if (MCS_rate[1]) {
1040 if (MCS_rate[1] & BIT(7))
1041 max_rate = (bw_40MHz) ? ((short_GI_40) ? 3000 : 2700) : ((short_GI_20) ? 1444 : 1300);
1042 else if (MCS_rate[1] & BIT(6))
1043 max_rate = (bw_40MHz) ? ((short_GI_40) ? 2700 : 2430) : ((short_GI_20) ? 1300 : 1170);
1044 else if (MCS_rate[1] & BIT(5))
1045 max_rate = (bw_40MHz) ? ((short_GI_40) ? 2400 : 2160) : ((short_GI_20) ? 1156 : 1040);
1046 else if (MCS_rate[1] & BIT(4))
1047 max_rate = (bw_40MHz) ? ((short_GI_40) ? 1800 : 1620) : ((short_GI_20) ? 867 : 780);
1048 else if (MCS_rate[1] & BIT(3))
1049 max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520);
1050 else if (MCS_rate[1] & BIT(2))
1051 max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390);
1052 else if (MCS_rate[1] & BIT(1))
1053 max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260);
1054 else if (MCS_rate[1] & BIT(0))
1055 max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130);
1056 } else {
1057 if (MCS_rate[0] & BIT(7))
1058 max_rate = (bw_40MHz) ? ((short_GI_40) ? 1500 : 1350) : ((short_GI_20) ? 722 : 650);
1059 else if (MCS_rate[0] & BIT(6))
1060 max_rate = (bw_40MHz) ? ((short_GI_40) ? 1350 : 1215) : ((short_GI_20) ? 650 : 585);
1061 else if (MCS_rate[0] & BIT(5))
1062 max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520);
1063 else if (MCS_rate[0] & BIT(4))
1064 max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390);
1065 else if (MCS_rate[0] & BIT(3))
1066 max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260);
1067 else if (MCS_rate[0] & BIT(2))
1068 max_rate = (bw_40MHz) ? ((short_GI_40) ? 450 : 405) : ((short_GI_20) ? 217 : 195);
1069 else if (MCS_rate[0] & BIT(1))
1070 max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130);
1071 else if (MCS_rate[0] & BIT(0))
1072 max_rate = (bw_40MHz) ? ((short_GI_40) ? 150 : 135) : ((short_GI_20) ? 72 : 65);
1073 }
1074 }
1075 return max_rate;
1076 }