qcacld-3.0: Handle request to delete NAN Data Interface (NDI)

qcacld-2.0 to qcacld-3.0 propagation

Add changes to handle request to delete NAN datapath interface.

Change-Id: I3efef6adf6c7a974d3e344a7609f8517cd1aa752
CRs-Fixed: 962367
This commit is contained in:
Deepak Dhamdhere 2016-05-31 19:06:09 -07:00 • committed by Nandini Suresh
commit 13983f2571
19 changed files with 507 additions and 97 deletions

View file

@ -68,10 +68,7 @@
#include <wlan_hdd_lro.h>
#include "cdp_txrx_flow_ctrl_legacy.h"
#include <cdp_txrx_peer_ops.h>
#ifdef WLAN_FEATURE_NAN_DATAPATH
#include "wlan_hdd_nan_datapath.h"
#endif
/*---------------------------------------------------------------------------
Preprocessor definitions and constants

View file

@ -60,7 +60,6 @@
#include "ol_rx_fwd.h"
#include "cdp_txrx_flow_ctrl_legacy.h"
#include "cdp_txrx_peer_ops.h"
#include "wlan_hdd_nan_datapath.h"
/* These are needed to recognize WPA and RSN suite types */
#define HDD_WPA_OUI_SIZE 4

View file

@ -45,7 +45,6 @@
#include <wlan_hdd_misc.h>
#include <wlan_hdd_napi.h>
#include <cds_concurrency.h>
#include "wlan_hdd_nan_datapath.h"
static void
cb_notify_set_roam_prefer5_g_hz(hdd_context_t *pHddCtx, unsigned long notifyId)

View file

