qcacmn: Move disconnect wait logic from osif to connection mgr

Move disconnect wait logic from osif to connection mgr, so that
MLO/IF manager can use the wait logic for disconnect
during vdev delete.

Change-Id: Ied2bbcfd6a532209f8008499424f94acc41efc0e
CRs-Fixed: 2800990
This commit is contained in:
gaurank kathpalia
2020-10-20 12:14:54 +05:30
committed by snandini
parent abb7d72f97
commit b8b58d8d12
12 changed files with 125 additions and 46 deletions

View File

@@ -160,7 +160,6 @@ QDF_STATUS osif_disconnect_handler(struct wlan_objmgr_vdev *vdev,
rsp->ap_discon_ie.len, GFP_KERNEL); rsp->ap_discon_ie.len, GFP_KERNEL);
osif_cm_disconnect_comp_ind(vdev, rsp, OSIF_POST_USERSPACE_UPDATE); osif_cm_disconnect_comp_ind(vdev, rsp, OSIF_POST_USERSPACE_UPDATE);
qdf_event_set(&osif_priv->cm_info.disconnect_complete);
return status; return status;
} }

View File

@@ -489,31 +489,12 @@ int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
int osif_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, uint16_t reason) int osif_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, uint16_t reason)
{ {
uint8_t vdev_id = wlan_vdev_get_id(vdev); uint8_t vdev_id = wlan_vdev_get_id(vdev);
struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
QDF_STATUS status; QDF_STATUS status;
if (ucfg_cm_is_vdev_disconnected(vdev))
return 0;
if (!osif_priv) {
osif_err("vdev %d invalid vdev osif priv", vdev_id);
return -EINVAL;
}
osif_info("vdevid-%d: Received Disconnect reason:%d %s", osif_info("vdevid-%d: Received Disconnect reason:%d %s",
vdev_id, reason, ucfg_cm_reason_code_to_str(reason)); vdev_id, reason, ucfg_cm_reason_code_to_str(reason));
qdf_event_reset(&osif_priv->cm_info.disconnect_complete); status = ucfg_cm_disconnect_sync(vdev, CM_OSIF_DISCONNECT, reason);
status = osif_cm_send_disconnect(vdev, reason);
if (QDF_IS_STATUS_ERROR(status)) {
osif_err("Disconnect failed with status %d", status);
return qdf_status_to_os_return(status);
}
status = qdf_wait_single_event(&osif_priv->cm_info.disconnect_complete,
CM_DISCONNECT_CMD_TIMEOUT);
if (QDF_IS_STATUS_ERROR(status))
osif_err("Disconnect timeout with status %d", status);
return qdf_status_to_os_return(status); return qdf_status_to_os_return(status);
} }

View File

@@ -337,7 +337,6 @@ QDF_STATUS osif_cm_osif_priv_init(struct wlan_objmgr_vdev *vdev)
{ {
struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(vdev); enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(vdev);
QDF_STATUS status;
if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE) if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
@@ -349,19 +348,7 @@ QDF_STATUS osif_cm_osif_priv_init(struct wlan_objmgr_vdev *vdev)
qdf_spinlock_create(&osif_priv->cm_info.cmd_id_lock); qdf_spinlock_create(&osif_priv->cm_info.cmd_id_lock);
status = qdf_event_create(&osif_priv->cm_info.disconnect_complete); return QDF_STATUS_SUCCESS;
if (QDF_IS_STATUS_ERROR(status)) {
osif_err("failed to create disconnect complete event fro vdev %d",
wlan_vdev_get_id(vdev));
goto event_create_fail;
}
return status;
event_create_fail:
qdf_spinlock_destroy(&osif_priv->cm_info.cmd_id_lock);
return status;
} }
QDF_STATUS osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev *vdev) QDF_STATUS osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
@@ -376,7 +363,6 @@ QDF_STATUS osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
osif_err("Invalid vdev osif priv"); osif_err("Invalid vdev osif priv");
return QDF_STATUS_E_INVAL; return QDF_STATUS_E_INVAL;
} }
qdf_event_destroy(&osif_priv->cm_info.disconnect_complete);
qdf_spinlock_destroy(&osif_priv->cm_info.cmd_id_lock); qdf_spinlock_destroy(&osif_priv->cm_info.cmd_id_lock);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;

View File

