qcacmn: Add disconnect sync API to wait for disconnect to complete
Add sync API for disconnect to wait for disconnect to complete. This can be used during vdev delete sequence to move the vdev and connection manager SM to init state before VDEV is marked logically deleted. Change-Id: Id562e444cf1995d800b8268f906f811f143d0fc9 CRs-Fixed: 2790885
This commit is contained in:
@@ -38,8 +38,7 @@
|
||||
*
|
||||
* Return: int
|
||||
*/
|
||||
int osif_cm_connect(struct net_device *dev,
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
int osif_cm_connect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
|
||||
struct cfg80211_connect_params *req);
|
||||
|
||||
/**
|
||||
@@ -50,8 +49,17 @@ int osif_cm_connect(struct net_device *dev,
|
||||
*
|
||||
* Return: int
|
||||
*/
|
||||
int osif_cm_disconnect(struct net_device *dev,
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
|
||||
uint16_t reason);
|
||||
|
||||
/**
|
||||
* osif_cm_disconnect_sync() - Disconnect vdev and wait for it to complete
|
||||
* @vdev: vdev pointer
|
||||
* @reason: disconnect reason
|
||||
*
|
||||
* Return: int
|
||||
*/
|
||||
int osif_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, uint16_t reason);
|
||||
|
||||
#endif
|
||||
#endif /* __OSIF_CM_REQ_H */
|
||||
|
@@ -150,5 +150,7 @@ QDF_STATUS osif_disconnect_handler(struct wlan_objmgr_vdev *vdev,
|
||||
locally_generated, rsp->ap_discon_ie.ptr,
|
||||
rsp->ap_discon_ie.len, GFP_KERNEL);
|
||||
|
||||
qdf_event_set(&osif_priv->cm_info.disconnect_complete);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
* request apis.
|
||||
*/
|
||||
|
||||
#include "wlan_osif_priv.h"
|
||||
#include "osif_cm_req.h"
|
||||
#include "wlan_cm_ucfg_api.h"
|
||||
#include "wlan_nl_to_crypto_params.h"
|
||||
@@ -395,16 +396,11 @@ connect_start_fail:
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
|
||||
static QDF_STATUS osif_cm_send_disconnect(struct wlan_objmgr_vdev *vdev,
|
||||
uint16_t reason)
|
||||
{
|
||||
struct wlan_cm_disconnect_req *req;
|
||||
uint8_t vdev_id = vdev->vdev_objmgr.vdev_id;
|
||||
QDF_STATUS status;
|
||||
|
||||
osif_info("%s(vdevid-%d): Received Disconnect reason:%d %s",
|
||||
dev->name, vdev_id, reason,
|
||||
ucfg_cm_reason_code_to_str(reason));
|
||||
struct wlan_cm_disconnect_req *req;
|
||||
|
||||
status = osif_cm_reset_id_and_src(vdev);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
@@ -412,17 +408,62 @@ int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
|
||||
|
||||
req = qdf_mem_malloc(sizeof(*req));
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
req->vdev_id = vdev_id;
|
||||
req->vdev_id = wlan_vdev_get_id(vdev);
|
||||
req->source = CM_OSIF_DISCONNECT;
|
||||
req->reason_code = reason;
|
||||
status = ucfg_cm_start_disconnect(vdev, req);
|
||||
qdf_mem_free(req);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
|
||||
uint16_t reason)
|
||||
{
|
||||
uint8_t vdev_id = wlan_vdev_get_id(vdev);
|
||||
QDF_STATUS status;
|
||||
|
||||
osif_info("%s(vdevid-%d): Received Disconnect reason:%d %s",
|
||||
dev->name, vdev_id, reason,
|
||||
ucfg_cm_reason_code_to_str(reason));
|
||||
|
||||
status = osif_cm_send_disconnect(vdev, reason);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
osif_err("Disconnect failed with status %d", status);
|
||||
|
||||
qdf_mem_free(req);
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
int osif_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, uint16_t reason)
|
||||
{
|
||||
uint8_t vdev_id = wlan_vdev_get_id(vdev);
|
||||
struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
|
||||
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",
|
||||
vdev_id, reason, ucfg_cm_reason_code_to_str(reason));
|
||||
|
||||
qdf_event_reset(&osif_priv->cm_info.disconnect_complete);
|
||||
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);
|
||||
}
|
||||
|
@@ -261,6 +261,7 @@ QDF_STATUS osif_cm_osif_priv_init(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
|
||||
enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
QDF_STATUS status;
|
||||
|
||||
if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
@@ -272,7 +273,19 @@ QDF_STATUS osif_cm_osif_priv_init(struct wlan_objmgr_vdev *vdev)
|
||||
|
||||
qdf_spinlock_create(&osif_priv->cm_info.cmd_id_lock);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
status = qdf_event_create(&osif_priv->cm_info.disconnect_complete);
|
||||
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)
|
||||
@@ -287,7 +300,7 @@ QDF_STATUS osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
|
||||
osif_err("Invalid vdev osif priv");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
qdf_event_destroy(&osif_priv->cm_info.disconnect_complete);
|
||||
qdf_spinlock_destroy(&osif_priv->cm_info.cmd_id_lock);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#define _WLAN_OSIF_PRIV_H_
|
||||
|
||||
#include "qdf_net_if.h"
|
||||
#include <qdf_event.h>
|
||||
#include "wlan_cm_public_struct.h"
|
||||
#include <qca_vendor.h>
|
||||
|
||||
@@ -49,6 +50,7 @@ struct pdev_osif_priv {
|
||||
* @cmd_id_lock: lock to update and read last command source
|
||||
* @last_disconnect_reason: last disconnect reason to be indicated in get
|
||||
* station
|
||||
* @disconnect_complete: disconnect completion wait event
|
||||
* @ext_priv: legacy data pointer.
|
||||
*/
|
||||
struct osif_cm_info {
|
||||
@@ -56,6 +58,7 @@ struct osif_cm_info {
|
||||
wlan_cm_id last_id;
|
||||
struct qdf_spinlock cmd_id_lock;
|
||||
enum qca_disconnect_reason_codes last_disconnect_reason;
|
||||
qdf_event_t disconnect_complete;
|
||||
void *ext_priv;
|
||||
};
|
||||
#endif
|
||||
|
@@ -117,8 +117,6 @@ cm_ser_disconnect_cb(struct wlan_serialization_command *cmd,
|
||||
return status;
|
||||
}
|
||||
|
||||
#define DISCONNECT_TIMEOUT STOP_RESPONSE_TIMER + DELETE_RESPONSE_TIMER + 1000
|
||||
|
||||
static QDF_STATUS cm_ser_disconnect_req(struct wlan_objmgr_pdev *pdev,
|
||||
struct cnx_mgr *cm_ctx,
|
||||
struct cm_disconnect_req *req)
|
||||
|
@@ -31,6 +31,12 @@
|
||||
#define CM_ID_INVALID 0xFFFFFFFF
|
||||
typedef uint32_t wlan_cm_id;
|
||||
|
||||
/* Diconnect active timeout */
|
||||
#define DISCONNECT_TIMEOUT STOP_RESPONSE_TIMER + DELETE_RESPONSE_TIMER + 1000
|
||||
|
||||
/* Diconnect command wait timeout */
|
||||
#define CM_DISCONNECT_CMD_TIMEOUT DISCONNECT_TIMEOUT + 2000
|
||||
|
||||
/**
|
||||
* struct wlan_cm_wep_key_params - store wep key info
|
||||
* @key: key info
|
||||
|
Reference in New Issue
Block a user