1 /* 2 * Copyright (c) 2018-2019, 2021 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: Implements VDEV MLME public APIs 19 */ 20 21 #include <wlan_objmgr_vdev_obj.h> 22 #include <wlan_mlme_dbg.h> 23 #include "include/wlan_vdev_mlme.h" 24 #include "../../core/src/vdev_mlme_sm.h" 25 #include <wlan_vdev_mlme_api.h> 26 #include <qdf_module.h> 27 28 struct vdev_mlme_obj *wlan_vdev_mlme_get_cmpt_obj(struct wlan_objmgr_vdev *vdev) 29 { 30 struct vdev_mlme_obj *vdev_mlme; 31 32 if (!vdev) { 33 mlme_err("vdev is NULL"); 34 return NULL; 35 } 36 37 vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(vdev, 38 WLAN_UMAC_COMP_MLME); 39 if (!vdev_mlme) { 40 mlme_err(" MLME component object is NULL"); 41 return NULL; 42 } 43 44 return vdev_mlme; 45 } 46 47 qdf_export_symbol(wlan_vdev_mlme_get_cmpt_obj); 48 49 void wlan_vdev_mlme_set_ext_hdl(struct wlan_objmgr_vdev *vdev, 50 mlme_vdev_ext_t *ext_hdl) 51 { 52 struct vdev_mlme_obj *vdev_mlme; 53 54 if (!ext_hdl) { 55 mlme_err("Invalid input"); 56 return; 57 } 58 59 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 60 if (vdev_mlme) 61 vdev_mlme->ext_vdev_ptr = ext_hdl; 62 } 63 64 qdf_export_symbol(wlan_vdev_mlme_set_ext_hdl); 65 66 mlme_vdev_ext_t *wlan_vdev_mlme_get_ext_hdl(struct wlan_objmgr_vdev *vdev) 67 { 68 struct vdev_mlme_obj *vdev_mlme; 69 70 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 71 if (vdev_mlme) 72 return vdev_mlme->ext_vdev_ptr; 73 74 return NULL; 75 } 76 77 qdf_export_symbol(wlan_vdev_mlme_get_ext_hdl); 78 79 QDF_STATUS wlan_vdev_mlme_sm_deliver_evt(struct wlan_objmgr_vdev *vdev, 80 enum wlan_vdev_sm_evt event, 81 uint16_t event_data_len, 82 void *event_data) 83 { 84 struct vdev_mlme_obj *vdev_mlme; 85 QDF_STATUS status; 86 enum wlan_vdev_state state_entry, state_exit; 87 enum wlan_vdev_state substate_entry, substate_exit; 88 89 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 90 if (!vdev_mlme) { 91 mlme_err("vdev component object is NULL"); 92 return QDF_STATUS_E_FAILURE; 93 } 94 95 mlme_vdev_sm_spin_lock(vdev_mlme); 96 97 /* store entry state and sub state for prints */ 98 state_entry = wlan_vdev_mlme_get_state(vdev); 99 substate_entry = wlan_vdev_mlme_get_substate(vdev); 100 mlme_vdev_sm_print_state_event(vdev_mlme, event); 101 102 status = mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len, 103 event_data); 104 /* Take exit state, exit substate for prints */ 105 state_exit = wlan_vdev_mlme_get_state(vdev); 106 substate_exit = wlan_vdev_mlme_get_substate(vdev); 107 /* If no state and substate change, don't print */ 108 if (!((state_entry == state_exit) && (substate_entry == substate_exit))) 109 mlme_vdev_sm_print_state(vdev_mlme); 110 mlme_vdev_sm_spin_unlock(vdev_mlme); 111 112 return status; 113 } 114 115 qdf_export_symbol(wlan_vdev_mlme_sm_deliver_evt); 116 117 QDF_STATUS wlan_vdev_mlme_sm_deliver_evt_sync(struct wlan_objmgr_vdev *vdev, 118 enum wlan_vdev_sm_evt event, 119 uint16_t event_data_len, 120 void *event_data) 121 { 122 struct vdev_mlme_obj *vdev_mlme; 123 QDF_STATUS status; 124 125 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 126 if (!vdev_mlme) { 127 mlme_err("vdev component object is NULL"); 128 return QDF_STATUS_E_FAILURE; 129 } 130 131 status = mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len, 132 event_data); 133 134 return status; 135 } 136 137 qdf_export_symbol(wlan_vdev_mlme_sm_deliver_evt_sync); 138 139 #ifdef SM_ENG_HIST_ENABLE 140 void wlan_vdev_mlme_sm_history_print(struct wlan_objmgr_vdev *vdev) 141 { 142 struct vdev_mlme_obj *vdev_mlme; 143 144 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 145 if (!vdev_mlme) { 146 mlme_err("vdev component object is NULL"); 147 return; 148 } 149 150 mlme_vdev_sm_history_print(vdev_mlme); 151 } 152 #endif 153 154 QDF_STATUS wlan_vdev_allow_connect_n_tx(struct wlan_objmgr_vdev *vdev) 155 { 156 enum wlan_vdev_state state; 157 enum wlan_vdev_state substate; 158 159 state = wlan_vdev_mlme_get_state(vdev); 160 substate = wlan_vdev_mlme_get_substate(vdev); 161 if ((state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_UP_ACTIVE) || 162 ((state == WLAN_VDEV_S_SUSPEND) && 163 (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART))) 164 return QDF_STATUS_SUCCESS; 165 166 return QDF_STATUS_E_FAILURE; 167 } 168 169 QDF_STATUS wlan_vdev_mlme_is_active(struct wlan_objmgr_vdev *vdev) 170 { 171 enum wlan_vdev_state state; 172 173 state = wlan_vdev_mlme_get_state(vdev); 174 if ((state == WLAN_VDEV_S_UP) || (state == WLAN_VDEV_S_DFS_CAC_WAIT) || 175 (state == WLAN_VDEV_S_SUSPEND)) 176 return QDF_STATUS_SUCCESS; 177 178 return QDF_STATUS_E_FAILURE; 179 } 180 181 qdf_export_symbol(wlan_vdev_mlme_is_active); 182 183 QDF_STATUS wlan_vdev_chan_config_valid(struct wlan_objmgr_vdev *vdev) 184 { 185 enum wlan_vdev_state state; 186 enum wlan_vdev_state substate; 187 188 state = wlan_vdev_mlme_get_state(vdev); 189 substate = wlan_vdev_mlme_get_substate(vdev); 190 if (!((state == WLAN_VDEV_S_INIT) || (state == WLAN_VDEV_S_STOP))) 191 return QDF_STATUS_SUCCESS; 192 193 return QDF_STATUS_E_FAILURE; 194 } 195 196 qdf_export_symbol(wlan_vdev_chan_config_valid); 197 198 QDF_STATUS wlan_vdev_mlme_is_csa_restart(struct wlan_objmgr_vdev *vdev) 199 { 200 enum wlan_vdev_state state; 201 enum wlan_vdev_state substate; 202 203 state = wlan_vdev_mlme_get_state(vdev); 204 substate = wlan_vdev_mlme_get_substate(vdev); 205 if ((state == WLAN_VDEV_S_SUSPEND) && 206 (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART)) 207 return QDF_STATUS_SUCCESS; 208 209 return QDF_STATUS_E_FAILURE; 210 } 211 212 QDF_STATUS wlan_vdev_is_going_down(struct wlan_objmgr_vdev *vdev) 213 { 214 enum wlan_vdev_state state; 215 enum wlan_vdev_state substate; 216 217 state = wlan_vdev_mlme_get_state(vdev); 218 substate = wlan_vdev_mlme_get_substate(vdev); 219 if ((state == WLAN_VDEV_S_STOP) || 220 ((state == WLAN_VDEV_S_SUSPEND) && 221 (substate == WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN))) 222 return QDF_STATUS_SUCCESS; 223 224 return QDF_STATUS_E_FAILURE; 225 } 226 227 QDF_STATUS wlan_vdev_is_peer_create_allowed(struct wlan_objmgr_vdev *vdev) 228 { 229 enum wlan_vdev_state state; 230 enum wlan_vdev_state substate; 231 232 if (!vdev) { 233 mlme_err("vdev is null"); 234 return QDF_STATUS_E_FAILURE; 235 } 236 237 state = wlan_vdev_mlme_get_state(vdev); 238 substate = wlan_vdev_mlme_get_substate(vdev); 239 if (!((state == WLAN_VDEV_S_INIT) || 240 (state == WLAN_VDEV_S_STOP) || 241 ((state == WLAN_VDEV_S_SUSPEND) && 242 (substate == WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN)))) 243 return QDF_STATUS_SUCCESS; 244 245 return QDF_STATUS_E_FAILURE; 246 } 247 248 QDF_STATUS wlan_vdev_is_restart_progress(struct wlan_objmgr_vdev *vdev) 249 { 250 enum wlan_vdev_state state; 251 enum wlan_vdev_state substate; 252 253 state = wlan_vdev_mlme_get_state(vdev); 254 substate = wlan_vdev_mlme_get_substate(vdev); 255 if ((state == WLAN_VDEV_S_START) && 256 (substate == WLAN_VDEV_SS_START_RESTART_PROGRESS)) 257 return QDF_STATUS_SUCCESS; 258 259 return QDF_STATUS_E_FAILURE; 260 } 261 262 QDF_STATUS wlan_vdev_is_dfs_cac_wait(struct wlan_objmgr_vdev *vdev) 263 { 264 if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_CAC_WAIT) 265 return QDF_STATUS_SUCCESS; 266 267 return QDF_STATUS_E_FAILURE; 268 } 269 270 void wlan_vdev_mlme_cmd_lock(struct wlan_objmgr_vdev *vdev) 271 { 272 struct vdev_mlme_obj *vdev_mlme; 273 274 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 275 if (!vdev_mlme) { 276 mlme_err("vdev component object is NULL"); 277 return; 278 } 279 280 mlme_vdev_cmd_mutex_acquire(vdev_mlme); 281 } 282 283 void wlan_vdev_mlme_cmd_unlock(struct wlan_objmgr_vdev *vdev) 284 { 285 struct vdev_mlme_obj *vdev_mlme; 286 287 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 288 if (!vdev_mlme) { 289 mlme_err("vdev component object is NULL"); 290 return; 291 } 292 293 mlme_vdev_cmd_mutex_release(vdev_mlme); 294 } 295 296 QDF_STATUS wlan_vdev_mlme_is_scan_allowed(struct wlan_objmgr_vdev *vdev) 297 { 298 enum wlan_vdev_state state; 299 enum wlan_vdev_state substate; 300 301 state = wlan_vdev_mlme_get_state(vdev); 302 substate = wlan_vdev_mlme_get_substate(vdev); 303 if ((state == WLAN_VDEV_S_INIT) || 304 (state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_UP_ACTIVE) || 305 (state == WLAN_VDEV_S_STOP)) 306 return QDF_STATUS_SUCCESS; 307 308 return QDF_STATUS_E_FAILURE; 309 } 310 311 QDF_STATUS wlan_vdev_mlme_is_init_state(struct wlan_objmgr_vdev *vdev) 312 { 313 enum wlan_vdev_state state; 314 315 state = wlan_vdev_mlme_get_state(vdev); 316 if (state == WLAN_VDEV_S_INIT) 317 return QDF_STATUS_SUCCESS; 318 319 return QDF_STATUS_E_FAILURE; 320 } 321 322 QDF_STATUS wlan_vdev_is_up_active_state(struct wlan_objmgr_vdev *vdev) 323 { 324 enum wlan_vdev_state state; 325 enum wlan_vdev_state substate; 326 327 state = wlan_vdev_mlme_get_state(vdev); 328 substate = wlan_vdev_mlme_get_substate(vdev); 329 if (state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_UP_ACTIVE) 330 return QDF_STATUS_SUCCESS; 331 332 return QDF_STATUS_E_FAILURE; 333 } 334