@ -89,7 +89,6 @@
#include "pld_common.h"
#include "wlan_hdd_ocb.h"
#include "wlan_hdd_nan.h"
#include "wlan_hdd_nan_datapath.h"
#include "wlan_hdd_debugfs.h"
#include "wlan_hdd_driver_ops.h"
#include "epping_main.h"
@ -105,7 +104,6 @@
#include <wlan_hdd_regulatory.h>
#include "ol_rx_fwd.h"
#include "wlan_hdd_lpass.h"
#include "wlan_hdd_nan_datapath.h"
#ifdef MODULE
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
@ -2170,6 +2168,12 @@ QDF_STATUS hdd_sme_close_session_callback(void *pContext)
return QDF_STATUS_NOT_INITIALIZED;
}
/*
* For NAN Data interface, the close session results in the final
* indication to the userspace
*/
hdd_ndp_session_end_handler(adapter);
clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
/*
@ -3056,21 +3060,33 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
case QDF_P2P_CLIENT_MODE:
case QDF_IBSS_MODE:
case QDF_P2P_DEVICE_MODE:
if (hdd_conn_is_connected(
case QDF_NDI_MODE:
if ((QDF_NDI_MODE == adapter->device_mode) ||
hdd_conn_is_connected(
WLAN_HDD_GET_STATION_CTX_PTR(adapter)) ||
hdd_is_connecting(
WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
if (pWextState->roamProfile.BSSType ==
eCSR_BSS_TYPE_START_IBSS)
qdf_ret_status =
sme_roam_disconnect(hdd_ctx->hHal,
adapter->sessionId,
eCSR_DISCONNECT_REASON_IBSS_LEAVE);
INIT_COMPLETION(adapter->disconnect_comp_var);
/*
* For NDI do not use pWextState from sta_ctx, if needed
* extract from ndi_ctx.
*/
if (QDF_NDI_MODE == adapter->device_mode)
qdf_ret_status = sme_roam_disconnect(
hdd_ctx->hHal,
adapter->sessionId,
eCSR_DISCONNECT_REASON_NDI_DELETE);
else if (pWextState->roamProfile.BSSType ==
eCSR_BSS_TYPE_START_IBSS)
qdf_ret_status = sme_roam_disconnect(
hdd_ctx->hHal,
adapter->sessionId,
eCSR_DISCONNECT_REASON_IBSS_LEAVE);
else
qdf_ret_status =
sme_roam_disconnect(hdd_ctx->hHal,
adapter->sessionId,
eCSR_DISCONNECT_REASON_UNSPECIFIED);
qdf_ret_status = sme_roam_disconnect(
hdd_ctx->hHal,
adapter->sessionId,
eCSR_DISCONNECT_REASON_UNSPECIFIED);
/* success implies disconnect command got queued up successfully */
if (qdf_ret_status == QDF_STATUS_SUCCESS) {
rc = wait_for_completion_timeout(

View file

@ -23,12 +23,12 @@
*
* WLAN Host Device Driver nan datapath API implementation
*/
#include <wlan_hdd_includes.h>
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include "wlan_hdd_includes.h"
#include "wlan_hdd_nan_datapath.h"
#include "wlan_hdd_p2p.h"
#include "wma_api.h"
@ -78,8 +78,8 @@ void hdd_ndp_print_ini_config(hdd_context_t *hdd_ctx)
* @hdd_ctx: Pointer to HDD context
* @cfg: Pointer to target device capability information
*
* NAN datapath functinality is enabled if it is enabled in
* .ini file and also supported in firmware.
* NAN datapath functionality is enabled if it is enabled in
* .ini file and also supported on target device.
*
* Return: None
*/
@ -110,7 +110,7 @@ static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
ENTER();
if (!roam_profile) {
hddLog(LOGE, FL("No valid roam profile"));
hdd_err(FL("No valid roam profile"));
return -EINVAL;
}
@ -153,7 +153,7 @@ static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
adapter->sessionId, roam_profile, &roam_id);
if (QDF_STATUS_SUCCESS != ret) {
hddLog(LOGE,
hdd_err(
FL("NDI sme_RoamConnect session %d failed with status %d -> NotConnected"),
adapter->sessionId, ret);
/* change back to NotConnected */
@ -193,13 +193,13 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
ENTER();
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
hddLog(LOGE, FL("Interface name string is unavailable"));
hdd_err(FL("Interface name string is unavailable"));
return -EINVAL;
}
iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
hddLog(LOGE, FL("transaction id is unavailable"));
hdd_err(FL("transaction id is unavailable"));
return -EINVAL;
}
transaction_id =
@ -208,7 +208,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
/* Check for an existing interface of NDI type */
adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
if (adapter) {
hddLog(LOGE, FL("Cannot support more than one NDI"));
hdd_err(FL("Cannot support more than one NDI"));
return -EEXIST;
}
@ -216,7 +216,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
true);
if (!adapter) {
hddLog(LOGE, FL("hdd_open_adapter failed"));
hdd_err(FL("hdd_open_adapter failed"));
return -ENOMEM;
}
@ -226,6 +226,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
*/
ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
ndp_ctx->ndp_create_transaction_id = transaction_id;
ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
/*
* The NAN data interface has been created at this point.
@ -242,7 +243,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
}
ret = hdd_ndi_start_bss(adapter, op_channel);
if (0 > ret)
hddLog(LOGE, FL("NDI start bss failed"));
hdd_err(FL("NDI start bss failed"));
EXIT();
return ret;
@ -258,7 +259,68 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
struct nlattr **tb)
{
return 0;
hdd_adapter_t *adapter;
char *iface_name;
uint16_t transaction_id;
struct nan_datapath_ctx *ndp_ctx;
int ret;
ENTER();
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
hdd_err(FL("Interface name string is unavailable"));
return -EINVAL;
}
iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
hdd_err(FL("Transaction id is unavailable"));
return -EINVAL;
}
transaction_id =
nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
/* Check if there is already an existing inteface with the same name */
adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
if (!adapter) {
hdd_err(FL("NAN data interface %s is not available"),
iface_name);
return -EINVAL;
}
/* check if adapter is in NDI mode */
if (QDF_NDI_MODE != adapter->device_mode) {
hdd_err(FL("Interface %s is not in NDI mode"),
iface_name);
return -EINVAL;
}
ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
if (!ndp_ctx) {
hdd_err(FL("ndp_ctx is NULL"));
return -EINVAL;
}
/* check if there are active NDP sessions on the adapter */
if (ndp_ctx->active_ndp_sessions > 0) {
hdd_err(FL("NDP sessions active %d, cannot delete NDI"),
ndp_ctx->active_ndp_sessions);
return -EINVAL;
}
ndp_ctx->ndp_delete_transaction_id = transaction_id;
ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
/* Delete the interface */
ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
if (ret < 0)
hdd_err(FL("NDI delete request failed"));
else
hdd_err(FL("NDI delete request successfully issued"));
return ret;
}
@ -348,7 +410,12 @@ static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
return;
if (!ndi_rsp) {
hddLog(LOGE, FL("Invalid ndi create response"));
hdd_err(FL("Invalid ndi create response"));
return;
}
if (!ndp_ctx) {
hdd_err(FL("ndp_ctx is NULL"));
return;
}
@ -360,35 +427,35 @@ static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
cds_get_gfp_flags());
if (!vendor_event) {
hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
hdd_err(FL("cfg80211_vendor_event_alloc failed"));
return;
}
/* Sub vendor command */
if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
hddLog(LOGE, FL("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail"));
hdd_err(FL("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail"));
goto nla_put_failure;
}
/* Transaction id */
if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
ndp_ctx->ndp_create_transaction_id)) {
hddLog(LOGE, FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"));
hdd_err(FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"));
goto nla_put_failure;
}
/* Status code */
if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
ndi_rsp->status)) {
hddLog(LOGE, FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"));
hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"));
goto nla_put_failure;
}
/* Status return value */
if (nla_put_u32(vendor_event,
QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0xA5)) {
hddLog(LOGE, FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"));
hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"));
goto nla_put_failure;
}
@ -408,10 +475,9 @@ static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
ndp_ctx->ndp_create_transaction_id = 0;
if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
hddLog(LOGE, FL("NDI interface successfully created"));
hdd_err(FL("NDI interface successfully created"));
} else {
hddLog(LOGE,
FL("NDI interface creation failed with reason %d"),
hdd_err(FL("NDI interface creation failed with reason %d"),
ndi_rsp->reason);
}
EXIT();
@ -432,9 +498,141 @@ nla_put_failure:
static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
void *rsp_params)
{
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct ndi_delete_rsp *ndi_rsp = rsp_params;
if (wlan_hdd_validate_context(hdd_ctx))
return;
if (!ndi_rsp) {
hdd_err(FL("Invalid ndi delete response"));
return;
}
if (ndi_rsp->status == QDF_STATUS_SUCCESS)
hdd_err(FL("NDI BSS successfully stopped"));
else
hdd_err(FL("NDI BSS stop failed with reason %d"),
ndi_rsp->reason);
complete(&adapter->disconnect_comp_var);
return;
}
/**
* hdd_ndp_session_end_handler() - NDI session termination handler
* @adapter: pointer to adapter context
*
* Following vendor event is sent to cfg80211:
* QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
* QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
* QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
* QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
* QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
*
* Return: none
*/
void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
{
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct sk_buff *vendor_event;
struct nan_datapath_ctx *ndp_ctx;
uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
(NLA_HDRLEN * 4) + NLMSG_HDRLEN;
ENTER();
if (wlan_hdd_validate_context(hdd_ctx))
return;
/* Handle only if adapter is in NDI mode */
if (QDF_NDI_MODE != adapter->device_mode) {
hdd_err(FL("Adapter is not in NDI mode"));
return;
}
ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
if (!ndp_ctx) {
hdd_err(FL("ndp context is NULL"));
return;
}
/*
* The virtual adapters are stopped and closed even during
* driver unload or stop, the service layer is not required
* to be informed in that case (response is not expected)
*/
if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
hdd_err(FL("NDI interface %s deleted"),
adapter->dev->name);
return;
}
/* notify response to the upper layer */
vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
NULL,
data_len,
QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
GFP_KERNEL);
if (!vendor_event) {
hdd_err(FL("cfg80211_vendor_event_alloc failed"));
return;
}
/* Sub vendor command goes first */
if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
hdd_err(FL("VENDOR_ATTR_NDP_SUBCMD put fail"));
goto failure;
}
/* Transaction id */
if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
ndp_ctx->ndp_delete_transaction_id)) {
hdd_err(FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"));
goto failure;
}
/* Status code */
if (nla_put_u32(vendor_event,
QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, 0x0)) {
hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"));
goto failure;
}
/* Status return value */
if (nla_put_u32(vendor_event,
QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0x0)) {
hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"));
goto failure;
}
hddLog(LOG2, FL("sub command: %d, value: %d"),
QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
hddLog(LOG2, FL("delete transaction id: %d, value: %d"),
QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
ndp_ctx->ndp_delete_transaction_id);
hddLog(LOG2, FL("status code: %d, value: %d"),
QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
true);
hddLog(LOG2, FL("Return value: %d, value: %d"),
QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0x5A);
ndp_ctx->ndp_delete_transaction_id = 0;
ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
cfg80211_vendor_event(vendor_event, GFP_KERNEL);
EXIT();
return;
failure:
kfree_skb(vendor_event);
}
/**
* hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
* @adapter: pointer to adapter context
@ -613,8 +811,7 @@ void hdd_ndp_event_handler(hdd_adapter_t *adapter,
&roam_info->ndp.ndp_end_ind_params);
break;
default:
hddLog(LOGE,
FL("Unknown NDP response event from SME %d"),
hdd_err(FL("Unknown NDP response event from SME %d"),
roam_result);
break;
}
@ -649,36 +846,36 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
return ret_val;
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
hddLog(LOGE, FL("Command not allowed in FTM mode"));
hdd_err(FL("Command not allowed in FTM mode"));
return -EPERM;
}
if (!hdd_ctx->config->enable_nan_datapath) {
hddLog(LOGE, FL("NAN datapath is not suported"));
hdd_err(FL("NAN datapath is not suported"));
return -EPERM;
}
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
data, data_len,
qca_wlan_vendor_ndp_policy)) {
hddLog(LOGE, FL("Invalid NDP vendor command attributes"));
hdd_err(FL("Invalid NDP vendor command attributes"));
return -EINVAL;
}
/* Parse and fetch NDP Command Type*/
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
hddLog(LOGE, FL("NAN datapath cmd type failed"));
hdd_err(FL("NAN datapath cmd type failed"));
return -EINVAL;
}
ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
hddLog(LOGE, FL("attr transaction id failed"));
hdd_err(FL("attr transaction id failed"));
return -EINVAL;
}
transaction_id = nla_get_u16(
tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
hddLog(LOGE, FL("Interface name string is unavailable"));
hdd_err(FL("Interface name string is unavailable"));
return -EINVAL;
}
iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
@ -706,7 +903,7 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
ret_val = hdd_ndp_schedule_req_handler(hdd_ctx, tb);
break;
default:
hddLog(LOGE, FL("Unrecognized NDP vendor cmd %d"),
hdd_err(FL("Unrecognized NDP vendor cmd %d"),
ndp_cmd_type);
ret_val = -EINVAL;
break;
@ -760,7 +957,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
if (QDF_STATUS_SUCCESS != status) {
hddLog(LOGE, "failed to get vdev type");
hdd_err("failed to get vdev type");
goto error_sme_open;
}
@ -769,7 +966,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
adapter, (uint8_t *)&adapter->macAddressCurrent,
&adapter->sessionId, type, sub_type);
if (QDF_STATUS_SUCCESS == status) {
hddLog(LOGE, "sme_open_session() failed with status code %d",
hdd_err("sme_open_session() failed with status code %d",
status);
ret_val = -EAGAIN;
goto error_sme_open;
@ -780,7 +977,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
&adapter->session_open_comp_var,
msecs_to_jiffies(timeout));
if (!rc) {
hddLog(LOGE,
hdd_err(
FL("Failed to open session, timeout code: %ld"), rc);
ret_val = -ETIMEDOUT;
goto error_sme_open;
@ -789,7 +986,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
/* Register wireless extensions */
ret_val = hdd_register_wext(wlan_dev);
if (0 > ret_val) {
hddLog(LOGE, FL("Wext registration failed with status code %d"),
hdd_err(FL("Wext registration failed with status code %d"),
ret_val);
ret_val = -EAGAIN;
goto error_register_wext;
@ -797,7 +994,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
status = hdd_init_tx_rx(adapter);
if (QDF_STATUS_SUCCESS != status) {
hddLog(LOGE, FL("hdd_init_tx_rx() init failed, status %d"),
hdd_err(FL("hdd_init_tx_rx() init failed, status %d"),
status);
ret_val = -EAGAIN;
goto error_init_txrx;
@ -807,7 +1004,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
status = hdd_wmm_adapter_init(adapter);
if (QDF_STATUS_SUCCESS != status) {
hddLog(LOGE, FL("hdd_wmm_adapter_init() failed, status %d"),
hdd_err(FL("hdd_wmm_adapter_init() failed, status %d"),
status);
ret_val = -EAGAIN;
goto error_wmm_init;
@ -820,7 +1017,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
(int)hdd_ctx->config->enableSifsBurst,
PDEV_CMD);
if (0 != ret_val) {
hddLog(LOGE, FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"),
hdd_err(FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"),
ret_val);
}
@ -846,8 +1043,7 @@ error_register_wext:
&adapter->session_close_comp_var,
msecs_to_jiffies(timeout));
if (rc <= 0) {
hddLog(LOGE,
FL("Session close failed status %ld"),
hdd_err(FL("Session close failed status %ld"),
rc);
ret_val = -ETIMEDOUT;
}

View file

@ -215,6 +215,7 @@ void hdd_ndp_event_handler(struct hdd_adapter_s *adapter,
int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
struct wireless_dev *wdev, const void *data, int data_len);
int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter);
void hdd_ndp_session_end_handler(hdd_adapter_t *adapter);
#else
static inline void hdd_ndp_print_ini_config(struct hdd_context_s *hdd_ctx)
{
@ -237,6 +238,9 @@ static inline int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
{
return 0;
}
static inline void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
{
}
#endif /* WLAN_FEATURE_NAN_DATAPATH */
#endif /* __WLAN_HDD_NAN_DATAPATH_H */

View file

@ -3435,34 +3435,39 @@ __lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
psessionEntry->smeSessionId = smesessionId;
psessionEntry->transactionId = smetransactionId;
/* BTAMP_STA and STA_IN_IBSS should NOT send Disassoc frame */
if (!LIM_IS_IBSS_ROLE(psessionEntry)) {
/* STA_IN_IBSS and NDI should NOT send Disassoc frame */
if (!LIM_IS_IBSS_ROLE(psessionEntry) &&
!LIM_IS_NDI_ROLE(psessionEntry)) {
tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES)
/* Send disassoc all stations associated thru TKIP */
__lim_counter_measures(pMac, psessionEntry);
else
lim_send_disassoc_mgmt_frame(pMac,
eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
bcAddr, psessionEntry, false);
eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
bcAddr, psessionEntry, false);
}
/* Free the buffer allocated in START_BSS_REQ */
qdf_mem_free(psessionEntry->addIeParams.probeRespData_buff);
psessionEntry->addIeParams.probeRespDataLen = 0;
psessionEntry->addIeParams.probeRespData_buff = NULL;
if (!LIM_IS_NDI_ROLE(psessionEntry)) {
/* Free the buffer allocated in START_BSS_REQ */
qdf_mem_free(psessionEntry->addIeParams.probeRespData_buff);
psessionEntry->addIeParams.probeRespDataLen = 0;
psessionEntry->addIeParams.probeRespData_buff = NULL;
qdf_mem_free(psessionEntry->addIeParams.assocRespData_buff);
psessionEntry->addIeParams.assocRespDataLen = 0;
psessionEntry->addIeParams.assocRespData_buff = NULL;
qdf_mem_free(psessionEntry->addIeParams.assocRespData_buff);
psessionEntry->addIeParams.assocRespDataLen = 0;
psessionEntry->addIeParams.assocRespData_buff = NULL;
qdf_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
psessionEntry->addIeParams.probeRespBCNDataLen = 0;
psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
/* lim_del_bss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg. */
pMac->lim.gLimIbssCoalescingHappened = false;
qdf_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
psessionEntry->addIeParams.probeRespBCNDataLen = 0;
psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
/*
* lim_del_bss is also called as part of coalescing,
* when we send DEL BSS followed by Add Bss msg.
*/
pMac->lim.gLimIbssCoalescingHappened = false;
}
for (i = 1; i < pMac->lim.gLimAssocStaLimit; i++) {
pStaDs =
dph_get_hash_entry(pMac, i, &psessionEntry->dph.dphHashTable);

View file

@ -57,6 +57,7 @@
#include "sir_api.h"
#include "cds_regdomain.h"
#include "lim_send_messages.h"
#include "nan_datapath.h"
static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
tpPESession session_entry, tSirResultCodes result_code,
@ -2249,12 +2250,12 @@ void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ MsgQ)
pDelBss->sessionId);
return;
}
if (LIM_IS_IBSS_ROLE(psessionEntry)) {
if (LIM_IS_IBSS_ROLE(psessionEntry))
lim_ibss_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
} else if (LIM_IS_UNKNOWN_ROLE(psessionEntry)) {
else if (LIM_IS_UNKNOWN_ROLE(psessionEntry))
lim_process_sme_del_bss_rsp(pMac, MsgQ->bodyval, psessionEntry);
}
else if (LIM_IS_NDI_ROLE(psessionEntry))
lim_ndi_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
else
lim_process_mlm_del_bss_rsp(pMac, MsgQ, psessionEntry);

View file

@ -27,6 +27,8 @@
#include "lim_utils.h"
#include "lim_api.h"
#include "nan_datapath.h"
#include "lim_types.h"
#include "lim_send_messages.h"
/**
* handle_ndp_request_message() - Function to handle NDP requests from SME
@ -97,3 +99,64 @@ end:
qdf_mem_free(lim_msgq->bodyptr);
lim_msgq->bodyptr = NULL;
}
/**
* lim_ndi_del_bss_rsp() - Handler for DEL BSS resp for NDI interface
* @mac_ctx: handle to mac structure
* @msg: pointer to message
* @session_entry: session entry
*
* Return: None
*/
void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx,
void *msg, tpPESession session_entry)
{
tSirResultCodes rc = eSIR_SME_SUCCESS;
tpDeleteBssParams del_bss = (tpDeleteBssParams) msg;
SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
if (del_bss == NULL) {
lim_log(mac_ctx, LOGE,
FL("NDI: DEL_BSS_RSP with no body!"));
rc = eSIR_SME_STOP_BSS_FAILURE;
goto end;
}
session_entry =
pe_find_session_by_session_id(mac_ctx, del_bss->sessionId);
if (!session_entry) {
lim_log(mac_ctx, LOGE,
FL("Session Does not exist for given sessionID"));
goto end;
}
if (del_bss->status != QDF_STATUS_SUCCESS) {
lim_log(mac_ctx, LOGE,
FL("NDI: DEL_BSS_RSP error (%x) Bss %d "),
del_bss->status, del_bss->bssIdx);
rc = eSIR_SME_STOP_BSS_FAILURE;
goto end;
}
if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE,
session_entry->selfMacAddr,
session_entry->selfMacAddr, NULL, NULL)
!= eSIR_SUCCESS) {
lim_log(mac_ctx, LOGE,
FL("NDI: DEL_BSS_RSP setLinkState failed"));
goto end;
}
session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
end:
if (del_bss)
qdf_mem_free(del_bss);
/* Delete PE session once BSS is deleted */
if (NULL != session_entry) {
lim_send_sme_rsp(mac_ctx, eWNI_SME_STOP_BSS_RSP,
rc, session_entry->smeSessionId,
session_entry->transactionId);
pe_delete_session(mac_ctx, session_entry);
session_entry = NULL;
}
}

View file

@ -109,6 +109,9 @@ QDF_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx,
void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
tpSirMsgQ lim_msg_q,
tpPESession session_entry);
/* Handler for DEL BSS resp for NDI interface */
void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx,
void *msg, tpPESession session_entry);
#else
/* Function to process NDP requests */
static inline QDF_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx,
@ -129,6 +132,10 @@ static inline void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
tpPESession session_entry)
{
}
static inline void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx,
void *msg, tpPESession session_entry)
{
}
#endif /* WLAN_FEATURE_NAN_DATAPATH */

