1 /* 2 * Copyright (c) 2018-2019 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, void *ext_hdl) 50 { 51 struct vdev_mlme_obj *vdev_mlme; 52 53 if (!ext_hdl) { 54 mlme_err("Invalid input"); 55 return; 56 } 57 58 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 59 if (vdev_mlme) 60 vdev_mlme->ext_vdev_ptr = ext_hdl; 61 } 62 63 qdf_export_symbol(wlan_vdev_mlme_set_ext_hdl); 64 65 void *wlan_vdev_mlme_get_ext_hdl(struct wlan_objmgr_vdev *vdev) 66 { 67 struct vdev_mlme_obj *vdev_mlme; 68 69 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 70 if (vdev_mlme) 71 return vdev_mlme->ext_vdev_ptr; 72 73 return NULL; 74 } 75 76 qdf_export_symbol(wlan_vdev_mlme_get_ext_hdl); 77 78 #ifdef CMN_VDEV_MLME_SM_ENABLE 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) || 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_restart_progress(struct wlan_objmgr_vdev *vdev) 228 { 229 enum wlan_vdev_state state; 230 enum wlan_vdev_state substate; 231 232 state = wlan_vdev_mlme_get_state(vdev); 233 substate = wlan_vdev_mlme_get_substate(vdev); 234 if ((state == WLAN_VDEV_S_START) && 235 (substate == WLAN_VDEV_SS_START_RESTART_PROGRESS)) 236 return QDF_STATUS_SUCCESS; 237 238 return QDF_STATUS_E_FAILURE; 239 } 240 241 QDF_STATUS wlan_vdev_is_dfs_cac_wait(struct wlan_objmgr_vdev *vdev) 242 { 243 if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_CAC_WAIT) 244 return QDF_STATUS_SUCCESS; 245 246 return QDF_STATUS_E_FAILURE; 247 } 248 249 void wlan_vdev_mlme_cmd_lock(struct wlan_objmgr_vdev *vdev) 250 { 251 struct vdev_mlme_obj *vdev_mlme; 252 253 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 254 if (!vdev_mlme) { 255 mlme_err("vdev component object is NULL"); 256 return; 257 } 258 259 mlme_vdev_cmd_mutex_acquire(vdev_mlme); 260 } 261 262 void wlan_vdev_mlme_cmd_unlock(struct wlan_objmgr_vdev *vdev) 263 { 264 struct vdev_mlme_obj *vdev_mlme; 265 266 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 267 if (!vdev_mlme) { 268 mlme_err("vdev component object is NULL"); 269 return; 270 } 271 272 mlme_vdev_cmd_mutex_release(vdev_mlme); 273 } 274 275 QDF_STATUS wlan_vdev_mlme_is_scan_allowed(struct wlan_objmgr_vdev *vdev) 276 { 277 enum wlan_vdev_state state; 278 279 state = wlan_vdev_mlme_get_state(vdev); 280 if ((state == WLAN_VDEV_S_INIT) || (state == WLAN_VDEV_S_UP) || 281 (state == WLAN_VDEV_S_STOP)) 282 return QDF_STATUS_SUCCESS; 283 284 return QDF_STATUS_E_FAILURE; 285 } 286 #endif 287