1 /* 2 * Copyright (c) 2017-2019 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 32 const char* 33 util_scan_get_ev_type_name(enum scan_event_type type) 34 { 35 static const char * const event_name[] = { 36 [SCAN_EVENT_TYPE_STARTED] = "STARTED", 37 [SCAN_EVENT_TYPE_COMPLETED] = "COMPLETED", 38 [SCAN_EVENT_TYPE_BSS_CHANNEL] = "HOME_CHANNEL", 39 [SCAN_EVENT_TYPE_FOREIGN_CHANNEL] = "FOREIGN_CHANNEL", 40 [SCAN_EVENT_TYPE_DEQUEUED] = "DEQUEUED", 41 [SCAN_EVENT_TYPE_PREEMPTED] = "PREEMPTED", 42 [SCAN_EVENT_TYPE_START_FAILED] = "START_FAILED", 43 [SCAN_EVENT_TYPE_RESTARTED] = "RESTARTED", 44 [SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT] = "FOREIGN_CHANNEL_EXIT", 45 [SCAN_EVENT_TYPE_SUSPENDED] = "SUSPENDED", 46 [SCAN_EVENT_TYPE_RESUMED] = "RESUMED", 47 [SCAN_EVENT_TYPE_NLO_COMPLETE] = "NLO_COMPLETE", 48 [SCAN_EVENT_TYPE_NLO_MATCH] = "NLO_MATCH", 49 [SCAN_EVENT_TYPE_INVALID] = "INVALID", 50 [SCAN_EVENT_TYPE_GPIO_TIMEOUT] = "GPIO_TIMEOUT", 51 [SCAN_EVENT_TYPE_RADIO_MEASUREMENT_START] = 52 "RADIO_MEASUREMENT_START", 53 [SCAN_EVENT_TYPE_RADIO_MEASUREMENT_END] = 54 "RADIO_MEASUREMENT_END", 55 [SCAN_EVENT_TYPE_BSSID_MATCH] = "BSSID_MATCH", 56 [SCAN_EVENT_TYPE_FOREIGN_CHANNEL_GET_NF] = 57 "FOREIGN_CHANNEL_GET_NF", 58 }; 59 60 if (type >= SCAN_EVENT_TYPE_MAX) 61 return "UNKNOWN"; 62 63 return event_name[type]; 64 } 65 66 67 const char* 68 util_scan_get_ev_reason_name(enum scan_completion_reason reason) 69 { 70 static const char * const reason_name[] = { 71 [SCAN_REASON_NONE] = "NONE", 72 [SCAN_REASON_COMPLETED] = "COMPLETED", 73 [SCAN_REASON_CANCELLED] = "CANCELLED", 74 [SCAN_REASON_PREEMPTED] = "PREEMPTED", 75 [SCAN_REASON_TIMEDOUT] = "TIMEDOUT", 76 [SCAN_REASON_INTERNAL_FAILURE] = "INTERNAL_FAILURE", 77 [SCAN_REASON_SUSPENDED] = "SUSPENDED", 78 [SCAN_REASON_RUN_FAILED] = "RUN_FAILED", 79 [SCAN_REASON_TERMINATION_FUNCTION] = "TERMINATION_FUNCTION", 80 [SCAN_REASON_MAX_OFFCHAN_RETRIES] = "MAX_OFFCHAN_RETRIES", 81 [SCAN_REASON_DFS_VIOLATION] = "DFS_NOL_VIOLATION", 82 }; 83 84 if (reason >= SCAN_REASON_MAX) 85 return "UNKNOWN"; 86 87 return reason_name[reason]; 88 } 89 90 qdf_time_t 91 util_get_last_scan_time(struct wlan_objmgr_vdev *vdev) 92 { 93 uint8_t pdev_id; 94 struct wlan_scan_obj *scan_obj; 95 96 if (!vdev) { 97 scm_warn("null vdev"); 98 QDF_ASSERT(0); 99 return 0; 100 } 101 pdev_id = wlan_scan_vdev_get_pdev_id(vdev); 102 scan_obj = wlan_vdev_get_scan_obj(vdev); 103 104 if (scan_obj) 105 return scan_obj->pdev_info[pdev_id].last_scan_time; 106 else 107 return 0; 108 } 109 110 enum wlan_band util_scan_scm_chan_to_band(uint32_t chan) 111 { 112 if (WLAN_CHAN_IS_2GHZ(chan)) 113 return WLAN_BAND_2_4_GHZ; 114 115 return WLAN_BAND_5_GHZ; 116 } 117 118 enum wlan_band util_scan_scm_freq_to_band(uint16_t freq) 119 { 120 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq)) 121 return WLAN_BAND_2_4_GHZ; 122 123 return WLAN_BAND_5_GHZ; 124 } 125 126 bool util_is_scan_entry_match( 127 struct scan_cache_entry *entry1, 128 struct scan_cache_entry *entry2) 129 { 130 131 if (entry1->cap_info.wlan_caps.ess != 132 entry2->cap_info.wlan_caps.ess) 133 return false; 134 135 if (entry1->cap_info.wlan_caps.ess && 136 !qdf_mem_cmp(entry1->bssid.bytes, 137 entry2->bssid.bytes, QDF_MAC_ADDR_SIZE)) { 138 /* Check for BSS */ 139 if (util_is_ssid_match(&entry1->ssid, &entry2->ssid) || 140 util_scan_is_null_ssid(&entry1->ssid) || 141 util_scan_is_null_ssid(&entry2->ssid)) 142 return true; 143 } else if (entry1->cap_info.wlan_caps.ibss && 144 (entry1->channel.chan_idx == 145 entry2->channel.chan_idx)) { 146 /* 147 * Same channel cannot have same SSID for 148 * different IBSS, so no need to check BSSID 149 */ 150 if (util_is_ssid_match( 151 &entry1->ssid, &entry2->ssid)) 152 return true; 153 } else if (!entry1->cap_info.wlan_caps.ibss && 154 !entry1->cap_info.wlan_caps.ess && 155 !qdf_mem_cmp(entry1->bssid.bytes, 156 entry2->bssid.bytes, QDF_MAC_ADDR_SIZE)) { 157 /* In case of P2P devices, ess and ibss will be set to zero */ 158 return true; 159 } 160 161 return false; 162 } 163 164 static bool util_is_pureg_rate(uint8_t *rates, uint8_t nrates) 165 { 166 static const uint8_t g_rates[] = {12, 18, 24, 36, 48, 72, 96, 108}; 167 bool pureg = false; 168 uint8_t i, j; 169 170 for (i = 0; i < nrates; i++) { 171 for (j = 0; j < QDF_ARRAY_SIZE(g_rates); j++) { 172 if (WLAN_RV(rates[i]) == g_rates[j]) { 173 pureg = true; 174 break; 175 } 176 } 177 if (pureg) 178 break; 179 } 180 181 return pureg; 182 } 183 static enum wlan_phymode 184 util_scan_get_phymode_5g(struct scan_cache_entry *scan_params) 185 { 186 enum wlan_phymode phymode = WLAN_PHYMODE_AUTO; 187 uint16_t ht_cap = 0; 188 struct htcap_cmn_ie *htcap; 189 struct wlan_ie_htinfo_cmn *htinfo; 190 struct wlan_ie_vhtop *vhtop; 191 192 htcap = (struct htcap_cmn_ie *) 193 util_scan_entry_htcap(scan_params); 194 htinfo = (struct wlan_ie_htinfo_cmn *) 195 util_scan_entry_htinfo(scan_params); 196 vhtop = (struct wlan_ie_vhtop *) 197 util_scan_entry_vhtop(scan_params); 198 199 if (!(htcap && htinfo)) 200 return WLAN_PHYMODE_11A; 201 202 if (htcap) 203 ht_cap = le16toh(htcap->hc_cap); 204 205 if (util_scan_entry_vhtcap(scan_params) && vhtop) { 206 switch (vhtop->vht_op_chwidth) { 207 case WLAN_VHTOP_CHWIDTH_2040: 208 if ((ht_cap & WLAN_HTCAP_C_CHWIDTH40) && 209 (htinfo->hi_extchoff == 210 WLAN_HTINFO_EXTOFFSET_ABOVE)) 211 phymode = WLAN_PHYMODE_11AC_VHT40PLUS; 212 else if ((ht_cap & WLAN_HTCAP_C_CHWIDTH40) && 213 (htinfo->hi_extchoff == 214 WLAN_HTINFO_EXTOFFSET_BELOW)) 215 phymode = WLAN_PHYMODE_11AC_VHT40MINUS; 216 else 217 phymode = WLAN_PHYMODE_11AC_VHT20; 218 break; 219 case WLAN_VHTOP_CHWIDTH_80: 220 if (WLAN_IS_REVSIG_VHT80_80(vhtop)) 221 phymode = WLAN_PHYMODE_11AC_VHT80_80; 222 else if (WLAN_IS_REVSIG_VHT160(vhtop)) 223 phymode = WLAN_PHYMODE_11AC_VHT160; 224 else 225 phymode = WLAN_PHYMODE_11AC_VHT80; 226 break; 227 case WLAN_VHTOP_CHWIDTH_160: 228 phymode = WLAN_PHYMODE_11AC_VHT160; 229 break; 230 case WLAN_VHTOP_CHWIDTH_80_80: 231 phymode = WLAN_PHYMODE_11AC_VHT80_80; 232 break; 233 default: 234 scm_err("bad channel: %d", 235 vhtop->vht_op_chwidth); 236 break; 237 } 238 } else if ((ht_cap & WLAN_HTCAP_C_CHWIDTH40) && 239 (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_ABOVE)) 240 phymode = WLAN_PHYMODE_11NA_HT40PLUS; 241 else if ((ht_cap & WLAN_HTCAP_C_CHWIDTH40) && 242 (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_BELOW)) 243 phymode = WLAN_PHYMODE_11NA_HT40MINUS; 244 else 245 phymode = WLAN_PHYMODE_11NA_HT20; 246 247 return phymode; 248 } 249 250 static enum wlan_phymode 251 util_scan_get_phymode_2g(struct scan_cache_entry *scan_params) 252 { 253 enum wlan_phymode phymode = WLAN_PHYMODE_AUTO; 254 uint16_t ht_cap = 0; 255 struct htcap_cmn_ie *htcap; 256 struct wlan_ie_htinfo_cmn *htinfo; 257 struct wlan_ie_vhtop *vhtop; 258 259 htcap = (struct htcap_cmn_ie *) 260 util_scan_entry_htcap(scan_params); 261 htinfo = (struct wlan_ie_htinfo_cmn *) 262 util_scan_entry_htinfo(scan_params); 263 vhtop = (struct wlan_ie_vhtop *) 264 util_scan_entry_vhtop(scan_params); 265 266 if (htcap) 267 ht_cap = le16toh(htcap->hc_cap); 268 269 if (htcap && htinfo) { 270 if ((ht_cap & WLAN_HTCAP_C_CHWIDTH40) && 271 (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_ABOVE)) 272 phymode = WLAN_PHYMODE_11NG_HT40PLUS; 273 else if ((ht_cap & WLAN_HTCAP_C_CHWIDTH40) && 274 (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_BELOW)) 275 phymode = WLAN_PHYMODE_11NG_HT40MINUS; 276 else 277 phymode = WLAN_PHYMODE_11NG_HT20; 278 } else if (util_scan_entry_xrates(scan_params)) { 279 /* only 11G stations will have more than 8 rates */ 280 phymode = WLAN_PHYMODE_11G; 281 } else { 282 /* Some mischievous g-only APs do not set extended rates */ 283 if (util_scan_entry_rates(scan_params)) { 284 if (util_is_pureg_rate(&scan_params->ie_list.rates[2], 285 scan_params->ie_list.rates[1])) 286 phymode = WLAN_PHYMODE_11G; 287 else 288 phymode = WLAN_PHYMODE_11B; 289 } else { 290 phymode = WLAN_PHYMODE_11B; 291 } 292 } 293 294 return phymode; 295 } 296 297 static QDF_STATUS 298 util_scan_parse_chan_switch_wrapper_ie(struct scan_cache_entry *scan_params, 299 struct ie_header *sub_ie, qdf_size_t sub_ie_len) 300 { 301 /* Walk through to check nothing is malformed */ 302 while (sub_ie_len >= sizeof(struct ie_header)) { 303 /* At least one more header is present */ 304 sub_ie_len -= sizeof(struct ie_header); 305 306 if (sub_ie->ie_len == 0) { 307 sub_ie += 1; 308 continue; 309 } 310 if (sub_ie_len < sub_ie->ie_len) { 311 scm_err("Incomplete corrupted IE:%x", 312 WLAN_ELEMID_CHAN_SWITCH_WRAP); 313 return QDF_STATUS_E_INVAL; 314 } 315 switch (sub_ie->ie_id) { 316 case WLAN_ELEMID_COUNTRY: 317 scan_params->ie_list.country = (uint8_t *)sub_ie; 318 break; 319 case WLAN_ELEMID_WIDE_BAND_CHAN_SWITCH: 320 scan_params->ie_list.widebw = (uint8_t *)sub_ie; 321 break; 322 case WLAN_ELEMID_VHT_TX_PWR_ENVLP: 323 scan_params->ie_list.txpwrenvlp = (uint8_t *)sub_ie; 324 break; 325 } 326 /* Consume sub info element */ 327 sub_ie_len -= sub_ie->ie_len; 328 /* go to next Sub IE */ 329 sub_ie = (struct ie_header *) 330 (((uint8_t *) sub_ie) + 331 sizeof(struct ie_header) + sub_ie->ie_len); 332 } 333 334 return QDF_STATUS_SUCCESS; 335 } 336 337 bool 338 util_scan_is_hidden_ssid(struct ie_ssid *ssid) 339 { 340 uint8_t i; 341 342 /* 343 * We flag this as Hidden SSID if the Length is 0 344 * of the SSID only contains 0's 345 */ 346 if (!ssid || !ssid->ssid_len) 347 return true; 348 349 for (i = 0; i < ssid->ssid_len; i++) 350 if (ssid->ssid[i] != 0) 351 return false; 352 353 /* All 0's */ 354 return true; 355 } 356 357 static QDF_STATUS 358 util_scan_parse_extn_ie(struct scan_cache_entry *scan_params, 359 struct ie_header *ie) 360 { 361 struct extn_ie_header *extn_ie = (struct extn_ie_header *) ie; 362 363 switch (extn_ie->ie_extn_id) { 364 case WLAN_EXTN_ELEMID_MAX_CHAN_SWITCH_TIME: 365 scan_params->ie_list.mcst = (uint8_t *)ie; 366 break; 367 case WLAN_EXTN_ELEMID_SRP: 368 scan_params->ie_list.srp = (uint8_t *)ie; 369 break; 370 case WLAN_EXTN_ELEMID_HECAP: 371 scan_params->ie_list.hecap = (uint8_t *)ie; 372 break; 373 case WLAN_EXTN_ELEMID_HEOP: 374 scan_params->ie_list.heop = (uint8_t *)ie; 375 break; 376 case WLAN_EXTN_ELEMID_ESP: 377 scan_params->ie_list.esp = (uint8_t *)ie; 378 break; 379 case WLAN_EXTN_ELEMID_MUEDCA: 380 scan_params->ie_list.muedca = (uint8_t *)ie; 381 break; 382 default: 383 break; 384 } 385 return QDF_STATUS_SUCCESS; 386 } 387 388 static QDF_STATUS 389 util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params, 390 struct ie_header *ie) 391 { 392 if (!scan_params->ie_list.vendor) 393 scan_params->ie_list.vendor = (uint8_t *)ie; 394 395 if (is_wpa_oui((uint8_t *)ie)) { 396 scan_params->ie_list.wpa = (uint8_t *)ie; 397 } else if (is_wps_oui((uint8_t *)ie)) { 398 scan_params->ie_list.wps = (uint8_t *)ie; 399 /* WCN IE should be a subset of WPS IE */ 400 if (is_wcn_oui((uint8_t *)ie)) 401 scan_params->ie_list.wcn = (uint8_t *)ie; 402 } else if (is_wme_param((uint8_t *)ie)) { 403 scan_params->ie_list.wmeparam = (uint8_t *)ie; 404 } else if (is_wme_info((uint8_t *)ie)) { 405 scan_params->ie_list.wmeinfo = (uint8_t *)ie; 406 } else if (is_atheros_oui((uint8_t *)ie)) { 407 scan_params->ie_list.athcaps = (uint8_t *)ie; 408 } else if (is_atheros_extcap_oui((uint8_t *)ie)) { 409 scan_params->ie_list.athextcaps = (uint8_t *)ie; 410 } else if (is_sfa_oui((uint8_t *)ie)) { 411 scan_params->ie_list.sfa = (uint8_t *)ie; 412 } else if (is_p2p_oui((uint8_t *)ie)) { 413 scan_params->ie_list.p2p = (uint8_t *)ie; 414 } else if (is_qca_son_oui((uint8_t *)ie, 415 QCA_OUI_WHC_AP_INFO_SUBTYPE)) { 416 scan_params->ie_list.sonadv = (uint8_t *)ie; 417 } else if (is_ht_cap((uint8_t *)ie)) { 418 /* we only care if there isn't already an HT IE (ANA) */ 419 if (!scan_params->ie_list.htcap) { 420 if (ie->ie_len != (WLAN_VENDOR_HT_IE_OFFSET_LEN + 421 sizeof(struct htcap_cmn_ie))) 422 return QDF_STATUS_E_INVAL; 423 scan_params->ie_list.htcap = 424 (uint8_t *)&(((struct wlan_vendor_ie_htcap *)ie)->ie); 425 } 426 } else if (is_ht_info((uint8_t *)ie)) { 427 /* we only care if there isn't already an HT IE (ANA) */ 428 if (!scan_params->ie_list.htinfo) { 429 if (ie->ie_len != WLAN_VENDOR_HT_IE_OFFSET_LEN + 430 sizeof(struct wlan_ie_htinfo_cmn)) 431 return QDF_STATUS_E_INVAL; 432 scan_params->ie_list.htinfo = 433 (uint8_t *)&(((struct wlan_vendor_ie_htinfo *) 434 ie)->hi_ie); 435 } 436 } else if (is_interop_vht((uint8_t *)ie) && 437 !(scan_params->ie_list.vhtop)) { 438 uint8_t *vendor_ie = (uint8_t *)(ie); 439 440 if (ie->ie_len < ((WLAN_VENDOR_VHTCAP_IE_OFFSET + 441 sizeof(struct wlan_ie_vhtcaps)) - 442 sizeof(struct ie_header))) 443 return QDF_STATUS_E_INVAL; 444 vendor_ie = ((uint8_t *)(ie)) + WLAN_VENDOR_VHTCAP_IE_OFFSET; 445 if (vendor_ie[1] != (sizeof(struct wlan_ie_vhtcaps)) - 446 sizeof(struct ie_header)) 447 return QDF_STATUS_E_INVAL; 448 /* location where Interop Vht Cap IE and VHT OP IE Present */ 449 scan_params->ie_list.vhtcap = (((uint8_t *)(ie)) + 450 WLAN_VENDOR_VHTCAP_IE_OFFSET); 451 if (ie->ie_len > ((WLAN_VENDOR_VHTCAP_IE_OFFSET + 452 sizeof(struct wlan_ie_vhtcaps)) - 453 sizeof(struct ie_header)) && 454 ie->ie_len < ((WLAN_VENDOR_VHTOP_IE_OFFSET + 455 sizeof(struct wlan_ie_vhtop)) - 456 sizeof(struct ie_header))) 457 return QDF_STATUS_E_INVAL; 458 vendor_ie = ((uint8_t *)(ie)) + WLAN_VENDOR_VHTOP_IE_OFFSET; 459 if (vendor_ie[1] != (sizeof(struct wlan_ie_vhtop) - 460 sizeof(struct ie_header))) 461 return QDF_STATUS_E_INVAL; 462 scan_params->ie_list.vhtop = (((uint8_t *)(ie)) + 463 WLAN_VENDOR_VHTOP_IE_OFFSET); 464 } else if (is_bwnss_oui((uint8_t *)ie)) { 465 /* 466 * Bandwidth-NSS map has sub-type & version. 467 * hence copy data just after version byte 468 */ 469 scan_params->ie_list.bwnss_map = (((uint8_t *)ie) + 8); 470 } else if (is_mbo_oce_oui((uint8_t *)ie)) { 471 scan_params->ie_list.mbo_oce = (uint8_t *)ie; 472 } else if (is_extender_oui((uint8_t *)ie)) { 473 scan_params->ie_list.extender = (uint8_t *)ie; 474 } else if (is_adaptive_11r_oui((uint8_t *)ie)) { 475 if ((ie->ie_len < OUI_LENGTH) || 476 (ie->ie_len > MAX_ADAPTIVE_11R_IE_LEN)) 477 return QDF_STATUS_E_INVAL; 478 479 scan_params->ie_list.adaptive_11r = (uint8_t *)ie + 480 sizeof(struct ie_header); 481 } 482 return QDF_STATUS_SUCCESS; 483 } 484 485 static QDF_STATUS 486 util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params) 487 { 488 struct ie_header *ie, *sub_ie; 489 uint32_t ie_len, sub_ie_len; 490 QDF_STATUS status; 491 492 ie_len = util_scan_entry_ie_len(scan_params); 493 ie = (struct ie_header *) 494 util_scan_entry_ie_data(scan_params); 495 496 while (ie_len >= sizeof(struct ie_header)) { 497 ie_len -= sizeof(struct ie_header); 498 499 if (!ie->ie_len) { 500 ie += 1; 501 continue; 502 } 503 504 if (ie_len < ie->ie_len) { 505 scm_debug("Incomplete corrupted IE:%x", 506 ie->ie_id); 507 return QDF_STATUS_E_INVAL; 508 } 509 510 switch (ie->ie_id) { 511 case WLAN_ELEMID_SSID: 512 if (ie->ie_len > (sizeof(struct ie_ssid) - 513 sizeof(struct ie_header))) 514 goto err; 515 scan_params->ie_list.ssid = (uint8_t *)ie; 516 break; 517 case WLAN_ELEMID_RATES: 518 if (ie->ie_len > WLAN_SUPPORTED_RATES_IE_MAX_LEN) 519 goto err; 520 scan_params->ie_list.rates = (uint8_t *)ie; 521 break; 522 case WLAN_ELEMID_DSPARMS: 523 if (ie->ie_len != WLAN_DS_PARAM_IE_MAX_LEN) 524 return QDF_STATUS_E_INVAL; 525 scan_params->ie_list.ds_param = (uint8_t *)ie; 526 scan_params->channel.chan_idx = 527 ((struct ds_ie *)ie)->cur_chan; 528 break; 529 case WLAN_ELEMID_TIM: 530 if (ie->ie_len < WLAN_TIM_IE_MIN_LENGTH) 531 goto err; 532 scan_params->ie_list.tim = (uint8_t *)ie; 533 scan_params->dtim_period = 534 ((struct wlan_tim_ie *)ie)->tim_period; 535 break; 536 case WLAN_ELEMID_COUNTRY: 537 if (ie->ie_len < WLAN_COUNTRY_IE_MIN_LEN) 538 goto err; 539 scan_params->ie_list.country = (uint8_t *)ie; 540 break; 541 case WLAN_ELEMID_QBSS_LOAD: 542 if (ie->ie_len != sizeof(struct qbss_load_ie) - 543 sizeof(struct ie_header)) { 544 /* 545 * Expected QBSS IE length is 5Bytes; For some 546 * old cisco AP, QBSS IE length is 4Bytes, which 547 * doesn't match with latest spec, So ignore 548 * QBSS IE in such case. 549 */ 550 break; 551 } 552 scan_params->ie_list.qbssload = (uint8_t *)ie; 553 break; 554 case WLAN_ELEMID_CHANSWITCHANN: 555 if (ie->ie_len != WLAN_CSA_IE_MAX_LEN) 556 goto err; 557 scan_params->ie_list.csa = (uint8_t *)ie; 558 break; 559 case WLAN_ELEMID_IBSSDFS: 560 if (ie->ie_len < WLAN_IBSSDFS_IE_MIN_LEN) 561 goto err; 562 scan_params->ie_list.ibssdfs = (uint8_t *)ie; 563 break; 564 case WLAN_ELEMID_QUIET: 565 if (ie->ie_len != WLAN_QUIET_IE_MAX_LEN) 566 goto err; 567 scan_params->ie_list.quiet = (uint8_t *)ie; 568 break; 569 case WLAN_ELEMID_ERP: 570 if (ie->ie_len != (sizeof(struct erp_ie) - 571 sizeof(struct ie_header))) 572 goto err; 573 scan_params->erp = ((struct erp_ie *)ie)->value; 574 break; 575 case WLAN_ELEMID_HTCAP_ANA: 576 if (ie->ie_len != sizeof(struct htcap_cmn_ie)) 577 goto err; 578 scan_params->ie_list.htcap = 579 (uint8_t *)&(((struct htcap_ie *)ie)->ie); 580 break; 581 case WLAN_ELEMID_RSN: 582 if (ie->ie_len < WLAN_RSN_IE_MIN_LEN) 583 goto err; 584 scan_params->ie_list.rsn = (uint8_t *)ie; 585 break; 586 case WLAN_ELEMID_XRATES: 587 scan_params->ie_list.xrates = (uint8_t *)ie; 588 break; 589 case WLAN_ELEMID_EXTCHANSWITCHANN: 590 if (ie->ie_len != WLAN_XCSA_IE_MAX_LEN) 591 goto err; 592 scan_params->ie_list.xcsa = (uint8_t *)ie; 593 break; 594 case WLAN_ELEMID_SECCHANOFFSET: 595 if (ie->ie_len != WLAN_SECCHANOFF_IE_MAX_LEN) 596 goto err; 597 scan_params->ie_list.secchanoff = (uint8_t *)ie; 598 break; 599 case WLAN_ELEMID_HTINFO_ANA: 600 if (ie->ie_len != sizeof(struct wlan_ie_htinfo_cmn)) 601 goto err; 602 scan_params->ie_list.htinfo = 603 (uint8_t *)&(((struct wlan_ie_htinfo *) ie)->hi_ie); 604 scan_params->channel.chan_idx = 605 ((struct wlan_ie_htinfo_cmn *) 606 (scan_params->ie_list.htinfo))->hi_ctrlchannel; 607 break; 608 case WLAN_ELEMID_WAPI: 609 if (ie->ie_len < WLAN_WAPI_IE_MIN_LEN) 610 goto err; 611 scan_params->ie_list.wapi = (uint8_t *)ie; 612 break; 613 case WLAN_ELEMID_XCAPS: 614 if (ie->ie_len > WLAN_EXTCAP_IE_MAX_LEN) 615 goto err; 616 scan_params->ie_list.extcaps = (uint8_t *)ie; 617 break; 618 case WLAN_ELEMID_VHTCAP: 619 if (ie->ie_len != (sizeof(struct wlan_ie_vhtcaps) - 620 sizeof(struct ie_header))) 621 goto err; 622 scan_params->ie_list.vhtcap = (uint8_t *)ie; 623 break; 624 case WLAN_ELEMID_VHTOP: 625 if (ie->ie_len != (sizeof(struct wlan_ie_vhtop) - 626 sizeof(struct ie_header))) 627 goto err; 628 scan_params->ie_list.vhtop = (uint8_t *)ie; 629 break; 630 case WLAN_ELEMID_OP_MODE_NOTIFY: 631 if (ie->ie_len != WLAN_OPMODE_IE_MAX_LEN) 632 goto err; 633 scan_params->ie_list.opmode = (uint8_t *)ie; 634 break; 635 case WLAN_ELEMID_MOBILITY_DOMAIN: 636 if (ie->ie_len != WLAN_MOBILITY_DOMAIN_IE_MAX_LEN) 637 goto err; 638 scan_params->ie_list.mdie = (uint8_t *)ie; 639 break; 640 case WLAN_ELEMID_VENDOR: 641 status = util_scan_parse_vendor_ie(scan_params, 642 ie); 643 if (QDF_IS_STATUS_ERROR(status)) 644 goto err_status; 645 break; 646 case WLAN_ELEMID_CHAN_SWITCH_WRAP: 647 scan_params->ie_list.cswrp = (uint8_t *)ie; 648 /* Go to next sub IE */ 649 sub_ie = (struct ie_header *) 650 (((uint8_t *)ie) + sizeof(struct ie_header)); 651 sub_ie_len = ie->ie_len; 652 status = 653 util_scan_parse_chan_switch_wrapper_ie( 654 scan_params, sub_ie, sub_ie_len); 655 if (QDF_IS_STATUS_ERROR(status)) { 656 goto err_status; 657 } 658 break; 659 case WLAN_ELEMID_FILS_INDICATION: 660 if (ie->ie_len < WLAN_FILS_INDICATION_IE_MIN_LEN) 661 goto err; 662 scan_params->ie_list.fils_indication = (uint8_t *)ie; 663 break; 664 case WLAN_ELEMID_EXTN_ELEM: 665 status = util_scan_parse_extn_ie(scan_params, ie); 666 if (QDF_IS_STATUS_ERROR(status)) 667 goto err_status; 668 break; 669 default: 670 break; 671 } 672 673 /* Consume info element */ 674 ie_len -= ie->ie_len; 675 /* Go to next IE */ 676 ie = (struct ie_header *) 677 (((uint8_t *) ie) + 678 sizeof(struct ie_header) + 679 ie->ie_len); 680 } 681 682 return QDF_STATUS_SUCCESS; 683 684 err: 685 status = QDF_STATUS_E_INVAL; 686 err_status: 687 scm_debug("failed to parse IE - id: %d, len: %d", 688 ie->ie_id, ie->ie_len); 689 690 return status; 691 } 692 693 /** 694 * util_scan_update_esp_data: update ESP params from beacon/probe response 695 * @esp_information: pointer to wlan_esp_information 696 * @scan_entry: new received entry 697 * 698 * The Estimated Service Parameters element is 699 * used by a AP to provide information to another STA which 700 * can then use the information as input to an algorithm to 701 * generate an estimate of throughput between the two STAs. 702 * The ESP Information List field contains from 1 to 4 ESP 703 * Information fields(each field 24 bits), each corresponding 704 * to an access category for which estimated service parameters 705 * information is provided. 706 * 707 * Return: None 708 */ 709 static void util_scan_update_esp_data(struct wlan_esp_ie *esp_information, 710 struct scan_cache_entry *scan_entry) 711 { 712 713 uint8_t *data; 714 int i = 0; 715 uint64_t total_elements; 716 struct wlan_esp_info *esp_info; 717 struct wlan_esp_ie *esp_ie; 718 719 esp_ie = (struct wlan_esp_ie *) 720 util_scan_entry_esp_info(scan_entry); 721 722 total_elements = esp_ie->esp_len; 723 data = (uint8_t *)esp_ie + 3; 724 do_div(total_elements, ESP_INFORMATION_LIST_LENGTH); 725 726 if (total_elements > MAX_ESP_INFORMATION_FIELD) { 727 scm_err("No of Air time fractions are greater than supported"); 728 return; 729 } 730 731 for (i = 0; i < total_elements; i++) { 732 esp_info = (struct wlan_esp_info *)data; 733 if (esp_info->access_category == ESP_AC_BK) { 734 qdf_mem_copy(&esp_information->esp_info_AC_BK, 735 data, 3); 736 data = data + ESP_INFORMATION_LIST_LENGTH; 737 continue; 738 } 739 if (esp_info->access_category == ESP_AC_BE) { 740 qdf_mem_copy(&esp_information->esp_info_AC_BE, 741 data, 3); 742 data = data + ESP_INFORMATION_LIST_LENGTH; 743 continue; 744 } 745 if (esp_info->access_category == ESP_AC_VI) { 746 qdf_mem_copy(&esp_information->esp_info_AC_VI, 747 data, 3); 748 data = data + ESP_INFORMATION_LIST_LENGTH; 749 continue; 750 } 751 if (esp_info->access_category == ESP_AC_VO) { 752 qdf_mem_copy(&esp_information->esp_info_AC_VO, 753 data, 3); 754 data = data + ESP_INFORMATION_LIST_LENGTH; 755 break; 756 } 757 } 758 } 759 760 /** 761 * util_scan_scm_update_bss_with_esp_dataa: calculate estimated air time 762 * fraction 763 * @scan_entry: new received entry 764 * 765 * This function process all Access category ESP params and provide 766 * best effort air time fraction. 767 * If best effort is not available, it will choose VI, VO and BK in sequence 768 * 769 */ 770 static void util_scan_scm_update_bss_with_esp_data( 771 struct scan_cache_entry *scan_entry) 772 { 773 uint8_t air_time_fraction = 0; 774 struct wlan_esp_ie esp_information; 775 776 if (!scan_entry->ie_list.esp) 777 return; 778 779 util_scan_update_esp_data(&esp_information, scan_entry); 780 781 /* 782 * If the ESP metric is transmitting multiple airtime fractions, then 783 * follow the sequence AC_BE, AC_VI, AC_VO, AC_BK and pick whichever is 784 * the first one available 785 */ 786 if (esp_information.esp_info_AC_BE.access_category 787 == ESP_AC_BE) 788 air_time_fraction = 789 esp_information.esp_info_AC_BE. 790 estimated_air_fraction; 791 else if (esp_information.esp_info_AC_VI.access_category 792 == ESP_AC_VI) 793 air_time_fraction = 794 esp_information.esp_info_AC_VI. 795 estimated_air_fraction; 796 else if (esp_information.esp_info_AC_VO.access_category 797 == ESP_AC_VO) 798 air_time_fraction = 799 esp_information.esp_info_AC_VO. 800 estimated_air_fraction; 801 else if (esp_information.esp_info_AC_BK.access_category 802 == ESP_AC_BK) 803 air_time_fraction = 804 esp_information.esp_info_AC_BK. 805 estimated_air_fraction; 806 scan_entry->air_time_fraction = air_time_fraction; 807 } 808 809 /** 810 * util_scan_scm_calc_nss_supported_by_ap() - finds out nss from AP 811 * @scan_entry: new received entry 812 * 813 * Return: number of nss advertised by AP 814 */ 815 static int util_scan_scm_calc_nss_supported_by_ap( 816 struct scan_cache_entry *scan_params) 817 { 818 struct htcap_cmn_ie *htcap; 819 struct wlan_ie_vhtcaps *vhtcaps; 820 uint8_t rx_mcs_map; 821 822 htcap = (struct htcap_cmn_ie *) 823 util_scan_entry_htcap(scan_params); 824 vhtcaps = (struct wlan_ie_vhtcaps *) 825 util_scan_entry_vhtcap(scan_params); 826 if (vhtcaps) { 827 rx_mcs_map = vhtcaps->rx_mcs_map; 828 if ((rx_mcs_map & 0xC0) != 0xC0) 829 return 4; 830 831 if ((rx_mcs_map & 0x30) != 0x30) 832 return 3; 833 834 if ((rx_mcs_map & 0x0C) != 0x0C) 835 return 2; 836 } else if (htcap) { 837 if (htcap->mcsset[3]) 838 return 4; 839 840 if (htcap->mcsset[2]) 841 return 3; 842 843 if (htcap->mcsset[1]) 844 return 2; 845 846 } 847 return 1; 848 } 849 850 #ifdef WLAN_DFS_CHAN_HIDDEN_SSID 851 QDF_STATUS 852 util_scan_add_hidden_ssid(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t bcnbuf) 853 { 854 struct wlan_frame_hdr *hdr; 855 struct wlan_bcn_frame *bcn; 856 struct wlan_scan_obj *scan_obj; 857 struct wlan_ssid *conf_ssid; 858 struct ie_header *ie; 859 uint32_t frame_len = qdf_nbuf_len(bcnbuf); 860 uint16_t bcn_ie_offset, ssid_ie_start_offset, ssid_ie_end_offset; 861 uint16_t tmplen, ie_length; 862 uint8_t *pbeacon, *tmp; 863 bool set_ssid_flag = false; 864 struct ie_ssid *ssid; 865 uint8_t pdev_id; 866 867 if (!pdev) { 868 scm_warn("pdev: 0x%pK is NULL", pdev); 869 return QDF_STATUS_E_NULL_VALUE; 870 } 871 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 872 scan_obj = wlan_pdev_get_scan_obj(pdev); 873 if (!scan_obj) { 874 scm_warn("null scan_obj"); 875 return QDF_STATUS_E_NULL_VALUE; 876 } 877 878 conf_ssid = &scan_obj->pdev_info[pdev_id].conf_ssid; 879 880 hdr = (struct wlan_frame_hdr *)qdf_nbuf_data(bcnbuf); 881 882 /* received bssid does not match configured bssid */ 883 if (qdf_mem_cmp(hdr->i_addr3, scan_obj->pdev_info[pdev_id].conf_bssid, 884 QDF_MAC_ADDR_SIZE) || 885 conf_ssid->length == 0) { 886 return QDF_STATUS_SUCCESS; 887 } 888 889 bcn = (struct wlan_bcn_frame *)(qdf_nbuf_data(bcnbuf) + sizeof(*hdr)); 890 pbeacon = (uint8_t *)bcn; 891 892 ie = (struct ie_header *)(pbeacon + 893 offsetof(struct wlan_bcn_frame, ie)); 894 895 bcn_ie_offset = offsetof(struct wlan_bcn_frame, ie); 896 ie_length = (uint16_t)(frame_len - sizeof(*hdr) - 897 bcn_ie_offset); 898 899 while (ie_length >= sizeof(struct ie_header)) { 900 ie_length -= sizeof(struct ie_header); 901 902 bcn_ie_offset += sizeof(struct ie_header); 903 904 if (ie_length < ie->ie_len) { 905 scm_debug("Incomplete corrupted IE:%x", ie->ie_id); 906 return QDF_STATUS_E_INVAL; 907 } 908 if (ie->ie_id == WLAN_ELEMID_SSID) { 909 if (ie->ie_len > (sizeof(struct ie_ssid) - 910 sizeof(struct ie_header))) { 911 return QDF_STATUS_E_INVAL; 912 } 913 ssid = (struct ie_ssid *)ie; 914 if (util_scan_is_hidden_ssid(ssid)) { 915 set_ssid_flag = true; 916 ssid_ie_start_offset = bcn_ie_offset - 917 sizeof(struct ie_header); 918 ssid_ie_end_offset = bcn_ie_offset + 919 ie->ie_len; 920 } 921 } 922 if (ie->ie_len == 0) { 923 ie += 1; /* next IE */ 924 continue; 925 } 926 if (ie->ie_id == WLAN_ELEMID_VENDOR && 927 is_wps_oui((uint8_t *)ie)) { 928 set_ssid_flag = false; 929 break; 930 } 931 /* Consume info element */ 932 ie_length -= ie->ie_len; 933 /* Go to next IE */ 934 ie = (struct ie_header *)(((uint8_t *)ie) + 935 sizeof(struct ie_header) + 936 ie->ie_len); 937 } 938 939 if (set_ssid_flag) { 940 /* Hidden SSID if the Length is 0 */ 941 if (!ssid->ssid_len) { 942 /* increase the taillength by length of ssid */ 943 if (qdf_nbuf_put_tail(bcnbuf, 944 conf_ssid->length) == NULL) { 945 scm_debug("No enough tailroom"); 946 return QDF_STATUS_E_NOMEM; 947 } 948 /* length of the buffer to be copied */ 949 tmplen = frame_len - 950 sizeof(*hdr) - ssid_ie_end_offset; 951 /* 952 * tmp memory to copy the beacon info 953 * after ssid ie. 954 */ 955 tmp = qdf_mem_malloc(tmplen * sizeof(u_int8_t)); 956 if (!tmp) 957 return QDF_STATUS_E_NOMEM; 958 959 /* Copy beacon data after ssid ie to tmp */ 960 qdf_nbuf_copy_bits(bcnbuf, (sizeof(*hdr) + 961 ssid_ie_end_offset), tmplen, tmp); 962 /* Add ssid length */ 963 *(pbeacon + (ssid_ie_start_offset + 1)) 964 = conf_ssid->length; 965 /* Insert the SSID string */ 966 qdf_mem_copy((pbeacon + ssid_ie_end_offset), 967 conf_ssid->ssid, conf_ssid->length); 968 /* Copy rest of the beacon data */ 969 qdf_mem_copy((pbeacon + ssid_ie_end_offset + 970 conf_ssid->length), tmp, tmplen); 971 qdf_mem_free(tmp); 972 973 /* Hidden ssid with all 0's */ 974 } else if (ssid->ssid_len == conf_ssid->length) { 975 /* Insert the SSID string */ 976 qdf_mem_copy((pbeacon + ssid_ie_start_offset + 977 sizeof(struct ie_header)), 978 conf_ssid->ssid, conf_ssid->length); 979 } else { 980 scm_debug("mismatch in hidden ssid length"); 981 return QDF_STATUS_E_INVAL; 982 } 983 } 984 return QDF_STATUS_SUCCESS; 985 } 986 #endif /* WLAN_DFS_CHAN_HIDDEN_SSID */ 987 988 #ifdef WLAN_ADAPTIVE_11R 989 /** 990 * scm_fill_adaptive_11r_cap() - Check if the AP supports adaptive 11r 991 * @scan_entry: Pointer to the scan entry 992 * 993 * Return: true if adaptive 11r is advertised else false 994 */ 995 static void scm_fill_adaptive_11r_cap(struct scan_cache_entry *scan_entry) 996 { 997 uint8_t *ie; 998 uint8_t data; 999 bool adaptive_11r; 1000 1001 ie = util_scan_entry_adaptive_11r(scan_entry); 1002 if (!ie) 1003 return; 1004 1005 data = *(ie + OUI_LENGTH); 1006 adaptive_11r = (data & 0x1) ? true : false; 1007 1008 scan_entry->adaptive_11r_ap = adaptive_11r; 1009 } 1010 #else 1011 static void scm_fill_adaptive_11r_cap(struct scan_cache_entry *scan_entry) 1012 { 1013 scan_entry->adaptive_11r_ap = false; 1014 } 1015 #endif 1016 1017 static QDF_STATUS 1018 util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, 1019 uint8_t *frame, qdf_size_t frame_len, 1020 uint32_t frm_subtype, 1021 struct mgmt_rx_event_params *rx_param, 1022 struct scan_mbssid_info *mbssid_info, 1023 qdf_list_t *scan_list) 1024 { 1025 struct wlan_frame_hdr *hdr; 1026 struct wlan_bcn_frame *bcn; 1027 QDF_STATUS status = QDF_STATUS_SUCCESS; 1028 struct ie_ssid *ssid; 1029 struct scan_cache_entry *scan_entry; 1030 struct qbss_load_ie *qbss_load; 1031 struct scan_cache_node *scan_node; 1032 uint8_t i; 1033 1034 scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry)); 1035 if (!scan_entry) { 1036 scm_err("failed to allocate memory for scan_entry"); 1037 return QDF_STATUS_E_NOMEM; 1038 } 1039 scan_entry->raw_frame.ptr = 1040 qdf_mem_malloc_atomic(frame_len); 1041 if (!scan_entry->raw_frame.ptr) { 1042 scm_err("failed to allocate memory for frame"); 1043 qdf_mem_free(scan_entry); 1044 return QDF_STATUS_E_NOMEM; 1045 } 1046 1047 bcn = (struct wlan_bcn_frame *) 1048 (frame + sizeof(*hdr)); 1049 hdr = (struct wlan_frame_hdr *)frame; 1050 1051 /* update timestamp in nanoseconds needed by kernel layers */ 1052 scan_entry->boottime_ns = qdf_get_bootbased_boottime_ns(); 1053 1054 scan_entry->frm_subtype = frm_subtype; 1055 qdf_mem_copy(scan_entry->bssid.bytes, 1056 hdr->i_addr3, QDF_MAC_ADDR_SIZE); 1057 /* Scr addr */ 1058 qdf_mem_copy(scan_entry->mac_addr.bytes, 1059 hdr->i_addr2, QDF_MAC_ADDR_SIZE); 1060 scan_entry->seq_num = 1061 (le16toh(*(uint16_t *)hdr->i_seq) >> WLAN_SEQ_SEQ_SHIFT); 1062 1063 scan_entry->rssi_raw = rx_param->rssi; 1064 scan_entry->avg_rssi = WLAN_RSSI_IN(scan_entry->rssi_raw); 1065 scan_entry->tsf_delta = rx_param->tsf_delta; 1066 1067 /* Copy per chain rssi to scan entry */ 1068 qdf_mem_copy(scan_entry->per_chain_rssi, rx_param->rssi_ctl, 1069 WLAN_MGMT_TXRX_HOST_MAX_ANTENNA); 1070 1071 if (!wlan_psoc_nif_fw_ext_cap_get(wlan_pdev_get_psoc(pdev), 1072 WLAN_SOC_CEXT_HW_DB2DBM)) { 1073 for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) { 1074 if (scan_entry->per_chain_rssi[i] != 1075 WLAN_INVALID_PER_CHAIN_SNR) 1076 scan_entry->per_chain_rssi[i] += 1077 WLAN_NOISE_FLOOR_DBM_DEFAULT; 1078 else 1079 scan_entry->per_chain_rssi[i] = 1080 WLAN_INVALID_PER_CHAIN_RSSI; 1081 } 1082 } 1083 1084 /* store jiffies */ 1085 scan_entry->rrm_parent_tsf = (uint32_t)qdf_system_ticks(); 1086 1087 scan_entry->bcn_int = le16toh(bcn->beacon_interval); 1088 1089 /* 1090 * In case if the beacon dosnt have 1091 * valid beacon interval falback to def 1092 */ 1093 if (!scan_entry->bcn_int) 1094 scan_entry->bcn_int = 100; 1095 scan_entry->cap_info.value = le16toh(bcn->capability.value); 1096 qdf_mem_copy(scan_entry->tsf_info.data, 1097 bcn->timestamp, 8); 1098 scan_entry->erp = ERP_NON_ERP_PRESENT; 1099 1100 scan_entry->scan_entry_time = 1101 qdf_mc_timer_get_system_time(); 1102 1103 scan_entry->raw_frame.len = frame_len; 1104 qdf_mem_copy(scan_entry->raw_frame.ptr, 1105 frame, frame_len); 1106 status = util_scan_populate_bcn_ie_list(scan_entry); 1107 if (QDF_IS_STATUS_ERROR(status)) { 1108 scm_debug("failed to parse beacon IE"); 1109 qdf_mem_free(scan_entry->raw_frame.ptr); 1110 qdf_mem_free(scan_entry); 1111 return QDF_STATUS_E_FAILURE; 1112 } 1113 1114 ssid = (struct ie_ssid *) 1115 scan_entry->ie_list.ssid; 1116 1117 if (ssid && (ssid->ssid_len > WLAN_SSID_MAX_LEN)) { 1118 qdf_mem_free(scan_entry->raw_frame.ptr); 1119 qdf_mem_free(scan_entry); 1120 return QDF_STATUS_E_FAILURE; 1121 } 1122 1123 if (scan_entry->ie_list.p2p) 1124 scan_entry->is_p2p = true; 1125 1126 /* If no channel info is present in beacon use meta channel */ 1127 if (!scan_entry->channel.chan_idx) { 1128 scan_entry->channel.chan_idx = 1129 rx_param->channel; 1130 } else if (rx_param->channel != 1131 scan_entry->channel.chan_idx) { 1132 if (!wlan_reg_chan_is_49ghz(pdev, scan_entry->channel.chan_idx)) 1133 scan_entry->channel_mismatch = true; 1134 } 1135 1136 if (util_scan_is_hidden_ssid(ssid)) { 1137 scan_entry->ie_list.ssid = NULL; 1138 scan_entry->is_hidden_ssid = true; 1139 } else { 1140 qdf_mem_copy(scan_entry->ssid.ssid, 1141 ssid->ssid, ssid->ssid_len); 1142 scan_entry->ssid.length = ssid->ssid_len; 1143 scan_entry->hidden_ssid_timestamp = 1144 scan_entry->scan_entry_time; 1145 } 1146 qdf_mem_copy(&scan_entry->mbssid_info, mbssid_info, 1147 sizeof(scan_entry->mbssid_info)); 1148 if (WLAN_CHAN_IS_5GHZ(scan_entry->channel.chan_idx)) 1149 scan_entry->phy_mode = util_scan_get_phymode_5g(scan_entry); 1150 else 1151 scan_entry->phy_mode = util_scan_get_phymode_2g(scan_entry); 1152 1153 scan_entry->nss = util_scan_scm_calc_nss_supported_by_ap(scan_entry); 1154 scm_fill_adaptive_11r_cap(scan_entry); 1155 1156 util_scan_scm_update_bss_with_esp_data(scan_entry); 1157 qbss_load = (struct qbss_load_ie *) 1158 util_scan_entry_qbssload(scan_entry); 1159 if (qbss_load) 1160 scan_entry->qbss_chan_load = qbss_load->qbss_chan_load; 1161 1162 scan_node = qdf_mem_malloc_atomic(sizeof(*scan_node)); 1163 if (!scan_node) { 1164 qdf_mem_free(scan_entry->raw_frame.ptr); 1165 qdf_mem_free(scan_entry); 1166 return QDF_STATUS_E_FAILURE; 1167 } 1168 1169 scan_node->entry = scan_entry; 1170 qdf_list_insert_front(scan_list, &scan_node->node); 1171 1172 return status; 1173 } 1174 1175 /** 1176 * util_scan_find_ie() - find information element 1177 * @eid: element id 1178 * @ies: pointer consisting of IEs 1179 * @len: IE length 1180 * 1181 * Return: NULL if the element ID is not found or 1182 * a pointer to the first byte of the requested 1183 * element 1184 */ 1185 static uint8_t *util_scan_find_ie(uint8_t eid, uint8_t *ies, 1186 int32_t len) 1187 { 1188 while (len >= 2 && len >= ies[1] + 2) { 1189 if (ies[0] == eid) 1190 return ies; 1191 len -= ies[1] + 2; 1192 ies += ies[1] + 2; 1193 } 1194 1195 return NULL; 1196 } 1197 1198 #ifdef WLAN_FEATURE_MBSSID 1199 static void util_gen_new_bssid(uint8_t *bssid, uint8_t max_bssid, 1200 uint8_t mbssid_index, 1201 uint8_t *new_bssid_addr) 1202 { 1203 uint64_t bssid_tmp = 0, new_bssid = 0; 1204 uint64_t lsb_n; 1205 int i; 1206 1207 for (i = 0; i < QDF_MAC_ADDR_SIZE; i++) 1208 bssid_tmp = bssid_tmp << 8 | bssid[i]; 1209 1210 lsb_n = bssid_tmp & ((1 << max_bssid) - 1); 1211 new_bssid = bssid_tmp; 1212 new_bssid &= ~((1 << max_bssid) - 1); 1213 new_bssid |= (lsb_n + mbssid_index) % (1 << max_bssid); 1214 1215 for (i = QDF_MAC_ADDR_SIZE - 1; i >= 0; i--) { 1216 new_bssid_addr[i] = new_bssid & 0xff; 1217 new_bssid = new_bssid >> 8; 1218 } 1219 } 1220 1221 static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen, 1222 uint8_t *subelement, 1223 size_t subie_len, uint8_t *new_ie) 1224 { 1225 uint8_t *pos, *tmp; 1226 const uint8_t *tmp_old, *tmp_new; 1227 uint8_t *sub_copy; 1228 1229 /* copy subelement as we need to change its content to 1230 * mark an ie after it is processed. 1231 */ 1232 sub_copy = qdf_mem_malloc(subie_len); 1233 if (!sub_copy) 1234 return 0; 1235 qdf_mem_copy(sub_copy, subelement, subie_len); 1236 1237 pos = &new_ie[0]; 1238 1239 /* new ssid */ 1240 tmp_new = util_scan_find_ie(WLAN_ELEMID_SSID, sub_copy, subie_len); 1241 if (tmp_new) { 1242 qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2); 1243 pos += (tmp_new[1] + 2); 1244 } 1245 1246 /* go through IEs in ie (skip SSID) and subelement, 1247 * merge them into new_ie 1248 */ 1249 tmp_old = util_scan_find_ie(WLAN_ELEMID_SSID, ie, ielen); 1250 tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; 1251 1252 while (tmp_old + tmp_old[1] + 2 - ie <= ielen) { 1253 if (tmp_old[0] == 0) { 1254 tmp_old++; 1255 continue; 1256 } 1257 1258 tmp = (uint8_t *)util_scan_find_ie(tmp_old[0], sub_copy, 1259 subie_len); 1260 if (!tmp) { 1261 /* ie in old ie but not in subelement */ 1262 if (tmp_old[0] != WLAN_ELEMID_MULTIPLE_BSSID) { 1263 qdf_mem_copy(pos, tmp_old, tmp_old[1] + 2); 1264 pos += tmp_old[1] + 2; 1265 } 1266 } else { 1267 /* ie in transmitting ie also in subelement, 1268 * copy from subelement and flag the ie in subelement 1269 * as copied (by setting eid field to 0xff). For 1270 * vendor ie, compare OUI + type + subType to 1271 * determine if they are the same ie. 1272 */ 1273 if (tmp_old[0] == WLAN_ELEMID_VENDOR) { 1274 if (!qdf_mem_cmp(tmp_old + 2, tmp + 2, 5)) { 1275 /* same vendor ie, copy from 1276 * subelement 1277 */ 1278 qdf_mem_copy(pos, tmp, tmp[1] + 2); 1279 pos += tmp[1] + 2; 1280 tmp[0] = 0xff; 1281 } else { 1282 qdf_mem_copy(pos, tmp_old, 1283 tmp_old[1] + 2); 1284 pos += tmp_old[1] + 2; 1285 } 1286 } else { 1287 /* copy ie from subelement into new ie */ 1288 qdf_mem_copy(pos, tmp, tmp[1] + 2); 1289 pos += tmp[1] + 2; 1290 tmp[0] = 0xff; 1291 } 1292 } 1293 1294 if (tmp_old + tmp_old[1] + 2 - ie == ielen) 1295 break; 1296 1297 tmp_old += tmp_old[1] + 2; 1298 } 1299 1300 /* go through subelement again to check if there is any ie not 1301 * copied to new ie, skip ssid, capability, bssid-index ie 1302 */ 1303 tmp_new = sub_copy; 1304 while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { 1305 if (!(tmp_new[0] == WLAN_ELEMID_NONTX_BSSID_CAP || 1306 tmp_new[0] == WLAN_ELEMID_SSID || 1307 tmp_new[0] == WLAN_ELEMID_MULTI_BSSID_IDX || 1308 tmp_new[0] == 0xff)) { 1309 qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2); 1310 pos += tmp_new[1] + 2; 1311 } 1312 if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len) 1313 break; 1314 tmp_new += tmp_new[1] + 2; 1315 } 1316 1317 qdf_mem_free(sub_copy); 1318 return pos - new_ie; 1319 } 1320 1321 static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, 1322 uint8_t *frame, qdf_size_t frame_len, 1323 uint32_t frm_subtype, 1324 struct mgmt_rx_event_params *rx_param, 1325 qdf_list_t *scan_list) 1326 { 1327 struct wlan_bcn_frame *bcn; 1328 struct wlan_frame_hdr *hdr; 1329 struct scan_mbssid_info mbssid_info; 1330 QDF_STATUS status; 1331 uint8_t *pos, *subelement, *mbssid_end_pos; 1332 uint8_t *tmp, *mbssid_index_ie; 1333 uint32_t subie_len, new_ie_len; 1334 uint8_t new_bssid[QDF_MAC_ADDR_SIZE], bssid[QDF_MAC_ADDR_SIZE]; 1335 uint8_t *new_ie; 1336 uint8_t *ie, *new_frame = NULL; 1337 uint64_t ielen, new_frame_len; 1338 1339 hdr = (struct wlan_frame_hdr *)frame; 1340 bcn = (struct wlan_bcn_frame *)(frame + sizeof(struct wlan_frame_hdr)); 1341 ie = (uint8_t *)&bcn->ie; 1342 ielen = (uint16_t)(frame_len - 1343 sizeof(struct wlan_frame_hdr) - 1344 offsetof(struct wlan_bcn_frame, ie)); 1345 qdf_mem_copy(bssid, hdr->i_addr3, QDF_MAC_ADDR_SIZE); 1346 1347 if (!util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, ie, ielen)) 1348 return QDF_STATUS_E_FAILURE; 1349 1350 pos = ie; 1351 1352 new_ie = qdf_mem_malloc(MAX_IE_LEN); 1353 if (!new_ie) 1354 return QDF_STATUS_E_NOMEM; 1355 1356 while (pos < ie + ielen + 2) { 1357 tmp = util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, pos, 1358 ielen - (pos - ie)); 1359 if (!tmp) 1360 break; 1361 1362 mbssid_info.profile_count = 1 << tmp[2]; 1363 mbssid_end_pos = tmp + tmp[1] + 2; 1364 /* Skip Element ID, Len, MaxBSSID Indicator */ 1365 if (tmp[1] < 4) 1366 break; 1367 for (subelement = tmp + 3; subelement < mbssid_end_pos - 1; 1368 subelement += 2 + subelement[1]) { 1369 subie_len = subelement[1]; 1370 if (mbssid_end_pos - subelement < 2 + subie_len) 1371 break; 1372 if (subelement[0] != 0 || subelement[1] < 4) { 1373 /* not a valid BSS profile */ 1374 continue; 1375 } 1376 1377 if (subelement[2] != WLAN_ELEMID_NONTX_BSSID_CAP || 1378 subelement[3] != 2) { 1379 /* The first element within the Nontransmitted 1380 * BSSID Profile is not the Nontransmitted 1381 * BSSID Capability element. 1382 */ 1383 continue; 1384 } 1385 1386 /* found a Nontransmitted BSSID Profile */ 1387 mbssid_index_ie = 1388 util_scan_find_ie(WLAN_ELEMID_MULTI_BSSID_IDX, 1389 subelement + 2, subie_len); 1390 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || 1391 mbssid_index_ie[2] == 0) { 1392 /* No valid Multiple BSSID-Index element */ 1393 continue; 1394 } 1395 qdf_mem_copy(&mbssid_info.trans_bssid, bssid, 1396 QDF_MAC_ADDR_SIZE); 1397 mbssid_info.profile_num = mbssid_index_ie[2]; 1398 util_gen_new_bssid(bssid, tmp[2], mbssid_index_ie[2], 1399 new_bssid); 1400 new_ie_len = util_gen_new_ie(ie, ielen, subelement + 2, 1401 subie_len, new_ie); 1402 if (!new_ie_len) 1403 continue; 1404 1405 new_frame_len = frame_len - ielen + new_ie_len; 1406 new_frame = qdf_mem_malloc(new_frame_len); 1407 if (!new_frame) { 1408 qdf_mem_free(new_ie); 1409 return QDF_STATUS_E_NOMEM; 1410 } 1411 1412 /* 1413 * Copy the header(24byte), timestamp(8 byte), 1414 * beaconinterval(2byte) and capability(2byte) 1415 */ 1416 qdf_mem_copy(new_frame, frame, 36); 1417 /* Copy the new ie generated from MBSSID profile*/ 1418 hdr = (struct wlan_frame_hdr *)new_frame; 1419 qdf_mem_copy(hdr->i_addr2, new_bssid, 1420 QDF_MAC_ADDR_SIZE); 1421 qdf_mem_copy(hdr->i_addr3, new_bssid, 1422 QDF_MAC_ADDR_SIZE); 1423 /* Copy the new ie generated from MBSSID profile*/ 1424 qdf_mem_copy(new_frame + 1425 offsetof(struct wlan_bcn_frame, ie) + 1426 sizeof(struct wlan_frame_hdr), 1427 new_ie, new_ie_len); 1428 status = util_scan_gen_scan_entry(pdev, new_frame, 1429 new_frame_len, 1430 frm_subtype, 1431 rx_param, 1432 &mbssid_info, 1433 scan_list); 1434 if (QDF_IS_STATUS_ERROR(status)) { 1435 qdf_mem_free(new_frame); 1436 scm_err("failed to generate a scan entry"); 1437 break; 1438 } 1439 /* scan entry makes its own copy so free the frame*/ 1440 qdf_mem_free(new_frame); 1441 } 1442 1443 pos = mbssid_end_pos; 1444 } 1445 qdf_mem_free(new_ie); 1446 1447 return QDF_STATUS_SUCCESS; 1448 } 1449 #else 1450 static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, 1451 uint8_t *frame, qdf_size_t frame_len, 1452 uint32_t frm_subtype, 1453 struct mgmt_rx_event_params *rx_param, 1454 qdf_list_t *scan_list) 1455 { 1456 return QDF_STATUS_SUCCESS; 1457 } 1458 #endif 1459 1460 static QDF_STATUS 1461 util_scan_parse_beacon_frame(struct wlan_objmgr_pdev *pdev, 1462 uint8_t *frame, 1463 qdf_size_t frame_len, 1464 uint32_t frm_subtype, 1465 struct mgmt_rx_event_params *rx_param, 1466 qdf_list_t *scan_list) 1467 { 1468 struct wlan_bcn_frame *bcn; 1469 struct wlan_frame_hdr *hdr; 1470 uint8_t *mbssid_ie = NULL; 1471 uint32_t ie_len = 0; 1472 QDF_STATUS status; 1473 struct scan_mbssid_info mbssid_info = { 0 }; 1474 1475 hdr = (struct wlan_frame_hdr *)frame; 1476 bcn = (struct wlan_bcn_frame *) 1477 (frame + sizeof(struct wlan_frame_hdr)); 1478 ie_len = (uint16_t)(frame_len - 1479 sizeof(struct wlan_frame_hdr) - 1480 offsetof(struct wlan_bcn_frame, ie)); 1481 1482 mbssid_ie = util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, 1483 (uint8_t *)&bcn->ie, ie_len); 1484 if (mbssid_ie) { 1485 qdf_mem_copy(&mbssid_info.trans_bssid, 1486 hdr->i_addr3, QDF_MAC_ADDR_SIZE); 1487 mbssid_info.profile_count = 1 << mbssid_ie[2]; 1488 } 1489 1490 status = util_scan_gen_scan_entry(pdev, frame, frame_len, 1491 frm_subtype, rx_param, 1492 &mbssid_info, 1493 scan_list); 1494 1495 /* 1496 * IF MBSSID IE is present in the beacon then 1497 * scan component will create a new entry for 1498 * each BSSID found in the MBSSID 1499 */ 1500 if (mbssid_ie) 1501 status = util_scan_parse_mbssid(pdev, frame, frame_len, 1502 frm_subtype, rx_param, 1503 scan_list); 1504 1505 if (QDF_IS_STATUS_ERROR(status)) 1506 scm_debug_rl("Failed to create a scan entry"); 1507 1508 return status; 1509 } 1510 1511 qdf_list_t * 1512 util_scan_unpack_beacon_frame(struct wlan_objmgr_pdev *pdev, uint8_t *frame, 1513 qdf_size_t frame_len, uint32_t frm_subtype, 1514 struct mgmt_rx_event_params *rx_param) 1515 { 1516 qdf_list_t *scan_list; 1517 QDF_STATUS status; 1518 1519 scan_list = qdf_mem_malloc_atomic(sizeof(*scan_list)); 1520 if (!scan_list) { 1521 scm_err("failed to allocate scan_list"); 1522 return NULL; 1523 } 1524 qdf_list_create(scan_list, MAX_SCAN_CACHE_SIZE); 1525 1526 status = util_scan_parse_beacon_frame(pdev, frame, frame_len, 1527 frm_subtype, rx_param, 1528 scan_list); 1529 if (QDF_IS_STATUS_ERROR(status)) { 1530 ucfg_scan_purge_results(scan_list); 1531 return NULL; 1532 } 1533 1534 return scan_list; 1535 } 1536 1537 QDF_STATUS 1538 util_scan_entry_update_mlme_info(struct wlan_objmgr_pdev *pdev, 1539 struct scan_cache_entry *scan_entry) 1540 { 1541 1542 if (!pdev || !scan_entry) { 1543 scm_err("pdev 0x%pK, scan_entry: 0x%pK", pdev, scan_entry); 1544 return QDF_STATUS_E_INVAL; 1545 } 1546 1547 return scm_update_scan_mlme_info(pdev, scan_entry); 1548 } 1549 1550 bool util_is_scan_completed(struct scan_event *event, bool *success) 1551 { 1552 if ((event->type == SCAN_EVENT_TYPE_COMPLETED) || 1553 (event->type == SCAN_EVENT_TYPE_DEQUEUED) || 1554 (event->type == SCAN_EVENT_TYPE_START_FAILED)) { 1555 if ((event->type == SCAN_EVENT_TYPE_COMPLETED) && 1556 (event->reason == SCAN_REASON_COMPLETED)) 1557 *success = true; 1558 else 1559 *success = false; 1560 1561 return true; 1562 } 1563 1564 *success = false; 1565 return false; 1566 } 1567 1568