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