123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- /**
- * DOC: This file contains definition for mandatory legacy API
- */
- #include "qdf_str.h"
- #include "wlan_utility.h"
- #include <wlan_cmn.h>
- #include "wlan_osif_priv.h"
- #include <net/cfg80211.h>
- #include <qdf_module.h>
- #include <wlan_vdev_mlme_api.h>
- uint32_t wlan_chan_to_freq(uint8_t chan)
- {
- /* ch 0 - ch 13 */
- if (chan < WLAN_24_GHZ_CHANNEL_14)
- return WLAN_24_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ;
- else if (chan == WLAN_24_GHZ_CHANNEL_14)
- return WLAN_CHAN_14_FREQ;
- else if (chan < WLAN_24_GHZ_CHANNEL_27)
- /* ch 15 - ch 26 */
- return WLAN_CHAN_15_FREQ +
- (chan - WLAN_24_GHZ_CHANNEL_15) * WLAN_CHAN_SPACING_20MHZ;
- else if (chan == WLAN_5_GHZ_CHANNEL_170)
- return WLAN_CHAN_170_FREQ;
- else
- return WLAN_5_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ;
- }
- uint8_t wlan_freq_to_chan(uint32_t freq)
- {
- uint8_t chan;
- if (freq > WLAN_24_GHZ_BASE_FREQ && freq < WLAN_CHAN_14_FREQ)
- chan = ((freq - WLAN_24_GHZ_BASE_FREQ) /
- WLAN_CHAN_SPACING_5MHZ);
- else if (freq == WLAN_CHAN_14_FREQ)
- chan = WLAN_24_GHZ_CHANNEL_14;
- else if ((freq > WLAN_24_GHZ_BASE_FREQ) &&
- (freq < WLAN_5_GHZ_BASE_FREQ))
- chan = (((freq - WLAN_CHAN_15_FREQ) /
- WLAN_CHAN_SPACING_20MHZ) +
- WLAN_24_GHZ_CHANNEL_15);
- else
- chan = (freq - WLAN_5_GHZ_BASE_FREQ) /
- WLAN_CHAN_SPACING_5MHZ;
- return chan;
- }
- bool wlan_is_ie_valid(const uint8_t *ie, size_t ie_len)
- {
- uint8_t elen;
- while (ie_len) {
- if (ie_len < 2)
- return false;
- elen = ie[1];
- ie_len -= 2;
- ie += 2;
- if (elen > ie_len)
- return false;
- ie_len -= elen;
- ie += elen;
- }
- return true;
- }
- static const uint8_t *wlan_get_ie_ptr_from_eid_n_oui(uint8_t eid,
- const uint8_t *oui,
- uint8_t oui_size,
- const uint8_t *ie,
- uint16_t ie_len)
- {
- int32_t left = ie_len;
- const uint8_t *ptr = ie;
- uint8_t elem_id, elem_len;
- while (left >= 2) {
- elem_id = ptr[0];
- elem_len = ptr[1];
- left -= 2;
- if (elem_len > left)
- return NULL;
- if (eid == elem_id) {
- /* if oui is not provide eid match is enough */
- if (!oui)
- return ptr;
- /*
- * if oui is provided and oui_size is more than left
- * bytes, then we cannot have match
- */
- if (oui_size > left)
- return NULL;
- if (qdf_mem_cmp(&ptr[2], oui, oui_size) == 0)
- return ptr;
- }
- left -= elem_len;
- ptr += (elem_len + 2);
- }
- return NULL;
- }
- const uint8_t *wlan_get_ie_ptr_from_eid(uint8_t eid,
- const uint8_t *ie,
- int ie_len)
- {
- return wlan_get_ie_ptr_from_eid_n_oui(eid, NULL, 0, ie, ie_len);
- }
- const uint8_t *wlan_get_vendor_ie_ptr_from_oui(const uint8_t *oui,
- uint8_t oui_size,
- const uint8_t *ie,
- uint16_t ie_len)
- {
- return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_VENDOR,
- oui, oui_size, ie, ie_len);
- }
- const uint8_t *wlan_get_ext_ie_ptr_from_ext_id(const uint8_t *oui,
- uint8_t oui_size,
- const uint8_t *ie,
- uint16_t ie_len)
- {
- return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_EXT,
- oui, oui_size, ie, ie_len);
- }
- bool wlan_is_emulation_platform(uint32_t phy_version)
- {
- if ((phy_version == 0xABC0) || (phy_version == 0xABC1) ||
- (phy_version == 0xABC2) || (phy_version == 0xABC3) ||
- (phy_version == 0xFFFF) || (phy_version == 0xABCD))
- return true;
- return false;
- }
- uint32_t wlan_get_pdev_id_from_vdev_id(struct wlan_objmgr_psoc *psoc,
- uint8_t vdev_id,
- wlan_objmgr_ref_dbgid dbg_id)
- {
- struct wlan_objmgr_vdev *vdev;
- struct wlan_objmgr_pdev *pdev = NULL;
- uint32_t pdev_id = WLAN_INVALID_PDEV_ID;
- vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
- vdev_id, dbg_id);
- if (vdev) {
- pdev = wlan_vdev_get_pdev(vdev);
- if (pdev)
- pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
- wlan_objmgr_vdev_release_ref(vdev, dbg_id);
- }
- return pdev_id;
- }
- qdf_export_symbol(wlan_get_pdev_id_from_vdev_id);
- #ifdef CMN_VDEV_MLME_SM_ENABLE
- static void wlan_vdev_active(struct wlan_objmgr_pdev *pdev, void *object,
- void *arg)
- {
- struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
- uint8_t *flag = (uint8_t *)arg;
- wlan_vdev_obj_lock(vdev);
- if (wlan_vdev_mlme_is_active(vdev) == QDF_STATUS_SUCCESS)
- *flag = 1;
- wlan_vdev_obj_unlock(vdev);
- }
- QDF_STATUS wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev)
- {
- return wlan_vdev_allow_connect_n_tx(vdev);
- }
- qdf_export_symbol(wlan_vdev_is_up);
- #else
- static void wlan_vdev_active(struct wlan_objmgr_pdev *pdev, void *object,
- void *arg)
- {
- struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
- uint8_t *flag = (uint8_t *)arg;
- wlan_vdev_obj_lock(vdev);
- if ((wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_RUN) ||
- (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_WAIT))
- *flag = 1;
- wlan_vdev_obj_unlock(vdev);
- }
- QDF_STATUS wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev)
- {
- QDF_STATUS is_up = QDF_STATUS_E_FAILURE;
- wlan_vdev_obj_lock(vdev);
- if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_RUN)
- is_up = QDF_STATUS_SUCCESS;
- wlan_vdev_obj_unlock(vdev);
- return is_up;
- }
- qdf_export_symbol(wlan_vdev_is_up);
- #endif
- QDF_STATUS wlan_util_is_vdev_active(struct wlan_objmgr_pdev *pdev,
- wlan_objmgr_ref_dbgid dbg_id)
- {
- uint8_t flag = 0;
- if (!pdev)
- return QDF_STATUS_E_INVAL;
- wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, wlan_vdev_active,
- &flag, 0, dbg_id);
- if (flag == 1)
- return QDF_STATUS_SUCCESS;
- return QDF_STATUS_E_INVAL;
- }
- #ifdef CMN_VDEV_MLME_SM_ENABLE
- void wlan_util_change_map_index(unsigned long *map, uint8_t id, uint8_t set)
- {
- if (set)
- qdf_set_bit(id, map);
- else
- qdf_clear_bit(id, map);
- }
- bool wlan_util_map_index_is_set(unsigned long *map, uint8_t id)
- {
- return qdf_test_bit(id, map);
- }
- static void wlan_vdev_chan_change_pending(struct wlan_objmgr_pdev *pdev,
- void *object, void *arg)
- {
- struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
- unsigned long *vdev_id_map = (unsigned long *)arg;
- uint8_t id = 0;
- struct wlan_objmgr_psoc *psoc;
- psoc = wlan_pdev_get_psoc(pdev);
- if (!psoc)
- return;
- wlan_vdev_obj_lock(vdev);
- if (wlan_vdev_chan_config_valid(vdev) == QDF_STATUS_SUCCESS) {
- id = wlan_vdev_get_id(vdev);
- /* Invalid vdev id */
- if (id >= wlan_psoc_get_max_vdev_count(psoc)) {
- wlan_vdev_obj_unlock(vdev);
- return;
- }
- wlan_util_change_map_index(vdev_id_map, id, 1);
- }
- wlan_vdev_obj_unlock(vdev);
- }
- QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev,
- unsigned long *vdev_id_map,
- wlan_objmgr_ref_dbgid dbg_id)
- {
- if (!pdev)
- return QDF_STATUS_E_INVAL;
- wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
- wlan_vdev_chan_change_pending,
- vdev_id_map, 0, dbg_id);
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2)
- {
- if ((chan1->ch_ieee == chan2->ch_ieee) &&
- (chan1->ch_freq_seg2 == chan2->ch_freq_seg2))
- return QDF_STATUS_SUCCESS;
- return QDF_STATUS_E_FAILURE;
- }
- void wlan_chan_copy(struct wlan_channel *tgt, struct wlan_channel *src)
- {
- qdf_mem_copy(tgt, src, sizeof(struct wlan_channel));
- }
- struct wlan_channel *wlan_vdev_get_active_channel(struct wlan_objmgr_vdev *vdev)
- {
- struct wlan_channel *comp_vdev_chan = NULL;
- if (wlan_vdev_chan_config_valid(vdev) == QDF_STATUS_SUCCESS) {
- /* compare with BSS channel, when vdev is active, since desired
- * channel gets update, if channel is triggered in another path
- */
- if (wlan_vdev_mlme_is_active(vdev) == QDF_STATUS_SUCCESS)
- comp_vdev_chan = wlan_vdev_mlme_get_bss_chan(vdev);
- else
- comp_vdev_chan = wlan_vdev_mlme_get_des_chan(vdev);
- }
- return comp_vdev_chan;
- }
- static void wlan_pdev_chan_match(struct wlan_objmgr_pdev *pdev, void *object,
- void *arg)
- {
- struct wlan_objmgr_vdev *comp_vdev = (struct wlan_objmgr_vdev *)object;
- struct wlan_vdev_ch_check_filter *ch_filter = arg;
- struct wlan_channel *vdev_chan;
- struct wlan_channel *iter_vdev_chan;
- if (ch_filter->flag)
- return;
- if (comp_vdev == ch_filter->vdev)
- return;
- wlan_vdev_obj_lock(comp_vdev);
- wlan_vdev_obj_lock(ch_filter->vdev);
- vdev_chan = wlan_vdev_get_active_channel(comp_vdev);
- if (vdev_chan) {
- iter_vdev_chan = wlan_vdev_mlme_get_des_chan(
- ch_filter->vdev);
- if (wlan_chan_eq(vdev_chan, iter_vdev_chan)
- != QDF_STATUS_SUCCESS) {
- ch_filter->flag = 1;
- qdf_nofl_err("==> iter vdev id: %d: ieee %d, mode %d",
- wlan_vdev_get_id(comp_vdev),
- vdev_chan->ch_ieee,
- vdev_chan->ch_phymode);
- qdf_nofl_err("fl %016llx, fl-ext %08x, s1 %d, s2 %d ",
- vdev_chan->ch_flags, vdev_chan->ch_flagext,
- vdev_chan->ch_freq_seg1,
- vdev_chan->ch_freq_seg2);
- qdf_nofl_err("==> base vdev id: %d: ieee %d mode %d",
- wlan_vdev_get_id(ch_filter->vdev),
- iter_vdev_chan->ch_ieee,
- iter_vdev_chan->ch_phymode);
- qdf_nofl_err("fl %016llx, fl-ext %08x s1 %d, s2 %d",
- iter_vdev_chan->ch_flags,
- iter_vdev_chan->ch_flagext,
- iter_vdev_chan->ch_freq_seg1,
- iter_vdev_chan->ch_freq_seg2);
- }
- }
- wlan_vdev_obj_unlock(ch_filter->vdev);
- wlan_vdev_obj_unlock(comp_vdev);
- }
- QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev,
- struct wlan_objmgr_vdev *vdev,
- wlan_objmgr_ref_dbgid dbg_id)
- {
- struct wlan_vdev_ch_check_filter ch_filter;
- if (!pdev)
- return QDF_STATUS_E_INVAL;
- if (wlan_pdev_nif_feat_cap_get(pdev, WLAN_PDEV_F_CHAN_CONCURRENCY))
- return QDF_STATUS_SUCCESS;
- if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == QDF_STATUS_SUCCESS) {
- ch_filter.flag = 0;
- ch_filter.vdev = vdev;
- wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
- wlan_pdev_chan_match,
- &ch_filter, 0, dbg_id);
- wlan_objmgr_vdev_release_ref(vdev, dbg_id);
- if (ch_filter.flag == 0)
- return QDF_STATUS_SUCCESS;
- }
- return QDF_STATUS_E_FAILURE;
- }
- static void wlan_vdev_restart_progress(struct wlan_objmgr_pdev *pdev,
- void *object, void *arg)
- {
- struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
- uint8_t *flag = (uint8_t *)arg;
- wlan_vdev_obj_lock(vdev);
- if (wlan_vdev_is_restart_progress(vdev) == QDF_STATUS_SUCCESS)
- *flag = 1;
- wlan_vdev_obj_unlock(vdev);
- }
- QDF_STATUS wlan_util_is_pdev_restart_progress(struct wlan_objmgr_pdev *pdev,
- wlan_objmgr_ref_dbgid dbg_id)
- {
- uint8_t flag = 0;
- if (!pdev)
- return QDF_STATUS_E_INVAL;
- wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
- wlan_vdev_restart_progress,
- &flag, 0, dbg_id);
- if (flag == 1)
- return QDF_STATUS_SUCCESS;
- return QDF_STATUS_E_INVAL;
- }
- static void wlan_vdev_scan_allowed(struct wlan_objmgr_pdev *pdev, void *object,
- void *arg)
- {
- struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
- uint8_t *flag = (uint8_t *)arg;
- wlan_vdev_obj_lock(vdev);
- if (wlan_vdev_mlme_is_scan_allowed(vdev) != QDF_STATUS_SUCCESS)
- *flag = 1;
- wlan_vdev_obj_unlock(vdev);
- }
- QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev,
- wlan_objmgr_ref_dbgid dbg_id)
- {
- uint8_t flag = 0;
- if (!pdev)
- return QDF_STATUS_E_INVAL;
- wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
- wlan_vdev_scan_allowed,
- &flag, 0, dbg_id);
- if (flag == 1)
- return QDF_STATUS_E_FAILURE;
- return QDF_STATUS_SUCCESS;
- }
- #else
- QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev,
- wlan_objmgr_ref_dbgid dbg_id)
- {
- return QDF_STATUS_SUCCESS;
- }
- #endif
- void
- wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr,
- int8_t *rssi)
- {
- uint32_t snr;
- if (db2dbm_enabled) {
- if (TGT_IS_VALID_RSSI(bcn_snr))
- *rssi = bcn_snr;
- else if (TGT_IS_VALID_RSSI(dat_snr))
- *rssi = dat_snr;
- else
- *rssi = TGT_NOISE_FLOOR_DBM;
- } else {
- if (TGT_IS_VALID_SNR(bcn_snr))
- snr = bcn_snr;
- else if (TGT_IS_VALID_SNR(dat_snr))
- snr = dat_snr;
- else
- snr = TGT_INVALID_SNR;
- /* Get the absolute rssi value from the current rssi value */
- *rssi = snr + TGT_NOISE_FLOOR_DBM;
- }
- }
|