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