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