1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: Functions to call mlme functions from DFS component. 22 */ 23 24 #include "wlan_dfs_mlme_api.h" 25 #include "wlan_objmgr_vdev_obj.h" 26 #include "wlan_objmgr_pdev_obj.h" 27 #include "../../core/src/dfs.h" 28 #include "scheduler_api.h" 29 #include <wlan_reg_ucfg_api.h> 30 #ifdef MOBILE_DFS_SUPPORT 31 #include "wni_api.h" 32 #endif 33 34 #if defined(QCA_DFS_RCSA_SUPPORT) 35 void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev, 36 bool *wait_for_csa) 37 { 38 if (global_dfs_to_mlme.dfs_start_rcsa) 39 global_dfs_to_mlme.dfs_start_rcsa(pdev, wait_for_csa); 40 } 41 #endif 42 43 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 44 void dfs_mlme_proc_spoof_success(struct wlan_objmgr_pdev *pdev) 45 { 46 if (global_dfs_to_mlme.mlme_proc_spoof_success) 47 global_dfs_to_mlme.mlme_proc_spoof_success(pdev); 48 } 49 #endif 50 51 #ifndef MOBILE_DFS_SUPPORT 52 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, 53 uint8_t ieee, 54 uint16_t freq, 55 uint16_t vhtop_ch_freq_seg2, 56 uint64_t flags) 57 { 58 if (global_dfs_to_mlme.mlme_mark_dfs) 59 global_dfs_to_mlme.mlme_mark_dfs(pdev, 60 ieee, 61 freq, 62 vhtop_ch_freq_seg2, 63 flags); 64 } 65 #else /* Else of ndef MCL_DFS_SUPPORT */ 66 static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev, 67 void *object, 68 void *arg) 69 { 70 struct scheduler_msg sme_msg = {0}; 71 uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object); 72 73 sme_msg.type = eWNI_SME_DFS_RADAR_FOUND; 74 sme_msg.bodyptr = NULL; 75 sme_msg.bodyval = vdev_id; 76 scheduler_post_message(QDF_MODULE_ID_DFS, 77 QDF_MODULE_ID_SME, 78 QDF_MODULE_ID_SME, &sme_msg); 79 dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted", 80 vdev_id); 81 } 82 83 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, 84 uint8_t ieee, 85 uint16_t freq, 86 uint16_t vhtop_ch_freq_seg2, 87 uint64_t flags) 88 { 89 struct wlan_objmgr_vdev *vdev; 90 91 if (!pdev) { 92 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 93 return; 94 } 95 96 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 97 98 if (vdev) { 99 dfs_send_radar_ind(pdev, vdev, NULL); 100 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 101 } 102 } 103 #endif 104 105 #ifndef MOBILE_DFS_SUPPORT 106 #ifdef CONFIG_CHAN_FREQ_API 107 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, 108 uint8_t ieee_chan, uint16_t freq, 109 uint16_t cfreq2, uint64_t flags) 110 { 111 if (global_dfs_to_mlme.mlme_start_csa_for_freq) 112 global_dfs_to_mlme.mlme_start_csa_for_freq(pdev, ieee_chan, 113 freq, cfreq2, flags); 114 } 115 #endif 116 #else 117 #ifdef CONFIG_CHAN_FREQ_API 118 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, 119 uint8_t ieee_chan, uint16_t freq, 120 uint16_t cfreq2, uint64_t flags) 121 { 122 struct wlan_objmgr_vdev *vdev; 123 124 if (!pdev) { 125 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 126 return; 127 } 128 129 vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); 130 131 if (vdev) { 132 dfs_send_radar_ind(pdev, vdev, NULL); 133 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 134 } 135 } 136 #endif 137 #endif 138 139 #ifndef MOBILE_DFS_SUPPORT 140 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 141 { 142 if (global_dfs_to_mlme.mlme_proc_cac) 143 global_dfs_to_mlme.mlme_proc_cac(pdev); 144 } 145 #else 146 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 147 { 148 struct scheduler_msg sme_msg = {0}; 149 150 sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE; 151 sme_msg.bodyptr = NULL; 152 sme_msg.bodyval = vdev_id; 153 scheduler_post_message(QDF_MODULE_ID_DFS, 154 QDF_MODULE_ID_SME, 155 QDF_MODULE_ID_SME, &sme_msg); 156 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_CAC_COMPLETE vdev%d posted", 157 vdev_id); 158 } 159 #endif 160 161 void dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev *pdev) 162 { 163 if (global_dfs_to_mlme.mlme_deliver_event_up_after_cac) 164 global_dfs_to_mlme.mlme_deliver_event_up_after_cac( 165 pdev); 166 } 167 168 #ifdef CONFIG_CHAN_FREQ_API 169 QDF_STATUS dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev *pdev, 170 uint16_t *dfs_chan_freq, 171 uint64_t *dfs_chan_flags, 172 uint16_t *dfs_chan_flagext, 173 uint8_t *dfs_chan_ieee, 174 uint8_t *dfs_chan_vhtop_ch_freq_seg1, 175 uint8_t *dfs_chan_vhtop_ch_freq_seg2, 176 uint16_t *dfs_chan_mhz_freq_seg1, 177 uint16_t *dfs_chan_mhz_freq_seg2) 178 { 179 if (global_dfs_to_mlme.mlme_get_extchan_for_freq) 180 return global_dfs_to_mlme.mlme_get_extchan_for_freq(pdev, 181 dfs_chan_freq, 182 dfs_chan_flags, 183 dfs_chan_flagext, 184 dfs_chan_ieee, 185 dfs_chan_vhtop_ch_freq_seg1, 186 dfs_chan_vhtop_ch_freq_seg2, 187 dfs_chan_mhz_freq_seg1, 188 dfs_chan_mhz_freq_seg2); 189 190 return QDF_STATUS_E_FAILURE; 191 } 192 #endif 193 194 void dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev *pdev, 195 int val) 196 { 197 if (global_dfs_to_mlme.mlme_set_no_chans_available) 198 global_dfs_to_mlme.mlme_set_no_chans_available( 199 pdev, 200 val); 201 } 202 203 int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag) 204 { 205 int freq = 0; 206 207 if (global_dfs_to_mlme.mlme_ieee2mhz) 208 global_dfs_to_mlme.mlme_ieee2mhz(pdev, 209 ieee, 210 flag, 211 &freq); 212 213 return freq; 214 } 215 216 #ifdef CONFIG_CHAN_FREQ_API 217 QDF_STATUS 218 dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev *pdev, 219 uint16_t freq, 220 uint16_t des_cfreq2, 221 int mode, 222 uint16_t *dfs_chan_freq, 223 uint64_t *dfs_chan_flag, 224 uint16_t *dfs_flagext, 225 uint8_t *dfs_chan_ieee, 226 uint8_t *dfs_cfreq1, 227 uint8_t *dfs_cfreq2, 228 uint16_t *cfreq1_mhz, 229 uint16_t *cfreq2_mhz) 230 { 231 if (global_dfs_to_mlme.mlme_find_dot11_chan_for_freq) 232 return global_dfs_to_mlme.mlme_find_dot11_chan_for_freq(pdev, 233 freq, 234 des_cfreq2, 235 mode, 236 dfs_chan_freq, 237 dfs_chan_flag, 238 dfs_flagext, 239 dfs_chan_ieee, 240 dfs_cfreq1, 241 dfs_cfreq2, 242 cfreq1_mhz, 243 cfreq2_mhz); 244 return QDF_STATUS_E_FAILURE; 245 } 246 #endif 247 248 249 uint32_t dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev *pdev) 250 { 251 uint16_t flag_ext = 0; 252 253 if (global_dfs_to_mlme.mlme_dfs_ch_flags_ext) 254 global_dfs_to_mlme.mlme_dfs_ch_flags_ext(pdev, 255 &flag_ext); 256 257 return flag_ext; 258 } 259 260 void dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev *pdev) 261 { 262 if (global_dfs_to_mlme.mlme_channel_change_by_precac) 263 global_dfs_to_mlme.mlme_channel_change_by_precac( 264 pdev); 265 } 266 267 void dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev *pdev) 268 { 269 if (global_dfs_to_mlme.mlme_nol_timeout_notification) 270 global_dfs_to_mlme.mlme_nol_timeout_notification( 271 pdev); 272 } 273 274 void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev, 275 void *nollist, 276 int nentries) 277 { 278 if (global_dfs_to_mlme.mlme_clist_update) 279 global_dfs_to_mlme.mlme_clist_update(pdev, 280 nollist, 281 nentries); 282 } 283 284 #ifdef CONFIG_CHAN_FREQ_API 285 int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev, 286 uint16_t dfs_chan_freq, 287 uint16_t dfs_cfreq2, 288 uint64_t dfs_ch_flags) 289 { 290 int cac_timeout = 0; 291 292 if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq) 293 global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev, 294 dfs_chan_freq, 295 dfs_cfreq2, 296 dfs_ch_flags, 297 &cac_timeout); 298 299 return cac_timeout; 300 } 301 #endif 302 303 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 304 int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( 305 struct wlan_objmgr_pdev *pdev) 306 { 307 if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels) 308 return 1; 309 310 return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels( 311 pdev); 312 } 313 314 void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, 315 int no_chans_avail) 316 { 317 if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan) 318 return; 319 320 global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev, 321 no_chans_avail); 322 } 323 #endif 324 325 #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN) 326 bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, 327 uint32_t chan_freq) 328 { 329 if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist) 330 return true; 331 332 return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev, 333 chan_freq); 334 } 335 336 #endif 337 338 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 339 void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) 340 { 341 bool dfs_enable = 0; 342 343 /*Disable all DFS channels in master channel list and ic channel list */ 344 ucfg_reg_enable_dfs_channels(pdev, dfs_enable); 345 346 /* send the updated channel list to FW */ 347 global_dfs_to_mlme.mlme_update_scan_channel_list(pdev); 348 } 349 #endif 350 351 bool dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev *pdev) 352 { 353 if (!global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed) 354 return false; 355 356 return global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed(pdev); 357 } 358 359 bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev) 360 { 361 if (!global_dfs_to_mlme.mlme_is_opmode_sta) 362 return false; 363 364 return global_dfs_to_mlme.mlme_is_opmode_sta(pdev); 365 } 366