View file

@ -646,6 +646,7 @@ typedef enum {
eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE,
eCSR_DISCONNECT_REASON_IBSS_LEAVE,
eCSR_DISCONNECT_REASON_STA_HAS_LEFT,
eCSR_DISCONNECT_REASON_NDI_DELETE,
} eCsrRoamDisconnectReason;
typedef enum {

View file

@ -71,7 +71,8 @@ void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
uint32_t result,
uint32_t *roam_status,
uint32_t *roam_result);
uint32_t *roam_result,
struct tagCsrRoamInfo *roam_info);
#else
/* Start NDI BSS */
@ -100,9 +101,10 @@ static inline void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
}
static inline void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
uint32_t result,
uint32_t *roam_status,
uint32_t *roam_result)
uint32_t result,
uint32_t *roam_status,
uint32_t *roam_result,
struct tagCsrRoamInfo *roam_info)
{
}
#endif /* WLAN_FEATURE_NAN_DATAPATH */

View file

@ -6398,12 +6398,15 @@ static void csr_roam_process_start_bss_success(tpAniSirGlobal mac_ctx,
}
if (CSR_IS_NDI(profile)) {
csr_roam_update_ndp_return_params(mac_ctx,
eCsrStartBssSuccess,
&roam_status, &roam_result);
csr_roam_fill_roaminfo_ndp(mac_ctx, &roam_info,
roam_result,
start_bss_rsp->statusCode,
0, 0);
eCsrStartBssSuccess,
&roam_status,
&roam_result,
&roam_info);
csr_roam_fill_roaminfo_ndp(mac_ctx,
&roam_info,
roam_result,
start_bss_rsp->statusCode,
0, 0);
}
/*
* Only tell upper layer is we start the BSS because Vista
@ -6880,7 +6883,7 @@ static bool csr_roam_process_results(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
if (CSR_IS_NDI(profile)) {
csr_roam_update_ndp_return_params(mac_ctx,
eCsrStartBssFailure,
&roam_status, &roam_result);
&roam_status, &roam_result, &roam_info);
csr_roam_fill_roaminfo_ndp(mac_ctx, &roam_info,
roam_result,
(start_bss_rsp) ? start_bss_rsp->statusCode :
@ -6972,6 +6975,24 @@ static bool csr_roam_process_results(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
SME_QOS_CSR_REASSOC_FAILURE, NULL);
#endif
break;
case eCsrStopBssSuccess:
if (CSR_IS_NDI(profile)) {
csr_roam_update_ndp_return_params(mac_ctx, res,
&roam_status, &roam_result, &roam_info);
csr_roam_call_callback(mac_ctx, session_id, &roam_info,
cmd->u.roamCmd.roamId,
roam_status, roam_result);
}
break;
case eCsrStopBssFailure:
if (CSR_IS_NDI(profile)) {
csr_roam_update_ndp_return_params(mac_ctx, res,
&roam_status, &roam_result, &roam_info);
csr_roam_call_callback(mac_ctx, session_id, &roam_info,
cmd->u.roamCmd.roamId,
roam_status, roam_result);
}
break;
case eCsrJoinFailure:
case eCsrNothingToJoin:
case eCsrJoinFailureDueToConcurrency:
@ -7984,9 +8005,12 @@ QDF_STATUS csr_roam_issue_disassociate_cmd(tpAniSirGlobal pMac, uint32_t session
pCommand->u.roamCmd.reason =
eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
FL
("SME convert to internal reason code eCsrStaHasLeft"));
FL("SME convert to internal reason code eCsrStaHasLeft"));
break;
case eCSR_DISCONNECT_REASON_NDI_DELETE:
pCommand->u.roamCmd.roamReason = eCsrStopBss;
pCommand->u.roamCmd.roamProfile.BSSType =
eCSR_BSS_TYPE_NDI;
default:
break;
}
@ -8048,7 +8072,8 @@ QDF_STATUS csr_roam_disconnect_internal(tpAniSirGlobal pMac, uint32_t sessionId,
/* Only issue disconnect when necessary */
if (csr_is_conn_state_connected(pMac, sessionId)
|| csr_is_bss_type_ibss(pSession->connectedProfile.BSSType)
|| csr_is_roam_command_waiting_for_session(pMac, sessionId)) {
|| csr_is_roam_command_waiting_for_session(pMac, sessionId)
|| CSR_IS_CONN_NDI(&pSession->connectedProfile)) {
sms_log(pMac, LOG2, FL("called"));
status = csr_roam_issue_disassociate_cmd(pMac, sessionId,
reason);
@ -8845,6 +8870,8 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac,
static void csr_roam_roaming_state_stop_bss_rsp_processor(tpAniSirGlobal pMac,
tSirSmeRsp *pSmeRsp)
{
eCsrRoamCompleteResult result_code = eCsrNothingToJoin;
#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
{
host_log_ibss_pkt_type *pIbssLog;
@ -8862,7 +8889,13 @@ static void csr_roam_roaming_state_stop_bss_rsp_processor(tpAniSirGlobal pMac,
pMac->roam.roamSession[pSmeRsp->sessionId].connectState =
eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(pMac, pSmeRsp->sessionId)) {
csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
if (CSR_IS_CONN_NDI(pMac->roam.roamSession[pSmeRsp->sessionId].
pCurRoamProfile)) {
result_code = eCsrStopBssSuccess;
if (pSmeRsp->statusCode != eSIR_SME_SUCCESS)
result_code = eCsrStopBssFailure;
}
csr_roam_complete(pMac, result_code, NULL);
} else
if (CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE
(pMac, pSmeRsp->sessionId)) {

View file

@ -140,7 +140,8 @@ typedef enum {
eCsrSilentlyStopRoaming,
eCsrSilentlyStopRoamingSaveState,
eCsrJoinFailureDueToConcurrency,
eCsrStopBssSuccess,
eCsrStopBssFailure,
} eCsrRoamCompleteResult;
typedef struct tagScanReqParam {

View file

@ -212,20 +212,33 @@ void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
* @result: result of the roaming command
* @roam_status: roam status returned to the roam command initiator
* @roam_result: roam result returned to the roam command initiator
* @roam_info: Roam info data structure to be updated
*
* Results: None
*/
void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
uint32_t result,
uint32_t *roam_status,
uint32_t *roam_result)
uint32_t *roam_result,
tCsrRoamInfo *roam_info)
{
switch (result) {
case eCsrStartBssSuccess:
case eCsrStartBssFailure:
*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
*roam_result = eCSR_ROAM_RESULT_NDP_CREATE_RSP;
break;
case eCsrStopBssSuccess:
*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
*roam_result = eCSR_ROAM_RESULT_NDP_DELETE_RSP;
roam_info->ndp.ndi_delete_params.status = QDF_STATUS_SUCCESS;
break;
case eCsrStopBssFailure:
*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
*roam_result = eCSR_ROAM_RESULT_NDP_DELETE_RSP;
roam_info->ndp.ndi_delete_params.status = QDF_STATUS_E_FAILURE;
break;
default:
sms_log(mac_ctx, LOGE,
FL("Invalid CSR Roam result code: %d"), result);

View file

@ -2122,6 +2122,9 @@ void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma,
struct set_ie_param *ie_params);
void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma,
struct set_ie_param *ie_params);
void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid,
u_int8_t vdev_id, ol_txrx_peer_handle peer,
bool roam_synch_in_progress);
#endif
struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma_handle);
WLAN_PHY_MODE wma_chan_phy_mode(u8 chan, enum phy_ch_width chan_width,

View file

@ -1378,7 +1378,11 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
}
if (wma_is_vdev_in_ibss_mode(wma, resp_event->vdev_id))
wma_delete_all_ibss_peers(wma, resp_event->vdev_id);
else {
else if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces,
resp_event->vdev_id)) {
wma_delete_all_nan_remote_peers(wma,
resp_event->vdev_id);
} else {
if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id)) {
wma_delete_all_ap_remote_peers(wma,
resp_event->vdev_id);
@ -4169,6 +4173,12 @@ void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
peer = ol_txrx_find_peer_by_addr(pdev,
wma->interfaces[params->smesessionId].addr,
&peer_id);
else if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces,
params->smesessionId))
/* In ndi case, self mac is used to create the self peer */
peer = ol_txrx_find_peer_by_addr(pdev,
wma->interfaces[params->smesessionId].addr,
&peer_id);
else
peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id);

