1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 #define _IEEE80211_C 8 9 #include <drv_types.h> 10 #include <rtw_debug.h> 11 #include <linux/of.h> 12 #include <asm/unaligned.h> 13 14 u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; 15 u16 RTW_WPA_VERSION = 1; 16 u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 }; 17 u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 }; 18 u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 }; 19 u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 }; 20 u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 }; 21 u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 }; 22 u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 }; 23 u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 }; 24 u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 }; 25 26 u16 RSN_VERSION_BSD = 1; 27 u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 }; 28 u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 }; 29 u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 }; 30 u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; 31 u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; 32 u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 }; 33 u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; 34 u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; 35 /* */ 36 /* for adhoc-master to generate ie and provide supported-rate to fw */ 37 /* */ 38 39 static u8 WIFI_CCKRATES[] = { 40 (IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK), 41 (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK), 42 (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK), 43 (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK) 44 }; 45 46 static u8 WIFI_OFDMRATES[] = { 47 (IEEE80211_OFDM_RATE_6MB), 48 (IEEE80211_OFDM_RATE_9MB), 49 (IEEE80211_OFDM_RATE_12MB), 50 (IEEE80211_OFDM_RATE_18MB), 51 (IEEE80211_OFDM_RATE_24MB), 52 IEEE80211_OFDM_RATE_36MB, 53 IEEE80211_OFDM_RATE_48MB, 54 IEEE80211_OFDM_RATE_54MB 55 }; 56 57 int rtw_get_bit_value_from_ieee_value(u8 val) 58 { 59 unsigned char dot11_rate_table[] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 0}; /* last element must be zero!! */ 60 int i = 0; 61 62 while (dot11_rate_table[i] != 0) { 63 if (dot11_rate_table[i] == val) 64 return BIT(i); 65 i++; 66 } 67 return 0; 68 } 69 70 bool rtw_is_cckrates_included(u8 *rate) 71 { 72 while (*rate) { 73 u8 r = *rate & 0x7f; 74 75 if (r == 2 || r == 4 || r == 11 || r == 22) 76 return true; 77 rate++; 78 } 79 80 return false; 81 } 82 83 bool rtw_is_cckratesonly_included(u8 *rate) 84 { 85 while (*rate) { 86 u8 r = *rate & 0x7f; 87 88 if (r != 2 && r != 4 && r != 11 && r != 22) 89 return false; 90 rate++; 91 } 92 93 return true; 94 } 95 96 int rtw_check_network_type(unsigned char *rate, int ratelen, int channel) 97 { 98 if (channel > 14) { 99 return WIRELESS_INVALID; 100 } else { /* could be pure B, pure G, or B/G */ 101 if (rtw_is_cckratesonly_included(rate)) 102 return WIRELESS_11B; 103 else if (rtw_is_cckrates_included(rate)) 104 return WIRELESS_11BG; 105 else 106 return WIRELESS_11G; 107 } 108 } 109 110 u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source, 111 unsigned int *frlen) 112 { 113 memcpy((void *)pbuf, (void *)source, len); 114 *frlen = *frlen + len; 115 return pbuf + len; 116 } 117 118 /* rtw_set_ie will update frame length */ 119 u8 *rtw_set_ie(u8 *pbuf, 120 signed int index, 121 uint len, 122 u8 *source, 123 uint *frlen) /* frame length */ 124 { 125 *pbuf = (u8)index; 126 127 *(pbuf + 1) = (u8)len; 128 129 if (len > 0) 130 memcpy((void *)(pbuf + 2), (void *)source, len); 131 132 *frlen = *frlen + (len + 2); 133 134 return pbuf + len + 2; 135 } 136 137 /*---------------------------------------------------------------------------- 138 index: the information element id index, limit is the limit for search 139 -----------------------------------------------------------------------------*/ 140 u8 *rtw_get_ie(u8 *pbuf, signed int index, signed int *len, signed int limit) 141 { 142 signed int tmp, i; 143 u8 *p; 144 145 if (limit < 1) 146 return NULL; 147 148 p = pbuf; 149 i = 0; 150 *len = 0; 151 while (1) { 152 if (*p == index) { 153 *len = *(p + 1); 154 return p; 155 } else { 156 tmp = *(p + 1); 157 p += (tmp + 2); 158 i += (tmp + 2); 159 } 160 if (i >= limit) 161 break; 162 } 163 return NULL; 164 } 165 166 /** 167 * rtw_get_ie_ex - Search specific IE from a series of IEs 168 * @in_ie: Address of IEs to search 169 * @in_len: Length limit from in_ie 170 * @eid: Element ID to match 171 * @oui: OUI to match 172 * @oui_len: OUI length 173 * @ie: If not NULL and the specific IE is found, the IE will be copied to the buf starting from the specific IE 174 * @ielen: If not NULL and the specific IE is found, will set to the length of the entire IE 175 * 176 * Returns: The address of the specific IE found, or NULL 177 */ 178 u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen) 179 { 180 uint cnt; 181 u8 *target_ie = NULL; 182 183 if (ielen) 184 *ielen = 0; 185 186 if (!in_ie || in_len <= 0) 187 return target_ie; 188 189 cnt = 0; 190 191 while (cnt < in_len) { 192 if (eid == in_ie[cnt] 193 && (!oui || !memcmp(&in_ie[cnt+2], oui, oui_len))) { 194 target_ie = &in_ie[cnt]; 195 196 if (ie) 197 memcpy(ie, &in_ie[cnt], in_ie[cnt+1]+2); 198 199 if (ielen) 200 *ielen = in_ie[cnt+1]+2; 201 202 break; 203 } else { 204 cnt += in_ie[cnt+1]+2; /* goto next */ 205 } 206 } 207 208 return target_ie; 209 } 210 211 /** 212 * rtw_ies_remove_ie - Find matching IEs and remove 213 * @ies: Address of IEs to search 214 * @ies_len: Pointer of length of ies, will update to new length 215 * @offset: The offset to start search 216 * @eid: Element ID to match 217 * @oui: OUI to match 218 * @oui_len: OUI length 219 * 220 * Returns: _SUCCESS: ies is updated, _FAIL: not updated 221 */ 222 int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len) 223 { 224 int ret = _FAIL; 225 u8 *target_ie; 226 u32 target_ielen; 227 u8 *start; 228 uint search_len; 229 230 if (!ies || !ies_len || *ies_len <= offset) 231 goto exit; 232 233 start = ies + offset; 234 search_len = *ies_len - offset; 235 236 while (1) { 237 target_ie = rtw_get_ie_ex(start, search_len, eid, oui, oui_len, NULL, &target_ielen); 238 if (target_ie && target_ielen) { 239 u8 *remain_ies = target_ie + target_ielen; 240 uint remain_len = search_len - (remain_ies - start); 241 242 memcpy(target_ie, remain_ies, remain_len); 243 *ies_len = *ies_len - target_ielen; 244 ret = _SUCCESS; 245 246 start = target_ie; 247 search_len = remain_len; 248 } else { 249 break; 250 } 251 } 252 exit: 253 return ret; 254 } 255 256 void rtw_set_supported_rate(u8 *SupportedRates, uint mode) 257 { 258 memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); 259 260 switch (mode) { 261 case WIRELESS_11B: 262 memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); 263 break; 264 265 case WIRELESS_11G: 266 memcpy(SupportedRates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN); 267 break; 268 269 case WIRELESS_11BG: 270 case WIRELESS_11G_24N: 271 case WIRELESS_11_24N: 272 case WIRELESS_11BG_24N: 273 memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); 274 memcpy(SupportedRates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN); 275 break; 276 } 277 } 278 279 uint rtw_get_rateset_len(u8 *rateset) 280 { 281 uint i; 282 283 for (i = 0; i < 13; i++) 284 if (rateset[i] == 0) 285 break; 286 return i; 287 } 288 289 int rtw_generate_ie(struct registry_priv *pregistrypriv) 290 { 291 u8 wireless_mode; 292 int sz = 0, rateLen; 293 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 294 u8 *ie = pdev_network->IEs; 295 296 /* timestamp will be inserted by hardware */ 297 sz += 8; 298 ie += sz; 299 300 /* beacon interval : 2bytes */ 301 *(__le16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);/* BCN_INTERVAL; */ 302 sz += 2; 303 ie += 2; 304 305 /* capability info */ 306 *(u16 *)ie = 0; 307 308 *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_IBSS); 309 310 if (pregistrypriv->preamble == PREAMBLE_SHORT) 311 *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); 312 313 if (pdev_network->Privacy) 314 *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); 315 316 sz += 2; 317 ie += 2; 318 319 /* SSID */ 320 ie = rtw_set_ie(ie, WLAN_EID_SSID, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz); 321 322 /* supported rates */ 323 wireless_mode = pregistrypriv->wireless_mode; 324 325 rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode); 326 327 rateLen = rtw_get_rateset_len(pdev_network->SupportedRates); 328 329 if (rateLen > 8) { 330 ie = rtw_set_ie(ie, WLAN_EID_SUPP_RATES, 8, pdev_network->SupportedRates, &sz); 331 /* ie = rtw_set_ie(ie, WLAN_EID_EXT_SUPP_RATES, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); */ 332 } else { 333 ie = rtw_set_ie(ie, WLAN_EID_SUPP_RATES, rateLen, pdev_network->SupportedRates, &sz); 334 } 335 336 /* DS parameter set */ 337 ie = rtw_set_ie(ie, WLAN_EID_DS_PARAMS, 1, (u8 *)&(pdev_network->Configuration.DSConfig), &sz); 338 339 /* IBSS Parameter Set */ 340 341 ie = rtw_set_ie(ie, WLAN_EID_IBSS_PARAMS, 2, (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz); 342 343 if (rateLen > 8) { 344 ie = rtw_set_ie(ie, WLAN_EID_EXT_SUPP_RATES, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); 345 } 346 347 /* HT Cap. */ 348 if ((pregistrypriv->wireless_mode & WIRELESS_11_24N) && 349 (pregistrypriv->ht_enable == true)) { 350 /* todo: */ 351 } 352 353 /* pdev_network->IELength = sz; update IELength */ 354 355 /* return _SUCCESS; */ 356 357 return sz; 358 } 359 360 unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) 361 { 362 int len; 363 u16 val16; 364 unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; 365 u8 *pbuf = pie; 366 int limit_new = limit; 367 __le16 le_tmp; 368 369 while (1) { 370 pbuf = rtw_get_ie(pbuf, WLAN_EID_VENDOR_SPECIFIC, &len, limit_new); 371 372 if (pbuf) { 373 /* check if oui matches... */ 374 if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type))) { 375 goto check_next_ie; 376 } 377 378 /* check version... */ 379 memcpy((u8 *)&le_tmp, (pbuf + 6), sizeof(val16)); 380 381 val16 = le16_to_cpu(le_tmp); 382 if (val16 != 0x0001) 383 goto check_next_ie; 384 385 *wpa_ie_len = *(pbuf + 1); 386 387 return pbuf; 388 389 } else { 390 *wpa_ie_len = 0; 391 return NULL; 392 } 393 394 check_next_ie: 395 396 limit_new = limit - (pbuf - pie) - 2 - len; 397 398 if (limit_new <= 0) 399 break; 400 401 pbuf += (2 + len); 402 } 403 404 *wpa_ie_len = 0; 405 406 return NULL; 407 } 408 409 unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit) 410 { 411 return rtw_get_ie(pie, WLAN_EID_RSN, rsn_ie_len, limit); 412 } 413 414 int rtw_get_wpa_cipher_suite(u8 *s) 415 { 416 if (!memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN)) 417 return WPA_CIPHER_NONE; 418 if (!memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN)) 419 return WPA_CIPHER_WEP40; 420 if (!memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN)) 421 return WPA_CIPHER_TKIP; 422 if (!memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN)) 423 return WPA_CIPHER_CCMP; 424 if (!memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN)) 425 return WPA_CIPHER_WEP104; 426 427 return 0; 428 } 429 430 int rtw_get_wpa2_cipher_suite(u8 *s) 431 { 432 if (!memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN)) 433 return WPA_CIPHER_NONE; 434 if (!memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN)) 435 return WPA_CIPHER_WEP40; 436 if (!memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN)) 437 return WPA_CIPHER_TKIP; 438 if (!memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN)) 439 return WPA_CIPHER_CCMP; 440 if (!memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN)) 441 return WPA_CIPHER_WEP104; 442 443 return 0; 444 } 445 446 int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) 447 { 448 int i, ret = _SUCCESS; 449 int left, count; 450 u8 *pos; 451 u8 SUITE_1X[4] = {0x00, 0x50, 0xf2, 1}; 452 453 if (wpa_ie_len <= 0) { 454 /* No WPA IE - fail silently */ 455 return _FAIL; 456 } 457 458 if ((*wpa_ie != WLAN_EID_VENDOR_SPECIFIC) || (*(wpa_ie+1) != (u8)(wpa_ie_len - 2)) || 459 (memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN))) { 460 return _FAIL; 461 } 462 463 pos = wpa_ie; 464 465 pos += 8; 466 left = wpa_ie_len - 8; 467 468 /* group_cipher */ 469 if (left >= WPA_SELECTOR_LEN) { 470 *group_cipher = rtw_get_wpa_cipher_suite(pos); 471 472 pos += WPA_SELECTOR_LEN; 473 left -= WPA_SELECTOR_LEN; 474 475 } else if (left > 0) 476 return _FAIL; 477 478 /* pairwise_cipher */ 479 if (left >= 2) { 480 /* count = le16_to_cpu(*(u16*)pos); */ 481 count = get_unaligned_le16(pos); 482 pos += 2; 483 left -= 2; 484 485 if (count == 0 || left < count * WPA_SELECTOR_LEN) 486 return _FAIL; 487 488 for (i = 0; i < count; i++) { 489 *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos); 490 491 pos += WPA_SELECTOR_LEN; 492 left -= WPA_SELECTOR_LEN; 493 } 494 495 } else if (left == 1) 496 return _FAIL; 497 498 if (is_8021x) { 499 if (left >= 6) { 500 pos += 2; 501 if (!memcmp(pos, SUITE_1X, 4)) { 502 *is_8021x = 1; 503 } 504 } 505 } 506 507 return ret; 508 } 509 510 int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) 511 { 512 int i, ret = _SUCCESS; 513 int left, count; 514 u8 *pos; 515 u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01}; 516 517 if (rsn_ie_len <= 0) { 518 /* No RSN IE - fail silently */ 519 return _FAIL; 520 } 521 522 if ((*rsn_ie != WLAN_EID_RSN) || (*(rsn_ie+1) != (u8)(rsn_ie_len - 2))) { 523 return _FAIL; 524 } 525 526 pos = rsn_ie; 527 pos += 4; 528 left = rsn_ie_len - 4; 529 530 /* group_cipher */ 531 if (left >= RSN_SELECTOR_LEN) { 532 *group_cipher = rtw_get_wpa2_cipher_suite(pos); 533 534 pos += RSN_SELECTOR_LEN; 535 left -= RSN_SELECTOR_LEN; 536 537 } else if (left > 0) 538 return _FAIL; 539 540 /* pairwise_cipher */ 541 if (left >= 2) { 542 /* count = le16_to_cpu(*(u16*)pos); */ 543 count = get_unaligned_le16(pos); 544 pos += 2; 545 left -= 2; 546 547 if (count == 0 || left < count * RSN_SELECTOR_LEN) 548 return _FAIL; 549 550 for (i = 0; i < count; i++) { 551 *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos); 552 553 pos += RSN_SELECTOR_LEN; 554 left -= RSN_SELECTOR_LEN; 555 } 556 557 } else if (left == 1) 558 return _FAIL; 559 560 if (is_8021x) { 561 if (left >= 6) { 562 pos += 2; 563 if (!memcmp(pos, SUITE_1X, 4)) 564 *is_8021x = 1; 565 } 566 } 567 568 return ret; 569 } 570 571 /* ifdef CONFIG_WAPI_SUPPORT */ 572 int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len) 573 { 574 int len = 0; 575 u8 authmode; 576 uint cnt; 577 u8 wapi_oui1[4] = {0x0, 0x14, 0x72, 0x01}; 578 u8 wapi_oui2[4] = {0x0, 0x14, 0x72, 0x02}; 579 580 if (wapi_len) 581 *wapi_len = 0; 582 583 if (!in_ie || in_len <= 0) 584 return len; 585 586 cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); 587 588 while (cnt < in_len) { 589 authmode = in_ie[cnt]; 590 591 /* if (authmode == WLAN_EID_BSS_AC_ACCESS_DELAY) */ 592 if (authmode == WLAN_EID_BSS_AC_ACCESS_DELAY && (!memcmp(&in_ie[cnt+6], wapi_oui1, 4) || 593 !memcmp(&in_ie[cnt+6], wapi_oui2, 4))) { 594 if (wapi_ie) 595 memcpy(wapi_ie, &in_ie[cnt], in_ie[cnt+1]+2); 596 597 if (wapi_len) 598 *wapi_len = in_ie[cnt+1]+2; 599 600 cnt += in_ie[cnt+1]+2; /* get next */ 601 } else { 602 cnt += in_ie[cnt+1]+2; /* get next */ 603 } 604 } 605 606 if (wapi_len) 607 len = *wapi_len; 608 609 return len; 610 } 611 /* endif */ 612 613 void rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len) 614 { 615 u8 authmode; 616 u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; 617 uint cnt; 618 619 /* Search required WPA or WPA2 IE and copy to sec_ie[ ] */ 620 621 cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); 622 623 while (cnt < in_len) { 624 authmode = in_ie[cnt]; 625 626 if ((authmode == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&in_ie[cnt+2], &wpa_oui[0], 4))) { 627 if (wpa_ie) 628 memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt+1]+2); 629 630 *wpa_len = in_ie[cnt + 1] + 2; 631 cnt += in_ie[cnt + 1] + 2; /* get next */ 632 } else { 633 if (authmode == WLAN_EID_RSN) { 634 if (rsn_ie) 635 memcpy(rsn_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); 636 637 *rsn_len = in_ie[cnt+1]+2; 638 cnt += in_ie[cnt+1]+2; /* get next */ 639 } else { 640 cnt += in_ie[cnt+1]+2; /* get next */ 641 } 642 } 643 } 644 } 645 646 u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen) 647 { 648 u8 match = false; 649 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 650 651 if (!ie_ptr) 652 return match; 653 654 eid = ie_ptr[0]; 655 656 if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&ie_ptr[2], wps_oui, 4))) { 657 *wps_ielen = ie_ptr[1]+2; 658 match = true; 659 } 660 return match; 661 } 662 663 /** 664 * rtw_get_wps_ie - Search WPS IE from a series of IEs 665 * @in_ie: Address of IEs to search 666 * @in_len: Length limit from in_ie 667 * @wps_ie: If not NULL and WPS IE is found, WPS IE will be copied to the buf starting from wps_ie 668 * @wps_ielen: If not NULL and WPS IE is found, will set to the length of the entire WPS IE 669 * 670 * Returns: The address of the WPS IE found, or NULL 671 */ 672 u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) 673 { 674 uint cnt; 675 u8 *wpsie_ptr = NULL; 676 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; 677 678 if (wps_ielen) 679 *wps_ielen = 0; 680 681 if (!in_ie || in_len <= 0) 682 return wpsie_ptr; 683 684 cnt = 0; 685 686 while (cnt < in_len) { 687 eid = in_ie[cnt]; 688 689 if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&in_ie[cnt+2], wps_oui, 4))) { 690 wpsie_ptr = &in_ie[cnt]; 691 692 if (wps_ie) 693 memcpy(wps_ie, &in_ie[cnt], in_ie[cnt+1]+2); 694 695 if (wps_ielen) 696 *wps_ielen = in_ie[cnt+1]+2; 697 698 cnt += in_ie[cnt+1]+2; 699 700 break; 701 } else { 702 cnt += in_ie[cnt+1]+2; /* goto next */ 703 } 704 } 705 706 return wpsie_ptr; 707 } 708 709 /** 710 * rtw_get_wps_attr - Search a specific WPS attribute from a given WPS IE 711 * @wps_ie: Address of WPS IE to search 712 * @wps_ielen: Length limit from wps_ie 713 * @target_attr_id: The attribute ID of WPS attribute to search 714 * @buf_attr: If not NULL and the WPS attribute is found, WPS attribute will be copied to the buf starting from buf_attr 715 * @len_attr: If not NULL and the WPS attribute is found, will set to the length of the entire WPS attribute 716 * 717 * Returns: the address of the specific WPS attribute found, or NULL 718 */ 719 u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attr, u32 *len_attr) 720 { 721 u8 *attr_ptr = NULL; 722 u8 *target_attr_ptr = NULL; 723 u8 wps_oui[4] = {0x00, 0x50, 0xF2, 0x04}; 724 725 if (len_attr) 726 *len_attr = 0; 727 728 if ((wps_ie[0] != WLAN_EID_VENDOR_SPECIFIC) || 729 (memcmp(wps_ie + 2, wps_oui, 4))) { 730 return attr_ptr; 731 } 732 733 /* 6 = 1(Element ID) + 1(Length) + 4(WPS OUI) */ 734 attr_ptr = wps_ie + 6; /* goto first attr */ 735 736 while (attr_ptr - wps_ie < wps_ielen) { 737 /* 4 = 2(Attribute ID) + 2(Length) */ 738 u16 attr_id = get_unaligned_be16(attr_ptr); 739 u16 attr_data_len = get_unaligned_be16(attr_ptr + 2); 740 u16 attr_len = attr_data_len + 4; 741 742 if (attr_id == target_attr_id) { 743 target_attr_ptr = attr_ptr; 744 745 if (buf_attr) 746 memcpy(buf_attr, attr_ptr, attr_len); 747 748 if (len_attr) 749 *len_attr = attr_len; 750 751 break; 752 } else { 753 attr_ptr += attr_len; /* goto next */ 754 } 755 } 756 757 return target_attr_ptr; 758 } 759 760 /** 761 * rtw_get_wps_attr_content - Search a specific WPS attribute content from a given WPS IE 762 * @wps_ie: Address of WPS IE to search 763 * @wps_ielen: Length limit from wps_ie 764 * @target_attr_id: The attribute ID of WPS attribute to search 765 * @buf_content: If not NULL and the WPS attribute is found, WPS attribute content will be copied to the buf starting from buf_content 766 * @len_content: If not NULL and the WPS attribute is found, will set to the length of the WPS attribute content 767 * 768 * Returns: the address of the specific WPS attribute content found, or NULL 769 */ 770 u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_content, uint *len_content) 771 { 772 u8 *attr_ptr; 773 u32 attr_len; 774 775 if (len_content) 776 *len_content = 0; 777 778 attr_ptr = rtw_get_wps_attr(wps_ie, wps_ielen, target_attr_id, NULL, &attr_len); 779 780 if (attr_ptr && attr_len) { 781 if (buf_content) 782 memcpy(buf_content, attr_ptr+4, attr_len-4); 783 784 if (len_content) 785 *len_content = attr_len-4; 786 787 return attr_ptr+4; 788 } 789 790 return NULL; 791 } 792 793 static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, 794 struct rtw_ieee802_11_elems *elems, 795 int show_errors) 796 { 797 unsigned int oui; 798 799 /* first 3 bytes in vendor specific information element are the IEEE 800 * OUI of the vendor. The following byte is used a vendor specific 801 * sub-type. */ 802 if (elen < 4) 803 return -1; 804 805 oui = get_unaligned_be24(pos); 806 switch (oui) { 807 case OUI_MICROSOFT: 808 /* Microsoft/Wi-Fi information elements are further typed and 809 * subtyped */ 810 switch (pos[3]) { 811 case 1: 812 /* Microsoft OUI (00:50:F2) with OUI Type 1: 813 * real WPA information element */ 814 elems->wpa_ie = pos; 815 elems->wpa_ie_len = elen; 816 break; 817 case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ 818 if (elen < 5) 819 return -1; 820 821 switch (pos[4]) { 822 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: 823 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: 824 elems->wme = pos; 825 elems->wme_len = elen; 826 break; 827 case WME_OUI_SUBTYPE_TSPEC_ELEMENT: 828 elems->wme_tspec = pos; 829 elems->wme_tspec_len = elen; 830 break; 831 default: 832 return -1; 833 } 834 break; 835 case 4: 836 /* Wi-Fi Protected Setup (WPS) IE */ 837 elems->wps_ie = pos; 838 elems->wps_ie_len = elen; 839 break; 840 default: 841 return -1; 842 } 843 break; 844 845 case OUI_BROADCOM: 846 switch (pos[3]) { 847 case VENDOR_HT_CAPAB_OUI_TYPE: 848 elems->vendor_ht_cap = pos; 849 elems->vendor_ht_cap_len = elen; 850 break; 851 default: 852 return -1; 853 } 854 break; 855 856 default: 857 return -1; 858 } 859 860 return 0; 861 } 862 863 /** 864 * rtw_ieee802_11_parse_elems - Parse information elements in management frames 865 * @start: Pointer to the start of IEs 866 * @len: Length of IE buffer in octets 867 * @elems: Data structure for parsed elements 868 * @show_errors: Whether to show parsing errors in debug log 869 * Returns: Parsing result 870 */ 871 enum ParseRes rtw_ieee802_11_parse_elems(u8 *start, uint len, 872 struct rtw_ieee802_11_elems *elems, 873 int show_errors) 874 { 875 uint left = len; 876 u8 *pos = start; 877 int unknown = 0; 878 879 memset(elems, 0, sizeof(*elems)); 880 881 while (left >= 2) { 882 u8 id, elen; 883 884 id = *pos++; 885 elen = *pos++; 886 left -= 2; 887 888 if (elen > left) 889 return ParseFailed; 890 891 switch (id) { 892 case WLAN_EID_SSID: 893 elems->ssid = pos; 894 elems->ssid_len = elen; 895 break; 896 case WLAN_EID_SUPP_RATES: 897 elems->supp_rates = pos; 898 elems->supp_rates_len = elen; 899 break; 900 case WLAN_EID_FH_PARAMS: 901 elems->fh_params = pos; 902 elems->fh_params_len = elen; 903 break; 904 case WLAN_EID_DS_PARAMS: 905 elems->ds_params = pos; 906 elems->ds_params_len = elen; 907 break; 908 case WLAN_EID_CF_PARAMS: 909 elems->cf_params = pos; 910 elems->cf_params_len = elen; 911 break; 912 case WLAN_EID_TIM: 913 elems->tim = pos; 914 elems->tim_len = elen; 915 break; 916 case WLAN_EID_IBSS_PARAMS: 917 elems->ibss_params = pos; 918 elems->ibss_params_len = elen; 919 break; 920 case WLAN_EID_CHALLENGE: 921 elems->challenge = pos; 922 elems->challenge_len = elen; 923 break; 924 case WLAN_EID_ERP_INFO: 925 elems->erp_info = pos; 926 elems->erp_info_len = elen; 927 break; 928 case WLAN_EID_EXT_SUPP_RATES: 929 elems->ext_supp_rates = pos; 930 elems->ext_supp_rates_len = elen; 931 break; 932 case WLAN_EID_VENDOR_SPECIFIC: 933 if (rtw_ieee802_11_parse_vendor_specific(pos, elen, 934 elems, 935 show_errors)) 936 unknown++; 937 break; 938 case WLAN_EID_RSN: 939 elems->rsn_ie = pos; 940 elems->rsn_ie_len = elen; 941 break; 942 case WLAN_EID_PWR_CAPABILITY: 943 elems->power_cap = pos; 944 elems->power_cap_len = elen; 945 break; 946 case WLAN_EID_SUPPORTED_CHANNELS: 947 elems->supp_channels = pos; 948 elems->supp_channels_len = elen; 949 break; 950 case WLAN_EID_MOBILITY_DOMAIN: 951 elems->mdie = pos; 952 elems->mdie_len = elen; 953 break; 954 case WLAN_EID_FAST_BSS_TRANSITION: 955 elems->ftie = pos; 956 elems->ftie_len = elen; 957 break; 958 case WLAN_EID_TIMEOUT_INTERVAL: 959 elems->timeout_int = pos; 960 elems->timeout_int_len = elen; 961 break; 962 case WLAN_EID_HT_CAPABILITY: 963 elems->ht_capabilities = pos; 964 elems->ht_capabilities_len = elen; 965 break; 966 case WLAN_EID_HT_OPERATION: 967 elems->ht_operation = pos; 968 elems->ht_operation_len = elen; 969 break; 970 case WLAN_EID_VHT_CAPABILITY: 971 elems->vht_capabilities = pos; 972 elems->vht_capabilities_len = elen; 973 break; 974 case WLAN_EID_VHT_OPERATION: 975 elems->vht_operation = pos; 976 elems->vht_operation_len = elen; 977 break; 978 case WLAN_EID_OPMODE_NOTIF: 979 elems->vht_op_mode_notify = pos; 980 elems->vht_op_mode_notify_len = elen; 981 break; 982 default: 983 unknown++; 984 break; 985 } 986 987 left -= elen; 988 pos += elen; 989 } 990 991 if (left) 992 return ParseFailed; 993 994 return unknown ? ParseUnknown : ParseOK; 995 } 996 997 void rtw_macaddr_cfg(struct device *dev, u8 *mac_addr) 998 { 999 u8 mac[ETH_ALEN]; 1000 struct device_node *np = dev->of_node; 1001 const unsigned char *addr; 1002 int len; 1003 1004 if (!mac_addr) 1005 return; 1006 1007 if (rtw_initmac && mac_pton(rtw_initmac, mac)) { 1008 /* Users specify the mac address */ 1009 ether_addr_copy(mac_addr, mac); 1010 } else { 1011 /* Use the mac address stored in the Efuse */ 1012 ether_addr_copy(mac, mac_addr); 1013 } 1014 1015 if (is_broadcast_ether_addr(mac) || is_zero_ether_addr(mac)) { 1016 addr = of_get_property(np, "local-mac-address", &len); 1017 1018 if (addr && len == ETH_ALEN) { 1019 ether_addr_copy(mac_addr, addr); 1020 } else { 1021 eth_random_addr(mac_addr); 1022 } 1023 } 1024 } 1025 1026 static int rtw_get_cipher_info(struct wlan_network *pnetwork) 1027 { 1028 u32 wpa_ielen; 1029 unsigned char *pbuf; 1030 int group_cipher = 0, pairwise_cipher = 0, is8021x = 0; 1031 int ret = _FAIL; 1032 1033 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); 1034 1035 if (pbuf && (wpa_ielen > 0)) { 1036 if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is8021x)) { 1037 pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; 1038 pnetwork->BcnInfo.group_cipher = group_cipher; 1039 pnetwork->BcnInfo.is_8021x = is8021x; 1040 ret = _SUCCESS; 1041 } 1042 } else { 1043 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); 1044 1045 if (pbuf && (wpa_ielen > 0)) { 1046 if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is8021x)) { 1047 pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; 1048 pnetwork->BcnInfo.group_cipher = group_cipher; 1049 pnetwork->BcnInfo.is_8021x = is8021x; 1050 ret = _SUCCESS; 1051 } 1052 } 1053 } 1054 1055 return ret; 1056 } 1057 1058 void rtw_get_bcn_info(struct wlan_network *pnetwork) 1059 { 1060 unsigned short cap = 0; 1061 u8 bencrypt = 0; 1062 /* u8 wpa_ie[255], rsn_ie[255]; */ 1063 u16 wpa_len = 0, rsn_len = 0; 1064 struct HT_info_element *pht_info = NULL; 1065 struct ieee80211_ht_cap *pht_cap = NULL; 1066 unsigned int len; 1067 unsigned char *p; 1068 __le16 le_cap; 1069 1070 memcpy((u8 *)&le_cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); 1071 cap = le16_to_cpu(le_cap); 1072 if (cap & WLAN_CAPABILITY_PRIVACY) { 1073 bencrypt = 1; 1074 pnetwork->network.Privacy = 1; 1075 } else { 1076 pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS; 1077 } 1078 rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &rsn_len, NULL, &wpa_len); 1079 1080 if (rsn_len > 0) { 1081 pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2; 1082 } else if (wpa_len > 0) { 1083 pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA; 1084 } else { 1085 if (bencrypt) 1086 pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP; 1087 } 1088 rtw_get_cipher_info(pnetwork); 1089 1090 /* get bwmode and ch_offset */ 1091 /* parsing HT_CAP_IE */ 1092 p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, WLAN_EID_HT_CAPABILITY, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); 1093 if (p && len > 0) { 1094 pht_cap = (struct ieee80211_ht_cap *)(p + 2); 1095 pnetwork->BcnInfo.ht_cap_info = le16_to_cpu(pht_cap->cap_info); 1096 } else { 1097 pnetwork->BcnInfo.ht_cap_info = 0; 1098 } 1099 /* parsing HT_INFO_IE */ 1100 p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, WLAN_EID_HT_OPERATION, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); 1101 if (p && len > 0) { 1102 pht_info = (struct HT_info_element *)(p + 2); 1103 pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0]; 1104 } else { 1105 pnetwork->BcnInfo.ht_info_infos_0 = 0; 1106 } 1107 } 1108 1109 /* show MCS rate, unit: 100Kbps */ 1110 u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI, unsigned char *MCS_rate) 1111 { 1112 u16 max_rate = 0; 1113 1114 if (rf_type == RF_1T1R) { 1115 if (MCS_rate[0] & BIT(7)) 1116 max_rate = (bw_40MHz) ? ((short_GI)?1500:1350):((short_GI)?722:650); 1117 else if (MCS_rate[0] & BIT(6)) 1118 max_rate = (bw_40MHz) ? ((short_GI)?1350:1215):((short_GI)?650:585); 1119 else if (MCS_rate[0] & BIT(5)) 1120 max_rate = (bw_40MHz) ? ((short_GI)?1200:1080):((short_GI)?578:520); 1121 else if (MCS_rate[0] & BIT(4)) 1122 max_rate = (bw_40MHz) ? ((short_GI)?900:810):((short_GI)?433:390); 1123 else if (MCS_rate[0] & BIT(3)) 1124 max_rate = (bw_40MHz) ? ((short_GI)?600:540):((short_GI)?289:260); 1125 else if (MCS_rate[0] & BIT(2)) 1126 max_rate = (bw_40MHz) ? ((short_GI)?450:405):((short_GI)?217:195); 1127 else if (MCS_rate[0] & BIT(1)) 1128 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130); 1129 else if (MCS_rate[0] & BIT(0)) 1130 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65); 1131 } else { 1132 if (MCS_rate[1]) { 1133 if (MCS_rate[1] & BIT(7)) 1134 max_rate = (bw_40MHz) ? ((short_GI)?3000:2700):((short_GI)?1444:1300); 1135 else if (MCS_rate[1] & BIT(6)) 1136 max_rate = (bw_40MHz) ? ((short_GI)?2700:2430):((short_GI)?1300:1170); 1137 else if (MCS_rate[1] & BIT(5)) 1138 max_rate = (bw_40MHz) ? ((short_GI)?2400:2160):((short_GI)?1156:1040); 1139 else if (MCS_rate[1] & BIT(4)) 1140 max_rate = (bw_40MHz) ? ((short_GI)?1800:1620):((short_GI)?867:780); 1141 else if (MCS_rate[1] & BIT(3)) 1142 max_rate = (bw_40MHz) ? ((short_GI)?1200:1080):((short_GI)?578:520); 1143 else if (MCS_rate[1] & BIT(2)) 1144 max_rate = (bw_40MHz) ? ((short_GI)?900:810):((short_GI)?433:390); 1145 else if (MCS_rate[1] & BIT(1)) 1146 max_rate = (bw_40MHz) ? ((short_GI)?600:540):((short_GI)?289:260); 1147 else if (MCS_rate[1] & BIT(0)) 1148 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130); 1149 } else { 1150 if (MCS_rate[0] & BIT(7)) 1151 max_rate = (bw_40MHz) ? ((short_GI)?1500:1350):((short_GI)?722:650); 1152 else if (MCS_rate[0] & BIT(6)) 1153 max_rate = (bw_40MHz) ? ((short_GI)?1350:1215):((short_GI)?650:585); 1154 else if (MCS_rate[0] & BIT(5)) 1155 max_rate = (bw_40MHz) ? ((short_GI)?1200:1080):((short_GI)?578:520); 1156 else if (MCS_rate[0] & BIT(4)) 1157 max_rate = (bw_40MHz) ? ((short_GI)?900:810):((short_GI)?433:390); 1158 else if (MCS_rate[0] & BIT(3)) 1159 max_rate = (bw_40MHz) ? ((short_GI)?600:540):((short_GI)?289:260); 1160 else if (MCS_rate[0] & BIT(2)) 1161 max_rate = (bw_40MHz) ? ((short_GI)?450:405):((short_GI)?217:195); 1162 else if (MCS_rate[0] & BIT(1)) 1163 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130); 1164 else if (MCS_rate[0] & BIT(0)) 1165 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65); 1166 } 1167 } 1168 return max_rate; 1169 } 1170 1171 int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *action) 1172 { 1173 const u8 *frame_body = frame + sizeof(struct ieee80211_hdr_3addr); 1174 u16 fc; 1175 u8 c; 1176 u8 a = ACT_PUBLIC_MAX; 1177 1178 fc = le16_to_cpu(((struct ieee80211_hdr_3addr *)frame)->frame_control); 1179 1180 if ((fc & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE)) 1181 != (IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_ACTION) 1182 ) { 1183 return false; 1184 } 1185 1186 c = frame_body[0]; 1187 1188 switch (c) { 1189 case RTW_WLAN_CATEGORY_P2P: /* vendor-specific */ 1190 break; 1191 default: 1192 a = frame_body[1]; 1193 } 1194 1195 if (category) 1196 *category = c; 1197 if (action) 1198 *action = a; 1199 1200 return true; 1201 } 1202 1203 static const char *_action_public_str[] = { 1204 "ACT_PUB_BSSCOEXIST", 1205 "ACT_PUB_DSE_ENABLE", 1206 "ACT_PUB_DSE_DEENABLE", 1207 "ACT_PUB_DSE_REG_LOCATION", 1208 "ACT_PUB_EXT_CHL_SWITCH", 1209 "ACT_PUB_DSE_MSR_REQ", 1210 "ACT_PUB_DSE_MSR_RPRT", 1211 "ACT_PUB_MP", 1212 "ACT_PUB_DSE_PWR_CONSTRAINT", 1213 "ACT_PUB_VENDOR", 1214 "ACT_PUB_GAS_INITIAL_REQ", 1215 "ACT_PUB_GAS_INITIAL_RSP", 1216 "ACT_PUB_GAS_COMEBACK_REQ", 1217 "ACT_PUB_GAS_COMEBACK_RSP", 1218 "ACT_PUB_TDLS_DISCOVERY_RSP", 1219 "ACT_PUB_LOCATION_TRACK", 1220 "ACT_PUB_RSVD", 1221 }; 1222 1223 const char *action_public_str(u8 action) 1224 { 1225 action = (action >= ACT_PUBLIC_MAX) ? ACT_PUBLIC_MAX : action; 1226 return _action_public_str[action]; 1227 } 1228