From b0b838e6d5b2310ecf1d6a1ca534b0c1244a2eb6 Mon Sep 17 00:00:00 2001 From: Prakash Dhavali Date: Thu, 25 Feb 2016 23:29:32 -0800 Subject: [PATCH 01/39] Merge remote-tracking branch 'origin/caf/caf-wlan/master' into wlan-cmn.driver.lnx.1.0-dev Sync-up wlan-cmn.driver.lnx.1.0-dev branch to caf master version of host-common driver that is exactly same as qcacld-3.0 driver version 5.0.0.149 * origin/caf/caf-wlan/master: (294 commits) qcacld-3.0: Lower the log level for unhandled Action frame logs qcacld-3.0: Add disconnect to the head of sme pending command list Release 5.0.0.149 QCACLD3 WLAN Driver qcacld-3.0: Enable emergency reaping for wmi pipe. qcacld-3.0: add retry logic if htc_issue_packets fails qcacld-3.0: Ignore HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND from FW qcacld-3.0: Do not reserve mgmt descriptors qcacld-3.0: Use appropriate list API qcacld-3.0: Remove per vdev tx descriptor pool qcacld-3.0: Enable enahnced flow control qcacld-3.0: Add support for telescopic PNO ... Release 5.0.0.140 ... Initial readme for WLAN Host Driver for iHelium Change-Id: I36e7222946f442159390bd78a65ee5dc6876b582 CRs-Fixed: 688141 From 1226de9d0683dd55ae41c2207614fc105a436d2c Mon Sep 17 00:00:00 2001 From: Prakash Dhavali Date: Tue, 1 Mar 2016 09:05:38 -0800 Subject: [PATCH 02/39] Merge commit '0219ae6' into wlan-cmn.driver.lnx.1.0-dev Sync up wlan-cmn.driver.lnx.1.0-dev to CAF 5.0.0.160 from 5.0.0.149 release as baseline for subsequent win and mcl convergence refactoring. * commit '0219ae6': (554 commits) Release 5.0.0.160 qcacld-3.0: Add wma handler for vdev delete and peer delete responses Release 5.0.0.159 qcacld-3.0: Fix Compilation error on WLAN_FEATURE_11W disabled qcacld-3.0: Update channel width and center freq qcacld-3.0: Move sta state to not connected after try disconnect qcacld-3.0: Remove #ifdef FEATURE_WLAN_LFR from HDD qcacld-3.0: Remove RRM ie in Assoc Req based on AP capability qcacld-3.0: Fix fw statistics parsing on the host qcacld-3.0: Fix IPA-uc callback in NON-SMP system qcacld-3.0: SAP DFS-3 Feature support in DFS layer qcacld-3.0: SAP DFS-3 Feature support in WMA qcacld-3.0: correct phy_mode in hdd_chan_change_notify qcacld-3.0: move hif_bus_open to hif_open qcacld-3.0: Remove hif_claim_device qcacld-3.0: Remove epping context from cds qcacld-3.0: Enable Tx beamformee in SAP mode qcacld-3.0: Set the IMPS enable/disable based on INI qcacld-3.0: Fix memory leak in case of fw reset stats command qcacld-3.0: Use appropriate API to get total free descriptors ... qcacld-3.0: Enable athdiag debug support for SNOC devices qcacld-3.0: Remove support of power gating parameters qcacld-3.0: Add log in vos_mem_alloc if kzalloc takes more than 3 seconds Change-Id: I903d2b6edfb715570daffbcfcdb46866f04737dc CRs-Fixed: 688141 From aeeb03b4b258c3e514156822b753a3d9753e790e Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Thu, 15 Dec 2016 12:44:14 -0800 Subject: [PATCH 03/39] qcacmn: Add new files for new NAN component Add new files for new NAN component. Change-Id: I817723e518d53e9348d817746fc8318171d6ddf3 CRs-Fixed: 2014795 --- inc/os_if_nan.h | 26 ++++++++++++++++++++++++++ src/os_if_nan.c | 22 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 inc/os_if_nan.h create mode 100644 src/os_if_nan.c diff --git a/inc/os_if_nan.h b/inc/os_if_nan.h new file mode 100644 index 0000000000..41207a4635 --- /dev/null +++ b/inc/os_if_nan.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: declares nan component os interface APIs + */ + +#ifndef _OS_IF_NAN_H_ +#define _OS_IF_NAN_H_ + +#endif diff --git a/src/os_if_nan.c b/src/os_if_nan.c new file mode 100644 index 0000000000..3ee4c47069 --- /dev/null +++ b/src/os_if_nan.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: defines nan component os interface APIs + */ + From 74b2eb34fc6d30448b9c1f8c0ecc0e4c6fec4ee0 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Tue, 21 Mar 2017 15:12:22 -0700 Subject: [PATCH 04/39] qcacmn: Define NDP structures and enums and private obj 1) Define NDP structures and enum. 2) Define PSOC and VDEV private object Change-Id: I3cb3c0e357f8b4598a0e4ec8abbd5b69e5de5180 CRs-Fixed: 2014795 --- inc/os_if_nan.h | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/inc/os_if_nan.h b/inc/os_if_nan.h index 41207a4635..3843abacfa 100644 --- a/inc/os_if_nan.h +++ b/inc/os_if_nan.h @@ -23,4 +23,95 @@ #ifndef _OS_IF_NAN_H_ #define _OS_IF_NAN_H_ +#ifdef WLAN_FEATURE_NAN_CONVERGENCE + +#define NDP_QOS_INFO_LEN 255 +#define NDP_APP_INFO_LEN 255 +#define NDP_PMK_LEN 32 +#define NDP_SCID_BUF_LEN 256 +#define NDP_NUM_INSTANCE_ID 255 + +/** + * enum qca_wlan_vendor_attr_ndp_params - vendor attribute parameters + * @QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD: NDP Sub command + * @QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID: Transaction id reference + * @QCA_WLAN_VENDOR_ATTR_NDP_STATUS_ID: NDP status id + * @QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID: Service instance id + * @QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL: Requested channel + * @QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR: Peer discovery mac addr + * @QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR: Iface name + * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY: Security configuration + * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS: Qos configuration + * @QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO: Application info + * @QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID: NDP instance id + * @QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY: NDP instance id array + * @QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE: Schedule response + * @QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR: NDI mac address + * @QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE: Driver return status + * @QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE: Driver return value + * @QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG: Channel config request type + * @QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE: Cipher Suit ID + * @QCA_WLAN_VENDOR_ATTR_NDP_PMK: Pairwise Master Key + * @QCA_WLAN_VENDOR_ATTR_NDP_SCID: Security Context ID + */ +enum qca_wlan_vendor_attr_ndp_params { + QCA_WLAN_VENDOR_ATTR_NDP_PARAM_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + /* CONFIG_SECURITY is deprecated, use NCS_SK_TYPE/PMK/SCID instead */ + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY, + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, + QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, + QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, + QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG, + QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE, + QCA_WLAN_VENDOR_ATTR_NDP_PMK, + QCA_WLAN_VENDOR_ATTR_NDP_SCID, + + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ndp_sub_cmd_value - NDP subcmd value + * @QCA_WLAN_VENDOR_ATTR_NDP_INVALID: Unused subcmd value + * @QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE: iface create + * @QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE: iface delete + * @QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST: NDP initiator request + * @QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE: NDP initiator response + * @QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST: NDP responder request + * @QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE: NDP responder response + * @QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST: NDP end request + * @QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE: NDP end response + * @QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND: NDP request indication + * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND: NDP confirm indication + * @QCA_WLAN_VENDOR_ATTR_NDP_END_IND: NDP End indication + */ +enum qca_wlan_vendor_attr_ndp_sub_cmd_value { + QCA_WLAN_VENDOR_ATTR_NDP_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE = 1, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE = 2, + QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST = 3, + QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE = 4, + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST = 5, + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE = 6, + QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST = 7, + QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE = 8, + QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND = 9, + QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND = 10, + QCA_WLAN_VENDOR_ATTR_NDP_END_IND = 11 +}; + +#endif /* WLAN_FEATURE_NAN_CONVERGENCE */ + #endif From 574d9b4316d63fd4acd92b2c23e478525d60bc6e Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Sun, 2 Apr 2017 18:25:54 -0700 Subject: [PATCH 05/39] qcacmn: Add framework for NDP cmd execution Add NDP command execution framework: 1) Define UCFG apis, that will be called from OS_IF layer 2) Define request proccessing functions to post to scheduler and callback. 3) Define request proccessing functions to post to serializer and callback. 4) Define functions handling activated, cancelled and timed out NDP req. Change-Id: Ibc6fe32c65f8de0c24e0537f2eb538f806cf5284 CRs-Fixed: 2014795 --- inc/os_if_nan.h | 29 +++++++++++++++ src/os_if_nan.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/inc/os_if_nan.h b/inc/os_if_nan.h index 3843abacfa..4e263d5ef6 100644 --- a/inc/os_if_nan.h +++ b/inc/os_if_nan.h @@ -23,6 +23,11 @@ #ifndef _OS_IF_NAN_H_ #define _OS_IF_NAN_H_ +#include "qdf_types.h" + +struct wlan_objmgr_psoc; +struct wlan_objmgr_vdev; + #ifdef WLAN_FEATURE_NAN_CONVERGENCE #define NDP_QOS_INFO_LEN 255 @@ -114,4 +119,28 @@ enum qca_wlan_vendor_attr_ndp_sub_cmd_value { #endif /* WLAN_FEATURE_NAN_CONVERGENCE */ +/** + * os_if_nan_process_ndp_cmd: os_if api to handle nan request message + * @psoc: pointer to psoc object + * @data: request data. contains vendor cmd tlvs + * @data_len: length of data + * + * Return: status of operation + */ +int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, + const void *data, int data_len); + +/** + * os_if_nan_event_handler: os_if handler api for nan response messages + * @psoc: pointer to psoc object + * @vdev: pointer to vdev object + * @type: message type + * @msg: msg buffer + * + * Return: None + */ +void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev, + uint32_t type, void *msg); + #endif diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 3ee4c47069..5d260ecc32 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -20,3 +20,99 @@ * DOC: defines nan component os interface APIs */ +#include "qdf_types.h" +#include "qdf_trace.h" +#include "os_if_nan.h" +#include "wlan_nlink_srv.h" +#include "nan_public_structs.h" +#include "wlan_cfg80211.h" + +/* NLA policy */ +static const struct nla_policy +vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 }, + [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_STRING, + .len = IFNAMSIZ }, + [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = { + .type = NLA_BINARY, + .len = QDF_MAC_ADDR_SIZE }, + [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 }, + [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY, + .len = NDP_QOS_INFO_LEN }, + [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY, + .len = NDP_APP_INFO_LEN }, + [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 }, + [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY, + .len = QDF_MAC_ADDR_SIZE }, + [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY, + .len = NDP_NUM_INSTANCE_ID }, + [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { .type = NLA_BINARY, + .len = NDP_PMK_LEN }, + [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { .type = NLA_BINARY, + .len = NDP_SCID_BUF_LEN }, + [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { .type = + NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 }, +}; + +int os_if_nan_process_ndp_cmd(void *ctx, struct wlan_objmgr_psoc *psoc, + const void *data, int data_len) +{ + uint32_t ndp_cmd_type; + uint16_t transaction_id; + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1]; + char *iface_name; + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX, + data, data_len, vendor_attr_policy)) { + cfg80211_err("Invalid NDP vendor command attributes"); + return -EINVAL; + } + + /* Parse and fetch NDP Command Type*/ + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) { + cfg80211_err("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]) { + cfg80211_err("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]) { + iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + cfg80211_err("Transaction Id: %d NDPCmd: %d iface_name: %s", + transaction_id, ndp_cmd_type, iface_name); + } else { + cfg80211_err("Transaction Id: %d NDPCmd: %d iface_name: unspecified", + transaction_id, ndp_cmd_type); + } + + switch (ndp_cmd_type) { + default: + cfg80211_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type); + return -EINVAL; + } + + return -EINVAL; +} + +void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev, + uint32_t type, void *msg) +{ + switch (type) { + default: + break; + } +} From 85f642e6c6508f2d9ac4df3c0af7d1103bb32814 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Sun, 2 Apr 2017 19:39:25 -0700 Subject: [PATCH 06/39] qcacmn: Add implementation for NDI Create/Delete Implement NDI create and NDI delete commands. Change-Id: Icd4c745f4d25c0f10f12271fd4fcd7720ad85860 CRs-Fixed: 2014795 --- inc/os_if_nan.h | 102 +++++++++++- src/os_if_nan.c | 413 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 511 insertions(+), 4 deletions(-) diff --git a/inc/os_if_nan.h b/inc/os_if_nan.h index 4e263d5ef6..9b8fc9f3db 100644 --- a/inc/os_if_nan.h +++ b/inc/os_if_nan.h @@ -24,6 +24,8 @@ #define _OS_IF_NAN_H_ #include "qdf_types.h" +#include "nan_public_structs.h" +#include "nan_ucfg_api.h" struct wlan_objmgr_psoc; struct wlan_objmgr_vdev; @@ -117,8 +119,6 @@ enum qca_wlan_vendor_attr_ndp_sub_cmd_value { QCA_WLAN_VENDOR_ATTR_NDP_END_IND = 11 }; -#endif /* WLAN_FEATURE_NAN_CONVERGENCE */ - /** * os_if_nan_process_ndp_cmd: os_if api to handle nan request message * @psoc: pointer to psoc object @@ -143,4 +143,102 @@ void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, uint32_t type, void *msg); +/** + * os_if_nan_register_hdd_callbacks: os_if api to register hdd callbacks + * @psoc: pointer to psoc object + * @cb_obj: struct pointer containing callbacks + * + * Return: status of operation + */ +int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, + struct nan_callbacks *cb_obj); + +/** + * os_if_nan_post_ndi_create_rsp: os_if api to pos ndi create rsp to umac nan + * component + * @psoc: pointer to psoc object + * @vdev_id: vdev id of ndi + * @success: if create was success or failure + * + * Return: None + */ +void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool success); + +/** + * os_if_nan_post_ndi_delete_rsp: os_if api to pos ndi delete rsp to umac nan + * component + * @psoc: pointer to psoc object + * @vdev_id: vdev id of ndi + * @success: if delete was success or failure + * + * Return: None + */ +void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool success); + +/** + * os_if_nan_ndi_session_end: os_if api to process ndi session end + * component + * @vdev: pointer to vdev deleted + * + * Return: None + */ +void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev); + +/** + * os_if_nan_set_ndi_state: os_if api set NDI state + * @vdev: pointer to vdev deleted + * @state: value to set + * + * Return: status of operation + */ +static inline QDF_STATUS os_if_nan_set_ndi_state(struct wlan_objmgr_vdev *vdev, + uint32_t state) +{ + return ucfg_nan_set_ndi_state(vdev, state); +} + +/** + * os_if_nan_set_ndp_create_transaction_id: set ndp create transaction id + * @vdev: pointer to vdev object + * @val: value to set + * + * Return: status of operation + */ +static inline QDF_STATUS os_if_nan_set_ndp_create_transaction_id( + struct wlan_objmgr_vdev *vdev, + uint16_t val) +{ + return ucfg_nan_set_ndp_create_transaction_id(vdev, val); +} + +/** + * os_if_nan_set_ndp_delete_transaction_id: set ndp delete transaction id + * @vdev: pointer to vdev object + * @val: value to set + * + * Return: status of operation + */ +static inline QDF_STATUS os_if_nan_set_ndp_delete_transaction_id( + struct wlan_objmgr_vdev *vdev, + uint16_t val) +{ + return ucfg_nan_set_ndp_delete_transaction_id(vdev, val); +} + +#else + +static inline void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool success) +{ +} + +static inline void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool success) +{ +} + +#endif /* WLAN_FEATURE_NAN_CONVERGENCE */ + #endif diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 5d260ecc32..311a26085d 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -23,9 +23,14 @@ #include "qdf_types.h" #include "qdf_trace.h" #include "os_if_nan.h" -#include "wlan_nlink_srv.h" +#include "wlan_nan_api.h" #include "nan_public_structs.h" +#include "wlan_osif_priv.h" +#include #include "wlan_cfg80211.h" +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_objmgr_pdev_obj.h" +#include "wlan_objmgr_vdev_obj.h" /* NLA policy */ static const struct nla_policy @@ -61,7 +66,109 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 }, }; -int os_if_nan_process_ndp_cmd(void *ctx, struct wlan_objmgr_psoc *psoc, +static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, + struct nlattr **tb) +{ + char *iface_name; + QDF_STATUS status; + uint16_t transaction_id; + struct wlan_objmgr_vdev *nan_vdev; + struct nan_callbacks cb_obj; + + cfg80211_debug("enter"); + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + cfg80211_err("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]) { + cfg80211_err("transaction id is unavailable"); + return -EINVAL; + } + transaction_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + + status = ucfg_nan_get_callbacks(psoc, &cb_obj); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("Couldn't get ballback object"); + return -EINVAL; + } + + nan_vdev = cb_obj.ndi_open(iface_name); + + if (!nan_vdev) { + cfg80211_err("ndi_open failed"); + return -EINVAL; + } + + /* + * Create transaction id is required to be saved since the firmware + * does not honor the transaction id for create request + */ + ucfg_nan_set_ndp_create_transaction_id(nan_vdev, transaction_id); + ucfg_nan_set_ndi_state(nan_vdev, NAN_DATA_NDI_CREATING_STATE); + + return cb_obj.ndi_start(wlan_vdev_get_id(nan_vdev)); +} + +static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, + struct nlattr **tb) +{ + uint8_t vdev_id; + char *iface_name; + QDF_STATUS status; + uint32_t num_peers; + uint16_t transaction_id; + struct nan_callbacks cb_obj; + struct wlan_objmgr_vdev *nan_vdev = NULL; + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + cfg80211_err("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]) { + cfg80211_err("Transaction id is unavailable"); + return -EINVAL; + } + + nan_vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID); + if (!nan_vdev) { + cfg80211_err("Nan datapath interface is not present"); + return -EINVAL; + } + + transaction_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + vdev_id = wlan_vdev_get_id(nan_vdev); + num_peers = ucfg_nan_get_active_peers(nan_vdev); + /* + * wlan_objmgr_get_vdev_by_opmode_from_psoc API will have incremented + * ref count - decrement here since vdev returned by that api is not + * used any more + */ + wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); + + /* check if there are active peers on the adapter */ + if (num_peers) { + cfg80211_err("NDP peers active: %d, cannot delete NDI", + num_peers); + return -EINVAL; + } + + status = ucfg_nan_get_callbacks(psoc, &cb_obj); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("Couldn't get ballback object"); + return -EINVAL; + } + + return cb_obj.ndi_delete(vdev_id, iface_name, transaction_id); +} + +int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, const void *data, int data_len) { uint32_t ndp_cmd_type; @@ -98,7 +205,12 @@ int os_if_nan_process_ndp_cmd(void *ctx, struct wlan_objmgr_psoc *psoc, transaction_id, ndp_cmd_type); } + cfg80211_debug("Received NDP cmd: %d", ndp_cmd_type); switch (ndp_cmd_type) { + case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE: + return os_if_nan_process_ndi_create(psoc, tb); + case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE: + return os_if_nan_process_ndi_delete(psoc, tb); default: cfg80211_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type); return -EINVAL; @@ -107,12 +219,309 @@ int os_if_nan_process_ndp_cmd(void *ctx, struct wlan_objmgr_psoc *psoc, return -EINVAL; } +/** + * os_if_ndp_iface_create_rsp_handler() - NDP iface create response handler + * @adapter: pointer to adapter context + * @rsp_params: response parameters + * + * The function is expected to send a response back to the user space + * even if the creation of BSS has failed + * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE + * + * Return: none + */ +static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev, + void *rsp_params) +{ + QDF_STATUS status; + bool create_fail = false; + struct nan_callbacks cb_obj; + struct sk_buff *vendor_event; + uint8_t create_transaction_id; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + uint32_t create_status = NAN_DATAPATH_RSP_STATUS_ERROR; + uint32_t create_reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED; + struct nan_datapath_inf_create_rsp *ndi_rsp = + (struct nan_datapath_inf_create_rsp *)rsp_params; + uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) + + NLMSG_HDRLEN + (4 * NLA_HDRLEN); + + status = ucfg_nan_get_callbacks(psoc, &cb_obj); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("Couldn't get ballback object"); + return; + } + + if (ndi_rsp) { + create_status = ndi_rsp->status; + create_reason = ndi_rsp->reason; + } else { + cfg80211_err("Invalid ndi create response"); + create_fail = true; + } + + create_transaction_id = ucfg_nan_get_ndp_create_transaction_id(vdev); + + /* notify response to the upper layer */ + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, + NULL, + data_len, + QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_KERNEL); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + create_fail = true; + goto close_ndi; + } + + /* Sub vendor command */ + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) { + cfg80211_err("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, + create_transaction_id)) { + cfg80211_err("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_RESPONSE_STATUS_TYPE, + create_status)) { + cfg80211_err("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, + create_reason)) { + cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"); + goto nla_put_failure; + } + + cfg80211_debug("sub command: %d, value: %d", + QCA_NL80211_VENDOR_SUBCMD_NDP, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE); + cfg80211_debug("create transaction id: %d, value: %d", + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id); + cfg80211_debug("status code: %d, value: %d", + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + create_status); + cfg80211_debug("Return value: %d, value: %d", + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason); + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + + if (!create_fail) { + /* update txrx queues and register self sta */ + cb_obj.drv_ndi_create_rsp_handler(wlan_vdev_get_id(vdev), + ndi_rsp); + } else { + cfg80211_err("NDI interface creation failed with reason %d", + ndi_rsp->reason); + goto close_ndi; + } + + return; + +nla_put_failure: + kfree_skb(vendor_event); +close_ndi: + cb_obj.ndi_close(wlan_vdev_get_id(vdev)); + return; +} + +/** + * os_if_ndp_iface_delete_rsp_handler() - NDP iface delete response handler + * @adapter: pointer to adapter context + * @rsp_params: response parameters + * + * Return: none + */ +static void os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev, + void *rsp_params) +{ + QDF_STATUS status; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + struct nan_datapath_inf_delete_rsp *ndi_rsp = rsp_params; + struct nan_callbacks cb_obj; + + if (!ndi_rsp) { + cfg80211_err("Invalid ndi delete response"); + return; + } + + status = ucfg_nan_get_callbacks(psoc, &cb_obj); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("Couldn't get ballback object"); + return; + } + + if (ndi_rsp->status == NAN_DATAPATH_RSP_STATUS_SUCCESS) + cfg80211_debug("NDI BSS successfully stopped"); + else + cfg80211_debug("NDI BSS stop failed with reason %d", + ndi_rsp->reason); + + ucfg_nan_set_ndi_delete_rsp_reason(vdev, ndi_rsp->reason); + ucfg_nan_set_ndi_delete_rsp_status(vdev, ndi_rsp->status); + cb_obj.drv_ndi_delete_rsp_handler(vdev_id); +} + void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, uint32_t type, void *msg) { switch (type) { + case NAN_DATAPATH_INF_CREATE_RSP: + os_if_ndp_iface_create_rsp_handler(psoc, vdev, msg); + break; + case NAN_DATAPATH_INF_DELETE_RSP: + os_if_ndp_iface_delete_rsp_handler(psoc, vdev, msg); + break; default: break; } } + +int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, + struct nan_callbacks *cb_obj) +{ + return ucfg_nan_register_hdd_callbacks(psoc, cb_obj, + os_if_nan_event_handler); +} + +void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool success) +{ + struct nan_datapath_inf_create_rsp rsp = {0}; + struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc( + psoc, vdev_id, WLAN_NAN_ID); + + if (success) { + rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS; + rsp.reason = 0; + os_if_nan_event_handler(psoc, vdev, + NAN_DATAPATH_INF_CREATE_RSP, &rsp); + } else { + rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR; + rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED; + os_if_nan_event_handler(psoc, vdev, + NAN_DATAPATH_INF_CREATE_RSP, &rsp); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID); +} + +void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool success) +{ + struct nan_datapath_inf_delete_rsp rsp = {0}; + struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc( + psoc, vdev_id, WLAN_NAN_ID); + if (success) { + rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS; + rsp.reason = 0; + os_if_nan_event_handler(psoc, vdev, + NAN_DATAPATH_INF_DELETE_RSP, &rsp); + } else { + rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR; + rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_DELETE_FAILED; + os_if_nan_event_handler(psoc, vdev, + NAN_DATAPATH_INF_DELETE_RSP, &rsp); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID); +} + +void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) +{ + struct sk_buff *vendor_event; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) + + (NLA_HDRLEN * 4) + NLMSG_HDRLEN; + + /* + * 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 != ucfg_nan_get_ndi_state(vdev)) { + cfg80211_err("NDI interface deleted"); + return; + } + + /* notify response to the upper layer */ + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_KERNEL); + + if (!vendor_event) { + cfg80211_err("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)) { + cfg80211_err("VENDOR_ATTR_NDP_SUBCMD put fail"); + goto failure; + } + + /* Transaction id */ + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + ucfg_nan_get_ndp_delete_transaction_id(vdev))) { + cfg80211_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"); + goto failure; + } + + /* Status code */ + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + ucfg_nan_get_ndi_delete_rsp_status(vdev))) { + cfg80211_err("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, + ucfg_nan_get_ndi_delete_rsp_reason(vdev))) { + cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"); + goto failure; + } + + cfg80211_debug("sub command: %d, value: %d", + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE); + cfg80211_debug("delete transaction id: %d, value: %d", + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + ucfg_nan_get_ndp_delete_transaction_id(vdev)); + cfg80211_debug("status code: %d, value: %d", + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + ucfg_nan_get_ndi_delete_rsp_status(vdev)); + cfg80211_debug("Return value: %d, value: %d", + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + ucfg_nan_get_ndi_delete_rsp_reason(vdev)); + + ucfg_nan_set_ndp_delete_transaction_id(vdev, 0); + ucfg_nan_set_ndi_state(vdev, NAN_DATA_NDI_DELETED_STATE); + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + + return; +failure: + kfree_skb(vendor_event); +} From 320064017e8922b773f48ff0e5c5ee9b1420bfcf Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Wed, 5 Apr 2017 17:26:18 -0700 Subject: [PATCH 07/39] qcacmn: NDP_INITIATOR_REQ implementation Add implementation for NDP_INITIATOR_REQ. Change-Id: Ieb4cb79d500fd75b23b4a3f8bfa414d14eb6fe18 CRs-Fixed: 2014795 --- inc/os_if_nan.h | 10 + src/os_if_nan.c | 524 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 534 insertions(+) diff --git a/inc/os_if_nan.h b/inc/os_if_nan.h index 9b8fc9f3db..a0355e7a70 100644 --- a/inc/os_if_nan.h +++ b/inc/os_if_nan.h @@ -153,6 +153,16 @@ void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, struct nan_callbacks *cb_obj); +/** + * os_if_nan_register_lim_callbacks: os_if api to register lim callbacks + * @psoc: pointer to psoc object + * @cb_obj: struct pointer containing callbacks + * + * Return: status of operation + */ +int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc, + struct nan_callbacks *cb_obj); + /** * os_if_nan_post_ndi_create_rsp: os_if api to pos ndi create rsp to umac nan * component diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 311a26085d..76012e2a6a 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -24,6 +24,7 @@ #include "qdf_trace.h" #include "os_if_nan.h" #include "wlan_nan_api.h" +#include "nan_ucfg_api.h" #include "nan_public_structs.h" #include "wlan_osif_priv.h" #include @@ -168,6 +169,147 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, return cb_obj.ndi_delete(vdev_id, iface_name, transaction_id); } +/** + * os_if_nan_process_ndp_initiator_req() - NDP initiator request handler + * @ctx: hdd context + * @tb: parsed NL attribute list + * + * tb will contain following vendor attributes: + * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID + * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional + * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG + * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID + * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR + * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional + * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional + * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional + * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional + * + * Return: 0 on success or error code on failure + */ +static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, + struct nlattr **tb) +{ + int ret = 0; + char *iface_name; + QDF_STATUS status; + uint32_t ndp_qos_cfg; + enum nan_datapath_state state; + struct wlan_objmgr_vdev *nan_vdev; + struct nan_datapath_initiator_req req = {0}; + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + cfg80211_err("Interface name string is unavailable"); + return -EINVAL; + } + + iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + nan_vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID); + if (!nan_vdev) { + cfg80211_err("NAN data interface %s not available", iface_name); + return -EINVAL; + } + + state = ucfg_nan_get_ndi_state(nan_vdev); + if (state == NAN_DATA_NDI_DELETED_STATE || + state == NAN_DATA_NDI_DELETING_STATE || + state == NAN_DATA_NDI_CREATING_STATE) { + cfg80211_err("Data request not allowed in NDI current state: %d", + state); + ret = -EINVAL; + goto initiator_req_failed; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { + cfg80211_err("Transaction ID is unavailable"); + ret = -EINVAL; + goto initiator_req_failed; + } + req.transaction_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) + req.channel = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]); + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]) { + req.channel_cfg = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]); + } else { + cfg80211_err("Channel config is unavailable"); + ret = -EINVAL; + goto initiator_req_failed; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) { + cfg80211_err("NDP service instance ID is unavailable"); + ret = -EINVAL; + goto initiator_req_failed; + } + req.service_instance_id = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]); + + qdf_mem_copy(req.self_ndi_mac_addr.bytes, + wlan_vdev_mlme_get_macaddr(nan_vdev), QDF_MAC_ADDR_SIZE); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) { + cfg80211_err("NDI peer discovery mac addr is unavailable"); + ret = -EINVAL; + goto initiator_req_failed; + } + qdf_mem_copy(req.peer_discovery_mac_addr.bytes, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), + QDF_MAC_ADDR_SIZE); + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { + req.ndp_info.ndp_app_info_len = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + req.ndp_info.ndp_app_info = + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) { + /* at present ndp config stores 4 bytes QOS info only */ + req.ndp_config.ndp_cfg_len = 4; + req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg; + ndp_qos_cfg = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] && + !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { + cfg80211_err("PMK cannot be absent when CSID is present."); + ret = -EINVAL; + goto initiator_req_failed; + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { + req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); + req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, + QDF_TRACE_LEVEL_DEBUG, + req.pmk.pmk, req.pmk.pmk_len); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) { + req.ncs_sk_type = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]); + + } + + cfg80211_debug("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, csid: %d, peer_discovery_mac_addr: %pM", + wlan_vdev_get_id(nan_vdev), req.transaction_id, req.channel, + req.service_instance_id, req.ndp_info.ndp_app_info_len, + req.ncs_sk_type, req.peer_discovery_mac_addr.bytes); + + status = ucfg_nan_req_processor(nan_vdev, &req, NDP_INITIATOR_REQ); + ret = qdf_status_to_os_return(status); +initiator_req_failed: + wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); + + return ret; +} + int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, const void *data, int data_len) { @@ -211,6 +353,8 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, return os_if_nan_process_ndi_create(psoc, tb); case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE: return os_if_nan_process_ndi_delete(psoc, tb); + case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST: + return os_if_nan_process_ndp_initiator_req(psoc, tb); default: cfg80211_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type); return -EINVAL; @@ -219,6 +363,368 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, return -EINVAL; } +/** + * os_if_ndp_initiator_rsp_handler() - NDP initiator response handler + * @vdev: pointer to vdev object + * @rsp_params: response parameters + * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) + * + * Return: none + */ +static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_initiator_rsp *rsp) +{ + uint32_t data_len; + struct sk_buff *vendor_event; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + + if (!rsp) { + cfg80211_err("Invalid NDP Initator response"); + return; + } + + data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) + + NLMSG_HDRLEN + (5 * NLA_HDRLEN); + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_ATOMIC); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE)) + goto ndp_initiator_rsp_nla_failed; + + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + rsp->transaction_id)) + goto ndp_initiator_rsp_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + rsp->ndp_instance_id)) + goto ndp_initiator_rsp_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + rsp->status)) + goto ndp_initiator_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + rsp->reason)) + goto ndp_initiator_rsp_nla_failed; + + cfg80211_debug("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d", + rsp->transaction_id, rsp->ndp_instance_id, rsp->status, + rsp->reason); + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); + return; +ndp_initiator_rsp_nla_failed: + cfg80211_err("nla_put api failed"); + kfree_skb(vendor_event); +} + +/** + * os_if_ndp_indication_handler() - NDP indication handler + * @vdev: pointer to vdev object + * @ind_params: indication parameters + * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ) + * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size) + * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size) + * + * Return: none + */ +static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_indication_event *event) +{ + uint16_t data_len; + uint32_t ndp_qos_config; + struct sk_buff *vendor_event; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + enum nan_datapath_state state; + + if (!event) { + cfg80211_err("Invalid NDP Indication"); + return; + } + + cfg80211_debug("NDP Indication, policy: %d", event->policy); + state = ucfg_nan_get_ndi_state(vdev); + /* check if we are in middle of deleting/creating the interface */ + + if (state == NAN_DATA_NDI_DELETED_STATE || + state == NAN_DATA_NDI_DELETING_STATE || + state == NAN_DATA_NDI_CREATING_STATE) { + cfg80211_err("Data request not allowed in current NDI state: %d", + state); + return; + } + + data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ + + event->ndp_info.ndp_app_info_len + event->scid.scid_len + + (10 * NLA_HDRLEN) + NLMSG_HDRLEN; + + /* notify response to the upper layer */ + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, + NULL, data_len, + QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_ATOMIC); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND)) + goto ndp_indication_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + IFNAMSIZ, "nan0"/* adapter->dev->name - fetch dev name */)) + goto ndp_indication_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, + event->service_instance_id)) + goto ndp_indication_nla_failed; + + if (nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, + QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes)) + goto ndp_indication_nla_failed; + + if (nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, + QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes)) + goto ndp_indication_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + event->ndp_instance_id)) + goto ndp_indication_nla_failed; + + if (event->ndp_info.ndp_app_info_len) + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, + event->ndp_info.ndp_app_info_len, + event->ndp_info.ndp_app_info)) + goto ndp_indication_nla_failed; + + if (event->ndp_config.ndp_cfg_len) { + ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg); + /* at present ndp config stores 4 bytes QOS info only */ + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, + ndp_qos_config)) + goto ndp_indication_nla_failed; + } + + if (event->scid.scid_len) { + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE, + event->ncs_sk_type)) + goto ndp_indication_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID, + event->scid.scid_len, + event->scid.scid)) + goto ndp_indication_nla_failed; + + cfg80211_debug("csid: %d, scid_len: %d", + event->ncs_sk_type, event->scid.scid_len); + + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, + event->scid.scid, event->scid.scid_len); + } + + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); + return; +ndp_indication_nla_failed: + cfg80211_err("nla_put api failed"); + kfree_skb(vendor_event); +} + +/** + * os_if_ndp_confirm_ind_handler() - NDP confirm indication handler + * @vdev: pointer to vdev object + * @ind_params: indication parameters + * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ) + * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size) + * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes) + * + * Return: none + */ +static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_confirm_event *ndp_confirm) +{ + int idx = 0; + uint32_t data_len; + QDF_STATUS status; + uint32_t ndp_qos_config = 0; + struct sk_buff *vendor_event; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + struct nan_callbacks cb_obj; + + if (!ndp_confirm) { + cfg80211_err("Invalid NDP Initator response"); + return; + } + + status = ucfg_nan_get_callbacks(psoc, &cb_obj); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("couldn't get callbacks"); + return; + } + + /* ndp_confirm is called each time user generated ndp req succeeds */ + idx = cb_obj.get_peer_idx(wlan_vdev_get_id(vdev), + &ndp_confirm->peer_ndi_mac_addr); + + if (idx < 0) + cfg80211_err("can't find addr: %pM in vdev_id: %d, peer table.", + &ndp_confirm->peer_ndi_mac_addr, + wlan_vdev_get_id(vdev)); + else if (ndp_confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT) { + uint32_t active_sessions = + ucfg_nan_get_active_ndp_sessions(vdev, idx); + ucfg_nan_set_active_ndp_sessions(vdev, active_sessions + 1, + idx); + } + + data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ + + + NLMSG_HDRLEN + (7 * NLA_HDRLEN) + + ndp_confirm->ndp_info.ndp_app_info_len; + + if (ndp_confirm->ndp_info.ndp_app_info_len) + data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len; + + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_ATOMIC); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND)) + goto ndp_confirm_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + ndp_confirm->ndp_instance_id)) + goto ndp_confirm_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, + QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes)) + goto ndp_confirm_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + IFNAMSIZ, "nan0" /* TBD adapter->dev->name - fetch name */)) + goto ndp_confirm_nla_failed; + + if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, + ndp_confirm->ndp_info.ndp_app_info_len, + ndp_confirm->ndp_info.ndp_app_info)) + goto ndp_confirm_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, + ndp_confirm->rsp_code)) + goto ndp_confirm_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + ndp_confirm->reason_code)) + goto ndp_confirm_nla_failed; + + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); + cfg80211_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM, ndp_cfg: %d, rsp_code: %d, reason_code: %d", + ndp_confirm->ndp_instance_id, + ndp_confirm->peer_ndi_mac_addr.bytes, + ndp_qos_config, ndp_confirm->rsp_code, + ndp_confirm->reason_code); + + cfg80211_debug("NDP confim, ndp app info dump"); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, + ndp_confirm->ndp_info.ndp_app_info, + ndp_confirm->ndp_info.ndp_app_info_len); + return; +ndp_confirm_nla_failed: + cfg80211_err("nla_put api failed"); + kfree_skb(vendor_event); +} + +/** + * os_if_new_peer_ind_handler() - NDP new peer indication handler + * @adapter: pointer to adapter context + * @ind_params: indication parameters + * + * Return: none + */ +static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_peer_ind *peer_ind) +{ + int ret; + QDF_STATUS status; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); + uint32_t active_peers = ucfg_nan_get_active_peers(vdev); + struct nan_callbacks cb_obj; + + if (NULL == peer_ind) { + cfg80211_err("Invalid new NDP peer params"); + return; + } + + status = ucfg_nan_get_callbacks(psoc, &cb_obj); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("failed to get callbacks"); + return; + } + + cfg80211_debug("session_id: %d, peer_mac: %pM, sta_id: %d", + peer_ind->session_id, peer_ind->peer_mac_addr.bytes, + peer_ind->sta_id); + ret = cb_obj.new_peer_ind(vdev_id, peer_ind->sta_id, + &peer_ind->peer_mac_addr, + (active_peers == 0 ? true : false)); + if (ret) { + cfg80211_err("new peer handling at HDD failed %d", ret); + return; + } + + active_peers++; + ucfg_nan_set_active_peers(vdev, active_peers); + cfg80211_debug("vdev_id: %d, num_peers: %d", vdev_id, active_peers); +} + /** * os_if_ndp_iface_create_rsp_handler() - NDP iface create response handler * @adapter: pointer to adapter context @@ -393,6 +899,18 @@ void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, case NAN_DATAPATH_INF_DELETE_RSP: os_if_ndp_iface_delete_rsp_handler(psoc, vdev, msg); break; + case NDP_CONFIRM: + os_if_ndp_confirm_ind_handler(vdev, msg); + break; + case NDP_INITIATOR_RSP: + os_if_ndp_initiator_rsp_handler(vdev, msg); + break; + case NDP_INDICATION: + os_if_ndp_indication_handler(vdev, msg); + break; + case NDP_NEW_PEER: + os_if_new_peer_ind_handler(vdev, msg); + break; default: break; } @@ -405,6 +923,12 @@ int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, os_if_nan_event_handler); } +int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc, + struct nan_callbacks *cb_obj) +{ + return ucfg_nan_register_lim_callbacks(psoc, cb_obj); +} + void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, bool success) { From 3bc4aed32e61251d7a5efd994e64df8e7b28a76e Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Tue, 4 Apr 2017 19:41:28 -0700 Subject: [PATCH 08/39] qcacmn: NDP_RESPONDER_REQ implementation Add implementation for NDP_RESPONDER_REQ. Change-Id: I27029eae88e0bc545c8444adf1342b2ec95f4d60 CRs-Fixed: 2014795 --- src/os_if_nan.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 76012e2a6a..0459f630c6 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -310,6 +310,138 @@ initiator_req_failed: return ret; } +/** + * os_if_nan_process_ndp_responder_req() - NDP responder request handler + * @nan_ctx: hdd context + * @tb: parsed NL attribute list + * + * tb includes following vendor attributes: + * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID + * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID + * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE + * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional + * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional + * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional + * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional + * + * Return: 0 on success or error code on failure + */ +static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, + struct nlattr **tb) +{ + int ret = 0; + char *iface_name; + QDF_STATUS status; + uint32_t ndp_qos_cfg; + enum nan_datapath_state state; + struct wlan_objmgr_vdev *nan_vdev; + struct nan_datapath_responder_req req = {0}; + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + cfg80211_err("Interface name string is unavailable"); + return -EINVAL; + } + + iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + /* Check if there is already an existing NAN interface */ + nan_vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID); + if (!nan_vdev) { + cfg80211_err("NAN data interface %s not available", iface_name); + return -EINVAL; + } + + state = ucfg_nan_get_ndi_state(nan_vdev); + if (state == NAN_DATA_NDI_DELETED_STATE || + state == NAN_DATA_NDI_DELETING_STATE || + state == NAN_DATA_NDI_CREATING_STATE) { + cfg80211_err("Data request not allowed in current NDI state:%d", + state); + ret = -EAGAIN; + goto responder_req_failed; + } + + req.vdev = nan_vdev; + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { + cfg80211_err("Transaction ID is unavailable"); + ret = -EINVAL; + goto responder_req_failed; + } + req.transaction_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) { + cfg80211_err("Instance ID is unavailable"); + ret = -EINVAL; + goto responder_req_failed; + } + req.ndp_instance_id = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) { + cfg80211_err("ndp_rsp is unavailable"); + ret = -EINVAL; + goto responder_req_failed; + } + req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { + req.ndp_info.ndp_app_info_len = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + if (req.ndp_info.ndp_app_info_len) { + req.ndp_info.ndp_app_info = + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + } + } else { + cfg80211_debug("NDP app info is unavailable"); + } + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) { + /* at present ndp config stores 4 bytes QOS info only */ + req.ndp_config.ndp_cfg_len = 4; + ndp_qos_cfg = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); + req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg; + } else { + cfg80211_debug("NDP config data is unavailable"); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] && + !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { + cfg80211_err("PMK cannot be absent when CSID is present."); + ret = -EINVAL; + goto responder_req_failed; + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { + req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); + req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, + QDF_TRACE_LEVEL_DEBUG, + req.pmk.pmk, req.pmk.pmk_len); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) { + req.ncs_sk_type = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]); + + } + + cfg80211_debug("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d", + wlan_vdev_get_id(nan_vdev), req.transaction_id, req.ndp_rsp, + req.ndp_instance_id, req.ndp_info.ndp_app_info_len, + req.ncs_sk_type); + + status = ucfg_nan_req_processor(nan_vdev, &req, NDP_RESPONDER_REQ); + ret = qdf_status_to_os_return(status); + +responder_req_failed: + wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); + + return ret; + +} + int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, const void *data, int data_len) { @@ -355,6 +487,8 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, return os_if_nan_process_ndi_delete(psoc, tb); case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST: return os_if_nan_process_ndp_initiator_req(psoc, tb); + case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST: + return os_if_nan_process_ndp_responder_req(psoc, tb); default: cfg80211_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type); return -EINVAL; @@ -433,6 +567,72 @@ ndp_initiator_rsp_nla_failed: kfree_skb(vendor_event); } + +/* + * os_if_ndp_responder_rsp_handler() - NDP responder response handler + * @vdev: pointer to vdev object + * @rsp: response parameters + * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) + * + * Return: none + */ +static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_responder_rsp *rsp) +{ + uint16_t data_len; + struct sk_buff *vendor_event; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + + if (!rsp) { + cfg80211_err("Invalid NDP Responder response"); + return; + } + + cfg80211_debug("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d", + wlan_vdev_get_id(rsp->vdev), rsp->transaction_id, + rsp->status, rsp->reason); + data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) + + 4 * NLA_HDRLEN + NLMSG_HDRLEN; + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_ATOMIC); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE)) + goto ndp_responder_rsp_nla_failed; + + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + rsp->transaction_id)) + goto ndp_responder_rsp_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + rsp->status)) + goto ndp_responder_rsp_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + rsp->reason)) + goto ndp_responder_rsp_nla_failed; + + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); + return; +ndp_responder_rsp_nla_failed: + cfg80211_err("nla_put api failed"); + kfree_skb(vendor_event); +} + /** * os_if_ndp_indication_handler() - NDP indication handler * @vdev: pointer to vdev object @@ -911,6 +1111,9 @@ void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, case NDP_NEW_PEER: os_if_new_peer_ind_handler(vdev, msg); break; + case NDP_RESPONDER_RSP: + os_if_ndp_responder_rsp_handler(vdev, msg); + break; default: break; } From 780272b6c77abd681cf0bf4887947d98eb8e0922 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Tue, 4 Apr 2017 19:41:56 -0700 Subject: [PATCH 09/39] qcacmn: NDP_END_REQ implementation Add implementation of NDP_END_REQ. Change-Id: Ifa0bdcdee09c15c68bb12c63ba1157c71650c5bc CRs-Fixed: 2014795 --- src/os_if_nan.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 0459f630c6..681c01ce9c 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -442,6 +442,61 @@ responder_req_failed: } +/** + * os_if_nan_process_ndp_end_req() - NDP end request handler + * @psoc: pointer to psoc object + * + * @tb: parsed NL attribute list + * tb includes following vendor attributes: + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID + * + * Return: 0 on success or error code on failure + */ +static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, + struct nlattr **tb) +{ + int ret = 0; + QDF_STATUS status; + struct wlan_objmgr_vdev *nan_vdev; + struct nan_datapath_end_req req = {0}; + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { + cfg80211_err("Transaction ID is unavailable"); + return -EINVAL; + } + req.transaction_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) { + cfg80211_err("NDP instance ID array is unavailable"); + return -EINVAL; + } + + req.num_ndp_instances = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) / + sizeof(uint32_t); + if (0 >= req.num_ndp_instances) { + cfg80211_err("Num NDP instances is 0"); + return -EINVAL; + } + req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]); + + cfg80211_debug("sending ndp_end_req to SME, transaction_id: %d", + req.transaction_id); + + nan_vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID); + if (!nan_vdev) { + cfg80211_err("NAN data interface is not available"); + return -EINVAL; + } + + status = ucfg_nan_req_processor(nan_vdev, &req, NDP_END_REQ); + ret = qdf_status_to_os_return(status); + wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); + + return ret; +} + int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, const void *data, int data_len) { @@ -489,6 +544,8 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, return os_if_nan_process_ndp_initiator_req(psoc, tb); case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST: return os_if_nan_process_ndp_responder_req(psoc, tb); + case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST: + return os_if_nan_process_ndp_end_req(psoc, tb); default: cfg80211_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type); return -EINVAL; @@ -881,6 +938,169 @@ ndp_confirm_nla_failed: kfree_skb(vendor_event); } +/** + * os_if_ndp_end_rsp_handler() - NDP end response handler + * @vdev: pointer to vdev object + * @rsp_params: response parameters + * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) + * + * Return: none + */ +static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_end_rsp_event *rsp) +{ + uint32_t data_len; + struct sk_buff *vendor_event; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + + if (!rsp) { + cfg80211_err("Invalid ndp end response"); + return; + } + + data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) + + sizeof(uint16_t); + + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_ATOMIC); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + rsp->status)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + rsp->reason)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + rsp->transaction_id)) + goto ndp_end_rsp_nla_failed; + + cfg80211_debug("NDP End rsp sent, transaction id: %d, status: %d, reason: %d", + rsp->transaction_id, rsp->status, rsp->reason); + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); + return; + +ndp_end_rsp_nla_failed: + cfg80211_err("nla_put api failed"); + kfree_skb(vendor_event); +} + +/** + * os_if_ndp_end_ind_handler() - NDP end indication handler + * @vdev: pointer to vdev object + * @ind_params: indication parameters + * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances) + * + * Return: none + */ +static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_end_indication_event *end_ind) +{ + QDF_STATUS status; + uint32_t data_len, i; + struct nan_callbacks cb_obj; + uint32_t *ndp_instance_array; + struct sk_buff *vendor_event; + struct wlan_objmgr_vdev *vdev_itr; + struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + + status = ucfg_nan_get_callbacks(psoc, &cb_obj); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("failed to get callbacks"); + return; + } + + if (!end_ind) { + cfg80211_err("Invalid ndp end indication"); + return; + } + + ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids * + sizeof(*ndp_instance_array)); + if (!ndp_instance_array) { + cfg80211_err("Failed to allocate ndp_instance_array"); + return; + } + for (i = 0; i < end_ind->num_ndp_ids; i++) { + int idx = 0; + + ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id; + vdev_itr = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + end_ind->ndp_map[i].vdev_id, WLAN_NAN_ID); + + if (vdev_itr == NULL) { + cfg80211_err("vdev not found for vdev_id: %d", + end_ind->ndp_map[i].vdev_id); + continue; + } + + idx = cb_obj.get_peer_idx(wlan_vdev_get_id(vdev), + &end_ind->ndp_map[i].peer_ndi_mac_addr); + if (idx < 0) { + cfg80211_err("can't find addr: %pM in sta_ctx.", + &end_ind->ndp_map[i].peer_ndi_mac_addr); + continue; + } + /* save the value of active sessions on each peer */ + ucfg_nan_set_active_ndp_sessions(vdev, + end_ind->ndp_map[i].num_active_ndp_sessions, + idx); + } + + data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) + + end_ind->num_ndp_ids * sizeof(*ndp_instance_array); + + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_ATOMIC); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_END_IND)) + goto ndp_end_ind_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, + end_ind->num_ndp_ids * sizeof(*ndp_instance_array), + ndp_instance_array)) + goto ndp_end_ind_nla_failed; + + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); + qdf_mem_free(ndp_instance_array); + return; + +ndp_end_ind_nla_failed: + cfg80211_err("nla_put api failed"); + kfree_skb(vendor_event); + qdf_mem_free(ndp_instance_array); +} + /** * os_if_new_peer_ind_handler() - NDP new peer indication handler * @adapter: pointer to adapter context @@ -925,6 +1145,42 @@ static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev, cfg80211_debug("vdev_id: %d, num_peers: %d", vdev_id, active_peers); } +/** + * os_if_peer_departed_ind_handler() - Handle NDP peer departed indication + * @adapter: pointer to adapter context + * @ind_params: indication parameters + * + * Return: none + */ +static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_peer_ind *peer_ind) +{ + QDF_STATUS status; + struct nan_callbacks cb_obj; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); + uint32_t active_peers = ucfg_nan_get_active_peers(vdev); + + status = ucfg_nan_get_callbacks(psoc, &cb_obj); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("failed to get callbacks"); + return; + } + + if (NULL == peer_ind) { + cfg80211_err("Invalid new NDP peer params"); + return; + } + cfg80211_debug("session_id: %d, peer_mac: %pM, sta_id: %d", + peer_ind->session_id, peer_ind->peer_mac_addr.bytes, + peer_ind->sta_id); + active_peers--; + ucfg_nan_set_active_peers(vdev, active_peers); + cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id, + &peer_ind->peer_mac_addr, + (active_peers == 0 ? true : false)); +} + /** * os_if_ndp_iface_create_rsp_handler() - NDP iface create response handler * @adapter: pointer to adapter context @@ -1114,6 +1370,15 @@ void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, case NDP_RESPONDER_RSP: os_if_ndp_responder_rsp_handler(vdev, msg); break; + case NDP_END_RSP: + os_if_ndp_end_rsp_handler(vdev, msg); + break; + case NDP_END_IND: + os_if_ndp_end_ind_handler(vdev, msg); + break; + case NDP_PEER_DEPARTED: + os_if_peer_departed_ind_handler(vdev, msg); + break; default: break; } From b6304681916bdcb885935d3c5253b92ec61232b3 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 19 Jun 2017 14:52:52 -0700 Subject: [PATCH 10/39] qcacmn: Properly validate QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR Currently the QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR nla_policy specifies a type of NLA_STRING, but the underlying implementation expects a NUL-terminated string. Update the policy to correctly use a type of NLA_NUL_STRING with the len updated to remove the allocation needed for the terminating NUL. Change-Id: Ic73241511ab73ae63fd7c1a8d6422da91931919c CRs-Fixed: 2063588 --- src/os_if_nan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 681c01ce9c..fe44346290 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -38,8 +38,8 @@ static const struct nla_policy vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 }, [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 }, - [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_STRING, - .len = IFNAMSIZ }, + [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_NUL_STRING, + .len = IFNAMSIZ - 1 }, [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 }, [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 }, [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = { From 7981ec30cb4a5345fa6bcdb2c701bdee2f41c2db Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Fri, 30 Jun 2017 10:48:48 -0700 Subject: [PATCH 11/39] qcacmn: Add Passphrase and Service Name parameter to NDP cmds Add Passphrase and Service Name to NDP initiator request and NDP responder request. Change-Id: I6a189747760a15393fcbac9dc382847fef789ab1 CRs-Fixed: 2072498 --- inc/os_if_nan.h | 7 ++++ src/os_if_nan.c | 109 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 82 insertions(+), 34 deletions(-) diff --git a/inc/os_if_nan.h b/inc/os_if_nan.h index a0355e7a70..31e56513fa 100644 --- a/inc/os_if_nan.h +++ b/inc/os_if_nan.h @@ -37,6 +37,9 @@ struct wlan_objmgr_vdev; #define NDP_PMK_LEN 32 #define NDP_SCID_BUF_LEN 256 #define NDP_NUM_INSTANCE_ID 255 +#define NAN_MAX_SERVICE_NAME_LEN 255 +#define NAN_PASSPHRASE_MIN_LEN 8 +#define NAN_PASSPHRASE_MAX_LEN 63 /** * enum qca_wlan_vendor_attr_ndp_params - vendor attribute parameters @@ -60,6 +63,8 @@ struct wlan_objmgr_vdev; * @QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE: Cipher Suit ID * @QCA_WLAN_VENDOR_ATTR_NDP_PMK: Pairwise Master Key * @QCA_WLAN_VENDOR_ATTR_NDP_SCID: Security Context ID + * @QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - pass phrase + * @QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - service name */ enum qca_wlan_vendor_attr_ndp_params { QCA_WLAN_VENDOR_ATTR_NDP_PARAM_INVALID = 0, @@ -83,6 +88,8 @@ enum qca_wlan_vendor_attr_ndp_params { QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE, QCA_WLAN_VENDOR_ATTR_NDP_PMK, QCA_WLAN_VENDOR_ATTR_NDP_SCID, + QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE, + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX = diff --git a/src/os_if_nan.c b/src/os_if_nan.c index fe44346290..31b7a00dde 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -65,6 +65,10 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { .type = NLA_U32 }, [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE] = { .type = NLA_BINARY, + .len = NAN_PASSPHRASE_MAX_LEN }, + [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME] = { .type = NLA_BINARY, + .len = NAN_MAX_SERVICE_NAME_LEN }, }; static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, @@ -169,6 +173,67 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, return cb_obj.ndi_delete(vdev_id, iface_name, transaction_id); } +/** + * os_if_nan_parse_security_params() - parse vendor attributes for security + * params. + * @tb: parsed NL attribute list + * @ncs_sk_type: out parameter to populate ncs_sk_type + * @pmk: out parameter to populate pmk + * @passphrase: out parameter to populate passphrase + * @service_name: out parameter to populate service_name + * + * Return: 0 on success or error code on failure + */ +static int os_if_nan_parse_security_params(struct nlattr **tb, + uint32_t *ncs_sk_type, struct nan_datapath_pmk *pmk, + struct ndp_passphrase *passphrase, + struct ndp_service_name *service_name) +{ + if (!ncs_sk_type || !pmk || !passphrase || !service_name) { + cfg80211_err("out buffers for one ore more parameters is null"); + return -EINVAL; + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) { + *ncs_sk_type = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { + pmk->pmk_len = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); + pmk->pmk = + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); + cfg80211_err("pmk len: %d", pmk->pmk_len); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + pmk->pmk, pmk->pmk_len); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]) { + passphrase->passphrase_len = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]); + passphrase->passphrase = + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]); + cfg80211_err("passphrase len: %d", passphrase->passphrase_len); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + passphrase->passphrase, passphrase->passphrase_len); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]) { + service_name->service_name_len = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]); + service_name->service_name = + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]); + cfg80211_err("service_name len: %d", + service_name->service_name_len); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + service_name->service_name, + service_name->service_name_len); + } + + return 0; +} + /** * os_if_nan_process_ndp_initiator_req() - NDP initiator request handler * @ctx: hdd context @@ -185,6 +250,8 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional + * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional + * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional * * Return: 0 on success or error code on failure */ @@ -276,27 +343,13 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); } - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] && - !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { - cfg80211_err("PMK cannot be absent when CSID is present."); + if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, + &req.passphrase, &req.service_name)) { + cfg80211_err("inconsistent security params in request."); ret = -EINVAL; goto initiator_req_failed; } - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { - req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); - req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); - QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, - QDF_TRACE_LEVEL_DEBUG, - req.pmk.pmk, req.pmk.pmk_len); - } - - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) { - req.ncs_sk_type = - nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]); - - } - cfg80211_debug("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, csid: %d, peer_discovery_mac_addr: %pM", wlan_vdev_get_id(nan_vdev), req.transaction_id, req.channel, req.service_instance_id, req.ndp_info.ndp_app_info_len, @@ -324,6 +377,8 @@ initiator_req_failed: * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional + * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional + * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional * * Return: 0 on success or error code on failure */ @@ -406,27 +461,13 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, cfg80211_debug("NDP config data is unavailable"); } - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] && - !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { - cfg80211_err("PMK cannot be absent when CSID is present."); + if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, + &req.passphrase, &req.service_name)) { + cfg80211_err("inconsistent security params in request."); ret = -EINVAL; goto responder_req_failed; } - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { - req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); - req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); - QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, - QDF_TRACE_LEVEL_DEBUG, - req.pmk.pmk, req.pmk.pmk_len); - } - - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) { - req.ncs_sk_type = - nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]); - - } - cfg80211_debug("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d", wlan_vdev_get_id(nan_vdev), req.transaction_id, req.ndp_rsp, req.ndp_instance_id, req.ndp_info.ndp_app_info_len, From 5d12cbaf80a7f585398a53c9e8e21452beeb8a90 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Mon, 3 Jul 2017 14:38:16 -0700 Subject: [PATCH 12/39] qcacmn: Allow nan data interface delete with peers attached Service layer was not allowed to delete NDI if there are active NDP sessions (peers). Service layer is expected to delete the active NDP sessions before issuing NDI delete. However, that is not guaranteed to happen. Hence allowing internal cleanup to happen by allowing the command to firmware. Change-Id: Iab9bc3bca431475792c164d16cdd18be2f346188 CRs-Fixed: 2072505 --- src/os_if_nan.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 31b7a00dde..9facb972c7 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -158,11 +158,9 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); /* check if there are active peers on the adapter */ - if (num_peers) { - cfg80211_err("NDP peers active: %d, cannot delete NDI", + if (num_peers) + cfg80211_err("NDP peers active: %d, active NDPs may not be terminated", num_peers); - return -EINVAL; - } status = ucfg_nan_get_callbacks(psoc, &cb_obj); if (QDF_IS_STATUS_ERROR(status)) { From b0a5c407e2002c7df8b97d91f14c6b8f44e21372 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Mon, 3 Jul 2017 16:10:05 -0700 Subject: [PATCH 13/39] qcacmn: Fix transaction id descrepancy during NDI create Driver truncated the transaction id to 8-bits from 16-bit value causing the descrepancy in transaction id exchange during NDI create. Change-Id: I502f422620411c39bd0e75f06e9b7200bfea24ae CRs-Fixed: 2072511 --- src/os_if_nan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 31b7a00dde..5c02c29143 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -1247,7 +1247,7 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, bool create_fail = false; struct nan_callbacks cb_obj; struct sk_buff *vendor_event; - uint8_t create_transaction_id; + uint16_t create_transaction_id; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); uint32_t create_status = NAN_DATAPATH_RSP_STATUS_ERROR; From 25b18872678414ba207bd7e653b791effe8941b8 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Mon, 3 Jul 2017 13:00:48 -0700 Subject: [PATCH 14/39] qcacmn: Make ndp channel config parameter optional The ndp channel config has no meaning if ndp channel itself is optional. Host will send ndp channel config as "optional" to FW if it is missing in the ndp command. Change-Id: I59e245f3fb05ae35aa185fba7bad09608f5334c8 CRs-Fixed: 2072502 --- src/os_if_nan.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 31b7a00dde..f4d92204f7 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -296,16 +296,17 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, req.transaction_id = nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) { req.channel = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]); - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]) { - req.channel_cfg = - nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]); - } else { - cfg80211_err("Channel config is unavailable"); - ret = -EINVAL; - goto initiator_req_failed; + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]) { + req.channel_cfg = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]); + } else { + cfg80211_err("Channel config is unavailable"); + ret = -EINVAL; + goto initiator_req_failed; + } } if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) { From 5d1f85ccb85b17a84397e8f1e649a3b044c88ed6 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Fri, 30 Jun 2017 10:48:48 -0700 Subject: [PATCH 15/39] qcacmn: Enable support for multiple NAN Data Interfaces Enable support for multiple nan data interfaces. The usespace may need to create multiple NDIs depending on whether it requires IP isolation or not. Change-Id: I4391f2efdc6bdede52a73915531d39dd7798c39d CRs-Fixed: 2072501 --- src/os_if_nan.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index f4d92204f7..92e4875998 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -140,7 +140,7 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, return -EINVAL; } - nan_vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID); + nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID); if (!nan_vdev) { cfg80211_err("Nan datapath interface is not present"); return -EINVAL; @@ -151,9 +151,8 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, vdev_id = wlan_vdev_get_id(nan_vdev); num_peers = ucfg_nan_get_active_peers(nan_vdev); /* - * wlan_objmgr_get_vdev_by_opmode_from_psoc API will have incremented - * ref count - decrement here since vdev returned by that api is not - * used any more + * wlan_util_get_vdev_by_ifname increments ref count + * decrement here since vdev returned by that api is not used any more */ wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); @@ -272,12 +271,17 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, } iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); - nan_vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID); + nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID); if (!nan_vdev) { cfg80211_err("NAN data interface %s not available", iface_name); return -EINVAL; } + if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { + cfg80211_err("Interface found is not NDI"); + return -EINVAL; + } + state = ucfg_nan_get_ndi_state(nan_vdev); if (state == NAN_DATA_NDI_DELETED_STATE || state == NAN_DATA_NDI_DELETING_STATE || @@ -401,12 +405,17 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); /* Check if there is already an existing NAN interface */ - nan_vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID); + nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID); if (!nan_vdev) { cfg80211_err("NAN data interface %s not available", iface_name); return -EINVAL; } + if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { + cfg80211_err("Interface found is not NDI"); + return -EINVAL; + } + state = ucfg_nan_get_ndi_state(nan_vdev); if (state == NAN_DATA_NDI_DELETED_STATE || state == NAN_DATA_NDI_DELETING_STATE || @@ -526,7 +535,8 @@ static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, cfg80211_debug("sending ndp_end_req to SME, transaction_id: %d", req.transaction_id); - nan_vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID); + nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE, + WLAN_NAN_ID); if (!nan_vdev) { cfg80211_err("NAN data interface is not available"); return -EINVAL; From fabadbbf6a00c32b36fee6768bab60be9107696b Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Mon, 3 Jul 2017 14:52:07 -0700 Subject: [PATCH 16/39] qcacmn: Check NAN iface with same name before creating another one There were some corner cases reported in which NDIs are getting created with same name. Providing fix for the same. Change-Id: I84ea80580faa44809e257d3b17645808637b5d51 CRs-Fixed: 2072509 --- src/os_if_nan.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 92e4875998..d65a1c6bc0 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -32,6 +32,7 @@ #include "wlan_objmgr_psoc_obj.h" #include "wlan_objmgr_pdev_obj.h" #include "wlan_objmgr_vdev_obj.h" +#include "wlan_utility.h" /* NLA policy */ static const struct nla_policy @@ -87,6 +88,14 @@ static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, } iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID); + if (nan_vdev) { + cfg80211_err("NAN data interface %s is already present", + iface_name); + wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); + return -EEXIST; + } + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { cfg80211_err("transaction id is unavailable"); return -EINVAL; From b4270e8aa41ef9e7d568b4ae087037cefcc0a8cd Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 17 Aug 2017 17:22:34 -0700 Subject: [PATCH 17/39] qcacmn: Add wrapper for nla_parse() The Linux kernel version 4.12 introduced an API change to nla_parse(). Add conditional compilation to call nla_parse with the correct parameters based on the version of the linux kernel being compiled against. Change-Id: Ie904d217a42a2396f8245251a9c90a15dac2c0c9 CRs-Fixed: 2093354 --- src/os_if_nan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 7820c83cd8..1f2269a2c4 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -564,8 +564,8 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1]; char *iface_name; - if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX, - data, data_len, vendor_attr_policy)) { + if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX, + data, data_len, vendor_attr_policy)) { cfg80211_err("Invalid NDP vendor command attributes"); return -EINVAL; } From df0ab768a38edb411f3dcea40378a750780b89e0 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Thu, 21 Dec 2017 11:30:40 -0800 Subject: [PATCH 18/39] qcacmn: Avoid null pointer dereference and OOB access Avoid possible null pointer dereferece and out of bound access in NAN component. Change-Id: I40ba4e340e34e8975c782c0a6329322e3c151326 CRs-Fixed: 2160751 --- src/os_if_nan.c | 99 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 31 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 1f2269a2c4..23b86fb014 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -772,12 +772,14 @@ ndp_responder_rsp_nla_failed: static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, struct nan_datapath_indication_event *event) { + uint8_t *ifname; uint16_t data_len; + uint8_t ifname_len; uint32_t ndp_qos_config; struct sk_buff *vendor_event; + enum nan_datapath_state state; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); - enum nan_datapath_state state; if (!event) { cfg80211_err("Invalid NDP Indication"); @@ -796,9 +798,20 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, return; } - data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ + - event->ndp_info.ndp_app_info_len + event->scid.scid_len + - (10 * NLA_HDRLEN) + NLMSG_HDRLEN; + ifname = wlan_util_vdev_get_if_name(vdev); + if (!ifname) { + cfg80211_err("ifname is null"); + return; + } + ifname_len = qdf_str_len(ifname); + if (ifname_len > IFNAMSIZ) { + cfg80211_err("ifname(%d) too long", ifname_len); + return; + } + + data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + + ifname_len + event->ndp_info.ndp_app_info_len + + event->scid.scid_len + (10 * NLA_HDRLEN) + NLMSG_HDRLEN; /* notify response to the upper layer */ vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, @@ -811,44 +824,44 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, } if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, - QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND)) + QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND)) goto ndp_indication_nla_failed; if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, - IFNAMSIZ, "nan0"/* adapter->dev->name - fetch dev name */)) + ifname_len, ifname)) goto ndp_indication_nla_failed; if (nla_put_u32(vendor_event, - QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, - event->service_instance_id)) + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, + event->service_instance_id)) goto ndp_indication_nla_failed; if (nla_put(vendor_event, - QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, - QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes)) + QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, + QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes)) goto ndp_indication_nla_failed; if (nla_put(vendor_event, - QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, - QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes)) + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, + QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes)) goto ndp_indication_nla_failed; if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, - event->ndp_instance_id)) + event->ndp_instance_id)) goto ndp_indication_nla_failed; if (event->ndp_info.ndp_app_info_len) if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, - event->ndp_info.ndp_app_info_len, - event->ndp_info.ndp_app_info)) + event->ndp_info.ndp_app_info_len, + event->ndp_info.ndp_app_info)) goto ndp_indication_nla_failed; if (event->ndp_config.ndp_cfg_len) { ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg); /* at present ndp config stores 4 bytes QOS info only */ if (nla_put_u32(vendor_event, - QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, - ndp_qos_config)) + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, + ndp_qos_config)) goto ndp_indication_nla_failed; } @@ -859,15 +872,15 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, goto ndp_indication_nla_failed; if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID, - event->scid.scid_len, - event->scid.scid)) + event->scid.scid_len, + event->scid.scid)) goto ndp_indication_nla_failed; cfg80211_debug("csid: %d, scid_len: %d", - event->ncs_sk_type, event->scid.scid_len); + event->ncs_sk_type, event->scid.scid_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, - event->scid.scid, event->scid.scid_len); + event->scid.scid, event->scid.scid_len); } cfg80211_vendor_event(vendor_event, GFP_ATOMIC); @@ -898,8 +911,10 @@ static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, struct nan_datapath_confirm_event *ndp_confirm) { int idx = 0; + uint8_t *ifname; uint32_t data_len; QDF_STATUS status; + uint8_t ifname_len; uint32_t ndp_qos_config = 0; struct sk_buff *vendor_event; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); @@ -933,7 +948,18 @@ static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, idx); } - data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ + + ifname = wlan_util_vdev_get_if_name(vdev); + if (!ifname) { + cfg80211_err("ifname is null"); + return; + } + ifname_len = qdf_str_len(ifname); + if (ifname_len > IFNAMSIZ) { + cfg80211_err("ifname(%d) too long", ifname_len); + return; + } + + data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + ifname_len + + NLMSG_HDRLEN + (7 * NLA_HDRLEN) + ndp_confirm->ndp_info.ndp_app_info_len; @@ -957,14 +983,15 @@ static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, goto ndp_confirm_nla_failed; if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, - QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes)) + QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes)) goto ndp_confirm_nla_failed; if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, - IFNAMSIZ, "nan0" /* TBD adapter->dev->name - fetch name */)) + ifname_len, ifname)) goto ndp_confirm_nla_failed; - if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event, + if (ndp_confirm->ndp_info.ndp_app_info_len && + nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, ndp_confirm->ndp_info.ndp_app_info_len, ndp_confirm->ndp_info.ndp_app_info)) @@ -982,10 +1009,10 @@ static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, cfg80211_vendor_event(vendor_event, GFP_ATOMIC); cfg80211_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM, ndp_cfg: %d, rsp_code: %d, reason_code: %d", - ndp_confirm->ndp_instance_id, - ndp_confirm->peer_ndi_mac_addr.bytes, - ndp_qos_config, ndp_confirm->rsp_code, - ndp_confirm->reason_code); + ndp_confirm->ndp_instance_id, + ndp_confirm->peer_ndi_mac_addr.bytes, + ndp_qos_config, ndp_confirm->rsp_code, + ndp_confirm->reason_code); cfg80211_debug("NDP confim, ndp app info dump"); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, @@ -1352,7 +1379,7 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, ndi_rsp); } else { cfg80211_err("NDI interface creation failed with reason %d", - ndi_rsp->reason); + create_reason); goto close_ndi; } @@ -1463,6 +1490,11 @@ void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc( psoc, vdev_id, WLAN_NAN_ID); + if (!vdev) { + cfg80211_err("vdev is null"); + return; + } + if (success) { rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS; rsp.reason = 0; @@ -1483,6 +1515,11 @@ void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc, struct nan_datapath_inf_delete_rsp rsp = {0}; struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc( psoc, vdev_id, WLAN_NAN_ID); + if (!vdev) { + cfg80211_err("vdev is null"); + return; + } + if (success) { rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS; rsp.reason = 0; From 1c5aaf61ad94802152ac63045db955345deab88f Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Thu, 14 Dec 2017 13:24:31 -0800 Subject: [PATCH 19/39] qcacmn: Avoid WMI TLV structures in NAN target_if Refactor NAN target_if to make it wmi-type agnostic. Specifically do not access wmi structures in NAN target_if. All the access to wmi structures should happen in tlv and non-tlv specific wmi files. Change-Id: I944b678fc501723d7cd26c9b21c4cc6ddb7fda4e CRs-Fixed: 2159876 --- inc/os_if_nan.h | 11 +---------- src/os_if_nan.c | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/inc/os_if_nan.h b/inc/os_if_nan.h index 31e56513fa..151c457bbf 100644 --- a/inc/os_if_nan.h +++ b/inc/os_if_nan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -32,15 +32,6 @@ struct wlan_objmgr_vdev; #ifdef WLAN_FEATURE_NAN_CONVERGENCE -#define NDP_QOS_INFO_LEN 255 -#define NDP_APP_INFO_LEN 255 -#define NDP_PMK_LEN 32 -#define NDP_SCID_BUF_LEN 256 -#define NDP_NUM_INSTANCE_ID 255 -#define NAN_MAX_SERVICE_NAME_LEN 255 -#define NAN_PASSPHRASE_MIN_LEN 8 -#define NAN_PASSPHRASE_MAX_LEN 63 - /** * enum qca_wlan_vendor_attr_ndp_params - vendor attribute parameters * @QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD: NDP Sub command diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 23b86fb014..e7d91d46c7 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -206,10 +206,10 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, } if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { - pmk->pmk_len = - nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); - pmk->pmk = - nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); + pmk->pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]); + qdf_mem_copy(pmk->pmk, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]), + pmk->pmk_len); cfg80211_err("pmk len: %d", pmk->pmk_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, pmk->pmk, pmk->pmk_len); @@ -218,8 +218,9 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]) { passphrase->passphrase_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]); - passphrase->passphrase = - nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]); + qdf_mem_copy(passphrase->passphrase, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]), + passphrase->passphrase_len); cfg80211_err("passphrase len: %d", passphrase->passphrase_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, passphrase->passphrase, passphrase->passphrase_len); @@ -228,8 +229,9 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, if (tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]) { service_name->service_name_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]); - service_name->service_name = - nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]); + qdf_mem_copy(service_name->service_name, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]), + service_name->service_name_len); cfg80211_err("service_name len: %d", service_name->service_name_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, @@ -267,7 +269,6 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, int ret = 0; char *iface_name; QDF_STATUS status; - uint32_t ndp_qos_cfg; enum nan_datapath_state state; struct wlan_objmgr_vdev *nan_vdev; struct nan_datapath_initiator_req req = {0}; @@ -343,15 +344,15 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { req.ndp_info.ndp_app_info_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); - req.ndp_info.ndp_app_info = - nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + qdf_mem_copy(req.ndp_info.ndp_app_info, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), + req.ndp_info.ndp_app_info_len); } if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) { /* at present ndp config stores 4 bytes QOS info only */ req.ndp_config.ndp_cfg_len = 4; - req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg; - ndp_qos_cfg = + *((uint32_t *)req.ndp_config.ndp_cfg) = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); } @@ -400,7 +401,6 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, int ret = 0; char *iface_name; QDF_STATUS status; - uint32_t ndp_qos_cfg; enum nan_datapath_state state; struct wlan_objmgr_vdev *nan_vdev; struct nan_datapath_responder_req req = {0}; @@ -461,19 +461,18 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { req.ndp_info.ndp_app_info_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); - if (req.ndp_info.ndp_app_info_len) { - req.ndp_info.ndp_app_info = - nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); - } + qdf_mem_copy(req.ndp_info.ndp_app_info, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), + req.ndp_info.ndp_app_info_len); } else { cfg80211_debug("NDP app info is unavailable"); } + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) { /* at present ndp config stores 4 bytes QOS info only */ req.ndp_config.ndp_cfg_len = 4; - ndp_qos_cfg = + *((uint32_t *)req.ndp_config.ndp_cfg) = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); - req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg; } else { cfg80211_debug("NDP config data is unavailable"); } @@ -537,7 +536,9 @@ static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, cfg80211_err("Num NDP instances is 0"); return -EINVAL; } - req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]); + qdf_mem_copy(req.ndp_ids, + tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY], + req.num_ndp_instances * sizeof(uint32_t)); cfg80211_debug("sending ndp_end_req to SME, transaction_id: %d", req.transaction_id); From c62ac3d5253c5a3c40bedcd806a37bd627821c88 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 27 Feb 2018 11:32:55 -0800 Subject: [PATCH 20/39] qcacmn: Use size_t for qdf_str_len() return type A recent commit changed the return type for qdf_str_len() to size_t from int32_t. Update call sites for qdf_str_len() to store the return value as size_t to match. Change-Id: Ib8bfad2c1fc7de1f6fc601d1be69e734d3a49dcf CRs-Fixed: 2196858 --- src/os_if_nan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index e7d91d46c7..f3409a5fd4 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -775,7 +775,7 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, { uint8_t *ifname; uint16_t data_len; - uint8_t ifname_len; + qdf_size_t ifname_len; uint32_t ndp_qos_config; struct sk_buff *vendor_event; enum nan_datapath_state state; @@ -806,7 +806,7 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, } ifname_len = qdf_str_len(ifname); if (ifname_len > IFNAMSIZ) { - cfg80211_err("ifname(%d) too long", ifname_len); + cfg80211_err("ifname(%zu) too long", ifname_len); return; } @@ -915,7 +915,7 @@ static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, uint8_t *ifname; uint32_t data_len; QDF_STATUS status; - uint8_t ifname_len; + qdf_size_t ifname_len; uint32_t ndp_qos_config = 0; struct sk_buff *vendor_event; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); @@ -956,7 +956,7 @@ static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, } ifname_len = qdf_str_len(ifname); if (ifname_len > IFNAMSIZ) { - cfg80211_err("ifname(%d) too long", ifname_len); + cfg80211_err("ifname(%zu) too long", ifname_len); return; } From ed557e9e5b0aea4d985e97bcb3c5008e585c8f30 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Mon, 26 Feb 2018 13:00:20 -0800 Subject: [PATCH 21/39] qcacmn: Include qdf_str.h The qdf_str APIs have recently been moved from qdf_mem. Reference the new qdf_str.h header file where appropriate. Change-Id: If97c9c37a7d720a7b93e50ec228da67a8e980c2e CRs-Fixed: 2196129 --- src/os_if_nan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index f3409a5fd4..c1fa9b8d0c 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -20,8 +20,9 @@ * DOC: defines nan component os interface APIs */ -#include "qdf_types.h" +#include "qdf_str.h" #include "qdf_trace.h" +#include "qdf_types.h" #include "os_if_nan.h" #include "wlan_nan_api.h" #include "nan_ucfg_api.h" From ddbaec0f4b7b5bf71eb585c17bdf80a72f153229 Mon Sep 17 00:00:00 2001 From: Ravi Joshi Date: Tue, 10 Apr 2018 15:21:13 -0700 Subject: [PATCH 22/39] qcacmn: Accept nan responder request without iface name The service layer need not provide the iface name in the responder request to the driver if the request is being rejected. The service layer maps the ndp_instance_id only after accepting the request, if the ndp indication is rejected, the user space has no knowledge of the iface name on which the NDP would have gotten mapped if it were successful CRs-Fixed: 2222041 Change-Id: I94a7de0c98c14dbe2389dd8364b6dd78858a9d0a --- src/os_if_nan.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index c1fa9b8d0c..1f1d3630cd 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -406,22 +406,36 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *nan_vdev; struct nan_datapath_responder_req req = {0}; - if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { - cfg80211_err("Interface name string is unavailable"); - return -EINVAL; - } + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); - iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); - /* Check if there is already an existing NAN interface */ - nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID); - if (!nan_vdev) { - cfg80211_err("NAN data interface %s not available", iface_name); - return -EINVAL; - } + /* Check if there is already an existing NAN interface */ + nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, + WLAN_NAN_ID); + if (!nan_vdev) { + cfg80211_err("NAN data interface %s not available", + iface_name); + return -ENODEV; + } - if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { - cfg80211_err("Interface found is not NDI"); - return -EINVAL; + if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { + cfg80211_err("Interface found is not NDI"); + return -ENODEV; + } + } else { + /* + * If the data indication is rejected, the userspace + * may not send the iface name. Use the first available NDI + * in that case + */ + cfg80211_debug("ndp rsp rejected, using first available NDI"); + + nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, + QDF_NDI_MODE, WLAN_NAN_ID); + if (!nan_vdev) { + cfg80211_err("NAN data interface is not available"); + return -ENODEV; + } } state = ucfg_nan_get_ndi_state(nan_vdev); From f6cf25d1543670562819458e425926552b814087 Mon Sep 17 00:00:00 2001 From: Ravi Joshi Date: Tue, 10 Apr 2018 16:06:39 -0700 Subject: [PATCH 23/39] qcacmn: Fix issue while handling ndp response without iface name Check for interface name only when ndp response is "accept" from user. In case of "reject" discard interface name provided and instead use first NDI available. CRs-Fixed: 2222041 Change-Id: Ib02fe7d5b93f8e388658e511317664a4999b5fa6 --- src/os_if_nan.c | 57 +++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 1f1d3630cd..5473bebceb 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -403,37 +403,49 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, char *iface_name; QDF_STATUS status; enum nan_datapath_state state; - struct wlan_objmgr_vdev *nan_vdev; + struct wlan_objmgr_vdev *nan_vdev = NULL; struct nan_datapath_responder_req req = {0}; - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { - iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) { + cfg80211_err("ndp_rsp is unavailable"); + ret = -EINVAL; + goto responder_req_failed; + } + req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); - /* Check if there is already an existing NAN interface */ - nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, - WLAN_NAN_ID); - if (!nan_vdev) { - cfg80211_err("NAN data interface %s not available", - iface_name); - return -ENODEV; - } + if (req.ndp_rsp == NAN_DATAPATH_RESPONSE_ACCEPT) { + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + iface_name = + nla_data( + tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); - if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { - cfg80211_err("Interface found is not NDI"); - return -ENODEV; + /* Check for an existing NAN interface */ + nan_vdev = wlan_util_get_vdev_by_ifname(psoc, + iface_name, WLAN_NAN_ID); + if (!nan_vdev) { + cfg80211_err("NAN data iface %s not available", + iface_name); + return -ENODEV; + } + + if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { + cfg80211_err("Interface found is not NDI"); + return -ENODEV; + } } } else { + /* * If the data indication is rejected, the userspace - * may not send the iface name. Use the first available NDI + * may not send the iface name. Use the first NDI * in that case */ - cfg80211_debug("ndp rsp rejected, using first available NDI"); + cfg80211_debug("ndp rsp rejected, using first NDI"); - nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_NDI_MODE, WLAN_NAN_ID); + nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( + psoc, QDF_NDI_MODE, WLAN_NAN_ID); if (!nan_vdev) { - cfg80211_err("NAN data interface is not available"); + cfg80211_err("NAN data iface is not available"); return -ENODEV; } } @@ -466,13 +478,6 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, req.ndp_instance_id = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); - if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) { - cfg80211_err("ndp_rsp is unavailable"); - ret = -EINVAL; - goto responder_req_failed; - } - req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { req.ndp_info.ndp_app_info_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); From 2c59b94216d4c59696a264444c21eed766d2d50a Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Sun, 15 Apr 2018 22:48:48 -0700 Subject: [PATCH 24/39] qcacmn: Re-factor buffer len calculation for NDP events Re-factor vendor event buffer length calculation for NDP events to a separate function call. Change-Id: I6828067d0e81987d7c903fd7f7df05b3a4eadbe3 CRs-Fixed: 2183658 --- src/os_if_nan.c | 303 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 244 insertions(+), 59 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 5473bebceb..b696cb8b85 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -38,39 +38,90 @@ /* NLA policy */ static const struct nla_policy vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { - [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 }, - [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_NUL_STRING, - .len = IFNAMSIZ - 1 }, - [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { + .type = NLA_U16, + .len = sizeof(uint16_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { + .type = NLA_NUL_STRING, + .len = IFNAMSIZ - 1 + }, + [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = { - .type = NLA_BINARY, - .len = QDF_MAC_ADDR_SIZE }, - [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 }, - [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY, - .len = NDP_QOS_INFO_LEN }, - [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY, - .len = NDP_APP_INFO_LEN }, - [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 }, - [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY, - .len = QDF_MAC_ADDR_SIZE }, - [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY, - .len = NDP_NUM_INSTANCE_ID }, - [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { .type = NLA_BINARY, - .len = NDP_PMK_LEN }, - [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { .type = NLA_BINARY, - .len = NDP_SCID_BUF_LEN }, - [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { .type = - NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE] = { .type = NLA_BINARY, - .len = NAN_PASSPHRASE_MAX_LEN }, - [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME] = { .type = NLA_BINARY, - .len = NAN_MAX_SERVICE_NAME_LEN }, + .type = NLA_BINARY, + .len = QDF_MAC_ADDR_SIZE + }, + [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { + .type = NLA_U16, + .len = sizeof(uint16_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { + .type = NLA_BINARY, + .len = NDP_QOS_INFO_LEN + }, + [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { + .type = NLA_BINARY, + .len = NDP_APP_INFO_LEN + }, + [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { + .type = NLA_U16, + .len = sizeof(uint16_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { + .type = NLA_BINARY, + .len = QDF_MAC_ADDR_SIZE + }, + [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { + .type = NLA_BINARY, + .len = NDP_NUM_INSTANCE_ID + }, + [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { + .type = NLA_BINARY, + .len = NDP_PMK_LEN + }, + [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { + .type = NLA_BINARY, + .len = NDP_SCID_BUF_LEN + }, + [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE] = { + .type = NLA_BINARY, + .len = NAN_PASSPHRASE_MAX_LEN + }, + [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME] = { + .type = NLA_BINARY, + .len = NAN_MAX_SERVICE_NAME_LEN + }, }; static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, @@ -634,6 +685,24 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, return -EINVAL; } +static inline uint32_t osif_ndp_get_ndp_initiator_rsp_len(void) +{ + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); + + return data_len; +} + /** * os_if_ndp_initiator_rsp_handler() - NDP initiator response handler * @vdev: pointer to vdev object @@ -662,8 +731,7 @@ static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev, return; } - data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) + - NLMSG_HDRLEN + (5 * NLA_HDRLEN); + data_len = osif_ndp_get_ndp_initiator_rsp_len(); vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); @@ -704,6 +772,21 @@ ndp_initiator_rsp_nla_failed: kfree_skb(vendor_event); } +static inline uint32_t osif_ndp_get_ndp_responder_rsp_len(void) +{ + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); + + return data_len; +} /* * os_if_ndp_responder_rsp_handler() - NDP responder response handler @@ -735,8 +818,7 @@ static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev, cfg80211_debug("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d", wlan_vdev_get_id(rsp->vdev), rsp->transaction_id, rsp->status, rsp->reason); - data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) + - 4 * NLA_HDRLEN + NLMSG_HDRLEN; + data_len = osif_ndp_get_ndp_responder_rsp_len(); vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); @@ -770,6 +852,36 @@ ndp_responder_rsp_nla_failed: kfree_skb(vendor_event); } +static inline uint32_t osif_ndp_get_ndp_req_ind_len( + struct nan_datapath_indication_event *event) +{ + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE].len); + /* allocate space including NULL terminator */ + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len); + if (event->scid.scid_len) + data_len += nla_total_size(event->scid.scid_len); + if (event->ndp_info.ndp_app_info_len) + data_len += nla_total_size(event->ndp_info.ndp_app_info_len); + + return data_len; +} + /** * os_if_ndp_indication_handler() - NDP indication handler * @vdev: pointer to vdev object @@ -830,10 +942,7 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, return; } - data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + - ifname_len + event->ndp_info.ndp_app_info_len + - event->scid.scid_len + (10 * NLA_HDRLEN) + NLMSG_HDRLEN; - + data_len = osif_ndp_get_ndp_req_ind_len(event); /* notify response to the upper layer */ vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, data_len, @@ -911,6 +1020,31 @@ ndp_indication_nla_failed: kfree_skb(vendor_event); } +static inline uint32_t osif_ndp_get_ndp_confirm_ind_len( + struct nan_datapath_confirm_event *ndp_confirm) +{ + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len); + /* allocate space including NULL terminator */ + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); + if (ndp_confirm->ndp_info.ndp_app_info_len) + data_len += + nla_total_size(ndp_confirm->ndp_info.ndp_app_info_len); + + return data_len; +} + /** * os_if_ndp_confirm_ind_handler() - NDP confirm indication handler * @vdev: pointer to vdev object @@ -924,7 +1058,7 @@ ndp_indication_nla_failed: * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ) * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size) * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes) - * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) * * Return: none */ @@ -980,13 +1114,7 @@ static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, return; } - data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + ifname_len + - + NLMSG_HDRLEN + (7 * NLA_HDRLEN) + - ndp_confirm->ndp_info.ndp_app_info_len; - - if (ndp_confirm->ndp_info.ndp_app_info_len) - data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len; - + data_len = osif_ndp_get_ndp_confirm_ind_len(ndp_confirm); vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); @@ -1045,6 +1173,22 @@ ndp_confirm_nla_failed: kfree_skb(vendor_event); } +static inline uint32_t osif_ndp_get_ndp_end_rsp_len(void) +{ + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); + + return data_len; +} + /** * os_if_ndp_end_rsp_handler() - NDP end response handler * @vdev: pointer to vdev object @@ -1072,9 +1216,7 @@ static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev, return; } - data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) + - sizeof(uint16_t); - + data_len = osif_ndp_get_ndp_end_rsp_len(); vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); @@ -1110,6 +1252,20 @@ ndp_end_rsp_nla_failed: kfree_skb(vendor_event); } +static inline uint32_t osif_ndp_get_ndp_end_ind_len( + struct nan_datapath_end_indication_event *end_ind) +{ + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + if (end_ind->num_ndp_ids) + data_len += nla_total_size(end_ind->num_ndp_ids * + sizeof(uint32_t)); + + return data_len; +} + /** * os_if_ndp_end_ind_handler() - NDP end indication handler * @vdev: pointer to vdev object @@ -1178,9 +1334,7 @@ static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev, idx); } - data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) + - end_ind->num_ndp_ids * sizeof(*ndp_instance_array); - + data_len = osif_ndp_get_ndp_end_ind_len(end_ind); vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); @@ -1288,6 +1442,22 @@ static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev, (active_peers == 0 ? true : false)); } +static inline uint32_t osif_ndp_get_ndi_create_rsp_len(void) +{ + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); + + return data_len; +} + /** * os_if_ndp_iface_create_rsp_handler() - NDP iface create response handler * @adapter: pointer to adapter context @@ -1309,6 +1479,7 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, void *rsp_params) { + uint32_t data_len; QDF_STATUS status; bool create_fail = false; struct nan_callbacks cb_obj; @@ -1320,8 +1491,6 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, uint32_t create_reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED; struct nan_datapath_inf_create_rsp *ndi_rsp = (struct nan_datapath_inf_create_rsp *)rsp_params; - uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) + - NLMSG_HDRLEN + (4 * NLA_HDRLEN); status = ucfg_nan_get_callbacks(psoc, &cb_obj); if (QDF_IS_STATUS_ERROR(status)) { @@ -1338,7 +1507,7 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, } create_transaction_id = ucfg_nan_get_ndp_create_transaction_id(vdev); - + data_len = osif_ndp_get_ndi_create_rsp_len(); /* notify response to the upper layer */ vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, @@ -1555,13 +1724,28 @@ void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc, wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID); } +static inline uint32_t osif_ndp_get_ndi_delete_rsp_len(void) +{ + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len); + + return data_len; +} + void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) { + uint32_t data_len; struct sk_buff *vendor_event; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); - uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) + - (NLA_HDRLEN * 4) + NLMSG_HDRLEN; /* * The virtual adapters are stopped and closed even during @@ -1573,6 +1757,7 @@ void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) return; } + data_len = osif_ndp_get_ndi_delete_rsp_len(); /* notify response to the upper layer */ vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, From 654aee1236dd8094f3f1a1cf1ed73fb2659e77b3 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 7 May 2018 17:42:32 -0700 Subject: [PATCH 25/39] qcacmn: Fix NDP Discovery MAC address policy The current qca_wlan_vendor_ndp_policy for attribute QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR uses type NLA_BINARY. Unfortunately this type uses the len as a maximum length and not a minimum length which means that nla_parse() cannot guarantee that 6 bytes of MAC address are present. Change the policy to use type NLA_UNSPEC so that nla_parse() will ensure that the NDP Discovery MAC address TLV contains (at least) 6 bytes. Change-Id: I2c7e1efdb413dbd2f79c36ed1626c006b86e8b5b CRs-Fixed: 2237658 --- src/os_if_nan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index b696cb8b85..a5c6bb454a 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -59,7 +59,7 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { .len = sizeof(uint32_t) }, [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = { - .type = NLA_BINARY, + .type = NLA_UNSPEC, .len = QDF_MAC_ADDR_SIZE }, [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { From bc404efdf3220f540dd4f07848cc611fd3d2426a Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 7 May 2018 17:46:00 -0700 Subject: [PATCH 26/39] qcacmn: Fix NDP Response Code policy The qca_wlan_vendor_ndp_policy for the attribute QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE currently specifies type NLA_U16. However this attribute is defined to be an unsigned 32 bit value, and nla_get_u32() is used to read the value, so change the policy to use type NLA_U32 so that nla_parse() can properly verify that the TLV payload has (at least) 4 bytes of data. Change-Id: I915a94e7449c2bc1abde64e2a7f5df6a58488ed6 CRs-Fixed: 2237659 --- src/os_if_nan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index a5c6bb454a..f395725711 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -79,8 +79,8 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { .len = sizeof(uint32_t) }, [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { - .type = NLA_U16, - .len = sizeof(uint16_t) + .type = NLA_U32, + .len = sizeof(uint32_t) }, [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY, From c3fd2a0d86003c0958a71c0b581277a3c6e707b7 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 7 May 2018 17:55:20 -0700 Subject: [PATCH 27/39] qcacmn: Fix NDP Config QoS policy The qca_wlan_vendor_ndp_policy for the attribute QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS currently specifies type NLA_BINARY with a maximum length of NDP_QOS_INFO_LEN (255). However this attribute is defined to be an unsigned 32 bit value, and nla_get_u32() is used to read the value, so change the policy to use type NLA_U32 so that nla_parse() can properly verify that the TLV payload has (at least) 4 bytes of data. Change-Id: Iee5b620ef199b731fc6a449d0055db328430921b CRs-Fixed: 2237660 --- src/os_if_nan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index f395725711..f9a35beb73 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -67,8 +67,8 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { .len = sizeof(uint16_t) }, [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { - .type = NLA_BINARY, - .len = NDP_QOS_INFO_LEN + .type = NLA_U32, + .len = sizeof(uint32_t) }, [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY, From 94763f52614624e3f5498afb53225bd5f8e5fba0 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Wed, 9 May 2018 11:09:41 -0700 Subject: [PATCH 28/39] qcacmn: Use NDP vendor attribute from qca_vendor.h Update qca_vendor.h with latest NDP vendor attribute definitions and use those definitions in NAN component. Change-Id: I43f0457690b1c4027adcd0abe4ef2ac2a8f9b068 CRs-Fixed: 2239047 --- inc/os_if_nan.h | 85 ------------------------------------------------- src/os_if_nan.c | 16 +++++----- 2 files changed, 8 insertions(+), 93 deletions(-) diff --git a/inc/os_if_nan.h b/inc/os_if_nan.h index 151c457bbf..338ea7462d 100644 --- a/inc/os_if_nan.h +++ b/inc/os_if_nan.h @@ -32,91 +32,6 @@ struct wlan_objmgr_vdev; #ifdef WLAN_FEATURE_NAN_CONVERGENCE -/** - * enum qca_wlan_vendor_attr_ndp_params - vendor attribute parameters - * @QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD: NDP Sub command - * @QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID: Transaction id reference - * @QCA_WLAN_VENDOR_ATTR_NDP_STATUS_ID: NDP status id - * @QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID: Service instance id - * @QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL: Requested channel - * @QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR: Peer discovery mac addr - * @QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR: Iface name - * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY: Security configuration - * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS: Qos configuration - * @QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO: Application info - * @QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID: NDP instance id - * @QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY: NDP instance id array - * @QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE: Schedule response - * @QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR: NDI mac address - * @QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE: Driver return status - * @QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE: Driver return value - * @QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG: Channel config request type - * @QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE: Cipher Suit ID - * @QCA_WLAN_VENDOR_ATTR_NDP_PMK: Pairwise Master Key - * @QCA_WLAN_VENDOR_ATTR_NDP_SCID: Security Context ID - * @QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - pass phrase - * @QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - service name - */ -enum qca_wlan_vendor_attr_ndp_params { - QCA_WLAN_VENDOR_ATTR_NDP_PARAM_INVALID = 0, - QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, - QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, - QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, - QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, - QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, - QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, - /* CONFIG_SECURITY is deprecated, use NCS_SK_TYPE/PMK/SCID instead */ - QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY, - QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, - QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, - QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, - QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, - QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, - QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, - QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, - QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, - QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG, - QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE, - QCA_WLAN_VENDOR_ATTR_NDP_PMK, - QCA_WLAN_VENDOR_ATTR_NDP_SCID, - QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE, - QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME, - - QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST, - QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX = - QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST - 1, -}; - -/** - * enum qca_wlan_vendor_attr_ndp_sub_cmd_value - NDP subcmd value - * @QCA_WLAN_VENDOR_ATTR_NDP_INVALID: Unused subcmd value - * @QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE: iface create - * @QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE: iface delete - * @QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST: NDP initiator request - * @QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE: NDP initiator response - * @QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST: NDP responder request - * @QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE: NDP responder response - * @QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST: NDP end request - * @QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE: NDP end response - * @QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND: NDP request indication - * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND: NDP confirm indication - * @QCA_WLAN_VENDOR_ATTR_NDP_END_IND: NDP End indication - */ -enum qca_wlan_vendor_attr_ndp_sub_cmd_value { - QCA_WLAN_VENDOR_ATTR_NDP_INVALID = 0, - QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE = 1, - QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE = 2, - QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST = 3, - QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE = 4, - QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST = 5, - QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE = 6, - QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST = 7, - QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE = 8, - QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND = 9, - QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND = 10, - QCA_WLAN_VENDOR_ATTR_NDP_END_IND = 11 -}; - /** * os_if_nan_process_ndp_cmd: os_if api to handle nan request message * @psoc: pointer to psoc object diff --git a/src/os_if_nan.c b/src/os_if_nan.c index f9a35beb73..fc06c42f0a 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -94,7 +94,7 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { .type = NLA_U32, .len = sizeof(uint32_t) }, - [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { + [QCA_WLAN_VENDOR_ATTR_NDP_CSID] = { .type = NLA_U32, .len = sizeof(uint32_t) }, @@ -252,9 +252,9 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, return -EINVAL; } - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) { + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CSID]) { *ncs_sk_type = - nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]); + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CSID]); } if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) { @@ -309,7 +309,7 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional - * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional + * QCA_WLAN_VENDOR_ATTR_NDP_CSID - optional * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional * @@ -441,7 +441,7 @@ initiator_req_failed: * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional - * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional + * QCA_WLAN_VENDOR_ATTR_NDP_CSID - optional * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional * @@ -866,7 +866,7 @@ static inline uint32_t osif_ndp_get_ndp_req_ind_len( data_len += nla_total_size(vendor_attr_policy[ QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS].len); data_len += nla_total_size(vendor_attr_policy[ - QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE].len); + QCA_WLAN_VENDOR_ATTR_NDP_CSID].len); /* allocate space including NULL terminator */ data_len += nla_total_size(vendor_attr_policy[ QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1); @@ -897,7 +897,7 @@ static inline uint32_t osif_ndp_get_ndp_req_ind_len( * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes) * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size) * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes) - * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_CSID(4 bytes) * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size) * * Return: none @@ -997,7 +997,7 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, if (event->scid.scid_len) { if (nla_put_u32(vendor_event, - QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE, + QCA_WLAN_VENDOR_ATTR_NDP_CSID, event->ncs_sk_type)) goto ndp_indication_nla_failed; From 366330a4177db9b12b327edd8d987a212e01c634 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Tue, 9 Jan 2018 17:54:41 -0800 Subject: [PATCH 29/39] qcacmn: Implement ndp schedule update and channel info in ndp confirm Add support for ndp schedule update event and provide channel information in ndp confirm event. Change-Id: Ic2c073dd4f220627cc2bd1a2d52d858136b6b450 CRs-Fixed: 2180310 --- src/os_if_nan.c | 248 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 241 insertions(+), 7 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index fc06c42f0a..92f00d2bd8 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -122,6 +122,14 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { .type = NLA_BINARY, .len = NAN_MAX_SERVICE_NAME_LEN }, + [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO] = { + .type = NLA_BINARY, + .len = NAN_CH_INFO_MAX_LEN + }, + [QCA_WLAN_VENDOR_ATTR_NDP_NSS] = { + .type = NLA_U32, + .len = sizeof(uint32_t) + }, }; static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, @@ -1023,6 +1031,7 @@ ndp_indication_nla_failed: static inline uint32_t osif_ndp_get_ndp_confirm_ind_len( struct nan_datapath_confirm_event *ndp_confirm) { + uint32_t ch_info_len = 0; uint32_t data_len = NLMSG_HDRLEN; data_len += nla_total_size(vendor_attr_policy[ @@ -1042,9 +1051,62 @@ static inline uint32_t osif_ndp_get_ndp_confirm_ind_len( data_len += nla_total_size(ndp_confirm->ndp_info.ndp_app_info_len); + /* ch_info is a nested array of following attributes */ + ch_info_len += nla_total_size( + vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len); + ch_info_len += nla_total_size( + vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH].len); + ch_info_len += nla_total_size( + vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_NSS].len); + + if (ndp_confirm->num_channels) + data_len += ndp_confirm->num_channels * + nla_total_size(ch_info_len); + return data_len; } +static QDF_STATUS os_if_ndp_confirm_pack_ch_info(struct sk_buff *event, + struct nan_datapath_confirm_event *ndp_confirm) +{ + int idx = 0; + struct nlattr *ch_array, *ch_element; + + cfg80211_debug("num_ch: %d", ndp_confirm->num_channels); + if (!ndp_confirm->num_channels) + return QDF_STATUS_SUCCESS; + + ch_array = nla_nest_start(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO); + if (!ch_array) + return QDF_STATUS_E_FAULT; + + for (idx = 0; idx < ndp_confirm->num_channels; idx++) { + cfg80211_debug("ch[%d]: freq: %d, width: %d, nss: %d", + idx, ndp_confirm->ch[idx].channel, + ndp_confirm->ch[idx].ch_width, + ndp_confirm->ch[idx].nss); + ch_element = nla_nest_start(event, idx); + if (!ch_element) + return QDF_STATUS_E_FAULT; + + if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, + ndp_confirm->ch[idx].channel)) + return QDF_STATUS_E_FAULT; + + if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH, + ndp_confirm->ch[idx].ch_width)) + return QDF_STATUS_E_FAULT; + + if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_NSS, + ndp_confirm->ch[idx].nss)) + return QDF_STATUS_E_FAULT; + nla_nest_end(event, ch_element); + } + nla_nest_end(event, ch_array); + + return QDF_STATUS_SUCCESS; +} + /** * os_if_ndp_confirm_ind_handler() - NDP confirm indication handler * @vdev: pointer to vdev object @@ -1062,20 +1124,20 @@ static inline uint32_t osif_ndp_get_ndp_confirm_ind_len( * * Return: none */ -static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, - struct nan_datapath_confirm_event *ndp_confirm) +static void +os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, + struct nan_datapath_confirm_event *ndp_confirm) { int idx = 0; uint8_t *ifname; uint32_t data_len; QDF_STATUS status; qdf_size_t ifname_len; - uint32_t ndp_qos_config = 0; + struct nan_callbacks cb_obj; struct sk_buff *vendor_event; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); - struct nan_callbacks cb_obj; if (!ndp_confirm) { cfg80211_err("Invalid NDP Initator response"); @@ -1156,12 +1218,19 @@ static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, ndp_confirm->reason_code)) goto ndp_confirm_nla_failed; + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS, + ndp_confirm->num_channels)) + goto ndp_confirm_nla_failed; + + status = os_if_ndp_confirm_pack_ch_info(vendor_event, ndp_confirm); + if (QDF_IS_STATUS_ERROR(status)) + goto ndp_confirm_nla_failed; + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); - cfg80211_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM, ndp_cfg: %d, rsp_code: %d, reason_code: %d", + cfg80211_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM rsp_code: %d, reason_code: %d", ndp_confirm->ndp_instance_id, ndp_confirm->peer_ndi_mac_addr.bytes, - ndp_qos_config, ndp_confirm->rsp_code, - ndp_confirm->reason_code); + ndp_confirm->rsp_code, ndp_confirm->reason_code); cfg80211_debug("NDP confim, ndp app info dump"); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, @@ -1620,6 +1689,168 @@ static void os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc *psoc, cb_obj.drv_ndi_delete_rsp_handler(vdev_id); } +static inline uint32_t osif_ndp_get_ndp_sch_update_ind_len( + struct nan_datapath_sch_update_event *sch_update) +{ + uint32_t ch_info_len = 0; + uint32_t data_len = NLMSG_HDRLEN; + + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len); + if (sch_update->num_ndp_instances) + data_len += nla_total_size(sch_update->num_ndp_instances * + sizeof(uint32_t)); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON].len); + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS].len); + /* ch_info is a nested array of following attributes */ + ch_info_len += nla_total_size( + vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len); + ch_info_len += nla_total_size( + vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH].len); + ch_info_len += nla_total_size( + vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_NSS].len); + + if (sch_update->num_ndp_instances) + data_len += sch_update->num_ndp_instances * + nla_total_size(ch_info_len); + + return data_len; +} + +static QDF_STATUS os_if_ndp_sch_update_pack_ch_info(struct sk_buff *event, + struct nan_datapath_sch_update_event *sch_update) +{ + int idx = 0; + struct nlattr *ch_array, *ch_element; + + cfg80211_debug("num_ch: %d", sch_update->num_channels); + if (!sch_update->num_channels) + return QDF_STATUS_SUCCESS; + + ch_array = nla_nest_start(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO); + if (!ch_array) + return QDF_STATUS_E_FAULT; + + for (idx = 0; idx < sch_update->num_channels; idx++) { + cfg80211_debug("ch[%d]: freq: %d, width: %d, nss: %d", + idx, sch_update->ch[idx].channel, + sch_update->ch[idx].ch_width, + sch_update->ch[idx].nss); + ch_element = nla_nest_start(event, idx); + if (!ch_element) + return QDF_STATUS_E_FAULT; + + if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, + sch_update->ch[idx].channel)) + return QDF_STATUS_E_FAULT; + + if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH, + sch_update->ch[idx].ch_width)) + return QDF_STATUS_E_FAULT; + + if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_NSS, + sch_update->ch[idx].nss)) + return QDF_STATUS_E_FAULT; + nla_nest_end(event, ch_element); + } + nla_nest_end(event, ch_array); + + return QDF_STATUS_SUCCESS; +} + +/** + * os_if_ndp_sch_update_ind_handler() - NDP schedule update handler + * @vdev: vdev object pointer + * @ind: sch update pointer + * + * Following vendor event is sent to cfg80211: + * + * Return: none + */ +static void os_if_ndp_sch_update_ind_handler(struct wlan_objmgr_vdev *vdev, + void *ind) +{ + int idx = 0; + uint8_t *ifname; + QDF_STATUS status; + uint32_t data_len; + uint8_t ifname_len; + struct sk_buff *vendor_event; + struct nan_datapath_sch_update_event *sch_update = ind; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); + + if (!sch_update) { + cfg80211_err("Invalid sch update params"); + return; + } + + ifname = wlan_util_vdev_get_if_name(vdev); + if (!ifname) { + cfg80211_err("ifname is null"); + return; + } + ifname_len = qdf_str_len(ifname); + if (ifname_len > IFNAMSIZ) { + cfg80211_err("ifname(%d) too long", ifname_len); + return; + } + + data_len = osif_ndp_get_ndp_sch_update_ind_len(sch_update); + vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_ATOMIC); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND)) + goto ndp_sch_ind_nla_failed; + + if (nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, + QDF_MAC_ADDR_SIZE, sch_update->peer_addr.bytes)) + goto ndp_sch_ind_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, + sch_update->num_ndp_instances * sizeof(uint32_t), + sch_update->ndp_instances)) + goto ndp_sch_ind_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON, + sch_update->flags)) + goto ndp_sch_ind_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS, + sch_update->num_channels)) + goto ndp_sch_ind_nla_failed; + + status = os_if_ndp_sch_update_pack_ch_info(vendor_event, sch_update); + if (QDF_IS_STATUS_ERROR(status)) + goto ndp_sch_ind_nla_failed; + + cfg80211_debug("Flags: %d, num_instance_id: %d", sch_update->flags, + sch_update->num_ndp_instances); + + for (idx = 0; idx < sch_update->num_ndp_instances; idx++) + cfg80211_debug("ndp_instance[%d]: %d", idx, + sch_update->ndp_instances[idx]); + + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); + return; + +ndp_sch_ind_nla_failed: + cfg80211_err("nla_put api failed"); + kfree_skb(vendor_event); +} + void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, uint32_t type, void *msg) @@ -1655,6 +1886,9 @@ void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc, case NDP_PEER_DEPARTED: os_if_peer_departed_ind_handler(vdev, msg); break; + case NDP_SCHEDULE_UPDATE: + os_if_ndp_sch_update_ind_handler(vdev, msg); + break; default: break; } From 93a3d3a358ce0af790c4d4c33c3f9844d1b33866 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Thu, 7 Jun 2018 11:50:40 -0700 Subject: [PATCH 30/39] qcacmn: Fix NPD in function os_if_nan_process_ndp_responder_req While processing of NDP responder request if NDP response code is accept NDI interface is must. Throw error if interface is not provided and bail out of the function. Change-Id: I7266e3c82062130f6dbeb078cddfaa15a87d9197 CRs-Fixed: 2247586 --- src/os_if_nan.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 92f00d2bd8..bf8b29c5d6 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -473,24 +473,24 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); if (req.ndp_rsp == NAN_DATAPATH_RESPONSE_ACCEPT) { - if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { - iface_name = - nla_data( - tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + cfg80211_err("Interface not provided"); + return -ENODEV; + } + iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); - /* Check for an existing NAN interface */ - nan_vdev = wlan_util_get_vdev_by_ifname(psoc, - iface_name, WLAN_NAN_ID); - if (!nan_vdev) { - cfg80211_err("NAN data iface %s not available", - iface_name); - return -ENODEV; - } + /* Check for an existing NAN interface */ + nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, + WLAN_NAN_ID); + if (!nan_vdev) { + cfg80211_err("NAN data iface %s not available", + iface_name); + return -ENODEV; + } - if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { - cfg80211_err("Interface found is not NDI"); - return -ENODEV; - } + if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { + cfg80211_err("Interface found is not NDI"); + return -ENODEV; } } else { From fad2a7d06b56ad87151af752cae29553096c3044 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Wed, 30 May 2018 17:47:15 -0700 Subject: [PATCH 31/39] qcacmn: Fix NDI create sequence Create NDI vdev after adapter is added to back of hdd adapter list, so that vdev create completion callback can identify right adapter and set corresponding completion variable. Change-Id: Id0d78a5e482c875fee346224f37c29a874814133 CRs-Fixed: 2252031 --- src/os_if_nan.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index bf8b29c5d6..6a08c88adb 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -135,6 +135,7 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, struct nlattr **tb) { + int ret; char *iface_name; QDF_STATUS status; uint16_t transaction_id; @@ -169,21 +170,14 @@ static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, return -EINVAL; } - nan_vdev = cb_obj.ndi_open(iface_name); - - if (!nan_vdev) { + ret = cb_obj.ndi_open(iface_name); + if (ret) { cfg80211_err("ndi_open failed"); - return -EINVAL; + return ret; } - /* - * Create transaction id is required to be saved since the firmware - * does not honor the transaction id for create request - */ - ucfg_nan_set_ndp_create_transaction_id(nan_vdev, transaction_id); - ucfg_nan_set_ndi_state(nan_vdev, NAN_DATA_NDI_CREATING_STATE); - return cb_obj.ndi_start(wlan_vdev_get_id(nan_vdev)); + return cb_obj.ndi_start(iface_name, transaction_id); } static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, From 39a489d82d9a896dfcf42dfa22937f065dba9e66 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Thu, 31 May 2018 10:40:32 -0700 Subject: [PATCH 32/39] qcacmn: Fix vdev reference in NDP commands Assign the vdev in NDP request message and hold the vdev reference till the command is processed. Else the consumer of message will fail when trying to take reference since vdev was not set in request packet. Change-Id: I4c7e50690eff1f92f151f00209ec786a03252e76 CRs-Fixed: 2252035 --- src/os_if_nan.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 6a08c88adb..06edb07f4b 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -341,7 +341,8 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { cfg80211_err("Interface found is not NDI"); - return -EINVAL; + ret = -EINVAL; + goto initiator_req_failed; } state = ucfg_nan_get_ndi_state(nan_vdev); @@ -422,10 +423,12 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, req.service_instance_id, req.ndp_info.ndp_app_info_len, req.ncs_sk_type, req.peer_discovery_mac_addr.bytes); + req.vdev = nan_vdev; status = ucfg_nan_req_processor(nan_vdev, &req, NDP_INITIATOR_REQ); ret = qdf_status_to_os_return(status); initiator_req_failed: - wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); + if (ret) + wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); return ret; } @@ -461,8 +464,7 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) { cfg80211_err("ndp_rsp is unavailable"); - ret = -EINVAL; - goto responder_req_failed; + return -EINVAL; } req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); @@ -484,7 +486,8 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { cfg80211_err("Interface found is not NDI"); - return -ENODEV; + ret = -ENODEV; + goto responder_req_failed; } } else { @@ -513,8 +516,6 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, goto responder_req_failed; } - req.vdev = nan_vdev; - if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { cfg80211_err("Transaction ID is unavailable"); ret = -EINVAL; @@ -562,11 +563,13 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, req.ndp_instance_id, req.ndp_info.ndp_app_info_len, req.ncs_sk_type); + req.vdev = nan_vdev; status = ucfg_nan_req_processor(nan_vdev, &req, NDP_RESPONDER_REQ); ret = qdf_status_to_os_return(status); responder_req_failed: - wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); + if (ret) + wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); return ret; @@ -623,9 +626,11 @@ static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, return -EINVAL; } + req.vdev = nan_vdev; status = ucfg_nan_req_processor(nan_vdev, &req, NDP_END_REQ); ret = qdf_status_to_os_return(status); - wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); + if (ret) + wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); return ret; } From 4ceeebe462a7a234a79f27da6907235e4f4e2341 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Thu, 31 May 2018 15:04:59 -0700 Subject: [PATCH 33/39] qcacmn: Add support for NDP TCP/IP params Add support for NDP TCP/IP params in ndp initiator request, responder request, indication and confirm. Change-Id: I5d60af154ea4a2f33d18d9b86049f316e7fbc524 CRs-Fixed: 2252227 --- src/os_if_nan.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 06edb07f4b..95ab8154df 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -130,6 +130,18 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { .type = NLA_U32, .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR] = { + .type = NLA_UNSPEC, + .len = QDF_IPV6_ADDR_SIZE + }, + [QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT] = { + .type = NLA_U16, + .len = sizeof(uint16_t) + }, + [QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL] = { + .type = NLA_U8, + .len = sizeof(uint8_t) + }, }; static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, @@ -411,6 +423,15 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); } + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) { + req.is_ipv6_addr_present = true; + qdf_mem_copy(req.ipv6_addr, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]), + QDF_IPV6_ADDR_SIZE); + } + cfg80211_debug("ipv6 addr present: %d, addr: %pI6", + req.is_ipv6_addr_present, req.ipv6_addr); + if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, &req.passphrase, &req.service_name)) { cfg80211_err("inconsistent security params in request."); @@ -490,7 +511,6 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, goto responder_req_failed; } } else { - /* * If the data indication is rejected, the userspace * may not send the iface name. Use the first NDI @@ -551,6 +571,28 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, cfg80211_debug("NDP config data is unavailable"); } + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) { + req.is_ipv6_addr_present = true; + qdf_mem_copy(req.ipv6_addr, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]), + QDF_IPV6_ADDR_SIZE); + } + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT]) { + req.is_port_present = true; + req.port = nla_get_u16( + tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT]); + } + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]) { + req.is_protocol_present = true; + req.protocol = nla_get_u8( + tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]); + } + cfg80211_debug("ipv6 addr present: %d, addr: %pI6", + req.is_ipv6_addr_present, req.ipv6_addr); + cfg80211_debug("port %d, present: %d", req.port, req.is_port_present); + cfg80211_debug("protocol %d, present: %d", + req.protocol, req.is_protocol_present); + if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, &req.passphrase, &req.service_name)) { cfg80211_err("inconsistent security params in request."); @@ -881,6 +923,9 @@ static inline uint32_t osif_ndp_get_ndp_req_ind_len( QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len); data_len += nla_total_size(vendor_attr_policy[ QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len); + if (event->is_ipv6_addr_present) + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR].len); if (event->scid.scid_len) data_len += nla_total_size(event->scid.scid_len); if (event->ndp_info.ndp_app_info_len) @@ -906,6 +951,7 @@ static inline uint32_t osif_ndp_get_ndp_req_ind_len( * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes) * QCA_WLAN_VENDOR_ATTR_NDP_CSID(4 bytes) * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size) + * QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR (16 bytes) * * Return: none */ @@ -1020,6 +1066,14 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, event->scid.scid, event->scid.scid_len); } + if (event->is_ipv6_addr_present) { + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR, + QDF_IPV6_ADDR_SIZE, event->ipv6_addr)) + goto ndp_indication_nla_failed; + } + cfg80211_debug("ipv6 addr present: %d, addr: %pI6", + event->is_ipv6_addr_present, event->ipv6_addr); + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); return; ndp_indication_nla_failed: @@ -1050,6 +1104,16 @@ static inline uint32_t osif_ndp_get_ndp_confirm_ind_len( data_len += nla_total_size(ndp_confirm->ndp_info.ndp_app_info_len); + if (ndp_confirm->is_ipv6_addr_present) + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR].len); + if (ndp_confirm->is_port_present) + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT].len); + if (ndp_confirm->is_protocol_present) + data_len += nla_total_size(vendor_attr_policy[ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL].len); + /* ch_info is a nested array of following attributes */ ch_info_len += nla_total_size( vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len); @@ -1120,6 +1184,9 @@ static QDF_STATUS os_if_ndp_confirm_pack_ch_info(struct sk_buff *event, * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size) * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes) * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR (16 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT (2 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL (1 byte) * * Return: none */ @@ -1225,6 +1292,29 @@ os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) goto ndp_confirm_nla_failed; + if (ndp_confirm->is_ipv6_addr_present) { + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR, + QDF_IPV6_ADDR_SIZE, ndp_confirm->ipv6_addr)) + goto ndp_confirm_nla_failed; + } + if (ndp_confirm->is_port_present) + if (nla_put_u16(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT, + ndp_confirm->port)) + goto ndp_confirm_nla_failed; + if (ndp_confirm->is_protocol_present) + if (nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL, + ndp_confirm->protocol)) + goto ndp_confirm_nla_failed; + cfg80211_debug("ipv6 addr present: %d, addr: %pI6", + ndp_confirm->is_ipv6_addr_present, + ndp_confirm->ipv6_addr); + cfg80211_debug("port %d, present: %d", + ndp_confirm->port, ndp_confirm->is_port_present); + cfg80211_debug("protocol %d, present: %d", + ndp_confirm->protocol, ndp_confirm->is_protocol_present); + cfg80211_vendor_event(vendor_event, GFP_ATOMIC); cfg80211_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM rsp_code: %d, reason_code: %d", ndp_confirm->ndp_instance_id, From b85908687851d1704d676bb98f671326e200c039 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Wed, 20 Jun 2018 19:48:17 -0700 Subject: [PATCH 34/39] qcacmn: Free NDI peers/vdev at time of ndi_delete/driver unload Sometime user may not delete active NDP sessions before deleting NDI or may not delete NDI before driver unload. In such case vdev/peer object memory will leak. Free all NDI peers for that vdev before processing NDI delete and free all NDI peers/vdev at driver unload. Change-Id: I04631ffd611d6ded318ddfb65b2dfeba479c9bdc CRs-Fixed: 2262769 --- src/os_if_nan.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 95ab8154df..614bf2febb 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -33,6 +33,7 @@ #include "wlan_objmgr_psoc_obj.h" #include "wlan_objmgr_pdev_obj.h" #include "wlan_objmgr_vdev_obj.h" +#include "wlan_objmgr_peer_obj.h" #include "wlan_utility.h" /* NLA policy */ @@ -188,10 +189,20 @@ static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, return ret; } - return cb_obj.ndi_start(iface_name, transaction_id); } +static void os_if_nan_vdev_delete_peer(struct wlan_objmgr_psoc *psoc, + void *peer, void *nan_vdev) +{ + /* if peer belongs to nan vdev */ + if (nan_vdev == wlan_peer_get_vdev(peer)) { + cfg80211_debug("deleting peer: %pM", + wlan_peer_get_macaddr(peer)); + wlan_objmgr_peer_obj_delete(peer); + } +} + static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, struct nlattr **tb) { @@ -225,6 +236,12 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); vdev_id = wlan_vdev_get_id(nan_vdev); num_peers = ucfg_nan_get_active_peers(nan_vdev); + + /* delete all peer for this interface first */ + wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP, + os_if_nan_vdev_delete_peer, + nan_vdev, 1, WLAN_UMAC_COMP_NAN); + /* * wlan_util_get_vdev_by_ifname increments ref count * decrement here since vdev returned by that api is not used any more From 803f628422de9cb6ae585e56e3b11091218155e6 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Fri, 29 Jun 2018 11:42:13 +0800 Subject: [PATCH 35/39] qcacmn: Fix compile implicit conversion from enumeration type error Error: implicit conversion from enumeration type 'enum wlan_umac_comp_id' to different enumeration type 'wlan_objmgr_ref_dbgid' [-Werror,-Wenum-conversion] Change-Id: I641c1eee77e977547841cebb4fd2fef8c06ca18c CRs-Fixed: 2271058 --- src/os_if_nan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 614bf2febb..b55ec22fec 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -240,7 +240,7 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, /* delete all peer for this interface first */ wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP, os_if_nan_vdev_delete_peer, - nan_vdev, 1, WLAN_UMAC_COMP_NAN); + nan_vdev, 1, WLAN_NAN_ID); /* * wlan_util_get_vdev_by_ifname increments ref count From 634d8e81113519b5939cc9cf0db29871f17f503a Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Tue, 24 Jul 2018 09:44:39 -0700 Subject: [PATCH 36/39] qcacmn: Remove session_id from nan_datapath_peer_ind (Step 1) Currently struct nan_datapath_peer_ind contains the following: uint8_t session_id; This is problematic since "session_id" is a legacy concept and should not be used in the converged project. Fortunately this field does not actually serve any purpose. But in order to cleanly remove it a 3-step approach is required. Step 1 (this change): Remove the logic from the converged NAN code which currently reads this field and logs the value. Step 2 (qcacld-3.0 Change I2819556d48a9dd901158aaa04d6bda9c36f33012): Remove the logic from the legacy NAN code which sets this field. Step 3 (qcacld Change Ibeb8007c96ae1a902bfd7dd99a42ba4a291a1dc6): Remove the session_id field from struct nan_datapath_peer_ind. Change-Id: If6cf48ccbfe87b23b275720df51c6cc26af9fa5e CRs-Fixed: 2284399 --- src/os_if_nan.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index b55ec22fec..37f97272c2 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -1565,9 +1565,9 @@ static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev, return; } - cfg80211_debug("session_id: %d, peer_mac: %pM, sta_id: %d", - peer_ind->session_id, peer_ind->peer_mac_addr.bytes, - peer_ind->sta_id); + cfg80211_debug("vdev_id: %d, peer_mac: %pM, sta_id: %d", + vdev_id, peer_ind->peer_mac_addr.bytes, + peer_ind->sta_id); ret = cb_obj.new_peer_ind(vdev_id, peer_ind->sta_id, &peer_ind->peer_mac_addr, (active_peers == 0 ? true : false)); @@ -1607,9 +1607,9 @@ static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev, cfg80211_err("Invalid new NDP peer params"); return; } - cfg80211_debug("session_id: %d, peer_mac: %pM, sta_id: %d", - peer_ind->session_id, peer_ind->peer_mac_addr.bytes, - peer_ind->sta_id); + cfg80211_debug("vdev_id: %d, peer_mac: %pM, sta_id: %d", + vdev_id, peer_ind->peer_mac_addr.bytes, + peer_ind->sta_id); active_peers--; ucfg_nan_set_active_peers(vdev, active_peers); cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id, From 1c9262fb9869a272d60e40bf5b326fc79b0aec49 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 20 Sep 2018 16:59:00 +0530 Subject: [PATCH 37/39] qcacmn: Release vdev ref in os_if_ndp_end_ind_handler NAN vdev ref count incremented as part of end_ind handler is not released which will result in the nan vdev not getting physically deleted. Fix is to release nan vdev ref in os_if_ndp_end_ind_handler. Change-Id: I31a32fa241fb9e86d3a64d490722bc42905970c4 CRs-Fixed: 2325580 --- src/os_if_nan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 37f97272c2..0dd33424d1 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -1496,17 +1496,19 @@ static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev, continue; } - idx = cb_obj.get_peer_idx(wlan_vdev_get_id(vdev), + idx = cb_obj.get_peer_idx(wlan_vdev_get_id(vdev_itr), &end_ind->ndp_map[i].peer_ndi_mac_addr); if (idx < 0) { cfg80211_err("can't find addr: %pM in sta_ctx.", &end_ind->ndp_map[i].peer_ndi_mac_addr); + wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID); continue; } /* save the value of active sessions on each peer */ - ucfg_nan_set_active_ndp_sessions(vdev, + ucfg_nan_set_active_ndp_sessions(vdev_itr, end_ind->ndp_map[i].num_active_ndp_sessions, idx); + wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID); } data_len = osif_ndp_get_ndp_end_ind_len(end_ind); From 0bfde711e4e71dab8cc05ed5a3d315f19c0e0c9a Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 4 Oct 2018 12:42:17 +0530 Subject: [PATCH 38/39] qcacmn: Fix incorrect NDP ids in NDP end request NDP ids copied from NDP instance id array for NDP end request does not use nla_data to copy the ids resulting in incorrect data getting copied. Fix is to use nla_data for NDP instance id array to copy the ids. Change-Id: I74795367a5c5a57f42cb1a67ece9cebfeb259b71 CRs-Fixed: 2328245 --- src/os_if_nan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os_if_nan.c b/src/os_if_nan.c index 0dd33424d1..9b444111e5 100644 --- a/src/os_if_nan.c +++ b/src/os_if_nan.c @@ -672,7 +672,7 @@ static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, return -EINVAL; } qdf_mem_copy(req.ndp_ids, - tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY], + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]), req.num_ndp_instances * sizeof(uint32_t)); cfg80211_debug("sending ndp_end_req to SME, transaction_id: %d", From bc04268a27cc0d58ecad0c75e6f2e983a8aadbf1 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 13 Nov 2018 16:07:49 +0530 Subject: [PATCH 39/39] qcacld-3.0: Merge NAN related OS IF files into CLD NAN component is not needed in the CMN repo. To reduce the unnecessary lines of code, merge the NAN related OS IF files from CMN into CLD. Subsequently remove these files from the CMN repo. Merge NAN related OS IF files from CMN into CLD. Change-Id: Iba5c367549f135800c6f36a7066829393d62e92b --- {inc => os_if/nan/inc}/os_if_nan.h | 0 {src => os_if/nan/src}/os_if_nan.c | 67 +++++++++++++++++------------- 2 files changed, 37 insertions(+), 30 deletions(-) rename {inc => os_if/nan/inc}/os_if_nan.h (100%) rename {src => os_if/nan/src}/os_if_nan.c (97%) diff --git a/inc/os_if_nan.h b/os_if/nan/inc/os_if_nan.h similarity index 100% rename from inc/os_if_nan.h rename to os_if/nan/inc/os_if_nan.h diff --git a/src/os_if_nan.c b/os_if/nan/src/os_if_nan.c similarity index 97% rename from src/os_if_nan.c rename to os_if/nan/src/os_if_nan.c index 9b444111e5..6f98e93dd2 100644 --- a/src/os_if_nan.c +++ b/os_if/nan/src/os_if_nan.c @@ -306,20 +306,22 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, passphrase->passphrase_len); cfg80211_err("passphrase len: %d", passphrase->passphrase_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, - passphrase->passphrase, passphrase->passphrase_len); + passphrase->passphrase, + passphrase->passphrase_len); } if (tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]) { service_name->service_name_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]); qdf_mem_copy(service_name->service_name, - nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]), - service_name->service_name_len); + nla_data( + tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]), + service_name->service_name_len); cfg80211_err("service_name len: %d", service_name->service_name_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, - service_name->service_name, - service_name->service_name_len); + service_name->service_name, + service_name->service_name_len); } return 0; @@ -379,7 +381,7 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, state == NAN_DATA_NDI_DELETING_STATE || state == NAN_DATA_NDI_CREATING_STATE) { cfg80211_err("Data request not allowed in NDI current state: %d", - state); + state); ret = -EINVAL; goto initiator_req_failed; } @@ -422,8 +424,9 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, goto initiator_req_failed; } qdf_mem_copy(req.peer_discovery_mac_addr.bytes, - nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), - QDF_MAC_ADDR_SIZE); + nla_data( + tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), + QDF_MAC_ADDR_SIZE); if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { req.ndp_info.ndp_app_info_len = @@ -450,16 +453,18 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, req.is_ipv6_addr_present, req.ipv6_addr); if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, - &req.passphrase, &req.service_name)) { + &req.passphrase, + &req.service_name)) { cfg80211_err("inconsistent security params in request."); ret = -EINVAL; goto initiator_req_failed; } cfg80211_debug("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, csid: %d, peer_discovery_mac_addr: %pM", - wlan_vdev_get_id(nan_vdev), req.transaction_id, req.channel, - req.service_instance_id, req.ndp_info.ndp_app_info_len, - req.ncs_sk_type, req.peer_discovery_mac_addr.bytes); + wlan_vdev_get_id(nan_vdev), req.transaction_id, + req.channel, req.service_instance_id, + req.ndp_info.ndp_app_info_len, req.ncs_sk_type, + req.peer_discovery_mac_addr.bytes); req.vdev = nan_vdev; status = ucfg_nan_req_processor(nan_vdev, &req, NDP_INITIATOR_REQ); @@ -1728,15 +1733,17 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, } cfg80211_debug("sub command: %d, value: %d", - QCA_NL80211_VENDOR_SUBCMD_NDP, - QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE); + QCA_NL80211_VENDOR_SUBCMD_NDP, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE); cfg80211_debug("create transaction id: %d, value: %d", - QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id); + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + create_transaction_id); cfg80211_debug("status code: %d, value: %d", - QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, - create_status); + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + create_status); cfg80211_debug("Return value: %d, value: %d", - QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason); + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + create_reason); cfg80211_vendor_event(vendor_event, GFP_KERNEL); @@ -1790,7 +1797,7 @@ static void os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc *psoc, cfg80211_debug("NDI BSS successfully stopped"); else cfg80211_debug("NDI BSS stop failed with reason %d", - ndi_rsp->reason); + ndi_rsp->reason); ucfg_nan_set_ndi_delete_rsp_reason(vdev, ndi_rsp->reason); ucfg_nan_set_ndi_delete_rsp_status(vdev, ndi_rsp->status); @@ -1845,9 +1852,9 @@ static QDF_STATUS os_if_ndp_sch_update_pack_ch_info(struct sk_buff *event, for (idx = 0; idx < sch_update->num_channels; idx++) { cfg80211_debug("ch[%d]: freq: %d, width: %d, nss: %d", - idx, sch_update->ch[idx].channel, - sch_update->ch[idx].ch_width, - sch_update->ch[idx].nss); + idx, sch_update->ch[idx].channel, + sch_update->ch[idx].ch_width, + sch_update->ch[idx].nss); ch_element = nla_nest_start(event, idx); if (!ch_element) return QDF_STATUS_E_FAULT; @@ -2141,17 +2148,17 @@ void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) } cfg80211_debug("sub command: %d, value: %d", - QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, - QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE); + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE); cfg80211_debug("delete transaction id: %d, value: %d", - QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, - ucfg_nan_get_ndp_delete_transaction_id(vdev)); + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + ucfg_nan_get_ndp_delete_transaction_id(vdev)); cfg80211_debug("status code: %d, value: %d", - QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, - ucfg_nan_get_ndi_delete_rsp_status(vdev)); + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + ucfg_nan_get_ndi_delete_rsp_status(vdev)); cfg80211_debug("Return value: %d, value: %d", - QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, - ucfg_nan_get_ndi_delete_rsp_reason(vdev)); + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + ucfg_nan_get_ndi_delete_rsp_reason(vdev)); ucfg_nan_set_ndp_delete_transaction_id(vdev, 0); ucfg_nan_set_ndi_state(vdev, NAN_DATA_NDI_DELETED_STATE);