1 /* 2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * DOC: Defines scan utility functions 21 */ 22 23 #include <wlan_cmn.h> 24 #include <wlan_scan_ucfg_api.h> 25 #include <wlan_scan_utils_api.h> 26 #include <../../core/src/wlan_scan_cache_db.h> 27 #include <../../core/src/wlan_scan_main.h> 28 #include <wlan_reg_services_api.h> 29 30 #define MAX_IE_LEN 1024 31 #define SHORT_SSID_LEN 4 32 #define NEIGHBOR_AP_LEN 1 33 #define BSS_PARAMS_LEN 1 34 35 const char* 36 util_scan_get_ev_type_name(enum scan_event_type type) 37 { 38 static const char * const event_name[] = { 39 [SCAN_EVENT_TYPE_STARTED] = "STARTED", 40 [SCAN_EVENT_TYPE_COMPLETED] = "COMPLETED", 41 [SCAN_EVENT_TYPE_BSS_CHANNEL] = "HOME_CHANNEL", 42 [SCAN_EVENT_TYPE_FOREIGN_CHANNEL] = "FOREIGN_CHANNEL", 43 [SCAN_EVENT_TYPE_DEQUEUED] = "DEQUEUED", 44 [SCAN_EVENT_TYPE_PREEMPTED] = "PREEMPTED", 45 [SCAN_EVENT_TYPE_START_FAILED] = "START_FAILED", 46 [SCAN_EVENT_TYPE_RESTARTED] = "RESTARTED", 47 [SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT] = "FOREIGN_CHANNEL_EXIT", 48 [SCAN_EVENT_TYPE_SUSPENDED] = "SUSPENDED", 49 [SCAN_EVENT_TYPE_RESUMED] = "RESUMED", 50 [SCAN_EVENT_TYPE_NLO_COMPLETE] = "NLO_COMPLETE", 51 [SCAN_EVENT_TYPE_NLO_MATCH] = "NLO_MATCH", 52 [SCAN_EVENT_TYPE_INVALID] = "INVALID", 53 [SCAN_EVENT_TYPE_GPIO_TIMEOUT] = "GPIO_TIMEOUT", 54 [SCAN_EVENT_TYPE_RADIO_MEASUREMENT_START] = 55 "RADIO_MEASUREMENT_START", 56 [SCAN_EVENT_TYPE_RADIO_MEASUREMENT_END] = 57 "RADIO_MEASUREMENT_END", 58 [SCAN_EVENT_TYPE_BSSID_MATCH] = "BSSID_MATCH", 59 [SCAN_EVENT_TYPE_FOREIGN_CHANNEL_GET_NF] = 60 "FOREIGN_CHANNEL_GET_NF", 61 }; 62 63 if (type >= SCAN_EVENT_TYPE_MAX) 64 return "UNKNOWN"; 65 66 return event_name[type]; 67 } 68 69 70 const char* 71 util_scan_get_ev_reason_name(enum scan_completion_reason reason) 72 { 73 static const char * const reason_name[] = { 74 [SCAN_REASON_NONE] = "NONE", 75 [SCAN_REASON_COMPLETED] = "COMPLETED", 76 [SCAN_REASON_CANCELLED] = "CANCELLED", 77 [SCAN_REASON_PREEMPTED] = "PREEMPTED", 78 [SCAN_REASON_TIMEDOUT] = "TIMEDOUT", 79 [SCAN_REASON_INTERNAL_FAILURE] = "INTERNAL_FAILURE", 80 [SCAN_REASON_SUSPENDED] = "SUSPENDED", 81 [SCAN_REASON_RUN_FAILED] = "RUN_FAILED", 82 [SCAN_REASON_TERMINATION_FUNCTION] = "TERMINATION_FUNCTION", 83 [SCAN_REASON_MAX_OFFCHAN_RETRIES] = "MAX_OFFCHAN_RETRIES", 84 [SCAN_REASON_DFS_VIOLATION] = "DFS_NOL_VIOLATION", 85 }; 86 87 if (reason >= SCAN_REASON_MAX) 88 return "UNKNOWN"; 89 90 return reason_name[reason]; 91 } 92 93 qdf_time_t 94 util_get_last_scan_time(struct wlan_objmgr_vdev *vdev) 95 { 96 uint8_t pdev_id; 97 struct wlan_scan_obj *scan_obj; 98 99 if (!vdev) { 100 scm_warn("null vdev"); 101 QDF_ASSERT(0); 102 return 0; 103 } 104 pdev_id = wlan_scan_vdev_get_pdev_id(vdev); 105 scan_obj = wlan_vdev_get_scan_obj(vdev); 106 107 if (scan_obj) 108 return scan_obj->pdev_info[pdev_id].last_scan_time; 109 else 110 return 0; 111 } 112 113 enum wlan_band util_scan_scm_chan_to_band(uint32_t chan) 114 { 115 if (WLAN_CHAN_IS_2GHZ(chan)) 116 return WLAN_BAND_2_4_GHZ; 117 118 return WLAN_BAND_5_GHZ; 119 } 120 121 enum wlan_band util_scan_scm_freq_to_band(uint16_t freq) 122 { 123 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq)) 124 return WLAN_BAND_2_4_GHZ; 125 126 return WLAN_BAND_5_GHZ; 127 } 128 129 bool util_is_scan_entry_match( 130 struct scan_cache_entry *entry1, 131 struct scan_cache_entry *entry2) 132 { 133 134 if (entry1->cap_info.wlan_caps.ess != 135 entry2->cap_info.wlan_caps.ess) 136 return false; 137 138 if (entry1->cap_info.wlan_caps.ess && 139 !qdf_mem_cmp(entry1->bssid.bytes, 140 entry2->bssid.bytes, QDF_MAC_ADDR_SIZE)) { 141 /* Check for BSS */ 142 if (util_is_ssid_match(&entry1->ssid, &entry2->ssid) || 143 util_scan_is_null_ssid(&entry1->ssid) || 144 util_scan_is_null_ssid(&entry2->ssid)) 145 return true; 146 } else if (entry1->cap_info.wlan_caps.ibss && 147 (entry1->channel.chan_freq == 148 entry2->channel.chan_freq)) { 149 /* 150 * Same channel cannot have same SSID for 151 * different IBSS, so no need to check BSSID 152 */ 153 if (util_is_ssid_match( 154 &entry1->ssid, &entry2->ssid)) 155 return true; 156 } else if (!entry1->cap_info.wlan_caps.ibss && 157 !entry1->cap_info.wlan_caps.ess && 158 !qdf_mem_cmp(entry1->bssid.bytes, 159 entry2->bssid.bytes, QDF_MAC_ADDR_SIZE)) { 160 /* In case of P2P devices, ess and ibss will be set to zero */ 161 return true; 162 } 163 164 return false; 165 } 166 167 static bool util_is_pureg_rate(uint8_t *rates, uint8_t nrates) 168 { 169 static const uint8_t g_rates[] = {12, 18, 24, 36, 48, 72, 96, 108}; 170 bool pureg = false; 171 uint8_t i, j; 172 173 for (i = 0; i < nrates; i++) { 174 for (j = 0; j < QDF_ARRAY_SIZE(g_rates); j++) { 175 if (WLAN_RV(rates[i]) == g_rates[j]) { 176 pureg = true; 177 break; 178 } 179 } 180 if (pureg) 181 break; 182 } 183 184 return pureg; 185 } 186 187 #ifdef CONFIG_BAND_6GHZ 188 static struct he_oper_6g_param *util_scan_get_he_6g_params(uint8_t *he_ops) 189 { 190 uint8_t len; 191 uint32_t he_oper_params; 192 193 if (!he_ops) 194 return NULL; 195 196 len = he_ops[1]; 197 he_ops += sizeof(struct ie_header); 198 199 if (len < WLAN_HEOP_FIXED_PARAM_LENGTH) 200 return NULL; 201 202 /* element id extension */ 203 he_ops++; 204 len--; 205 206 he_oper_params = LE_READ_4(he_ops); 207 if (!(he_oper_params & WLAN_HEOP_6GHZ_INFO_PRESENT_MASK)) 208 return NULL; 209 210 /* fixed params - element id extension */ 211 he_ops += WLAN_HEOP_FIXED_PARAM_LENGTH - 1; 212 len -= WLAN_HEOP_FIXED_PARAM_LENGTH - 1; 213 214 if (!len) 215 return NULL; 216 217 /* vht oper params */ 218 if (he_oper_params & WLAN_HEOP_VHTOP_PRESENT_MASK) { 219 if (len < WLAN_HEOP_VHTOP_LENGTH) 220 return NULL; 221 he_ops += WLAN_HEOP_VHTOP_LENGTH; 222 len -= WLAN_HEOP_VHTOP_LENGTH; 223 } 224 225 if (!len) 226 return NULL; 227 228 if (he_oper_params & WLAN_HEOP_CO_LOCATED_BSS_MASK) { 229 he_ops += WLAN_HEOP_CO_LOCATED_BSS_LENGTH; 230 len -= WLAN_HEOP_CO_LOCATED_BSS_LENGTH; 231 } 232 233 if (len < sizeof(struct he_oper_6g_param)) 234 return NULL; 235 236 return (struct he_oper_6g_param *)he_ops; 237 } 238 239 static void 240 util_scan_get_chan_from_he_6g_params(struct scan_cache_entry *scan_params, 241 uint8_t *chan_idx, bool *he_6g_dup_bcon) 242 { 243 struct he_oper_6g_param *he_6g_params; 244 uint8_t *he_ops; 245 246 *he_6g_dup_bcon = false; 247 248 he_ops = util_scan_entry_heop(scan_params); 249 if (!util_scan_entry_hecap(scan_params) || !he_ops) 250 return; 251 252 he_6g_params = util_scan_get_he_6g_params(he_ops); 253 if (!he_6g_params) 254 return; 255 256 *chan_idx = he_6g_params->primary_channel; 257 *he_6g_dup_bcon = he_6g_params->duplicate_beacon ? true : false; 258 } 259 260 static enum wlan_phymode 261 util_scan_get_phymode_6g(struct wlan_objmgr_pdev *pdev, 262 struct scan_cache_entry *scan_params) 263 { 264 struct he_oper_6g_param *he_6g_params; 265 enum wlan_phymode phymode = WLAN_PHYMODE_11AXA_HE20; 266 uint8_t *he_ops; 267 uint8_t band_mask = BIT(REG_BAND_6G); 268 269 he_ops = util_scan_entry_heop(scan_params); 270 if (!util_scan_entry_hecap(scan_params) || !he_ops) 271 return phymode; 272 273 he_6g_params = util_scan_get_he_6g_params(he_ops); 274 if (!he_6g_params) 275 return phymode; 276 277 switch (he_6g_params->width) { 278 case WLAN_HE_6GHZ_CHWIDTH_20: 279 phymode = WLAN_PHYMODE_11AXA_HE20; 280 break; 281 case WLAN_HE_6GHZ_CHWIDTH_40: 282 phymode = WLAN_PHYMODE_11AXA_HE40; 283 break; 284 case WLAN_HE_6GHZ_CHWIDTH_80: 285 phymode = WLAN_PHYMODE_11AXA_HE80; 286 break; 287 case WLAN_HE_6GHZ_CHWIDTH_160_80_80: 288 if (WLAN_IS_HE80_80(he_6g_params)) 289 phymode = WLAN_PHYMODE_11AXA_HE80_80; 290 else if (WLAN_IS_HE160(he_6g_params)) 291 phymode = WLAN_PHYMODE_11AXA_HE160; 292 else 293 phymode = WLAN_PHYMODE_11AXA_HE80; 294 break; 295 default: 296 scm_err("Invalid he_6g_params width: %d", he_6g_params->width); 297 phymode = WLAN_PHYMODE_11AXA_HE20; 298 break; 299 } 300 301 if (he_6g_params->chan_freq_seg0) 302 scan_params->channel.cfreq0 = 303 wlan_reg_chan_band_to_freq(pdev, 304 he_6g_params->chan_freq_seg0, 305 band_mask); 306 if (he_6g_params->chan_freq_seg1) 307 scan_params->channel.cfreq1 = 308 wlan_reg_chan_band_to_freq(pdev, 309 he_6g_params->chan_freq_seg1, 310 band_mask); 311 312 return phymode; 313 } 314 #else 315 static void 316 util_scan_get_chan_from_he_6g_params(struct scan_cache_entry *scan_params, 317 uint8_t *chan_idx, bool *he_6g_dup_bcon) 318 {} 319 static inline enum wlan_phymode 320 util_scan_get_phymode_6g(struct wlan_objmgr_pdev *pdev, 321 struct scan_cache_entry *scan_params) 322 { 323 return WLAN_PHYMODE_AUTO; 324 } 325 #endif 326 327 static inline 328 uint32_t util_scan_sec_chan_freq_from_htinfo(struct wlan_ie_htinfo_cmn *htinfo, 329 uint32_t primary_chan_freq) 330 { 331 if (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_ABOVE) 332 return primary_chan_freq + WLAN_CHAN_SPACING_20MHZ; 333 else if (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_BELOW) 334 return primary_chan_freq - WLAN_CHAN_SPACING_20MHZ; 335 336 return 0; 337 } 338 339 static enum wlan_phymode 340 util_scan_get_phymode_5g(struct wlan_objmgr_pdev *pdev, 341 struct scan_cache_entry *scan_params) 342 { 343 enum wlan_phymode phymode = WLAN_PHYMODE_AUTO; 344 uint16_t ht_cap = 0; 345 struct htcap_cmn_ie *htcap; 346 struct wlan_ie_htinfo_cmn *htinfo; 347 struct wlan_ie_vhtop *vhtop; 348 uint8_t band_mask = BIT(REG_BAND_5G); 349 350 htcap = (struct htcap_cmn_ie *) 351 util_scan_entry_htcap(scan_params); 352 htinfo = (struct wlan_ie_htinfo_cmn *) 353 util_scan_entry_htinfo(scan_params); 354 vhtop = (struct wlan_ie_vhtop *) 355 util_scan_entry_vhtop(scan_params); 356 357 if (!(htcap && htinfo)) 358 return WLAN_PHYMODE_11A; 359 360 if (htcap) 361 ht_cap = le16toh(htcap->hc_cap); 362 363 if (ht_cap & WLAN_HTCAP_C_CHWIDTH40) 364 phymode = WLAN_PHYMODE_11NA_HT40; 365 else 366 phymode = WLAN_PHYMODE_11NA_HT20; 367 368 scan_params->channel.cfreq0 = 369 util_scan_sec_chan_freq_from_htinfo(htinfo, 370 scan_params->channel.chan_freq); 371 372 if (util_scan_entry_vhtcap(scan_params) && vhtop) { 373 switch (vhtop->vht_op_chwidth) { 374 case WLAN_VHTOP_CHWIDTH_2040: 375 if (ht_cap & WLAN_HTCAP_C_CHWIDTH40) 376 phymode = WLAN_PHYMODE_11AC_VHT40; 377 else 378 phymode = WLAN_PHYMODE_11AC_VHT20; 379 break; 380 case WLAN_VHTOP_CHWIDTH_80: 381 if (WLAN_IS_REVSIG_VHT80_80(vhtop)) 382 phymode = WLAN_PHYMODE_11AC_VHT80_80; 383 else if (WLAN_IS_REVSIG_VHT160(vhtop)) 384 phymode = WLAN_PHYMODE_11AC_VHT160; 385 else 386 phymode = WLAN_PHYMODE_11AC_VHT80; 387 break; 388 case WLAN_VHTOP_CHWIDTH_160: 389 phymode = WLAN_PHYMODE_11AC_VHT160; 390 break; 391 case WLAN_VHTOP_CHWIDTH_80_80: 392 phymode = WLAN_PHYMODE_11AC_VHT80_80; 393 break; 394 default: 395 scm_err("bad channel: %d", 396 vhtop->vht_op_chwidth); 397 phymode = WLAN_PHYMODE_11AC_VHT20; 398 break; 399 } 400 if (vhtop->vht_op_ch_freq_seg1) 401 scan_params->channel.cfreq0 = 402 wlan_reg_chan_band_to_freq(pdev, 403 vhtop->vht_op_ch_freq_seg1, 404 band_mask); 405 if (vhtop->vht_op_ch_freq_seg2) 406 scan_params->channel.cfreq1 = 407 wlan_reg_chan_band_to_freq(pdev, 408 vhtop->vht_op_ch_freq_seg2, 409 band_mask); 410 } 411 412 if (!util_scan_entry_hecap(scan_params)) 413 return phymode; 414 415 /* for 5Ghz Check for HE, only if VHT cap and HE cap are present */ 416 if (!IS_WLAN_PHYMODE_VHT(phymode)) 417 return phymode; 418 419 switch (phymode) { 420 case WLAN_PHYMODE_11AC_VHT20: 421 phymode = WLAN_PHYMODE_11AXA_HE20; 422 break; 423 case WLAN_PHYMODE_11AC_VHT40: 424 phymode = WLAN_PHYMODE_11AXA_HE40; 425 break; 426 case WLAN_PHYMODE_11AC_VHT80: 427 phymode = WLAN_PHYMODE_11AXA_HE80; 428 break; 429 case WLAN_PHYMODE_11AC_VHT160: 430 phymode = WLAN_PHYMODE_11AXA_HE160; 431 break; 432 case WLAN_PHYMODE_11AC_VHT80_80: 433 phymode = WLAN_PHYMODE_11AXA_HE80_80; 434 break; 435 default: 436 phymode = WLAN_PHYMODE_11AXA_HE20; 437 break; 438 } 439 440 return phymode; 441 } 442 443 static enum wlan_phymode 444 util_scan_get_phymode_2g(struct scan_cache_entry *scan_params) 445 { 446 enum wlan_phymode phymode = WLAN_PHYMODE_AUTO; 447 uint16_t ht_cap = 0; 448 struct htcap_cmn_ie *htcap; 449 struct wlan_ie_htinfo_cmn *htinfo; 450 struct wlan_ie_vhtop *vhtop; 451 452 htcap = (struct htcap_cmn_ie *) 453 util_scan_entry_htcap(scan_params); 454 htinfo = (struct wlan_ie_htinfo_cmn *) 455 util_scan_entry_htinfo(scan_params); 456 vhtop = (struct wlan_ie_vhtop *) 457 util_scan_entry_vhtop(scan_params); 458 459 if (htcap) 460 ht_cap = le16toh(htcap->hc_cap); 461 462 if (htcap && htinfo) { 463 if ((ht_cap & WLAN_HTCAP_C_CHWIDTH40) && 464 (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_ABOVE)) 465 phymode = WLAN_PHYMODE_11NG_HT40PLUS; 466 else if ((ht_cap & WLAN_HTCAP_C_CHWIDTH40) && 467 (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_BELOW)) 468 phymode = WLAN_PHYMODE_11NG_HT40MINUS; 469 else 470 phymode = WLAN_PHYMODE_11NG_HT20; 471 } else if (util_scan_entry_xrates(scan_params)) { 472 /* only 11G stations will have more than 8 rates */ 473 phymode = WLAN_PHYMODE_11G; 474 } else { 475 /* Some mischievous g-only APs do not set extended rates */ 476 if (util_scan_entry_rates(scan_params)) { 477 if (util_is_pureg_rate(&scan_params->ie_list.rates[2], 478 scan_params->ie_list.rates[1])) 479 phymode = WLAN_PHYMODE_11G; 480 else 481 phymode = WLAN_PHYMODE_11B; 482 } else { 483 phymode = WLAN_PHYMODE_11B; 484 } 485 } 486 487 /* Check for VHT only if HT cap is present */ 488 if (!IS_WLAN_PHYMODE_HT(phymode)) 489 return phymode; 490 491 scan_params->channel.cfreq0 = 492 util_scan_sec_chan_freq_from_htinfo(htinfo, 493 scan_params->channel.chan_freq); 494 495 if (util_scan_entry_vhtcap(scan_params) && vhtop) { 496 switch (vhtop->vht_op_chwidth) { 497 case WLAN_VHTOP_CHWIDTH_2040: 498 if (phymode == WLAN_PHYMODE_11NG_HT40PLUS) 499 phymode = WLAN_PHYMODE_11AC_VHT40PLUS_2G; 500 else if (phymode == WLAN_PHYMODE_11NG_HT40MINUS) 501 phymode = WLAN_PHYMODE_11AC_VHT40MINUS_2G; 502 else 503 phymode = WLAN_PHYMODE_11AC_VHT20_2G; 504 505 break; 506 default: 507 scm_info("bad vht_op_chwidth: %d", 508 vhtop->vht_op_chwidth); 509 phymode = WLAN_PHYMODE_11AC_VHT20_2G; 510 break; 511 } 512 } 513 514 if (!util_scan_entry_hecap(scan_params)) 515 return phymode; 516 517 if (phymode == WLAN_PHYMODE_11AC_VHT40PLUS_2G || 518 phymode == WLAN_PHYMODE_11NG_HT40PLUS) 519 phymode = WLAN_PHYMODE_11AXG_HE40PLUS; 520 else if (phymode == WLAN_PHYMODE_11AC_VHT40MINUS_2G || 521 phymode == WLAN_PHYMODE_11NG_HT40MINUS) 522 phymode = WLAN_PHYMODE_11AXG_HE40MINUS; 523 else 524 phymode = WLAN_PHYMODE_11AXG_HE20; 525 526 return phymode; 527 } 528 529 static enum wlan_phymode 530 util_scan_get_phymode(struct wlan_objmgr_pdev *pdev, 531 struct scan_cache_entry *scan_params) 532 { 533 if (WLAN_REG_IS_24GHZ_CH_FREQ(scan_params->channel.chan_freq)) 534 return util_scan_get_phymode_2g(scan_params); 535 else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(scan_params->channel.chan_freq)) 536 return util_scan_get_phymode_6g(pdev, scan_params); 537 else 538 return util_scan_get_phymode_5g(pdev, scan_params); 539 } 540 541 static QDF_STATUS 542 util_scan_parse_chan_switch_wrapper_ie(struct scan_cache_entry *scan_params, 543 struct ie_header *sub_ie, qdf_size_t sub_ie_len) 544 { 545 /* Walk through to check nothing is malformed */ 546 while (sub_ie_len >= sizeof(struct ie_header)) { 547 /* At least one more header is present */ 548 sub_ie_len -= sizeof(struct ie_header); 549 550 if (sub_ie->ie_len == 0) { 551 sub_ie += 1; 552 continue; 553 } 554 if (sub_ie_len < sub_ie->ie_len) { 555 scm_err("Incomplete corrupted IE:%x", 556 WLAN_ELEMID_CHAN_SWITCH_WRAP); 557 return QDF_STATUS_E_INVAL; 558 } 559 switch (sub_ie->ie_id) { 560 case WLAN_ELEMID_COUNTRY: 561 scan_params->ie_list.country = (uint8_t *)sub_ie; 562 break; 563 case WLAN_ELEMID_WIDE_BAND_CHAN_SWITCH: 564 scan_params->ie_list.widebw = (uint8_t *)sub_ie; 565 break; 566 case WLAN_ELEMID_VHT_TX_PWR_ENVLP: 567 scan_params->ie_list.txpwrenvlp = (uint8_t *)sub_ie; 568 break; 569 } 570 /* Consume sub info element */ 571 sub_ie_len -= sub_ie->ie_len; 572 /* go to next Sub IE */ 573 sub_ie = (struct ie_header *) 574 (((uint8_t *) sub_ie) + 575 sizeof(struct ie_header) + sub_ie->ie_len); 576 } 577 578 return QDF_STATUS_SUCCESS; 579 } 580 581 bool 582 util_scan_is_hidden_ssid(struct ie_ssid *ssid) 583 { 584 uint8_t i; 585 586 /* 587 * We flag this as Hidden SSID if the Length is 0 588 * of the SSID only contains 0's 589 */ 590 if (!ssid || !ssid->ssid_len) 591 return true; 592 593 for (i = 0; i < ssid->ssid_len; i++) 594 if (ssid->ssid[i] != 0) 595 return false; 596 597 /* All 0's */ 598 return true; 599 } 600 601 static QDF_STATUS 602 util_scan_update_rnr(struct rnr_bss_info *rnr, 603 struct neighbor_ap_info_field *ap_info, 604 uint8_t *data) 605 { 606 uint8_t tbtt_info_length; 607 608 tbtt_info_length = ap_info->tbtt_header.tbtt_info_length; 609 610 switch (tbtt_info_length) { 611 case TBTT_NEIGHBOR_AP_OFFSET_ONLY: 612 /* Dont store it skip*/ 613 break; 614 615 case TBTT_NEIGHBOR_AP_BSS_PARAM: 616 /* Dont store it skip*/ 617 break; 618 619 case TBTT_NEIGHBOR_AP_SHORTSSID: 620 rnr->channel_number = ap_info->channel_number; 621 rnr->operating_class = ap_info->operting_class; 622 qdf_mem_copy(&rnr->short_ssid, &data[1], SHORT_SSID_LEN); 623 break; 624 625 case TBTT_NEIGHBOR_AP_S_SSID_BSS_PARAM: 626 rnr->channel_number = ap_info->channel_number; 627 rnr->operating_class = ap_info->operting_class; 628 qdf_mem_copy(&rnr->short_ssid, &data[1], SHORT_SSID_LEN); 629 rnr->bss_params = data[5]; 630 break; 631 632 case TBTT_NEIGHBOR_AP_BSSID: 633 rnr->channel_number = ap_info->channel_number; 634 rnr->operating_class = ap_info->operting_class; 635 qdf_mem_copy(&rnr->bssid, &data[1], QDF_MAC_ADDR_SIZE); 636 break; 637 638 case TBTT_NEIGHBOR_AP_BSSID_BSS_PARAM: 639 rnr->channel_number = ap_info->channel_number; 640 rnr->operating_class = ap_info->operting_class; 641 qdf_mem_copy(&rnr->bssid, &data[1], QDF_MAC_ADDR_SIZE); 642 rnr->bss_params = data[7]; 643 break; 644 645 case TBTT_NEIGHBOR_AP_BSSSID_S_SSID: 646 rnr->channel_number = ap_info->channel_number; 647 rnr->operating_class = ap_info->operting_class; 648 qdf_mem_copy(&rnr->bssid, &data[1], QDF_MAC_ADDR_SIZE); 649 qdf_mem_copy(&rnr->short_ssid, &data[7], SHORT_SSID_LEN); 650 break; 651 652 case TBTT_NEIGHBOR_AP_BSSID_S_SSID_BSS_PARAM: 653 rnr->channel_number = ap_info->channel_number; 654 rnr->operating_class = ap_info->operting_class; 655 qdf_mem_copy(&rnr->bssid, &data[1], QDF_MAC_ADDR_SIZE); 656 qdf_mem_copy(&rnr->short_ssid, &data[7], SHORT_SSID_LEN); 657 rnr->bss_params = data[11]; 658 break; 659 660 default: 661 scm_debug("Wrong fieldtype"); 662 } 663 664 return QDF_STATUS_SUCCESS; 665 } 666 667 static QDF_STATUS 668 util_scan_parse_rnr_ie(struct scan_cache_entry *scan_entry, 669 struct ie_header *ie) 670 { 671 uint32_t rnr_ie_len; 672 uint16_t tbtt_count, tbtt_length, i, fieldtype; 673 uint8_t *data; 674 struct neighbor_ap_info_field *neighbor_ap_info; 675 676 rnr_ie_len = ie->ie_len; 677 data = (uint8_t *)ie + sizeof(struct ie_header); 678 679 while (data < ((uint8_t *)ie + rnr_ie_len + 2)) { 680 neighbor_ap_info = (struct neighbor_ap_info_field *)data; 681 tbtt_count = neighbor_ap_info->tbtt_header.tbtt_info_count; 682 tbtt_length = neighbor_ap_info->tbtt_header.tbtt_info_length; 683 fieldtype = neighbor_ap_info->tbtt_header.tbbt_info_fieldtype; 684 scm_debug("channel number %d, op class %d", 685 neighbor_ap_info->channel_number, 686 neighbor_ap_info->operting_class); 687 scm_debug("tbtt_count %d, tbtt_length %d, fieldtype %d", 688 tbtt_count, tbtt_length, fieldtype); 689 data += sizeof(struct neighbor_ap_info_field); 690 for (i = 0; i < (tbtt_count + 1) ; i++) { 691 if (i < MAX_RNR_BSS) 692 util_scan_update_rnr( 693 &scan_entry->rnr.bss_info[i], 694 neighbor_ap_info, 695 data); 696 data += tbtt_length; 697 } 698 } 699 700 return QDF_STATUS_SUCCESS; 701 } 702 703 static QDF_STATUS 704 util_scan_parse_extn_ie(struct scan_cache_entry *scan_params, 705 struct ie_header *ie) 706 { 707 struct extn_ie_header *extn_ie = (struct extn_ie_header *) ie; 708 709 switch (extn_ie->ie_extn_id) { 710 case WLAN_EXTN_ELEMID_MAX_CHAN_SWITCH_TIME: 711 scan_params->ie_list.mcst = (uint8_t *)ie; 712 break; 713 case WLAN_EXTN_ELEMID_SRP: 714 scan_params->ie_list.srp = (uint8_t *)ie; 715 break; 716 case WLAN_EXTN_ELEMID_HECAP: 717 scan_params->ie_list.hecap = (uint8_t *)ie; 718 break; 719 case WLAN_EXTN_ELEMID_HEOP: 720 scan_params->ie_list.heop = (uint8_t *)ie; 721 break; 722 case WLAN_EXTN_ELEMID_ESP: 723 scan_params->ie_list.esp = (uint8_t *)ie; 724 break; 725 case WLAN_EXTN_ELEMID_MUEDCA: 726 scan_params->ie_list.muedca = (uint8_t *)ie; 727 break; 728 case WLAN_EXTN_ELEMID_HE_6G_CAP: 729 scan_params->ie_list.hecap_6g = (uint8_t *)ie; 730 break; 731 default: 732 break; 733 } 734 return QDF_STATUS_SUCCESS; 735 } 736 737 static QDF_STATUS 738 util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params, 739 struct ie_header *ie) 740 { 741 if (!scan_params->ie_list.vendor) 742 scan_params->ie_list.vendor = (uint8_t *)ie; 743 744 if (is_wpa_oui((uint8_t *)ie)) { 745 scan_params->ie_list.wpa = (uint8_t *)ie; 746 } else if (is_wps_oui((uint8_t *)ie)) { 747 scan_params->ie_list.wps = (uint8_t *)ie; 748 /* WCN IE should be a subset of WPS IE */ 749 if (is_wcn_oui((uint8_t *)ie)) 750 scan_params->ie_list.wcn = (uint8_t *)ie; 751 } else if (is_wme_param((uint8_t *)ie)) { 752 scan_params->ie_list.wmeparam = (uint8_t *)ie; 753 } else if (is_wme_info((uint8_t *)ie)) { 754 scan_params->ie_list.wmeinfo = (uint8_t *)ie; 755 } else if (is_atheros_oui((uint8_t *)ie)) { 756 scan_params->ie_list.athcaps = (uint8_t *)ie; 757 } else if (is_atheros_extcap_oui((uint8_t *)ie)) { 758 scan_params->ie_list.athextcaps = (uint8_t *)ie; 759 } else if (is_sfa_oui((uint8_t *)ie)) { 760 scan_params->ie_list.sfa = (uint8_t *)ie; 761 } else if (is_p2p_oui((uint8_t *)ie)) { 762 scan_params->ie_list.p2p = (uint8_t *)ie; 763 } else if (is_qca_son_oui((uint8_t *)ie, 764 QCA_OUI_WHC_AP_INFO_SUBTYPE)) { 765 scan_params->ie_list.sonadv = (uint8_t *)ie; 766 } else if (is_ht_cap((uint8_t *)ie)) { 767 /* we only care if there isn't already an HT IE (ANA) */ 768 if (!scan_params->ie_list.htcap) { 769 if (ie->ie_len != (WLAN_VENDOR_HT_IE_OFFSET_LEN + 770 sizeof(struct htcap_cmn_ie))) 771 return QDF_STATUS_E_INVAL; 772 scan_params->ie_list.htcap = 773 (uint8_t *)&(((struct wlan_vendor_ie_htcap *)ie)->ie); 774 } 775 } else if (is_ht_info((uint8_t *)ie)) { 776 /* we only care if there isn't already an HT IE (ANA) */ 777 if (!scan_params->ie_list.htinfo) { 778 if (ie->ie_len != WLAN_VENDOR_HT_IE_OFFSET_LEN + 779 sizeof(struct wlan_ie_htinfo_cmn)) 780 return QDF_STATUS_E_INVAL; 781 scan_params->ie_list.htinfo = 782 (uint8_t *)&(((struct wlan_vendor_ie_htinfo *) 783 ie)->hi_ie); 784 } 785 } else if (is_interop_vht((uint8_t *)ie) && 786 !(scan_params->ie_list.vhtcap)) { 787 uint8_t *vendor_ie = (uint8_t *)(ie); 788 789 if (ie->ie_len < ((WLAN_VENDOR_VHTCAP_IE_OFFSET + 790 sizeof(struct wlan_ie_vhtcaps)) - 791 sizeof(struct ie_header))) 792 return QDF_STATUS_E_INVAL; 793 vendor_ie = ((uint8_t *)(ie)) + WLAN_VENDOR_VHTCAP_IE_OFFSET; 794 if (vendor_ie[1] != (sizeof(struct wlan_ie_vhtcaps)) - 795 sizeof(struct ie_header)) 796 return QDF_STATUS_E_INVAL; 797 /* location where Interop Vht Cap IE and VHT OP IE Present */ 798 scan_params->ie_list.vhtcap = (((uint8_t *)(ie)) + 799 WLAN_VENDOR_VHTCAP_IE_OFFSET); 800 if (ie->ie_len > ((WLAN_VENDOR_VHTCAP_IE_OFFSET + 801 sizeof(struct wlan_ie_vhtcaps)) - 802 sizeof(struct ie_header))) { 803 if (ie->ie_len < ((WLAN_VENDOR_VHTOP_IE_OFFSET + 804 sizeof(struct wlan_ie_vhtop)) - 805 sizeof(struct ie_header))) 806 return QDF_STATUS_E_INVAL; 807 vendor_ie = ((uint8_t *)(ie)) + 808 WLAN_VENDOR_VHTOP_IE_OFFSET; 809 if (vendor_ie[1] != (sizeof(struct wlan_ie_vhtop) - 810 sizeof(struct ie_header))) 811 return QDF_STATUS_E_INVAL; 812 scan_params->ie_list.vhtop = (((uint8_t *)(ie)) + 813 WLAN_VENDOR_VHTOP_IE_OFFSET); 814 } 815 } else if (is_bwnss_oui((uint8_t *)ie)) { 816 /* 817 * Bandwidth-NSS map has sub-type & version. 818 * hence copy data just after version byte 819 */ 820 scan_params->ie_list.bwnss_map = (((uint8_t *)ie) + 8); 821 } else if (is_mbo_oce_oui((uint8_t *)ie)) { 822 scan_params->ie_list.mbo_oce = (uint8_t *)ie; 823 } else if (is_extender_oui((uint8_t *)ie)) { 824 scan_params->ie_list.extender = (uint8_t *)ie; 825 } else if (is_adaptive_11r_oui((uint8_t *)ie)) { 826 if ((ie->ie_len < OUI_LENGTH) || 827 (ie->ie_len > MAX_ADAPTIVE_11R_IE_LEN)) 828 return QDF_STATUS_E_INVAL; 829 830 scan_params->ie_list.adaptive_11r = (uint8_t *)ie + 831 sizeof(struct ie_header); 832 } else if (is_sae_single_pmk_oui((uint8_t *)ie)) { 833 if ((ie->ie_len < OUI_LENGTH) || 834 (ie->ie_len > MAX_SAE_SINGLE_PMK_IE_LEN)) { 835 scm_debug("Invalid sae single pmk OUI"); 836 return QDF_STATUS_E_INVAL; 837 } 838 scan_params->ie_list.single_pmk = (uint8_t *)ie + 839 sizeof(struct ie_header); 840 } 841 return QDF_STATUS_SUCCESS; 842 } 843 844 static QDF_STATUS 845 util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params, 846 uint8_t *chan_idx) 847 { 848 struct ie_header *ie, *sub_ie; 849 uint32_t ie_len, sub_ie_len; 850 QDF_STATUS status; 851 852 ie_len = util_scan_entry_ie_len(scan_params); 853 ie = (struct ie_header *) 854 util_scan_entry_ie_data(scan_params); 855 856 while (ie_len >= sizeof(struct ie_header)) { 857 ie_len -= sizeof(struct ie_header); 858 859 if (!ie->ie_len) { 860 ie += 1; 861 continue; 862 } 863 864 if (ie_len < ie->ie_len) { 865 scm_debug("Incomplete corrupted IE:%x", 866 ie->ie_id); 867 return QDF_STATUS_E_INVAL; 868 } 869 870 switch (ie->ie_id) { 871 case WLAN_ELEMID_SSID: 872 if (ie->ie_len > (sizeof(struct ie_ssid) - 873 sizeof(struct ie_header))) 874 goto err; 875 scan_params->ie_list.ssid = (uint8_t *)ie; 876 break; 877 case WLAN_ELEMID_RATES: 878 if (ie->ie_len > WLAN_SUPPORTED_RATES_IE_MAX_LEN) 879 goto err; 880 scan_params->ie_list.rates = (uint8_t *)ie; 881 break; 882 case WLAN_ELEMID_DSPARMS: 883 if (ie->ie_len != WLAN_DS_PARAM_IE_MAX_LEN) 884 return QDF_STATUS_E_INVAL; 885 scan_params->ie_list.ds_param = (uint8_t *)ie; 886 *chan_idx = 887 ((struct ds_ie *)ie)->cur_chan; 888 break; 889 case WLAN_ELEMID_TIM: 890 if (ie->ie_len < WLAN_TIM_IE_MIN_LENGTH) 891 goto err; 892 scan_params->ie_list.tim = (uint8_t *)ie; 893 scan_params->dtim_period = 894 ((struct wlan_tim_ie *)ie)->tim_period; 895 break; 896 case WLAN_ELEMID_COUNTRY: 897 if (ie->ie_len < WLAN_COUNTRY_IE_MIN_LEN) 898 goto err; 899 scan_params->ie_list.country = (uint8_t *)ie; 900 break; 901 case WLAN_ELEMID_QBSS_LOAD: 902 if (ie->ie_len != sizeof(struct qbss_load_ie) - 903 sizeof(struct ie_header)) { 904 /* 905 * Expected QBSS IE length is 5Bytes; For some 906 * old cisco AP, QBSS IE length is 4Bytes, which 907 * doesn't match with latest spec, So ignore 908 * QBSS IE in such case. 909 */ 910 break; 911 } 912 scan_params->ie_list.qbssload = (uint8_t *)ie; 913 break; 914 case WLAN_ELEMID_CHANSWITCHANN: 915 if (ie->ie_len != WLAN_CSA_IE_MAX_LEN) 916 goto err; 917 scan_params->ie_list.csa = (uint8_t *)ie; 918 break; 919 case WLAN_ELEMID_IBSSDFS: 920 if (ie->ie_len < WLAN_IBSSDFS_IE_MIN_LEN) 921 goto err; 922 scan_params->ie_list.ibssdfs = (uint8_t *)ie; 923 break; 924 case WLAN_ELEMID_QUIET: 925 if (ie->ie_len != WLAN_QUIET_IE_MAX_LEN) 926 goto err; 927 scan_params->ie_list.quiet = (uint8_t *)ie; 928 break; 929 case WLAN_ELEMID_ERP: 930 if (ie->ie_len != (sizeof(struct erp_ie) - 931 sizeof(struct ie_header))) 932 goto err; 933 scan_params->erp = ((struct erp_ie *)ie)->value; 934 break; 935 case WLAN_ELEMID_HTCAP_ANA: 936 if (ie->ie_len != sizeof(struct htcap_cmn_ie)) 937 goto err; 938 scan_params->ie_list.htcap = 939 (uint8_t *)&(((struct htcap_ie *)ie)->ie); 940 break; 941 case WLAN_ELEMID_RSN: 942 if (ie->ie_len < WLAN_RSN_IE_MIN_LEN) 943 goto err; 944 scan_params->ie_list.rsn = (uint8_t *)ie; 945 break; 946 case WLAN_ELEMID_XRATES: 947 scan_params->ie_list.xrates = (uint8_t *)ie; 948 break; 949 case WLAN_ELEMID_EXTCHANSWITCHANN: 950 if (ie->ie_len != WLAN_XCSA_IE_MAX_LEN) 951 goto err; 952 scan_params->ie_list.xcsa = (uint8_t *)ie; 953 break; 954 case WLAN_ELEMID_SECCHANOFFSET: 955 if (ie->ie_len != WLAN_SECCHANOFF_IE_MAX_LEN) 956 goto err; 957 scan_params->ie_list.secchanoff = (uint8_t *)ie; 958 break; 959 case WLAN_ELEMID_HTINFO_ANA: 960 if (ie->ie_len != sizeof(struct wlan_ie_htinfo_cmn)) 961 goto err; 962 scan_params->ie_list.htinfo = 963 (uint8_t *)&(((struct wlan_ie_htinfo *) ie)->hi_ie); 964 *chan_idx = 965 ((struct wlan_ie_htinfo_cmn *) 966 (scan_params->ie_list.htinfo))->hi_ctrlchannel; 967 break; 968 case WLAN_ELEMID_WAPI: 969 if (ie->ie_len < WLAN_WAPI_IE_MIN_LEN) 970 goto err; 971 scan_params->ie_list.wapi = (uint8_t *)ie; 972 break; 973 case WLAN_ELEMID_XCAPS: 974 if (ie->ie_len > WLAN_EXTCAP_IE_MAX_LEN) 975 goto err; 976 scan_params->ie_list.extcaps = (uint8_t *)ie; 977 break; 978 case WLAN_ELEMID_VHTCAP: 979 if (ie->ie_len != (sizeof(struct wlan_ie_vhtcaps) - 980 sizeof(struct ie_header))) 981 goto err; 982 scan_params->ie_list.vhtcap = (uint8_t *)ie; 983 break; 984 case WLAN_ELEMID_VHTOP: 985 if (ie->ie_len != (sizeof(struct wlan_ie_vhtop) - 986 sizeof(struct ie_header))) 987 goto err; 988 scan_params->ie_list.vhtop = (uint8_t *)ie; 989 break; 990 case WLAN_ELEMID_OP_MODE_NOTIFY: 991 if (ie->ie_len != WLAN_OPMODE_IE_MAX_LEN) 992 goto err; 993 scan_params->ie_list.opmode = (uint8_t *)ie; 994 break; 995 case WLAN_ELEMID_MOBILITY_DOMAIN: 996 if (ie->ie_len != WLAN_MOBILITY_DOMAIN_IE_MAX_LEN) 997 goto err; 998 scan_params->ie_list.mdie = (uint8_t *)ie; 999 break; 1000 case WLAN_ELEMID_VENDOR: 1001 status = util_scan_parse_vendor_ie(scan_params, 1002 ie); 1003 if (QDF_IS_STATUS_ERROR(status)) 1004 goto err_status; 1005 break; 1006 case WLAN_ELEMID_CHAN_SWITCH_WRAP: 1007 scan_params->ie_list.cswrp = (uint8_t *)ie; 1008 /* Go to next sub IE */ 1009 sub_ie = (struct ie_header *) 1010 (((uint8_t *)ie) + sizeof(struct ie_header)); 1011 sub_ie_len = ie->ie_len; 1012 status = 1013 util_scan_parse_chan_switch_wrapper_ie( 1014 scan_params, sub_ie, sub_ie_len); 1015 if (QDF_IS_STATUS_ERROR(status)) { 1016 goto err_status; 1017 } 1018 break; 1019 case WLAN_ELEMID_FILS_INDICATION: 1020 if (ie->ie_len < WLAN_FILS_INDICATION_IE_MIN_LEN) 1021 goto err; 1022 scan_params->ie_list.fils_indication = (uint8_t *)ie; 1023 break; 1024 case WLAN_ELEMID_EXTN_ELEM: 1025 status = util_scan_parse_extn_ie(scan_params, ie); 1026 if (QDF_IS_STATUS_ERROR(status)) 1027 goto err_status; 1028 break; 1029 case WLAN_ELEMID_REDUCED_NEIGHBOR_REPORT: 1030 if (ie->ie_len < WLAN_RNR_IE_MIN_LEN) 1031 goto err; 1032 scan_params->ie_list.rnrie = (uint8_t *)ie; 1033 status = util_scan_parse_rnr_ie(scan_params, ie); 1034 if (QDF_IS_STATUS_ERROR(status)) 1035 goto err_status; 1036 break; 1037 default: 1038 break; 1039 } 1040 1041 /* Consume info element */ 1042 ie_len -= ie->ie_len; 1043 /* Go to next IE */ 1044 ie = (struct ie_header *) 1045 (((uint8_t *) ie) + 1046 sizeof(struct ie_header) + 1047 ie->ie_len); 1048 } 1049 1050 return QDF_STATUS_SUCCESS; 1051 1052 err: 1053 status = QDF_STATUS_E_INVAL; 1054 err_status: 1055 scm_debug("failed to parse IE - id: %d, len: %d", 1056 ie->ie_id, ie->ie_len); 1057 1058 return status; 1059 } 1060 1061 /** 1062 * util_scan_update_esp_data: update ESP params from beacon/probe response 1063 * @esp_information: pointer to wlan_esp_information 1064 * @scan_entry: new received entry 1065 * 1066 * The Estimated Service Parameters element is 1067 * used by a AP to provide information to another STA which 1068 * can then use the information as input to an algorithm to 1069 * generate an estimate of throughput between the two STAs. 1070 * The ESP Information List field contains from 1 to 4 ESP 1071 * Information fields(each field 24 bits), each corresponding 1072 * to an access category for which estimated service parameters 1073 * information is provided. 1074 * 1075 * Return: None 1076 */ 1077 static void util_scan_update_esp_data(struct wlan_esp_ie *esp_information, 1078 struct scan_cache_entry *scan_entry) 1079 { 1080 1081 uint8_t *data; 1082 int i = 0; 1083 uint64_t total_elements; 1084 struct wlan_esp_info *esp_info; 1085 struct wlan_esp_ie *esp_ie; 1086 1087 esp_ie = (struct wlan_esp_ie *) 1088 util_scan_entry_esp_info(scan_entry); 1089 1090 total_elements = esp_ie->esp_len; 1091 data = (uint8_t *)esp_ie + 3; 1092 do_div(total_elements, ESP_INFORMATION_LIST_LENGTH); 1093 1094 if (total_elements > MAX_ESP_INFORMATION_FIELD) { 1095 scm_err("No of Air time fractions are greater than supported"); 1096 return; 1097 } 1098 1099 for (i = 0; i < total_elements; i++) { 1100 esp_info = (struct wlan_esp_info *)data; 1101 if (esp_info->access_category == ESP_AC_BK) { 1102 qdf_mem_copy(&esp_information->esp_info_AC_BK, 1103 data, 3); 1104 data = data + ESP_INFORMATION_LIST_LENGTH; 1105 continue; 1106 } 1107 if (esp_info->access_category == ESP_AC_BE) { 1108 qdf_mem_copy(&esp_information->esp_info_AC_BE, 1109 data, 3); 1110 data = data + ESP_INFORMATION_LIST_LENGTH; 1111 continue; 1112 } 1113 if (esp_info->access_category == ESP_AC_VI) { 1114 qdf_mem_copy(&esp_information->esp_info_AC_VI, 1115 data, 3); 1116 data = data + ESP_INFORMATION_LIST_LENGTH; 1117 continue; 1118 } 1119 if (esp_info->access_category == ESP_AC_VO) { 1120 qdf_mem_copy(&esp_information->esp_info_AC_VO, 1121 data, 3); 1122 data = data + ESP_INFORMATION_LIST_LENGTH; 1123 break; 1124 } 1125 } 1126 } 1127 1128 /** 1129 * util_scan_scm_update_bss_with_esp_dataa: calculate estimated air time 1130 * fraction 1131 * @scan_entry: new received entry 1132 * 1133 * This function process all Access category ESP params and provide 1134 * best effort air time fraction. 1135 * If best effort is not available, it will choose VI, VO and BK in sequence 1136 * 1137 */ 1138 static void util_scan_scm_update_bss_with_esp_data( 1139 struct scan_cache_entry *scan_entry) 1140 { 1141 uint8_t air_time_fraction = 0; 1142 struct wlan_esp_ie esp_information; 1143 1144 if (!scan_entry->ie_list.esp) 1145 return; 1146 1147 util_scan_update_esp_data(&esp_information, scan_entry); 1148 1149 /* 1150 * If the ESP metric is transmitting multiple airtime fractions, then 1151 * follow the sequence AC_BE, AC_VI, AC_VO, AC_BK and pick whichever is 1152 * the first one available 1153 */ 1154 if (esp_information.esp_info_AC_BE.access_category 1155 == ESP_AC_BE) 1156 air_time_fraction = 1157 esp_information.esp_info_AC_BE. 1158 estimated_air_fraction; 1159 else if (esp_information.esp_info_AC_VI.access_category 1160 == ESP_AC_VI) 1161 air_time_fraction = 1162 esp_information.esp_info_AC_VI. 1163 estimated_air_fraction; 1164 else if (esp_information.esp_info_AC_VO.access_category 1165 == ESP_AC_VO) 1166 air_time_fraction = 1167 esp_information.esp_info_AC_VO. 1168 estimated_air_fraction; 1169 else if (esp_information.esp_info_AC_BK.access_category 1170 == ESP_AC_BK) 1171 air_time_fraction = 1172 esp_information.esp_info_AC_BK. 1173 estimated_air_fraction; 1174 scan_entry->air_time_fraction = air_time_fraction; 1175 } 1176 1177 /** 1178 * util_scan_scm_calc_nss_supported_by_ap() - finds out nss from AP 1179 * @scan_entry: new received entry 1180 * 1181 * Return: number of nss advertised by AP 1182 */ 1183 static int util_scan_scm_calc_nss_supported_by_ap( 1184 struct scan_cache_entry *scan_params) 1185 { 1186 struct htcap_cmn_ie *htcap; 1187 struct wlan_ie_vhtcaps *vhtcaps; 1188 uint8_t rx_mcs_map; 1189 1190 htcap = (struct htcap_cmn_ie *) 1191 util_scan_entry_htcap(scan_params); 1192 vhtcaps = (struct wlan_ie_vhtcaps *) 1193 util_scan_entry_vhtcap(scan_params); 1194 if (vhtcaps) { 1195 rx_mcs_map = vhtcaps->rx_mcs_map; 1196 if ((rx_mcs_map & 0xC0) != 0xC0) 1197 return 4; 1198 1199 if ((rx_mcs_map & 0x30) != 0x30) 1200 return 3; 1201 1202 if ((rx_mcs_map & 0x0C) != 0x0C) 1203 return 2; 1204 } else if (htcap) { 1205 if (htcap->mcsset[3]) 1206 return 4; 1207 1208 if (htcap->mcsset[2]) 1209 return 3; 1210 1211 if (htcap->mcsset[1]) 1212 return 2; 1213 1214 } 1215 return 1; 1216 } 1217 1218 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID 1219 QDF_STATUS 1220 util_scan_add_hidden_ssid(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t bcnbuf) 1221 { 1222 struct wlan_frame_hdr *hdr; 1223 struct wlan_bcn_frame *bcn; 1224 struct wlan_scan_obj *scan_obj; 1225 struct wlan_ssid *conf_ssid; 1226 struct ie_header *ie; 1227 uint32_t frame_len = qdf_nbuf_len(bcnbuf); 1228 uint16_t bcn_ie_offset, ssid_ie_start_offset, ssid_ie_end_offset; 1229 uint16_t tmplen, ie_length; 1230 uint8_t *pbeacon, *tmp; 1231 bool set_ssid_flag = false; 1232 struct ie_ssid *ssid; 1233 uint8_t pdev_id; 1234 1235 if (!pdev) { 1236 scm_warn("pdev: 0x%pK is NULL", pdev); 1237 return QDF_STATUS_E_NULL_VALUE; 1238 } 1239 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1240 scan_obj = wlan_pdev_get_scan_obj(pdev); 1241 if (!scan_obj) { 1242 scm_warn("null scan_obj"); 1243 return QDF_STATUS_E_NULL_VALUE; 1244 } 1245 1246 conf_ssid = &scan_obj->pdev_info[pdev_id].conf_ssid; 1247 1248 hdr = (struct wlan_frame_hdr *)qdf_nbuf_data(bcnbuf); 1249 1250 /* received bssid does not match configured bssid */ 1251 if (qdf_mem_cmp(hdr->i_addr3, scan_obj->pdev_info[pdev_id].conf_bssid, 1252 QDF_MAC_ADDR_SIZE) || 1253 conf_ssid->length == 0) { 1254 return QDF_STATUS_SUCCESS; 1255 } 1256 1257 bcn = (struct wlan_bcn_frame *)(qdf_nbuf_data(bcnbuf) + sizeof(*hdr)); 1258 pbeacon = (uint8_t *)bcn; 1259 1260 ie = (struct ie_header *)(pbeacon + 1261 offsetof(struct wlan_bcn_frame, ie)); 1262 1263 bcn_ie_offset = offsetof(struct wlan_bcn_frame, ie); 1264 ie_length = (uint16_t)(frame_len - sizeof(*hdr) - 1265 bcn_ie_offset); 1266 1267 while (ie_length >= sizeof(struct ie_header)) { 1268 ie_length -= sizeof(struct ie_header); 1269 1270 bcn_ie_offset += sizeof(struct ie_header); 1271 1272 if (ie_length < ie->ie_len) { 1273 scm_debug("Incomplete corrupted IE:%x", ie->ie_id); 1274 return QDF_STATUS_E_INVAL; 1275 } 1276 if (ie->ie_id == WLAN_ELEMID_SSID) { 1277 if (ie->ie_len > (sizeof(struct ie_ssid) - 1278 sizeof(struct ie_header))) { 1279 return QDF_STATUS_E_INVAL; 1280 } 1281 ssid = (struct ie_ssid *)ie; 1282 if (util_scan_is_hidden_ssid(ssid)) { 1283 set_ssid_flag = true; 1284 ssid_ie_start_offset = bcn_ie_offset - 1285 sizeof(struct ie_header); 1286 ssid_ie_end_offset = bcn_ie_offset + 1287 ie->ie_len; 1288 } 1289 } 1290 if (ie->ie_len == 0) { 1291 ie += 1; /* next IE */ 1292 continue; 1293 } 1294 if (ie->ie_id == WLAN_ELEMID_VENDOR && 1295 is_wps_oui((uint8_t *)ie)) { 1296 set_ssid_flag = false; 1297 break; 1298 } 1299 /* Consume info element */ 1300 ie_length -= ie->ie_len; 1301 /* Go to next IE */ 1302 ie = (struct ie_header *)(((uint8_t *)ie) + 1303 sizeof(struct ie_header) + 1304 ie->ie_len); 1305 } 1306 1307 if (set_ssid_flag) { 1308 /* Hidden SSID if the Length is 0 */ 1309 if (!ssid->ssid_len) { 1310 /* increase the taillength by length of ssid */ 1311 if (qdf_nbuf_put_tail(bcnbuf, 1312 conf_ssid->length) == NULL) { 1313 scm_debug("No enough tailroom"); 1314 return QDF_STATUS_E_NOMEM; 1315 } 1316 /* length of the buffer to be copied */ 1317 tmplen = frame_len - 1318 sizeof(*hdr) - ssid_ie_end_offset; 1319 /* 1320 * tmp memory to copy the beacon info 1321 * after ssid ie. 1322 */ 1323 tmp = qdf_mem_malloc(tmplen * sizeof(u_int8_t)); 1324 if (!tmp) 1325 return QDF_STATUS_E_NOMEM; 1326 1327 /* Copy beacon data after ssid ie to tmp */ 1328 qdf_nbuf_copy_bits(bcnbuf, (sizeof(*hdr) + 1329 ssid_ie_end_offset), tmplen, tmp); 1330 /* Add ssid length */ 1331 *(pbeacon + (ssid_ie_start_offset + 1)) 1332 = conf_ssid->length; 1333 /* Insert the SSID string */ 1334 qdf_mem_copy((pbeacon + ssid_ie_end_offset), 1335 conf_ssid->ssid, conf_ssid->length); 1336 /* Copy rest of the beacon data */ 1337 qdf_mem_copy((pbeacon + ssid_ie_end_offset + 1338 conf_ssid->length), tmp, tmplen); 1339 qdf_mem_free(tmp); 1340 1341 /* Hidden ssid with all 0's */ 1342 } else if (ssid->ssid_len == conf_ssid->length) { 1343 /* Insert the SSID string */ 1344 qdf_mem_copy((pbeacon + ssid_ie_start_offset + 1345 sizeof(struct ie_header)), 1346 conf_ssid->ssid, conf_ssid->length); 1347 } else { 1348 scm_debug("mismatch in hidden ssid length"); 1349 return QDF_STATUS_E_INVAL; 1350 } 1351 } 1352 return QDF_STATUS_SUCCESS; 1353 } 1354 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */ 1355 1356 #ifdef WLAN_ADAPTIVE_11R 1357 /** 1358 * scm_fill_adaptive_11r_cap() - Check if the AP supports adaptive 11r 1359 * @scan_entry: Pointer to the scan entry 1360 * 1361 * Return: true if adaptive 11r is advertised else false 1362 */ 1363 static void scm_fill_adaptive_11r_cap(struct scan_cache_entry *scan_entry) 1364 { 1365 uint8_t *ie; 1366 uint8_t data; 1367 bool adaptive_11r; 1368 1369 ie = util_scan_entry_adaptive_11r(scan_entry); 1370 if (!ie) 1371 return; 1372 1373 data = *(ie + OUI_LENGTH); 1374 adaptive_11r = (data & 0x1) ? true : false; 1375 1376 scan_entry->adaptive_11r_ap = adaptive_11r; 1377 } 1378 #else 1379 static void scm_fill_adaptive_11r_cap(struct scan_cache_entry *scan_entry) 1380 { 1381 scan_entry->adaptive_11r_ap = false; 1382 } 1383 #endif 1384 1385 static void util_scan_set_security(struct scan_cache_entry *scan_params) 1386 { 1387 if (util_scan_entry_wpa(scan_params)) 1388 scan_params->security_type |= SCAN_SECURITY_TYPE_WPA; 1389 1390 if (util_scan_entry_rsn(scan_params)) 1391 scan_params->security_type |= SCAN_SECURITY_TYPE_RSN; 1392 if (util_scan_entry_wapi(scan_params)) 1393 scan_params->security_type |= SCAN_SECURITY_TYPE_WAPI; 1394 1395 if (!scan_params->security_type && 1396 scan_params->cap_info.wlan_caps.privacy) 1397 scan_params->security_type |= SCAN_SECURITY_TYPE_WEP; 1398 } 1399 1400 static QDF_STATUS 1401 util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, 1402 uint8_t *frame, qdf_size_t frame_len, 1403 uint32_t frm_subtype, 1404 struct mgmt_rx_event_params *rx_param, 1405 struct scan_mbssid_info *mbssid_info, 1406 qdf_list_t *scan_list) 1407 { 1408 struct wlan_frame_hdr *hdr; 1409 struct wlan_bcn_frame *bcn; 1410 QDF_STATUS status = QDF_STATUS_SUCCESS; 1411 struct ie_ssid *ssid; 1412 struct scan_cache_entry *scan_entry; 1413 struct qbss_load_ie *qbss_load; 1414 struct scan_cache_node *scan_node; 1415 uint8_t i, chan_idx = 0; 1416 bool he_6g_dup_bcon = false; 1417 1418 scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry)); 1419 if (!scan_entry) { 1420 scm_err("failed to allocate memory for scan_entry"); 1421 return QDF_STATUS_E_NOMEM; 1422 } 1423 scan_entry->raw_frame.ptr = 1424 qdf_mem_malloc_atomic(frame_len); 1425 if (!scan_entry->raw_frame.ptr) { 1426 scm_err("failed to allocate memory for frame"); 1427 qdf_mem_free(scan_entry); 1428 return QDF_STATUS_E_NOMEM; 1429 } 1430 1431 bcn = (struct wlan_bcn_frame *) 1432 (frame + sizeof(*hdr)); 1433 hdr = (struct wlan_frame_hdr *)frame; 1434 1435 /* update timestamp in nanoseconds needed by kernel layers */ 1436 scan_entry->boottime_ns = qdf_get_bootbased_boottime_ns(); 1437 1438 scan_entry->frm_subtype = frm_subtype; 1439 qdf_mem_copy(scan_entry->bssid.bytes, 1440 hdr->i_addr3, QDF_MAC_ADDR_SIZE); 1441 /* Scr addr */ 1442 qdf_mem_copy(scan_entry->mac_addr.bytes, 1443 hdr->i_addr2, QDF_MAC_ADDR_SIZE); 1444 scan_entry->seq_num = 1445 (le16toh(*(uint16_t *)hdr->i_seq) >> WLAN_SEQ_SEQ_SHIFT); 1446 1447 scan_entry->snr = rx_param->snr; 1448 scan_entry->avg_snr = WLAN_SNR_IN(scan_entry->snr); 1449 scan_entry->rssi_raw = rx_param->rssi; 1450 scan_entry->avg_rssi = WLAN_RSSI_IN(scan_entry->rssi_raw); 1451 scan_entry->tsf_delta = rx_param->tsf_delta; 1452 scan_entry->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1453 1454 /* Copy per chain rssi to scan entry */ 1455 qdf_mem_copy(scan_entry->per_chain_rssi, rx_param->rssi_ctl, 1456 WLAN_MGMT_TXRX_HOST_MAX_ANTENNA); 1457 1458 if (!wlan_psoc_nif_fw_ext_cap_get(wlan_pdev_get_psoc(pdev), 1459 WLAN_SOC_CEXT_HW_DB2DBM)) { 1460 for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) { 1461 if (scan_entry->per_chain_rssi[i] != 1462 WLAN_INVALID_PER_CHAIN_SNR) 1463 scan_entry->per_chain_rssi[i] += 1464 WLAN_NOISE_FLOOR_DBM_DEFAULT; 1465 else 1466 scan_entry->per_chain_rssi[i] = 1467 WLAN_INVALID_PER_CHAIN_RSSI; 1468 } 1469 } 1470 1471 /* store jiffies */ 1472 scan_entry->rrm_parent_tsf = (uint32_t)qdf_system_ticks(); 1473 1474 scan_entry->bcn_int = le16toh(bcn->beacon_interval); 1475 1476 /* 1477 * In case if the beacon dosnt have 1478 * valid beacon interval falback to def 1479 */ 1480 if (!scan_entry->bcn_int) 1481 scan_entry->bcn_int = 100; 1482 scan_entry->cap_info.value = le16toh(bcn->capability.value); 1483 qdf_mem_copy(scan_entry->tsf_info.data, 1484 bcn->timestamp, 8); 1485 scan_entry->erp = ERP_NON_ERP_PRESENT; 1486 1487 scan_entry->scan_entry_time = 1488 qdf_mc_timer_get_system_time(); 1489 1490 scan_entry->raw_frame.len = frame_len; 1491 qdf_mem_copy(scan_entry->raw_frame.ptr, 1492 frame, frame_len); 1493 status = util_scan_populate_bcn_ie_list(scan_entry, &chan_idx); 1494 if (QDF_IS_STATUS_ERROR(status)) { 1495 scm_debug("failed to parse beacon IE"); 1496 qdf_mem_free(scan_entry->raw_frame.ptr); 1497 qdf_mem_free(scan_entry); 1498 return QDF_STATUS_E_FAILURE; 1499 } 1500 1501 ssid = (struct ie_ssid *) 1502 scan_entry->ie_list.ssid; 1503 1504 if (ssid && (ssid->ssid_len > WLAN_SSID_MAX_LEN)) { 1505 qdf_mem_free(scan_entry->raw_frame.ptr); 1506 qdf_mem_free(scan_entry); 1507 return QDF_STATUS_E_FAILURE; 1508 } 1509 1510 if (scan_entry->ie_list.p2p) 1511 scan_entry->is_p2p = true; 1512 1513 if (!chan_idx && util_scan_entry_hecap(scan_entry)) 1514 util_scan_get_chan_from_he_6g_params(scan_entry, &chan_idx, 1515 &he_6g_dup_bcon); 1516 1517 if (chan_idx) { 1518 uint8_t band_mask = BIT(wlan_reg_freq_to_band( 1519 rx_param->chan_freq)); 1520 1521 scan_entry->channel.chan_freq = 1522 wlan_reg_chan_band_to_freq( 1523 pdev, chan_idx, 1524 band_mask); 1525 } 1526 /* If no channel info is present in beacon use meta channel */ 1527 if (!scan_entry->channel.chan_freq) { 1528 scan_entry->channel.chan_freq = rx_param->chan_freq; 1529 } else if (rx_param->chan_freq != 1530 scan_entry->channel.chan_freq) { 1531 if (!wlan_reg_is_49ghz_freq(scan_entry->channel.chan_freq) && 1532 !he_6g_dup_bcon) 1533 scan_entry->channel_mismatch = true; 1534 } 1535 1536 if (util_scan_is_hidden_ssid(ssid)) { 1537 scan_entry->ie_list.ssid = NULL; 1538 scan_entry->is_hidden_ssid = true; 1539 } else { 1540 qdf_mem_copy(scan_entry->ssid.ssid, 1541 ssid->ssid, ssid->ssid_len); 1542 scan_entry->ssid.length = ssid->ssid_len; 1543 scan_entry->hidden_ssid_timestamp = 1544 scan_entry->scan_entry_time; 1545 } 1546 qdf_mem_copy(&scan_entry->mbssid_info, mbssid_info, 1547 sizeof(scan_entry->mbssid_info)); 1548 1549 scan_entry->phy_mode = util_scan_get_phymode(pdev, scan_entry); 1550 1551 scan_entry->nss = util_scan_scm_calc_nss_supported_by_ap(scan_entry); 1552 scm_fill_adaptive_11r_cap(scan_entry); 1553 util_scan_set_security(scan_entry); 1554 1555 util_scan_scm_update_bss_with_esp_data(scan_entry); 1556 qbss_load = (struct qbss_load_ie *) 1557 util_scan_entry_qbssload(scan_entry); 1558 if (qbss_load) 1559 scan_entry->qbss_chan_load = qbss_load->qbss_chan_load; 1560 1561 scan_node = qdf_mem_malloc_atomic(sizeof(*scan_node)); 1562 if (!scan_node) { 1563 qdf_mem_free(scan_entry->raw_frame.ptr); 1564 qdf_mem_free(scan_entry); 1565 return QDF_STATUS_E_FAILURE; 1566 } 1567 1568 scan_node->entry = scan_entry; 1569 qdf_list_insert_front(scan_list, &scan_node->node); 1570 1571 return status; 1572 } 1573 1574 /** 1575 * util_scan_find_ie() - find information element 1576 * @eid: element id 1577 * @ies: pointer consisting of IEs 1578 * @len: IE length 1579 * 1580 * Return: NULL if the element ID is not found or 1581 * a pointer to the first byte of the requested 1582 * element 1583 */ 1584 static uint8_t *util_scan_find_ie(uint8_t eid, uint8_t *ies, 1585 int32_t len) 1586 { 1587 while (len >= 2 && len >= ies[1] + 2) { 1588 if (ies[0] == eid) 1589 return ies; 1590 len -= ies[1] + 2; 1591 ies += ies[1] + 2; 1592 } 1593 1594 return NULL; 1595 } 1596 1597 #ifdef WLAN_FEATURE_MBSSID 1598 static void util_gen_new_bssid(uint8_t *bssid, uint8_t max_bssid, 1599 uint8_t mbssid_index, 1600 uint8_t *new_bssid_addr) 1601 { 1602 uint8_t lsb_n; 1603 int i; 1604 1605 for (i = 0; i < QDF_MAC_ADDR_SIZE; i++) 1606 new_bssid_addr[i] = bssid[i]; 1607 1608 lsb_n = new_bssid_addr[5] & ((1 << max_bssid) - 1); 1609 1610 new_bssid_addr[5] &= ~((1 << max_bssid) - 1); 1611 new_bssid_addr[5] |= (lsb_n + mbssid_index) % (1 << max_bssid); 1612 } 1613 1614 static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen, 1615 uint8_t *subelement, 1616 size_t subie_len, uint8_t *new_ie) 1617 { 1618 uint8_t *pos, *tmp; 1619 const uint8_t *tmp_old, *tmp_new; 1620 uint8_t *sub_copy; 1621 1622 /* copy subelement as we need to change its content to 1623 * mark an ie after it is processed. 1624 */ 1625 sub_copy = qdf_mem_malloc(subie_len); 1626 if (!sub_copy) 1627 return 0; 1628 qdf_mem_copy(sub_copy, subelement, subie_len); 1629 1630 pos = &new_ie[0]; 1631 1632 /* new ssid */ 1633 tmp_new = util_scan_find_ie(WLAN_ELEMID_SSID, sub_copy, subie_len); 1634 if (tmp_new) { 1635 qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2); 1636 pos += (tmp_new[1] + 2); 1637 } 1638 1639 /* go through IEs in ie (skip SSID) and subelement, 1640 * merge them into new_ie 1641 */ 1642 tmp_old = util_scan_find_ie(WLAN_ELEMID_SSID, ie, ielen); 1643 tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; 1644 1645 while (tmp_old + tmp_old[1] + 2 - ie <= ielen) { 1646 if (tmp_old[0] == 0) { 1647 tmp_old++; 1648 continue; 1649 } 1650 1651 tmp = (uint8_t *)util_scan_find_ie(tmp_old[0], sub_copy, 1652 subie_len); 1653 if (!tmp) { 1654 /* ie in old ie but not in subelement */ 1655 if (tmp_old[0] != WLAN_ELEMID_MULTIPLE_BSSID) { 1656 qdf_mem_copy(pos, tmp_old, tmp_old[1] + 2); 1657 pos += tmp_old[1] + 2; 1658 } 1659 } else { 1660 /* ie in transmitting ie also in subelement, 1661 * copy from subelement and flag the ie in subelement 1662 * as copied (by setting eid field to 0xff). For 1663 * vendor ie, compare OUI + type + subType to 1664 * determine if they are the same ie. 1665 */ 1666 if (tmp_old[0] == WLAN_ELEMID_VENDOR) { 1667 if (!qdf_mem_cmp(tmp_old + 2, tmp + 2, 5)) { 1668 /* same vendor ie, copy from 1669 * subelement 1670 */ 1671 qdf_mem_copy(pos, tmp, tmp[1] + 2); 1672 pos += tmp[1] + 2; 1673 tmp[0] = 0xff; 1674 } else { 1675 qdf_mem_copy(pos, tmp_old, 1676 tmp_old[1] + 2); 1677 pos += tmp_old[1] + 2; 1678 } 1679 } else { 1680 /* copy ie from subelement into new ie */ 1681 qdf_mem_copy(pos, tmp, tmp[1] + 2); 1682 pos += tmp[1] + 2; 1683 tmp[0] = 0xff; 1684 } 1685 } 1686 1687 if (tmp_old + tmp_old[1] + 2 - ie == ielen) 1688 break; 1689 1690 tmp_old += tmp_old[1] + 2; 1691 } 1692 1693 /* go through subelement again to check if there is any ie not 1694 * copied to new ie, skip ssid, capability, bssid-index ie 1695 */ 1696 tmp_new = sub_copy; 1697 while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { 1698 if (!(tmp_new[0] == WLAN_ELEMID_NONTX_BSSID_CAP || 1699 tmp_new[0] == WLAN_ELEMID_SSID || 1700 tmp_new[0] == WLAN_ELEMID_MULTI_BSSID_IDX || 1701 tmp_new[0] == 0xff)) { 1702 qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2); 1703 pos += tmp_new[1] + 2; 1704 } 1705 if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len) 1706 break; 1707 tmp_new += tmp_new[1] + 2; 1708 } 1709 1710 qdf_mem_free(sub_copy); 1711 return pos - new_ie; 1712 } 1713 1714 static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, 1715 uint8_t *frame, qdf_size_t frame_len, 1716 uint32_t frm_subtype, 1717 struct mgmt_rx_event_params *rx_param, 1718 qdf_list_t *scan_list) 1719 { 1720 struct wlan_bcn_frame *bcn; 1721 struct wlan_frame_hdr *hdr; 1722 struct scan_mbssid_info mbssid_info; 1723 QDF_STATUS status; 1724 uint8_t *pos, *subelement, *mbssid_end_pos; 1725 uint8_t *tmp, *mbssid_index_ie; 1726 uint32_t subie_len, new_ie_len; 1727 uint8_t new_bssid[QDF_MAC_ADDR_SIZE], bssid[QDF_MAC_ADDR_SIZE]; 1728 uint8_t *new_ie; 1729 uint8_t *ie, *new_frame = NULL; 1730 uint64_t ielen, new_frame_len; 1731 1732 hdr = (struct wlan_frame_hdr *)frame; 1733 bcn = (struct wlan_bcn_frame *)(frame + sizeof(struct wlan_frame_hdr)); 1734 ie = (uint8_t *)&bcn->ie; 1735 ielen = (uint16_t)(frame_len - 1736 sizeof(struct wlan_frame_hdr) - 1737 offsetof(struct wlan_bcn_frame, ie)); 1738 qdf_mem_copy(bssid, hdr->i_addr3, QDF_MAC_ADDR_SIZE); 1739 1740 if (!util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, ie, ielen)) 1741 return QDF_STATUS_E_FAILURE; 1742 1743 pos = ie; 1744 1745 new_ie = qdf_mem_malloc(MAX_IE_LEN); 1746 if (!new_ie) 1747 return QDF_STATUS_E_NOMEM; 1748 1749 while (pos < ie + ielen + 2) { 1750 tmp = util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, pos, 1751 ielen - (pos - ie)); 1752 if (!tmp) 1753 break; 1754 1755 mbssid_info.profile_count = 1 << tmp[2]; 1756 mbssid_end_pos = tmp + tmp[1] + 2; 1757 /* Skip Element ID, Len, MaxBSSID Indicator */ 1758 if (tmp[1] < 4) 1759 break; 1760 for (subelement = tmp + 3; subelement < mbssid_end_pos - 1; 1761 subelement += 2 + subelement[1]) { 1762 subie_len = subelement[1]; 1763 if (mbssid_end_pos - subelement < 2 + subie_len) 1764 break; 1765 if (subelement[0] != 0 || subelement[1] < 4) { 1766 /* not a valid BSS profile */ 1767 continue; 1768 } 1769 1770 if (subelement[2] != WLAN_ELEMID_NONTX_BSSID_CAP || 1771 subelement[3] != 2) { 1772 /* The first element within the Nontransmitted 1773 * BSSID Profile is not the Nontransmitted 1774 * BSSID Capability element. 1775 */ 1776 continue; 1777 } 1778 1779 /* found a Nontransmitted BSSID Profile */ 1780 mbssid_index_ie = 1781 util_scan_find_ie(WLAN_ELEMID_MULTI_BSSID_IDX, 1782 subelement + 2, subie_len); 1783 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || 1784 mbssid_index_ie[2] == 0) { 1785 /* No valid Multiple BSSID-Index element */ 1786 continue; 1787 } 1788 qdf_mem_copy(&mbssid_info.trans_bssid, bssid, 1789 QDF_MAC_ADDR_SIZE); 1790 mbssid_info.profile_num = mbssid_index_ie[2]; 1791 util_gen_new_bssid(bssid, tmp[2], mbssid_index_ie[2], 1792 new_bssid); 1793 new_ie_len = util_gen_new_ie(ie, ielen, subelement + 2, 1794 subie_len, new_ie); 1795 if (!new_ie_len) 1796 continue; 1797 1798 new_frame_len = frame_len - ielen + new_ie_len; 1799 new_frame = qdf_mem_malloc(new_frame_len); 1800 if (!new_frame) { 1801 qdf_mem_free(new_ie); 1802 return QDF_STATUS_E_NOMEM; 1803 } 1804 1805 /* 1806 * Copy the header(24byte), timestamp(8 byte), 1807 * beaconinterval(2byte) and capability(2byte) 1808 */ 1809 qdf_mem_copy(new_frame, frame, 36); 1810 /* Copy the new ie generated from MBSSID profile*/ 1811 hdr = (struct wlan_frame_hdr *)new_frame; 1812 qdf_mem_copy(hdr->i_addr2, new_bssid, 1813 QDF_MAC_ADDR_SIZE); 1814 qdf_mem_copy(hdr->i_addr3, new_bssid, 1815 QDF_MAC_ADDR_SIZE); 1816 /* Copy the new ie generated from MBSSID profile*/ 1817 qdf_mem_copy(new_frame + 1818 offsetof(struct wlan_bcn_frame, ie) + 1819 sizeof(struct wlan_frame_hdr), 1820 new_ie, new_ie_len); 1821 status = util_scan_gen_scan_entry(pdev, new_frame, 1822 new_frame_len, 1823 frm_subtype, 1824 rx_param, 1825 &mbssid_info, 1826 scan_list); 1827 if (QDF_IS_STATUS_ERROR(status)) { 1828 qdf_mem_free(new_frame); 1829 scm_err("failed to generate a scan entry"); 1830 break; 1831 } 1832 /* scan entry makes its own copy so free the frame*/ 1833 qdf_mem_free(new_frame); 1834 } 1835 1836 pos = mbssid_end_pos; 1837 } 1838 qdf_mem_free(new_ie); 1839 1840 return QDF_STATUS_SUCCESS; 1841 } 1842 #else 1843 static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, 1844 uint8_t *frame, qdf_size_t frame_len, 1845 uint32_t frm_subtype, 1846 struct mgmt_rx_event_params *rx_param, 1847 qdf_list_t *scan_list) 1848 { 1849 return QDF_STATUS_SUCCESS; 1850 } 1851 #endif 1852 1853 static QDF_STATUS 1854 util_scan_parse_beacon_frame(struct wlan_objmgr_pdev *pdev, 1855 uint8_t *frame, 1856 qdf_size_t frame_len, 1857 uint32_t frm_subtype, 1858 struct mgmt_rx_event_params *rx_param, 1859 qdf_list_t *scan_list) 1860 { 1861 struct wlan_bcn_frame *bcn; 1862 struct wlan_frame_hdr *hdr; 1863 uint8_t *mbssid_ie = NULL; 1864 uint32_t ie_len = 0; 1865 QDF_STATUS status; 1866 struct scan_mbssid_info mbssid_info = { 0 }; 1867 1868 hdr = (struct wlan_frame_hdr *)frame; 1869 bcn = (struct wlan_bcn_frame *) 1870 (frame + sizeof(struct wlan_frame_hdr)); 1871 ie_len = (uint16_t)(frame_len - 1872 sizeof(struct wlan_frame_hdr) - 1873 offsetof(struct wlan_bcn_frame, ie)); 1874 1875 mbssid_ie = util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, 1876 (uint8_t *)&bcn->ie, ie_len); 1877 if (mbssid_ie) { 1878 qdf_mem_copy(&mbssid_info.trans_bssid, 1879 hdr->i_addr3, QDF_MAC_ADDR_SIZE); 1880 mbssid_info.profile_count = 1 << mbssid_ie[2]; 1881 } 1882 1883 status = util_scan_gen_scan_entry(pdev, frame, frame_len, 1884 frm_subtype, rx_param, 1885 &mbssid_info, 1886 scan_list); 1887 1888 /* 1889 * IF MBSSID IE is present in the beacon then 1890 * scan component will create a new entry for 1891 * each BSSID found in the MBSSID 1892 */ 1893 if (mbssid_ie) 1894 status = util_scan_parse_mbssid(pdev, frame, frame_len, 1895 frm_subtype, rx_param, 1896 scan_list); 1897 1898 if (QDF_IS_STATUS_ERROR(status)) 1899 scm_debug_rl("Failed to create a scan entry"); 1900 1901 return status; 1902 } 1903 1904 qdf_list_t * 1905 util_scan_unpack_beacon_frame(struct wlan_objmgr_pdev *pdev, uint8_t *frame, 1906 qdf_size_t frame_len, uint32_t frm_subtype, 1907 struct mgmt_rx_event_params *rx_param) 1908 { 1909 qdf_list_t *scan_list; 1910 QDF_STATUS status; 1911 1912 scan_list = qdf_mem_malloc_atomic(sizeof(*scan_list)); 1913 if (!scan_list) { 1914 scm_err("failed to allocate scan_list"); 1915 return NULL; 1916 } 1917 qdf_list_create(scan_list, MAX_SCAN_CACHE_SIZE); 1918 1919 status = util_scan_parse_beacon_frame(pdev, frame, frame_len, 1920 frm_subtype, rx_param, 1921 scan_list); 1922 if (QDF_IS_STATUS_ERROR(status)) { 1923 ucfg_scan_purge_results(scan_list); 1924 return NULL; 1925 } 1926 1927 return scan_list; 1928 } 1929 1930 QDF_STATUS 1931 util_scan_entry_update_mlme_info(struct wlan_objmgr_pdev *pdev, 1932 struct scan_cache_entry *scan_entry) 1933 { 1934 1935 if (!pdev || !scan_entry) { 1936 scm_err("pdev 0x%pK, scan_entry: 0x%pK", pdev, scan_entry); 1937 return QDF_STATUS_E_INVAL; 1938 } 1939 1940 return scm_update_scan_mlme_info(pdev, scan_entry); 1941 } 1942 1943 bool util_is_scan_completed(struct scan_event *event, bool *success) 1944 { 1945 if ((event->type == SCAN_EVENT_TYPE_COMPLETED) || 1946 (event->type == SCAN_EVENT_TYPE_DEQUEUED) || 1947 (event->type == SCAN_EVENT_TYPE_START_FAILED)) { 1948 if ((event->type == SCAN_EVENT_TYPE_COMPLETED) && 1949 (event->reason == SCAN_REASON_COMPLETED)) 1950 *success = true; 1951 else 1952 *success = false; 1953 1954 return true; 1955 } 1956 1957 *success = false; 1958 return false; 1959 } 1960 1961