View file

@ -253,3 +253,55 @@ send_fail_resp:
wma_send_msg(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
}
/**
* wma_delete_all_nan_remote_peers() - Delete all nan peers
* @wma: wma handle
* @vdev_id: vdev id
*
* Return: None
*/
void wma_delete_all_nan_remote_peers(tp_wma_handle wma, uint32_t vdev_id)
{
ol_txrx_vdev_handle vdev;
ol_txrx_peer_handle peer, temp;
if (vdev_id > wma->max_bssid) {
WMA_LOGE("%s: invalid vdev_id = %d", __func__, vdev_id);
return;
}
vdev = wma->interfaces[vdev_id].handle;
if (!vdev) {
WMA_LOGE("%s: vdev is NULL for vdev_id = %d",
__func__, vdev_id);
return;
}
/* remove all remote peers of ndi */
qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex);
temp = NULL;
TAILQ_FOREACH_REVERSE(peer, &vdev->peer_list,
peer_list_t, peer_list_elem) {
if (temp) {
qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex);
if (qdf_atomic_read(
&temp->delete_in_progress) == 0)
wma_remove_peer(wma, temp->mac_addr.raw,
vdev_id, temp, false);
qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex);
}
/* self peer is deleted last */
if (peer == TAILQ_FIRST(&vdev->peer_list)) {
WMA_LOGE("%s: self peer removed", __func__);
break;
} else
temp = peer;
}
qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex);
/* remove ndi self peer last */
peer = TAILQ_FIRST(&vdev->peer_list);
wma_remove_peer(wma, peer->mac_addr.raw, vdev_id, peer,
false);
}

View file

@ -31,6 +31,8 @@
#include "sir_api.h"
#ifdef WLAN_FEATURE_NAN_DATAPATH
#define WMA_IS_VDEV_IN_NDI_MODE(intf, vdev_id) \
(WMI_VDEV_TYPE_NDI == intf[vdev_id].type)
void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss);
@ -46,8 +48,10 @@ static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle,
{
tgt_cfg->nan_datapath_enabled = wma_handle->nan_datapath_enabled;
}
void wma_delete_all_nan_remote_peers(tp_wma_handle wma,
uint32_t vdev_id);
#else
#define WMA_IS_VDEV_IN_NDI_MODE(intf, vdev_id) (false)
static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle,
struct wma_tgt_cfg *tgt_cfg)
{
@ -59,6 +63,10 @@ static inline void wma_add_bss_ndi_mode(tp_wma_handle wma,
return;
}
#endif /* WLAN_FEATURE_NAN_DATAPATH */
static inline void wma_delete_all_nan_remote_peers(tp_wma_handle wma,
uint32_t vdev_id)
{
}
#endif /* WLAN_FEATURE_NAN_DATAPATH */
#endif /* __WMA_NAN_DATAPATH_H */