From 9375922ab214d0e4942db63ef6be8eb497dc3ee5 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 9 Jun 2020 23:45:50 +0530 Subject: [PATCH] qcacmn: Add basic infra for connection manager Add basic infra for connection mgr state machine to handle connect and disconnect requests. Change-Id: I671f62f66ab511912886c1da84c3a69be0032872 CRs-Fixed: 2707901 --- .../connection_mgr/core/src/wlan_cm_cmn.c | 19 + .../connection_mgr/core/src/wlan_cm_connect.c | 19 + .../core/src/wlan_cm_connect_scan.c | 20 + .../core/src/wlan_cm_disconnect.c | 19 + .../connection_mgr/core/src/wlan_cm_main.c | 64 ++ .../connection_mgr/core/src/wlan_cm_main.h | 353 ++++++++ .../core/src/wlan_cm_main_api.h | 26 + .../connection_mgr/core/src/wlan_cm_roam_sm.c | 178 ++++ .../connection_mgr/core/src/wlan_cm_roam_sm.h | 219 +++++ .../mlme/connection_mgr/core/src/wlan_cm_sm.c | 764 ++++++++++++++++++ .../mlme/connection_mgr/core/src/wlan_cm_sm.h | 237 ++++++ .../dispatcher/inc/wlan_cm_public_struct.h | 260 ++++++ umac/mlme/include/wlan_vdev_mlme.h | 5 + .../dispatcher/src/wlan_vdev_mlme_main.c | 9 + 14 files changed, 2192 insertions(+) create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_cmn.c create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_connect.c create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_connect_scan.c create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_main.c create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_main.h create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.h create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_sm.c create mode 100644 umac/mlme/connection_mgr/core/src/wlan_cm_sm.h create mode 100644 umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_cmn.c b/umac/mlme/connection_mgr/core/src/wlan_cm_cmn.c new file mode 100644 index 000000000000..2e16b9188f9e --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_cmn.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Implements general apis of connection manager + */ diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c b/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c new file mode 100644 index 000000000000..197896bc128a --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Implements connect specific APIs of connection manager + */ diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_connect_scan.c b/umac/mlme/connection_mgr/core/src/wlan_cm_connect_scan.c new file mode 100644 index 000000000000..c82ac3eaef73 --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_connect_scan.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Implements connect scan (scan for ssid) specific apis of + * connection manager + */ diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c b/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c new file mode 100644 index 000000000000..ae860f37d087 --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Implements disconnect specific apis of connection manager + */ diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_main.c b/umac/mlme/connection_mgr/core/src/wlan_cm_main.c new file mode 100644 index 000000000000..6db054ee0fa7 --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_main.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Implements init/deinit specific apis of connection manager + */ + +#include "wlan_cm_main.h" +#include "wlan_cm_sm.h" + +QDF_STATUS mlme_cm_init(struct vdev_mlme_obj *vdev_mlme) +{ + struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; + enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); + QDF_STATUS status; + + if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) + return QDF_STATUS_SUCCESS; + + vdev_mlme->cnx_mgr_ctx = qdf_mem_malloc(sizeof(struct cnx_mgr)); + if (!vdev_mlme->cnx_mgr_ctx) + return QDF_STATUS_E_NOMEM; + + vdev_mlme->cnx_mgr_ctx->vdev = vdev_mlme->vdev; + status = mlme_cm_sm_create(vdev_mlme->cnx_mgr_ctx); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("CM MLME SM allocation failed"); + qdf_mem_free(vdev_mlme->cnx_mgr_ctx); + vdev_mlme->cnx_mgr_ctx = NULL; + return QDF_STATUS_E_NOMEM; + } + qdf_list_create(&vdev_mlme->cnx_mgr_ctx->req_list, CM_MAX_REQ); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS mlme_cm_deinit(struct vdev_mlme_obj *vdev_mlme) +{ + struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; + enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); + + if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) + return QDF_STATUS_SUCCESS; + + qdf_list_destroy(&vdev_mlme->cnx_mgr_ctx->req_list); + mlme_cm_sm_destroy(vdev_mlme->cnx_mgr_ctx); + qdf_mem_free(vdev_mlme->cnx_mgr_ctx); + vdev_mlme->cnx_mgr_ctx = NULL; + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_main.h b/umac/mlme/connection_mgr/core/src/wlan_cm_main.h new file mode 100644 index 000000000000..6cbca061689e --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_main.h @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_cm_main.h + * + * This header file maintain structures required for connection mgr core + */ + +#ifndef __WLAN_CM_MAIN_H__ +#define __WLAN_CM_MAIN_H__ + +#include "include/wlan_vdev_mlme.h" + +#ifdef FEATURE_CM_ENABLE +#include + +/* Max candidate to be tried to connect */ +#define CM_MAX_CANDIDATE_TO_BE_TRIED 5 +/* Max time to wait for scan for SSID */ +#define CM_SCAN_MAX_TIME 5000 +/* Max connect/disconnect/roam req that can be queued at a time */ +#define CM_MAX_REQ 5 + +/** + * enum wlan_cm_sm_state - Connection manager states + * @WLAN_CM_S_INIT: Default state, IDLE state + * @WLAN_CM_S_CONNECTING: State when connect request comes + * @WLAN_CM_S_CONNECTED: State when connect is complete + * @WLAN_CM_S_DISCONNECTING: State when disconnect request comes + * @WLAN_CM_S_ROAMING: State when roaming is in progress + * @WLAN_CM_S_MAX: Max State + * @WLAN_CM_SS_IDLE: Idle state (no substate) + * @WLAN_CM_SS_JOIN_PENDING: Connect request not serialized + * @WLAN_CM_SS_SCAN: Scan for SSID state + * @WLAN_CM_SS_JOIN_ACTIVE: Conenct request activated + * @WLAN_CM_SS_PREAUTH: Roam substate of preauth stage + * @WLAN_CM_SS_REASSOC: Roam substate for reassoc state + * @WLAN_CM_SS_ROAM_STARTED: Roaming in progress (LFR 3.0) + * @WLAN_CM_SS_ROAM_SYNC: Roam sync indication from FW + * @WLAN_CM_SS_MAX: Max Substate + */ +enum wlan_cm_sm_state { + WLAN_CM_S_INIT = 0, + WLAN_CM_S_CONNECTING = 1, + WLAN_CM_S_CONNECTED = 2, + WLAN_CM_S_DISCONNECTING = 3, + WLAN_CM_S_ROAMING = 4, + WLAN_CM_S_MAX = 5, + WLAN_CM_SS_IDLE = 6, + WLAN_CM_SS_JOIN_PENDING = 7, + WLAN_CM_SS_SCAN = 8, + WLAN_CM_SS_JOIN_ACTIVE = 9, + WLAN_CM_SS_PREAUTH = 10, + WLAN_CM_SS_REASSOC = 11, + WLAN_CM_SS_ROAM_STARTED = 12, + WLAN_CM_SS_ROAM_SYNC = 13, + WLAN_CM_SS_MAX = 14, +}; + +/** + * enum wlan_cm_sm_evt - connection manager related events + * @WLAN_CM_SM_EV_CONNECT_REQ: Connect request event + * @WLAN_CM_SM_EV_SCAN_FOR_SSID: Event for scan for SSID + * @WLAN_CM_SM_EV_SCAN_FOR_SSID_SUCCESS: Scan for SSID success event + * @WLAN_CM_SM_EV_SCAN_FOR_SSID_FAILURE: Scan for SSID fail event + * @WLAN_CM_SM_EV_CONNECT_START_REQ: Connect start request after BSSID list + * is prepared + * @WLAN_CM_SM_EV_CONNECT_START: Connect request for a particular BSSID + * @WLAN_CM_SM_EV_CONNECT_SUCCESS: Connect success + * @WLAN_CM_SM_EV_CONNECT_NEXT_CANDIDATE: Select next candidate for connection + * @WLAN_CM_SM_EV_CONNECT_FAILURE: Connect failed event + * @WLAN_CM_SM_EV_DISCONNECT_REQ: Disconnect request event + * @WLAN_CM_SM_EV_DISCONNECT_START_REQ: Start disconnect sequence + * @WLAN_CM_SM_EV_DISCONNECT_START: Disconnect process start event + * @WLAN_CM_SM_EV_DISCONNECT_DONE: Disconnect done event + * @WLAN_CM_SM_EV_ROAM_START: Roam start event + * @WLAN_CM_SM_EV_ROAM_SYNC: Roam sync event + * @WLAN_CM_SM_EV_ROAM_INVOKE_FAIL: Roam invoke fail event + * @WLAN_CM_SM_EV_ROAM_HO_FAIL: Hand off failed event + * @WLAN_CM_SM_EV_PREAUTH_DONE: Preauth is completed + * @WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP: Get next candidate as preauth failed + * @WLAN_CM_SM_EV_PREAUTH_FAIL: Preauth failed for all candidate + * @WLAN_CM_SM_EV_START_REASSOC: Start reassoc after preauth done + * @WLAN_CM_SM_EV_REASSOC_DONE: Reassoc completed + * @WLAN_CM_SM_EV_REASSOC_FAILURE: Reassoc failed + * @WLAN_CM_SM_EV_ROAM_COMPLETE: Roaming completed + * @WLAN_CM_SM_EV_CONNECT_TIMEOUT: Connect timeout event + * @WLAN_CM_SM_EV_CONNECT_SER_FAIL: Connect request failed to serialize + * @WLAN_CM_SM_EV_HW_MODE_CHANGE_FAIL: HW mode change failed event + * @WLAN_CM_SM_EV_MAX: Max event + */ +enum wlan_cm_sm_evt { + WLAN_CM_SM_EV_CONNECT_REQ = 0, + WLAN_CM_SM_EV_SCAN_FOR_SSID = 1, + WLAN_CM_SM_EV_SCAN_FOR_SSID_SUCCESS = 2, + WLAN_CM_SM_EV_SCAN_FOR_SSID_FAILURE = 3, + WLAN_CM_SM_EV_CONNECT_START_REQ = 4, + WLAN_CM_SM_EV_CONNECT_START = 5, + WLAN_CM_SM_EV_CONNECT_SUCCESS = 6, + WLAN_CM_SM_EV_CONNECT_NEXT_CANDIDATE = 7, + WLAN_CM_SM_EV_CONNECT_FAILURE = 8, + WLAN_CM_SM_EV_DISCONNECT_REQ = 9, + WLAN_CM_SM_EV_DISCONNECT_START_REQ = 10, + WLAN_CM_SM_EV_DISCONNECT_START = 11, + WLAN_CM_SM_EV_DISCONNECT_DONE = 12, + WLAN_CM_SM_EV_ROAM_START = 13, + WLAN_CM_SM_EV_ROAM_SYNC = 14, + WLAN_CM_SM_EV_ROAM_INVOKE_FAIL = 15, + WLAN_CM_SM_EV_ROAM_HO_FAIL = 16, + WLAN_CM_SM_EV_PREAUTH_DONE = 17, + WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP = 18, + WLAN_CM_SM_EV_PREAUTH_FAIL = 19, + WLAN_CM_SM_EV_START_REASSOC = 20, + WLAN_CM_SM_EV_REASSOC_DONE = 21, + WLAN_CM_SM_EV_REASSOC_FAILURE = 22, + WLAN_CM_SM_EV_ROAM_COMPLETE = 23, + WLAN_CM_SM_EV_CONNECT_TIMEOUT = 24, + WLAN_CM_SM_EV_CONNECT_SER_FAIL = 25, + WLAN_CM_SM_EV_HW_MODE_CHANGE_FAIL = 26, + WLAN_CM_SM_EV_MAX, +}; + +/** + * struct cm_state_sm - connection manager sm + * @cm_sm_lock: sm lock + * @sm_hdl: sm handlers + * @cm_state: current state + * @cm_substate: current substate + */ +struct cm_state_sm { +#ifdef WLAN_CM_USE_SPINLOCK + qdf_spinlock_t cm_sm_lock; +#else + qdf_mutex_t cm_sm_lock; +#endif + struct wlan_sm *sm_hdl; + enum wlan_cm_sm_state cm_state; + enum wlan_cm_sm_state cm_substate; +}; + +/** + * struct cm_connect_req - connect req stored in connect manager + * @cm_id: Connect manager id + * @scan_id: scan id for scan for ssid + * @scan_timer: timer for scan for ssid to get completed + * @hw_mode_timer: timer for hw mode chane to get completed + * @req: connect req from osif + * @candidate_list: candidate list + * @cur_candidate: current candidate + */ +struct cm_connect_req { + uint64_t cm_id; + uint64_t scan_id; + qdf_timer_t scan_timer; + qdf_timer_t hw_mode_timer; + struct wlan_cm_connect_req req; + qdf_list_t candidate_list; + struct scan_cache_node *cur_candidate; +}; + +/** + * struct cm_disconnect_req - disconnect req + * @cm_id: Connect manager id + * @req: disconnect connect req from osif + */ +struct cm_disconnect_req { + uint64_t cm_id; + struct wlan_cm_disconnect_req req; +}; + +/** + * struct cm_req - connect manager req + * @node: connection manager req node + * @source: req source + * @cm_id: cm id + * @connect_req: connect req + * @disconnect_req: disconnect req + */ +struct cm_req { + qdf_list_node_t node; + enum wlan_cm_source source; + uint64_t cm_id; + union { + struct cm_connect_req connect_req; + struct cm_disconnect_req discon_req; + }; +}; + +/** + * struct connect_req_ies - connect req ies stored in vdev + * @additional_assoc_ie: assoc req additional IE to be appended to assoc req + * @auth_ft_ies: auth ft ies received during preauth phase + * @reassoc_ft_ies: reassoc ft ies received during reassoc phase + * @cck_ie: cck ie for cck connection + * @forced_rsn_ie: set if force_rsne_override is set from the connect IE. This + * is used to store the invalid RSN IE from suplicant to enable testbed STA for + * cert cases. + */ +struct connect_req_ies { + struct element_info additional_assoc_ie; + struct element_info auth_ft_ies; + struct element_info reassoc_ft_ies; + struct element_info cck_ie; + struct element_info forced_rsn_ie; +}; + +#ifdef WLAN_FEATURE_FILS_SK +#define CM_FILS_MAX_HLP_DATA_LEN 2048 +#define MAX_KEK_LENGTH 64 +#define MAX_TK_LENGTH 32 +#define MAX_GTK_LENGTH 255 + +/** + * struct fils_connect_rsp_params - fils related connect rsp params + * @fils_pmk: fils pmk + * @fils_pmk_len: fils pmk length + * @fils_pmkid: fils pmkid + * @kek: kek + * @kek_len: kek length + * @tk: tk + * @tk_len: tk length + * @gtk: gtk + * @gtk_len: gtk length + * @dst_mac: dst mac + * @src_mac: src mac + * @hlp_data: hlp data + * @hlp_data_len: hlp data length + */ +struct fils_connect_rsp_params { + uint8_t *fils_pmk; + uint8_t fils_pmk_len; + uint8_t fils_pmkid[PMKID_LEN]; + uint8_t kek[MAX_KEK_LENGTH]; + uint8_t kek_len; + uint8_t tk[MAX_TK_LENGTH]; + uint8_t tk_len; + uint8_t gtk[MAX_GTK_LENGTH]; + uint8_t gtk_len; + struct qdf_mac_addr dst_mac; + struct qdf_mac_addr src_mac; + uint8_t hlp_data[CM_FILS_MAX_HLP_DATA_LEN]; + uint16_t hlp_data_len; +}; +#endif + +/** + * struct connect_rsp_ies - connect rsp ies stored in vdev filled during connect + * @bcn_probe_rsp: beacon or probe rsp of connected AP + * @assoc_req: assoc req send during conenct + * @assoc_rsq: assoc rsp received during connection + * @ric_resp_ie: ric ie from assoc resp received during connection + * @fills_ie: fills connection ie received during connection + */ +struct connect_rsp_ies { + struct element_info bcn_probe_rsp; + struct element_info assoc_req; + struct element_info assoc_rsp; + struct element_info ric_resp_ie; +#ifdef WLAN_FEATURE_FILS_SK + struct fils_connect_rsp_params fils_ie; +#endif +}; + +/** + * struct disconnect_ies - disconnect ies stored in vdev filled during + * disconnect + * @peer_discon_ie: disconnect ie sent by peer to be sent to OSIF + * @self_discon_ie: disconnect ie to be sent in disassoc/deauth filled by OSIF + */ +struct disconnect_ies { + struct element_info peer_discon_ie; + struct element_info self_discon_ie; +}; + +/** + * struct cnx_mgr - connect manager req + * @vdev: vdev back pointer + * @sm: state machine + * @req_list: connect/disconnect req list + * @disconnect_count: disconnect count + * @connect_count: connect count + * @force_rsne_override: if QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE is set by + * framework + * @req_ie: request ies for connect + * @rsp_ie: connect resp ie + * @discon_ie: disconnect IE + * @fils_info: fils info for the connect req + */ +struct cnx_mgr { + struct wlan_objmgr_vdev *vdev; + struct cm_state_sm sm; + qdf_list_t req_list; + uint8_t disconnect_count; + uint8_t connect_count; + bool force_rsne_override; + struct connect_req_ies req_ie; + struct connect_rsp_ies rsp_ie; + struct disconnect_ies discon_ie; +#ifdef WLAN_FEATURE_FILS_SK + struct wlan_fils_con_info fils_info; +#endif +}; + +/** + * mlme_cm_init() - Invoke connection manager init + * @vdev_mlme_obj: VDEV MLME comp object + * + * API allocates CM and init + * + * Return: SUCCESS on successful allocation + * FAILURE, if registration fails + */ +QDF_STATUS mlme_cm_init(struct vdev_mlme_obj *vdev_mlme); + +/** + * mlme_cm_deinit() - Invoke connection manager deinit + * @vdev_mlme_obj: VDEV MLME comp object + * + * API destroys CM + * + * Return: SUCCESS on successful deletion + * FAILURE, if deletion fails + */ +QDF_STATUS mlme_cm_deinit(struct vdev_mlme_obj *vdev_mlme); +#else + +static inline QDF_STATUS mlme_cm_init(struct vdev_mlme_obj *vdev_mlme) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS mlme_cm_deinit(struct vdev_mlme_obj *vdev_mlme) +{ + return QDF_STATUS_SUCCESS; +} + +#endif /* FEATURE_CM_ENABLE */ + +#endif /* __WLAN_CM_MAIN_H__ */ diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h b/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h new file mode 100644 index 000000000000..c0da8496205b --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_cm_main_api.h + * + * This header file maintain connect, disconnect APIs of connection manager + */ + +#ifndef __WLAN_CM_MAIN_API_H__ +#define __WLAN_CM_MAIN_API_H__ + +#endif /* __WLAN_CM_MAIN_API_H__ */ diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c b/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c new file mode 100644 index 000000000000..5dd92bffb622 --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Implements general SM framework for connection manager roaming sm + */ + +#include "wlan_cm_main.h" +#include "wlan_cm_roam_sm.h" +#include "wlan_cm_sm.h" + +void mlme_cm_state_roaming_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_ROAMING, WLAN_CM_SS_IDLE); +} + +void mlme_cm_state_roaming_exit(void *ctx) +{ +} + +bool mlme_cm_state_roaming_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +#ifdef WLAN_FEATURE_HOST_ROAM +#ifdef WLAN_FEATURE_PREAUTH_ENABLE +void mlme_cm_subst_preauth_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_ROAMING) + QDF_BUG(0); + + mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_PREAUTH); +} + +void mlme_cm_subst_preauth_exit(void *ctx) +{ +} + +bool mlme_cm_subst_preauth_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +#endif /* WLAN_FEATURE_PREAUTH_ENABLE */ + +void mlme_cm_subst_reassoc_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_ROAMING) + QDF_BUG(0); + + mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_REASSOC); +} + +void mlme_cm_subst_reassoc_exit(void *ctx) +{ +} + +bool mlme_cm_subst_reassoc_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +#endif /* WLAN_FEATURE_HOST_ROAM */ + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +void mlme_cm_subst_roam_start_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_ROAMING) + QDF_BUG(0); + + mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_ROAM_STARTED); +} + +void mlme_cm_subst_roam_start_exit(void *ctx) +{ +} + +bool mlme_cm_subst_roam_start_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +void mlme_cm_subst_roam_sync_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_ROAMING) + QDF_BUG(0); + + mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_ROAM_SYNC); +} + +void mlme_cm_subst_roam_sync_exit(void *ctx) +{ +} + +bool mlme_cm_subst_roam_sync_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} +#endif /* WLAN_FEATURE_ROAM_OFFLOAD */ diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.h b/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.h new file mode 100644 index 000000000000..f4e1ef1dd777 --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_cm_roam_sm.h + * + * This header file maintain structures required for connection mgr roam sm + */ + +#ifndef __WLAN_CM_ROAM_SM_H__ +#define __WLAN_CM_ROAM_SM_H__ + +/** + * mlme_cm_state_roaming_entry() - Entry API for roaming state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to roaming state + * + * Return: void + */ +void mlme_cm_state_roaming_entry(void *ctx); + +/** + * mlme_cm_state_roaming_exit() - Exit API for roaming state for connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from roaming state + * + * Return: void + */ +void mlme_cm_state_roaming_exit(void *ctx); + +/** + * mlme_cm_state_roaming_event() - Roaming State event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in roaming state + * + * Return: bool + */ +bool mlme_cm_state_roaming_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data); + +#ifdef WLAN_FEATURE_HOST_ROAM +#ifdef WLAN_FEATURE_PREAUTH_ENABLE +/** + * mlme_cm_subst_preauth_entry() - Entry API for preauth sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to preauth sub-state + * + * Return: void + */ +void mlme_cm_subst_preauth_entry(void *ctx); + +/** + * mlme_cm_subst_preauth_exit() - Exit API for preauth sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from preauth sub-state + * + * Return: void + */ +void mlme_cm_subst_preauth_exit(void *ctx); + +/** + * mlme_cm_subst_preauth_event() - Preauth sub-state event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in preauth sub-state + * + * Return: bool + */ +bool mlme_cm_subst_preauth_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data); +#else /* WLAN_FEATURE_PREAUTH_ENABLE && WLAN_FEATURE_HOST_ROAM */ + +static inline void mlme_cm_subst_preauth_entry(void *ctx) {} + +static inline void mlme_cm_subst_preauth_exit(void *ctx) {} + +static inline bool mlme_cm_subst_preauth_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ + return true; +} +#endif /* WLAN_FEATURE_PREAUTH_ENABLE */ + +/** + * mlme_cm_subst_reassoc_entry() - Entry API for reassoc sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to reassoc sub-state + * + * Return: void + */ +void mlme_cm_subst_reassoc_entry(void *ctx); + +/** + * mlme_cm_subst_reassoc_exit() - Exit API for reassoc sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from reassoc sub-state + * + * Return: void + */ +void mlme_cm_subst_reassoc_exit(void *ctx); + +/** + * mlme_cm_subst_reassoc_event() - Reassoc sub-state event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in preauth sub-state + * + * Return: bool + */ +bool mlme_cm_subst_reassoc_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data); +#endif /* WLAN_FEATURE_HOST_ROAM */ + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + +/** + * mlme_cm_subst_roam_start_entry() - Entry API for roam start sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to roam start sub-state + * + * Return: void + */ +void mlme_cm_subst_roam_start_entry(void *ctx); + +/** + * mlme_cm_subst_roam_start_exit() - Exit API for roam start sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from roam start sub-state + * + * Return: void + */ +void mlme_cm_subst_roam_start_exit(void *ctx); + +/** + * mlme_cm_subst_roam_start_event() - Roam start sub-state event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in roam start sub-state + * + * Return: bool + */ +bool mlme_cm_subst_roam_start_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data); + +/** + * mlme_cm_subst_roam_sync_entry() - Entry API for roam sync sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to roam sync sub-state + * + * Return: void + */ +void mlme_cm_subst_roam_sync_entry(void *ctx); + +/** + * mlme_cm_subst_roam_sync_exit() - Exit API for roam sync sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from roam sync sub-state + * + * Return: void + */ +void mlme_cm_subst_roam_sync_exit(void *ctx); + +/** + * mlme_cm_subst_roam_sync_event() - Roam sync sub-state event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in roam sync sub-state + * + * Return: bool + */ +bool mlme_cm_subst_roam_sync_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data); +#endif /* WLAN_FEATURE_ROAM_OFFLOAD */ + +#endif /* __WLAN_CM_ROAM_SM_H__ */ diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c new file mode 100644 index 000000000000..b58afc7f61ad --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c @@ -0,0 +1,764 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Implements general SM framework for connection manager + */ + +#include "wlan_cm_main.h" +#include "wlan_cm_sm.h" +#include "wlan_cm_roam_sm.h" + +void mlme_cm_set_state(struct cnx_mgr *cm_ctx, enum wlan_cm_sm_state state) +{ + if (state < WLAN_CM_S_MAX) + cm_ctx->sm.cm_state = state; + else + mlme_err("mlme state (%d) is invalid", state); +} + +void mlme_cm_set_substate(struct cnx_mgr *cm_ctx, + enum wlan_cm_sm_state substate) +{ + if ((substate > WLAN_CM_S_MAX) && (substate < WLAN_CM_SS_MAX)) + cm_ctx->sm.cm_substate = substate; + else + mlme_err(" mlme sub state (%d) is invalid", substate); +} + +void mlme_cm_sm_state_update(struct cnx_mgr *cm_ctx, + enum wlan_cm_sm_state state, + enum wlan_cm_sm_state substate) +{ + if (!cm_ctx) { + mlme_err("cm_ctx is NULL"); + return; + } + + mlme_cm_set_state(cm_ctx, state); + mlme_cm_set_substate(cm_ctx, substate); +} + +/** + * mlme_cm_state_init_entry() - Entry API for init state for connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to init state + * + * Return: void + */ +static void mlme_cm_state_init_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_INIT, WLAN_CM_SS_IDLE); +} + +/** + * mlme_cm_state_init_exit() - Exit API for init state for connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from init state + * + * Return: void + */ +static void mlme_cm_state_init_exit(void *ctx) +{ +} + +/** + * mlme_cm_state_init_event() - Init State event handler for connection mgr + * @ctx: connection manager ctx + * + * API to handle events in INIT state + * + * Return: bool + */ +static bool mlme_cm_state_init_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +/** + * mlme_cm_state_connecting_entry() - Entry API for connecting state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to connecting state + * + * Return: void + */ +static void mlme_cm_state_connecting_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_CONNECTING, WLAN_CM_SS_IDLE); +} + +/** + * mlme_cm_state_connecting_exit() - Exit API for connecting state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from connecting state + * + * Return: void + */ +static void mlme_cm_state_connecting_exit(void *ctx) +{ +} + +/** + * mlme_cm_state_connecting_event() - Connecting State event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in CONNECTING state + * + * Return: bool + */ +static bool mlme_cm_state_connecting_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +/** + * mlme_cm_state_connected_entry() - Entry API for connected state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to connected state + * + * Return: void + */ +static void mlme_cm_state_connected_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_CONNECTED, WLAN_CM_SS_IDLE); +} + +/** + * mlme_cm_state_connected_exit() - Exit API for connected state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from connected state + * + * Return: void + */ +static void mlme_cm_state_connected_exit(void *ctx) +{ +} + +/** + * mlme_cm_state_connected_event() - Connected State event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in CONNECTED state + * + * Return: bool + */ +static bool mlme_cm_state_connected_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +/** + * mlme_cm_state_disconnecting_entry() - Entry API for disconnecting state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to disconnecting state + * + * Return: void + */ +static void mlme_cm_state_disconnecting_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + mlme_cm_sm_state_update(cm_ctx, WLAN_CM_S_DISCONNECTING, + WLAN_CM_SS_IDLE); +} + +/** + * mlme_cm_state_disconnecting_exit() - Exit API for disconnecting state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from disconnecting state + * + * Return: void + */ +static void mlme_cm_state_disconnecting_exit(void *ctx) +{ +} + +/** + * mlme_cm_state_connected_event() - Disconnecting State event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in Disconnecting state + * + * Return: bool + */ +static bool mlme_cm_state_disconnecting_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +/** + * mlme_cm_subst_join_pending_entry() - Entry API for join pending sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to join pending sub-state + * + * Return: void + */ +static void mlme_cm_subst_join_pending_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING) + QDF_BUG(0); + + mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_JOIN_PENDING); +} + +/** + * mlme_cm_subst_join_pending_exit() - Exit API for join pending sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from join pending sub-state + * + * Return: void + */ +static void mlme_cm_subst_join_pending_exit(void *ctx) +{ +} + +/** + * mlme_cm_subst_join_pending_event() - Join pending sub-state event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in Join pending sub-state + * + * Return: bool + */ +static bool mlme_cm_subst_join_pending_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +/** + * mlme_cm_subst_scan_entry() - Entry API for scan sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to scan sub-state + * + * Return: void + */ +static void mlme_cm_subst_scan_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING) + QDF_BUG(0); + + mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_SCAN); +} + +/** + * mlme_cm_subst_scan_exit() - Exit API for scan sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from scan sub-state + * + * Return: void + */ +static void mlme_cm_subst_scan_exit(void *ctx) +{ +} + +/** + * mlme_cm_subst_scan_event() - Scan sub-state event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in scan sub-state + * + * Return: bool + */ +static bool mlme_cm_subst_scan_event(void *ctx, uint16_t event, + uint16_t event_data_len, void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +/** + * mlme_cm_subst_join_active_entry() - Entry API for join active sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on moving to join active sub-state + * + * Return: void + */ +static void mlme_cm_subst_join_active_entry(void *ctx) +{ + struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + + if (mlme_cm_get_state(cm_ctx) != WLAN_CM_S_CONNECTING) + QDF_BUG(0); + + mlme_cm_set_substate(cm_ctx, WLAN_CM_SS_JOIN_ACTIVE); +} + +/** + * mlme_cm_subst_join_active_exit() - Exit API for join active sub-state for + * connection mgr + * @ctx: connection manager ctx + * + * API to perform operations on exiting from join active sub-state + * + * Return: void + */ +static void mlme_cm_subst_join_active_exit(void *ctx) +{ +} + +/** + * mlme_cm_subst_join_active_event() - Join active sub-state event handler for + * connection mgr + * @ctx: connection manager ctx + * + * API to handle events in join active sub-state + * + * Return: bool + */ +static bool mlme_cm_subst_join_active_event(void *ctx, uint16_t event, + uint16_t event_data_len, + void *event_data) +{ +// struct cnx_mgr *cm_ctx = (struct cnx_mgr *)ctx; + bool status; + + switch (event) { + default: + status = false; + break; + } + + return status; +} + +struct wlan_sm_state_info cm_sm_info[] = { + { + (uint8_t)WLAN_CM_S_INIT, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + true, + "INIT", + mlme_cm_state_init_entry, + mlme_cm_state_init_exit, + mlme_cm_state_init_event + }, + { + (uint8_t)WLAN_CM_S_CONNECTING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + true, + "CONNECTING", + mlme_cm_state_connecting_entry, + mlme_cm_state_connecting_exit, + mlme_cm_state_connecting_event + }, + { + (uint8_t)WLAN_CM_S_CONNECTED, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + true, + "CONNECTED", + mlme_cm_state_connected_entry, + mlme_cm_state_connected_exit, + mlme_cm_state_connected_event + }, + { + (uint8_t)WLAN_CM_S_DISCONNECTING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + true, + "DISCONNECTING", + mlme_cm_state_disconnecting_entry, + mlme_cm_state_disconnecting_exit, + mlme_cm_state_disconnecting_event + }, + { + (uint8_t)WLAN_CM_S_ROAMING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + true, + "ROAMING", + mlme_cm_state_roaming_entry, + mlme_cm_state_roaming_exit, + mlme_cm_state_roaming_event + }, + { + (uint8_t)WLAN_CM_S_MAX, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "INVALID", + NULL, + NULL, + NULL + }, + { + (uint8_t)WLAN_CM_SS_IDLE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "IDLE", + NULL, + NULL, + NULL + }, + { + (uint8_t)WLAN_CM_SS_JOIN_PENDING, + (uint8_t)WLAN_CM_S_CONNECTING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "JOIN_PENDING", + mlme_cm_subst_join_pending_entry, + mlme_cm_subst_join_pending_exit, + mlme_cm_subst_join_pending_event + }, + { + (uint8_t)WLAN_CM_SS_SCAN, + (uint8_t)WLAN_CM_S_CONNECTING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "SCAN", + mlme_cm_subst_scan_entry, + mlme_cm_subst_scan_exit, + mlme_cm_subst_scan_event + }, + { + (uint8_t)WLAN_CM_SS_JOIN_ACTIVE, + (uint8_t)WLAN_CM_S_CONNECTING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "JOIN_ACTIVE", + mlme_cm_subst_join_active_entry, + mlme_cm_subst_join_active_exit, + mlme_cm_subst_join_active_event + }, +#ifdef WLAN_FEATURE_HOST_ROAM + { + (uint8_t)WLAN_CM_SS_PREAUTH, + (uint8_t)WLAN_CM_S_ROAMING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "PREAUTH", + mlme_cm_subst_preauth_entry, + mlme_cm_subst_preauth_exit, + mlme_cm_subst_preauth_event + }, + { + (uint8_t)WLAN_CM_SS_REASSOC, + (uint8_t)WLAN_CM_S_ROAMING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "REASSOC", + mlme_cm_subst_reassoc_entry, + mlme_cm_subst_reassoc_exit, + mlme_cm_subst_reassoc_event + }, +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + { + (uint8_t)WLAN_CM_SS_ROAM_STARTED, + (uint8_t)WLAN_CM_S_ROAMING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "ROAM_START", + mlme_cm_subst_roam_start_entry, + mlme_cm_subst_roam_start_exit, + mlme_cm_subst_roam_start_event + }, + { + (uint8_t)WLAN_CM_SS_ROAM_SYNC, + (uint8_t)WLAN_CM_S_ROAMING, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "ROAM_SYNC", + mlme_cm_subst_roam_sync_entry, + mlme_cm_subst_roam_sync_exit, + mlme_cm_subst_roam_sync_event + }, +#endif + { + (uint8_t)WLAN_CM_SS_MAX, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + (uint8_t)WLAN_SM_ENGINE_STATE_NONE, + false, + "INVALID", + NULL, + NULL, + NULL + }, +}; + +static const char *cm_sm_event_names[] = { + "EV_CONNECT_REQ", + "EV_SCAN_FOR_SSID", + "EV_SCAN_FOR_SSID_SUCCESS", + "EV_SCAN_FOR_SSID_FAILURE", + "EV_CONNECT_START_REQ", + "EV_CONNECT_START", + "EV_CONNECT_SUCCESS", + "EV_CONNECT_NEXT_CANDIDATE", + "EV_CONNECT_FAILURE", + "EV_DISCONNECT_REQ", + "EV_DISCONNECT_START_REQ", + "EV_DISCONNECT_START", + "EV_DISCONNECT_DONE", + "EV_ROAM_START", + "EV_ROAM_SYNC", + "EV_ROAM_INVOKE_FAIL", + "EV_ROAM_HO_FAIL", + "EV_PREAUTH_DONE", + "EV_GET_NEXT_PREAUTH_AP", + "EV_PREAUTH_FAIL", + "EV_START_REASSOC", + "EV_REASSOC_DONE", + "EV_REASSOC_FAILURE", + "EV_ROAM_COMPLETE", + "EV_CONNECT_TIMEOUT", + "EV_CONNECT_SER_FAIL", + "EV_HW_MODE_CHANGE_FAIL", +}; + +enum wlan_cm_sm_state mlme_cm_get_state(struct cnx_mgr *cm_ctx) +{ + enum QDF_OPMODE op_mode; + + if (!cm_ctx || !cm_ctx->vdev) + return WLAN_CM_S_MAX; + + op_mode = wlan_vdev_mlme_get_opmode(cm_ctx->vdev); + + if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) + return WLAN_CM_S_MAX; + + return cm_ctx->sm.cm_state; +} + +enum wlan_cm_sm_state mlme_cm_get_sub_state(struct cnx_mgr *cm_ctx) +{ + enum QDF_OPMODE op_mode; + + if (!cm_ctx || !cm_ctx->vdev) + return WLAN_CM_SS_MAX; + + op_mode = wlan_vdev_mlme_get_opmode(cm_ctx->vdev); + + if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) + return WLAN_CM_SS_MAX; + + return cm_ctx->sm.cm_substate; +} + +static inline +QDF_STATUS mlme_cm_sm_deliver_event(struct cnx_mgr *cm_ctx, + enum wlan_cm_sm_evt event, + uint16_t event_data_len, void *event_data) +{ + return wlan_sm_dispatch(cm_ctx->sm.sm_hdl, event, + event_data_len, event_data); +} + +static void mlme_cm_sm_print_state_event(struct cnx_mgr *cm_ctx, + enum wlan_cm_sm_evt event) +{ + enum wlan_cm_sm_state state; + enum wlan_cm_sm_state substate; + + state = mlme_cm_get_state(cm_ctx); + substate = mlme_cm_get_sub_state(cm_ctx); + + mlme_nofl_debug("[%s]%s - %s, %s", cm_ctx->sm.sm_hdl->name, + cm_sm_info[state].name, cm_sm_info[substate].name, + cm_sm_event_names[event]); +} + +static void mlme_cm_sm_print_state(struct cnx_mgr *cm_ctx) +{ + enum wlan_cm_sm_state state; + enum wlan_cm_sm_state substate; + + state = mlme_cm_get_state(cm_ctx); + substate = mlme_cm_get_sub_state(cm_ctx); + + mlme_nofl_debug("[%s]%s - %s", cm_ctx->sm.sm_hdl->name, + cm_sm_info[state].name, cm_sm_info[substate].name); +} + +QDF_STATUS mlme_cm_sm_deliver_evt(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_sm_evt event, + uint16_t event_data_len, + void *event_data) +{ + struct vdev_mlme_obj *vdev_mlme; + QDF_STATUS status; + enum wlan_cm_sm_state state_entry, state_exit; + enum wlan_cm_sm_state substate_entry, substate_exit; + enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); + struct cnx_mgr *cm_ctx; + + if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) { + mlme_err("Invalid mode %d", op_mode); + return QDF_STATUS_E_NOSUPPORT; + } + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme || !vdev_mlme->cnx_mgr_ctx) { + mlme_err("vdev mlme or cm ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + cm_ctx = vdev_mlme->cnx_mgr_ctx; + mlme_cm_lock_acquire(cm_ctx); + + /* store entry state and sub state for prints */ + state_entry = mlme_cm_get_state(cm_ctx); + substate_entry = mlme_cm_get_sub_state(cm_ctx); + mlme_cm_sm_print_state_event(cm_ctx, event); + + status = mlme_cm_sm_deliver_event(cm_ctx, event, event_data_len, + event_data); + /* Take exit state, exit substate for prints */ + state_exit = mlme_cm_get_state(cm_ctx); + substate_exit = mlme_cm_get_sub_state(cm_ctx); + /* If no state and substate change, don't print */ + if (!((state_entry == state_exit) && (substate_entry == substate_exit))) + mlme_cm_sm_print_state(cm_ctx); + mlme_cm_lock_release(cm_ctx); + + return status; +} + +QDF_STATUS mlme_cm_sm_create(struct cnx_mgr *cm_ctx) +{ + struct wlan_sm *sm; + uint8_t name[WLAN_SM_ENGINE_MAX_NAME]; + + qdf_snprintf(name, sizeof(name), "CM-VDEV-%d", + wlan_vdev_get_id(cm_ctx->vdev)); + sm = wlan_sm_create(name, cm_ctx, + WLAN_CM_S_INIT, + cm_sm_info, + QDF_ARRAY_SIZE(cm_sm_info), + cm_sm_event_names, + QDF_ARRAY_SIZE(cm_sm_event_names)); + if (!sm) { + mlme_err("CM MLME SM allocation failed"); + return QDF_STATUS_E_NOMEM; + } + cm_ctx->sm.sm_hdl = sm; + + mlme_cm_lock_create(cm_ctx); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS mlme_cm_sm_destroy(struct cnx_mgr *cm_ctx) +{ + mlme_cm_lock_destroy(cm_ctx); + wlan_sm_delete(cm_ctx->sm.sm_hdl); + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h new file mode 100644 index 000000000000..8b2bbffa1549 --- /dev/null +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_cm_sm.h + * + * This header file maintain structures required for connection mgr sm infra + */ + +#ifndef __WLAN_CM_SM_H__ +#define __WLAN_CM_SM_H__ + +#ifdef FEATURE_CM_ENABLE +#include + +/** + * mlme_cm_sm_create() - Invoke SM creation for connection manager + * @cm_ctx: connection manager ctx + * + * API allocates CM MLME SM and initializes SM lock + * + * Return: SUCCESS on successful allocation + * FAILURE, if registration fails + */ +QDF_STATUS mlme_cm_sm_create(struct cnx_mgr *cm_ctx); + +/** + * mlme_cm_sm_destroy() - Invoke SM deletion for connection manager + * @cm_ctx: connection manager ctx + * + * API destroys CM MLME SM and SM lock + * + * Return: SUCCESS on successful deletion + * FAILURE, if deletion fails + */ +QDF_STATUS mlme_cm_sm_destroy(struct cnx_mgr *cm_ctx); + +/** + * mlme_cm_sm_history_print() - Prints SM history + * @cm_ctx: connection manager ctx + * + * API to print CM SM history + * + * Return: void + */ +#ifdef SM_ENG_HIST_ENABLE +static inline void mlme_cm_sm_history_print(struct cnx_mgr *cm_ctx) +{ + return wlan_sm_print_history(cm_ctx->sm.sm_hdl); +} +#else +static inline void mlme_cm_sm_history_print(struct cnx_mgr *cm_ctx) +{ +} +#endif + +#ifdef WLAN_CM_USE_SPINLOCK +/** + * mlme_cm_lock_create - Create CM SM mutex/spinlock + * @cm_ctx: connection manager ctx + * + * Creates CM SM mutex/spinlock + * + * Return: void + */ +static inline void +mlme_cm_lock_create(struct cnx_mgr *cm_ctx) +{ + qdf_spinlock_create(&cm_ctx->sm.cm_sm_lock); +} + +/** + * mlme_cm_lock_destroy - Destroy CM SM mutex/spinlock + * @cm_ctx: connection manager ctx + * + * Destroy CM SM mutex/spinlock + * + * Return: void + */ +static inline void +mlme_cm_lock_destroy(struct cnx_mgr *cm_ctx) +{ + qdf_spinlock_destroy(&cm_ctx->sm.cm_sm_lock); +} + +/** + * mlme_cm_lock_acquire - acquire CM SM mutex/spinlock + * @cm_ctx: connection manager ctx + * + * acquire CM SM mutex/spinlock + * + * return: void + */ +static inline void mlme_cm_lock_acquire(struct cnx_mgr *cm_ctx) +{ + qdf_spinlock_acquire(&cm_ctx->sm.cm_sm_lock); +} + +/** + * mlme_cm_lock_release - release CM SM mutex/spinlock + * @cm_ctx: connection manager ctx + * + * release CM SM mutex/spinlock + * + * return: void + */ +static inline void mlme_cm_lock_release(struct cnx_mgr *cm_ctx) +{ + qdf_spinlock_release(&cm_ctx->sm.cm_sm_lock); +} +#else +static inline void +mlme_cm_lock_create(struct cnx_mgr *cm_ctx) +{ + qdf_mutex_create(&cm_ctx->sm.cm_sm_lock); +} + +static inline void +mlme_cm_lock_destroy(struct cnx_mgr *cm_ctx) +{ + qdf_mutex_destroy(&cm_ctx->sm.cm_sm_lock); +} + +static inline void mlme_cm_lock_acquire(struct cnx_mgr *cm_ctx) +{ + qdf_mutex_acquire(&cm_ctx->sm.cm_sm_lock); +} + +static inline void mlme_cm_lock_release(struct cnx_mgr *cm_ctx) +{ + qdf_mutex_release(&cm_ctx->sm.cm_sm_lock); +} +#endif /* WLAN_CM_USE_SPINLOCK */ + +/** + * mlme_cm_sm_transition_to() - invokes state transition + * @cm_ctx: connection manager ctx + * @state: new cm state + * + * API to invoke SM API to move to new state + * + * Return: void + */ +static inline void mlme_cm_sm_transition_to(struct cnx_mgr *cm_ctx, + enum wlan_cm_sm_state state) +{ + wlan_sm_transition_to(cm_ctx->sm.sm_hdl, state); +} + +/** + * mlme_cm_get_state() - get mlme state + * @cm_ctx: connection manager SM ctx + * + * API to get cm state + * + * Return: state of cm + */ +enum wlan_cm_sm_state mlme_cm_get_state(struct cnx_mgr *cm_ctx); + +/** + * mlme_cm_get_sub_state() - get mlme substate + * @cm_ctx: connection manager SM ctx + * + * API to get cm substate + * + * Return: substate of cm + */ +enum wlan_cm_sm_state mlme_cm_get_sub_state(struct cnx_mgr *cm_ctx); + +/** + * mlme_cm_set_state() - set cm mlme state + * @cm_ctx: connection manager SM ctx + * @state: cm state + * + * API to set cm state + * + * Return: void + */ +void mlme_cm_set_state(struct cnx_mgr *cm_ctx, enum wlan_cm_sm_state state); +/** + * mlme_cm_set_substate() - set cm mlme sub state + * @cm_ctx: connection manager SM ctx + * @substate: cm sub state + * + * API to set cm sub state + * + * Return: void + */ +void mlme_cm_set_substate(struct cnx_mgr *cm_ctx, + enum wlan_cm_sm_state substate); + +/** + * mlme_cm_sm_state_update() - set cm mlme state and sub state + * @cm_ctx: connection manager SM ctx + * @state: cm state + * @substate: cm sub state + * + * API to invoke util APIs to set state and MLME sub state + * + * Return: void + */ +void mlme_cm_sm_state_update(struct cnx_mgr *cm_ctx, + enum wlan_cm_sm_state state, + enum wlan_cm_sm_state substate); + +/** + * mlme_cm_sm_deliver_evt() - Delivers event to CM SM + * @vdev: Object manager VDEV object + * @event: CM event + * @event_data_len: data size + * @event_data: event data + * + * API to dispatch event to VDEV MLME SM with lock acquired + * + * Return: SUCCESS: on handling event + * FAILURE: on ignoring the event + */ +QDF_STATUS mlme_cm_sm_deliver_evt(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_sm_evt event, + uint16_t event_data_len, + void *event_data); + +#endif /* FEATURE_CM_ENABLE */ +#endif /* __WLAN_CM_SM_H__ */ diff --git a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h new file mode 100644 index 000000000000..61f9548731d3 --- /dev/null +++ b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_cm_public_struct.h + * + * This header file maintain public structures required for connection mgr + */ + +#ifndef __WLAN_CM_PUBLIC_STRUCT_H__ +#define __WLAN_CM_PUBLIC_STRUCT_H__ + +#ifdef FEATURE_CM_ENABLE +#include + +/** + * struct wlan_cm_wep_key_params - store wep key info + * @key: key info + * @seq: seq info + * @key_len: key length + * @seq_len: seq len + * @key_idx: key index + */ +struct wlan_cm_wep_key_params { + uint8_t *key; + uint8_t *seq; + uint8_t key_len; + uint8_t seq_len; + uint8_t key_idx; +}; + +#define WLAN_CM_MAX_NR_CIPHER_SUITES 5 +#define WLAN_CM_MAX_NR_AKM_SUITES 2 + +/** + * struct wlan_cm_connect_crypto_info - Crypto settings + * @wpa_versions: indicates which, if any, WPA versions are enabled + * (from enum nl80211_wpa_versions) + * @group_cipher: group key cipher suite (or 0 if unset) + * @n_ciphers_pairwise: number of AP supported unicast ciphers + * @ciphers_pairwise: unicast key cipher suites + * @n_akm_suites: number of AKM suites + * @akm_suites: AKM suites + * @wep_keys: static WEP keys, if not NULL points to an array of + * MAX_WEP_KEYS WEP keys + * @pmf_cap: Pmf capability + */ +struct wlan_cm_connect_crypto_info { + uint32_t wpa_versions; + wlan_crypto_auth_mode auth_type; + wlan_crypto_cipher_type group_cipher; + uint32_t n_ciphers_pairwise; + wlan_crypto_cipher_type ciphers_pairwise[WLAN_CM_MAX_NR_CIPHER_SUITES]; + uint32_t n_akm_suites; + wlan_crypto_key_mgmt akm_suites[WLAN_CM_MAX_NR_AKM_SUITES]; + struct wlan_cm_wep_key_params wep_keys; + enum wlan_pmf_cap pmf_cap; + uint32_t rsn_ie_len; + uint8_t *rsn_ie; +}; + +#ifdef WLAN_FEATURE_FILS_SK +#define WLAN_CM_FILS_MAX_KEYNAME_NAI_LENGTH 253 +#define WLAN_CM_FILS_MAX_REALM_LEN 255 +#define WLAN_CM_FILS_MAX_RRK_LENGTH 64 +#define WLAN_CM_FILS_MAX_RIK_LENGTH CM_FILS_MAX_RRK_LENGTH + +/** + * struct wlan_fils_con_info - fils connect req info + * @is_fils_connection: is fils connection + * @username_len: username length + * @username: username + * @realm_len: realm length + * @realm: realm + * @next_seq_num: next seq number + * @rrk_len: rrk length + * @rrk: rrk + */ +struct wlan_fils_con_info { + bool is_fils_connection; + uint32_t username_len; + uint8_t username[WLAN_CM_FILS_MAX_KEYNAME_NAI_LENGTH]; + uint32_t realm_len; + uint8_t realm[WLAN_CM_FILS_MAX_REALM_LEN]; + uint16_t next_seq_num; + uint32_t rrk_len; + uint8_t rrk[WLAN_CM_FILS_MAX_RRK_LENGTH]; +}; +#endif + +/** + * enum wlan_cm_source - connection manager req source + * @CM_OSIF_CONENCT_REQ: Connect req initiated by OSIF or north bound + * @CM_ROAMING: Roaming request + * @CM_OSIF_DISCONNECT: Disconnect req initiated by OSIF or north bound + * @CM_PEER_DISCONNECT: Disconnect req initiated by peer sending deauth/disassoc + * only for this localy generated will be false while indicating to kernel + * @CM_SB_DISCONNECT: Disconnect req initiated by South bound/VDEV mgr/Peer mgr + * @CM_INTERNAL_DISCONNECT: Internal disconnect initiated by Connection manager + * on receiving the back to back commands + * @CM_ROAM_DISCONNECT: Disconnect req due to HO failure + */ +enum wlan_cm_source { + CM_OSIF_CONENCT_REQ, + CM_ROAMING, + CM_OSIF_DISCONNECT, + CM_PEER_DISCONNECT, + CM_SB_DISCONNECT, + CM_INTERNAL_DISCONNECT, + CM_ROAM_DISCONNECT, +}; + +/** + * struct wlan_cm_connect_req - connect req from requester + * @vdev_id: vdev id + * @source: source of the req + * @bssid: bssid given + * @prev_bssid: prev AP bssid, given in case supplican want to roam to new BSSID + * @ssid: profile SSID + * @bssid_hint: bssid hint to connect + * @chan_freq: channel of the AP + * @crypto: crypto related info + * @connect_ie: connect IE additional assoc IE + * @ht_caps: ht capability + * @ht_caps_mask: mask of valid ht caps + * @vht_caps: vht capability + * @vht_caps_mask: mask of valid vht caps + * @fils_info: Fills related connect info + */ +struct wlan_cm_connect_req { + uint8_t vdev_id; + enum wlan_cm_source source; + struct qdf_mac_addr bssid; + struct qdf_mac_addr prev_bssid; + struct wlan_ssid ssid; + struct qdf_mac_addr bssid_hint; + uint32_t chan_freq; + struct wlan_cm_connect_crypto_info crypto; + struct element_info connect_ie; + uint16_t ht_caps; + uint16_t ht_caps_mask; + uint32_t vht_caps; + uint32_t vht_caps_mask; +#ifdef WLAN_FEATURE_FILS_SK + struct wlan_fils_con_info fils_info; +#endif +}; + +/** + * struct wlan_cm_vdev_connect_req - connect req from connection manager to + * vdev mgr + * @vdev_id: vdev id + * @cm_id: Connect manager id + * @bss: scan entry for the candidate + */ +struct wlan_cm_vdev_connect_req { + uint8_t vdev_id; + uint8_t cm_id; + struct scan_cache_node *bss; +}; + +/** + * struct wlan_cm_disconnect_req - disconnect req from requester + * @vdev_id: vdev id + * @source: source of disconnect + * @reason_code: protocol/propitiatory reason code of the disconnect. + * propitiatory will be used to send in + * QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON + * @bssid: bssid of AP + */ +struct wlan_cm_disconnect_req { + uint8_t vdev_id; + enum wlan_cm_source source; + uint16_t reason_code; + struct qdf_mac_addr bssid; +}; + +/** + * struct wlan_cm_vdev_discon_req - disconnect req from connection manager to + * vdev mgr + * @cm_id: connection manager ID + * @req: disconnect req + */ +struct wlan_cm_vdev_discon_req { + uint8_t cm_id; + struct wlan_cm_disconnect_req req; +}; + +/* + * enum wlan_cm_connect_fail_reason: connection manager connect fail reason + * @CM_NO_CANDIDATE_FOUND: No candidate found + * @CM_JOIN_FAILED: Failed in joining state + * (BSS peer creation or other handling) + * @CM_JOIN_TIMEOUT: Did not receive beacon or probe response after unicast + * probe request + * @CM_AUTH_FAILED: Auth rejected by AP + * @CM_AUTH_TIMEOUT: No Auth resp from AP + * @CM_ASSOC_FAILED: Assoc rejected by AP + * @CM_ASSOC_TIMEOUT: No Assoc resp from AP + * @CM_HW_MODE_FAILURE: failed to change HW mode + * @CM_SER_FAILURE: Failed to serialize command + * @CM_GENERIC_FAILURE: Generic failure apart from above + */ +enum wlan_cm_connect_fail_reason { + CM_NO_CANDIDATE_FOUND, + CM_JOIN_FAILED, + CM_JOIN_TIMEOUT, + CM_AUTH_FAILED, + CM_AUTH_TIMEOUT, + CM_ASSOC_FAILED, + CM_ASSOC_TIMEOUT, + CM_HW_MODE_FAILURE, + CM_SER_FAILURE, + CM_GENERIC_FAILURE, +}; + +/** + * struct wlan_cm_connect_rsp - connect resp from VDEV mgr and will be sent to + * OSIF + * @vdev_id: vdev id + * @cm_id: Connect manager id + * @connect_status: connect status success or failure + * @reason: connect fail reason + * @reason_code: protocol reason code of the connect failure + * @peer_macaddr: bssid of AP + */ +struct wlan_cm_connect_rsp { + uint8_t vdev_id; + uint8_t cm_id; + uint8_t connect_status; + enum wlan_cm_connect_fail_reason reason; + uint8_t failure_code; + uint8_t aid; +}; + +/** + * struct wlan_cm_discon_rsp - disconnect resp from VDEV mgr and will be sent to + * OSIF + * @req: disconnect req sent to vdev mgr + */ +struct wlan_cm_discon_rsp { + struct wlan_cm_vdev_discon_req req; +}; + +#endif /* FEATURE_CM_ENABLE */ + +#endif /* __WLAN_CM_PUBLIC_STRUCT_H__ */ diff --git a/umac/mlme/include/wlan_vdev_mlme.h b/umac/mlme/include/wlan_vdev_mlme.h index 257df1dfbd6e..a07470d6fa1f 100644 --- a/umac/mlme/include/wlan_vdev_mlme.h +++ b/umac/mlme/include/wlan_vdev_mlme.h @@ -26,6 +26,7 @@ #include struct vdev_mlme_obj; +struct cnx_mgr; /* Requestor ID for multiple vdev restart */ #define MULTIPLE_VDEV_RESTART_REQ_ID 0x1234 @@ -536,6 +537,7 @@ struct vdev_mlme_ops { * @sm_lock: VDEV SM lock * @vdev_cmd_lock: VDEV MLME command atomicity * @sm_hdl: VDEV SM handle + * @cnx_mgr_ctx: connection manager context, valid for STA and P2P-CLI mode only * @vdev: Pointer to vdev objmgr * @ops: VDEV MLME callback table * @ext_vdev_ptr: VDEV MLME legacy pointer @@ -550,6 +552,9 @@ struct vdev_mlme_obj { qdf_mutex_t vdev_cmd_lock; #endif struct wlan_sm *sm_hdl; + union { + struct cnx_mgr *cnx_mgr_ctx; + }; struct wlan_objmgr_vdev *vdev; struct vdev_mlme_ops *ops; mlme_vdev_ext_t *ext_vdev_ptr; diff --git a/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c b/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c index 1b8183361425..93ddce0e4b9d 100644 --- a/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c +++ b/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c @@ -33,6 +33,7 @@ #include #include #include +#include "connection_mgr/core/src/wlan_cm_main.h" static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg) @@ -103,6 +104,11 @@ static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, goto init_failed; } + if (QDF_IS_STATUS_ERROR(mlme_cm_init(vdev_mlme))) { + mlme_err("CM SM create failed"); + goto cm_sm_create_failed; + } + if (mlme_vdev_ops_ext_hdl_create(vdev_mlme) != QDF_STATUS_SUCCESS) { mlme_err("Legacy vdev object creation failed"); @@ -127,6 +133,8 @@ ext_hdl_post_create_failed: wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, vdev_mlme); ext_hdl_create_failed: + mlme_cm_deinit(vdev_mlme); +cm_sm_create_failed: mlme_vdev_sm_destroy(vdev_mlme); init_failed: wlan_minidump_remove(vdev_mlme); @@ -150,6 +158,7 @@ static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } + mlme_cm_deinit(vdev_mlme); mlme_vdev_sm_destroy(vdev_mlme); mlme_vdev_ops_ext_hdl_destroy(vdev_mlme);