1 /* 2 * Copyright (c) 2016-2019 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 QCA_MCL_DFS_SUPPORT 31 #include "wni_api.h" 32 #endif 33 34 void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev, 35 bool *wait_for_csa) 36 { 37 if (global_dfs_to_mlme.dfs_start_rcsa != NULL) 38 global_dfs_to_mlme.dfs_start_rcsa(pdev, wait_for_csa); 39 } 40 41 #ifndef QCA_MCL_DFS_SUPPORT 42 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, 43 uint8_t ieee, 44 uint16_t freq, 45 uint8_t vhtop_ch_freq_seg2, 46 uint64_t flags) 47 { 48 if (global_dfs_to_mlme.mlme_mark_dfs != NULL) 49 global_dfs_to_mlme.mlme_mark_dfs(pdev, 50 ieee, 51 freq, 52 vhtop_ch_freq_seg2, 53 flags); 54 } 55 #else 56 static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev, 57 void *object, 58 void *arg) 59 { 60 struct scheduler_msg sme_msg = {0}; 61 uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object); 62 63 sme_msg.type = eWNI_SME_DFS_RADAR_FOUND; 64 sme_msg.bodyptr = NULL; 65 sme_msg.bodyval = vdev_id; 66 scheduler_post_message(QDF_MODULE_ID_DFS, 67 QDF_MODULE_ID_SME, 68 QDF_MODULE_ID_SME, &sme_msg); 69 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted", 70 vdev_id); 71 } 72 73 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, 74 uint8_t ieee, 75 uint16_t freq, 76 uint8_t vhtop_ch_freq_seg2, 77 uint64_t flags) 78 { 79 if (!pdev) { 80 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 81 return; 82 } 83 84 wlan_objmgr_pdev_iterate_obj_list(pdev, 85 WLAN_VDEV_OP, 86 dfs_send_radar_ind, 87 NULL, 0, WLAN_DFS_ID); 88 } 89 #endif 90 91 #ifndef QCA_MCL_DFS_SUPPORT 92 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, 93 uint8_t ieee_chan, uint16_t freq, 94 uint8_t cfreq2, uint64_t flags) 95 { 96 if (global_dfs_to_mlme.mlme_start_csa != NULL) 97 global_dfs_to_mlme.mlme_start_csa(pdev, ieee_chan, freq, cfreq2, 98 flags); 99 } 100 #else 101 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, 102 uint8_t ieee_chan, uint16_t freq, 103 uint8_t cfreq2, uint64_t flags) 104 { 105 if (!pdev) { 106 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); 107 return; 108 } 109 110 wlan_objmgr_pdev_iterate_obj_list(pdev, 111 WLAN_VDEV_OP, 112 dfs_send_radar_ind, 113 NULL, 0, WLAN_DFS_ID); 114 } 115 #endif 116 117 #ifndef QCA_MCL_DFS_SUPPORT 118 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 119 { 120 if (global_dfs_to_mlme.mlme_proc_cac != NULL) 121 global_dfs_to_mlme.mlme_proc_cac(pdev); 122 } 123 #else 124 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) 125 { 126 struct scheduler_msg sme_msg = {0}; 127 128 sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE; 129 sme_msg.bodyptr = NULL; 130 sme_msg.bodyval = vdev_id; 131 scheduler_post_message(QDF_MODULE_ID_DFS, 132 QDF_MODULE_ID_SME, 133 QDF_MODULE_ID_SME, &sme_msg); 134 dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_CAC_COMPLETE vdev%d posted", 135 vdev_id); 136 } 137 #endif 138 139 void dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev *pdev) 140 { 141 if (global_dfs_to_mlme.mlme_deliver_event_up_after_cac) 142 global_dfs_to_mlme.mlme_deliver_event_up_after_cac( 143 pdev); 144 } 145 146 void dfs_mlme_get_dfs_ch_nchans(struct wlan_objmgr_pdev *pdev, 147 int *nchans) 148 { 149 if (global_dfs_to_mlme.mlme_get_dfs_ch_nchans != NULL) 150 global_dfs_to_mlme.mlme_get_dfs_ch_nchans(pdev, 151 nchans); 152 } 153 154 QDF_STATUS dfs_mlme_get_extchan(struct wlan_objmgr_pdev *pdev, 155 uint16_t *dfs_ch_freq, 156 uint64_t *dfs_ch_flags, 157 uint16_t *dfs_ch_flagext, 158 uint8_t *dfs_ch_ieee, 159 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 160 uint8_t *dfs_ch_vhtop_ch_freq_seg2) 161 { 162 if (global_dfs_to_mlme.mlme_get_extchan != NULL) 163 return global_dfs_to_mlme.mlme_get_extchan(pdev, 164 dfs_ch_freq, 165 dfs_ch_flags, 166 dfs_ch_flagext, 167 dfs_ch_ieee, 168 dfs_ch_vhtop_ch_freq_seg1, 169 dfs_ch_vhtop_ch_freq_seg2); 170 171 return QDF_STATUS_E_FAILURE; 172 } 173 174 void dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev *pdev, 175 int val) 176 { 177 if (global_dfs_to_mlme.mlme_set_no_chans_available != NULL) 178 global_dfs_to_mlme.mlme_set_no_chans_available( 179 pdev, 180 val); 181 } 182 183 int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag) 184 { 185 int freq = 0; 186 187 if (global_dfs_to_mlme.mlme_ieee2mhz != NULL) 188 global_dfs_to_mlme.mlme_ieee2mhz(pdev, 189 ieee, 190 flag, 191 &freq); 192 193 return freq; 194 } 195 196 QDF_STATUS 197 dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev, 198 uint8_t ieee, 199 uint8_t des_cfreq2, 200 int mode, 201 uint16_t *dfs_ch_freq, 202 uint64_t *dfs_ch_flags, 203 uint16_t *dfs_ch_flagext, 204 uint8_t *dfs_ch_ieee, 205 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 206 uint8_t *dfs_ch_vhtop_ch_freq_seg2) 207 { 208 if (global_dfs_to_mlme.mlme_find_dot11_channel != NULL) 209 return global_dfs_to_mlme.mlme_find_dot11_channel(pdev, 210 ieee, 211 des_cfreq2, 212 mode, 213 dfs_ch_freq, 214 dfs_ch_flags, 215 dfs_ch_flagext, 216 dfs_ch_ieee, 217 dfs_ch_vhtop_ch_freq_seg1, 218 dfs_ch_vhtop_ch_freq_seg2); 219 return QDF_STATUS_E_FAILURE; 220 } 221 222 void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev, 223 uint16_t *dfs_ch_freq, 224 uint64_t *dfs_ch_flags, 225 uint16_t *dfs_ch_flagext, 226 uint8_t *dfs_ch_ieee, 227 uint8_t *dfs_ch_vhtop_ch_freq_seg1, 228 uint8_t *dfs_ch_vhtop_ch_freq_seg2, 229 int index) 230 { 231 if (global_dfs_to_mlme.mlme_get_dfs_ch_channels != NULL) 232 global_dfs_to_mlme.mlme_get_dfs_ch_channels(pdev, 233 dfs_ch_freq, 234 dfs_ch_flags, 235 dfs_ch_flagext, 236 dfs_ch_ieee, 237 dfs_ch_vhtop_ch_freq_seg1, 238 dfs_ch_vhtop_ch_freq_seg2, 239 index); 240 } 241 242 uint32_t dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev *pdev) 243 { 244 uint16_t flag_ext = 0; 245 246 if (global_dfs_to_mlme.mlme_dfs_ch_flags_ext != NULL) 247 global_dfs_to_mlme.mlme_dfs_ch_flags_ext(pdev, 248 &flag_ext); 249 250 return flag_ext; 251 } 252 253 void dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev *pdev) 254 { 255 if (global_dfs_to_mlme.mlme_channel_change_by_precac != NULL) 256 global_dfs_to_mlme.mlme_channel_change_by_precac( 257 pdev); 258 } 259 260 void dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev *pdev) 261 { 262 if (global_dfs_to_mlme.mlme_nol_timeout_notification != NULL) 263 global_dfs_to_mlme.mlme_nol_timeout_notification( 264 pdev); 265 } 266 267 void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev, 268 void *nollist, 269 int nentries) 270 { 271 if (global_dfs_to_mlme.mlme_clist_update != NULL) 272 global_dfs_to_mlme.mlme_clist_update(pdev, 273 nollist, 274 nentries); 275 } 276 277 int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev, 278 uint16_t dfs_ch_freq, 279 uint8_t dfs_ch_vhtop_ch_freq_seg2, 280 uint64_t dfs_ch_flags) 281 { 282 int cac_timeout = 0; 283 284 if (global_dfs_to_mlme.mlme_get_cac_timeout != NULL) 285 global_dfs_to_mlme.mlme_get_cac_timeout(pdev, 286 dfs_ch_freq, 287 dfs_ch_vhtop_ch_freq_seg2, 288 dfs_ch_flags, 289 &cac_timeout); 290 291 return cac_timeout; 292 } 293 294 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 295 int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( 296 struct wlan_objmgr_pdev *pdev) 297 { 298 if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels) 299 return 1; 300 301 return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels( 302 pdev); 303 } 304 305 void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, 306 int no_chans_avail) 307 { 308 if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan) 309 return; 310 311 global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev, 312 no_chans_avail); 313 } 314 #endif 315 316 #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN) 317 bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, 318 uint32_t chan_num) 319 { 320 if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist) 321 return true; 322 323 return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev, 324 chan_num); 325 } 326 327 #endif 328 329 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) 330 void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) 331 { 332 bool dfs_enable = 0; 333 334 /*Disable all DFS channels in master channel list and ic channel list */ 335 ucfg_reg_enable_dfs_channels(pdev, dfs_enable); 336 337 /* send the updated channel list to FW */ 338 global_dfs_to_mlme.mlme_update_scan_channel_list(pdev); 339 } 340 #endif 341 342 bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev) 343 { 344 if (!global_dfs_to_mlme.mlme_is_opmode_sta) 345 return false; 346 347 return global_dfs_to_mlme.mlme_is_opmode_sta(pdev); 348 } 349