blob: 9f696564551efa47a174d121e6eb82c7dcb7d5f2 [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>
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070038
Naveen Rawat97500352017-03-22 10:07:58 -070039#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070040/* NLA policy */
41static const struct nla_policy
42qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
43 [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 },
44 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 },
45 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_STRING,
46 .len = IFNAMSIZ },
Naveen Rawat19da3d12016-08-16 12:39:38 -070047 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070048 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070049 [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = {
Naveen Rawatf28315c2016-06-29 18:06:02 -070050 .type = NLA_BINARY,
51 .len = QDF_MAC_ADDR_SIZE },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070052 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 },
53 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY,
54 .len = NDP_QOS_INFO_LEN },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070055 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY,
56 .len = NDP_APP_INFO_LEN },
57 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070058 [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070059 [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY,
60 .len = QDF_MAC_ADDR_SIZE },
Naveen Rawatf28315c2016-06-29 18:06:02 -070061 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY,
62 .len = NDP_NUM_INSTANCE_ID },
Naveen Rawat0a017052016-10-19 14:17:07 -070063 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { .type = NLA_U32 },
Naveen Rawat4f3983e2016-11-29 16:12:09 -080064 [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { .type = NLA_U32 },
65 [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { .type = NLA_BINARY,
66 .len = NDP_PMK_LEN },
67 [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { .type = NLA_BINARY,
68 .len = NDP_SCID_BUF_LEN },
Rakesh Sunkid92d1082017-01-04 15:14:28 -080069 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { .type =
70 NLA_U32 },
71 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070072};
Naveen Rawat97500352017-03-22 10:07:58 -070073#endif
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070074
75/**
76 * hdd_ndp_print_ini_config()- Print nan datapath specific INI configuration
77 * @hdd_ctx: handle to hdd context
78 *
79 * Return: None
80 */
81void hdd_ndp_print_ini_config(hdd_context_t *hdd_ctx)
82{
Naveen Rawatba4f6612016-07-05 12:03:16 -070083 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_DATAPATH_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070084 hdd_ctx->config->enable_nan_datapath);
Naveen Rawatba4f6612016-07-05 12:03:16 -070085 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_NDI_CHANNEL_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070086 hdd_ctx->config->nan_datapath_ndi_channel);
87}
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070088
89/**
90 * hdd_nan_datapath_target_config() - Configure NAN datapath features
91 * @hdd_ctx: Pointer to HDD context
92 * @cfg: Pointer to target device capability information
93 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070094 * NAN datapath functionality is enabled if it is enabled in
95 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070096 *
97 * Return: None
98 */
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070099void hdd_nan_datapath_target_config(hdd_context_t *hdd_ctx,
100 struct wma_tgt_cfg *cfg)
101{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -0700102 hdd_ctx->nan_datapath_enabled =
103 hdd_ctx->config->enable_nan_datapath &&
104 cfg->nan_datapath_enabled;
Naveen Rawatba4f6612016-07-05 12:03:16 -0700105 hdd_info("enable_nan_datapath: %d", hdd_ctx->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -0700106}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700107
108/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700109 * hdd_close_ndi() - close NAN Data interface
110 * @adapter: adapter context
111 *
112 * Close the adapter if start BSS fails
113 *
114 * Returns: 0 on success, negative error code otherwise
115 */
116static int hdd_close_ndi(hdd_adapter_t *adapter)
117{
Dustin Brown0d2eeae2017-03-24 15:21:32 -0700118 int errno;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700119 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700120
121 ENTER();
122
123 /* check if the adapter is in NAN Data mode */
124 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700125 hdd_err("Interface is not in NDI mode");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700126 return -EINVAL;
127 }
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700128 wlan_hdd_netif_queue_control(adapter,
129 WLAN_NETIF_TX_DISABLE_N_CARRIER,
130 WLAN_CONTROL_PATH);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700131
132#ifdef WLAN_OPEN_SOURCE
133 cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
134#endif
135 hdd_deregister_tx_flow_control(adapter);
136
137#ifdef WLAN_NS_OFFLOAD
138#ifdef WLAN_OPEN_SOURCE
139 cancel_work_sync(&adapter->ipv6NotifierWorkQueue);
140#endif
141#endif
Dustin Brown0d2eeae2017-03-24 15:21:32 -0700142 errno = hdd_vdev_destroy(adapter);
143 if (errno)
144 hdd_err("failed to destroy vdev: %d", errno);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700145
146 /* We are good to close the adapter */
147 hdd_close_adapter(hdd_ctx, adapter, true);
148
149 EXIT();
150 return 0;
151}
152
153/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700154 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
155 * @hdd_ctx: hdd context
156 *
157 * NDP is not allowed with any other role active except STA.
158 *
159 * Return: true if allowed, false otherwise
160 */
161static bool hdd_is_ndp_allowed(hdd_context_t *hdd_ctx)
162{
163 hdd_adapter_t *adapter;
164 hdd_station_ctx_t *sta_ctx;
165 QDF_STATUS status;
166 hdd_adapter_list_node_t *curr = NULL, *next = NULL;
167
168 status = hdd_get_front_adapter(hdd_ctx, &curr);
169 while (QDF_STATUS_SUCCESS == status) {
170 adapter = curr->pAdapter;
171 if (!adapter)
172 goto next_adapter;
173
174 switch (adapter->device_mode) {
175 case QDF_P2P_GO_MODE:
176 case QDF_SAP_MODE:
177 if (test_bit(SOFTAP_BSS_STARTED,
178 &adapter->event_flags))
179 return false;
180 break;
181 case QDF_P2P_CLIENT_MODE:
182 case QDF_IBSS_MODE:
183 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
184 if (hdd_conn_is_connected(sta_ctx) ||
185 hdd_is_connecting(sta_ctx))
186 return false;
187 break;
188 default:
189 break;
190 }
191next_adapter:
192 status = hdd_get_next_adapter(hdd_ctx, curr, &next);
193 curr = next;
194 }
195
196 return true;
197}
198
199/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700200 * hdd_ndi_start_bss() - Start BSS on NAN data interface
201 * @adapter: adapter context
202 * @operating_channel: channel on which the BSS to be started
203 *
204 * Return: 0 on success, error value on failure
205 */
206static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
207 uint8_t operating_channel)
208{
209 int ret;
210 uint32_t roam_id;
211 hdd_wext_state_t *wext_state =
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -0700212 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700213 tCsrRoamProfile *roam_profile = &wext_state->roamProfile;
214
215 ENTER();
216
217 if (!roam_profile) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700218 hdd_err("No valid roam profile");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700219 return -EINVAL;
220 }
221
222 if (HDD_WMM_USER_MODE_NO_QOS ==
223 (WLAN_HDD_GET_CTX(adapter))->config->WmmMode) {
224 /* QoS not enabled in cfg file*/
225 roam_profile->uapsd_mask = 0;
226 } else {
227 /* QoS enabled, update uapsd mask from cfg file*/
228 roam_profile->uapsd_mask =
229 (WLAN_HDD_GET_CTX(adapter))->config->UapsdMask;
230 }
231
232 roam_profile->csrPersona = adapter->device_mode;
233
234 roam_profile->ChannelInfo.numOfChannels = 1;
235 if (operating_channel) {
236 roam_profile->ChannelInfo.ChannelList = &operating_channel;
237 } else {
238 roam_profile->ChannelInfo.ChannelList[0] =
239 NAN_SOCIAL_CHANNEL_2_4GHZ;
240 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700241
242 roam_profile->SSIDs.numOfSSIDs = 1;
243 roam_profile->SSIDs.SSIDList->SSID.length = 0;
244
245 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
246 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
247 roam_profile->BSSIDs.numOfBSSIDs = 1;
248 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
249 &adapter->macAddressCurrent.bytes[0],
250 QDF_MAC_ADDR_SIZE);
251
252 roam_profile->AuthType.numEntries = 1;
253 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
254 roam_profile->EncryptionType.numEntries = 1;
255 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
256
257 ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
258 adapter->sessionId, roam_profile, &roam_id);
259 if (QDF_STATUS_SUCCESS != ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700260 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
261 adapter->sessionId, ret);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700262 /* change back to NotConnected */
263 hdd_conn_set_connection_state(adapter,
264 eConnectionState_NotConnected);
265 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700266 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700267 }
268
269 roam_profile->ChannelInfo.ChannelList = NULL;
270 roam_profile->ChannelInfo.numOfChannels = 0;
271
272 EXIT();
273
274 return ret;
275}
276
Naveen Rawat97500352017-03-22 10:07:58 -0700277#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700278/**
279 * hdd_ndi_create_req_handler() - NDI create request handler
280 * @hdd_ctx: hdd context
281 * @tb: parsed NL attribute list
282 *
283 * Return: 0 on success or error code on failure
284 */
285static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
286 struct nlattr **tb)
287{
288 hdd_adapter_t *adapter;
289 char *iface_name;
290 uint16_t transaction_id;
291 int ret;
292 struct nan_datapath_ctx *ndp_ctx;
293 uint8_t op_channel =
294 hdd_ctx->config->nan_datapath_ndi_channel;
295
296 ENTER();
297
298 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700299 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700300 return -EINVAL;
301 }
302 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
303
304 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700305 hdd_err("transaction id is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700306 return -EINVAL;
307 }
308 transaction_id =
309 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
310
311 /* Check for an existing interface of NDI type */
312 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
313 if (adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700314 hdd_err("Cannot support more than one NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700315 return -EEXIST;
316 }
317
318 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
319 wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
320 true);
321 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700322 hdd_err("hdd_open_adapter failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700323 return -ENOMEM;
324 }
325
326 /*
327 * Create transaction id is required to be saved since the firmware
328 * does not honor the transaction id for create request
329 */
330 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
331 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700332 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700333
334 /*
335 * The NAN data interface has been created at this point.
336 * Unlike traditional device modes, where the higher application
337 * layer initiates connect / join / start, the NAN data interface
338 * does not have any such formal requests. The NDI create request
339 * is responsible for starting the BSS as well.
340 */
341 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
342 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
343 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
344 /* start NDI on the default 2.4 GHz social channel */
345 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
346 }
347 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700348 if (0 > ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700349 hdd_err("NDI start bss failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700350 /* Start BSS failed, delete the interface */
351 hdd_close_ndi(adapter);
352 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700353
354 EXIT();
355 return ret;
356}
357
358/**
359 * hdd_ndi_delete_req_handler() - NDI delete request handler
360 * @hdd_ctx: hdd context
361 * @tb: parsed NL attribute list
362 *
363 * Return: 0 on success or error code on failure
364 */
365static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
366 struct nlattr **tb)
367{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700368 hdd_adapter_t *adapter;
369 char *iface_name;
370 uint16_t transaction_id;
371 struct nan_datapath_ctx *ndp_ctx;
372 int ret;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700373 hdd_station_ctx_t *sta_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700374
375 ENTER();
376
377 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700378 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700379 return -EINVAL;
380 }
381
382 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
383
384 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700385 hdd_err("Transaction id is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700386 return -EINVAL;
387 }
388
389 transaction_id =
390 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
391
392 /* Check if there is already an existing inteface with the same name */
393 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
394 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700395 hdd_err("NAN data interface %s is not available", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700396 return -EINVAL;
397 }
398
399 /* check if adapter is in NDI mode */
400 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700401 hdd_err("Interface %s is not in NDI mode", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700402 return -EINVAL;
403 }
404
405 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
406 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700407 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700408 return -EINVAL;
409 }
410
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700411 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
412 if (!sta_ctx) {
413 hdd_err("sta_ctx is NULL");
414 return -EINVAL;
415 }
416
Naveen Rawatf28315c2016-06-29 18:06:02 -0700417 /* check if there are active peers on the adapter */
418 if (ndp_ctx->active_ndp_peers > 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700419 hdd_err("NDP peers active: %d, cannot delete NDI",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700420 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700421 return -EINVAL;
422 }
423
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700424 /*
425 * Since, the interface is being deleted, remove the
426 * broadcast id.
427 */
428 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
429 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
430
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700431 ndp_ctx->ndp_delete_transaction_id = transaction_id;
432 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
433
434 /* Delete the interface */
435 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
436 if (ret < 0)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700437 hdd_err("NDI delete request failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700438 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700439 hdd_err("NDI delete request successfully issued");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700440
441 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700442}
443
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700444/**
445 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
446 * @hdd_ctx: hdd context
447 * @tb: parsed NL attribute list
448 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800449 * tb will contain following vendor attributes:
450 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
451 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
452 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
Ravi Joshi71e82f32017-02-09 23:15:16 -0800453 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG - optional
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800454 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
455 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
456 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
457 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
458 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
459 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
460 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700461 * Return: 0 on success or error code on failure
462 */
463static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx,
464 struct nlattr **tb)
465{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700466 hdd_adapter_t *adapter;
467 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700468 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700469 QDF_STATUS status;
470 uint32_t ndp_qos_cfg;
471 tHalHandle hal = hdd_ctx->hHal;
472 struct nan_datapath_ctx *ndp_ctx;
473
474 ENTER();
475
476 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700477 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700478 return -EINVAL;
479 }
480
481 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
482 /* Check for interface in NDI mode */
483 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
484 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700485 hdd_err("NAN data interface %s not available", iface_name);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700486 return -EINVAL;
487 }
488
489 /* NAN data path coexists only with STA interface */
490 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700491 hdd_err("Unsupported concurrency for NAN datapath");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700492 return -EPERM;
493 }
494
495 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
496
497 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
498 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
499 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700500 hdd_err("Data request not allowed in NDI current state: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700501 ndp_ctx->state);
502 return -EINVAL;
503 }
504
505 req.vdev_id = adapter->sessionId;
506
507 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700508 hdd_err("Transaction ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700509 return -EINVAL;
510 }
511 req.transaction_id =
512 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
513
Naveen Rawat0a017052016-10-19 14:17:07 -0700514 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL])
515 req.channel =
516 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
517
Ravi Joshi71e82f32017-02-09 23:15:16 -0800518 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG])
Naveen Rawat0a017052016-10-19 14:17:07 -0700519 req.channel_cfg =
520 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700521
522 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700523 hdd_err("NDP service instance ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700524 return -EINVAL;
525 }
526 req.service_instance_id =
Naveen Rawat19da3d12016-08-16 12:39:38 -0700527 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700528
529 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
530 adapter->macAddressCurrent.bytes, QDF_MAC_ADDR_SIZE);
531
532 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700533 hdd_err("NDI peer discovery mac addr is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700534 return -EINVAL;
535 }
536 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
537 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
538 QDF_MAC_ADDR_SIZE);
539
Naveen Rawat90ae3082016-06-29 18:22:59 -0700540 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
541 req.ndp_info.ndp_app_info_len =
542 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
543 req.ndp_info.ndp_app_info =
544 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700545 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700546
547 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
548 /* at present ndp config stores 4 bytes QOS info only */
549 req.ndp_config.ndp_cfg_len = 4;
550 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
551 ndp_qos_cfg =
552 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
553 }
554
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800555 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
556 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
557 hdd_err("PMK cannot be absent when CSID is present.");
558 return -EINVAL;
559 }
560
561 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
562 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
563 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
564 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
565 QDF_TRACE_LEVEL_DEBUG,
566 req.pmk.pmk, req.pmk.pmk_len);
567 }
568
569 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
570 req.ncs_sk_type =
571 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
572
573 }
574
Ravi Joshi71e82f32017-02-09 23:15:16 -0800575 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",
576 req.vdev_id, req.transaction_id, req.channel, req.channel_cfg,
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700577 req.service_instance_id, req.ndp_info.ndp_app_info_len,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800578 req.ncs_sk_type, req.peer_discovery_mac_addr.bytes);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700579 status = sme_ndp_initiator_req_handler(hal, &req);
580 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700581 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700582 status);
583 return -ECOMM;
584 }
585 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700586 return 0;
587}
588
589/**
590 * hdd_ndp_responder_req_handler() - NDP responder request handler
591 * @hdd_ctx: hdd context
592 * @tb: parsed NL attribute list
593 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800594 * tb includes following vendor attributes:
595 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
596 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
597 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
598 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
599 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
600 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
601 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
602 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
603 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700604 * Return: 0 on success or error code on failure
605 */
606static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx,
607 struct nlattr **tb)
608{
Abhishek Singh4fef7472016-06-06 11:36:03 -0700609 hdd_adapter_t *adapter;
610 char *iface_name;
611 struct ndp_responder_req req = {0};
612 QDF_STATUS status;
613 int ret = 0;
614 struct nan_datapath_ctx *ndp_ctx;
615 uint32_t ndp_qos_cfg;
616
617 ENTER();
618
619 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700620 hdd_err("Interface name string is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700621 return -EINVAL;
622 }
623
624 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
625 /* Check if there is already an existing NAN interface */
626 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
627 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700628 hdd_err("NAN data interface %s not available", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700629 return -EINVAL;
630 }
631
632 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700633 hdd_err("Interface %s not in NDI mode", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700634 return -EINVAL;
635 }
636
637 /* NAN data path coexists only with STA interface */
638 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700639 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700640 return -EINVAL;
641 }
642
643 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
644
645 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
646 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
647 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700648 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700649 ndp_ctx->state);
650 return -EAGAIN;
651 }
652
653 req.vdev_id = adapter->sessionId;
654
655 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700656 hdd_err("Transaction ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700657 return -EINVAL;
658 }
659 req.transaction_id =
660 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
661
662 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700663 hdd_err("Instance ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700664 return -EINVAL;
665 }
666 req.ndp_instance_id =
667 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
668
669 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700670 hdd_err("ndp_rsp is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700671 return -EINVAL;
672 }
673 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
674
675 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
676 req.ndp_info.ndp_app_info_len =
677 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
678 if (req.ndp_info.ndp_app_info_len) {
679 req.ndp_info.ndp_app_info =
680 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
681 }
682 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700683 hdd_info("NDP app info is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700684 }
685 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
686 /* at present ndp config stores 4 bytes QOS info only */
687 req.ndp_config.ndp_cfg_len = 4;
688 ndp_qos_cfg =
689 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
690 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
691 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700692 hdd_info("NDP config data is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700693 }
694
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800695 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
696 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
697 hdd_err("PMK cannot be absent when CSID is present.");
698 return -EINVAL;
699 }
700
701 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
702 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
703 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
704 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
705 QDF_TRACE_LEVEL_DEBUG,
706 req.pmk.pmk, req.pmk.pmk_len);
707 }
708
709 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
710 req.ncs_sk_type =
711 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
712
713 }
714
715 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 -0700716 req.vdev_id, req.transaction_id, req.ndp_rsp,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800717 req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
718 req.ncs_sk_type);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700719
720 status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req);
721 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700722 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700723 status);
724 ret = -EINVAL;
725 }
726
727 EXIT();
728 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700729}
730
731/**
732 * hdd_ndp_end_req_handler() - NDP end request handler
733 * @hdd_ctx: hdd context
734 * @tb: parsed NL attribute list
735 *
736 * Return: 0 on success or error code on failure
737 */
Naveen Rawatf28315c2016-06-29 18:06:02 -0700738static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700739{
Naveen Rawatf28315c2016-06-29 18:06:02 -0700740 struct ndp_end_req req = {0};
741 QDF_STATUS status;
742 tHalHandle hal = hdd_ctx->hHal;
743
744 ENTER();
745
746 /* NAN data path coexists only with STA interface */
747 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700748 hdd_err("Unsupported concurrency for NAN datapath");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700749 return -EINVAL;
750 }
751
752 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700753 hdd_err("Transaction ID is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700754 return -EINVAL;
755 }
756 req.transaction_id =
757 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
758
759 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700760 hdd_err("NDP instance ID array is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700761 return -EINVAL;
762 }
763
764 req.num_ndp_instances =
765 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
766 sizeof(uint32_t);
767 if (0 >= req.num_ndp_instances) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700768 hdd_err("Num NDP instances is 0");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700769 return -EINVAL;
770 }
771 req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
772
Naveen Rawatba4f6612016-07-05 12:03:16 -0700773 hdd_info("sending ndp_end_req to SME, transaction_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700774 req.transaction_id);
775
776 status = sme_ndp_end_req_handler(hal, &req);
777 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700778 hdd_err("sme_ndp_end_req_handler failed, status: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700779 status);
780 return -ECOMM;
781 }
782 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700783 return 0;
784}
785
786/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700787 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
788 * @adapter: pointer to adapter context
789 * @rsp_params: response parameters
790 *
791 * The function is expected to send a response back to the user space
792 * even if the creation of BSS has failed
793 *
794 * Following vendor event is sent to cfg80211:
795 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
796 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
797 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800798 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700799 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
800 *
801 * Return: none
802 */
803static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
804 void *rsp_params)
805{
806 struct sk_buff *vendor_event;
807 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
808 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
809 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
810 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
811 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700812 bool create_fail = false;
813 uint8_t create_transaction_id = 0;
Naveen Rawate21103f2016-07-08 14:18:00 -0700814 uint32_t create_status = NDP_RSP_STATUS_ERROR;
815 uint32_t create_reason = NDP_NAN_DATA_IFACE_CREATE_FAILED;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700816 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
817 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
818 tCsrRoamInfo roam_info = {0};
819 tSirBssDescription tmp_bss_descp = {0};
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700820
821 ENTER();
822
823 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700824 /* No way the driver can send response back to user space */
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700825 return;
826
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700827 if (ndi_rsp) {
828 create_status = ndi_rsp->status;
Naveen Rawate21103f2016-07-08 14:18:00 -0700829 create_reason = ndi_rsp->reason;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700830 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700831 hdd_err("Invalid ndi create response");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700832 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700833 }
834
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700835 if (ndp_ctx) {
836 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
837 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700838 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700839 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700840 }
841
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700842 if (!sta_ctx) {
843 hdd_err("sta_ctx is NULL");
844 create_fail = true;
845 }
846
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700847 /* notify response to the upper layer */
848 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
849 NULL,
850 data_len,
851 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
852 cds_get_gfp_flags());
853
854 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700855 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700856 create_fail = true;
857 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700858 }
859
860 /* Sub vendor command */
861 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
862 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700863 hdd_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700864 goto nla_put_failure;
865 }
866
867 /* Transaction id */
868 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700869 create_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700870 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700871 goto nla_put_failure;
872 }
873
874 /* Status code */
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800875 if (nla_put_u32(vendor_event,
876 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700877 create_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700878 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700879 goto nla_put_failure;
880 }
881
882 /* Status return value */
883 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700884 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawate21103f2016-07-08 14:18:00 -0700885 create_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700886 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700887 goto nla_put_failure;
888 }
889
Naveen Rawatba4f6612016-07-05 12:03:16 -0700890 hdd_info("sub command: %d, value: %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700891 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
892 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700893 hdd_info("create transaction id: %d, value: %d",
894 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
895 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800896 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
897 create_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700898 hdd_info("Return value: %d, value: %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700899 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700900
901 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
902
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700903 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700904 hdd_err("NDI interface successfully created");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700905 ndp_ctx->ndp_create_transaction_id = 0;
906 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700907 wlan_hdd_netif_queue_control(adapter,
908 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
909 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700910 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700911 hdd_err("NDI interface creation failed with reason %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700912 create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700913 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700914
915 /* Something went wrong while starting the BSS */
916 if (create_fail)
917 goto close_ndi;
918
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700919 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
920 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
921 hdd_roam_register_sta(adapter, &roam_info,
922 sta_ctx->broadcast_staid,
923 &bc_mac_addr, &tmp_bss_descp);
924 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
925
926
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700927 EXIT();
928 return;
929
930nla_put_failure:
931 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700932close_ndi:
933 hdd_close_ndi(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700934 return;
935}
936
937/**
938 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
939 * @adapter: pointer to adapter context
940 * @rsp_params: response parameters
941 *
942 * Return: none
943 */
944static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
945 void *rsp_params)
946{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700947 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
948 struct ndi_delete_rsp *ndi_rsp = rsp_params;
Naveen Rawat8d63a592016-06-29 18:30:59 -0700949 struct nan_datapath_ctx *ndp_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700950
951 if (wlan_hdd_validate_context(hdd_ctx))
952 return;
953
954 if (!ndi_rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700955 hdd_err("Invalid ndi delete response");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700956 return;
957 }
958
Naveen Rawat8d63a592016-06-29 18:30:59 -0700959 if (ndi_rsp->status == NDP_RSP_STATUS_SUCCESS)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700960 hdd_err("NDI BSS successfully stopped");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700961 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700962 hdd_err("NDI BSS stop failed with reason %d", ndi_rsp->reason);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700963
964 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
965 ndp_ctx->ndi_delete_rsp_reason = ndi_rsp->reason;
966 ndp_ctx->ndi_delete_rsp_status = ndi_rsp->status;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700967 wlan_hdd_netif_queue_control(adapter,
968 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
969 WLAN_CONTROL_PATH);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700970
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700971 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700972 return;
973}
974
975/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700976 * hdd_ndp_session_end_handler() - NDI session termination handler
977 * @adapter: pointer to adapter context
978 *
979 * Following vendor event is sent to cfg80211:
980 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
981 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
982 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800983 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700984 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
985 *
986 * Return: none
987 */
988void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
989{
990 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
991 struct sk_buff *vendor_event;
992 struct nan_datapath_ctx *ndp_ctx;
993 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
994 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
995
996 ENTER();
997
998 if (wlan_hdd_validate_context(hdd_ctx))
999 return;
1000
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001001 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1002 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001003 hdd_err("ndp context is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001004 return;
1005 }
1006
1007 /*
1008 * The virtual adapters are stopped and closed even during
1009 * driver unload or stop, the service layer is not required
1010 * to be informed in that case (response is not expected)
1011 */
1012 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001013 hdd_err("NDI interface %s deleted", adapter->dev->name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001014 return;
1015 }
1016
1017 /* notify response to the upper layer */
1018 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1019 NULL,
1020 data_len,
1021 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1022 GFP_KERNEL);
1023
1024 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001025 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001026 return;
1027 }
1028
1029 /* Sub vendor command goes first */
1030 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1031 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001032 hdd_err("VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001033 goto failure;
1034 }
1035
1036 /* Transaction id */
1037 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1038 ndp_ctx->ndp_delete_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001039 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001040 goto failure;
1041 }
1042
1043 /* Status code */
1044 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001045 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001046 ndp_ctx->ndi_delete_rsp_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001047 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001048 goto failure;
1049 }
1050
1051 /* Status return value */
1052 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001053 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1054 ndp_ctx->ndi_delete_rsp_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001055 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001056 goto failure;
1057 }
1058
Naveen Rawatba4f6612016-07-05 12:03:16 -07001059 hdd_info("sub command: %d, value: %d", QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001060 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001061 hdd_info("delete transaction id: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001062 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1063 ndp_ctx->ndp_delete_transaction_id);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001064 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001065 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001066 ndp_ctx->ndi_delete_rsp_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001067 hdd_info("Return value: %d, value: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001068 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1069 ndp_ctx->ndi_delete_rsp_reason);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001070
1071 ndp_ctx->ndp_delete_transaction_id = 0;
1072 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
1073
1074 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1075
1076 EXIT();
1077 return;
1078
1079failure:
1080 kfree_skb(vendor_event);
1081}
1082
1083
1084/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001085 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
1086 * @adapter: pointer to adapter context
1087 * @rsp_params: response parameters
1088 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001089 * Following vendor event is sent to cfg80211:
1090 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1091 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1092 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1093 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001094 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001095 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1096 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001097 * Return: none
1098 */
1099static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter,
1100 void *rsp_params)
1101{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001102 struct sk_buff *vendor_event;
1103 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1104 struct ndp_initiator_rsp *rsp = rsp_params;
1105 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
1106 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
1107
1108 ENTER();
1109
1110 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001111 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001112 return;
1113 }
1114
1115 if (0 != wlan_hdd_validate_context(hdd_ctx))
1116 return;
1117
1118 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1119 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1120 GFP_KERNEL);
1121 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001122 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001123 return;
1124 }
1125
1126 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1127 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1128 goto ndp_initiator_rsp_nla_failed;
1129
1130 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1131 rsp->transaction_id))
1132 goto ndp_initiator_rsp_nla_failed;
1133
1134 if (nla_put_u32(vendor_event,
1135 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1136 rsp->ndp_instance_id))
1137 goto ndp_initiator_rsp_nla_failed;
1138
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001139 if (nla_put_u32(vendor_event,
1140 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001141 rsp->status))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001142 goto ndp_initiator_rsp_nla_failed;
1143
1144 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001145 rsp->reason))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001146 goto ndp_initiator_rsp_nla_failed;
1147
Naveen Rawatba4f6612016-07-05 12:03:16 -07001148 hdd_info("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001149 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1150 rsp->reason);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001151 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1152 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001153 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001154ndp_initiator_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001155 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001156 kfree_skb(vendor_event);
1157 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001158}
1159
1160/**
1161 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
1162 * @adapter: pointer to adapter context
1163 * @ind_params: indication parameters
1164 *
1165 * Return: none
1166 */
1167static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
1168 void *ind_params)
1169{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001170 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
1171 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1172 tSirBssDescription tmp_bss_descp = {0};
1173 tCsrRoamInfo roam_info = {0};
1174 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1175 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1176
1177 ENTER();
1178
1179 if (NULL == ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001180 hdd_err("Invalid new NDP peer params");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001181 return;
1182 }
Naveen Rawatba4f6612016-07-05 12:03:16 -07001183 hdd_info("session_id: %d, peer_mac: %pM, sta_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001184 new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
1185 new_peer_ind->sta_id);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001186
1187 /* save peer in ndp ctx */
1188 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
1189 &new_peer_ind->peer_mac_addr)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001190 hdd_err("Ndp peer table full. cannot save new peer");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001191 return;
1192 }
1193
1194 /* this function is called for each new peer */
1195 ndp_ctx->active_ndp_peers++;
Naveen Rawatba4f6612016-07-05 12:03:16 -07001196 hdd_info("vdev_id: %d, num_peers: %d", adapter->sessionId,
1197 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001198
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001199 hdd_roam_register_sta(adapter, &roam_info, new_peer_ind->sta_id,
1200 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
1201 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
1202 /* perform following steps for first new peer ind */
1203 if (ndp_ctx->active_ndp_peers == 1) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001204 hdd_info("Set ctx connection state to connected");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001205 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
1206 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001207 wlan_hdd_netif_queue_control(adapter,
1208 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001209 }
1210 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001211}
1212
1213/**
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001214 * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001215 * @adapter: pointer to adapter context
1216 * @ind_params: indication parameters
1217 *
1218 * Return: none
1219 */
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001220static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter,
1221 void *ind_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001222{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001223 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1224 struct sme_ndp_peer_ind *peer_ind = ind_params;
1225 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1226 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1227
1228 hdd_roam_deregister_sta(adapter, peer_ind->sta_id);
1229 hdd_delete_peer(sta_ctx, peer_ind->sta_id);
1230 hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
1231
1232 if (--ndp_ctx->active_ndp_peers == 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001233 hdd_info("No more ndp peers.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001234 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
1235 hdd_conn_set_connection_state(adapter,
1236 eConnectionState_NdiDisconnected);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001237 hdd_info("Stop netif tx queues.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001238 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
1239 WLAN_CONTROL_PATH);
1240 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001241}
1242
1243/**
1244 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1245 * @adapter: pointer to adapter context
1246 * @ind_params: indication parameters
1247 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001248 * Following vendor event is sent to cfg80211:
1249 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1250 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1251 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1252 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1253 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1254 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1255 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1256 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1257 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001258 * Return: none
1259 */
1260static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
1261 void *ind_params)
1262{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001263 int idx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001264 uint32_t ndp_qos_config = 0;
1265 struct ndp_confirm_event *ndp_confirm = ind_params;
1266 struct sk_buff *vendor_event;
1267 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1268 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Naveen Rawatf28315c2016-06-29 18:06:02 -07001269 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001270 uint32_t data_len;
1271
1272 ENTER();
1273 if (!ndp_confirm) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001274 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001275 return;
1276 }
1277
1278 if (0 != wlan_hdd_validate_context(hdd_ctx))
1279 return;
1280
Naveen Rawatf28315c2016-06-29 18:06:02 -07001281 /* ndp_confirm is called each time user generated ndp req succeeds */
1282 idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
1283 if (idx == INVALID_PEER_IDX)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001284 hdd_err("can't find addr: %pM in vdev_id: %d, peer table.",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001285 &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId);
Naveen Rawat460be782016-06-29 18:26:22 -07001286 else if (ndp_confirm->rsp_code == NDP_RESPONSE_ACCEPT)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001287 ndp_ctx->active_ndp_sessions[idx]++;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001288
1289 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
Naveen Rawat90ae3082016-06-29 18:22:59 -07001290 + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001291 ndp_confirm->ndp_info.ndp_app_info_len;
1292
Naveen Rawat8d63a592016-06-29 18:30:59 -07001293 if (ndp_confirm->ndp_info.ndp_app_info_len)
1294 data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
1295
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001296 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1297 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1298 GFP_KERNEL);
1299 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001300 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001301 return;
1302 }
1303
1304 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1305 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1306 goto ndp_confirm_nla_failed;
1307
1308 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1309 ndp_confirm->ndp_instance_id))
1310 goto ndp_confirm_nla_failed;
1311
1312 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1313 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1314 goto ndp_confirm_nla_failed;
1315
1316 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1317 IFNAMSIZ, adapter->dev->name))
1318 goto ndp_confirm_nla_failed;
1319
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001320 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001321 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1322 ndp_confirm->ndp_info.ndp_app_info_len,
1323 ndp_confirm->ndp_info.ndp_app_info))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001324 goto ndp_confirm_nla_failed;
1325
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001326 if (nla_put_u32(vendor_event,
1327 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1328 ndp_confirm->rsp_code))
1329 goto ndp_confirm_nla_failed;
1330
Naveen Rawat8d63a592016-06-29 18:30:59 -07001331 if (nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1333 ndp_confirm->reason_code))
1334 goto ndp_confirm_nla_failed;
1335
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001336 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001337 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 -07001338 ndp_confirm->ndp_instance_id,
1339 ndp_confirm->peer_ndi_mac_addr.bytes,
Naveen Rawat460be782016-06-29 18:26:22 -07001340 ndp_qos_config, ndp_confirm->rsp_code,
1341 ndp_confirm->reason_code);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001342
Naveen Rawatba4f6612016-07-05 12:03:16 -07001343 hdd_info("NDP confim, ndp app info dump");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001344 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1345 ndp_confirm->ndp_info.ndp_app_info,
1346 ndp_confirm->ndp_info.ndp_app_info_len);
1347 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001348 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001349ndp_confirm_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001350 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001351 kfree_skb(vendor_event);
1352 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001353}
1354
1355/**
1356 * hdd_ndp_indication_handler() - NDP indication handler
1357 * @adapter: pointer to adapter context
1358 * @ind_params: indication parameters
1359 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001360 * Following vendor event is sent to cfg80211:
1361 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1362 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1363 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
Naveen Rawat19da3d12016-08-16 12:39:38 -07001364 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001365 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1366 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1367 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1368 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1369 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001370 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes)
1371 * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001372 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001373 * Return: none
1374 */
1375static void hdd_ndp_indication_handler(hdd_adapter_t *adapter,
1376 void *ind_params)
1377{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001378 struct sk_buff *vendor_event;
1379 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1380 struct ndp_indication_event *event = ind_params;
1381 uint32_t ndp_qos_config;
1382 struct nan_datapath_ctx *ndp_ctx;
1383 uint16_t data_len;
1384
1385 ENTER();
1386 if (!ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001387 hdd_err("Invalid NDP Indication");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001388 return;
1389 }
1390
1391 if (0 != wlan_hdd_validate_context(hdd_ctx))
1392 return;
1393
1394 /* Handle only if adapter is in NDI mode */
1395 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001396 hdd_err("Adapter is not in NDI mode");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001397 return;
1398 }
1399
Naveen Rawatba4f6612016-07-05 12:03:16 -07001400 hdd_info("NDP Indication, policy: %d", event->policy);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001401
1402 /* Policy check */
1403 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001404 hdd_err("NAN datapath is not suported");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001405 return;
1406 }
1407
1408 /* NAN data path coexists only with STA interface */
1409 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001410 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001411 return;
1412 }
1413
1414 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1415
1416 /* check if we are in middle of deleting/creating the interface */
1417 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
1418 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
1419 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001420 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001421 ndp_ctx->state);
1422 return;
1423 }
1424
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001425 data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
1426 event->ndp_info.ndp_app_info_len + event->scid.scid_len +
1427 (10 * NLA_HDRLEN) + NLMSG_HDRLEN;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001428
1429 /* notify response to the upper layer */
1430 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1431 NULL, data_len,
1432 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1433 GFP_KERNEL);
1434 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001435 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001436 return;
1437 }
1438
1439 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1440 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1441 goto ndp_indication_nla_failed;
1442
1443 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1444 IFNAMSIZ, adapter->dev->name))
1445 goto ndp_indication_nla_failed;
1446
Naveen Rawat19da3d12016-08-16 12:39:38 -07001447 if (nla_put_u32(vendor_event,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001448 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1449 event->service_instance_id))
1450 goto ndp_indication_nla_failed;
1451
1452 if (nla_put(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1454 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1455 goto ndp_indication_nla_failed;
1456
1457 if (nla_put(vendor_event,
Jeff Johnson03294f12016-12-09 17:10:24 -08001458 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001459 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1460 goto ndp_indication_nla_failed;
1461
1462 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1463 event->ndp_instance_id))
1464 goto ndp_indication_nla_failed;
1465
1466 if (event->ndp_info.ndp_app_info_len)
1467 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1468 event->ndp_info.ndp_app_info_len,
1469 event->ndp_info.ndp_app_info))
1470 goto ndp_indication_nla_failed;
1471
1472 if (event->ndp_config.ndp_cfg_len) {
1473 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1474 /* at present ndp config stores 4 bytes QOS info only */
1475 if (nla_put_u32(vendor_event,
1476 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1477 ndp_qos_config))
1478 goto ndp_indication_nla_failed;
1479 }
1480
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001481 if (event->scid.scid_len) {
1482 if (nla_put_u32(vendor_event,
1483 QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE,
1484 event->ncs_sk_type))
1485 goto ndp_indication_nla_failed;
1486
1487 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
1488 event->scid.scid_len,
1489 event->scid.scid))
1490 goto ndp_indication_nla_failed;
1491
1492 hdd_info("csid: %d, scid_len: %d",
1493 event->ncs_sk_type, event->scid.scid_len);
1494
1495 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1496 event->scid.scid, event->scid.scid_len);
1497 }
1498
Abhishek Singh4fef7472016-06-06 11:36:03 -07001499 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1500 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001501 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001502ndp_indication_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001503 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001504 kfree_skb(vendor_event);
1505 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001506}
1507
1508/**
1509 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1510 * @adapter: pointer to adapter context
1511 * @rsp_params: response parameters
1512 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001513 * Following vendor event is sent to cfg80211:
1514 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1515 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1516 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001517 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1518 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001519 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001520 * Return: none
1521 */
1522static void hdd_ndp_responder_rsp_handler(hdd_adapter_t *adapter,
1523 void *rsp_params)
1524{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001525 struct sk_buff *vendor_event;
1526 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1527 struct ndp_responder_rsp_event *rsp = rsp_params;
1528 uint16_t data_len;
1529
1530 ENTER();
1531 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001532 hdd_err("Invalid NDP Responder response");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001533 return;
1534 }
1535
1536 if (0 != wlan_hdd_validate_context(hdd_ctx))
1537 return;
1538
Naveen Rawatba4f6612016-07-05 12:03:16 -07001539 hdd_info("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001540 rsp->vdev_id, rsp->transaction_id,
1541 rsp->status, rsp->reason);
1542
1543 data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
1544 4 * NLA_HDRLEN + NLMSG_HDRLEN;
1545 /* notify response to the upper layer */
1546 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1547 NULL, data_len,
1548 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1549 GFP_KERNEL);
1550 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001551 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001552 return;
1553 }
1554
1555 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1556 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1557 goto ndp_responder_rsp_nla_failed;
1558
1559 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1560 rsp->transaction_id))
1561 goto ndp_responder_rsp_nla_failed;
1562
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001563 if (nla_put_u32(vendor_event,
1564 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001565 rsp->status))
1566 goto ndp_responder_rsp_nla_failed;
1567
1568 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001569 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001570 rsp->reason))
1571 goto ndp_responder_rsp_nla_failed;
1572
1573 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1574 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001575 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001576ndp_responder_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001577 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001578 kfree_skb(vendor_event);
1579 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001580}
1581
1582/**
1583 * hdd_ndp_end_rsp_handler() - NDP end response handler
1584 * @adapter: pointer to adapter context
1585 * @rsp_params: response parameters
1586 *
Naveen Rawatf28315c2016-06-29 18:06:02 -07001587 * Following vendor event is sent to cfg80211:
1588 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1589 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001590 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001591 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1592 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1593 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001594 * Return: none
1595 */
Naveen Rawatf28315c2016-06-29 18:06:02 -07001596static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, void *rsp_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001597{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001598 struct sk_buff *vendor_event;
1599 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1600 struct ndp_end_rsp_event *rsp = rsp_params;
Rakesh Sunkiae936b62016-07-28 16:01:45 -07001601 uint32_t data_len;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001602
1603 ENTER();
1604
1605 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001606 hdd_err("Invalid ndp end response");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001607 return;
1608 }
1609
1610 if (0 != wlan_hdd_validate_context(hdd_ctx))
1611 return;
1612
Naveen Rawatf28315c2016-06-29 18:06:02 -07001613 data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
1614 sizeof(uint16_t);
1615
1616 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1617 data_len, 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");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001621 return;
1622 }
1623
1624 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1625 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1626 goto ndp_end_rsp_nla_failed;
1627
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001628 if (nla_put_u32(vendor_event,
1629 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001630 rsp->status))
1631 goto ndp_end_rsp_nla_failed;
1632
1633 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1634 rsp->reason))
1635 goto ndp_end_rsp_nla_failed;
1636
1637 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1638 rsp->transaction_id))
1639 goto ndp_end_rsp_nla_failed;
1640
Naveen Rawatba4f6612016-07-05 12:03:16 -07001641 hdd_info("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001642 rsp->transaction_id, rsp->status, rsp->reason);
1643 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1644 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001645 return;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001646
1647ndp_end_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001648 hdd_err("nla_put api failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001649 kfree_skb(vendor_event);
1650 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001651}
1652
1653/**
1654 * hdd_ndp_end_ind_handler() - NDP end indication handler
1655 * @adapter: pointer to adapter context
1656 * @ind_params: indication parameters
1657 *
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001658 * Following vendor event is sent to cfg80211:
1659 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1660 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001661 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1662 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001663 * Return: none
1664 */
1665static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
1666 void *ind_params)
1667{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001668 struct sk_buff *vendor_event;
1669 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1670 struct ndp_end_indication_event *end_ind = ind_params;
1671 uint32_t data_len, i;
1672 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1673 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1674 uint32_t *ndp_instance_array;
Naveen Rawate21103f2016-07-08 14:18:00 -07001675 hdd_adapter_t *ndi_adapter;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001676
1677 ENTER();
1678
1679 if (!end_ind) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001680 hdd_err("Invalid ndp end indication");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001681 return;
1682 }
1683
1684 if (0 != wlan_hdd_validate_context(hdd_ctx))
1685 return;
1686
1687 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1688 sizeof(*ndp_instance_array));
1689 if (!ndp_instance_array) {
1690 hdd_err("Failed to allocate ndp_instance_array");
1691 return;
1692 }
1693 for (i = 0; i < end_ind->num_ndp_ids; i++) {
1694 int idx;
1695
1696 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
Naveen Rawate21103f2016-07-08 14:18:00 -07001697 ndi_adapter = hdd_get_adapter_by_vdev(hdd_ctx,
1698 end_ind->ndp_map[i].vdev_id);
1699 if (ndi_adapter == NULL) {
1700 hdd_err("Adapter not found for vdev_id: %d",
1701 end_ind->ndp_map[i].vdev_id);
1702 continue;
1703 }
1704 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
Govind Singhb8475942016-08-12 11:07:09 +05301705 if (!ndp_ctx) {
1706 hdd_err("ndp_ctx is NULL for vdev id: %d",
1707 end_ind->ndp_map[i].vdev_id);
1708 continue;
1709 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001710 idx = hdd_get_peer_idx(sta_ctx,
1711 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1712 if (idx == INVALID_PEER_IDX) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001713 hdd_err("can't find addr: %pM in sta_ctx.",
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001714 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1715 continue;
1716 }
1717 /* save the value of active sessions on each peer */
1718 ndp_ctx->active_ndp_sessions[idx] =
1719 end_ind->ndp_map[i].num_active_ndp_sessions;
1720 }
1721
Naveen Rawat90ae3082016-06-29 18:22:59 -07001722 data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001723 end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
1724
1725 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1726 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1727 GFP_KERNEL);
1728 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001729 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001730 return;
1731 }
1732
1733 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1734 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1735 goto ndp_end_ind_nla_failed;
1736
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001737 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1738 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1739 ndp_instance_array))
1740 goto ndp_end_ind_nla_failed;
1741
1742 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1743 qdf_mem_free(ndp_instance_array);
1744 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001745 return;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001746
1747ndp_end_ind_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001748 hdd_err("nla_put api failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001749 kfree_skb(vendor_event);
1750 qdf_mem_free(ndp_instance_array);
1751 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001752}
1753
1754/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001755 * hdd_ndp_event_handler() - ndp response and indication handler
1756 * @adapter: adapter context
1757 * @roam_info: pointer to roam_info structure
1758 * @roam_id: roam id as indicated by SME
1759 * @roam_status: roam status
1760 * @roam_result: roam result
1761 *
1762 * Return: none
1763 */
1764void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1765 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1766 eCsrRoamResult roam_result)
1767{
1768 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1769 switch (roam_result) {
Naveen Rawat8d63a592016-06-29 18:30:59 -07001770 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001771 hdd_ndp_iface_create_rsp_handler(adapter,
1772 &roam_info->ndp.ndi_create_params);
1773 break;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001774 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001775 hdd_ndp_iface_delete_rsp_handler(adapter,
1776 &roam_info->ndp.ndi_delete_params);
1777 break;
1778 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1779 hdd_ndp_initiator_rsp_handler(adapter,
1780 &roam_info->ndp.ndp_init_rsp_params);
1781 break;
1782 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1783 hdd_ndp_new_peer_ind_handler(adapter,
1784 &roam_info->ndp.ndp_peer_ind_params);
1785 break;
1786 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1787 hdd_ndp_confirm_ind_handler(adapter,
1788 &roam_info->ndp.ndp_confirm_params);
1789 break;
1790 case eCSR_ROAM_RESULT_NDP_INDICATION:
1791 hdd_ndp_indication_handler(adapter,
1792 &roam_info->ndp.ndp_indication_params);
1793 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001794 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1795 hdd_ndp_responder_rsp_handler(adapter,
1796 &roam_info->ndp.ndp_responder_rsp_params);
1797 break;
1798 case eCSR_ROAM_RESULT_NDP_END_RSP:
1799 hdd_ndp_end_rsp_handler(adapter,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001800 roam_info->ndp.ndp_end_rsp_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001801 break;
1802 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1803 hdd_ndp_peer_departed_ind_handler(adapter,
1804 &roam_info->ndp.ndp_peer_ind_params);
1805 break;
1806 case eCSR_ROAM_RESULT_NDP_END_IND:
1807 hdd_ndp_end_ind_handler(adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001808 roam_info->ndp.ndp_end_ind_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001809 break;
1810 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001811 hdd_err("Unknown NDP response event from SME %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001812 roam_result);
1813 break;
1814 }
1815 }
1816}
Naveen Rawat97500352017-03-22 10:07:58 -07001817#else
1818void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1819 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1820 eCsrRoamResult roam_result)
1821{
1822}
1823#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001824
1825/**
1826 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1827 * @wiphy: pointer to wireless wiphy structure.
1828 * @wdev: pointer to wireless_dev structure.
1829 * @data: Pointer to the data to be passed via vendor interface
1830 * @data_len:Length of the data to be passed
1831 *
1832 * This function is invoked to handle vendor command
1833 *
1834 * Return: 0 on success, negative errno on failure
1835 */
1836static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1837 struct wireless_dev *wdev, const void *data, int data_len)
1838{
1839 uint32_t ndp_cmd_type;
1840 uint16_t transaction_id;
1841 int ret_val;
1842 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1843 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1844 char *iface_name;
1845
1846 ENTER();
1847
1848 ret_val = wlan_hdd_validate_context(hdd_ctx);
1849 if (ret_val)
1850 return ret_val;
1851
1852 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001853 hdd_err("Command not allowed in FTM mode");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001854 return -EPERM;
1855 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07001856 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001857 hdd_err("NAN datapath is not enabled");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001858 return -EPERM;
1859 }
1860 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1861 data, data_len,
1862 qca_wlan_vendor_ndp_policy)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001863 hdd_err("Invalid NDP vendor command attributes");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001864 return -EINVAL;
1865 }
1866
1867 /* Parse and fetch NDP Command Type*/
1868 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001869 hdd_err("NAN datapath cmd type failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001870 return -EINVAL;
1871 }
1872 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1873
1874 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001875 hdd_err("attr transaction id failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001876 return -EINVAL;
1877 }
1878 transaction_id = nla_get_u16(
1879 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1880
Naveen Rawatf28315c2016-06-29 18:06:02 -07001881 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
1882 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001883 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: %s",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001884 transaction_id, ndp_cmd_type, iface_name);
1885 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001886 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: unspecified",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001887 transaction_id, ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001888 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001889
1890 switch (ndp_cmd_type) {
1891 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
1892 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
1893 break;
1894 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
1895 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
1896 break;
1897 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
1898 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
1899 break;
1900 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
1901 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
1902 break;
1903 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
1904 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
1905 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001906 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001907 hdd_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001908 ret_val = -EINVAL;
1909 break;
1910 }
1911
1912 return ret_val;
1913}
1914
1915/**
1916 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
1917 * @wiphy: pointer to wireless wiphy structure.
1918 * @wdev: pointer to wireless_dev structure.
1919 * @data: Pointer to the data to be passed via vendor interface
1920 * @data_len:Length of the data to be passed
1921 *
1922 * This function is called to send a NAN request to
1923 * firmware. This is an SSR-protected wrapper function.
1924 *
1925 * Return: 0 on success, negative errno on failure
1926 */
1927int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1928 struct wireless_dev *wdev, const void *data, int data_len)
1929{
1930 int ret;
1931
1932 cds_ssr_protect(__func__);
1933 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
1934 cds_ssr_unprotect(__func__);
1935
1936 return ret;
1937}
1938
1939/**
1940 * hdd_init_nan_data_mode() - initialize nan data mode
1941 * @adapter: adapter context
1942 *
1943 * Returns: 0 on success negative error code on error
1944 */
1945int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
1946{
1947 struct net_device *wlan_dev = adapter->dev;
1948 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1949 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1950 QDF_STATUS status;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001951 int32_t ret_val = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001952
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001953 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001954
Dustin Brownd28772b2017-03-17 14:16:07 -07001955 ret_val = hdd_vdev_create(adapter);
1956 if (ret_val) {
1957 hdd_err("failed to create vdev: %d", ret_val);
1958 return ret_val;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001959 }
1960
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001961 /* Register wireless extensions */
1962 ret_val = hdd_register_wext(wlan_dev);
1963 if (0 > ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001964 hdd_err("Wext registration failed with status code %d",
1965 ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001966 ret_val = -EAGAIN;
1967 goto error_register_wext;
1968 }
1969
1970 status = hdd_init_tx_rx(adapter);
1971 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001972 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001973 ret_val = -EAGAIN;
1974 goto error_init_txrx;
1975 }
1976
1977 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
1978
1979 status = hdd_wmm_adapter_init(adapter);
1980 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001981 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001982 ret_val = -EAGAIN;
1983 goto error_wmm_init;
1984 }
1985
1986 set_bit(WMM_INIT_DONE, &adapter->event_flags);
1987
1988 ret_val = wma_cli_set_command((int)adapter->sessionId,
1989 (int)WMI_PDEV_PARAM_BURST_ENABLE,
1990 (int)hdd_ctx->config->enableSifsBurst,
1991 PDEV_CMD);
1992 if (0 != ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001993 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001994 }
1995
1996 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
1997 return ret_val;
1998
1999error_wmm_init:
2000 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2001 hdd_deinit_tx_rx(adapter);
2002
2003error_init_txrx:
2004 hdd_unregister_wext(wlan_dev);
2005
2006error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07002007 QDF_BUG(!hdd_vdev_destroy(adapter));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002008
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002009 return ret_val;
2010}