@@ -21,7 +21,6 @@
#define _WLAN_OSIF_PRIV_H_ #define _WLAN_OSIF_PRIV_H_
#include "qdf_net_if.h" #include "qdf_net_if.h"
#include <qdf_event.h>
#include "wlan_cm_public_struct.h" #include "wlan_cm_public_struct.h"
#include <qca_vendor.h> #include <qca_vendor.h>
@@ -50,7 +49,6 @@ struct pdev_osif_priv {
* @cmd_id_lock: lock to update and read last command source * @cmd_id_lock: lock to update and read last command source
* @last_disconnect_reason: last disconnect reason to be indicated in get * @last_disconnect_reason: last disconnect reason to be indicated in get
* station * station
* @disconnect_complete: disconnect completion wait event
* @ext_priv: legacy data pointer. * @ext_priv: legacy data pointer.
*/ */
struct osif_cm_info { struct osif_cm_info {
@@ -58,7 +56,6 @@ struct osif_cm_info {
wlan_cm_id last_id; wlan_cm_id last_id;
struct qdf_spinlock cmd_id_lock; struct qdf_spinlock cmd_id_lock;
enum qca_disconnect_reason_codes last_disconnect_reason; enum qca_disconnect_reason_codes last_disconnect_reason;
qdf_event_t disconnect_complete;
void *ext_priv; void *ext_priv;
}; };
#endif #endif

View File

@@ -401,6 +401,10 @@ QDF_STATUS cm_disconnect_complete(struct cnx_mgr *cm_ctx,
if (!cm_ctx->disconnect_count && cm_ctx->connect_count) if (!cm_ctx->disconnect_count && cm_ctx->connect_count)
cm_flush_pending_request(cm_ctx, CONNECT_REQ_PREFIX, true); cm_flush_pending_request(cm_ctx, CONNECT_REQ_PREFIX, true);
/* Set the disconnect wait event once all disconnect are completed */
if (!cm_ctx->disconnect_count)
qdf_event_set(&cm_ctx->disconnect_complete);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
@@ -539,6 +543,31 @@ QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev,
return status; return status;
} }
QDF_STATUS cm_disconnect_start_req_sync(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req)
{
struct cnx_mgr *cm_ctx;
QDF_STATUS status;
cm_ctx = cm_get_cm_ctx(vdev);
if (!cm_ctx)
return QDF_STATUS_E_INVAL;
qdf_event_reset(&cm_ctx->disconnect_complete);
status = cm_disconnect_start_req(vdev, req);
if (QDF_IS_STATUS_ERROR(status)) {
mlme_err("Disconnect failed with status %d", status);
return status;
}
status = qdf_wait_single_event(&cm_ctx->disconnect_complete,
CM_DISCONNECT_CMD_TIMEOUT);
if (QDF_IS_STATUS_ERROR(status))
mlme_err("Disconnect timeout with status %d", status);
return status;
}
QDF_STATUS cm_disconnect_rsp(struct wlan_objmgr_vdev *vdev, QDF_STATUS cm_disconnect_rsp(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_discon_rsp *resp) struct wlan_cm_discon_rsp *resp)
{ {

View File

@@ -96,6 +96,7 @@ QDF_STATUS wlan_cm_init(struct vdev_mlme_obj *vdev_mlme)
"CM", "CM",
wlan_cm_scan_cb, wlan_cm_scan_cb,
vdev_mlme->cnx_mgr_ctx); vdev_mlme->cnx_mgr_ctx);
qdf_event_create(&vdev_mlme->cnx_mgr_ctx->disconnect_complete);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
@@ -110,6 +111,7 @@ QDF_STATUS wlan_cm_deinit(struct vdev_mlme_obj *vdev_mlme)
if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE)
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
qdf_event_destroy(&vdev_mlme->cnx_mgr_ctx->disconnect_complete);
scan_requester_id = vdev_mlme->cnx_mgr_ctx->scan_requester_id; scan_requester_id = vdev_mlme->cnx_mgr_ctx->scan_requester_id;
wlan_scan_unregister_requester(psoc, wlan_scan_unregister_requester(psoc,
scan_requester_id); scan_requester_id);

View File

