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