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: This file contains definition for mandatory legacy API 21 */ 22 23 #include "qdf_str.h" 24 #include "wlan_utility.h" 25 #include <wlan_cmn.h> 26 #include "wlan_osif_priv.h" 27 #include <net/cfg80211.h> 28 #include <qdf_module.h> 29 30 uint32_t wlan_chan_to_freq(uint8_t chan) 31 { 32 /* ch 0 - ch 13 */ 33 if (chan < WLAN_24_GHZ_CHANNEL_14) 34 return WLAN_24_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ; 35 else if (chan == WLAN_24_GHZ_CHANNEL_14) 36 return WLAN_CHAN_14_FREQ; 37 else if (chan < WLAN_24_GHZ_CHANNEL_27) 38 /* ch 15 - ch 26 */ 39 return WLAN_CHAN_15_FREQ + 40 (chan - WLAN_24_GHZ_CHANNEL_15) * WLAN_CHAN_SPACING_20MHZ; 41 else if (chan == WLAN_5_GHZ_CHANNEL_170) 42 return WLAN_CHAN_170_FREQ; 43 else 44 return WLAN_5_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ; 45 } 46 47 bool wlan_is_dsrc_channel(uint16_t center_freq) 48 { 49 if (center_freq >= 5852 && 50 center_freq <= 5920) 51 return true; 52 53 return false; 54 } 55 56 uint8_t wlan_freq_to_chan(uint32_t freq) 57 { 58 uint8_t chan; 59 60 if (freq > WLAN_24_GHZ_BASE_FREQ && freq < WLAN_CHAN_14_FREQ) 61 chan = ((freq - WLAN_24_GHZ_BASE_FREQ) / 62 WLAN_CHAN_SPACING_5MHZ); 63 else if (freq == WLAN_CHAN_14_FREQ) 64 chan = WLAN_24_GHZ_CHANNEL_14; 65 else if ((freq > WLAN_24_GHZ_BASE_FREQ) && 66 (freq < WLAN_5_GHZ_BASE_FREQ)) 67 chan = (((freq - WLAN_CHAN_15_FREQ) / 68 WLAN_CHAN_SPACING_20MHZ) + 69 WLAN_24_GHZ_CHANNEL_15); 70 else 71 chan = (freq - WLAN_5_GHZ_BASE_FREQ) / 72 WLAN_CHAN_SPACING_5MHZ; 73 74 return chan; 75 } 76 77 bool wlan_is_ie_valid(const uint8_t *ie, size_t ie_len) 78 { 79 uint8_t elen; 80 81 while (ie_len) { 82 if (ie_len < 2) 83 return false; 84 85 elen = ie[1]; 86 ie_len -= 2; 87 ie += 2; 88 if (elen > ie_len) 89 return false; 90 91 ie_len -= elen; 92 ie += elen; 93 } 94 95 return true; 96 } 97 98 static const uint8_t *wlan_get_ie_ptr_from_eid_n_oui(uint8_t eid, 99 const uint8_t *oui, 100 uint8_t oui_size, 101 const uint8_t *ie, 102 uint16_t ie_len) 103 { 104 int32_t left = ie_len; 105 const uint8_t *ptr = ie; 106 uint8_t elem_id, elem_len; 107 108 while (left >= 2) { 109 elem_id = ptr[0]; 110 elem_len = ptr[1]; 111 left -= 2; 112 113 if (elem_len > left) 114 return NULL; 115 116 if (eid == elem_id) { 117 /* if oui is not provide eid match is enough */ 118 if (!oui) 119 return ptr; 120 121 /* 122 * if oui is provided and oui_size is more than left 123 * bytes, then we cannot have match 124 */ 125 if (oui_size > left) 126 return NULL; 127 128 if (qdf_mem_cmp(&ptr[2], oui, oui_size) == 0) 129 return ptr; 130 } 131 132 left -= elem_len; 133 ptr += (elem_len + 2); 134 } 135 136 return NULL; 137 } 138 139 const uint8_t *wlan_get_ie_ptr_from_eid(uint8_t eid, 140 const uint8_t *ie, 141 int ie_len) 142 { 143 return wlan_get_ie_ptr_from_eid_n_oui(eid, NULL, 0, ie, ie_len); 144 } 145 146 const uint8_t *wlan_get_vendor_ie_ptr_from_oui(const uint8_t *oui, 147 uint8_t oui_size, 148 const uint8_t *ie, 149 uint16_t ie_len) 150 { 151 return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_VENDOR, 152 oui, oui_size, ie, ie_len); 153 } 154 155 const uint8_t *wlan_get_ext_ie_ptr_from_ext_id(const uint8_t *oui, 156 uint8_t oui_size, 157 const uint8_t *ie, 158 uint16_t ie_len) 159 { 160 return wlan_get_ie_ptr_from_eid_n_oui(WLAN_MAC_EID_EXT, 161 oui, oui_size, ie, ie_len); 162 } 163 164 bool wlan_is_emulation_platform(uint32_t phy_version) 165 { 166 if ((phy_version == 0xABC0) || (phy_version == 0xABC1) || 167 (phy_version == 0xABC2) || (phy_version == 0xABC3) || 168 (phy_version == 0xFFFF) || (phy_version == 0xABCD)) 169 return true; 170 171 return false; 172 } 173 174 uint32_t wlan_get_pdev_id_from_vdev_id(struct wlan_objmgr_psoc *psoc, 175 uint8_t vdev_id, 176 wlan_objmgr_ref_dbgid dbg_id) 177 { 178 struct wlan_objmgr_vdev *vdev; 179 struct wlan_objmgr_pdev *pdev = NULL; 180 uint32_t pdev_id = WLAN_INVALID_PDEV_ID; 181 182 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 183 vdev_id, dbg_id); 184 185 if (vdev) { 186 pdev = wlan_vdev_get_pdev(vdev); 187 if (pdev) 188 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 189 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 190 } 191 192 return pdev_id; 193 } 194 qdf_export_symbol(wlan_get_pdev_id_from_vdev_id); 195 196 static void wlan_util_get_vdev_by_ifname_cb(struct wlan_objmgr_psoc *psoc, 197 void *obj, void *arg) 198 { 199 struct wlan_objmgr_vdev *vdev = obj; 200 struct wlan_find_vdev_filter *filter = arg; 201 202 if (filter->found_vdev) 203 return; 204 205 wlan_vdev_obj_lock(vdev); 206 if (!qdf_str_cmp(vdev->vdev_nif.osdev->wdev->netdev->name, 207 filter->ifname)) { 208 filter->found_vdev = vdev; 209 } 210 wlan_vdev_obj_unlock(vdev); 211 } 212 213 struct wlan_objmgr_vdev *wlan_util_get_vdev_by_ifname( 214 struct wlan_objmgr_psoc *psoc, char *ifname, 215 wlan_objmgr_ref_dbgid ref_id) 216 { 217 QDF_STATUS status; 218 struct wlan_find_vdev_filter filter = {0}; 219 220 filter.ifname = ifname; 221 wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, 222 wlan_util_get_vdev_by_ifname_cb, 223 &filter, 0, ref_id); 224 225 if (!filter.found_vdev) 226 return NULL; 227 228 status = wlan_objmgr_vdev_try_get_ref(filter.found_vdev, ref_id); 229 if (QDF_IS_STATUS_ERROR(status)) 230 return NULL; 231 232 return filter.found_vdev; 233 } 234 235 /** 236 * wlan_util_vdev_get_if_name() - get vdev's interface name 237 * @vdev: VDEV object 238 * 239 * API to get vdev's interface name 240 * 241 * Return: 242 * @id: vdev's interface name 243 */ 244 uint8_t *wlan_util_vdev_get_if_name(struct wlan_objmgr_vdev *vdev) 245 { 246 uint8_t *name; 247 struct vdev_osif_priv *osif_priv; 248 249 wlan_vdev_obj_lock(vdev); 250 251 osif_priv = wlan_vdev_get_ospriv(vdev); 252 if (!osif_priv) { 253 wlan_vdev_obj_unlock(vdev); 254 return NULL; 255 } 256 257 if (!osif_priv->wdev) { 258 wlan_vdev_obj_unlock(vdev); 259 return NULL; 260 } 261 262 name = osif_priv->wdev->netdev->name; 263 wlan_vdev_obj_unlock(vdev); 264 265 return name; 266 } 267 qdf_export_symbol(wlan_util_vdev_get_if_name); 268 269 static void wlan_vap_active(struct wlan_objmgr_pdev *pdev, 270 void *object, 271 void *arg) 272 { 273 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 274 uint8_t *flag = (uint8_t *)arg; 275 276 wlan_vdev_obj_lock(vdev); 277 if ((wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_RUN) || 278 (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_WAIT)) { 279 *flag = 1; 280 } 281 wlan_vdev_obj_unlock(vdev); 282 } 283 284 QDF_STATUS wlan_util_is_vap_active(struct wlan_objmgr_pdev *pdev) 285 { 286 uint8_t flag = 0; 287 288 if (!pdev) 289 return QDF_STATUS_E_INVAL; 290 291 wlan_objmgr_pdev_iterate_obj_list(pdev, 292 WLAN_VDEV_OP, 293 wlan_vap_active, 294 &flag, 0, WLAN_OBJMGR_ID); 295 296 if (flag == 1) 297 return QDF_STATUS_SUCCESS; 298 299 return QDF_STATUS_E_INVAL; 300 } 301