blob: a8a5a6ebe87b725410ebe881189190e414b6ff10 [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
Dustin Brown920397d2017-12-13 16:27:50 -0800172 hdd_for_each_adapter(hdd_ctx, adapter) {
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700173 switch (adapter->device_mode) {
174 case QDF_P2P_GO_MODE:
175 case QDF_SAP_MODE:
176 if (test_bit(SOFTAP_BSS_STARTED,
177 &adapter->event_flags))
178 return false;
179 break;
180 case QDF_P2P_CLIENT_MODE:
181 case QDF_IBSS_MODE:
182 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
183 if (hdd_conn_is_connected(sta_ctx) ||
184 hdd_is_connecting(sta_ctx))
185 return false;
186 break;
187 default:
188 break;
189 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700190 }
191
192 return true;
193}
194
195/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700196 * hdd_ndi_start_bss() - Start BSS on NAN data interface
197 * @adapter: adapter context
198 * @operating_channel: channel on which the BSS to be started
199 *
200 * Return: 0 on success, error value on failure
201 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700202static int hdd_ndi_start_bss(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700203 uint8_t operating_channel)
204{
205 int ret;
206 uint32_t roam_id;
Jeff Johnson2a722002017-09-30 20:02:35 -0700207 struct hdd_wext_state *wext_state =
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -0700208 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700209 tCsrRoamProfile *roam_profile = &wext_state->roamProfile;
210
211 ENTER();
212
213 if (!roam_profile) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700214 hdd_err("No valid roam profile");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700215 return -EINVAL;
216 }
217
218 if (HDD_WMM_USER_MODE_NO_QOS ==
219 (WLAN_HDD_GET_CTX(adapter))->config->WmmMode) {
220 /* QoS not enabled in cfg file*/
221 roam_profile->uapsd_mask = 0;
222 } else {
223 /* QoS enabled, update uapsd mask from cfg file*/
224 roam_profile->uapsd_mask =
225 (WLAN_HDD_GET_CTX(adapter))->config->UapsdMask;
226 }
227
228 roam_profile->csrPersona = adapter->device_mode;
229
230 roam_profile->ChannelInfo.numOfChannels = 1;
231 if (operating_channel) {
232 roam_profile->ChannelInfo.ChannelList = &operating_channel;
233 } else {
234 roam_profile->ChannelInfo.ChannelList[0] =
235 NAN_SOCIAL_CHANNEL_2_4GHZ;
236 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700237
238 roam_profile->SSIDs.numOfSSIDs = 1;
239 roam_profile->SSIDs.SSIDList->SSID.length = 0;
240
241 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
242 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
243 roam_profile->BSSIDs.numOfBSSIDs = 1;
244 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
Jeff Johnson1e851a12017-10-28 14:36:12 -0700245 &adapter->mac_addr.bytes[0],
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700246 QDF_MAC_ADDR_SIZE);
247
248 roam_profile->AuthType.numEntries = 1;
249 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
250 roam_profile->EncryptionType.numEntries = 1;
251 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
252
253 ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -0700254 adapter->session_id, roam_profile, &roam_id);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700255 if (QDF_STATUS_SUCCESS != ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700256 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
Jeff Johnson1b780e42017-10-31 14:11:45 -0700257 adapter->session_id, ret);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700258 /* change back to NotConnected */
259 hdd_conn_set_connection_state(adapter,
260 eConnectionState_NotConnected);
261 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700262 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700263 }
264
265 roam_profile->ChannelInfo.ChannelList = NULL;
266 roam_profile->ChannelInfo.numOfChannels = 0;
267
268 EXIT();
269
270 return ret;
271}
272
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700273/**
274 * hdd_get_random_nan_mac_addr() - generate random non pre-existent mac address
275 * @hdd_ctx: hdd context pointer
276 * @mac_addr: mac address buffer to populate
277 *
278 * Return: status of operation
279 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700280static int hdd_get_random_nan_mac_addr(struct hdd_context *hdd_ctx,
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700281 struct qdf_mac_addr *mac_addr)
282{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700283 struct hdd_adapter *adapter;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700284 uint8_t i, attempts, max_attempt = 16;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700285
286 for (attempts = 0; attempts < max_attempt; attempts++) {
287 cds_rand_get_bytes(0, (uint8_t *)mac_addr, sizeof(*mac_addr));
Ravi Joshi04a1c992017-06-11 19:47:54 -0700288
289 /*
290 * Reset multicast bit (bit-0) and set locally-administered bit
291 */
292 mac_addr->bytes[0] = 0x2;
293
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700294 /*
295 * to avoid potential conflict with FW's generated NMI mac addr,
296 * host sets LSB if 6th byte to 0
297 */
298 mac_addr->bytes[5] &= 0xFE;
299
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700300 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
301 if (!qdf_mem_cmp(hdd_ctx->config->intfMacAddr[i].bytes,
302 mac_addr, sizeof(*mac_addr)))
303 continue;
304 }
305
306 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
307 if (!adapter)
308 return 0;
309 }
310
311 hdd_err("unable to get non-pre-existing mac address in %d attempts",
312 max_attempt);
313
314 return -EINVAL;
315}
316
Naveen Rawat97500352017-03-22 10:07:58 -0700317#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700318/**
319 * hdd_ndi_create_req_handler() - NDI create request handler
320 * @hdd_ctx: hdd context
321 * @tb: parsed NL attribute list
322 *
323 * Return: 0 on success or error code on failure
324 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700325static int hdd_ndi_create_req_handler(struct hdd_context *hdd_ctx,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700326 struct nlattr **tb)
327{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700328 struct hdd_adapter *adapter;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700329 char *iface_name;
330 uint16_t transaction_id;
331 int ret;
332 struct nan_datapath_ctx *ndp_ctx;
333 uint8_t op_channel =
334 hdd_ctx->config->nan_datapath_ndi_channel;
Ravi Joshi9771d432017-06-26 13:58:12 -0700335 struct qdf_mac_addr random_ndi_mac;
336 uint8_t *ndi_mac_addr;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700337
338 ENTER();
339
340 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700341 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700342 return -EINVAL;
343 }
344 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
345
346 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700347 hdd_err("transaction id is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700348 return -EINVAL;
349 }
350 transaction_id =
351 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
352
353 /* Check for an existing interface of NDI type */
354 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
355 if (adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700356 hdd_err("Cannot support more than one NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700357 return -EEXIST;
358 }
359
Ravi Joshi9771d432017-06-26 13:58:12 -0700360 if (hdd_ctx->config->is_ndi_mac_randomized) {
361 if (hdd_get_random_nan_mac_addr(hdd_ctx, &random_ndi_mac)) {
362 hdd_err("get random mac address failed");
363 return -EINVAL;
364 }
365 ndi_mac_addr = &random_ndi_mac.bytes[0];
366 } else {
367 ndi_mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
368 if (!ndi_mac_addr) {
369 hdd_err("get intf address failed");
370 return -EINVAL;
371 }
372 }
373
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700374 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
Ravi Joshi9771d432017-06-26 13:58:12 -0700375 ndi_mac_addr, NET_NAME_UNKNOWN, true);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700376 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700377 hdd_err("hdd_open_adapter failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700378 return -ENOMEM;
379 }
380
381 /*
382 * Create transaction id is required to be saved since the firmware
383 * does not honor the transaction id for create request
384 */
385 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
386 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700387 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700388
389 /*
390 * The NAN data interface has been created at this point.
391 * Unlike traditional device modes, where the higher application
392 * layer initiates connect / join / start, the NAN data interface
393 * does not have any such formal requests. The NDI create request
394 * is responsible for starting the BSS as well.
395 */
396 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
397 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
398 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
399 /* start NDI on the default 2.4 GHz social channel */
400 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
401 }
402 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700403 if (0 > ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700404 hdd_err("NDI start bss failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700405 /* Start BSS failed, delete the interface */
406 hdd_close_ndi(adapter);
407 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700408
409 EXIT();
410 return ret;
411}
412
413/**
414 * hdd_ndi_delete_req_handler() - NDI delete request handler
415 * @hdd_ctx: hdd context
416 * @tb: parsed NL attribute list
417 *
418 * Return: 0 on success or error code on failure
419 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700420static int hdd_ndi_delete_req_handler(struct hdd_context *hdd_ctx,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700421 struct nlattr **tb)
422{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700423 struct hdd_adapter *adapter;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700424 char *iface_name;
425 uint16_t transaction_id;
426 struct nan_datapath_ctx *ndp_ctx;
427 int ret;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700428 struct hdd_station_ctx *sta_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700429
430 ENTER();
431
432 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700433 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700434 return -EINVAL;
435 }
436
437 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
438
439 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700440 hdd_err("Transaction id is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700441 return -EINVAL;
442 }
443
444 transaction_id =
445 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
446
447 /* Check if there is already an existing inteface with the same name */
448 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
449 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700450 hdd_err("NAN data interface %s is not available", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700451 return -EINVAL;
452 }
453
454 /* check if adapter is in NDI mode */
455 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700456 hdd_err("Interface %s is not in NDI mode", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700457 return -EINVAL;
458 }
459
460 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
461 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700462 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700463 return -EINVAL;
464 }
465
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700466 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
467 if (!sta_ctx) {
468 hdd_err("sta_ctx is NULL");
469 return -EINVAL;
470 }
471
Naveen Rawatf28315c2016-06-29 18:06:02 -0700472 /* check if there are active peers on the adapter */
473 if (ndp_ctx->active_ndp_peers > 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700474 hdd_err("NDP peers active: %d, cannot delete NDI",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700475 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700476 return -EINVAL;
477 }
478
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700479 /*
480 * Since, the interface is being deleted, remove the
481 * broadcast id.
482 */
483 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
484 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
485
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700486 ndp_ctx->ndp_delete_transaction_id = transaction_id;
487 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
488
489 /* Delete the interface */
490 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
491 if (ret < 0)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700492 hdd_err("NDI delete request failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700493 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700494 hdd_err("NDI delete request successfully issued");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700495
496 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700497}
498
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700499/**
500 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
501 * @hdd_ctx: hdd context
502 * @tb: parsed NL attribute list
503 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800504 * tb will contain following vendor attributes:
505 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
506 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
507 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
Ravi Joshi71e82f32017-02-09 23:15:16 -0800508 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG - optional
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800509 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
510 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
511 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
512 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
513 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
514 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
515 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700516 * Return: 0 on success or error code on failure
517 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700518static int hdd_ndp_initiator_req_handler(struct hdd_context *hdd_ctx,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700519 struct nlattr **tb)
520{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700521 struct hdd_adapter *adapter;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700522 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700523 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700524 QDF_STATUS status;
525 uint32_t ndp_qos_cfg;
526 tHalHandle hal = hdd_ctx->hHal;
527 struct nan_datapath_ctx *ndp_ctx;
528
529 ENTER();
530
531 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700532 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700533 return -EINVAL;
534 }
535
536 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
537 /* Check for interface in NDI mode */
538 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
539 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700540 hdd_err("NAN data interface %s not available", iface_name);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700541 return -EINVAL;
542 }
543
544 /* NAN data path coexists only with STA interface */
545 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700546 hdd_err("Unsupported concurrency for NAN datapath");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700547 return -EPERM;
548 }
549
550 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
551
552 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
553 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
554 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700555 hdd_err("Data request not allowed in NDI current state: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700556 ndp_ctx->state);
557 return -EINVAL;
558 }
559
Jeff Johnson1b780e42017-10-31 14:11:45 -0700560 req.vdev_id = adapter->session_id;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700561
562 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700563 hdd_err("Transaction ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700564 return -EINVAL;
565 }
566 req.transaction_id =
567 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
568
Naveen Rawat0a017052016-10-19 14:17:07 -0700569 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL])
570 req.channel =
571 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
572
Ravi Joshi71e82f32017-02-09 23:15:16 -0800573 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG])
Naveen Rawat0a017052016-10-19 14:17:07 -0700574 req.channel_cfg =
575 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700576
577 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700578 hdd_err("NDP service instance ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700579 return -EINVAL;
580 }
581 req.service_instance_id =
Naveen Rawat19da3d12016-08-16 12:39:38 -0700582 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700583
584 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
Jeff Johnson1e851a12017-10-28 14:36:12 -0700585 adapter->mac_addr.bytes, QDF_MAC_ADDR_SIZE);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700586
587 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700588 hdd_err("NDI peer discovery mac addr is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700589 return -EINVAL;
590 }
591 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
592 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
593 QDF_MAC_ADDR_SIZE);
594
Naveen Rawat90ae3082016-06-29 18:22:59 -0700595 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
596 req.ndp_info.ndp_app_info_len =
597 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
598 req.ndp_info.ndp_app_info =
599 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700600 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700601
602 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
603 /* at present ndp config stores 4 bytes QOS info only */
604 req.ndp_config.ndp_cfg_len = 4;
605 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
606 ndp_qos_cfg =
607 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
608 }
609
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800610 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
611 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
612 hdd_err("PMK cannot be absent when CSID is present.");
613 return -EINVAL;
614 }
615
616 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
617 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
618 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
619 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
620 QDF_TRACE_LEVEL_DEBUG,
621 req.pmk.pmk, req.pmk.pmk_len);
622 }
623
624 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
625 req.ncs_sk_type =
626 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
627
628 }
629
Ravi Joshi71e82f32017-02-09 23:15:16 -0800630 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",
631 req.vdev_id, req.transaction_id, req.channel, req.channel_cfg,
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700632 req.service_instance_id, req.ndp_info.ndp_app_info_len,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800633 req.ncs_sk_type, req.peer_discovery_mac_addr.bytes);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700634 status = sme_ndp_initiator_req_handler(hal, &req);
635 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700636 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700637 status);
638 return -ECOMM;
639 }
640 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700641 return 0;
642}
643
644/**
645 * hdd_ndp_responder_req_handler() - NDP responder request handler
646 * @hdd_ctx: hdd context
647 * @tb: parsed NL attribute list
648 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800649 * tb includes following vendor attributes:
650 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
651 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
652 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
653 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
654 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
655 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
656 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
657 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
658 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700659 * Return: 0 on success or error code on failure
660 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700661static int hdd_ndp_responder_req_handler(struct hdd_context *hdd_ctx,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700662 struct nlattr **tb)
663{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700664 struct hdd_adapter *adapter;
Abhishek Singh4fef7472016-06-06 11:36:03 -0700665 char *iface_name;
666 struct ndp_responder_req req = {0};
667 QDF_STATUS status;
668 int ret = 0;
669 struct nan_datapath_ctx *ndp_ctx;
670 uint32_t ndp_qos_cfg;
671
672 ENTER();
673
674 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700675 hdd_err("Interface name string is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700676 return -EINVAL;
677 }
678
679 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
680 /* Check if there is already an existing NAN interface */
681 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
682 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700683 hdd_err("NAN data interface %s not available", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700684 return -EINVAL;
685 }
686
687 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700688 hdd_err("Interface %s not in NDI mode", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700689 return -EINVAL;
690 }
691
692 /* NAN data path coexists only with STA interface */
693 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700694 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700695 return -EINVAL;
696 }
697
698 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
699
700 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
701 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
702 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700703 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700704 ndp_ctx->state);
705 return -EAGAIN;
706 }
707
Jeff Johnson1b780e42017-10-31 14:11:45 -0700708 req.vdev_id = adapter->session_id;
Abhishek Singh4fef7472016-06-06 11:36:03 -0700709
710 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700711 hdd_err("Transaction ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700712 return -EINVAL;
713 }
714 req.transaction_id =
715 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
716
717 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700718 hdd_err("Instance ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700719 return -EINVAL;
720 }
721 req.ndp_instance_id =
722 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
723
724 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700725 hdd_err("ndp_rsp is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700726 return -EINVAL;
727 }
728 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
729
730 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
731 req.ndp_info.ndp_app_info_len =
732 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
733 if (req.ndp_info.ndp_app_info_len) {
734 req.ndp_info.ndp_app_info =
735 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
736 }
737 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700738 hdd_info("NDP app info is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700739 }
740 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
741 /* at present ndp config stores 4 bytes QOS info only */
742 req.ndp_config.ndp_cfg_len = 4;
743 ndp_qos_cfg =
744 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
745 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
746 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700747 hdd_info("NDP config data is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700748 }
749
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800750 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
751 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
752 hdd_err("PMK cannot be absent when CSID is present.");
753 return -EINVAL;
754 }
755
756 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
757 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
758 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
759 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
760 QDF_TRACE_LEVEL_DEBUG,
761 req.pmk.pmk, req.pmk.pmk_len);
762 }
763
764 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
765 req.ncs_sk_type =
766 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
767
768 }
769
770 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 -0700771 req.vdev_id, req.transaction_id, req.ndp_rsp,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800772 req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
773 req.ncs_sk_type);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700774
775 status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req);
776 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700777 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700778 status);
779 ret = -EINVAL;
780 }
781
782 EXIT();
783 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700784}
785
786/**
787 * hdd_ndp_end_req_handler() - NDP end request handler
788 * @hdd_ctx: hdd context
789 * @tb: parsed NL attribute list
790 *
791 * Return: 0 on success or error code on failure
792 */
Jeff Johnson11b4c322017-10-06 11:48:23 -0700793static int hdd_ndp_end_req_handler(struct hdd_context *hdd_ctx,
794 struct nlattr **tb)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700795{
Naveen Rawatf28315c2016-06-29 18:06:02 -0700796 struct ndp_end_req req = {0};
797 QDF_STATUS status;
798 tHalHandle hal = hdd_ctx->hHal;
799
800 ENTER();
801
802 /* NAN data path coexists only with STA interface */
803 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700804 hdd_err("Unsupported concurrency for NAN datapath");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700805 return -EINVAL;
806 }
807
808 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700809 hdd_err("Transaction ID is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700810 return -EINVAL;
811 }
812 req.transaction_id =
813 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
814
815 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700816 hdd_err("NDP instance ID array is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700817 return -EINVAL;
818 }
819
820 req.num_ndp_instances =
821 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
822 sizeof(uint32_t);
823 if (0 >= req.num_ndp_instances) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700824 hdd_err("Num NDP instances is 0");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700825 return -EINVAL;
826 }
827 req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
828
Naveen Rawatba4f6612016-07-05 12:03:16 -0700829 hdd_info("sending ndp_end_req to SME, transaction_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700830 req.transaction_id);
831
832 status = sme_ndp_end_req_handler(hal, &req);
833 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700834 hdd_err("sme_ndp_end_req_handler failed, status: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700835 status);
836 return -ECOMM;
837 }
838 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700839 return 0;
840}
841
842/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700843 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
844 * @adapter: pointer to adapter context
845 * @rsp_params: response parameters
846 *
847 * The function is expected to send a response back to the user space
848 * even if the creation of BSS has failed
849 *
850 * Following vendor event is sent to cfg80211:
851 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
852 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
853 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800854 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700855 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
856 *
857 * Return: none
858 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700859static void hdd_ndp_iface_create_rsp_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700860 void *rsp_params)
861{
862 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700863 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700864 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
865 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
866 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
867 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700868 bool create_fail = false;
869 uint8_t create_transaction_id = 0;
Naveen Rawate21103f2016-07-08 14:18:00 -0700870 uint32_t create_status = NDP_RSP_STATUS_ERROR;
871 uint32_t create_reason = NDP_NAN_DATA_IFACE_CREATE_FAILED;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700872 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700873 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Jeff Johnson172237b2017-11-07 15:32:59 -0800874 struct csr_roam_info *roam_info;
Jeff Johnson4ba73cb2017-10-06 11:12:33 -0700875 struct bss_description tmp_bss_descp = {0};
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700876
877 ENTER();
878
Kapil Guptaffa26022017-08-16 12:20:09 +0530879 roam_info = qdf_mem_malloc(sizeof(*roam_info));
880 if (!roam_info) {
881 hdd_err("failed to allocate memory");
882 return;
883 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700884 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700885 /* No way the driver can send response back to user space */
Kapil Guptaffa26022017-08-16 12:20:09 +0530886 qdf_mem_free(roam_info);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700887 return;
888
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700889 if (ndi_rsp) {
890 create_status = ndi_rsp->status;
Naveen Rawate21103f2016-07-08 14:18:00 -0700891 create_reason = ndi_rsp->reason;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700892 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700893 hdd_err("Invalid ndi create response");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700894 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700895 }
896
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700897 if (ndp_ctx) {
898 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
899 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700900 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700901 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700902 }
903
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700904 if (!sta_ctx) {
905 hdd_err("sta_ctx is NULL");
906 create_fail = true;
907 }
908
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700909 /* notify response to the upper layer */
910 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
911 NULL,
912 data_len,
913 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
914 cds_get_gfp_flags());
915
916 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700917 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700918 create_fail = true;
919 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700920 }
921
922 /* Sub vendor command */
923 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
924 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700925 hdd_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700926 goto nla_put_failure;
927 }
928
929 /* Transaction id */
930 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700931 create_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700932 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700933 goto nla_put_failure;
934 }
935
936 /* Status code */
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800937 if (nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700939 create_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700940 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700941 goto nla_put_failure;
942 }
943
944 /* Status return value */
945 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700946 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawate21103f2016-07-08 14:18:00 -0700947 create_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700948 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700949 goto nla_put_failure;
950 }
951
Naveen Rawatba4f6612016-07-05 12:03:16 -0700952 hdd_info("sub command: %d, value: %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700953 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
954 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700955 hdd_info("create transaction id: %d, value: %d",
956 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
957 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800958 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
959 create_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700960 hdd_info("Return value: %d, value: %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700961 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700962
963 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
964
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700965 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700966 hdd_err("NDI interface successfully created");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700967 ndp_ctx->ndp_create_transaction_id = 0;
968 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700969 wlan_hdd_netif_queue_control(adapter,
970 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
971 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700972 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700973 hdd_err("NDI interface creation failed with reason %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700974 create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700975 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700976
977 /* Something went wrong while starting the BSS */
978 if (create_fail)
979 goto close_ndi;
980
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700981 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
982 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
Kapil Guptaffa26022017-08-16 12:20:09 +0530983 hdd_roam_register_sta(adapter, roam_info,
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700984 sta_ctx->broadcast_staid,
985 &bc_mac_addr, &tmp_bss_descp);
986 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
987
Kapil Guptaffa26022017-08-16 12:20:09 +0530988 qdf_mem_free(roam_info);
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700989
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700990 EXIT();
991 return;
992
993nla_put_failure:
994 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700995close_ndi:
996 hdd_close_ndi(adapter);
Kapil Guptaffa26022017-08-16 12:20:09 +0530997 qdf_mem_free(roam_info);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700998}
999
1000/**
1001 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
1002 * @adapter: pointer to adapter context
1003 * @rsp_params: response parameters
1004 *
1005 * Return: none
1006 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001007static void hdd_ndp_iface_delete_rsp_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001008 void *rsp_params)
1009{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001010 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001011 struct ndi_delete_rsp *ndi_rsp = rsp_params;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001012 struct nan_datapath_ctx *ndp_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001013
1014 if (wlan_hdd_validate_context(hdd_ctx))
1015 return;
1016
1017 if (!ndi_rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001018 hdd_err("Invalid ndi delete response");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001019 return;
1020 }
1021
Naveen Rawat8d63a592016-06-29 18:30:59 -07001022 if (ndi_rsp->status == NDP_RSP_STATUS_SUCCESS)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001023 hdd_err("NDI BSS successfully stopped");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001024 else
Naveen Rawatba4f6612016-07-05 12:03:16 -07001025 hdd_err("NDI BSS stop failed with reason %d", ndi_rsp->reason);
Naveen Rawat8d63a592016-06-29 18:30:59 -07001026
1027 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1028 ndp_ctx->ndi_delete_rsp_reason = ndi_rsp->reason;
1029 ndp_ctx->ndi_delete_rsp_status = ndi_rsp->status;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001030 wlan_hdd_netif_queue_control(adapter,
1031 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
1032 WLAN_CONTROL_PATH);
Naveen Rawat8d63a592016-06-29 18:30:59 -07001033
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001034 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001035}
1036
1037/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001038 * hdd_ndp_session_end_handler() - NDI session termination handler
1039 * @adapter: pointer to adapter context
1040 *
1041 * Following vendor event is sent to cfg80211:
1042 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1043 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
1044 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001045 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001046 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1047 *
1048 * Return: none
1049 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001050void hdd_ndp_session_end_handler(struct hdd_adapter *adapter)
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001051{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001052 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001053 struct sk_buff *vendor_event;
1054 struct nan_datapath_ctx *ndp_ctx;
1055 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
1056 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
1057
1058 ENTER();
1059
1060 if (wlan_hdd_validate_context(hdd_ctx))
1061 return;
1062
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001063 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1064 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001065 hdd_err("ndp context is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001066 return;
1067 }
1068
1069 /*
1070 * The virtual adapters are stopped and closed even during
1071 * driver unload or stop, the service layer is not required
1072 * to be informed in that case (response is not expected)
1073 */
1074 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001075 hdd_err("NDI interface %s deleted", adapter->dev->name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001076 return;
1077 }
1078
1079 /* notify response to the upper layer */
1080 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1081 NULL,
1082 data_len,
1083 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1084 GFP_KERNEL);
1085
1086 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001087 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001088 return;
1089 }
1090
1091 /* Sub vendor command goes first */
1092 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1093 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001094 hdd_err("VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001095 goto failure;
1096 }
1097
1098 /* Transaction id */
1099 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1100 ndp_ctx->ndp_delete_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001101 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001102 goto failure;
1103 }
1104
1105 /* Status code */
1106 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001107 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001108 ndp_ctx->ndi_delete_rsp_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001109 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001110 goto failure;
1111 }
1112
1113 /* Status return value */
1114 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001115 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1116 ndp_ctx->ndi_delete_rsp_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001117 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001118 goto failure;
1119 }
1120
Naveen Rawatba4f6612016-07-05 12:03:16 -07001121 hdd_info("sub command: %d, value: %d", QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001122 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001123 hdd_info("delete transaction id: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001124 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1125 ndp_ctx->ndp_delete_transaction_id);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001126 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001127 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001128 ndp_ctx->ndi_delete_rsp_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001129 hdd_info("Return value: %d, value: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001130 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1131 ndp_ctx->ndi_delete_rsp_reason);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001132
1133 ndp_ctx->ndp_delete_transaction_id = 0;
1134 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
1135
1136 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1137
1138 EXIT();
1139 return;
1140
1141failure:
1142 kfree_skb(vendor_event);
1143}
1144
1145
1146/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001147 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
1148 * @adapter: pointer to adapter context
1149 * @rsp_params: response parameters
1150 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001151 * Following vendor event is sent to cfg80211:
1152 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1153 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1154 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1155 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001156 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001157 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1158 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001159 * Return: none
1160 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001161static void hdd_ndp_initiator_rsp_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001162 void *rsp_params)
1163{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001164 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001165 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001166 struct ndp_initiator_rsp *rsp = rsp_params;
1167 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
1168 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
1169
1170 ENTER();
1171
1172 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001173 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001174 return;
1175 }
1176
1177 if (0 != wlan_hdd_validate_context(hdd_ctx))
1178 return;
1179
1180 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1181 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1182 GFP_KERNEL);
1183 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001184 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001185 return;
1186 }
1187
1188 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1189 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1190 goto ndp_initiator_rsp_nla_failed;
1191
1192 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1193 rsp->transaction_id))
1194 goto ndp_initiator_rsp_nla_failed;
1195
1196 if (nla_put_u32(vendor_event,
1197 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1198 rsp->ndp_instance_id))
1199 goto ndp_initiator_rsp_nla_failed;
1200
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001201 if (nla_put_u32(vendor_event,
1202 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001203 rsp->status))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001204 goto ndp_initiator_rsp_nla_failed;
1205
1206 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001207 rsp->reason))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001208 goto ndp_initiator_rsp_nla_failed;
1209
Naveen Rawatba4f6612016-07-05 12:03:16 -07001210 hdd_info("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001211 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1212 rsp->reason);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001213 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1214 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001215 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001216ndp_initiator_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001217 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001218 kfree_skb(vendor_event);
1219 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001220}
1221
1222/**
1223 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
1224 * @adapter: pointer to adapter context
1225 * @ind_params: indication parameters
1226 *
1227 * Return: none
1228 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001229static void hdd_ndp_new_peer_ind_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001230 void *ind_params)
1231{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001232 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001233 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson4ba73cb2017-10-06 11:12:33 -07001234 struct bss_description tmp_bss_descp = {0};
Jeff Johnson172237b2017-11-07 15:32:59 -08001235 struct csr_roam_info *roam_info;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001236 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07001237 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001238
1239 ENTER();
1240
Kapil Guptaffa26022017-08-16 12:20:09 +05301241 roam_info = qdf_mem_malloc(sizeof(*roam_info));
1242 if (!roam_info) {
1243 hdd_err("failed to allocate memory");
1244 return;
1245 }
1246
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001247 if (NULL == ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001248 hdd_err("Invalid new NDP peer params");
Kapil Guptaffa26022017-08-16 12:20:09 +05301249 goto free;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001250 }
Naveen Rawatba4f6612016-07-05 12:03:16 -07001251 hdd_info("session_id: %d, peer_mac: %pM, sta_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001252 new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
1253 new_peer_ind->sta_id);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001254
1255 /* save peer in ndp ctx */
1256 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
1257 &new_peer_ind->peer_mac_addr)) {
Kapil Guptaffa26022017-08-16 12:20:09 +05301258 hdd_warn("Ndp peer table full. cannot save new peer");
1259 goto free;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001260 }
1261
1262 /* this function is called for each new peer */
1263 ndp_ctx->active_ndp_peers++;
Jeff Johnson1b780e42017-10-31 14:11:45 -07001264 hdd_info("vdev_id: %d, num_peers: %d", adapter->session_id,
Naveen Rawatba4f6612016-07-05 12:03:16 -07001265 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001266
Kapil Guptaffa26022017-08-16 12:20:09 +05301267 hdd_roam_register_sta(adapter, roam_info, new_peer_ind->sta_id,
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001268 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
1269 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
1270 /* perform following steps for first new peer ind */
1271 if (ndp_ctx->active_ndp_peers == 1) {
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07001272 hdd_conn_set_connection_state(adapter,
1273 eConnectionState_NdiConnected);
Kapil Guptaffa26022017-08-16 12:20:09 +05301274 hdd_wmm_connect(adapter, roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001275 wlan_hdd_netif_queue_control(adapter,
1276 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001277 }
Kapil Guptaffa26022017-08-16 12:20:09 +05301278free:
1279 qdf_mem_free(roam_info);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001280 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001281}
1282
1283/**
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001284 * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001285 * @adapter: pointer to adapter context
1286 * @ind_params: indication parameters
1287 *
1288 * Return: none
1289 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001290static void hdd_ndp_peer_departed_ind_handler(struct hdd_adapter *adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001291 void *ind_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001292{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001293 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001294 struct sme_ndp_peer_ind *peer_ind = ind_params;
1295 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07001296 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001297
1298 hdd_roam_deregister_sta(adapter, peer_ind->sta_id);
1299 hdd_delete_peer(sta_ctx, peer_ind->sta_id);
1300 hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
1301
1302 if (--ndp_ctx->active_ndp_peers == 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001303 hdd_info("No more ndp peers.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001304 hdd_conn_set_connection_state(adapter,
1305 eConnectionState_NdiDisconnected);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001306 hdd_info("Stop netif tx queues.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001307 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
1308 WLAN_CONTROL_PATH);
1309 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001310}
1311
1312/**
1313 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1314 * @adapter: pointer to adapter context
1315 * @ind_params: indication parameters
1316 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001317 * Following vendor event is sent to cfg80211:
1318 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1319 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1320 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1321 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1322 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1323 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1324 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1325 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1326 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001327 * Return: none
1328 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001329static void hdd_ndp_confirm_ind_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001330 void *ind_params)
1331{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001332 int idx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001333 uint32_t ndp_qos_config = 0;
1334 struct ndp_confirm_event *ndp_confirm = ind_params;
1335 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001336 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001337 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07001338 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001339 uint32_t data_len;
1340
1341 ENTER();
1342 if (!ndp_confirm) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001343 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001344 return;
1345 }
1346
1347 if (0 != wlan_hdd_validate_context(hdd_ctx))
1348 return;
1349
Naveen Rawatf28315c2016-06-29 18:06:02 -07001350 /* ndp_confirm is called each time user generated ndp req succeeds */
1351 idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
1352 if (idx == INVALID_PEER_IDX)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001353 hdd_err("can't find addr: %pM in vdev_id: %d, peer table.",
Jeff Johnson1b780e42017-10-31 14:11:45 -07001354 &ndp_confirm->peer_ndi_mac_addr, adapter->session_id);
Naveen Rawat460be782016-06-29 18:26:22 -07001355 else if (ndp_confirm->rsp_code == NDP_RESPONSE_ACCEPT)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001356 ndp_ctx->active_ndp_sessions[idx]++;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001357
1358 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
Naveen Rawat90ae3082016-06-29 18:22:59 -07001359 + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001360 ndp_confirm->ndp_info.ndp_app_info_len;
1361
Naveen Rawat8d63a592016-06-29 18:30:59 -07001362 if (ndp_confirm->ndp_info.ndp_app_info_len)
1363 data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
1364
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001365 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1366 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1367 GFP_KERNEL);
1368 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001369 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001370 return;
1371 }
1372
1373 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1374 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1375 goto ndp_confirm_nla_failed;
1376
1377 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1378 ndp_confirm->ndp_instance_id))
1379 goto ndp_confirm_nla_failed;
1380
1381 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1382 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1383 goto ndp_confirm_nla_failed;
1384
1385 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1386 IFNAMSIZ, adapter->dev->name))
1387 goto ndp_confirm_nla_failed;
1388
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001389 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001390 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1391 ndp_confirm->ndp_info.ndp_app_info_len,
1392 ndp_confirm->ndp_info.ndp_app_info))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001393 goto ndp_confirm_nla_failed;
1394
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001395 if (nla_put_u32(vendor_event,
1396 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1397 ndp_confirm->rsp_code))
1398 goto ndp_confirm_nla_failed;
1399
Naveen Rawat8d63a592016-06-29 18:30:59 -07001400 if (nla_put_u32(vendor_event,
1401 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1402 ndp_confirm->reason_code))
1403 goto ndp_confirm_nla_failed;
1404
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001405 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001406 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 -07001407 ndp_confirm->ndp_instance_id,
1408 ndp_confirm->peer_ndi_mac_addr.bytes,
Naveen Rawat460be782016-06-29 18:26:22 -07001409 ndp_qos_config, ndp_confirm->rsp_code,
1410 ndp_confirm->reason_code);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001411
Naveen Rawatba4f6612016-07-05 12:03:16 -07001412 hdd_info("NDP confim, ndp app info dump");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001413 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1414 ndp_confirm->ndp_info.ndp_app_info,
1415 ndp_confirm->ndp_info.ndp_app_info_len);
1416 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001417 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001418ndp_confirm_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001419 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001420 kfree_skb(vendor_event);
1421 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001422}
1423
1424/**
1425 * hdd_ndp_indication_handler() - NDP indication handler
1426 * @adapter: pointer to adapter context
1427 * @ind_params: indication parameters
1428 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001429 * Following vendor event is sent to cfg80211:
1430 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1431 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1432 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
Naveen Rawat19da3d12016-08-16 12:39:38 -07001433 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001434 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1435 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1436 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1437 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1438 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001439 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes)
1440 * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001441 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001442 * Return: none
1443 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001444static void hdd_ndp_indication_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001445 void *ind_params)
1446{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001447 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001448 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001449 struct ndp_indication_event *event = ind_params;
1450 uint32_t ndp_qos_config;
1451 struct nan_datapath_ctx *ndp_ctx;
1452 uint16_t data_len;
1453
1454 ENTER();
1455 if (!ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001456 hdd_err("Invalid NDP Indication");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001457 return;
1458 }
1459
1460 if (0 != wlan_hdd_validate_context(hdd_ctx))
1461 return;
1462
1463 /* Handle only if adapter is in NDI mode */
1464 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001465 hdd_err("Adapter is not in NDI mode");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001466 return;
1467 }
1468
Naveen Rawatba4f6612016-07-05 12:03:16 -07001469 hdd_info("NDP Indication, policy: %d", event->policy);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001470
1471 /* Policy check */
1472 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001473 hdd_err("NAN datapath is not suported");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001474 return;
1475 }
1476
1477 /* NAN data path coexists only with STA interface */
1478 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001479 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001480 return;
1481 }
1482
1483 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1484
1485 /* check if we are in middle of deleting/creating the interface */
1486 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
1487 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
1488 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001489 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001490 ndp_ctx->state);
1491 return;
1492 }
1493
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001494 data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
1495 event->ndp_info.ndp_app_info_len + event->scid.scid_len +
1496 (10 * NLA_HDRLEN) + NLMSG_HDRLEN;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001497
1498 /* notify response to the upper layer */
1499 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1500 NULL, data_len,
1501 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1502 GFP_KERNEL);
1503 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001504 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001505 return;
1506 }
1507
1508 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1509 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1510 goto ndp_indication_nla_failed;
1511
1512 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1513 IFNAMSIZ, adapter->dev->name))
1514 goto ndp_indication_nla_failed;
1515
Naveen Rawat19da3d12016-08-16 12:39:38 -07001516 if (nla_put_u32(vendor_event,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001517 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1518 event->service_instance_id))
1519 goto ndp_indication_nla_failed;
1520
1521 if (nla_put(vendor_event,
1522 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1523 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1524 goto ndp_indication_nla_failed;
1525
1526 if (nla_put(vendor_event,
Jeff Johnson03294f12016-12-09 17:10:24 -08001527 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001528 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1529 goto ndp_indication_nla_failed;
1530
1531 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1532 event->ndp_instance_id))
1533 goto ndp_indication_nla_failed;
1534
1535 if (event->ndp_info.ndp_app_info_len)
1536 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1537 event->ndp_info.ndp_app_info_len,
1538 event->ndp_info.ndp_app_info))
1539 goto ndp_indication_nla_failed;
1540
1541 if (event->ndp_config.ndp_cfg_len) {
1542 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1543 /* at present ndp config stores 4 bytes QOS info only */
1544 if (nla_put_u32(vendor_event,
1545 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1546 ndp_qos_config))
1547 goto ndp_indication_nla_failed;
1548 }
1549
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001550 if (event->scid.scid_len) {
1551 if (nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE,
1553 event->ncs_sk_type))
1554 goto ndp_indication_nla_failed;
1555
1556 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
1557 event->scid.scid_len,
1558 event->scid.scid))
1559 goto ndp_indication_nla_failed;
1560
1561 hdd_info("csid: %d, scid_len: %d",
1562 event->ncs_sk_type, event->scid.scid_len);
1563
1564 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1565 event->scid.scid, event->scid.scid_len);
1566 }
1567
Abhishek Singh4fef7472016-06-06 11:36:03 -07001568 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1569 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001570 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001571ndp_indication_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001572 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001573 kfree_skb(vendor_event);
1574 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001575}
1576
1577/**
1578 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1579 * @adapter: pointer to adapter context
1580 * @rsp_params: response parameters
1581 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001582 * Following vendor event is sent to cfg80211:
1583 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1584 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1585 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001586 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1587 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001588 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001589 * Return: none
1590 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001591static void hdd_ndp_responder_rsp_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001592 void *rsp_params)
1593{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001594 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001595 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001596 struct ndp_responder_rsp_event *rsp = rsp_params;
1597 uint16_t data_len;
1598
1599 ENTER();
1600 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001601 hdd_err("Invalid NDP Responder response");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001602 return;
1603 }
1604
1605 if (0 != wlan_hdd_validate_context(hdd_ctx))
1606 return;
1607
Naveen Rawatba4f6612016-07-05 12:03:16 -07001608 hdd_info("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001609 rsp->vdev_id, rsp->transaction_id,
1610 rsp->status, rsp->reason);
1611
1612 data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
1613 4 * NLA_HDRLEN + NLMSG_HDRLEN;
1614 /* notify response to the upper layer */
1615 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1616 NULL, data_len,
1617 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1618 GFP_KERNEL);
1619 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001620 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001621 return;
1622 }
1623
1624 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1625 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1626 goto ndp_responder_rsp_nla_failed;
1627
1628 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1629 rsp->transaction_id))
1630 goto ndp_responder_rsp_nla_failed;
1631
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001632 if (nla_put_u32(vendor_event,
1633 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001634 rsp->status))
1635 goto ndp_responder_rsp_nla_failed;
1636
1637 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001638 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001639 rsp->reason))
1640 goto ndp_responder_rsp_nla_failed;
1641
1642 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1643 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001644 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001645ndp_responder_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001646 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001647 kfree_skb(vendor_event);
1648 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001649}
1650
1651/**
1652 * hdd_ndp_end_rsp_handler() - NDP end response handler
1653 * @adapter: pointer to adapter context
1654 * @rsp_params: response parameters
1655 *
Naveen Rawatf28315c2016-06-29 18:06:02 -07001656 * Following vendor event is sent to cfg80211:
1657 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1658 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001659 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001660 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1661 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1662 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001663 * Return: none
1664 */
Jeff Johnson11b4c322017-10-06 11:48:23 -07001665static void hdd_ndp_end_rsp_handler(struct hdd_adapter *adapter,
1666 void *rsp_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001667{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001668 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001669 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Naveen Rawatf28315c2016-06-29 18:06:02 -07001670 struct ndp_end_rsp_event *rsp = rsp_params;
Rakesh Sunkiae936b62016-07-28 16:01:45 -07001671 uint32_t data_len;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001672
1673 ENTER();
1674
1675 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001676 hdd_err("Invalid ndp end response");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001677 return;
1678 }
1679
1680 if (0 != wlan_hdd_validate_context(hdd_ctx))
1681 return;
1682
Naveen Rawatf28315c2016-06-29 18:06:02 -07001683 data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
1684 sizeof(uint16_t);
1685
1686 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1687 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1688 GFP_KERNEL);
1689 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001690 hdd_err("cfg80211_vendor_event_alloc failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001691 return;
1692 }
1693
1694 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1695 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1696 goto ndp_end_rsp_nla_failed;
1697
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001698 if (nla_put_u32(vendor_event,
1699 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001700 rsp->status))
1701 goto ndp_end_rsp_nla_failed;
1702
1703 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1704 rsp->reason))
1705 goto ndp_end_rsp_nla_failed;
1706
1707 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1708 rsp->transaction_id))
1709 goto ndp_end_rsp_nla_failed;
1710
Naveen Rawatba4f6612016-07-05 12:03:16 -07001711 hdd_info("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001712 rsp->transaction_id, rsp->status, rsp->reason);
1713 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1714 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001715 return;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001716
1717ndp_end_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001718 hdd_err("nla_put api failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001719 kfree_skb(vendor_event);
1720 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001721}
1722
1723/**
1724 * hdd_ndp_end_ind_handler() - NDP end indication handler
1725 * @adapter: pointer to adapter context
1726 * @ind_params: indication parameters
1727 *
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001728 * Following vendor event is sent to cfg80211:
1729 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1730 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001731 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1732 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001733 * Return: none
1734 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001735static void hdd_ndp_end_ind_handler(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001736 void *ind_params)
1737{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001738 struct sk_buff *vendor_event;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001739 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001740 struct ndp_end_indication_event *end_ind = ind_params;
1741 uint32_t data_len, i;
1742 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07001743 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001744 uint32_t *ndp_instance_array;
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001745 struct hdd_adapter *ndi_adapter;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001746
1747 ENTER();
1748
1749 if (!end_ind) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001750 hdd_err("Invalid ndp end indication");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001751 return;
1752 }
1753
1754 if (0 != wlan_hdd_validate_context(hdd_ctx))
1755 return;
1756
1757 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1758 sizeof(*ndp_instance_array));
1759 if (!ndp_instance_array) {
1760 hdd_err("Failed to allocate ndp_instance_array");
1761 return;
1762 }
1763 for (i = 0; i < end_ind->num_ndp_ids; i++) {
1764 int idx;
1765
1766 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
Naveen Rawate21103f2016-07-08 14:18:00 -07001767 ndi_adapter = hdd_get_adapter_by_vdev(hdd_ctx,
1768 end_ind->ndp_map[i].vdev_id);
1769 if (ndi_adapter == NULL) {
1770 hdd_err("Adapter not found for vdev_id: %d",
1771 end_ind->ndp_map[i].vdev_id);
1772 continue;
1773 }
1774 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
Govind Singhb8475942016-08-12 11:07:09 +05301775 if (!ndp_ctx) {
1776 hdd_err("ndp_ctx is NULL for vdev id: %d",
1777 end_ind->ndp_map[i].vdev_id);
1778 continue;
1779 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001780 idx = hdd_get_peer_idx(sta_ctx,
1781 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1782 if (idx == INVALID_PEER_IDX) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001783 hdd_err("can't find addr: %pM in sta_ctx.",
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001784 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1785 continue;
1786 }
1787 /* save the value of active sessions on each peer */
1788 ndp_ctx->active_ndp_sessions[idx] =
1789 end_ind->ndp_map[i].num_active_ndp_sessions;
1790 }
1791
Naveen Rawat90ae3082016-06-29 18:22:59 -07001792 data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001793 end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
1794
1795 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1796 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1797 GFP_KERNEL);
1798 if (!vendor_event) {
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05301799 qdf_mem_free(ndp_instance_array);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001800 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001801 return;
1802 }
1803
1804 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1805 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1806 goto ndp_end_ind_nla_failed;
1807
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001808 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1809 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1810 ndp_instance_array))
1811 goto ndp_end_ind_nla_failed;
1812
1813 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1814 qdf_mem_free(ndp_instance_array);
1815 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001816 return;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001817
1818ndp_end_ind_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001819 hdd_err("nla_put api failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001820 kfree_skb(vendor_event);
1821 qdf_mem_free(ndp_instance_array);
1822 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001823}
1824
1825/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001826 * hdd_ndp_event_handler() - ndp response and indication handler
1827 * @adapter: adapter context
1828 * @roam_info: pointer to roam_info structure
1829 * @roam_id: roam id as indicated by SME
1830 * @roam_status: roam status
1831 * @roam_result: roam result
1832 *
1833 * Return: none
1834 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001835void hdd_ndp_event_handler(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -08001836 struct csr_roam_info *roam_info,
1837 uint32_t roam_id, eRoamCmdStatus roam_status,
1838 eCsrRoamResult roam_result)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001839{
1840 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1841 switch (roam_result) {
Naveen Rawat8d63a592016-06-29 18:30:59 -07001842 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001843 hdd_ndp_iface_create_rsp_handler(adapter,
1844 &roam_info->ndp.ndi_create_params);
1845 break;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001846 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001847 hdd_ndp_iface_delete_rsp_handler(adapter,
1848 &roam_info->ndp.ndi_delete_params);
1849 break;
1850 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1851 hdd_ndp_initiator_rsp_handler(adapter,
1852 &roam_info->ndp.ndp_init_rsp_params);
1853 break;
1854 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1855 hdd_ndp_new_peer_ind_handler(adapter,
1856 &roam_info->ndp.ndp_peer_ind_params);
1857 break;
1858 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1859 hdd_ndp_confirm_ind_handler(adapter,
1860 &roam_info->ndp.ndp_confirm_params);
1861 break;
1862 case eCSR_ROAM_RESULT_NDP_INDICATION:
1863 hdd_ndp_indication_handler(adapter,
1864 &roam_info->ndp.ndp_indication_params);
1865 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001866 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1867 hdd_ndp_responder_rsp_handler(adapter,
1868 &roam_info->ndp.ndp_responder_rsp_params);
1869 break;
1870 case eCSR_ROAM_RESULT_NDP_END_RSP:
1871 hdd_ndp_end_rsp_handler(adapter,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001872 roam_info->ndp.ndp_end_rsp_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001873 break;
1874 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1875 hdd_ndp_peer_departed_ind_handler(adapter,
1876 &roam_info->ndp.ndp_peer_ind_params);
1877 break;
1878 case eCSR_ROAM_RESULT_NDP_END_IND:
1879 hdd_ndp_end_ind_handler(adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001880 roam_info->ndp.ndp_end_ind_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001881 break;
1882 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001883 hdd_err("Unknown NDP response event from SME %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001884 roam_result);
1885 break;
1886 }
1887 }
1888}
Naveen Rawat97500352017-03-22 10:07:58 -07001889#else
Jeff Johnson8cb9df12017-08-29 14:28:45 -07001890void hdd_ndp_event_handler(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -08001891 struct csr_roam_info *roam_info,
1892 uint32_t roam_id, eRoamCmdStatus roam_status,
1893 eCsrRoamResult roam_result)
Naveen Rawat97500352017-03-22 10:07:58 -07001894{
Naveen Rawatcb5c5402017-03-22 10:12:19 -07001895 bool success;
1896 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(adapter->hdd_vdev);
1897
1898 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1899 switch (roam_result) {
1900 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
1901 success = (roam_info->ndp.ndi_create_params.status ==
1902 NAN_DATAPATH_RSP_STATUS_SUCCESS);
1903 hdd_debug("posting ndi create status: %d to umac",
1904 success);
Jeff Johnson1b780e42017-10-31 14:11:45 -07001905 os_if_nan_post_ndi_create_rsp(psoc, adapter->session_id,
Naveen Rawatcb5c5402017-03-22 10:12:19 -07001906 success);
1907 return;
1908 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
1909 success = (roam_info->ndp.ndi_create_params.status ==
1910 NAN_DATAPATH_RSP_STATUS_SUCCESS);
1911 hdd_debug("posting ndi delete status: %d to umac",
1912 success);
Jeff Johnson1b780e42017-10-31 14:11:45 -07001913 os_if_nan_post_ndi_delete_rsp(psoc, adapter->session_id,
Naveen Rawatcb5c5402017-03-22 10:12:19 -07001914 success);
1915 return;
1916 default:
1917 hdd_err("in correct roam_result: %d", roam_result);
1918 return;
1919 }
1920 } else {
1921 hdd_err("in correct roam_status: %d", roam_status);
1922 return;
1923 }
Naveen Rawat97500352017-03-22 10:07:58 -07001924}
1925#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001926
1927/**
1928 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1929 * @wiphy: pointer to wireless wiphy structure.
1930 * @wdev: pointer to wireless_dev structure.
1931 * @data: Pointer to the data to be passed via vendor interface
1932 * @data_len:Length of the data to be passed
1933 *
1934 * This function is invoked to handle vendor command
1935 *
1936 * Return: 0 on success, negative errno on failure
1937 */
Naveen Rawat63de5422017-03-22 11:03:56 -07001938#ifdef WLAN_FEATURE_NAN_CONVERGENCE
1939static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1940 struct wireless_dev *wdev, const void *data, int data_len)
1941{
1942 int ret_val;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001943 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Naveen Rawat63de5422017-03-22 11:03:56 -07001944
1945 ENTER();
1946
1947 ret_val = wlan_hdd_validate_context(hdd_ctx);
1948 if (ret_val)
1949 return ret_val;
1950
1951 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1952 hdd_err("Command not allowed in FTM mode");
1953 return -EPERM;
1954 }
1955
1956 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
1957 hdd_err("NAN datapath is not enabled");
1958 return -EPERM;
1959 }
1960 /* NAN data path coexists only with STA interface */
1961 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
1962 hdd_err("Unsupported concurrency for NAN datapath");
1963 return -EPERM;
1964 }
1965
1966 /* NAN data path coexists only with STA interface */
1967 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
1968 hdd_err("Unsupported concurrency for NAN datapath");
1969 return -EPERM;
1970 }
1971
1972 return os_if_nan_process_ndp_cmd(hdd_ctx->hdd_psoc,
1973 data, data_len);
1974}
1975#else
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001976static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1977 struct wireless_dev *wdev, const void *data, int data_len)
1978{
1979 uint32_t ndp_cmd_type;
1980 uint16_t transaction_id;
1981 int ret_val;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07001982 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001983 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1984 char *iface_name;
1985
1986 ENTER();
1987
1988 ret_val = wlan_hdd_validate_context(hdd_ctx);
1989 if (ret_val)
1990 return ret_val;
1991
1992 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001993 hdd_err("Command not allowed in FTM mode");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001994 return -EPERM;
1995 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07001996 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001997 hdd_err("NAN datapath is not enabled");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001998 return -EPERM;
1999 }
Dustin Brown3fb15042017-08-15 15:54:49 -07002000 if (hdd_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
2001 data, data_len, qca_wlan_vendor_ndp_policy)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002002 hdd_err("Invalid NDP vendor command attributes");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002003 return -EINVAL;
2004 }
2005
2006 /* Parse and fetch NDP Command Type*/
2007 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002008 hdd_err("NAN datapath cmd type failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002009 return -EINVAL;
2010 }
2011 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
2012
2013 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002014 hdd_err("attr transaction id failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002015 return -EINVAL;
2016 }
2017 transaction_id = nla_get_u16(
2018 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
2019
Naveen Rawatf28315c2016-06-29 18:06:02 -07002020 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
2021 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002022 hdd_debug("Transaction Id: %d NDP Cmd: %d iface_name: %s",
Naveen Rawatf28315c2016-06-29 18:06:02 -07002023 transaction_id, ndp_cmd_type, iface_name);
2024 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002025 hdd_debug("Transaction Id: %d NDP Cmd: %d iface_name: unspecified",
Naveen Rawatf28315c2016-06-29 18:06:02 -07002026 transaction_id, ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002027 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002028
2029 switch (ndp_cmd_type) {
2030 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
2031 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
2032 break;
2033 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
2034 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
2035 break;
2036 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
2037 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
2038 break;
2039 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
2040 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
2041 break;
2042 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
2043 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
2044 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002045 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07002046 hdd_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002047 ret_val = -EINVAL;
2048 break;
2049 }
2050
2051 return ret_val;
2052}
Naveen Rawat63de5422017-03-22 11:03:56 -07002053#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002054
2055/**
2056 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
2057 * @wiphy: pointer to wireless wiphy structure.
2058 * @wdev: pointer to wireless_dev structure.
2059 * @data: Pointer to the data to be passed via vendor interface
2060 * @data_len:Length of the data to be passed
2061 *
2062 * This function is called to send a NAN request to
2063 * firmware. This is an SSR-protected wrapper function.
2064 *
2065 * Return: 0 on success, negative errno on failure
2066 */
2067int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
2068 struct wireless_dev *wdev, const void *data, int data_len)
2069{
2070 int ret;
2071
2072 cds_ssr_protect(__func__);
2073 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
2074 cds_ssr_unprotect(__func__);
2075
2076 return ret;
2077}
2078
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002079#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Jeff Johnson85b5c112017-08-11 15:15:23 -07002080static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002081{
2082 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
2083
2084 ndp_ctx->state = state;
2085 return 0;
2086}
2087#else
Jeff Johnson85b5c112017-08-11 15:15:23 -07002088static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002089{
2090 return os_if_nan_set_ndi_state(adapter->hdd_vdev, state);
2091}
2092#endif
2093
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002094/**
2095 * hdd_init_nan_data_mode() - initialize nan data mode
2096 * @adapter: adapter context
2097 *
2098 * Returns: 0 on success negative error code on error
2099 */
Jeff Johnson85b5c112017-08-11 15:15:23 -07002100int hdd_init_nan_data_mode(struct hdd_adapter *adapter)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002101{
2102 struct net_device *wlan_dev = adapter->dev;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002103 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002104 QDF_STATUS status;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002105 int32_t ret_val = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002106
Krunal Sonib51eec72017-11-20 21:53:01 -08002107 ret_val = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07002108 if (ret_val) {
2109 hdd_err("failed to create vdev: %d", ret_val);
2110 return ret_val;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002111 }
2112
Ravi Joshi8eb65f92017-07-20 16:30:19 -07002113 /* Configure self HT/VHT capabilities */
2114 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
2115 sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
Jeff Johnson1b780e42017-10-31 14:11:45 -07002116 sme_set_vdev_ies_per_band(hdd_ctx->hHal, adapter->session_id);
Ravi Joshi8eb65f92017-07-20 16:30:19 -07002117
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002118 /* Register wireless extensions */
2119 ret_val = hdd_register_wext(wlan_dev);
2120 if (0 > ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002121 hdd_err("Wext registration failed with status code %d",
2122 ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002123 ret_val = -EAGAIN;
2124 goto error_register_wext;
2125 }
2126
2127 status = hdd_init_tx_rx(adapter);
2128 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002129 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002130 ret_val = -EAGAIN;
2131 goto error_init_txrx;
2132 }
2133
2134 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2135
2136 status = hdd_wmm_adapter_init(adapter);
2137 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002138 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002139 ret_val = -EAGAIN;
2140 goto error_wmm_init;
2141 }
2142
2143 set_bit(WMM_INIT_DONE, &adapter->event_flags);
2144
Jeff Johnson1b780e42017-10-31 14:11:45 -07002145 ret_val = wma_cli_set_command((int)adapter->session_id,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002146 (int)WMI_PDEV_PARAM_BURST_ENABLE,
2147 (int)hdd_ctx->config->enableSifsBurst,
2148 PDEV_CMD);
Arunk Khandavalli15664e42017-06-29 15:56:14 +05302149 if (0 != ret_val)
Naveen Rawatba4f6612016-07-05 12:03:16 -07002150 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Arunk Khandavalli15664e42017-06-29 15:56:14 +05302151
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002152
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002153 update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002154 return ret_val;
2155
2156error_wmm_init:
2157 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2158 hdd_deinit_tx_rx(adapter);
2159
2160error_init_txrx:
2161 hdd_unregister_wext(wlan_dev);
2162
2163error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07002164 QDF_BUG(!hdd_vdev_destroy(adapter));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002165
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002166 return ret_val;
2167}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002168
2169#ifdef WLAN_FEATURE_NAN_CONVERGENCE
2170struct wlan_objmgr_vdev *hdd_ndi_open(char *iface_name)
2171{
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002172 struct hdd_adapter *adapter;
Ravi Joshi9771d432017-06-26 13:58:12 -07002173 struct qdf_mac_addr random_ndi_mac;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002174 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Ravi Joshi9771d432017-06-26 13:58:12 -07002175 uint8_t *ndi_mac_addr;
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002176
2177 ENTER();
Naveen Rawat5a6f8402017-07-03 16:00:11 -07002178
Ravi Joshi9771d432017-06-26 13:58:12 -07002179 if (hdd_ctx->config->is_ndi_mac_randomized) {
2180 if (hdd_get_random_nan_mac_addr(hdd_ctx, &random_ndi_mac)) {
2181 hdd_err("get random mac address failed");
2182 return NULL;
2183 }
2184 ndi_mac_addr = &random_ndi_mac.bytes[0];
2185 } else {
2186 ndi_mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
2187 if (!ndi_mac_addr) {
2188 hdd_err("get intf address failed");
2189 return NULL;
2190 }
Naveen Rawat5a6f8402017-07-03 16:00:11 -07002191 }
2192
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002193 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
Ravi Joshi9771d432017-06-26 13:58:12 -07002194 ndi_mac_addr, NET_NAME_UNKNOWN, true);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002195 if (!adapter) {
2196 hdd_err("hdd_open_adapter failed");
2197 return NULL;
2198 }
2199
2200 EXIT();
2201 return adapter->hdd_vdev;
2202}
2203
2204int hdd_ndi_start(uint8_t vdev_id)
2205{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002206 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002207 uint8_t op_channel = hdd_ctx->config->nan_datapath_ndi_channel;
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002208 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002209
2210 ENTER();
2211 /*
2212 * The NAN data interface has been created at this point.
2213 * Unlike traditional device modes, where the higher application
2214 * layer initiates connect / join / start, the NAN data
2215 * interface does not have any such formal requests. The NDI
2216 * create request is responsible for starting the BSS as well.
2217 */
2218 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
2219 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
2220 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
2221 /* start NDI on the default 2.4 GHz social channel */
2222 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
2223 }
2224 if (hdd_ndi_start_bss(adapter, op_channel)) {
2225 hdd_err("NDI start bss failed");
2226 /* Start BSS failed, delete the interface */
2227 hdd_close_ndi(adapter);
2228 EXIT();
2229 return -EINVAL;
2230 }
2231
2232 return 0;
2233}
2234
2235int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id)
2236{
2237 int ret;
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002238 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002239 struct hdd_station_ctx *sta_ctx;
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002240 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002241
Naveen Rawatc4b045c2017-06-30 16:11:42 -07002242 /* check if adapter by vdev_id is valid NDI */
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002243 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2244 if (!adapter || !WLAN_HDD_IS_NDI(adapter)) {
2245 hdd_err("NAN data interface %s is not available", iface_name);
2246 return -EINVAL;
2247 }
2248
2249 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2250 if (!sta_ctx) {
2251 hdd_err("sta_ctx is NULL");
2252 return -EINVAL;
2253 }
2254
2255 /* Since, the interface is being deleted, remove the broadcast id. */
2256 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
2257 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
2258
2259 os_if_nan_set_ndp_delete_transaction_id(adapter->hdd_vdev,
2260 transaction_id);
2261 os_if_nan_set_ndi_state(adapter->hdd_vdev, NAN_DATA_NDI_DELETING_STATE);
2262
2263 /* Delete the interface */
2264 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
2265 if (ret)
2266 hdd_err("NDI delete request failed");
2267 else
2268 hdd_err("NDI delete request successfully issued");
2269
2270 return ret;
2271}
2272
2273void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id,
2274 struct nan_datapath_inf_create_rsp *ndi_rsp)
2275{
Jeff Johnson172237b2017-11-07 15:32:59 -08002276 struct csr_roam_info roam_info = {0};
Jeff Johnson4ba73cb2017-10-06 11:12:33 -07002277 struct bss_description tmp_bss_descp = {0};
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002278 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002279 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002280 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002281 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002282
2283 if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
2284 hdd_alert("NDI interface successfully created");
2285 os_if_nan_set_ndp_create_transaction_id(adapter->hdd_vdev, 0);
2286 os_if_nan_set_ndi_state(adapter->hdd_vdev,
2287 NAN_DATA_NDI_CREATED_STATE);
2288 wlan_hdd_netif_queue_control(adapter,
2289 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2290 WLAN_CONTROL_PATH);
2291 } else {
2292 hdd_alert("NDI interface creation failed with reason %d",
2293 ndi_rsp->reason /* create_reason */);
2294 }
2295
2296 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
2297 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
2298 hdd_roam_register_sta(adapter, &roam_info,
2299 sta_ctx->broadcast_staid,
2300 &bc_mac_addr, &tmp_bss_descp);
Naveen Rawatb7be1ed2017-11-16 16:52:08 -08002301 if (hdd_objmgr_add_peer_object(adapter->hdd_vdev,
2302 QDF_NDI_MODE, bc_mac_addr.bytes, false))
2303 hdd_err("Peer object "MAC_ADDRESS_STR" add fails!",
2304 MAC_ADDR_ARRAY(bc_mac_addr.bytes));
2305
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002306 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
2307}
2308
2309void hdd_ndi_close(uint8_t vdev_id)
2310{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002311 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002312 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002313
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002314 hdd_close_ndi(adapter);
2315}
2316
2317void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id)
2318{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002319 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002320 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Naveen Rawatb7be1ed2017-11-16 16:52:08 -08002321 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2322
2323 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = NULL;
2324 hdd_roam_deregister_sta(adapter, sta_ctx->broadcast_staid);
2325 hdd_delete_peer(sta_ctx, sta_ctx->broadcast_staid);
2326 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002327
2328 wlan_hdd_netif_queue_control(adapter,
2329 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
2330 WLAN_CONTROL_PATH);
2331
2332 complete(&adapter->disconnect_comp_var);
2333}
2334
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002335void hdd_ndp_session_end_handler(struct hdd_adapter *adapter)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002336{
2337 os_if_nan_ndi_session_end(adapter->hdd_vdev);
2338}
2339
Naveen Rawat37f62c82017-03-26 22:24:43 -07002340int hdd_ndp_get_peer_idx(uint8_t vdev_id, struct qdf_mac_addr *addr)
2341{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002342 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002343 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002344 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002345
Naveen Rawat37f62c82017-03-26 22:24:43 -07002346 return hdd_get_peer_idx(sta_ctx, addr);
2347}
2348
2349/**
2350 * hdd_ndp_new_peer_handler() - NDP new peer indication handler
2351 * @adapter: pointer to adapter context
2352 * @ind_params: indication parameters
2353 *
2354 * Return: none
2355 */
2356int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id,
2357 struct qdf_mac_addr *peer_mac_addr, bool fist_peer)
2358{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002359 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002360 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson4ba73cb2017-10-06 11:12:33 -07002361 struct bss_description tmp_bss_descp = {0};
Jeff Johnson172237b2017-11-07 15:32:59 -08002362 struct csr_roam_info roam_info = {0};
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002363 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Naveen Rawat37f62c82017-03-26 22:24:43 -07002364
2365 ENTER();
2366 /* save peer in ndp ctx */
2367 if (false == hdd_save_peer(sta_ctx, sta_id, peer_mac_addr)) {
2368 hdd_err("Ndp peer table full. cannot save new peer");
2369 return -EPERM;
2370 }
2371
2372 /* this function is called for each new peer */
2373 hdd_roam_register_sta(adapter, &roam_info, sta_id,
2374 peer_mac_addr, &tmp_bss_descp);
Naveen Rawatb7be1ed2017-11-16 16:52:08 -08002375 if (hdd_objmgr_add_peer_object(adapter->hdd_vdev,
2376 QDF_NDI_MODE, peer_mac_addr->bytes, false))
2377 hdd_err("Peer object "MAC_ADDRESS_STR" add fails!",
2378 MAC_ADDR_ARRAY(peer_mac_addr->bytes));
Naveen Rawat37f62c82017-03-26 22:24:43 -07002379 hdd_ctx->sta_to_adapter[sta_id] = adapter;
2380 /* perform following steps for first new peer ind */
2381 if (fist_peer) {
2382 hdd_info("Set ctx connection state to connected");
2383 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
2384 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
2385 wlan_hdd_netif_queue_control(adapter,
2386 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
2387 }
2388 EXIT();
2389 return 0;
2390}
2391
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002392
2393/**
2394 * hdd_ndp_peer_departed_handler() - Handle NDP peer departed indication
2395 * @adapter: pointer to adapter context
2396 * @ind_params: indication parameters
2397 *
2398 * Return: none
2399 */
2400void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id,
2401 struct qdf_mac_addr *peer_mac_addr, bool last_peer)
2402{
Jeff Johnson88dc4f92017-08-28 11:51:34 -07002403 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -07002404 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002405 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002406
2407 ENTER();
2408 hdd_roam_deregister_sta(adapter, sta_id);
2409 hdd_delete_peer(sta_ctx, sta_id);
2410 hdd_ctx->sta_to_adapter[sta_id] = NULL;
2411
2412 if (last_peer) {
2413 hdd_info("No more ndp peers.");
2414 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
2415 hdd_conn_set_connection_state(adapter,
2416 eConnectionState_NdiDisconnected);
2417 hdd_info("Stop netif tx queues.");
2418 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
2419 WLAN_CONTROL_PATH);
2420 }
2421 EXIT();
2422}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002423#endif