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 QDF_STATUS wlan_vdev_mlme_sm_deliver_evt(struct wlan_objmgr_vdev *vdev, 79 enum wlan_vdev_sm_evt event, 80 uint16_t event_data_len, 81 void *event_data) 82 { 83 struct vdev_mlme_obj *vdev_mlme; 84 QDF_STATUS status; 85 enum wlan_vdev_state state_entry, state_exit; 86 enum wlan_vdev_state substate_entry, substate_exit; 87 88 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 89 if (!vdev_mlme) { 90 mlme_err("vdev component object is NULL"); 91 return QDF_STATUS_E_FAILURE; 92 } 93 94 mlme_vdev_sm_spin_lock(vdev_mlme); 95 96 /* store entry state and sub state for prints */ 97 state_entry = wlan_vdev_mlme_get_state(vdev); 98 substate_entry = wlan_vdev_mlme_get_substate(vdev); 99 mlme_vdev_sm_print_state_event(vdev_mlme, event); 100 101 status = mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len, 102 event_data); 103 /* Take exit state, exit substate for prints */ 104 state_exit = wlan_vdev_mlme_get_state(vdev); 105 substate_exit = wlan_vdev_mlme_get_substate(vdev); 106 /* If no state and substate change, don't print */ 107 if (!((state_entry == state_exit) && (substate_entry == substate_exit))) 108 mlme_vdev_sm_print_state(vdev_mlme); 109 mlme_vdev_sm_spin_unlock(vdev_mlme); 110 111 return status; 112 } 113 114 qdf_export_symbol(wlan_vdev_mlme_sm_deliver_evt); 115 116 QDF_STATUS wlan_vdev_mlme_sm_deliver_evt_sync(struct wlan_objmgr_vdev *vdev, 117 enum wlan_vdev_sm_evt event, 118 uint16_t event_data_len, 119 void *event_data) 120 { 121 struct vdev_mlme_obj *vdev_mlme; 122 QDF_STATUS status; 123 124 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 125 if (!vdev_mlme) { 126 mlme_err("vdev component object is NULL"); 127 return QDF_STATUS_E_FAILURE; 128 } 129 130 status = mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len, 131 event_data); 132 133 return status; 134 } 135 136 qdf_export_symbol(wlan_vdev_mlme_sm_deliver_evt_sync); 137 138 #ifdef SM_ENG_HIST_ENABLE 139 void wlan_vdev_mlme_sm_history_print(struct wlan_objmgr_vdev *vdev) 140 { 141 struct vdev_mlme_obj *vdev_mlme; 142 143 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 144 if (!vdev_mlme) { 145 mlme_err("vdev component object is NULL"); 146 return; 147 } 148 149 mlme_vdev_sm_history_print(vdev_mlme); 150 } 151 #endif 152 153 QDF_STATUS wlan_vdev_allow_connect_n_tx(struct wlan_objmgr_vdev *vdev) 154 { 155 enum wlan_vdev_state state; 156 enum wlan_vdev_state substate; 157 158 state = wlan_vdev_mlme_get_state(vdev); 159 substate = wlan_vdev_mlme_get_substate(vdev); 160 if ((state == WLAN_VDEV_S_UP) || 161 ((state == WLAN_VDEV_S_SUSPEND) && 162 (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART))) 163 return QDF_STATUS_SUCCESS; 164 165 return QDF_STATUS_E_FAILURE; 166 } 167 168 QDF_STATUS wlan_vdev_mlme_is_active(struct wlan_objmgr_vdev *vdev) 169 { 170 enum wlan_vdev_state state; 171 172 state = wlan_vdev_mlme_get_state(vdev); 173 if ((state == WLAN_VDEV_S_UP) || (state == WLAN_VDEV_S_DFS_CAC_WAIT) || 174 (state == WLAN_VDEV_S_SUSPEND)) 175 return QDF_STATUS_SUCCESS; 176 177 return QDF_STATUS_E_FAILURE; 178 } 179 180 qdf_export_symbol(wlan_vdev_mlme_is_active); 181 182 QDF_STATUS wlan_vdev_chan_config_valid(struct wlan_objmgr_vdev *vdev) 183 { 184 enum wlan_vdev_state state; 185 enum wlan_vdev_state substate; 186 187 state = wlan_vdev_mlme_get_state(vdev); 188 substate = wlan_vdev_mlme_get_substate(vdev); 189 if (!((state == WLAN_VDEV_S_INIT) || (state == WLAN_VDEV_S_STOP))) 190 return QDF_STATUS_SUCCESS; 191 192 return QDF_STATUS_E_FAILURE; 193 } 194 195 qdf_export_symbol(wlan_vdev_chan_config_valid); 196 197 QDF_STATUS wlan_vdev_mlme_is_csa_restart(struct wlan_objmgr_vdev *vdev) 198 { 199 enum wlan_vdev_state state; 200 enum wlan_vdev_state substate; 201 202 state = wlan_vdev_mlme_get_state(vdev); 203 substate = wlan_vdev_mlme_get_substate(vdev); 204 if ((state == WLAN_VDEV_S_SUSPEND) && 205 (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART)) 206 return QDF_STATUS_SUCCESS; 207 208 return QDF_STATUS_E_FAILURE; 209 } 210 211 QDF_STATUS wlan_vdev_is_going_down(struct wlan_objmgr_vdev *vdev) 212 { 213 enum wlan_vdev_state state; 214 enum wlan_vdev_state substate; 215 216 state = wlan_vdev_mlme_get_state(vdev); 217 substate = wlan_vdev_mlme_get_substate(vdev); 218 if ((state == WLAN_VDEV_S_STOP) || 219 ((state == WLAN_VDEV_S_SUSPEND) && 220 (substate == WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN))) 221 return QDF_STATUS_SUCCESS; 222 223 return QDF_STATUS_E_FAILURE; 224 } 225 226 QDF_STATUS wlan_vdev_is_restart_progress(struct wlan_objmgr_vdev *vdev) 227 { 228 enum wlan_vdev_state state; 229 enum wlan_vdev_state substate; 230 231 state = wlan_vdev_mlme_get_state(vdev); 232 substate = wlan_vdev_mlme_get_substate(vdev); 233 if ((state == WLAN_VDEV_S_START) && 234 (substate == WLAN_VDEV_SS_START_RESTART_PROGRESS)) 235 return QDF_STATUS_SUCCESS; 236 237 return QDF_STATUS_E_FAILURE; 238 } 239 240 QDF_STATUS wlan_vdev_is_dfs_cac_wait(struct wlan_objmgr_vdev *vdev) 241 { 242 if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_CAC_WAIT) 243 return QDF_STATUS_SUCCESS; 244 245 return QDF_STATUS_E_FAILURE; 246 } 247 248 void wlan_vdev_mlme_cmd_lock(struct wlan_objmgr_vdev *vdev) 249 { 250 struct vdev_mlme_obj *vdev_mlme; 251 252 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 253 if (!vdev_mlme) { 254 mlme_err("vdev component object is NULL"); 255 return; 256 } 257 258 mlme_vdev_cmd_mutex_acquire(vdev_mlme); 259 } 260 261 void wlan_vdev_mlme_cmd_unlock(struct wlan_objmgr_vdev *vdev) 262 { 263 struct vdev_mlme_obj *vdev_mlme; 264 265 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 266 if (!vdev_mlme) { 267 mlme_err("vdev component object is NULL"); 268 return; 269 } 270 271 mlme_vdev_cmd_mutex_release(vdev_mlme); 272 } 273 274 QDF_STATUS wlan_vdev_mlme_is_scan_allowed(struct wlan_objmgr_vdev *vdev) 275 { 276 enum wlan_vdev_state state; 277 278 state = wlan_vdev_mlme_get_state(vdev); 279 if ((state == WLAN_VDEV_S_INIT) || (state == WLAN_VDEV_S_UP) || 280 (state == WLAN_VDEV_S_STOP)) 281 return QDF_STATUS_SUCCESS; 282 283 return QDF_STATUS_E_FAILURE; 284 } 285