qcacmn: Handle disconnect ind to kernel for connection manager

Add support in connection manager for disconnect done indication
to kernel.

Change-Id: Ia4e767a95403de04268ed8c5e424974788c90b17
CRs-Fixed: 2765978
这个提交包含在:
Ashish Kumar Dhanotiya
2020-08-27 19:05:57 +05:30
提交者 snandini
父节点 96d7fbafaf
当前提交 45a6ac131e
修改 6 个文件,包含 197 行新增7 行删除

查看文件

@@ -24,4 +24,22 @@
#ifndef __WLAN_CFG80211_CM_RSP_H
#define __WLAN_CFG80211_CM_RSP_H
#include "wlan_objmgr_vdev_obj.h"
#include "wlan_cm_public_struct.h"
/**
* osif_disconnect_handler() - Indicate disconnnect to userspace
* @vdev: vdev pointer
* @rsp: Disconnect response from connection manager
*
* This function indicates disconnect to the kernel which thus indicates
* to the userspace.
*
* Context: Any context
* Return: QDF_STATUS_SUCCESS on successful indication to kernel,
* else QDF_STATUS with failure reason
*/
QDF_STATUS osif_disconnect_handler(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_discon_rsp *rsp);
#endif /* __WLAN_CFG80211_CM_RSP_H */

查看文件

@@ -31,4 +31,33 @@
* Return: QDF_STATUS
*/
QDF_STATUS osif_cm_register_cb(void);
/**
* osif_cm_reset_id_and_src_no_lock() - Function to resets last
* connection manager command id and source in osif
* @osif_priv: Pointer to vdev osif priv
*
* This function resets the last connection manager command id
* and source.
*
* Context: Any context. This function should be called by holding
* cmd id spinlock
* Return: None
*/
void osif_cm_reset_id_and_src_no_lock(struct vdev_osif_priv *osif_priv);
/**
* osif_cm_reset_id_and_src() - Function to resets last
* connection manager command id and source in osif
* @vdev: vdev pointer
*
* This function resets the last connection manager command id
* and source.
*
* Context: Any context. Takes and release cmd id spinlock
* Return: None
*/
QDF_STATUS osif_cm_reset_id_and_src(struct wlan_objmgr_vdev *vdev);
#endif /* __WLAN_CFG80211_CM_UTIL_H */

查看文件

@@ -20,3 +20,109 @@
* This file maintains definitaions of disconnect response
* fucntions.
*/
#include <wlan_cfg80211.h>
#include <linux/wireless.h>
#include "wlan_cfg80211_cm_rsp.h"
#include "wlan_osif_priv.h"
#include "wlan_cfg80211_cm_util.h"
/**
* osif_validate_disconnect_and_reset_src_id() - Validate disconnection
* and resets source and id
* @osif_priv: Pointer to vdev osif priv
* @rsp: Disconnect response from connectin manager
*
* This function validates disconnect response and if the disconnect
* response is valid, resets the source and id of the command
*
* Context: Any context. Takes and releases cmd id spinlock.
* Return: QDF_STATUS
*/
static QDF_STATUS
osif_validate_disconnect_and_reset_src_id(struct vdev_osif_priv *osif_priv,
struct wlan_cm_discon_rsp *rsp)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
/* Always drop internal disconnect */
qdf_spinlock_acquire(&osif_priv->last_cmd_info.cmd_id_lock);
if (rsp->req.req.source == CM_INTERNAL_DISCONNECT) {
osif_debug("ignore internal disconnect");
status = QDF_STATUS_E_INVAL;
goto rel_lock;
}
/*
* Send to kernel only if last osif cmd type is disconnect and
* cookie match else drop. If cookie match reset the cookie
* and source
*/
if (rsp->req.cm_id != osif_priv->last_cmd_info.last_id ||
rsp->req.req.source != osif_priv->last_cmd_info.last_source) {
osif_debug("Ignore as cm_id(%d)/src(%d) didn't match stored cm_id(%d)/src(%d)",
rsp->req.cm_id, rsp->req.req.source,
osif_priv->last_cmd_info.last_id,
osif_priv->last_cmd_info.last_source);
status = QDF_STATUS_E_INVAL;
goto rel_lock;
}
osif_cm_reset_id_and_src_no_lock(osif_priv);
rel_lock:
qdf_spinlock_release(&osif_priv->last_cmd_info.cmd_id_lock);
return status;
}
#if defined(CFG80211_DISCONNECTED_V2) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
static void
osif_cm_indicate_disconnect(struct net_device *dev,
enum ieee80211_reasoncode reason,
bool locally_generated, const u8 *ie,
size_t ie_len, gfp_t gfp)
{
cfg80211_disconnected(dev, reason, ie, ie_len, locally_generated, gfp);
}
#else
static void
osif_cm_indicate_disconnect(struct net_device *dev,
enum ieee80211_reasoncode reason,
bool locally_generated, const u8 *ie,
size_t ie_len, gfp_t gfp)
{
cfg80211_disconnected(dev, reason, ie, ie_len, gfp);
}
#endif
QDF_STATUS osif_disconnect_handler(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_discon_rsp *rsp)
{
enum ieee80211_reasoncode ieee80211_reason = rsp->req.req.reason_code;
struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
bool locally_generated = true;
QDF_STATUS status = QDF_STATUS_SUCCESS;
osif_info("%s(vdevid-%d): Disconnected, bssid: " QDF_MAC_ADDR_FMT " cm_id %d source %d reason_code %d locally_generated %d",
osif_priv->wdev->netdev->name,
rsp->req.req.vdev_id,
QDF_MAC_ADDR_REF(rsp->req.req.bssid.bytes),
rsp->req.cm_id, rsp->req.req.source,
rsp->req.req.reason_code,
locally_generated);
status = osif_validate_disconnect_and_reset_src_id(osif_priv, rsp);
if (QDF_IS_STATUS_ERROR(status))
return status;
if (rsp->req.req.source == CM_PEER_DISCONNECT)
locally_generated = false;
osif_cm_indicate_disconnect(osif_priv->wdev->netdev, ieee80211_reason,
locally_generated, rsp->ap_discon_ie.ptr,
rsp->ap_discon_ie.len, GFP_KERNEL);
return status;
}

