1 /* 2 * Copyright (c) 2017-2018 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: contains scan public utility functions 21 */ 22 23 #ifndef _WLAN_SCAN_UTILS_H_ 24 #define _WLAN_SCAN_UTILS_H_ 25 26 #include <wlan_objmgr_cmn.h> 27 #include <qdf_mc_timer.h> 28 #include <wlan_objmgr_psoc_obj.h> 29 #include <wlan_objmgr_pdev_obj.h> 30 #include <wlan_objmgr_vdev_obj.h> 31 #include <wlan_scan_public_structs.h> 32 #include<wlan_mgmt_txrx_utils_api.h> 33 34 /** 35 * util_is_scan_entry_match() - func to check if both scan entry 36 * are from same AP 37 * @entry1: scan entry 1 38 * @entry2: scan entry 2 39 * 40 * match the two scan entries 41 * 42 * Return: true if entry match else false. 43 */ 44 bool util_is_scan_entry_match( 45 struct scan_cache_entry *entry1, 46 struct scan_cache_entry *entry2); 47 48 /** 49 * util_scan_unpack_beacon_frame() - func to unpack beacon frame to scan entry 50 * @frame: beacon/probe frame 51 * @frame_len: beacon frame len 52 * @frm_subtype: beacon or probe 53 * @rx_param: rx meta data 54 * 55 * get the defaults scan params 56 * 57 * Return: unpacked list of scan entries. 58 */ 59 qdf_list_t *util_scan_unpack_beacon_frame( 60 uint8_t *frame, qdf_size_t frame_len, uint32_t frm_subtype, 61 struct mgmt_rx_event_params *rx_param); 62 63 /** 64 * util_scan_get_ev_type_name() - converts enum event to printable string 65 * @event: event of type scan_event_type 66 * 67 * API, converts enum event to printable character string 68 * 69 * Return: pointer to printable string 70 */ 71 const char *util_scan_get_ev_type_name(enum scan_event_type event); 72 73 /** 74 * util_scan_get_ev_reason_name() - converts enum reason to printable string 75 * @reason enum of scan completion reason 76 * 77 * API, converts enum event to printable character string 78 * 79 * Return: pointer to printable string 80 */ 81 const char *util_scan_get_ev_reason_name(enum scan_completion_reason reason); 82 83 /** 84 * util_scan_entry_macaddr() - function to read transmitter address 85 * @scan_entry: scan entry 86 * 87 * API, function to read transmitter address of scan entry 88 * 89 * Return: pointer to mac address 90 */ 91 static inline uint8_t* 92 util_scan_entry_macaddr(struct scan_cache_entry *scan_entry) 93 { 94 return &(scan_entry->mac_addr.bytes[0]); 95 } 96 97 /** 98 * util_scan_entry_bssid() - function to read bssid 99 * @scan_entry: scan entry 100 * 101 * API, function to read bssid of scan entry 102 * 103 * Return: pointer to mac address 104 */ 105 static inline uint8_t* 106 util_scan_entry_bssid(struct scan_cache_entry *scan_entry) 107 { 108 return &(scan_entry->bssid.bytes[0]); 109 } 110 111 /** 112 * util_scan_entry_capinfo() - function to read capibility info 113 * @scan_entry: scan entry 114 * 115 * API, function to read capibility info of scan entry 116 * 117 * Return: capability info 118 */ 119 static inline union wlan_capability 120 util_scan_entry_capinfo(struct scan_cache_entry *scan_entry) 121 { 122 return scan_entry->cap_info; 123 } 124 125 /** 126 * util_scan_entry_beacon_interval() - function to read beacon interval 127 * @scan_entry: scan entry 128 * 129 * API, function to read beacon interval of scan entry 130 * 131 * Return: beacon interval 132 */ 133 static inline uint16_t 134 util_scan_entry_beacon_interval(struct scan_cache_entry *scan_entry) 135 { 136 return scan_entry->bcn_int; 137 } 138 139 /** 140 * util_scan_entry_sequence_number() - function to read sequence number 141 * @scan_entry: scan entry 142 * 143 * API, function to read sequence number of scan entry 144 * 145 * Return: sequence number 146 */ 147 static inline uint16_t 148 util_scan_entry_sequence_number(struct scan_cache_entry *scan_entry) 149 { 150 return scan_entry->seq_num; 151 } 152 153 /** 154 * util_scan_entry_tsf() - function to read tsf 155 * @scan_entry: scan entry 156 * 157 * API, function to read tsf of scan entry 158 * 159 * Return: tsf 160 */ 161 static inline uint8_t* 162 util_scan_entry_tsf(struct scan_cache_entry *scan_entry) 163 { 164 return scan_entry->tsf_info.data; 165 } 166 167 /** 168 * util_scan_entry_reset_timestamp() - function to reset bcn receive timestamp 169 * @scan_entry: scan entry 170 * 171 * API, function to reset bcn receive timestamp of scan entry 172 * 173 * Return: void 174 */ 175 static inline void 176 util_scan_entry_reset_timestamp(struct scan_cache_entry *scan_entry) 177 { 178 scan_entry->scan_entry_time = 0; 179 } 180 181 /* 182 * Macros used for RSSI calculation. 183 */ 184 #define WLAN_RSSI_AVERAGING_TIME (5 * 1000) /* 5 seconds */ 185 186 #define WLAN_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */ 187 188 #define WLAN_RSSI_LPF_LEN 10 189 #define WLAN_RSSI_DUMMY_MARKER 0x127 190 191 #define WLAN_EP_MUL(x, mul) ((x) * (mul)) 192 193 #define WLAN_EP_RND(x, mul) ((((x)%(mul)) >= ((mul)/2)) ?\ 194 ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) 195 196 #define WLAN_RSSI_GET(x) WLAN_EP_RND(x, WLAN_RSSI_EP_MULTIPLIER) 197 198 #define RSSI_LPF_THRESHOLD -20 199 200 201 #define WLAN_RSSI_OUT(x) (((x) != WLAN_RSSI_DUMMY_MARKER) ? \ 202 (WLAN_EP_RND((x), WLAN_RSSI_EP_MULTIPLIER)) : WLAN_RSSI_DUMMY_MARKER) 203 204 205 #define WLAN_RSSI_IN(x) (WLAN_EP_MUL((x), WLAN_RSSI_EP_MULTIPLIER)) 206 207 #define WLAN_LPF_RSSI(x, y, len) \ 208 ((x != WLAN_RSSI_DUMMY_MARKER) ? ((((x) << 3) + (y) - (x)) >> 3) : (y)) 209 210 #define WLAN_RSSI_LPF(x, y) do { \ 211 if ((y) >= RSSI_LPF_THRESHOLD) \ 212 x = WLAN_LPF_RSSI((x), WLAN_RSSI_IN((y)), WLAN_RSSI_LPF_LEN); \ 213 } while (0) 214 215 #define WLAN_ABS_RSSI_LPF(x, y) do { \ 216 if ((y) >= (RSSI_LPF_THRESHOLD + WLAN_DEFAULT_NOISE_FLOOR)) \ 217 x = WLAN_LPF_RSSI((x), WLAN_RSSI_IN((y)), WLAN_RSSI_LPF_LEN); \ 218 } while (0) 219 220 /** 221 * util_scan_entry_rssi() - function to read rssi of scan entry 222 * @scan_entry: scan entry 223 * 224 * API, function to read rssi value of scan entry 225 * 226 * Return: rssi 227 */ 228 static inline uint8_t 229 util_scan_entry_rssi(struct scan_cache_entry *scan_entry) 230 { 231 uint32_t rssi = WLAN_RSSI_OUT(scan_entry->avg_rssi); 232 /* 233 * An entry is in the BSS list means we've received at least one beacon 234 * from the corresponding AP, so the rssi must be initialized. 235 * 236 * If the RSSI is not initialized, return 0 (i.e. RSSI == Noise Floor). 237 * Once se_avgrssi field has been initialized, ATH_RSSI_OUT always 238 * returns values that fit in an 8-bit variable 239 * (RSSI values are typically 0-90). 240 */ 241 return (rssi >= WLAN_RSSI_DUMMY_MARKER) ? 0 : (uint8_t) rssi; 242 } 243 244 /** 245 * util_scan_entry_phymode() - function to read phymode of scan entry 246 * @scan_entry: scan entry 247 * 248 * API, function to read phymode of scan entry 249 * 250 * Return: phymode 251 */ 252 static inline enum wlan_phymode 253 util_scan_entry_phymode(struct scan_cache_entry *scan_entry) 254 { 255 return scan_entry->phy_mode; 256 } 257 258 /** 259 * util_is_ssid_match() - to check if ssid match 260 * @ssid1: ssid 1 261 * @ssid2: ssid 2 262 * 263 * Return: true if ssid match 264 */ 265 static inline bool 266 util_is_ssid_match(struct wlan_ssid *ssid1, 267 struct wlan_ssid *ssid2) 268 { 269 270 if (ssid1->length == 0) 271 return true; 272 273 if (ssid1->length != ssid2->length) 274 return false; 275 276 if (!qdf_mem_cmp(ssid1->ssid, 277 ssid2->ssid, ssid1->length)) 278 return true; 279 280 return false; 281 } 282 283 /** 284 * util_is_bssid_match() - to check if bssid match 285 * @bssid1: bssid 1 286 * @bssid2: bssid 2 287 * 288 * Return: true if bssid match 289 */ 290 static inline bool util_is_bssid_match(struct qdf_mac_addr *bssid1, 291 struct qdf_mac_addr *bssid2) 292 { 293 294 if (qdf_is_macaddr_zero(bssid1) || 295 qdf_is_macaddr_broadcast(bssid1)) 296 return true; 297 298 if (qdf_is_macaddr_equal(bssid1, bssid2)) 299 return true; 300 301 return false; 302 } 303 304 /** 305 * util_is_bss_type_match() - to check if bss type 306 * @bss_type: bss type 307 * @cap: capability 308 * 309 * Return: true if bss type match 310 */ 311 static inline bool util_is_bss_type_match(enum wlan_bss_type bss_type, 312 union wlan_capability cap) 313 { 314 bool match = true; 315 316 switch (bss_type) { 317 case WLAN_TYPE_ANY: 318 break; 319 case WLAN_TYPE_IBSS: 320 if (!cap.wlan_caps.ibss) 321 match = false; 322 break; 323 case WLAN_TYPE_BSS: 324 if (!cap.wlan_caps.ess) 325 match = false; 326 break; 327 default: 328 match = false; 329 } 330 331 return match; 332 } 333 334 /** 335 * util_country_code_match() - to check if country match 336 * @country: country code pointer 337 * @country_ie: country IE in beacon 338 * 339 * Return: true if country match 340 */ 341 static inline bool util_country_code_match(uint8_t *country, 342 struct wlan_country_ie *cc) 343 { 344 if (!country || !country[0]) 345 return true; 346 347 if (!cc) 348 return false; 349 350 if (cc->cc[0] == country[0] && 351 cc->cc[1] == country[1]) 352 return true; 353 354 return false; 355 } 356 357 /** 358 * util_mdie_match() - to check if mdie match 359 * @mobility_domain: mobility domain 360 * @mdie: mobility domain ie 361 * 362 * Return: true if country match 363 */ 364 static inline bool util_mdie_match(uint16_t mobility_domain, 365 struct rsn_mdie *mdie) 366 { 367 uint16_t md; 368 369 if (!mobility_domain) 370 return true; 371 372 if (!mdie) 373 return false; 374 375 md = 376 (mdie->mobility_domain[1] << 8) | 377 mdie->mobility_domain[0]; 378 379 if (md == mobility_domain) 380 return true; 381 382 return false; 383 } 384 385 /** 386 * util_scan_entry_ssid() - function to read ssid of scan entry 387 * @scan_entry: scan entry 388 * 389 * API, function to read ssid of scan entry 390 * 391 * Return: ssid 392 */ 393 static inline struct wlan_ssid* 394 util_scan_entry_ssid(struct scan_cache_entry *scan_entry) 395 { 396 return &(scan_entry->ssid); 397 } 398 399 /** 400 * util_scan_entry_dtimperiod() - function to read dtim period of scan entry 401 * @scan_entry: scan entry 402 * 403 * API, function to read dtim period of scan entry 404 * 405 * Return: dtim period 406 */ 407 static inline uint8_t 408 util_scan_entry_dtimperiod(struct scan_cache_entry *scan_entry) 409 { 410 return scan_entry->dtim_period; 411 } 412 413 /** 414 * util_scan_entry_tim() - function to read tim ie of scan entry 415 * @scan_entry: scan entry 416 * 417 * API, function to read tim ie of scan entry 418 * 419 * Return: timie or NULL if ie is not present 420 */ 421 static inline uint8_t* 422 util_scan_entry_tim(struct scan_cache_entry *scan_entry) 423 { 424 return scan_entry->ie_list.tim; 425 } 426 427 /** 428 * util_scan_entry_beacon_frame() - function to read full beacon or 429 * probe resp frame 430 * @scan_entry: scan entry 431 * 432 * API, function to read full beacon or probe resp frame including frame header 433 * 434 * Return: beacon/probe resp frame 435 */ 436 static inline struct element_info 437 util_scan_entry_beacon_frame(struct scan_cache_entry *scan_entry) 438 { 439 /* util_scan_entry_beacon_data */ 440 return scan_entry->raw_frame; 441 } 442 443 /** 444 * util_scan_entry_ie_data() - function to read tagged IEs 445 * @scan_entry: scan entry 446 * 447 * API, function to read beacon/probe response frames starting from tagged IEs 448 * (excluding frame header and fixed parameters) 449 * 450 * Return: tagged IES of beacon/probe resp frame 451 */ 452 static inline uint8_t* 453 util_scan_entry_ie_data(struct scan_cache_entry *scan_entry) 454 { 455 struct element_info bcn_frm; 456 uint8_t *ie_data = NULL; 457 458 bcn_frm = util_scan_entry_beacon_frame(scan_entry); 459 ie_data = (uint8_t *) (bcn_frm.ptr + 460 sizeof(struct wlan_frame_hdr) + 461 offsetof(struct wlan_bcn_frame, ie)); 462 return ie_data; 463 } 464 465 /** 466 * util_scan_entry_ie_len() - function to read length of all tagged IEs 467 * @scan_entry: scan entry 468 * 469 * API, function to read length of all tagged IEs 470 * 471 * Return: length of all tagged IEs 472 */ 473 static inline uint16_t 474 util_scan_entry_ie_len(struct scan_cache_entry *scan_entry) 475 { 476 struct element_info bcn_frm; 477 uint16_t ie_len = 0; 478 479 bcn_frm = util_scan_entry_beacon_frame(scan_entry); 480 ie_len = (uint16_t) (bcn_frm.len - 481 sizeof(struct wlan_frame_hdr) - 482 offsetof(struct wlan_bcn_frame, ie)); 483 return ie_len; 484 } 485 486 /** 487 * util_scan_entry_frame_len() - function to frame length 488 * @scan_entry: scan entry 489 * 490 * API, function to read frame length 491 * 492 * Return: frame length 493 */ 494 static inline uint32_t 495 util_scan_entry_frame_len(struct scan_cache_entry *scan_entry) 496 { 497 return scan_entry->raw_frame.len; 498 } 499 500 /** 501 * util_scan_entry_frame_ptr() - function to get frame ptr 502 * @scan_entry: scan entry 503 * 504 * API, function to read frame ptr 505 * 506 * Return: frame ptr 507 */ 508 static inline uint8_t* 509 util_scan_entry_frame_ptr(struct scan_cache_entry *scan_entry) 510 { 511 return scan_entry->raw_frame.ptr; 512 } 513 514 /** 515 * util_scan_entry_copy_ie_data() - function to get a copy of all tagged IEs 516 * @scan_entry: scan entry 517 * 518 * API, function to get a copy of all tagged IEs in passed memory 519 * 520 * Return: QDF_STATUS_SUCCESS if tagged IEs copied successfully 521 * QDF_STATUS_E_NOMEM if passed memory/length can't hold all tagged IEs 522 */ 523 static inline QDF_STATUS 524 util_scan_entry_copy_ie_data(struct scan_cache_entry *scan_entry, 525 uint8_t *iebuf, uint16_t *ie_len) 526 { 527 u_int8_t *buff; 528 u_int16_t buff_len; 529 530 /* iebuf can be NULL, ie_len must be a valid pointer. */ 531 QDF_ASSERT(ie_len != NULL); 532 533 buff = util_scan_entry_ie_data(scan_entry); 534 buff_len = util_scan_entry_ie_len(scan_entry); 535 /* 536 * If caller passed a buffer, check the length to make sure 537 * it's large enough. 538 * If no buffer is passed, just return the length of the IE blob. 539 */ 540 if (iebuf != NULL) { 541 if (*ie_len >= buff_len) { 542 qdf_mem_copy(iebuf, buff, buff_len); 543 *ie_len = buff_len; 544 return QDF_STATUS_SUCCESS; 545 } 546 } 547 548 *ie_len = buff_len; 549 return QDF_STATUS_E_NOMEM; 550 } 551 552 /** 553 * util_scan_free_cache_entry() - function to free scan 554 * cache entry 555 * @scan_entry: scan entry 556 * 557 * API, function to free scan cache entry 558 * 559 * Return: void 560 */ 561 static inline void 562 util_scan_free_cache_entry(struct scan_cache_entry *scan_entry) 563 { 564 if (!scan_entry) 565 return; 566 if (scan_entry->alt_wcn_ie.ptr) 567 qdf_mem_free(scan_entry->alt_wcn_ie.ptr); 568 if (scan_entry->raw_frame.ptr) 569 qdf_mem_free(scan_entry->raw_frame.ptr); 570 qdf_mem_free(scan_entry); 571 } 572 573 #define conv_ptr(_address, _base1, _base2) \ 574 ((_address != NULL) ? (((u_int8_t *) (_address) - \ 575 (u_int8_t *) (_base1)) + (u_int8_t *) (_base2)) : NULL) 576 577 /** 578 * util_scan_copy_beacon_data() - copy beacon and update ie ptrs 579 * cache entry 580 * @new_entry: new scan entry 581 * @scan_entry: entry from where data is copied 582 * 583 * API, function to copy beacon and update ie ptrs 584 * 585 * Return: QDF_STATUS 586 */ 587 static inline QDF_STATUS 588 util_scan_copy_beacon_data(struct scan_cache_entry *new_entry, 589 struct scan_cache_entry *scan_entry) 590 { 591 u_int8_t *new_ptr, *old_ptr; 592 struct ie_list *ie_lst; 593 594 new_entry->raw_frame.ptr = 595 qdf_mem_malloc(scan_entry->raw_frame.len); 596 if (!new_entry->raw_frame.ptr) 597 return QDF_STATUS_E_NOMEM; 598 599 qdf_mem_copy(new_entry->raw_frame.ptr, 600 scan_entry->raw_frame.ptr, 601 scan_entry->raw_frame.len); 602 new_entry->raw_frame.len = scan_entry->raw_frame.len; 603 new_ptr = new_entry->raw_frame.ptr; 604 old_ptr = scan_entry->raw_frame.ptr; 605 606 new_entry->ie_list = scan_entry->ie_list; 607 608 ie_lst = &new_entry->ie_list; 609 610 /* New info_element needs also be added in ieee80211_parse_beacon */ 611 ie_lst->tim = conv_ptr(ie_lst->tim, old_ptr, new_ptr); 612 ie_lst->country = conv_ptr(ie_lst->country, old_ptr, new_ptr); 613 ie_lst->ssid = conv_ptr(ie_lst->ssid, old_ptr, new_ptr); 614 ie_lst->rates = conv_ptr(ie_lst->rates, old_ptr, new_ptr); 615 ie_lst->xrates = conv_ptr(ie_lst->xrates, old_ptr, new_ptr); 616 ie_lst->ds_param = conv_ptr(ie_lst->ds_param, old_ptr, new_ptr); 617 ie_lst->csa = conv_ptr(ie_lst->csa, old_ptr, new_ptr); 618 ie_lst->xcsa = conv_ptr(ie_lst->xcsa, old_ptr, new_ptr); 619 ie_lst->secchanoff = conv_ptr(ie_lst->secchanoff, old_ptr, new_ptr); 620 ie_lst->wpa = conv_ptr(ie_lst->wpa, old_ptr, new_ptr); 621 ie_lst->wcn = conv_ptr(ie_lst->wcn, old_ptr, new_ptr); 622 ie_lst->rsn = conv_ptr(ie_lst->rsn, old_ptr, new_ptr); 623 ie_lst->wps = conv_ptr(ie_lst->wps, old_ptr, new_ptr); 624 ie_lst->wmeinfo = conv_ptr(ie_lst->wmeinfo, old_ptr, new_ptr); 625 ie_lst->wmeparam = conv_ptr(ie_lst->wmeparam, old_ptr, new_ptr); 626 ie_lst->quiet = conv_ptr(ie_lst->quiet, old_ptr, new_ptr); 627 ie_lst->htcap = conv_ptr(ie_lst->htcap, old_ptr, new_ptr); 628 ie_lst->htinfo = conv_ptr(ie_lst->htinfo, old_ptr, new_ptr); 629 ie_lst->athcaps = conv_ptr(ie_lst->athcaps, old_ptr, new_ptr); 630 ie_lst->athextcaps = conv_ptr(ie_lst->athextcaps, old_ptr, new_ptr); 631 ie_lst->sfa = conv_ptr(ie_lst->sfa, old_ptr, new_ptr); 632 ie_lst->vendor = conv_ptr(ie_lst->vendor, old_ptr, new_ptr); 633 ie_lst->qbssload = conv_ptr(ie_lst->qbssload, old_ptr, new_ptr); 634 ie_lst->wapi = conv_ptr(ie_lst->wapi, old_ptr, new_ptr); 635 ie_lst->p2p = conv_ptr(ie_lst->p2p, old_ptr, new_ptr); 636 ie_lst->alt_wcn = conv_ptr(ie_lst->alt_wcn, old_ptr, new_ptr); 637 ie_lst->extcaps = conv_ptr(ie_lst->extcaps, old_ptr, new_ptr); 638 ie_lst->ibssdfs = conv_ptr(ie_lst->ibssdfs, old_ptr, new_ptr); 639 ie_lst->sonadv = conv_ptr(ie_lst->sonadv, old_ptr, new_ptr); 640 ie_lst->vhtcap = conv_ptr(ie_lst->vhtcap, old_ptr, new_ptr); 641 ie_lst->vhtop = conv_ptr(ie_lst->vhtop, old_ptr, new_ptr); 642 ie_lst->opmode = conv_ptr(ie_lst->opmode, old_ptr, new_ptr); 643 ie_lst->cswrp = conv_ptr(ie_lst->cswrp, old_ptr, new_ptr); 644 ie_lst->widebw = conv_ptr(ie_lst->widebw, old_ptr, new_ptr); 645 ie_lst->txpwrenvlp = conv_ptr(ie_lst->txpwrenvlp, old_ptr, new_ptr); 646 ie_lst->bwnss_map = conv_ptr(ie_lst->bwnss_map, old_ptr, new_ptr); 647 ie_lst->mdie = conv_ptr(ie_lst->mdie, old_ptr, new_ptr); 648 ie_lst->hecap = conv_ptr(ie_lst->hecap, old_ptr, new_ptr); 649 ie_lst->heop = conv_ptr(ie_lst->heop, old_ptr, new_ptr); 650 ie_lst->fils_indication = conv_ptr(ie_lst->fils_indication, 651 old_ptr, new_ptr); 652 ie_lst->esp = conv_ptr(ie_lst->esp, old_ptr, new_ptr); 653 ie_lst->mbo_oce = conv_ptr(ie_lst->mbo_oce, old_ptr, new_ptr); 654 655 return QDF_STATUS_SUCCESS; 656 } 657 /** 658 * util_scan_copy_cache_entry() - function to create a copy 659 * of scan cache entry 660 * @scan_entry: scan entry 661 * 662 * API, function to create a copy of scan cache entry 663 * 664 * Return: copy of scan_entry 665 */ 666 static inline struct scan_cache_entry * 667 util_scan_copy_cache_entry(struct scan_cache_entry *scan_entry) 668 { 669 struct scan_cache_entry *new_entry; 670 QDF_STATUS status; 671 672 if (!scan_entry) 673 return NULL; 674 675 new_entry = 676 qdf_mem_malloc(sizeof(*scan_entry)); 677 if (!new_entry) 678 return NULL; 679 680 qdf_mem_copy(new_entry, 681 scan_entry, sizeof(*scan_entry)); 682 683 if (scan_entry->alt_wcn_ie.ptr) { 684 new_entry->alt_wcn_ie.ptr = 685 qdf_mem_malloc(scan_entry->alt_wcn_ie.len); 686 if (!new_entry->alt_wcn_ie.ptr) { 687 qdf_mem_free(new_entry); 688 return NULL; 689 } 690 qdf_mem_copy(new_entry->alt_wcn_ie.ptr, 691 scan_entry->alt_wcn_ie.ptr, 692 scan_entry->alt_wcn_ie.len); 693 new_entry->alt_wcn_ie.len = 694 scan_entry->alt_wcn_ie.len; 695 } 696 697 status = util_scan_copy_beacon_data(new_entry, scan_entry); 698 if (QDF_IS_STATUS_ERROR(status)) { 699 util_scan_free_cache_entry(new_entry); 700 return NULL; 701 } 702 703 return new_entry; 704 } 705 706 /** 707 * util_scan_entry_channel() - function to read channel info 708 * @scan_entry: scan entry 709 * 710 * API, function to read channel info 711 * 712 * Return: channel info 713 */ 714 static inline struct channel_info* 715 util_scan_entry_channel(struct scan_cache_entry *scan_entry) 716 { 717 return &(scan_entry->channel); 718 } 719 720 /** 721 * util_scan_entry_channel_num() - function to read channel number 722 * @scan_entry: scan entry 723 * 724 * API, function to read channel number 725 * 726 * Return: channel number 727 */ 728 static inline uint8_t 729 util_scan_entry_channel_num(struct scan_cache_entry *scan_entry) 730 { 731 return scan_entry->channel.chan_idx; 732 } 733 734 /** 735 * util_scan_entry_erpinfo() - function to read erp info 736 * @scan_entry: scan entry 737 * 738 * API, function to read erp info 739 * 740 * Return: erp info 741 */ 742 static inline uint8_t 743 util_scan_entry_erpinfo(struct scan_cache_entry *scan_entry) 744 { 745 return scan_entry->erp; 746 } 747 748 /** 749 * util_scan_entry_rates() - function to read supported rates IE 750 * @scan_entry: scan entry 751 * 752 * API, function to read supported rates IE 753 * 754 * Return: basic ratesie or NULL if ie is not present 755 */ 756 static inline uint8_t* 757 util_scan_entry_rates(struct scan_cache_entry *scan_entry) 758 { 759 return scan_entry->ie_list.rates; 760 } 761 762 /** 763 * util_scan_entry_xrates()- function to read extended supported rates IE 764 * @scan_entry: scan entry 765 * 766 * API, function to read extended supported rates IE 767 * 768 * Return: extended supported ratesie or NULL if ie is not present 769 */ 770 static inline uint8_t* 771 util_scan_entry_xrates(struct scan_cache_entry *scan_entry) 772 { 773 return scan_entry->ie_list.xrates; 774 } 775 776 /** 777 * util_scan_entry_rsn()- function to read rsn IE 778 * @scan_entry: scan entry 779 * 780 * API, function to read rsn IE 781 * 782 * Return: rsnie or NULL if ie is not present 783 */ 784 static inline uint8_t* 785 util_scan_entry_rsn(struct scan_cache_entry *scan_entry) 786 { 787 return scan_entry->ie_list.rsn; 788 } 789 790 /** 791 * util_scan_get_rsn_len()- function to read rsn IE length if present 792 * @scan_entry: scan entry 793 * 794 * API, function to read rsn length if present 795 * 796 * Return: rsnie length 797 */ 798 static inline uint8_t 799 util_scan_get_rsn_len(struct scan_cache_entry *scan_entry) 800 { 801 if (scan_entry && scan_entry->ie_list.rsn) 802 return scan_entry->ie_list.rsn[1] + 2; 803 else 804 return 0; 805 } 806 807 808 /** 809 * util_scan_entry_wpa() - function to read wpa IE 810 * @scan_entry: scan entry 811 * 812 * API, function to read wpa IE 813 * 814 * Return: wpaie or NULL if ie is not present 815 */ 816 static inline uint8_t* 817 util_scan_entry_wpa(struct scan_cache_entry *scan_entry) 818 { 819 return scan_entry->ie_list.wpa; 820 } 821 822 /** 823 * util_scan_get_wpa_len()- function to read wpa IE length if present 824 * @scan_entry: scan entry 825 * 826 * API, function to read wpa ie length if present 827 * 828 * Return: wpa ie length 829 */ 830 static inline uint8_t 831 util_scan_get_wpa_len(struct scan_cache_entry *scan_entry) 832 { 833 if (scan_entry && scan_entry->ie_list.wpa) 834 return scan_entry->ie_list.wpa[1] + 2; 835 else 836 return 0; 837 } 838 839 840 /** 841 * util_scan_entry_wapi() - function to read wapi IE 842 * @scan_entry: scan entry 843 * 844 * API, function to read wapi IE 845 * 846 * Return: wapiie or NULL if ie is not present 847 */ 848 static inline uint8_t* 849 util_scan_entry_wapi(struct scan_cache_entry *scan_entry) 850 { 851 return scan_entry->ie_list.wapi; 852 } 853 854 /** 855 * util_scan_entry_wps() - function to read wps IE 856 * @scan_entry: scan entry 857 * 858 * API, function to read wps IE 859 * 860 * Return: wpsie or NULL if ie is not present 861 */ 862 static inline uint8_t* 863 util_scan_entry_wps(struct scan_cache_entry *scan_entry) 864 { 865 return scan_entry->ie_list.wps; 866 } 867 868 /** 869 * util_scan_entry_sfa() - function to read sfa IE 870 * @scan_entry: scan entry 871 * 872 * API, function to read sfa IE 873 * 874 * Return: sfaie or NULL if ie is not present 875 */ 876 static inline uint8_t* 877 util_scan_entry_sfa(struct scan_cache_entry *scan_entry) 878 { 879 return scan_entry->ie_list.sfa; 880 } 881 882 /** 883 * util_scan_entry_ds_param() - function to read ds params 884 * @scan_entry: scan entry 885 * 886 * API, function to read ds params 887 * 888 * Return: ds params or NULL if ie is not present 889 */ 890 static inline uint8_t* 891 util_scan_entry_ds_param(struct scan_cache_entry *scan_entry) 892 { 893 if (scan_entry) 894 return scan_entry->ie_list.ds_param; 895 else 896 return NULL; 897 } 898 899 /** 900 * util_scan_entry_csa() - function to read csa IE 901 * @scan_entry: scan entry 902 * 903 * API, function to read csa IE 904 * 905 * Return: csaie or NULL if ie is not present 906 */ 907 static inline uint8_t* 908 util_scan_entry_csa(struct scan_cache_entry *scan_entry) 909 { 910 return scan_entry->ie_list.csa; 911 } 912 913 /** 914 * util_scan_entry_xcsa() - function to read extended csa IE 915 * @scan_entry: scan entry 916 * 917 * API, function to read extended csa IE 918 * 919 * Return: extended csaie or NULL if ie is not present 920 */ 921 static inline uint8_t* 922 util_scan_entry_xcsa(struct scan_cache_entry *scan_entry) 923 { 924 return scan_entry->ie_list.xcsa; 925 } 926 927 /** 928 * util_scan_entry_htinfo() - function to read htinfo IE 929 * @scan_entry: scan entry 930 * 931 * API, function to read htinfo IE 932 * 933 * Return: htinfoie or NULL if ie is not present 934 */ 935 static inline uint8_t* 936 util_scan_entry_htinfo(struct scan_cache_entry *scan_entry) 937 { 938 return scan_entry->ie_list.htinfo; 939 } 940 941 942 /** 943 * util_scan_entry_htcap() - function to read htcap IE 944 * @scan_entry: scan entry 945 * 946 * API, function to read htcap IE 947 * 948 * Return: htcapie or NULL if ie is not present 949 */ 950 static inline uint8_t* 951 util_scan_entry_htcap(struct scan_cache_entry *scan_entry) 952 { 953 return scan_entry->ie_list.htcap; 954 } 955 956 /** 957 * util_scan_entry_vhtcap() - function to read vhtcap IE 958 * @scan_entry: scan entry 959 * 960 * API, function to read vhtcap IE 961 * 962 * Return: vhtcapie or NULL if ie is not present 963 */ 964 static inline uint8_t* 965 util_scan_entry_vhtcap(struct scan_cache_entry *scan_entry) 966 { 967 return scan_entry->ie_list.vhtcap; 968 } 969 970 /** 971 * util_scan_entry_vhtop() - function to read vhtop IE 972 * @scan_entry: scan entry 973 * 974 * API, function to read vhtop IE 975 * 976 * Return: vhtopie or NULL if ie is not present 977 */ 978 static inline uint8_t* 979 util_scan_entry_vhtop(struct scan_cache_entry *scan_entry) 980 { 981 return scan_entry->ie_list.vhtop; 982 } 983 984 /** 985 * util_scan_entry_quiet() - function to read quiet IE 986 * @scan_entry: scan entry 987 * 988 * API, function to read quiet IE 989 * 990 * Return: quietie or NULL if ie is not present 991 */ 992 static inline uint8_t* 993 util_scan_entry_quiet(struct scan_cache_entry *scan_entry) 994 { 995 return scan_entry->ie_list.quiet; 996 } 997 998 /** 999 * util_scan_entry_qbssload() - function to read qbss load IE 1000 * @scan_entry: scan entry 1001 * 1002 * API, function to read qbss load IE 1003 * 1004 * Return: qbss loadie or NULL if ie is not present 1005 */ 1006 static inline uint8_t* 1007 util_scan_entry_qbssload(struct scan_cache_entry *scan_entry) 1008 { 1009 return scan_entry->ie_list.qbssload; 1010 } 1011 1012 /** 1013 * util_scan_entry_vendor() - function to read vendor IE 1014 * @scan_entry: scan entry 1015 * 1016 * API, function to read vendor IE 1017 * 1018 * Return: vendorie or NULL if ie is not present 1019 */ 1020 static inline uint8_t* 1021 util_scan_entry_vendor(struct scan_cache_entry *scan_entry) 1022 { 1023 return scan_entry->ie_list.vendor; 1024 } 1025 1026 /** 1027 * util_scan_entry_country() - function to read country IE 1028 * @scan_entry: scan entry 1029 * 1030 * API, function to read country IE 1031 * 1032 * Return: countryie or NULL if ie is not present 1033 */ 1034 static inline struct wlan_country_ie* 1035 util_scan_entry_country(struct scan_cache_entry *scan_entry) 1036 { 1037 return (struct wlan_country_ie *)scan_entry->ie_list.country; 1038 } 1039 1040 /** 1041 * util_scan_entry_copy_country() - function to copy country name 1042 * @scan_entry: scan entry 1043 * @cntry: out buffer 1044 * 1045 * API, function to copy country name code string in given memory @centry 1046 * 1047 * Return: QDF_STATUS_SUCCESS if successfully copied country name 1048 * QDF_STATUS_E_INVAL if passed buffer is null 1049 * QDF_STATUS_E_NOMEM if scan entry dont have country IE 1050 */ 1051 static inline QDF_STATUS 1052 util_scan_entry_copy_country(struct scan_cache_entry *scan_entry, 1053 uint8_t *cntry) 1054 { 1055 struct wlan_country_ie *country_ie; 1056 1057 if (!cntry) 1058 return QDF_STATUS_E_INVAL; 1059 1060 country_ie = util_scan_entry_country(scan_entry); 1061 1062 if (!country_ie) 1063 return QDF_STATUS_E_NOMEM; 1064 1065 qdf_mem_copy(cntry, country_ie->cc, 3); 1066 1067 return QDF_STATUS_SUCCESS; 1068 } 1069 1070 /** 1071 * util_scan_entry_wmeinfo() - function to read wme info ie 1072 * @scan_entry: scan entry 1073 * 1074 * API, function to read wme info ie 1075 * 1076 * Return: wme infoie or NULL if ie is not present 1077 */ 1078 static inline uint8_t* 1079 util_scan_entry_wmeinfo(struct scan_cache_entry *scan_entry) 1080 { 1081 return scan_entry->ie_list.wmeinfo; 1082 } 1083 1084 /** 1085 * util_scan_entry_wmeparam() - function to read wme param ie 1086 * @scan_entry: scan entry 1087 * 1088 * API, function to read wme param ie 1089 * 1090 * Return: wme paramie or NULL if ie is not present 1091 */ 1092 static inline uint8_t* 1093 util_scan_entry_wmeparam(struct scan_cache_entry *scan_entry) 1094 { 1095 return scan_entry->ie_list.wmeparam; 1096 } 1097 1098 /** 1099 * util_scan_entry_age() - function to read age of scan entry 1100 * @scan_entry: scan entry 1101 * 1102 * API, function to read age of scan entry 1103 * 1104 * Return: age in ms 1105 */ 1106 static inline uint32_t 1107 util_scan_entry_age(struct scan_cache_entry *scan_entry) 1108 { 1109 unsigned long ts = scan_entry->scan_entry_time; 1110 1111 return qdf_mc_timer_get_system_time() - ts; 1112 } 1113 1114 /** 1115 * util_scan_mlme_info() - function to read mlme info struct 1116 * @scan_entry: scan entry 1117 * 1118 * API, function to read mlme info struct 1119 * 1120 * Return: mlme info 1121 */ 1122 static inline struct mlme_info* 1123 util_scan_mlme_info(struct scan_cache_entry *scan_entry) 1124 { 1125 return &scan_entry->mlme_info; 1126 } 1127 1128 /** 1129 * util_scan_entry_bss_type() - function to read bss type 1130 * @scan_entry: scan entry 1131 * 1132 * API, function to read bss type 1133 * 1134 * Return: bss type 1135 */ 1136 static inline enum wlan_bss_type 1137 util_scan_entry_bss_type(struct scan_cache_entry *scan_entry) 1138 { 1139 if (scan_entry->cap_info.value & WLAN_CAPINFO_ESS) 1140 return WLAN_TYPE_BSS; 1141 else if (scan_entry->cap_info.value & WLAN_CAPINFO_IBSS) 1142 return WLAN_TYPE_IBSS; 1143 else 1144 return WLAN_TYPE_ANY; 1145 } 1146 1147 /** 1148 * util_scan_entry_privacy() - function to check if privacy is enebled 1149 * @scan_entry: scan entry 1150 * 1151 * API, function to check if privacy is enebled 1152 * 1153 * Return: true if privacy is enabled, false other wise 1154 */ 1155 static inline bool 1156 util_scan_entry_privacy(struct scan_cache_entry *scan_entry) 1157 { 1158 return (scan_entry->cap_info.value & 1159 WLAN_CAPINFO_PRIVACY) ? true : false; 1160 } 1161 1162 /** 1163 * util_scan_entry_athcaps() - function to read ath caps vendor ie 1164 * @scan_entry: scan entry 1165 * 1166 * API, function to read ath caps vendor ie 1167 * 1168 * Return: ath caps vendorie or NULL if ie is not present 1169 */ 1170 static inline uint8_t* 1171 util_scan_entry_athcaps(struct scan_cache_entry *scan_entry) 1172 { 1173 return scan_entry->ie_list.athcaps; 1174 } 1175 1176 /** 1177 * util_scan_entry_athextcaps() - function to read ath extcaps vendor ie 1178 * @scan_entry: scan entry 1179 * 1180 * API, function to read ath extcaps vendor ie 1181 * 1182 * Return: ath extcaps vendorie or NULL if ie is not present 1183 */ 1184 static inline uint8_t* 1185 util_scan_entry_athextcaps(struct scan_cache_entry *scan_entry) 1186 { 1187 return scan_entry->ie_list.athextcaps; 1188 } 1189 1190 /** 1191 * util_scan_entry_bwnss_map() - function to read bwnss_map ie 1192 * @scan_entry: scan entry 1193 * 1194 * API, function to read bwnss_map ie 1195 * 1196 * Return: bwnss_map ie or NULL if ie is not present 1197 */ 1198 static inline uint8_t* 1199 util_scan_entry_bwnss_map(struct scan_cache_entry *scan_entry) 1200 { 1201 return scan_entry->ie_list.bwnss_map; 1202 } 1203 1204 /** 1205 * util_scan_entry_sonie() - function to read son ie 1206 * @scan_entry: scan entry 1207 * 1208 * API, function to read son ie 1209 * 1210 * Return: son ie or NULL if ie is not present 1211 */ 1212 static inline uint8_t* 1213 util_scan_entry_sonie(struct scan_cache_entry *scan_entry) 1214 { 1215 return scan_entry->ie_list.sonadv; 1216 } 1217 1218 /** 1219 * util_scan_entry_widebw() - function to read wide band chan switch sub elem ie 1220 * @scan_entry: scan entry 1221 * 1222 * API, function to read wide band chan switch sub elem ie 1223 * 1224 * Return: wide band chan switch sub elem or NULL if ie is not present 1225 */ 1226 static inline uint8_t* 1227 util_scan_entry_widebw(struct scan_cache_entry *scan_entry) 1228 { 1229 return scan_entry->ie_list.widebw; 1230 } 1231 1232 /** 1233 * util_scan_entry_secchanoff() - function to read secondary channel offset ie 1234 * @scan_entry: scan entry 1235 * 1236 * API, function to read secondary channel offset ie 1237 * 1238 * Return: secondary channel offset element or NULL if ie is not present 1239 */ 1240 static inline uint8_t* 1241 util_scan_entry_secchanoff(struct scan_cache_entry *scan_entry) 1242 { 1243 return scan_entry->ie_list.secchanoff; 1244 } 1245 1246 /** 1247 * util_scan_entry_cswrp() - function to read channel switch wrapper ie 1248 * @scan_entry: scan entry 1249 * 1250 * API, function to read channel switch wrapper ie 1251 * 1252 * Return: channel switch wrapper element or NULL if ie is not present 1253 */ 1254 static inline uint8_t* 1255 util_scan_entry_cswrp(struct scan_cache_entry *scan_entry) 1256 { 1257 return scan_entry->ie_list.cswrp; 1258 } 1259 1260 /** 1261 * util_scan_entry_omn() - function to read operating mode notification ie 1262 * @scan_entry: scan entry 1263 * 1264 * API, function to read operating mode notification 1265 * 1266 * Return: operating mode notification element or NULL if ie is not present 1267 */ 1268 static inline uint8_t* 1269 util_scan_entry_omn(struct scan_cache_entry *scan_entry) 1270 { 1271 return scan_entry->ie_list.opmode; 1272 } 1273 1274 /** 1275 * util_scan_entry_extcaps() - function to read extcap ie 1276 * @scan_entry: scan entry 1277 * 1278 * API, function to read extcap ie 1279 * 1280 * Return: extcap element or NULL if ie is not present 1281 */ 1282 static inline uint8_t* 1283 util_scan_entry_extcaps(struct scan_cache_entry *scan_entry) 1284 { 1285 return scan_entry->ie_list.extcaps; 1286 } 1287 1288 /** 1289 * util_scan_entry_athcaps() - function to read ath caps vendor ie 1290 * @scan_entry: scan entry 1291 * 1292 * API, function to read ath caps vendor ie 1293 * 1294 * Return: ath caps vendorie or NULL if ie is not present 1295 */ 1296 static inline struct mlme_info* 1297 util_scan_entry_mlme_info(struct scan_cache_entry *scan_entry) 1298 { 1299 return &(scan_entry->mlme_info); 1300 } 1301 1302 /** 1303 * util_scan_entry_hecap() - function to read he caps vendor ie 1304 * @scan_entry: scan entry 1305 * 1306 * API, function to read he caps vendor ie 1307 * 1308 * Return: he caps vendorie or NULL if ie is not present 1309 */ 1310 static inline uint8_t* 1311 util_scan_entry_hecap(struct scan_cache_entry *scan_entry) 1312 { 1313 return scan_entry->ie_list.hecap; 1314 } 1315 1316 1317 /** 1318 * util_scan_entry_heop() - function to read heop vendor ie 1319 * @scan_entry: scan entry 1320 * 1321 * API, function to read heop vendor ie 1322 * 1323 * Return, heop vendorie or NULL if ie is not present 1324 */ 1325 static inline uint8_t* 1326 util_scan_entry_heop(struct scan_cache_entry *scan_entry) 1327 { 1328 return scan_entry->ie_list.heop; 1329 } 1330 1331 /** 1332 * util_scan_entry_spatial_reuse_parameter() - function to read spatial reuse 1333 * parameter ie 1334 * @scan_entry: scan entry 1335 * 1336 * API, function to read scan_entry reuse parameter ie 1337 * 1338 * Return, spatial reuse parameter ie or NULL if ie is not present 1339 */ 1340 static inline uint8_t* 1341 util_scan_entry_spatial_reuse_parameter(struct scan_cache_entry *scan_entry) 1342 { 1343 return scan_entry->ie_list.srp; 1344 } 1345 1346 /** 1347 * util_scan_entry_fils_indication() - function to read FILS indication ie 1348 * @scan_entry: scan entry 1349 * 1350 * API, function to read FILS indication ie 1351 * 1352 * Return, FILS indication ie or NULL if ie is not present 1353 */ 1354 static inline uint8_t* 1355 util_scan_entry_fils_indication(struct scan_cache_entry *scan_entry) 1356 { 1357 return scan_entry->ie_list.fils_indication; 1358 } 1359 1360 /** 1361 * util_get_last_scan_time() - function to get last scan time on this pdev 1362 * @vdev: vdev object 1363 * 1364 * API, function to read last scan time on this pdev 1365 * 1366 * Return: qdf_time_t 1367 */ 1368 qdf_time_t 1369 util_get_last_scan_time(struct wlan_objmgr_vdev *vdev); 1370 1371 /** 1372 * util_scan_entry_update_mlme_info() - function to update mlme info 1373 * @scan_entry: scan entry object 1374 * 1375 * API, function to update mlme info in scan DB 1376 * 1377 * Return: QDF_STATUS 1378 */ 1379 QDF_STATUS 1380 util_scan_entry_update_mlme_info(struct wlan_objmgr_pdev *pdev, 1381 struct scan_cache_entry *scan_entry); 1382 1383 /** 1384 * util_scan_is_hidden_ssid() - function to check if ssid is hidden 1385 * @ssid: struct ie_ssid object 1386 * 1387 * API, function to check if ssid is hidden 1388 * 1389 * Return: true if ap is hidden, false otherwise 1390 */ 1391 bool 1392 util_scan_is_hidden_ssid(struct ie_ssid *ssid); 1393 1394 /** 1395 * util_scan_entry_is_hidden_ap() - function to check if ap is hidden 1396 * @scan_entry: scan entry 1397 * 1398 * API, function to check if ap is hidden 1399 * 1400 * Return: true if ap is hidden, false otherwise 1401 */ 1402 static inline bool 1403 util_scan_entry_is_hidden_ap(struct scan_cache_entry *scan_entry) 1404 { 1405 return util_scan_is_hidden_ssid( 1406 (struct ie_ssid *)scan_entry->ie_list.ssid); 1407 } 1408 1409 /** 1410 * util_scan_entry_espinfo() - function to read ESP info 1411 * @scan_entry: scan entry 1412 * 1413 * API, function to read ESP info 1414 * 1415 * Return: erp info 1416 */ 1417 static inline uint8_t * 1418 util_scan_entry_esp_info(struct scan_cache_entry *scan_entry) 1419 { 1420 return scan_entry->ie_list.esp; 1421 } 1422 1423 /** 1424 * util_scan_entry_mbo_oce() - function to read MBO/OCE ie 1425 * @scan_entry: scan entry 1426 * 1427 * API, function to read MBO/OCE ie 1428 * 1429 * Return: MBO/OCE ie 1430 */ 1431 static inline uint8_t * 1432 util_scan_entry_mbo_oce(struct scan_cache_entry *scan_entry) 1433 { 1434 return scan_entry->ie_list.mbo_oce; 1435 } 1436 1437 /** 1438 * util_scan_scm_chan_to_band() - function to tell band for channel number 1439 * @chan: Channel number 1440 * 1441 * Return: Band information as per channel 1442 */ 1443 enum wlan_band util_scan_scm_chan_to_band(uint32_t chan); 1444 1445 #endif 1446