diff --git a/os_if/linux/mlme/src/wlan_cfg80211_cm_util.c b/os_if/linux/mlme/src/wlan_cfg80211_cm_util.c index a6c4e343cf23..ff55ce78c690 100644 --- a/os_if/linux/mlme/src/wlan_cfg80211_cm_util.c +++ b/os_if/linux/mlme/src/wlan_cfg80211_cm_util.c @@ -22,18 +22,21 @@ */ #include #include "wlan_cfg80211_cm_util.h" +#include "wlan_osif_priv.h" +#include "wlan_cfg80211.h" /** * osif_cm_connect_complete_cb() - Connect complete callback * @vdev: vdev pointer * @cm_conn_rsp: connect response * - * Return: None + * Return: QDF_STATUS */ -static void +static QDF_STATUS osif_cm_connect_complete_cb(struct wlan_objmgr_vdev *vdev, struct wlan_cm_connect_rsp *cm_conn_rsp) { + return QDF_STATUS_SUCCESS; } /** @@ -41,27 +44,42 @@ osif_cm_connect_complete_cb(struct wlan_objmgr_vdev *vdev, * @vdev: vdev pointer * @cm_conn_rsp: connect response * - * Return: None + * Return: QDF_STATUS */ -static void +static QDF_STATUS osif_cm_failed_candidate_cb(struct wlan_objmgr_vdev *vdev, struct wlan_cm_connect_rsp *cm_conn_rsp) { + return QDF_STATUS_SUCCESS; } /** - * osif_cm_update_conn_id_and_src_cb() - Callback to update connect id and - * source of the connect request + * osif_cm_update_id_and_src_cb() - Callback to update id and + * source of the connect/disconnect request * @vdev: vdev pointer * @Source: Source of the connect req - * @conn_id: Connect id + * @id: Connect/disconnect id * - * Return: None + * Context: Any context. Takes and releases cmd id spinlock + * Return: QDF_STATUS */ -static void -osif_cm_update_conn_id_and_src_cb(struct wlan_objmgr_vdev *vdev, - enum wlan_cm_source source, uint64_t conn_id) +static QDF_STATUS +osif_cm_update_id_and_src_cb(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_source source, wlan_cm_id cm_id) { + struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); + + if (!osif_priv) { + osif_err("Invalid vdev osif priv"); + return QDF_STATUS_E_INVAL; + } + + qdf_spinlock_acquire(&osif_priv->last_cmd_info.cmd_id_lock); + osif_priv->last_cmd_info.last_id = cm_id; + osif_priv->last_cmd_info.last_source = source; + qdf_spinlock_release(&osif_priv->last_cmd_info.cmd_id_lock); + + return QDF_STATUS_SUCCESS; } /** @@ -69,13 +87,14 @@ osif_cm_update_conn_id_and_src_cb(struct wlan_objmgr_vdev *vdev, * @vdev: vdev pointer * @cm_disconnect_rsp: Disconnect response * - * Return: None + * Return: QDF_STATUS */ -static void +static QDF_STATUS osif_cm_disconnect_complete_cb(struct wlan_objmgr_vdev *vdev, struct wlan_cm_discon_rsp *cm_disconnect_rsp) { + return QDF_STATUS_SUCCESS; } /** @@ -85,17 +104,18 @@ osif_cm_disconnect_complete_cb(struct wlan_objmgr_vdev *vdev, * This callback indicates os_if that disconnection is started * so that os_if can stop all the activity on this connection * - * Return: None + * Return: QDF_STATUS */ -static void +static QDF_STATUS osif_cm_disconnect_start_cb(struct wlan_objmgr_vdev *vdev) { + return QDF_STATUS_SUCCESS; } static struct mlme_cm_ops cm_ops = { .mlme_cm_connect_complete_cb = osif_cm_connect_complete_cb, .mlme_cm_failed_candidate_cb = osif_cm_failed_candidate_cb, - .mlme_cm_update_conn_id_and_src_cb = osif_cm_update_conn_id_and_src_cb, + .mlme_cm_update_id_and_src_cb = osif_cm_update_id_and_src_cb, .mlme_cm_disconnect_complete_cb = osif_cm_disconnect_complete_cb, .mlme_cm_disconnect_start_cb = osif_cm_disconnect_start_cb, }; diff --git a/os_if/linux/wlan_osif_priv.h b/os_if/linux/wlan_osif_priv.h index 44df0416b134..337f6e91e102 100644 --- a/os_if/linux/wlan_osif_priv.h +++ b/os_if/linux/wlan_osif_priv.h @@ -21,16 +21,17 @@ #define _WLAN_OSIF_PRIV_H_ #include "qdf_net_if.h" +#include "wlan_cm_public_struct.h" struct osif_scan_pdev; struct osif_tdls_vdev; /** - * struct pdev_osif_priv - OS private structure - * @wiphy: wiphy handle - * @legacy_osif_priv: legacy osif private handle - * @scan_priv: Scan related data used by cfg80211 scan - * @nif: pdev net device + * struct pdev_osif_priv - OS private structure + * @wiphy: wiphy handle + * @legacy_osif_priv: legacy osif private handle + * @scan_priv: Scan related data used by cfg80211 scan + * @nif: pdev net device */ struct pdev_osif_priv { struct wiphy *wiphy; @@ -40,14 +41,34 @@ struct pdev_osif_priv { }; /** - * struct vdev_osif_priv - OS private structure of vdev - * @wdev: wireless device handle - * @legacy_osif_priv: legacy osif private handle + * struct osif_cm_command_info - osif connection manager command info + * @last_source: Last command request source + * @last_id: Cookie from connection manager + * @cmd_id_lock: lock to update and read last command source + * @legacy: legacy data structure. Big data etc for MCC + */ +#ifdef FEATURE_CM_ENABLE +struct osif_cm_command_info { + enum wlan_cm_source last_source; + wlan_cm_id last_id; + struct qdf_spinlock cmd_id_lock; + void *legacy; +}; +#endif + +/** + * struct vdev_osif_priv - OS private structure of vdev + * @wdev: wireless device handle + * @legacy_osif_priv: legacy osif private handle + * @connect_info: osif connection manager command info */ struct vdev_osif_priv { struct wireless_dev *wdev; void *legacy_osif_priv; struct osif_tdls_vdev *osif_tdls; +#ifdef FEATURE_CM_ENABLE + struct osif_cm_command_info last_cmd_info; +#endif }; #endif diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c index 2feeea5d64d0..aa0e1be831ec 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c @@ -75,6 +75,50 @@ static QDF_STATUS wlan_objmgr_vdev_object_status( return status; } +#ifdef FEATURE_CM_ENABLE +/** + * wlan_vdev_mlme_create_cmd_id_lock() - Function to create connection + * manager command id lock + * @osif_priv: Pointer to osif private data structure of vdev + * + * Context: Any context. + * Return: None + */ + +static void +wlan_vdev_mlme_create_cmd_id_lock(struct vdev_osif_priv *osif_priv) +{ + qdf_spinlock_create(&osif_priv->last_cmd_info.cmd_id_lock); +} + +/** + * wlan_vdev_mlme_destroy_cmd_id_lock() - Function to destroy connection + * manager command id lock + * @osif_priv: Pointer to osif private data structure of vdev + * + * Context: Any context. + * Return: None + */ +static void +wlan_vdev_mlme_destroy_cmd_id_lock(struct vdev_osif_priv *osif_priv) +{ + qdf_spinlock_destroy(&osif_priv->last_cmd_info.cmd_id_lock); +} + +#else + +static inline void +wlan_vdev_mlme_create_cmd_id_lock(struct vdev_osif_priv *osif_priv) +{ +} + +static inline void +wlan_vdev_mlme_destroy_cmd_id_lock(struct vdev_osif_priv *osif_priv) +{ +} + +#endif + static QDF_STATUS wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev *vdev) { struct wlan_objmgr_pdev *pdev; @@ -97,6 +141,10 @@ static QDF_STATUS wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_E_FAILURE; } + if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE || + vdev->vdev_mlme.vdev_opmode == QDF_P2P_CLIENT_MODE) + wlan_vdev_mlme_destroy_cmd_id_lock(wlan_vdev_get_ospriv(vdev)); + /* Detach VDEV from PDEV VDEV's list */ if (wlan_objmgr_pdev_vdev_detach(pdev, vdev) == QDF_STATUS_E_FAILURE) @@ -213,6 +261,11 @@ struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create( vdev->vdev_objmgr.c_flags = params->flags; /* store os-specific pointer */ vdev->vdev_nif.osdev = wlan_objmgr_vdev_get_osif_priv(vdev); + + if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE || + vdev->vdev_mlme.vdev_opmode == QDF_P2P_CLIENT_MODE) + wlan_vdev_mlme_create_cmd_id_lock(vdev->vdev_nif.osdev); + /* peer count to 0 */ vdev->vdev_objmgr.wlan_peer_count = 0; qdf_atomic_init(&vdev->vdev_objmgr.ref_cnt); diff --git a/umac/mlme/include/wlan_mlme_cmn.h b/umac/mlme/include/wlan_mlme_cmn.h index 1b704d3313e5..37643ba3dbc4 100644 --- a/umac/mlme/include/wlan_mlme_cmn.h +++ b/umac/mlme/include/wlan_mlme_cmn.h @@ -39,8 +39,8 @@ * @vdev: vdev pointer * @rsp: connect response * - * @mlme_cm_update_conn_id_and_src_cb: Callback to update connect id and - * source of the connect request + * @mlme_cm_update_id_and_src_cb: Callback to update connect id and + * source of the connect request * @vdev: vdev pointer * @Source: Source of the connect req * @cm_id: connection manager id @@ -53,16 +53,21 @@ * @vdev: vdev pointer */ struct mlme_cm_ops { - void (*mlme_cm_connect_complete_cb)(struct wlan_objmgr_vdev *vdev, - struct wlan_cm_connect_rsp *rsp); - void (*mlme_cm_failed_candidate_cb)(struct wlan_objmgr_vdev *vdev, - struct wlan_cm_connect_rsp *rsp); - void (*mlme_cm_update_conn_id_and_src_cb)(struct wlan_objmgr_vdev *vdev, - enum wlan_cm_source source, - uint64_t cm_id); - void (*mlme_cm_disconnect_complete_cb)(struct wlan_objmgr_vdev *vdev, - struct wlan_cm_discon_rsp *rsp); - void (*mlme_cm_disconnect_start_cb)(struct wlan_objmgr_vdev *vdev); + QDF_STATUS (*mlme_cm_connect_complete_cb)( + struct wlan_objmgr_vdev *vdev, + struct wlan_cm_connect_rsp *rsp); + QDF_STATUS (*mlme_cm_failed_candidate_cb)( + struct wlan_objmgr_vdev *vdev, + struct wlan_cm_connect_rsp *rsp); + QDF_STATUS (*mlme_cm_update_id_and_src_cb)( + struct wlan_objmgr_vdev *vdev, + enum wlan_cm_source source, + wlan_cm_id cm_id); + QDF_STATUS (*mlme_cm_disconnect_complete_cb)( + struct wlan_objmgr_vdev *vdev, + struct wlan_cm_discon_rsp *rsp); + QDF_STATUS (*mlme_cm_disconnect_start_cb)( + struct wlan_objmgr_vdev *vdev); }; #endif diff --git a/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c b/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c index a43038b10ea7..e6a458b7f7c7 100644 --- a/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c +++ b/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c @@ -359,52 +359,62 @@ QDF_STATUS mlme_cm_vdev_down_req(struct wlan_objmgr_vdev *vdev) QDF_STATUS mlme_cm_osif_connect_complete(struct wlan_objmgr_vdev *vdev, struct wlan_cm_connect_rsp *rsp) { - if (glbl_cm_ops && glbl_cm_ops->mlme_cm_connect_complete_cb) - glbl_cm_ops->mlme_cm_connect_complete_cb(vdev, rsp); + QDF_STATUS ret = QDF_STATUS_SUCCESS; - return QDF_STATUS_SUCCESS; + if (glbl_cm_ops && glbl_cm_ops->mlme_cm_connect_complete_cb) + ret = glbl_cm_ops->mlme_cm_connect_complete_cb(vdev, rsp); + + return ret; } QDF_STATUS mlme_cm_osif_failed_candidate_ind(struct wlan_objmgr_vdev *vdev, struct wlan_cm_connect_rsp *rsp) { + QDF_STATUS ret = QDF_STATUS_SUCCESS; + if (glbl_cm_ops && glbl_cm_ops->mlme_cm_failed_candidate_cb) - glbl_cm_ops->mlme_cm_failed_candidate_cb(vdev, rsp); + ret = glbl_cm_ops->mlme_cm_failed_candidate_cb(vdev, rsp); - return QDF_STATUS_SUCCESS; + return ret; } QDF_STATUS mlme_cm_osif_update_id_and_src(struct wlan_objmgr_vdev *vdev, enum wlan_cm_source source, wlan_cm_id cm_id) { - if (glbl_cm_ops && - glbl_cm_ops->mlme_cm_update_conn_id_and_src_cb) - glbl_cm_ops->mlme_cm_update_conn_id_and_src_cb(vdev, source, - cm_id); + QDF_STATUS ret = QDF_STATUS_SUCCESS; - return QDF_STATUS_SUCCESS; + if (glbl_cm_ops && + glbl_cm_ops->mlme_cm_update_id_and_src_cb) + ret = glbl_cm_ops->mlme_cm_update_id_and_src_cb(vdev, source, + cm_id); + + return ret; } QDF_STATUS mlme_cm_osif_disconnect_complete(struct wlan_objmgr_vdev *vdev, struct wlan_cm_discon_rsp *rsp) { + QDF_STATUS ret = QDF_STATUS_SUCCESS; + if (glbl_cm_ops && glbl_cm_ops->mlme_cm_disconnect_complete_cb) - glbl_cm_ops->mlme_cm_disconnect_complete_cb(vdev, rsp); + ret = glbl_cm_ops->mlme_cm_disconnect_complete_cb(vdev, rsp); - return QDF_STATUS_SUCCESS; + return ret; } QDF_STATUS mlme_cm_osif_disconnect_start_ind(struct wlan_objmgr_vdev *vdev) { + QDF_STATUS ret = QDF_STATUS_SUCCESS; + if (glbl_cm_ops && glbl_cm_ops->mlme_cm_disconnect_start_cb) - glbl_cm_ops->mlme_cm_disconnect_start_cb(vdev); + ret = glbl_cm_ops->mlme_cm_disconnect_start_cb(vdev); - return QDF_STATUS_SUCCESS; + return ret; } void mlme_set_osif_cm_cb(osif_cm_get_global_ops_cb osif_cm_ops)