查看文件

@@ -25,6 +25,7 @@
#include "wlan_cm_ucfg_api.h"
#include "wlan_nl_to_crypto_params.h"
#include <wlan_cfg80211.h>
#include "wlan_cfg80211_cm_util.h"
static void wlan_osif_free_wep_key_params(
struct wlan_cm_connect_req *connect_req)
@@ -319,6 +320,10 @@ int wlan_osif_cfg80211_connect(struct net_device *dev,
osif_dump_connect_req(dev, vdev_id, req);
status = osif_cm_reset_id_and_src(vdev);
if (QDF_IS_STATUS_ERROR(status))
return qdf_status_to_os_return(status);
connect_req = qdf_mem_malloc(sizeof(*connect_req));
if (!connect_req)
return -ENOMEM;
@@ -398,14 +403,18 @@ int wlan_osif_cfg80211_disconnect(struct net_device *dev,
uint8_t vdev_id = vdev->vdev_objmgr.vdev_id;
QDF_STATUS status;
req = qdf_mem_malloc(sizeof(*req));
if (!req)
return -ENOMEM;
/* print reason in string */
osif_info("%s(vdevid-%d): Received Disconnect reason:%d",
dev->name, vdev_id, reason);
status = osif_cm_reset_id_and_src(vdev);
if (QDF_IS_STATUS_ERROR(status))
return qdf_status_to_os_return(status);
req = qdf_mem_malloc(sizeof(*req));
if (!req)
return -ENOMEM;
req->vdev_id = vdev_id;
req->source = CM_OSIF_DISCONNECT;
req->reason_code = reason;

查看文件

@@ -24,6 +24,28 @@
#include "wlan_cfg80211_cm_util.h"
#include "wlan_osif_priv.h"
#include "wlan_cfg80211.h"
#include "wlan_cfg80211_cm_rsp.h"
void osif_cm_reset_id_and_src_no_lock(struct vdev_osif_priv *osif_priv)
{
osif_priv->last_cmd_info.last_id = CM_ID_INVALID;
osif_priv->last_cmd_info.last_source = CM_SOURCE_INVALID;
}
QDF_STATUS osif_cm_reset_id_and_src(struct wlan_objmgr_vdev *vdev)
{
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_cm_reset_id_and_src_no_lock(osif_priv);
qdf_spinlock_release(&osif_priv->last_cmd_info.cmd_id_lock);
return QDF_STATUS_SUCCESS;
}
/**
* osif_cm_connect_complete_cb() - Connect complete callback
@@ -85,16 +107,17 @@ osif_cm_update_id_and_src_cb(struct wlan_objmgr_vdev *vdev,
/**
* osif_cm_disconnect_complete_cb() - Disconnect done callback
* @vdev: vdev pointer
* @cm_disconnect_rsp: Disconnect response
* @disconnect_rsp: Disconnect response
*
* Context: Any context
* Return: QDF_STATUS
*/
static QDF_STATUS
osif_cm_disconnect_complete_cb(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_discon_rsp *cm_disconnect_rsp)
struct wlan_cm_discon_rsp *rsp)
{
return QDF_STATUS_SUCCESS;
return osif_disconnect_handler(vdev, rsp);
}
/**