1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: This file contains definition for mandatory legacy API 19 */ 20 21 #include "qdf_str.h" 22 #include "wlan_utility.h" 23 #include <wlan_cmn.h> 24 #include "wlan_osif_priv.h" 25 #include <net/cfg80211.h> 26 #include <qdf_module.h> 27 #include <wlan_vdev_mlme_api.h> 28 #include "cfg_ucfg_api.h" 29 #include <wlan_serialization_api.h> 30 31 uint32_t wlan_chan_to_freq(uint8_t chan) 32 { 33 if (chan == 0 ) 34 return 0; 35 36 if (chan < WLAN_24_GHZ_CHANNEL_14) 37 return WLAN_24_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ; 38 else if (chan == WLAN_24_GHZ_CHANNEL_14) 39 return WLAN_CHAN_14_FREQ; 40 else if (chan < WLAN_24_GHZ_CHANNEL_27) 41 /* ch 15 - ch 26 */ 42 return WLAN_CHAN_15_FREQ + 43 (chan - WLAN_24_GHZ_CHANNEL_15) * WLAN_CHAN_SPACING_20MHZ; 44 else if (chan == WLAN_5_GHZ_CHANNEL_170) 45 return WLAN_CHAN_170_FREQ; 46 else 47 return WLAN_5_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ; 48 } 49 50 uint8_t wlan_freq_to_chan(uint32_t freq) 51 { 52 uint8_t chan; 53 54 if (freq == 0) 55 return 0; 56 57 if (freq > WLAN_24_GHZ_BASE_FREQ && freq < WLAN_CHAN_14_FREQ) 58 chan = ((freq - WLAN_24_GHZ_BASE_FREQ) / 59 WLAN_CHAN_SPACING_5MHZ); 60 else if (freq == WLAN_CHAN_14_FREQ) 61 chan = WLAN_24_GHZ_CHANNEL_14; 62 else if ((freq > WLAN_24_GHZ_BASE_FREQ) && 63 (freq < WLAN_5_GHZ_BASE_FREQ)) 64 chan = (((freq - WLAN_CHAN_15_FREQ) / 65 WLAN_CHAN_SPACING_20MHZ) + 66 WLAN_24_GHZ_CHANNEL_15); 67 else 68 chan = (freq - WLAN_5_GHZ_BASE_FREQ) / 69 WLAN_CHAN_SPACING_5MHZ; 70 71 return chan; 72 } 73 74 void 75 wlan_get_320_center_freq(qdf_freq_t freq, 76 qdf_freq_t *center_freq1, 77 qdf_freq_t *center_freq2) 78 { 79 *center_freq1 = 0; 80 *center_freq2 = 0; 81 82 if ((freq >= 5500) && (freq <= 5800)) { 83 *center_freq1 = 5650; 84 } else if ((freq >= 5955) && (freq <= 6095)) { 85 *center_freq1 = 6105; 86 } else if ((freq >= 6115) && (freq <= 6255)) { 87 *center_freq1 = 6105; 88 *center_freq2 = 6205; 89 } else if ((freq >= 6275) && (freq <= 6415)) { 90 *center_freq1 = 6265; 91 *center_freq2 = 6425; 92 } else if ((freq >= 6435) && (freq <= 6575)) { 93 *center_freq1 = 6425; 94 *center_freq2 = 6585; 95 } else if ((freq >= 6595) && (freq <= 6735)) { 96 *center_freq1 = 6585; 97 *center_freq2 = 6745; 98 } else if ((freq >= 6755) && (freq <= 6895)) { 99 *center_freq1 = 6745; 100 *center_freq2 = 6905; 101 } else if ((freq >= 6915) && (freq <= 7055)) { 102 *center_freq1 = 6905; 103 } 104 } 105 106 bool wlan_is_ie_valid(const uint8_t *ie, size_t ie_len) 107 { 108 uint8_t elen; 109 110 while (ie_len) { 111 if (ie_len < 2) 112 return false; 113 114 elen = ie[1]; 115 ie_len -= 2; 116 ie += 2; 117 if (elen > ie_len) 118 return false; 119 120 ie_len -= elen; 121 ie += elen; 122 } 123 124 return true; 125 } 126 127 static const uint8_t *wlan_get_ie_ptr_from_eid_n_oui(uint8_t eid, 128 const uint8_t *oui, 129 uint8_t oui_size, 130 const uint8_t *ie, 131 uint16_t ie_len) 132 { 133 int32_t left = ie_len; 134 const uint8_t *ptr = ie; 135 uint8_t elem_id, elem_len; 136 137 while (left >= 2) { 138 elem_id = ptr[0]; 139 elem_len = ptr[1]; 140 left -= 2; 141 142 if (elem_len > left) 143 return NULL; 144 145 if (eid == elem_id) { 146 /* if oui is not provide eid match is enough */ 147 if (!oui) 148 return ptr; 149 150 /* 151 * if oui is provided and oui_size is more than left 152 * bytes, then we cannot have match 153 */ 154 if (oui_size > left) 155 return NULL; 156 157 if (qdf_mem_cmp(&ptr[2], oui, oui_size) == 0) 158 return ptr; 159 } 160 161 left -= elem_len; 162 ptr += (elem_len + 2); 163 } 164 165 return NULL; 166 } 167 168 const uint8_t *wlan_get_ie_ptr_from_eid(uint8_t eid, 169 const uint8_t *ie, 170 int ie_len) 171 { 172 return wlan_get_ie_ptr_from_eid_n_oui(eid, NULL, 0, ie, ie_len); 173 } 174 175 const uint8_t *wlan_get_vendor_ie_ptr_from_oui(const uint8_t *oui, 176 uint8_t oui_size, 177 const uint8_t *ie, 178 uint16_t ie_len) 179 { 180 return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_VENDOR, 181 oui, oui_size, ie, ie_len); 182 } 183 184 const uint8_t *wlan_get_ext_ie_ptr_from_ext_id(const uint8_t *oui, 185 uint8_t oui_size, 186 const uint8_t *ie, 187 uint16_t ie_len) 188 { 189 return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_EXT, 190 oui, oui_size, ie, ie_len); 191 } 192 193 bool wlan_is_emulation_platform(uint32_t phy_version) 194 { 195 if ((phy_version == 0xABC0) || (phy_version == 0xABC1) || 196 (phy_version == 0xABC2) || (phy_version == 0xABC3) || 197 (phy_version == 0xFFFF) || (phy_version == 0xABCD)) 198 return true; 199 200 return false; 201 } 202 203 uint32_t wlan_get_pdev_id_from_vdev_id(struct wlan_objmgr_psoc *psoc, 204 uint8_t vdev_id, 205 wlan_objmgr_ref_dbgid dbg_id) 206 { 207 struct wlan_objmgr_vdev *vdev; 208 struct wlan_objmgr_pdev *pdev = NULL; 209 uint32_t pdev_id = WLAN_INVALID_PDEV_ID; 210 211 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 212 vdev_id, dbg_id); 213 214 if (vdev) { 215 pdev = wlan_vdev_get_pdev(vdev); 216 if (pdev) 217 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 218 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 219 } 220 221 return pdev_id; 222 } 223 qdf_export_symbol(wlan_get_pdev_id_from_vdev_id); 224 225 static void wlan_vdev_active(struct wlan_objmgr_pdev *pdev, void *object, 226 void *arg) 227 { 228 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 229 uint8_t *flag = (uint8_t *)arg; 230 231 wlan_vdev_obj_lock(vdev); 232 if (wlan_vdev_mlme_is_active(vdev) == QDF_STATUS_SUCCESS) 233 *flag = 1; 234 235 wlan_vdev_obj_unlock(vdev); 236 } 237 238 QDF_STATUS wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev) 239 { 240 return wlan_vdev_allow_connect_n_tx(vdev); 241 } 242 qdf_export_symbol(wlan_vdev_is_up); 243 244 QDF_STATUS wlan_util_is_vdev_active(struct wlan_objmgr_pdev *pdev, 245 wlan_objmgr_ref_dbgid dbg_id) 246 { 247 uint8_t flag = 0; 248 249 if (!pdev) 250 return QDF_STATUS_E_INVAL; 251 252 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, wlan_vdev_active, 253 &flag, 0, dbg_id); 254 255 if (flag == 1) 256 return QDF_STATUS_SUCCESS; 257 258 return QDF_STATUS_E_INVAL; 259 } 260 261 qdf_export_symbol(wlan_util_is_vdev_active); 262 263 void wlan_util_change_map_index(unsigned long *map, uint8_t id, uint8_t set) 264 { 265 if (set) 266 qdf_set_bit(id, map); 267 else 268 qdf_clear_bit(id, map); 269 } 270 271 bool wlan_util_map_index_is_set(unsigned long *map, uint8_t id) 272 { 273 return qdf_test_bit(id, map); 274 } 275 276 bool wlan_util_map_is_any_index_set(unsigned long *map, unsigned long nbytes) 277 { 278 return !qdf_bitmap_empty(map, QDF_CHAR_BIT * nbytes); 279 } 280 281 static void wlan_vdev_chan_change_pending(struct wlan_objmgr_pdev *pdev, 282 void *object, void *arg) 283 { 284 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 285 unsigned long *vdev_id_map = (unsigned long *)arg; 286 uint8_t id = 0; 287 struct wlan_objmgr_psoc *psoc; 288 289 psoc = wlan_pdev_get_psoc(pdev); 290 if (!psoc) 291 return; 292 293 wlan_vdev_obj_lock(vdev); 294 if (wlan_vdev_chan_config_valid(vdev) == QDF_STATUS_SUCCESS) { 295 id = wlan_vdev_get_id(vdev); 296 /* Invalid vdev id */ 297 if (id >= wlan_psoc_get_max_vdev_count(psoc)) { 298 wlan_vdev_obj_unlock(vdev); 299 return; 300 } 301 302 wlan_util_change_map_index(vdev_id_map, id, 1); 303 } 304 305 wlan_vdev_obj_unlock(vdev); 306 } 307 308 QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev, 309 unsigned long *vdev_id_map, 310 wlan_objmgr_ref_dbgid dbg_id) 311 { 312 if (!pdev) 313 return QDF_STATUS_E_INVAL; 314 315 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 316 wlan_vdev_chan_change_pending, 317 vdev_id_map, 0, dbg_id); 318 319 return QDF_STATUS_SUCCESS; 320 } 321 322 static void wlan_vdev_down_pending(struct wlan_objmgr_pdev *pdev, 323 void *object, void *arg) 324 { 325 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 326 unsigned long *vdev_id_map = (unsigned long *)arg; 327 uint8_t id = 0; 328 struct wlan_objmgr_psoc *psoc; 329 enum wlan_serialization_cmd_type cmd_type; 330 331 psoc = wlan_pdev_get_psoc(pdev); 332 if (!psoc) 333 return; 334 335 cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev); 336 wlan_vdev_obj_lock(vdev); 337 if ((wlan_vdev_mlme_is_init_state(vdev) != QDF_STATUS_SUCCESS) || 338 (cmd_type == WLAN_SER_CMD_VDEV_START_BSS)) { 339 id = wlan_vdev_get_id(vdev); 340 /* Invalid vdev id */ 341 if (id >= wlan_psoc_get_max_vdev_count(psoc)) { 342 wlan_vdev_obj_unlock(vdev); 343 return; 344 } 345 wlan_util_change_map_index(vdev_id_map, id, 1); 346 } 347 348 wlan_vdev_obj_unlock(vdev); 349 } 350 351 static void wlan_vdev_ap_down_pending(struct wlan_objmgr_pdev *pdev, 352 void *object, void *arg) 353 { 354 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 355 unsigned long *vdev_id_map = (unsigned long *)arg; 356 uint8_t id = 0; 357 struct wlan_objmgr_psoc *psoc; 358 enum wlan_serialization_cmd_type cmd_type; 359 360 psoc = wlan_pdev_get_psoc(pdev); 361 if (!psoc) 362 return; 363 364 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE) 365 return; 366 367 cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev); 368 wlan_vdev_obj_lock(vdev); 369 if ((wlan_vdev_mlme_is_init_state(vdev) != QDF_STATUS_SUCCESS) || 370 (cmd_type == WLAN_SER_CMD_VDEV_START_BSS)) { 371 id = wlan_vdev_get_id(vdev); 372 /* Invalid vdev id */ 373 if (id >= wlan_psoc_get_max_vdev_count(psoc)) { 374 wlan_vdev_obj_unlock(vdev); 375 return; 376 } 377 wlan_util_change_map_index(vdev_id_map, id, 1); 378 } 379 380 wlan_vdev_obj_unlock(vdev); 381 } 382 383 QDF_STATUS wlan_pdev_chan_change_pending_vdevs_down( 384 struct wlan_objmgr_pdev *pdev, 385 unsigned long *vdev_id_map, 386 wlan_objmgr_ref_dbgid dbg_id) 387 { 388 if (!pdev) 389 return QDF_STATUS_E_INVAL; 390 391 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 392 wlan_vdev_down_pending, 393 vdev_id_map, 0, dbg_id); 394 395 return QDF_STATUS_SUCCESS; 396 } 397 398 QDF_STATUS wlan_pdev_chan_change_pending_ap_vdevs_down( 399 struct wlan_objmgr_pdev *pdev, 400 unsigned long *vdev_id_map, 401 wlan_objmgr_ref_dbgid dbg_id) 402 { 403 if (!pdev) 404 return QDF_STATUS_E_INVAL; 405 406 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 407 wlan_vdev_ap_down_pending, 408 vdev_id_map, 0, dbg_id); 409 410 return QDF_STATUS_SUCCESS; 411 } 412 413 #ifdef WLAN_FEATURE_11BE 414 static inline bool 415 wlan_chan_puncture_eq(struct wlan_channel *chan1, struct wlan_channel *chan2) 416 { 417 if (chan1->puncture_bitmap == chan2->puncture_bitmap) 418 return true; 419 420 return false; 421 } 422 #else 423 static inline bool 424 wlan_chan_puncture_eq(struct wlan_channel *chan1, struct wlan_channel *chan2) 425 { 426 return true; 427 } 428 #endif /* WLAN_FEATURE_11BE */ 429 430 QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2) 431 { 432 if ((chan1->ch_ieee == chan2->ch_ieee) && 433 (chan1->ch_freq_seg2 == chan2->ch_freq_seg2) && 434 wlan_chan_puncture_eq(chan1, chan2)) 435 return QDF_STATUS_SUCCESS; 436 437 return QDF_STATUS_E_FAILURE; 438 } 439 440 void wlan_chan_copy(struct wlan_channel *tgt, struct wlan_channel *src) 441 { 442 qdf_mem_copy(tgt, src, sizeof(struct wlan_channel)); 443 } 444 445 struct wlan_channel *wlan_vdev_get_active_channel(struct wlan_objmgr_vdev *vdev) 446 { 447 struct wlan_channel *comp_vdev_chan = NULL; 448 449 if (wlan_vdev_chan_config_valid(vdev) == QDF_STATUS_SUCCESS) { 450 /* compare with BSS channel, when vdev is active, since desired 451 * channel gets update, if channel is triggered in another path 452 */ 453 if (wlan_vdev_mlme_is_active(vdev) == QDF_STATUS_SUCCESS) 454 comp_vdev_chan = wlan_vdev_mlme_get_bss_chan(vdev); 455 else 456 comp_vdev_chan = wlan_vdev_mlme_get_des_chan(vdev); 457 } 458 459 return comp_vdev_chan; 460 } 461 462 /** 463 * struct wlan_check_bssid_context - bssid check context 464 * @bssid: bssid to be checked 465 * @connected: connected by vdev or not 466 * @vdev_id: vdev id of connected vdev 467 */ 468 struct wlan_check_bssid_context { 469 struct qdf_mac_addr bssid; 470 bool connected; 471 uint8_t vdev_id; 472 }; 473 474 /** 475 * wlan_get_connected_vdev_handler() - check vdev connected on bssid 476 * @psoc: psoc object 477 * @obj: vdev object 478 * @args: handler context 479 * 480 * This function will check whether vdev is connected on bssid or not and 481 * update the result to handler context accordingly. 482 * 483 * Return: void 484 */ 485 static void wlan_get_connected_vdev_handler(struct wlan_objmgr_psoc *psoc, 486 void *obj, void *args) 487 { 488 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj; 489 struct wlan_check_bssid_context *context = 490 (struct wlan_check_bssid_context *)args; 491 struct qdf_mac_addr bss_peer_mac; 492 enum QDF_OPMODE op_mode; 493 494 if (context->connected) 495 return; 496 op_mode = wlan_vdev_mlme_get_opmode(vdev); 497 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) 498 return; 499 if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) 500 return; 501 if (wlan_vdev_get_bss_peer_mac(vdev, &bss_peer_mac) != 502 QDF_STATUS_SUCCESS) 503 return; 504 if (qdf_is_macaddr_equal(&bss_peer_mac, &context->bssid)) { 505 context->connected = true; 506 context->vdev_id = wlan_vdev_get_id(vdev); 507 } 508 } 509 510 bool wlan_get_connected_vdev_by_bssid(struct wlan_objmgr_pdev *pdev, 511 uint8_t *bssid, uint8_t *vdev_id) 512 { 513 struct wlan_objmgr_psoc *psoc; 514 struct wlan_check_bssid_context context; 515 516 psoc = wlan_pdev_get_psoc(pdev); 517 qdf_mem_zero(&context, sizeof(struct wlan_check_bssid_context)); 518 qdf_mem_copy(context.bssid.bytes, bssid, QDF_MAC_ADDR_SIZE); 519 wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, 520 wlan_get_connected_vdev_handler, 521 &context, true, WLAN_OSIF_SCAN_ID); 522 if (context.connected) 523 *vdev_id = context.vdev_id; 524 525 return context.connected; 526 } 527 528 qdf_export_symbol(wlan_get_connected_vdev_by_bssid); 529 530 static void wlan_pdev_chan_match(struct wlan_objmgr_pdev *pdev, void *object, 531 void *arg) 532 { 533 struct wlan_objmgr_vdev *comp_vdev = (struct wlan_objmgr_vdev *)object; 534 struct wlan_vdev_ch_check_filter *ch_filter = arg; 535 struct wlan_channel vdev_chan, *chan; 536 struct wlan_channel *iter_vdev_chan; 537 538 if (ch_filter->flag) 539 return; 540 541 if (comp_vdev == ch_filter->vdev) 542 return; 543 544 wlan_vdev_obj_lock(comp_vdev); 545 chan = wlan_vdev_get_active_channel(comp_vdev); 546 if (!chan) { 547 wlan_vdev_obj_unlock(comp_vdev); 548 return; 549 } 550 wlan_chan_copy(&vdev_chan, chan); 551 wlan_vdev_obj_unlock(comp_vdev); 552 553 wlan_vdev_obj_lock(ch_filter->vdev); 554 iter_vdev_chan = wlan_vdev_mlme_get_des_chan(ch_filter->vdev); 555 if (wlan_chan_eq(&vdev_chan, iter_vdev_chan) 556 != QDF_STATUS_SUCCESS) { 557 ch_filter->flag = 1; 558 qdf_nofl_err("==> iter vdev id: %d: ieee %d, mode %d", 559 wlan_vdev_get_id(comp_vdev), 560 vdev_chan.ch_ieee, 561 vdev_chan.ch_phymode); 562 qdf_nofl_err("fl %016llx, fl-ext %08x, s1 %d, s2 %d ", 563 vdev_chan.ch_flags, vdev_chan.ch_flagext, 564 vdev_chan.ch_freq_seg1, 565 vdev_chan.ch_freq_seg2); 566 qdf_nofl_err("==> base vdev id: %d: ieee %d mode %d", 567 wlan_vdev_get_id(ch_filter->vdev), 568 iter_vdev_chan->ch_ieee, 569 iter_vdev_chan->ch_phymode); 570 qdf_nofl_err("fl %016llx, fl-ext %08x s1 %d, s2 %d", 571 iter_vdev_chan->ch_flags, 572 iter_vdev_chan->ch_flagext, 573 iter_vdev_chan->ch_freq_seg1, 574 iter_vdev_chan->ch_freq_seg2); 575 } 576 wlan_vdev_obj_unlock(ch_filter->vdev); 577 } 578 579 QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev, 580 struct wlan_objmgr_vdev *vdev, 581 wlan_objmgr_ref_dbgid dbg_id) 582 { 583 struct wlan_vdev_ch_check_filter ch_filter; 584 585 if (!pdev) 586 return QDF_STATUS_E_INVAL; 587 588 if (wlan_pdev_nif_feat_cap_get(pdev, WLAN_PDEV_F_CHAN_CONCURRENCY)) 589 return QDF_STATUS_SUCCESS; 590 591 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == QDF_STATUS_SUCCESS) { 592 ch_filter.flag = 0; 593 ch_filter.vdev = vdev; 594 595 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 596 wlan_pdev_chan_match, 597 &ch_filter, 0, dbg_id); 598 599 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 600 601 if (ch_filter.flag == 0) 602 return QDF_STATUS_SUCCESS; 603 } 604 605 return QDF_STATUS_E_FAILURE; 606 } 607 608 static void wlan_vdev_restart_progress(struct wlan_objmgr_pdev *pdev, 609 void *object, void *arg) 610 { 611 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 612 uint8_t *flag = (uint8_t *)arg; 613 614 wlan_vdev_obj_lock(vdev); 615 if (wlan_vdev_is_restart_progress(vdev) == QDF_STATUS_SUCCESS) 616 *flag = 1; 617 618 wlan_vdev_obj_unlock(vdev); 619 } 620 621 QDF_STATUS wlan_util_is_pdev_restart_progress(struct wlan_objmgr_pdev *pdev, 622 wlan_objmgr_ref_dbgid dbg_id) 623 { 624 uint8_t flag = 0; 625 626 if (!pdev) 627 return QDF_STATUS_E_INVAL; 628 629 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 630 wlan_vdev_restart_progress, 631 &flag, 0, dbg_id); 632 633 if (flag == 1) 634 return QDF_STATUS_SUCCESS; 635 636 return QDF_STATUS_E_INVAL; 637 } 638 639 static void wlan_vdev_scan_allowed(struct wlan_objmgr_pdev *pdev, void *object, 640 void *arg) 641 { 642 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 643 uint8_t *flag = (uint8_t *)arg; 644 645 wlan_vdev_obj_lock(vdev); 646 if (wlan_vdev_mlme_is_scan_allowed(vdev) != QDF_STATUS_SUCCESS) 647 *flag = 1; 648 649 wlan_vdev_obj_unlock(vdev); 650 } 651 652 QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev, 653 wlan_objmgr_ref_dbgid dbg_id) 654 { 655 uint8_t flag = 0; 656 657 if (!pdev) 658 return QDF_STATUS_E_INVAL; 659 660 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 661 wlan_vdev_scan_allowed, 662 &flag, 0, dbg_id); 663 664 if (flag == 1) 665 return QDF_STATUS_E_FAILURE; 666 667 return QDF_STATUS_SUCCESS; 668 } 669 670 void 671 wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr, 672 int8_t *rssi) 673 { 674 uint32_t snr; 675 676 if (db2dbm_enabled) { 677 if (TGT_IS_VALID_RSSI(bcn_snr)) 678 *rssi = bcn_snr; 679 else if (TGT_IS_VALID_RSSI(dat_snr)) 680 *rssi = dat_snr; 681 else 682 *rssi = TGT_NOISE_FLOOR_DBM; 683 } else { 684 if (TGT_IS_VALID_SNR(bcn_snr)) 685 snr = bcn_snr; 686 else if (TGT_IS_VALID_SNR(dat_snr)) 687 snr = dat_snr; 688 else 689 snr = TGT_INVALID_SNR; 690 691 /* Get the absolute rssi value from the current rssi value */ 692 *rssi = snr + TGT_NOISE_FLOOR_DBM; 693 } 694 } 695 696 /** 697 * wlan_util_get_mode_specific_peer_count - This api gives vdev mode specific 698 * peer count` 699 * @pdev: PDEV object 700 * @object: vdev object 701 * @arg: argument passed by caller 702 * 703 * Return: void 704 */ 705 static void 706 wlan_util_get_mode_specific_peer_count(struct wlan_objmgr_pdev *pdev, 707 void *object, void *arg) 708 { 709 struct wlan_objmgr_vdev *vdev = object; 710 uint16_t temp_count = 0; 711 struct wlan_op_mode_peer_count *count = arg; 712 713 wlan_vdev_obj_lock(vdev); 714 if (wlan_vdev_mlme_get_opmode(vdev) == count->opmode) { 715 temp_count = wlan_vdev_get_peer_count(vdev); 716 /* Decrement the self peer count */ 717 if (temp_count > 1) 718 count->peer_count += (temp_count - 1); 719 } 720 wlan_vdev_obj_unlock(vdev); 721 } 722 723 uint16_t wlan_util_get_peer_count_for_mode(struct wlan_objmgr_pdev *pdev, 724 enum QDF_OPMODE mode) 725 { 726 struct wlan_op_mode_peer_count count; 727 728 count.opmode = mode; 729 count.peer_count = 0; 730 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 731 wlan_util_get_mode_specific_peer_count, &count, 732 0, WLAN_OBJMGR_ID); 733 734 return count.peer_count; 735 } 736 737 #ifdef CONFIG_QCA_MINIDUMP 738 static bool wlan_minidump_log_enabled(struct wlan_objmgr_psoc *psoc, 739 enum wlan_minidump_host_data type) 740 { 741 bool setval = false; 742 743 switch (type) { 744 case WLAN_MD_CP_EXT_PDEV: 745 if (cfg_get(psoc, CFG_OL_MD_CP_EXT_PDEV)) 746 setval = true; 747 break; 748 case WLAN_MD_CP_EXT_PSOC: 749 if (cfg_get(psoc, CFG_OL_MD_CP_EXT_PSOC)) 750 setval = true; 751 break; 752 case WLAN_MD_CP_EXT_VDEV: 753 if (cfg_get(psoc, CFG_OL_MD_CP_EXT_VDEV)) 754 setval = true; 755 break; 756 case WLAN_MD_CP_EXT_PEER: 757 if (cfg_get(psoc, CFG_OL_MD_CP_EXT_PEER)) 758 setval = true; 759 break; 760 case WLAN_MD_DP_SOC: 761 if (cfg_get(psoc, CFG_OL_MD_DP_SOC)) 762 setval = true; 763 break; 764 case WLAN_MD_DP_PDEV: 765 if (cfg_get(psoc, CFG_OL_MD_DP_PDEV)) 766 setval = true; 767 break; 768 case WLAN_MD_DP_PEER: 769 if (cfg_get(psoc, CFG_OL_MD_DP_PEER)) 770 setval = true; 771 break; 772 case WLAN_MD_DP_SRNG_REO_DEST: 773 case WLAN_MD_DP_SRNG_REO_EXCEPTION: 774 case WLAN_MD_DP_SRNG_RX_REL: 775 case WLAN_MD_DP_SRNG_REO_REINJECT: 776 case WLAN_MD_DP_SRNG_REO_CMD: 777 case WLAN_MD_DP_SRNG_REO_STATUS: 778 if (cfg_get(psoc, CFG_OL_MD_DP_SRNG_REO)) 779 setval = true; 780 break; 781 case WLAN_MD_DP_SRNG_TCL_DATA: 782 case WLAN_MD_DP_SRNG_TCL_CMD: 783 case WLAN_MD_DP_SRNG_TCL_STATUS: 784 case WLAN_MD_DP_SRNG_TX_COMP: 785 if (cfg_get(psoc, CFG_OL_MD_DP_SRNG_TCL)) 786 setval = true; 787 break; 788 case WLAN_MD_DP_SRNG_WBM_DESC_REL: 789 case WLAN_MD_DP_SRNG_WBM_IDLE_LINK: 790 if (cfg_get(psoc, CFG_OL_MD_DP_SRNG_WBM)) 791 setval = true; 792 break; 793 case WLAN_MD_DP_LINK_DESC_BANK: 794 if (cfg_get(psoc, CFG_OL_MD_DP_LINK_DESC_BANK)) 795 setval = true; 796 break; 797 case WLAN_MD_DP_SRNG_RXDMA_MON_BUF: 798 case WLAN_MD_DP_SRNG_RXDMA_MON_DST: 799 case WLAN_MD_DP_SRNG_RXDMA_MON_DESC: 800 case WLAN_MD_DP_SRNG_RXDMA_ERR_DST: 801 case WLAN_MD_DP_SRNG_RXDMA_MON_STATUS: 802 if (cfg_get(psoc, CFG_OL_MD_DP_SRNG_RXDMA)) 803 setval = true; 804 break; 805 case WLAN_MD_DP_HAL_SOC: 806 if (cfg_get(psoc, CFG_OL_MD_DP_HAL_SOC)) 807 setval = true; 808 break; 809 case WLAN_MD_OBJMGR_PSOC: 810 case WLAN_MD_OBJMGR_PSOC_TGT_INFO: 811 if (cfg_get(psoc, CFG_OL_MD_OBJMGR_PSOC)) 812 setval = true; 813 break; 814 case WLAN_MD_OBJMGR_PDEV: 815 case WLAN_MD_OBJMGR_PDEV_MLME: 816 if (cfg_get(psoc, CFG_OL_MD_OBJMGR_PDEV)) 817 setval = true; 818 break; 819 case WLAN_MD_OBJMGR_VDEV_MLME: 820 case WLAN_MD_OBJMGR_VDEV_SM: 821 case WLAN_MD_OBJMGR_VDEV: 822 if (cfg_get(psoc, CFG_OL_MD_OBJMGR_VDEV)) 823 setval = true; 824 break; 825 default: 826 qdf_debug("Minidump: Type not implemented"); 827 } 828 829 return setval; 830 } 831 #else /* CONFIG_QCA_MINIDUMP */ 832 static bool wlan_minidump_log_enabled(struct wlan_objmgr_psoc *psoc, 833 enum wlan_minidump_host_data type) 834 { 835 return false; 836 } 837 #endif 838 void wlan_minidump_log(void *start_addr, const size_t size, 839 void *psoc_obj, 840 enum wlan_minidump_host_data type, 841 const char *name) 842 { 843 struct wlan_objmgr_psoc *psoc; 844 845 if (!psoc_obj) { 846 qdf_debug("Minidump: Psoc is NULL"); 847 return; 848 } 849 850 psoc = (struct wlan_objmgr_psoc *)psoc_obj; 851 852 if (psoc && wlan_minidump_log_enabled(psoc, type)) 853 qdf_minidump_log(start_addr, size, name); 854 } 855 qdf_export_symbol(wlan_minidump_log); 856 857 void wlan_minidump_remove(void *start_addr, const size_t size, 858 void *psoc_obj, 859 enum wlan_minidump_host_data type, 860 const char *name) 861 { 862 struct wlan_objmgr_psoc *psoc; 863 864 if (!psoc_obj) { 865 qdf_debug("Minidump: Psoc is NULL"); 866 return; 867 } 868 869 psoc = (struct wlan_objmgr_psoc *)psoc_obj; 870 871 if (psoc && wlan_minidump_log_enabled(psoc, type)) 872 qdf_minidump_remove(start_addr, size, name); 873 } 874 qdf_export_symbol(wlan_minidump_remove); 875