blob: 808330d5c8c3b41e553f1d46402e0071edb99591 [file] [log] [blame]
Ravi Joshia063dd92016-05-25 16:43:13 -07001/*
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302 * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
Ravi Joshia063dd92016-05-25 16:43:13 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for
7 * any purpose with or without fee is hereby granted, provided that the
8 * above copyright notice and this permission notice appear in all
9 * copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18 * PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/**
22 * DOC: wlan_hdd_nan_datapath.c
23 *
24 * WLAN Host Device Driver nan datapath API implementation
25 */
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070026#include <wlan_hdd_includes.h>
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070027#include <linux/if.h>
28#include <linux/netdevice.h>
29#include <linux/skbuff.h>
30#include <linux/etherdevice.h>
31#include "wlan_hdd_includes.h"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070032#include "wlan_hdd_p2p.h"
33#include "wma_api.h"
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070034#include "wlan_hdd_assoc.h"
35#include "sme_nan_datapath.h"
Rajeev Kumar699debf2017-01-06 14:17:00 -080036#include "wlan_hdd_object_manager.h"
Sandeep Puligillafdd201e2017-02-02 18:43:46 -080037#include <qca_vendor.h>
Naveen Rawat63de5422017-03-22 11:03:56 -070038#include "os_if_nan.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -070039#include "wlan_nan_api.h"
40#include "nan_public_structs.h"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070041
Naveen Rawat97500352017-03-22 10:07:58 -070042#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070043/* NLA policy */
44static const struct nla_policy
45qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
46 [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 },
47 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 },
Jeff Johnson438ff422017-06-15 14:56:45 -070048 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_NUL_STRING,
49 .len = IFNAMSIZ - 1 },
Naveen Rawat19da3d12016-08-16 12:39:38 -070050 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070051 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070052 [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = {
Naveen Rawatf28315c2016-06-29 18:06:02 -070053 .type = NLA_BINARY,
54 .len = QDF_MAC_ADDR_SIZE },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070055 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 },
56 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY,
57 .len = NDP_QOS_INFO_LEN },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070058 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY,
59 .len = NDP_APP_INFO_LEN },
60 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070061 [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070062 [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY,
63 .len = QDF_MAC_ADDR_SIZE },
Naveen Rawatf28315c2016-06-29 18:06:02 -070064 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY,
65 .len = NDP_NUM_INSTANCE_ID },
Naveen Rawat0a017052016-10-19 14:17:07 -070066 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { .type = NLA_U32 },
Naveen Rawat4f3983e2016-11-29 16:12:09 -080067 [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { .type = NLA_U32 },
68 [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { .type = NLA_BINARY,
69 .len = NDP_PMK_LEN },
70 [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { .type = NLA_BINARY,
71 .len = NDP_SCID_BUF_LEN },
Rakesh Sunkid92d1082017-01-04 15:14:28 -080072 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { .type =
73 NLA_U32 },
74 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070075};
Naveen Rawat97500352017-03-22 10:07:58 -070076#endif
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070077
78/**
79 * hdd_ndp_print_ini_config()- Print nan datapath specific INI configuration
80 * @hdd_ctx: handle to hdd context
81 *
82 * Return: None
83 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -070084void hdd_ndp_print_ini_config(struct hdd_context *hdd_ctx)
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070085{
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -070086 hdd_debug("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_DATAPATH_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070087 hdd_ctx->config->enable_nan_datapath);
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -070088 hdd_debug("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_NDI_CHANNEL_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070089 hdd_ctx->config->nan_datapath_ndi_channel);
90}
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070091
92/**
93 * hdd_nan_datapath_target_config() - Configure NAN datapath features
94 * @hdd_ctx: Pointer to HDD context
95 * @cfg: Pointer to target device capability information
96 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070097 * NAN datapath functionality is enabled if it is enabled in
98 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070099 *
100 * Return: None
101 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700102void hdd_nan_datapath_target_config(struct hdd_context *hdd_ctx,
Deepak Dhamdhere13230d32016-05-26 00:46:53 -0700103 struct wma_tgt_cfg *cfg)
104{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -0700105 hdd_ctx->nan_datapath_enabled =
106 hdd_ctx->config->enable_nan_datapath &&
107 cfg->nan_datapath_enabled;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700108 hdd_info("enable_nan_datapath: final: %d, host: %d, fw: %d",
109 hdd_ctx->nan_datapath_enabled,
110 hdd_ctx->config->enable_nan_datapath,
111 cfg->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -0700112}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700113
114/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700115 * hdd_close_ndi() - close NAN Data interface
116 * @adapter: adapter context
117 *
118 * Close the adapter if start BSS fails
119 *
120 * Returns: 0 on success, negative error code otherwise
121 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700122static int hdd_close_ndi(struct hdd_adapter *adapter)
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700123{
Dustin Brown0d2eeae2017-03-24 15:21:32 -0700124 int errno;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700125 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700126
127 ENTER();
128
129 /* check if the adapter is in NAN Data mode */
130 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700131 hdd_err("Interface is not in NDI mode");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700132 return -EINVAL;
133 }
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700134 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +0530135 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700136 WLAN_CONTROL_PATH);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700137
138#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -0700139 cancel_work_sync(&adapter->ipv4_notifier_work);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700140#endif
141 hdd_deregister_tx_flow_control(adapter);
142
143#ifdef WLAN_NS_OFFLOAD
144#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -0700145 cancel_work_sync(&adapter->ipv6_notifier_work);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700146#endif
147#endif
Dustin Brown0d2eeae2017-03-24 15:21:32 -0700148 errno = hdd_vdev_destroy(adapter);
149 if (errno)
150 hdd_err("failed to destroy vdev: %d", errno);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700151
152 /* We are good to close the adapter */
153 hdd_close_adapter(hdd_ctx, adapter, true);
154
155 EXIT();
156 return 0;
157}
158
159/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700160 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
161 * @hdd_ctx: hdd context
162 *
163 * NDP is not allowed with any other role active except STA.
164 *
165 * Return: true if allowed, false otherwise
166 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700167static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700168{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700169 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700170 struct hdd_station_ctx *sta_ctx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700171 QDF_STATUS status;
172 hdd_adapter_list_node_t *curr = NULL, *next = NULL;
173
174 status = hdd_get_front_adapter(hdd_ctx, &curr);
175 while (QDF_STATUS_SUCCESS == status) {
Jeff Johnson57eb2732017-10-02 11:40:20 -0700176 adapter = curr->adapter;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700177 if (!adapter)
178 goto next_adapter;
179
180 switch (adapter->device_mode) {
181 case QDF_P2P_GO_MODE:
182 case QDF_SAP_MODE:
183 if (test_bit(SOFTAP_BSS_STARTED,
184 &adapter->event_flags))
185 return false;
186 break;
187 case QDF_P2P_CLIENT_MODE:
188 case QDF_IBSS_MODE:
189 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
190 if (hdd_conn_is_connected(sta_ctx) ||
191 hdd_is_connecting(sta_ctx))
192 return false;
193 break;
194 default:
195 break;
196 }
197next_adapter:
198 status = hdd_get_next_adapter(hdd_ctx, curr, &next);
199 curr = next;
200 }
201
202 return true;
203}
204
205/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700206 * hdd_ndi_start_bss() - Start BSS on NAN data interface
207 * @adapter: adapter context
208 * @operating_channel: channel on which the BSS to be started
209 *
210 * Return: 0 on success, error value on failure
211 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700212static int hdd_ndi_start_bss(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700213 uint8_t operating_channel)
214{
215 int ret;
216 uint32_t roam_id;
Jeff Johnson2a722002017-09-30 20:02:35 -0700217 struct hdd_wext_state *wext_state =
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -0700218 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700219 tCsrRoamProfile *roam_profile = &wext_state->roamProfile;
220
221 ENTER();
222
223 if (!roam_profile) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700224 hdd_err("No valid roam profile");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700225 return -EINVAL;
226 }
227
228 if (HDD_WMM_USER_MODE_NO_QOS ==
229 (WLAN_HDD_GET_CTX(adapter))->config->WmmMode) {
230 /* QoS not enabled in cfg file*/
231 roam_profile->uapsd_mask = 0;
232 } else {
233 /* QoS enabled, update uapsd mask from cfg file*/
234 roam_profile->uapsd_mask =
235 (WLAN_HDD_GET_CTX(adapter))->config->UapsdMask;
236 }
237
238 roam_profile->csrPersona = adapter->device_mode;
239
240 roam_profile->ChannelInfo.numOfChannels = 1;
241 if (operating_channel) {
242 roam_profile->ChannelInfo.ChannelList = &operating_channel;
243 } else {
244 roam_profile->ChannelInfo.ChannelList[0] =
245 NAN_SOCIAL_CHANNEL_2_4GHZ;
246 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700247
248 roam_profile->SSIDs.numOfSSIDs = 1;
249 roam_profile->SSIDs.SSIDList->SSID.length = 0;
250
251 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
252 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
253 roam_profile->BSSIDs.numOfBSSIDs = 1;
254 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
Jeff Johnson1e851a12017-10-28 14:36:12 -0700255 &adapter->mac_addr.bytes[0],
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700256 QDF_MAC_ADDR_SIZE);
257
258 roam_profile->AuthType.numEntries = 1;
259 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
260 roam_profile->EncryptionType.numEntries = 1;
261 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
262
263 ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -0700264 adapter->session_id, roam_profile, &roam_id);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700265 if (QDF_STATUS_SUCCESS != ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700266 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
Jeff Johnson1b780e42017-10-31 14:11:45 -0700267 adapter->session_id, ret);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700268 /* change back to NotConnected */
269 hdd_conn_set_connection_state(adapter,
270 eConnectionState_NotConnected);
271 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700272 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700273 }
274
275 roam_profile->ChannelInfo.ChannelList = NULL;
276 roam_profile->ChannelInfo.numOfChannels = 0;
277
278 EXIT();
279
280 return ret;
281}
282
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700283/**
284 * hdd_get_random_nan_mac_addr() - generate random non pre-existent mac address
285 * @hdd_ctx: hdd context pointer
286 * @mac_addr: mac address buffer to populate
287 *
288 * Return: status of operation
289 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700290static int hdd_get_random_nan_mac_addr(struct hdd_context *hdd_ctx,
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700291 struct qdf_mac_addr *mac_addr)
292{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700293 struct hdd_adapter *adapter;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700294 uint8_t i, attempts, max_attempt = 16;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700295
296 for (attempts = 0; attempts < max_attempt; attempts++) {
297 cds_rand_get_bytes(0, (uint8_t *)mac_addr, sizeof(*mac_addr));
Ravi Joshi04a1c992017-06-11 19:47:54 -0700298
299 /*
300 * Reset multicast bit (bit-0) and set locally-administered bit
301 */
302 mac_addr->bytes[0] = 0x2;
303
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700304 /*
305 * to avoid potential conflict with FW's generated NMI mac addr,
306 * host sets LSB if 6th byte to 0
307 */
308 mac_addr->bytes[5] &= 0xFE;
309
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700310 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
311 if (!qdf_mem_cmp(hdd_ctx->config->intfMacAddr[i].bytes,
312 mac_addr, sizeof(*mac_addr)))
313 continue;
314 }
315
316 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
317 if (!adapter)
318 return 0;
319 }
320
321 hdd_err("unable to get non-pre-existing mac address in %d attempts",
322 max_attempt);
323
324 return -EINVAL;
325}
326
Naveen Rawat97500352017-03-22 10:07:58 -0700327#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700328/**
329 * hdd_ndi_create_req_handler() - NDI create request handler
330 * @hdd_ctx: hdd context
331 * @tb: parsed NL attribute list
332 *
333 * Return: 0 on success or error code on failure
334 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700335static int hdd_ndi_create_req_handler(struct hdd_context *hdd_ctx,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700336 struct nlattr **tb)
337{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700338 struct hdd_adapter *adapter;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700339 char *iface_name;
340 uint16_t transaction_id;
341 int ret;
342 struct nan_datapath_ctx *ndp_ctx;
343 uint8_t op_channel =
344 hdd_ctx->config->nan_datapath_ndi_channel;
Ravi Joshi9771d432017-06-26 13:58:12 -0700345 struct qdf_mac_addr random_ndi_mac;
346 uint8_t *ndi_mac_addr;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700347
348 ENTER();
349
350 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700351 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700352 return -EINVAL;
353 }
354 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
355
356 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700357 hdd_err("transaction id is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700358 return -EINVAL;
359 }
360 transaction_id =
361 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
362
363 /* Check for an existing interface of NDI type */
364 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
365 if (adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700366 hdd_err("Cannot support more than one NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700367 return -EEXIST;
368 }
369
Ravi Joshi9771d432017-06-26 13:58:12 -0700370 if (hdd_ctx->config->is_ndi_mac_randomized) {
371 if (hdd_get_random_nan_mac_addr(hdd_ctx, &random_ndi_mac)) {
372 hdd_err("get random mac address failed");
373 return -EINVAL;
374 }
375 ndi_mac_addr = &random_ndi_mac.bytes[0];
376 } else {
377 ndi_mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
378 if (!ndi_mac_addr) {
379 hdd_err("get intf address failed");
380 return -EINVAL;
381 }
382 }
383
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700384 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
Ravi Joshi9771d432017-06-26 13:58:12 -0700385 ndi_mac_addr, NET_NAME_UNKNOWN, true);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700386 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700387 hdd_err("hdd_open_adapter failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700388 return -ENOMEM;
389 }
390
391 /*
392 * Create transaction id is required to be saved since the firmware
393 * does not honor the transaction id for create request
394 */
395 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
396 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700397 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700398
399 /*
400 * The NAN data interface has been created at this point.
401 * Unlike traditional device modes, where the higher application
402 * layer initiates connect / join / start, the NAN data interface
403 * does not have any such formal requests. The NDI create request
404 * is responsible for starting the BSS as well.
405 */
406 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
407 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
408 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
409 /* start NDI on the default 2.4 GHz social channel */
410 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
411 }
412 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700413 if (0 > ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700414 hdd_err("NDI start bss failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700415 /* Start BSS failed, delete the interface */
416 hdd_close_ndi(adapter);
417 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700418
419 EXIT();
420 return ret;
421}
422
423/**
424 * hdd_ndi_delete_req_handler() - NDI delete request handler
425 * @hdd_ctx: hdd context
426 * @tb: parsed NL attribute list
427 *
428 * Return: 0 on success or error code on failure
429 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700430static int hdd_ndi_delete_req_handler(struct hdd_context *hdd_ctx,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700431 struct nlattr **tb)
432{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700433 struct hdd_adapter *adapter;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700434 char *iface_name;
435 uint16_t transaction_id;
436 struct nan_datapath_ctx *ndp_ctx;
437 int ret;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700438 struct hdd_station_ctx *sta_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700439
440 ENTER();
441
442 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700443 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700444 return -EINVAL;
445 }
446
447 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
448
449 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700450 hdd_err("Transaction id is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700451 return -EINVAL;
452 }
453
454 transaction_id =
455 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
456
457 /* Check if there is already an existing inteface with the same name */
458 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
459 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700460 hdd_err("NAN data interface %s is not available", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700461 return -EINVAL;
462 }
463
464 /* check if adapter is in NDI mode */
465 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700466 hdd_err("Interface %s is not in NDI mode", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700467 return -EINVAL;
468 }
469
470 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
471 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700472 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700473 return -EINVAL;
474 }
475
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700476 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
477 if (!sta_ctx) {
478 hdd_err("sta_ctx is NULL");
479 return -EINVAL;
480 }
481
Naveen Rawatf28315c2016-06-29 18:06:02 -0700482 /* check if there are active peers on the adapter */
483 if (ndp_ctx->active_ndp_peers > 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700484 hdd_err("NDP peers active: %d, cannot delete NDI",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700485 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700486 return -EINVAL;
487 }
488
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700489 /*
490 * Since, the interface is being deleted, remove the
491 * broadcast id.
492 */
493 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
494 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
495
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700496 ndp_ctx->ndp_delete_transaction_id = transaction_id;
497 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
498
499 /* Delete the interface */
500 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
501 if (ret < 0)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700502 hdd_err("NDI delete request failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700503 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700504 hdd_err("NDI delete request successfully issued");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700505
506 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700507}
508
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700509/**
510 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
511 * @hdd_ctx: hdd context
512 * @tb: parsed NL attribute list
513 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800514 * tb will contain following vendor attributes:
515 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
516 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
517 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
Ravi Joshi71e82f32017-02-09 23:15:16 -0800518 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG - optional
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800519 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
520 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
521 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
522 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
523 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
524 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
525 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700526 * Return: 0 on success or error code on failure
527 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700528static int hdd_ndp_initiator_req_handler(struct hdd_context *hdd_ctx,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700529 struct nlattr **tb)
530{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700531 struct hdd_adapter *adapter;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700532 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700533 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700534 QDF_STATUS status;
535 uint32_t ndp_qos_cfg;
536 tHalHandle hal = hdd_ctx->hHal;
537 struct nan_datapath_ctx *ndp_ctx;
538
539 ENTER();
540
541 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700542 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700543 return -EINVAL;
544 }
545
546 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
547 /* Check for interface in NDI mode */
548 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
549 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700550 hdd_err("NAN data interface %s not available", iface_name);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700551 return -EINVAL;
552 }
553
554 /* NAN data path coexists only with STA interface */
555 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700556 hdd_err("Unsupported concurrency for NAN datapath");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700557 return -EPERM;
558 }
559
560 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
561
562 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
563 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
564 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700565 hdd_err("Data request not allowed in NDI current state: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700566 ndp_ctx->state);
567 return -EINVAL;
568 }
569
Jeff Johnson1b780e42017-10-31 14:11:45 -0700570 req.vdev_id = adapter->session_id;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700571
572 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700573 hdd_err("Transaction ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700574 return -EINVAL;
575 }
576 req.transaction_id =
577 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
578
Naveen Rawat0a017052016-10-19 14:17:07 -0700579 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL])
580 req.channel =
581 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
582
Ravi Joshi71e82f32017-02-09 23:15:16 -0800583 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG])
Naveen Rawat0a017052016-10-19 14:17:07 -0700584 req.channel_cfg =
585 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700586
587 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700588 hdd_err("NDP service instance ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700589 return -EINVAL;
590 }
591 req.service_instance_id =
Naveen Rawat19da3d12016-08-16 12:39:38 -0700592 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700593
594 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
Jeff Johnson1e851a12017-10-28 14:36:12 -0700595 adapter->mac_addr.bytes, QDF_MAC_ADDR_SIZE);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700596
597 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700598 hdd_err("NDI peer discovery mac addr is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700599 return -EINVAL;
600 }
601 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
602 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
603 QDF_MAC_ADDR_SIZE);
604
Naveen Rawat90ae3082016-06-29 18:22:59 -0700605 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
606 req.ndp_info.ndp_app_info_len =
607 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
608 req.ndp_info.ndp_app_info =
609 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700610 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700611
612 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
613 /* at present ndp config stores 4 bytes QOS info only */
614 req.ndp_config.ndp_cfg_len = 4;
615 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
616 ndp_qos_cfg =
617 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
618 }
619
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800620 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
621 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
622 hdd_err("PMK cannot be absent when CSID is present.");
623 return -EINVAL;
624 }
625
626 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
627 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
628 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
629 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
630 QDF_TRACE_LEVEL_DEBUG,
631 req.pmk.pmk, req.pmk.pmk_len);
632 }
633
634 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
635 req.ncs_sk_type =
636 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
637
638 }
639
Ravi Joshi71e82f32017-02-09 23:15:16 -0800640 hdd_info("vdev_id: %d, transaction_id: %d, channel: %d, channel_cfg: %d, service_instance_id: %d, ndp_app_info_len: %d, csid: %d, peer_discovery_mac_addr: %pM",
641 req.vdev_id, req.transaction_id, req.channel, req.channel_cfg,
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700642 req.service_instance_id, req.ndp_info.ndp_app_info_len,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800643 req.ncs_sk_type, req.peer_discovery_mac_addr.bytes);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700644 status = sme_ndp_initiator_req_handler(hal, &req);
645 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700646 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700647 status);
648 return -ECOMM;
649 }
650 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700651 return 0;
652}
653
654/**
655 * hdd_ndp_responder_req_handler() - NDP responder request handler
656 * @hdd_ctx: hdd context
657 * @tb: parsed NL attribute list
658 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800659 * tb includes following vendor attributes:
660 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
661 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
662 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
663 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
664 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
665 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
666 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
667 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
668 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700669 * Return: 0 on success or error code on failure
670 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700671static int hdd_ndp_responder_req_handler(struct hdd_context *hdd_ctx,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700672 struct nlattr **tb)
673{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700674 struct hdd_adapter *adapter;
Abhishek Singh4fef7472016-06-06 11:36:03 -0700675 char *iface_name;
676 struct ndp_responder_req req = {0};
677 QDF_STATUS status;
678 int ret = 0;
679 struct nan_datapath_ctx *ndp_ctx;
680 uint32_t ndp_qos_cfg;
681
682 ENTER();
683
684 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700685 hdd_err("Interface name string is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700686 return -EINVAL;
687 }
688
689 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
690 /* Check if there is already an existing NAN interface */
691 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
692 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700693 hdd_err("NAN data interface %s not available", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700694 return -EINVAL;
695 }
696
697 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700698 hdd_err("Interface %s not in NDI mode", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700699 return -EINVAL;
700 }
701
702 /* NAN data path coexists only with STA interface */
703 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700704 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700705 return -EINVAL;
706 }
707
708 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
709
710 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
711 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
712 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700713 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700714 ndp_ctx->state);
715 return -EAGAIN;
716 }
717
Jeff Johnson1b780e42017-10-31 14:11:45 -0700718 req.vdev_id = adapter->session_id;
Abhishek Singh4fef7472016-06-06 11:36:03 -0700719
720 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700721 hdd_err("Transaction ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700722 return -EINVAL;
723 }
724 req.transaction_id =
725 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
726
727 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700728 hdd_err("Instance ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700729 return -EINVAL;
730 }
731 req.ndp_instance_id =
732 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
733
734 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700735 hdd_err("ndp_rsp is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700736 return -EINVAL;
737 }
738 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
739
740 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
741 req.ndp_info.ndp_app_info_len =
742 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
743 if (req.ndp_info.ndp_app_info_len) {
744 req.ndp_info.ndp_app_info =
745 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
746 }
747 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700748 hdd_info("NDP app info is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700749 }
750 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
751 /* at present ndp config stores 4 bytes QOS info only */
752 req.ndp_config.ndp_cfg_len = 4;
753 ndp_qos_cfg =
754 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
755 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
756 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700757 hdd_info("NDP config data is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700758 }
759
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800760 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
761 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
762 hdd_err("PMK cannot be absent when CSID is present.");
763 return -EINVAL;
764 }
765
766 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
767 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
768 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
769 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
770 QDF_TRACE_LEVEL_DEBUG,
771 req.pmk.pmk, req.pmk.pmk_len);
772 }
773
774 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
775 req.ncs_sk_type =
776 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
777
778 }
779
780 hdd_info("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700781 req.vdev_id, req.transaction_id, req.ndp_rsp,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800782 req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
783 req.ncs_sk_type);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700784
785 status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req);
786 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700787 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700788 status);
789 ret = -EINVAL;
790 }
791
792 EXIT();
793 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700794}
795
796/**
797 * hdd_ndp_end_req_handler() - NDP end request handler
798 * @hdd_ctx: hdd context
799 * @tb: parsed NL attribute list
800 *
801 * Return: 0 on success or error code on failure
802 */
Jeff Johnson11b4c322017-10-06 11:48:23 -0700803static int hdd_ndp_end_req_handler(struct hdd_context *hdd_ctx,
804 struct nlattr **tb)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700805{
Naveen Rawatf28315c2016-06-29 18:06:02 -0700806 struct ndp_end_req req = {0};
807 QDF_STATUS status;
808 tHalHandle hal = hdd_ctx->hHal;
809
810 ENTER();
811
812 /* NAN data path coexists only with STA interface */
813 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700814 hdd_err("Unsupported concurrency for NAN datapath");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700815 return -EINVAL;
816 }
817
818 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700819 hdd_err("Transaction ID is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700820 return -EINVAL;
821 }
822 req.transaction_id =
823 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
824
825 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700826 hdd_err("NDP instance ID array is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700827 return -EINVAL;
828 }
829
830 req.num_ndp_instances =
831 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
832 sizeof(uint32_t);
833 if (0 >= req.num_ndp_instances) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700834 hdd_err("Num NDP instances is 0");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700835 return -EINVAL;
836 }
837 req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
838
Naveen Rawatba4f6612016-07-05 12:03:16 -0700839 hdd_info("sending ndp_end_req to SME, transaction_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700840 req.transaction_id);
841
842 status = sme_ndp_end_req_handler(hal, &req);
843 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700844 hdd_err("sme_ndp_end_req_handler failed, status: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700845 status);
846 return -ECOMM;
847 }
848 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700849 return 0;
850}
851
852/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700853 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
854 * @adapter: pointer to adapter context
855 * @rsp_params: response parameters
856 *
857 * The function is expected to send a response back to the user space
858 * even if the creation of BSS has failed
859 *
860 * Following vendor event is sent to cfg80211:
861 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
862 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
863 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800864 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700865 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
866 *
867 * Return: none
868 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700869static void hdd_ndp_iface_create_rsp_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700870 void *rsp_params)
871{
872 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700873 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700874 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
875 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
876 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
877 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700878 bool create_fail = false;
879 uint8_t create_transaction_id = 0;
Naveen Rawate21103f2016-07-08 14:18:00 -0700880 uint32_t create_status = NDP_RSP_STATUS_ERROR;
881 uint32_t create_reason = NDP_NAN_DATA_IFACE_CREATE_FAILED;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700882 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700883 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Jeff Johnson172237b2017-11-07 15:32:59 -0800884 struct csr_roam_info *roam_info;
Jeff Johnson4ba73cb2017-10-06 11:12:33 -0700885 struct bss_description tmp_bss_descp = {0};
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700886
887 ENTER();
888
Kapil Guptaffa26022017-08-16 12:20:09 +0530889 roam_info = qdf_mem_malloc(sizeof(*roam_info));
890 if (!roam_info) {
891 hdd_err("failed to allocate memory");
892 return;
893 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700894 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700895 /* No way the driver can send response back to user space */
Kapil Guptaffa26022017-08-16 12:20:09 +0530896 qdf_mem_free(roam_info);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700897 return;
898
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700899 if (ndi_rsp) {
900 create_status = ndi_rsp->status;
Naveen Rawate21103f2016-07-08 14:18:00 -0700901 create_reason = ndi_rsp->reason;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700902 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700903 hdd_err("Invalid ndi create response");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700904 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700905 }
906
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700907 if (ndp_ctx) {
908 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
909 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700910 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700911 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700912 }
913
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700914 if (!sta_ctx) {
915 hdd_err("sta_ctx is NULL");
916 create_fail = true;
917 }
918
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700919 /* notify response to the upper layer */
920 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
921 NULL,
922 data_len,
923 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
924 cds_get_gfp_flags());
925
926 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700927 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700928 create_fail = true;
929 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700930 }
931
932 /* Sub vendor command */
933 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
934 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700935 hdd_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700936 goto nla_put_failure;
937 }
938
939 /* Transaction id */
940 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700941 create_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700942 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700943 goto nla_put_failure;
944 }
945
946 /* Status code */
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800947 if (nla_put_u32(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700949 create_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700950 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700951 goto nla_put_failure;
952 }
953
954 /* Status return value */
955 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700956 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawate21103f2016-07-08 14:18:00 -0700957 create_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700958 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700959 goto nla_put_failure;
960 }
961
Naveen Rawatba4f6612016-07-05 12:03:16 -0700962 hdd_info("sub command: %d, value: %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700963 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
964 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700965 hdd_info("create transaction id: %d, value: %d",
966 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
967 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800968 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
969 create_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700970 hdd_info("Return value: %d, value: %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700971 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700972
973 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
974
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700975 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700976 hdd_err("NDI interface successfully created");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700977 ndp_ctx->ndp_create_transaction_id = 0;
978 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700979 wlan_hdd_netif_queue_control(adapter,
980 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
981 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700982 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700983 hdd_err("NDI interface creation failed with reason %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700984 create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700985 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700986
987 /* Something went wrong while starting the BSS */
988 if (create_fail)
989 goto close_ndi;
990
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700991 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
992 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
Kapil Guptaffa26022017-08-16 12:20:09 +0530993 hdd_roam_register_sta(adapter, roam_info,
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700994 sta_ctx->broadcast_staid,
995 &bc_mac_addr, &tmp_bss_descp);
996 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
997
Kapil Guptaffa26022017-08-16 12:20:09 +0530998 qdf_mem_free(roam_info);
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700999
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001000 EXIT();
1001 return;
1002
1003nla_put_failure:
1004 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -07001005close_ndi:
1006 hdd_close_ndi(adapter);
Kapil Guptaffa26022017-08-16 12:20:09 +05301007 qdf_mem_free(roam_info);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001008}
1009
1010/**
1011 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
1012 * @adapter: pointer to adapter context
1013 * @rsp_params: response parameters
1014 *
1015 * Return: none
1016 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001017static void hdd_ndp_iface_delete_rsp_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001018 void *rsp_params)
1019{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001020 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001021 struct ndi_delete_rsp *ndi_rsp = rsp_params;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001022 struct nan_datapath_ctx *ndp_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001023
1024 if (wlan_hdd_validate_context(hdd_ctx))
1025 return;
1026
1027 if (!ndi_rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001028 hdd_err("Invalid ndi delete response");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001029 return;
1030 }
1031
Naveen Rawat8d63a592016-06-29 18:30:59 -07001032 if (ndi_rsp->status == NDP_RSP_STATUS_SUCCESS)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001033 hdd_err("NDI BSS successfully stopped");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001034 else
Naveen Rawatba4f6612016-07-05 12:03:16 -07001035 hdd_err("NDI BSS stop failed with reason %d", ndi_rsp->reason);
Naveen Rawat8d63a592016-06-29 18:30:59 -07001036
1037 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1038 ndp_ctx->ndi_delete_rsp_reason = ndi_rsp->reason;
1039 ndp_ctx->ndi_delete_rsp_status = ndi_rsp->status;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001040 wlan_hdd_netif_queue_control(adapter,
1041 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
1042 WLAN_CONTROL_PATH);
Naveen Rawat8d63a592016-06-29 18:30:59 -07001043
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001044 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001045}
1046
1047/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001048 * hdd_ndp_session_end_handler() - NDI session termination handler
1049 * @adapter: pointer to adapter context
1050 *
1051 * Following vendor event is sent to cfg80211:
1052 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1053 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
1054 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001055 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001056 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1057 *
1058 * Return: none
1059 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001060void hdd_ndp_session_end_handler(struct hdd_adapter *adapter)
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001061{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001062 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001063 struct sk_buff *vendor_event;
1064 struct nan_datapath_ctx *ndp_ctx;
1065 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
1066 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
1067
1068 ENTER();
1069
1070 if (wlan_hdd_validate_context(hdd_ctx))
1071 return;
1072
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001073 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1074 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001075 hdd_err("ndp context is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001076 return;
1077 }
1078
1079 /*
1080 * The virtual adapters are stopped and closed even during
1081 * driver unload or stop, the service layer is not required
1082 * to be informed in that case (response is not expected)
1083 */
1084 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001085 hdd_err("NDI interface %s deleted", adapter->dev->name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001086 return;
1087 }
1088
1089 /* notify response to the upper layer */
1090 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1091 NULL,
1092 data_len,
1093 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1094 GFP_KERNEL);
1095
1096 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001097 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001098 return;
1099 }
1100
1101 /* Sub vendor command goes first */
1102 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1103 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001104 hdd_err("VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001105 goto failure;
1106 }
1107
1108 /* Transaction id */
1109 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1110 ndp_ctx->ndp_delete_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001111 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001112 goto failure;
1113 }
1114
1115 /* Status code */
1116 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001117 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001118 ndp_ctx->ndi_delete_rsp_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001119 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001120 goto failure;
1121 }
1122
1123 /* Status return value */
1124 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001125 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1126 ndp_ctx->ndi_delete_rsp_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001127 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001128 goto failure;
1129 }
1130
Naveen Rawatba4f6612016-07-05 12:03:16 -07001131 hdd_info("sub command: %d, value: %d", QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001132 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001133 hdd_info("delete transaction id: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001134 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1135 ndp_ctx->ndp_delete_transaction_id);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001136 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001137 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001138 ndp_ctx->ndi_delete_rsp_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001139 hdd_info("Return value: %d, value: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001140 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1141 ndp_ctx->ndi_delete_rsp_reason);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001142
1143 ndp_ctx->ndp_delete_transaction_id = 0;
1144 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
1145
1146 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1147
1148 EXIT();
1149 return;
1150
1151failure:
1152 kfree_skb(vendor_event);
1153}
1154
1155
1156/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001157 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
1158 * @adapter: pointer to adapter context
1159 * @rsp_params: response parameters
1160 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001161 * Following vendor event is sent to cfg80211:
1162 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1163 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1164 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1165 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001166 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001167 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1168 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001169 * Return: none
1170 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001171static void hdd_ndp_initiator_rsp_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001172 void *rsp_params)
1173{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001174 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001175 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001176 struct ndp_initiator_rsp *rsp = rsp_params;
1177 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
1178 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
1179
1180 ENTER();
1181
1182 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001183 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001184 return;
1185 }
1186
1187 if (0 != wlan_hdd_validate_context(hdd_ctx))
1188 return;
1189
1190 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1191 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1192 GFP_KERNEL);
1193 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001194 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001195 return;
1196 }
1197
1198 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1199 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1200 goto ndp_initiator_rsp_nla_failed;
1201
1202 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1203 rsp->transaction_id))
1204 goto ndp_initiator_rsp_nla_failed;
1205
1206 if (nla_put_u32(vendor_event,
1207 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1208 rsp->ndp_instance_id))
1209 goto ndp_initiator_rsp_nla_failed;
1210
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001211 if (nla_put_u32(vendor_event,
1212 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001213 rsp->status))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001214 goto ndp_initiator_rsp_nla_failed;
1215
1216 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001217 rsp->reason))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001218 goto ndp_initiator_rsp_nla_failed;
1219
Naveen Rawatba4f6612016-07-05 12:03:16 -07001220 hdd_info("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001221 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1222 rsp->reason);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001223 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1224 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001225 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001226ndp_initiator_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001227 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001228 kfree_skb(vendor_event);
1229 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001230}
1231
1232/**
1233 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
1234 * @adapter: pointer to adapter context
1235 * @ind_params: indication parameters
1236 *
1237 * Return: none
1238 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001239static void hdd_ndp_new_peer_ind_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001240 void *ind_params)
1241{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001242 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001243 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson4ba73cb2017-10-06 11:12:33 -07001244 struct bss_description tmp_bss_descp = {0};
Jeff Johnson172237b2017-11-07 15:32:59 -08001245 struct csr_roam_info *roam_info;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001246 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07001247 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001248
1249 ENTER();
1250
Kapil Guptaffa26022017-08-16 12:20:09 +05301251 roam_info = qdf_mem_malloc(sizeof(*roam_info));
1252 if (!roam_info) {
1253 hdd_err("failed to allocate memory");
1254 return;
1255 }
1256
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001257 if (NULL == ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001258 hdd_err("Invalid new NDP peer params");
Kapil Guptaffa26022017-08-16 12:20:09 +05301259 goto free;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001260 }
Naveen Rawatba4f6612016-07-05 12:03:16 -07001261 hdd_info("session_id: %d, peer_mac: %pM, sta_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001262 new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
1263 new_peer_ind->sta_id);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001264
1265 /* save peer in ndp ctx */
1266 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
1267 &new_peer_ind->peer_mac_addr)) {
Kapil Guptaffa26022017-08-16 12:20:09 +05301268 hdd_warn("Ndp peer table full. cannot save new peer");
1269 goto free;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001270 }
1271
1272 /* this function is called for each new peer */
1273 ndp_ctx->active_ndp_peers++;
Jeff Johnson1b780e42017-10-31 14:11:45 -07001274 hdd_info("vdev_id: %d, num_peers: %d", adapter->session_id,
Naveen Rawatba4f6612016-07-05 12:03:16 -07001275 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001276
Kapil Guptaffa26022017-08-16 12:20:09 +05301277 hdd_roam_register_sta(adapter, roam_info, new_peer_ind->sta_id,
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001278 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
1279 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
1280 /* perform following steps for first new peer ind */
1281 if (ndp_ctx->active_ndp_peers == 1) {
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07001282 hdd_conn_set_connection_state(adapter,
1283 eConnectionState_NdiConnected);
Kapil Guptaffa26022017-08-16 12:20:09 +05301284 hdd_wmm_connect(adapter, roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001285 wlan_hdd_netif_queue_control(adapter,
1286 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001287 }
Kapil Guptaffa26022017-08-16 12:20:09 +05301288free:
1289 qdf_mem_free(roam_info);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001290 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001291}
1292
1293/**
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001294 * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001295 * @adapter: pointer to adapter context
1296 * @ind_params: indication parameters
1297 *
1298 * Return: none
1299 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001300static void hdd_ndp_peer_departed_ind_handler(struct hdd_adapter *adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001301 void *ind_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001302{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001303 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001304 struct sme_ndp_peer_ind *peer_ind = ind_params;
1305 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07001306 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001307
1308 hdd_roam_deregister_sta(adapter, peer_ind->sta_id);
1309 hdd_delete_peer(sta_ctx, peer_ind->sta_id);
1310 hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
1311
1312 if (--ndp_ctx->active_ndp_peers == 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001313 hdd_info("No more ndp peers.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001314 hdd_conn_set_connection_state(adapter,
1315 eConnectionState_NdiDisconnected);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001316 hdd_info("Stop netif tx queues.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001317 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
1318 WLAN_CONTROL_PATH);
1319 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001320}
1321
1322/**
1323 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1324 * @adapter: pointer to adapter context
1325 * @ind_params: indication parameters
1326 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001327 * Following vendor event is sent to cfg80211:
1328 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1329 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1330 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1331 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1332 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1333 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1334 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1335 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1336 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001337 * Return: none
1338 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001339static void hdd_ndp_confirm_ind_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001340 void *ind_params)
1341{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001342 int idx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001343 uint32_t ndp_qos_config = 0;
1344 struct ndp_confirm_event *ndp_confirm = ind_params;
1345 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001346 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001347 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07001348 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001349 uint32_t data_len;
1350
1351 ENTER();
1352 if (!ndp_confirm) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001353 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001354 return;
1355 }
1356
1357 if (0 != wlan_hdd_validate_context(hdd_ctx))
1358 return;
1359
Naveen Rawatf28315c2016-06-29 18:06:02 -07001360 /* ndp_confirm is called each time user generated ndp req succeeds */
1361 idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
1362 if (idx == INVALID_PEER_IDX)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001363 hdd_err("can't find addr: %pM in vdev_id: %d, peer table.",
Jeff Johnson1b780e42017-10-31 14:11:45 -07001364 &ndp_confirm->peer_ndi_mac_addr, adapter->session_id);
Naveen Rawat460be782016-06-29 18:26:22 -07001365 else if (ndp_confirm->rsp_code == NDP_RESPONSE_ACCEPT)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001366 ndp_ctx->active_ndp_sessions[idx]++;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001367
1368 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
Naveen Rawat90ae3082016-06-29 18:22:59 -07001369 + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001370 ndp_confirm->ndp_info.ndp_app_info_len;
1371
Naveen Rawat8d63a592016-06-29 18:30:59 -07001372 if (ndp_confirm->ndp_info.ndp_app_info_len)
1373 data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
1374
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001375 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1376 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1377 GFP_KERNEL);
1378 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001379 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001380 return;
1381 }
1382
1383 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1384 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1385 goto ndp_confirm_nla_failed;
1386
1387 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1388 ndp_confirm->ndp_instance_id))
1389 goto ndp_confirm_nla_failed;
1390
1391 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1392 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1393 goto ndp_confirm_nla_failed;
1394
1395 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1396 IFNAMSIZ, adapter->dev->name))
1397 goto ndp_confirm_nla_failed;
1398
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001399 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001400 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1401 ndp_confirm->ndp_info.ndp_app_info_len,
1402 ndp_confirm->ndp_info.ndp_app_info))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001403 goto ndp_confirm_nla_failed;
1404
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001405 if (nla_put_u32(vendor_event,
1406 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1407 ndp_confirm->rsp_code))
1408 goto ndp_confirm_nla_failed;
1409
Naveen Rawat8d63a592016-06-29 18:30:59 -07001410 if (nla_put_u32(vendor_event,
1411 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1412 ndp_confirm->reason_code))
1413 goto ndp_confirm_nla_failed;
1414
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001415 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001416 hdd_info("NDP confim sent, ndp instance id: %d, peer addr: %pM, ndp_cfg: %d, rsp_code: %d, reason_code: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001417 ndp_confirm->ndp_instance_id,
1418 ndp_confirm->peer_ndi_mac_addr.bytes,
Naveen Rawat460be782016-06-29 18:26:22 -07001419 ndp_qos_config, ndp_confirm->rsp_code,
1420 ndp_confirm->reason_code);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001421
Naveen Rawatba4f6612016-07-05 12:03:16 -07001422 hdd_info("NDP confim, ndp app info dump");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001423 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1424 ndp_confirm->ndp_info.ndp_app_info,
1425 ndp_confirm->ndp_info.ndp_app_info_len);
1426 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001427 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001428ndp_confirm_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001429 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001430 kfree_skb(vendor_event);
1431 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001432}
1433
1434/**
1435 * hdd_ndp_indication_handler() - NDP indication handler
1436 * @adapter: pointer to adapter context
1437 * @ind_params: indication parameters
1438 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001439 * Following vendor event is sent to cfg80211:
1440 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1441 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1442 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
Naveen Rawat19da3d12016-08-16 12:39:38 -07001443 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001444 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1445 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1446 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1447 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1448 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001449 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes)
1450 * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001451 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001452 * Return: none
1453 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001454static void hdd_ndp_indication_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001455 void *ind_params)
1456{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001457 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001458 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001459 struct ndp_indication_event *event = ind_params;
1460 uint32_t ndp_qos_config;
1461 struct nan_datapath_ctx *ndp_ctx;
1462 uint16_t data_len;
1463
1464 ENTER();
1465 if (!ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001466 hdd_err("Invalid NDP Indication");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001467 return;
1468 }
1469
1470 if (0 != wlan_hdd_validate_context(hdd_ctx))
1471 return;
1472
1473 /* Handle only if adapter is in NDI mode */
1474 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001475 hdd_err("Adapter is not in NDI mode");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001476 return;
1477 }
1478
Naveen Rawatba4f6612016-07-05 12:03:16 -07001479 hdd_info("NDP Indication, policy: %d", event->policy);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001480
1481 /* Policy check */
1482 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001483 hdd_err("NAN datapath is not suported");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001484 return;
1485 }
1486
1487 /* NAN data path coexists only with STA interface */
1488 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001489 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001490 return;
1491 }
1492
1493 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1494
1495 /* check if we are in middle of deleting/creating the interface */
1496 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
1497 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
1498 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001499 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001500 ndp_ctx->state);
1501 return;
1502 }
1503
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001504 data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
1505 event->ndp_info.ndp_app_info_len + event->scid.scid_len +
1506 (10 * NLA_HDRLEN) + NLMSG_HDRLEN;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001507
1508 /* notify response to the upper layer */
1509 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1510 NULL, data_len,
1511 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1512 GFP_KERNEL);
1513 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001514 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001515 return;
1516 }
1517
1518 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1519 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1520 goto ndp_indication_nla_failed;
1521
1522 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1523 IFNAMSIZ, adapter->dev->name))
1524 goto ndp_indication_nla_failed;
1525
Naveen Rawat19da3d12016-08-16 12:39:38 -07001526 if (nla_put_u32(vendor_event,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001527 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1528 event->service_instance_id))
1529 goto ndp_indication_nla_failed;
1530
1531 if (nla_put(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1533 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1534 goto ndp_indication_nla_failed;
1535
1536 if (nla_put(vendor_event,
Jeff Johnson03294f12016-12-09 17:10:24 -08001537 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001538 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1539 goto ndp_indication_nla_failed;
1540
1541 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1542 event->ndp_instance_id))
1543 goto ndp_indication_nla_failed;
1544
1545 if (event->ndp_info.ndp_app_info_len)
1546 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1547 event->ndp_info.ndp_app_info_len,
1548 event->ndp_info.ndp_app_info))
1549 goto ndp_indication_nla_failed;
1550
1551 if (event->ndp_config.ndp_cfg_len) {
1552 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1553 /* at present ndp config stores 4 bytes QOS info only */
1554 if (nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1556 ndp_qos_config))
1557 goto ndp_indication_nla_failed;
1558 }
1559
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001560 if (event->scid.scid_len) {
1561 if (nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE,
1563 event->ncs_sk_type))
1564 goto ndp_indication_nla_failed;
1565
1566 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
1567 event->scid.scid_len,
1568 event->scid.scid))
1569 goto ndp_indication_nla_failed;
1570
1571 hdd_info("csid: %d, scid_len: %d",
1572 event->ncs_sk_type, event->scid.scid_len);
1573
1574 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1575 event->scid.scid, event->scid.scid_len);
1576 }
1577
Abhishek Singh4fef7472016-06-06 11:36:03 -07001578 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1579 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001580 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001581ndp_indication_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001582 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001583 kfree_skb(vendor_event);
1584 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001585}
1586
1587/**
1588 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1589 * @adapter: pointer to adapter context
1590 * @rsp_params: response parameters
1591 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001592 * Following vendor event is sent to cfg80211:
1593 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1594 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1595 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001596 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1597 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001598 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001599 * Return: none
1600 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001601static void hdd_ndp_responder_rsp_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001602 void *rsp_params)
1603{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001604 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001605 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001606 struct ndp_responder_rsp_event *rsp = rsp_params;
1607 uint16_t data_len;
1608
1609 ENTER();
1610 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001611 hdd_err("Invalid NDP Responder response");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001612 return;
1613 }
1614
1615 if (0 != wlan_hdd_validate_context(hdd_ctx))
1616 return;
1617
Naveen Rawatba4f6612016-07-05 12:03:16 -07001618 hdd_info("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001619 rsp->vdev_id, rsp->transaction_id,
1620 rsp->status, rsp->reason);
1621
1622 data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
1623 4 * NLA_HDRLEN + NLMSG_HDRLEN;
1624 /* notify response to the upper layer */
1625 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1626 NULL, data_len,
1627 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1628 GFP_KERNEL);
1629 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001630 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001631 return;
1632 }
1633
1634 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1635 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1636 goto ndp_responder_rsp_nla_failed;
1637
1638 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1639 rsp->transaction_id))
1640 goto ndp_responder_rsp_nla_failed;
1641
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001642 if (nla_put_u32(vendor_event,
1643 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001644 rsp->status))
1645 goto ndp_responder_rsp_nla_failed;
1646
1647 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001648 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001649 rsp->reason))
1650 goto ndp_responder_rsp_nla_failed;
1651
1652 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1653 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001654 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001655ndp_responder_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001656 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001657 kfree_skb(vendor_event);
1658 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001659}
1660
1661/**
1662 * hdd_ndp_end_rsp_handler() - NDP end response handler
1663 * @adapter: pointer to adapter context
1664 * @rsp_params: response parameters
1665 *
Naveen Rawatf28315c2016-06-29 18:06:02 -07001666 * Following vendor event is sent to cfg80211:
1667 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1668 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001669 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001670 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1671 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1672 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001673 * Return: none
1674 */
Jeff Johnson11b4c322017-10-06 11:48:23 -07001675static void hdd_ndp_end_rsp_handler(struct hdd_adapter *adapter,
1676 void *rsp_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001677{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001678 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001679 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Naveen Rawatf28315c2016-06-29 18:06:02 -07001680 struct ndp_end_rsp_event *rsp = rsp_params;
Rakesh Sunkiae936b62016-07-28 16:01:45 -07001681 uint32_t data_len;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001682
1683 ENTER();
1684
1685 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001686 hdd_err("Invalid ndp end response");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001687 return;
1688 }
1689
1690 if (0 != wlan_hdd_validate_context(hdd_ctx))
1691 return;
1692
Naveen Rawatf28315c2016-06-29 18:06:02 -07001693 data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
1694 sizeof(uint16_t);
1695
1696 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1697 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1698 GFP_KERNEL);
1699 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001700 hdd_err("cfg80211_vendor_event_alloc failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001701 return;
1702 }
1703
1704 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1705 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1706 goto ndp_end_rsp_nla_failed;
1707
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001708 if (nla_put_u32(vendor_event,
1709 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001710 rsp->status))
1711 goto ndp_end_rsp_nla_failed;
1712
1713 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1714 rsp->reason))
1715 goto ndp_end_rsp_nla_failed;
1716
1717 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1718 rsp->transaction_id))
1719 goto ndp_end_rsp_nla_failed;
1720
Naveen Rawatba4f6612016-07-05 12:03:16 -07001721 hdd_info("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001722 rsp->transaction_id, rsp->status, rsp->reason);
1723 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1724 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001725 return;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001726
1727ndp_end_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001728 hdd_err("nla_put api failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001729 kfree_skb(vendor_event);
1730 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001731}
1732
1733/**
1734 * hdd_ndp_end_ind_handler() - NDP end indication handler
1735 * @adapter: pointer to adapter context
1736 * @ind_params: indication parameters
1737 *
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001738 * Following vendor event is sent to cfg80211:
1739 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1740 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001741 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1742 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001743 * Return: none
1744 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001745static void hdd_ndp_end_ind_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001746 void *ind_params)
1747{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001748 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001749 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001750 struct ndp_end_indication_event *end_ind = ind_params;
1751 uint32_t data_len, i;
1752 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07001753 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001754 uint32_t *ndp_instance_array;
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001755 struct hdd_adapter *ndi_adapter;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001756
1757 ENTER();
1758
1759 if (!end_ind) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001760 hdd_err("Invalid ndp end indication");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001761 return;
1762 }
1763
1764 if (0 != wlan_hdd_validate_context(hdd_ctx))
1765 return;
1766
1767 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1768 sizeof(*ndp_instance_array));
1769 if (!ndp_instance_array) {
1770 hdd_err("Failed to allocate ndp_instance_array");
1771 return;
1772 }
1773 for (i = 0; i < end_ind->num_ndp_ids; i++) {
1774 int idx;
1775
1776 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
Naveen Rawate21103f2016-07-08 14:18:00 -07001777 ndi_adapter = hdd_get_adapter_by_vdev(hdd_ctx,
1778 end_ind->ndp_map[i].vdev_id);
1779 if (ndi_adapter == NULL) {
1780 hdd_err("Adapter not found for vdev_id: %d",
1781 end_ind->ndp_map[i].vdev_id);
1782 continue;
1783 }
1784 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
Govind Singhb8475942016-08-12 11:07:09 +05301785 if (!ndp_ctx) {
1786 hdd_err("ndp_ctx is NULL for vdev id: %d",
1787 end_ind->ndp_map[i].vdev_id);
1788 continue;
1789 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001790 idx = hdd_get_peer_idx(sta_ctx,
1791 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1792 if (idx == INVALID_PEER_IDX) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001793 hdd_err("can't find addr: %pM in sta_ctx.",
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001794 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1795 continue;
1796 }
1797 /* save the value of active sessions on each peer */
1798 ndp_ctx->active_ndp_sessions[idx] =
1799 end_ind->ndp_map[i].num_active_ndp_sessions;
1800 }
1801
Naveen Rawat90ae3082016-06-29 18:22:59 -07001802 data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001803 end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
1804
1805 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1806 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1807 GFP_KERNEL);
1808 if (!vendor_event) {
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05301809 qdf_mem_free(ndp_instance_array);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001810 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001811 return;
1812 }
1813
1814 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1815 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1816 goto ndp_end_ind_nla_failed;
1817
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001818 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1819 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1820 ndp_instance_array))
1821 goto ndp_end_ind_nla_failed;
1822
1823 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1824 qdf_mem_free(ndp_instance_array);
1825 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001826 return;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001827
1828ndp_end_ind_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001829 hdd_err("nla_put api failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001830 kfree_skb(vendor_event);
1831 qdf_mem_free(ndp_instance_array);
1832 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001833}
1834
1835/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001836 * hdd_ndp_event_handler() - ndp response and indication handler
1837 * @adapter: adapter context
1838 * @roam_info: pointer to roam_info structure
1839 * @roam_id: roam id as indicated by SME
1840 * @roam_status: roam status
1841 * @roam_result: roam result
1842 *
1843 * Return: none
1844 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001845void hdd_ndp_event_handler(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -08001846 struct csr_roam_info *roam_info,
1847 uint32_t roam_id, eRoamCmdStatus roam_status,
1848 eCsrRoamResult roam_result)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001849{
1850 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1851 switch (roam_result) {
Naveen Rawat8d63a592016-06-29 18:30:59 -07001852 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001853 hdd_ndp_iface_create_rsp_handler(adapter,
1854 &roam_info->ndp.ndi_create_params);
1855 break;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001856 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001857 hdd_ndp_iface_delete_rsp_handler(adapter,
1858 &roam_info->ndp.ndi_delete_params);
1859 break;
1860 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1861 hdd_ndp_initiator_rsp_handler(adapter,
1862 &roam_info->ndp.ndp_init_rsp_params);
1863 break;
1864 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1865 hdd_ndp_new_peer_ind_handler(adapter,
1866 &roam_info->ndp.ndp_peer_ind_params);
1867 break;
1868 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1869 hdd_ndp_confirm_ind_handler(adapter,
1870 &roam_info->ndp.ndp_confirm_params);
1871 break;
1872 case eCSR_ROAM_RESULT_NDP_INDICATION:
1873 hdd_ndp_indication_handler(adapter,
1874 &roam_info->ndp.ndp_indication_params);
1875 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001876 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1877 hdd_ndp_responder_rsp_handler(adapter,
1878 &roam_info->ndp.ndp_responder_rsp_params);
1879 break;
1880 case eCSR_ROAM_RESULT_NDP_END_RSP:
1881 hdd_ndp_end_rsp_handler(adapter,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001882 roam_info->ndp.ndp_end_rsp_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001883 break;
1884 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1885 hdd_ndp_peer_departed_ind_handler(adapter,
1886 &roam_info->ndp.ndp_peer_ind_params);
1887 break;
1888 case eCSR_ROAM_RESULT_NDP_END_IND:
1889 hdd_ndp_end_ind_handler(adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001890 roam_info->ndp.ndp_end_ind_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001891 break;
1892 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001893 hdd_err("Unknown NDP response event from SME %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001894 roam_result);
1895 break;
1896 }
1897 }
1898}
Naveen Rawat97500352017-03-22 10:07:58 -07001899#else
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001900void hdd_ndp_event_handler(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -08001901 struct csr_roam_info *roam_info,
1902 uint32_t roam_id, eRoamCmdStatus roam_status,
1903 eCsrRoamResult roam_result)
Naveen Rawat97500352017-03-22 10:07:58 -07001904{
Naveen Rawatcb5c5402017-03-22 10:12:19 -07001905 bool success;
1906 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(adapter->hdd_vdev);
1907
1908 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1909 switch (roam_result) {
1910 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
1911 success = (roam_info->ndp.ndi_create_params.status ==
1912 NAN_DATAPATH_RSP_STATUS_SUCCESS);
1913 hdd_debug("posting ndi create status: %d to umac",
1914 success);
Jeff Johnson1b780e42017-10-31 14:11:45 -07001915 os_if_nan_post_ndi_create_rsp(psoc, adapter->session_id,
Naveen Rawatcb5c5402017-03-22 10:12:19 -07001916 success);
1917 return;
1918 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
1919 success = (roam_info->ndp.ndi_create_params.status ==
1920 NAN_DATAPATH_RSP_STATUS_SUCCESS);
1921 hdd_debug("posting ndi delete status: %d to umac",
1922 success);
Jeff Johnson1b780e42017-10-31 14:11:45 -07001923 os_if_nan_post_ndi_delete_rsp(psoc, adapter->session_id,
Naveen Rawatcb5c5402017-03-22 10:12:19 -07001924 success);
1925 return;
1926 default:
1927 hdd_err("in correct roam_result: %d", roam_result);
1928 return;
1929 }
1930 } else {
1931 hdd_err("in correct roam_status: %d", roam_status);
1932 return;
1933 }
Naveen Rawat97500352017-03-22 10:07:58 -07001934}
1935#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001936
1937/**
1938 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1939 * @wiphy: pointer to wireless wiphy structure.
1940 * @wdev: pointer to wireless_dev structure.
1941 * @data: Pointer to the data to be passed via vendor interface
1942 * @data_len:Length of the data to be passed
1943 *
1944 * This function is invoked to handle vendor command
1945 *
1946 * Return: 0 on success, negative errno on failure
1947 */
Naveen Rawat63de5422017-03-22 11:03:56 -07001948#ifdef WLAN_FEATURE_NAN_CONVERGENCE
1949static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1950 struct wireless_dev *wdev, const void *data, int data_len)
1951{
1952 int ret_val;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001953 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Naveen Rawat63de5422017-03-22 11:03:56 -07001954
1955 ENTER();
1956
1957 ret_val = wlan_hdd_validate_context(hdd_ctx);
1958 if (ret_val)
1959 return ret_val;
1960
1961 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1962 hdd_err("Command not allowed in FTM mode");
1963 return -EPERM;
1964 }
1965
1966 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
1967 hdd_err("NAN datapath is not enabled");
1968 return -EPERM;
1969 }
1970 /* NAN data path coexists only with STA interface */
1971 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
1972 hdd_err("Unsupported concurrency for NAN datapath");
1973 return -EPERM;
1974 }
1975
1976 /* NAN data path coexists only with STA interface */
1977 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
1978 hdd_err("Unsupported concurrency for NAN datapath");
1979 return -EPERM;
1980 }
1981
1982 return os_if_nan_process_ndp_cmd(hdd_ctx->hdd_psoc,
1983 data, data_len);
1984}
1985#else
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001986static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1987 struct wireless_dev *wdev, const void *data, int data_len)
1988{
1989 uint32_t ndp_cmd_type;
1990 uint16_t transaction_id;
1991 int ret_val;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001992 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001993 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1994 char *iface_name;
1995
1996 ENTER();
1997
1998 ret_val = wlan_hdd_validate_context(hdd_ctx);
1999 if (ret_val)
2000 return ret_val;
2001
2002 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002003 hdd_err("Command not allowed in FTM mode");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002004 return -EPERM;
2005 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07002006 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002007 hdd_err("NAN datapath is not enabled");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002008 return -EPERM;
2009 }
Dustin Brown3fb15042017-08-15 15:54:49 -07002010 if (hdd_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
2011 data, data_len, qca_wlan_vendor_ndp_policy)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002012 hdd_err("Invalid NDP vendor command attributes");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002013 return -EINVAL;
2014 }
2015
2016 /* Parse and fetch NDP Command Type*/
2017 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002018 hdd_err("NAN datapath cmd type failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002019 return -EINVAL;
2020 }
2021 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
2022
2023 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002024 hdd_err("attr transaction id failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002025 return -EINVAL;
2026 }
2027 transaction_id = nla_get_u16(
2028 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
2029
Naveen Rawatf28315c2016-06-29 18:06:02 -07002030 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
2031 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002032 hdd_debug("Transaction Id: %d NDP Cmd: %d iface_name: %s",
Naveen Rawatf28315c2016-06-29 18:06:02 -07002033 transaction_id, ndp_cmd_type, iface_name);
2034 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002035 hdd_debug("Transaction Id: %d NDP Cmd: %d iface_name: unspecified",
Naveen Rawatf28315c2016-06-29 18:06:02 -07002036 transaction_id, ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002037 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002038
2039 switch (ndp_cmd_type) {
2040 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
2041 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
2042 break;
2043 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
2044 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
2045 break;
2046 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
2047 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
2048 break;
2049 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
2050 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
2051 break;
2052 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
2053 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
2054 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002055 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07002056 hdd_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002057 ret_val = -EINVAL;
2058 break;
2059 }
2060
2061 return ret_val;
2062}
Naveen Rawat63de5422017-03-22 11:03:56 -07002063#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002064
2065/**
2066 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
2067 * @wiphy: pointer to wireless wiphy structure.
2068 * @wdev: pointer to wireless_dev structure.
2069 * @data: Pointer to the data to be passed via vendor interface
2070 * @data_len:Length of the data to be passed
2071 *
2072 * This function is called to send a NAN request to
2073 * firmware. This is an SSR-protected wrapper function.
2074 *
2075 * Return: 0 on success, negative errno on failure
2076 */
2077int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
2078 struct wireless_dev *wdev, const void *data, int data_len)
2079{
2080 int ret;
2081
2082 cds_ssr_protect(__func__);
2083 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
2084 cds_ssr_unprotect(__func__);
2085
2086 return ret;
2087}
2088
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002089#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Jeff Johnson85b5c112017-08-11 15:15:23 -07002090static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002091{
2092 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
2093
2094 ndp_ctx->state = state;
2095 return 0;
2096}
2097#else
Jeff Johnson85b5c112017-08-11 15:15:23 -07002098static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002099{
2100 return os_if_nan_set_ndi_state(adapter->hdd_vdev, state);
2101}
2102#endif
2103
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002104/**
2105 * hdd_init_nan_data_mode() - initialize nan data mode
2106 * @adapter: adapter context
2107 *
2108 * Returns: 0 on success negative error code on error
2109 */
Jeff Johnson85b5c112017-08-11 15:15:23 -07002110int hdd_init_nan_data_mode(struct hdd_adapter *adapter)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002111{
2112 struct net_device *wlan_dev = adapter->dev;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002113 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002114 QDF_STATUS status;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002115 int32_t ret_val = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002116
Dustin Brownd28772b2017-03-17 14:16:07 -07002117 ret_val = hdd_vdev_create(adapter);
2118 if (ret_val) {
2119 hdd_err("failed to create vdev: %d", ret_val);
2120 return ret_val;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002121 }
2122
Ravi Joshi8eb65f92017-07-20 16:30:19 -07002123 /* Configure self HT/VHT capabilities */
2124 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
2125 sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
Jeff Johnson1b780e42017-10-31 14:11:45 -07002126 sme_set_vdev_ies_per_band(hdd_ctx->hHal, adapter->session_id);
Ravi Joshi8eb65f92017-07-20 16:30:19 -07002127
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002128 /* Register wireless extensions */
2129 ret_val = hdd_register_wext(wlan_dev);
2130 if (0 > ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002131 hdd_err("Wext registration failed with status code %d",
2132 ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002133 ret_val = -EAGAIN;
2134 goto error_register_wext;
2135 }
2136
2137 status = hdd_init_tx_rx(adapter);
2138 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002139 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002140 ret_val = -EAGAIN;
2141 goto error_init_txrx;
2142 }
2143
2144 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2145
2146 status = hdd_wmm_adapter_init(adapter);
2147 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002148 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002149 ret_val = -EAGAIN;
2150 goto error_wmm_init;
2151 }
2152
2153 set_bit(WMM_INIT_DONE, &adapter->event_flags);
2154
Jeff Johnson1b780e42017-10-31 14:11:45 -07002155 ret_val = wma_cli_set_command((int)adapter->session_id,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002156 (int)WMI_PDEV_PARAM_BURST_ENABLE,
2157 (int)hdd_ctx->config->enableSifsBurst,
2158 PDEV_CMD);
Arunk Khandavalli15664e42017-06-29 15:56:14 +05302159 if (0 != ret_val)
Naveen Rawatba4f6612016-07-05 12:03:16 -07002160 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Arunk Khandavalli15664e42017-06-29 15:56:14 +05302161
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002162
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002163 update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002164 return ret_val;
2165
2166error_wmm_init:
2167 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2168 hdd_deinit_tx_rx(adapter);
2169
2170error_init_txrx:
2171 hdd_unregister_wext(wlan_dev);
2172
2173error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07002174 QDF_BUG(!hdd_vdev_destroy(adapter));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002175
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002176 return ret_val;
2177}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002178
2179#ifdef WLAN_FEATURE_NAN_CONVERGENCE
2180struct wlan_objmgr_vdev *hdd_ndi_open(char *iface_name)
2181{
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002182 struct hdd_adapter *adapter;
Ravi Joshi9771d432017-06-26 13:58:12 -07002183 struct qdf_mac_addr random_ndi_mac;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002184 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Ravi Joshi9771d432017-06-26 13:58:12 -07002185 uint8_t *ndi_mac_addr;
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002186
2187 ENTER();
Naveen Rawat5a6f8402017-07-03 16:00:11 -07002188
Ravi Joshi9771d432017-06-26 13:58:12 -07002189 if (hdd_ctx->config->is_ndi_mac_randomized) {
2190 if (hdd_get_random_nan_mac_addr(hdd_ctx, &random_ndi_mac)) {
2191 hdd_err("get random mac address failed");
2192 return NULL;
2193 }
2194 ndi_mac_addr = &random_ndi_mac.bytes[0];
2195 } else {
2196 ndi_mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
2197 if (!ndi_mac_addr) {
2198 hdd_err("get intf address failed");
2199 return NULL;
2200 }
Naveen Rawat5a6f8402017-07-03 16:00:11 -07002201 }
2202
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002203 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
Ravi Joshi9771d432017-06-26 13:58:12 -07002204 ndi_mac_addr, NET_NAME_UNKNOWN, true);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002205 if (!adapter) {
2206 hdd_err("hdd_open_adapter failed");
2207 return NULL;
2208 }
2209
2210 EXIT();
2211 return adapter->hdd_vdev;
2212}
2213
2214int hdd_ndi_start(uint8_t vdev_id)
2215{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002216 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002217 uint8_t op_channel = hdd_ctx->config->nan_datapath_ndi_channel;
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002218 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002219
2220 ENTER();
2221 /*
2222 * The NAN data interface has been created at this point.
2223 * Unlike traditional device modes, where the higher application
2224 * layer initiates connect / join / start, the NAN data
2225 * interface does not have any such formal requests. The NDI
2226 * create request is responsible for starting the BSS as well.
2227 */
2228 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
2229 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
2230 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
2231 /* start NDI on the default 2.4 GHz social channel */
2232 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
2233 }
2234 if (hdd_ndi_start_bss(adapter, op_channel)) {
2235 hdd_err("NDI start bss failed");
2236 /* Start BSS failed, delete the interface */
2237 hdd_close_ndi(adapter);
2238 EXIT();
2239 return -EINVAL;
2240 }
2241
2242 return 0;
2243}
2244
2245int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id)
2246{
2247 int ret;
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002248 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002249 struct hdd_station_ctx *sta_ctx;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002250 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002251
Naveen Rawatc4b045c2017-06-30 16:11:42 -07002252 /* check if adapter by vdev_id is valid NDI */
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002253 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2254 if (!adapter || !WLAN_HDD_IS_NDI(adapter)) {
2255 hdd_err("NAN data interface %s is not available", iface_name);
2256 return -EINVAL;
2257 }
2258
2259 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2260 if (!sta_ctx) {
2261 hdd_err("sta_ctx is NULL");
2262 return -EINVAL;
2263 }
2264
2265 /* Since, the interface is being deleted, remove the broadcast id. */
2266 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
2267 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
2268
2269 os_if_nan_set_ndp_delete_transaction_id(adapter->hdd_vdev,
2270 transaction_id);
2271 os_if_nan_set_ndi_state(adapter->hdd_vdev, NAN_DATA_NDI_DELETING_STATE);
2272
2273 /* Delete the interface */
2274 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
2275 if (ret)
2276 hdd_err("NDI delete request failed");
2277 else
2278 hdd_err("NDI delete request successfully issued");
2279
2280 return ret;
2281}
2282
2283void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id,
2284 struct nan_datapath_inf_create_rsp *ndi_rsp)
2285{
Jeff Johnson172237b2017-11-07 15:32:59 -08002286 struct csr_roam_info roam_info = {0};
Jeff Johnson4ba73cb2017-10-06 11:12:33 -07002287 struct bss_description tmp_bss_descp = {0};
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002288 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002289 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002290 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002291 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002292
2293 if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
2294 hdd_alert("NDI interface successfully created");
2295 os_if_nan_set_ndp_create_transaction_id(adapter->hdd_vdev, 0);
2296 os_if_nan_set_ndi_state(adapter->hdd_vdev,
2297 NAN_DATA_NDI_CREATED_STATE);
2298 wlan_hdd_netif_queue_control(adapter,
2299 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2300 WLAN_CONTROL_PATH);
2301 } else {
2302 hdd_alert("NDI interface creation failed with reason %d",
2303 ndi_rsp->reason /* create_reason */);
2304 }
2305
2306 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
2307 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
2308 hdd_roam_register_sta(adapter, &roam_info,
2309 sta_ctx->broadcast_staid,
2310 &bc_mac_addr, &tmp_bss_descp);
2311 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
2312}
2313
2314void hdd_ndi_close(uint8_t vdev_id)
2315{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002316 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002317 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002318
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002319 hdd_close_ndi(adapter);
2320}
2321
2322void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id)
2323{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002324 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002325 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002326
2327 wlan_hdd_netif_queue_control(adapter,
2328 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
2329 WLAN_CONTROL_PATH);
2330
2331 complete(&adapter->disconnect_comp_var);
2332}
2333
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002334void hdd_ndp_session_end_handler(struct hdd_adapter *adapter)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002335{
2336 os_if_nan_ndi_session_end(adapter->hdd_vdev);
2337}
2338
Naveen Rawat37f62c82017-03-26 22:24:43 -07002339int hdd_ndp_get_peer_idx(uint8_t vdev_id, struct qdf_mac_addr *addr)
2340{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002341 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002342 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002343 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002344
Naveen Rawat37f62c82017-03-26 22:24:43 -07002345 return hdd_get_peer_idx(sta_ctx, addr);
2346}
2347
2348/**
2349 * hdd_ndp_new_peer_handler() - NDP new peer indication handler
2350 * @adapter: pointer to adapter context
2351 * @ind_params: indication parameters
2352 *
2353 * Return: none
2354 */
2355int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id,
2356 struct qdf_mac_addr *peer_mac_addr, bool fist_peer)
2357{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002358 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002359 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson4ba73cb2017-10-06 11:12:33 -07002360 struct bss_description tmp_bss_descp = {0};
Jeff Johnson172237b2017-11-07 15:32:59 -08002361 struct csr_roam_info roam_info = {0};
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002362 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Naveen Rawat37f62c82017-03-26 22:24:43 -07002363
2364 ENTER();
2365 /* save peer in ndp ctx */
2366 if (false == hdd_save_peer(sta_ctx, sta_id, peer_mac_addr)) {
2367 hdd_err("Ndp peer table full. cannot save new peer");
2368 return -EPERM;
2369 }
2370
2371 /* this function is called for each new peer */
2372 hdd_roam_register_sta(adapter, &roam_info, sta_id,
2373 peer_mac_addr, &tmp_bss_descp);
2374 hdd_ctx->sta_to_adapter[sta_id] = adapter;
2375 /* perform following steps for first new peer ind */
2376 if (fist_peer) {
2377 hdd_info("Set ctx connection state to connected");
2378 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
2379 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
2380 wlan_hdd_netif_queue_control(adapter,
2381 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
2382 }
2383 EXIT();
2384 return 0;
2385}
2386
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002387
2388/**
2389 * hdd_ndp_peer_departed_handler() - Handle NDP peer departed indication
2390 * @adapter: pointer to adapter context
2391 * @ind_params: indication parameters
2392 *
2393 * Return: none
2394 */
2395void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id,
2396 struct qdf_mac_addr *peer_mac_addr, bool last_peer)
2397{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002398 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002399 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002400 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002401
2402 ENTER();
2403 hdd_roam_deregister_sta(adapter, sta_id);
2404 hdd_delete_peer(sta_ctx, sta_id);
2405 hdd_ctx->sta_to_adapter[sta_id] = NULL;
2406
2407 if (last_peer) {
2408 hdd_info("No more ndp peers.");
2409 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
2410 hdd_conn_set_connection_state(adapter,
2411 eConnectionState_NdiDisconnected);
2412 hdd_info("Stop netif tx queues.");
2413 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
2414 WLAN_CONTROL_PATH);
2415 }
2416 EXIT();
2417}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002418#endif