@@ -24,6 +24,7 @@
#define __WLAN_CM_MAIN_H__ #define __WLAN_CM_MAIN_H__
#include "include/wlan_vdev_mlme.h" #include "include/wlan_vdev_mlme.h"
#include <qdf_event.h>
#ifdef FEATURE_CM_ENABLE #ifdef FEATURE_CM_ENABLE
#include <wlan_cm_public_struct.h> #include <wlan_cm_public_struct.h>
@@ -177,6 +178,7 @@ struct connect_ies {
* @global_cmd_id: global cmd id for getting cm id for connect/disconnect req * @global_cmd_id: global cmd id for getting cm id for connect/disconnect req
* @max_connect_attempts: Max attempts to be tried for a connect req * @max_connect_attempts: Max attempts to be tried for a connect req
* @scan_requester_id: scan requester id. * @scan_requester_id: scan requester id.
* @disconnect_complete: disconnect completion wait event
*/ */
struct cnx_mgr { struct cnx_mgr {
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
@@ -195,6 +197,7 @@ struct cnx_mgr {
qdf_atomic_t global_cmd_id; qdf_atomic_t global_cmd_id;
uint8_t max_connect_attempts; uint8_t max_connect_attempts;
wlan_scan_requester scan_requester_id; wlan_scan_requester scan_requester_id;
qdf_event_t disconnect_complete;
}; };
/** /**

View File

@@ -363,6 +363,20 @@ QDF_STATUS cm_add_disconnect_req_to_list(struct cnx_mgr *cm_ctx,
QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev, QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req); struct wlan_cm_disconnect_req *req);
/**
* cm_disconnect_start_req_sync() - disconnect request with wait till
* completed
* @vdev: vdev pointer
* @req: disconnect req
*
* Context: Only call for north bound disconnect req, if wait till complete
* is required, e.g. during vdev delete. Do not call from scheduler context.
*
* Return: QDF_STATUS
*/
QDF_STATUS cm_disconnect_start_req_sync(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req);
/** /**
* cm_bss_peer_delete_req() - Connection manager bss peer delete * cm_bss_peer_delete_req() - Connection manager bss peer delete
* request * request

View File

@@ -37,14 +37,36 @@ QDF_STATUS wlan_cm_start_connect(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_req *req); struct wlan_cm_connect_req *req);
/** /**
* wlan_cm_start_disconnect() - disconnect start request * wlan_cm_disconnect() - disconnect start request
* @vdev: vdev pointer * @vdev: vdev pointer
* @req: disconnect req * @source: disconnect source
* @reason_code: disconnect reason
* @bssid: bssid of AP to disconnect, can be null if not known
*
* Context: can be called from any context
* *
* Return: QDF_STATUS * Return: QDF_STATUS
*/ */
QDF_STATUS wlan_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, QDF_STATUS wlan_cm_disconnect(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req); enum wlan_cm_source source,
enum wlan_reason_code reason_code,
struct qdf_mac_addr *bssid);
/**
* wlan_cm_disconnect_sync() - disconnect request with wait till
* completed
* @vdev: vdev pointer
* @source: disconnect source
* @reason_code: disconnect reason
*
* Context: Only call for north bound disconnect req, if wait till complete
* is required, e.g. during vdev delete. Do not call from scheduler context.
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev,
enum wlan_cm_source source,
enum wlan_reason_code reason_code);
/** /**
* wlan_cm_bss_select_ind_rsp() - Connection manager resp for bss * wlan_cm_bss_select_ind_rsp() - Connection manager resp for bss

View File

@@ -47,6 +47,22 @@ QDF_STATUS ucfg_cm_start_connect(struct wlan_objmgr_vdev *vdev,
QDF_STATUS ucfg_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_cm_start_disconnect(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req); struct wlan_cm_disconnect_req *req);
/**
* ucfg_cm_disconnect_sync() - disconnect request with wait till
* completed
* @vdev: vdev pointer
* @source: disconnect source
* @reason_code: disconnect reason
*
* Context: Only call for north bound disconnect req, if wait till complete
* is required, e.g. during vdev delete. Do not call from scheduler context.
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev,
enum wlan_cm_source source,
enum wlan_reason_code reason_code);
/** /**
* ucfg_cm_is_vdev_connecting() - check if vdev is in conneting state * ucfg_cm_is_vdev_connecting() - check if vdev is in conneting state
* @vdev: vdev pointer * @vdev: vdev pointer

View File

@@ -29,10 +29,33 @@ QDF_STATUS wlan_cm_start_connect(struct wlan_objmgr_vdev *vdev,
return cm_connect_start_req(vdev, req); return cm_connect_start_req(vdev, req);
} }
QDF_STATUS wlan_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, QDF_STATUS wlan_cm_disconnect(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_disconnect_req *req) enum wlan_cm_source source,
enum wlan_reason_code reason_code,
struct qdf_mac_addr *bssid)
{ {
return cm_disconnect_start_req(vdev, req); struct wlan_cm_disconnect_req req = {0};
req.vdev_id = wlan_vdev_get_id(vdev);
req.source = source;
req.reason_code = reason_code;
if (bssid)
qdf_copy_macaddr(&req.bssid, bssid);
return cm_disconnect_start_req(vdev, &req);
}
QDF_STATUS wlan_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev,
enum wlan_cm_source source,
enum wlan_reason_code reason_code)
{
struct wlan_cm_disconnect_req req = {0};
req.vdev_id = wlan_vdev_get_id(vdev);
req.source = source;
req.reason_code = reason_code;
return cm_disconnect_start_req_sync(vdev, &req);
} }
QDF_STATUS wlan_cm_bss_select_ind_rsp(struct wlan_objmgr_vdev *vdev, QDF_STATUS wlan_cm_bss_select_ind_rsp(struct wlan_objmgr_vdev *vdev,

View File

@@ -35,6 +35,13 @@ QDF_STATUS ucfg_cm_start_disconnect(struct wlan_objmgr_vdev *vdev,
return cm_disconnect_start_req(vdev, req); return cm_disconnect_start_req(vdev, req);
} }
QDF_STATUS ucfg_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev,
enum wlan_cm_source source,
enum wlan_reason_code reason_code)
{
return wlan_cm_disconnect_sync(vdev, source, reason_code);
}
bool ucfg_cm_is_vdev_connecting(struct wlan_objmgr_vdev *vdev) bool ucfg_cm_is_vdev_connecting(struct wlan_objmgr_vdev *vdev)
{ {
return cm_is_vdev_connecting(vdev); return cm_is_vdev_connecting(vdev);