blob: 3cdadc50332592571a228f8c1e5dc5d921fbe2a4 [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
39/* NLA policy */
40static const struct nla_policy
41qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
42 [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 },
43 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 },
44 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_STRING,
45 .len = IFNAMSIZ },
Naveen Rawat19da3d12016-08-16 12:39:38 -070046 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070047 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070048 [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = {
Naveen Rawatf28315c2016-06-29 18:06:02 -070049 .type = NLA_BINARY,
50 .len = QDF_MAC_ADDR_SIZE },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070051 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 },
52 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY,
53 .len = NDP_QOS_INFO_LEN },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070054 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY,
55 .len = NDP_APP_INFO_LEN },
56 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070057 [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070058 [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY,
59 .len = QDF_MAC_ADDR_SIZE },
Naveen Rawatf28315c2016-06-29 18:06:02 -070060 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY,
61 .len = NDP_NUM_INSTANCE_ID },
Naveen Rawat0a017052016-10-19 14:17:07 -070062 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { .type = NLA_U32 },
Naveen Rawat4f3983e2016-11-29 16:12:09 -080063 [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { .type = NLA_U32 },
64 [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { .type = NLA_BINARY,
65 .len = NDP_PMK_LEN },
66 [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { .type = NLA_BINARY,
67 .len = NDP_SCID_BUF_LEN },
Rakesh Sunkid92d1082017-01-04 15:14:28 -080068 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { .type =
69 NLA_U32 },
70 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070071};
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070072
73/**
74 * hdd_ndp_print_ini_config()- Print nan datapath specific INI configuration
75 * @hdd_ctx: handle to hdd context
76 *
77 * Return: None
78 */
79void hdd_ndp_print_ini_config(hdd_context_t *hdd_ctx)
80{
Naveen Rawatba4f6612016-07-05 12:03:16 -070081 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_DATAPATH_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070082 hdd_ctx->config->enable_nan_datapath);
Naveen Rawatba4f6612016-07-05 12:03:16 -070083 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_NDI_CHANNEL_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070084 hdd_ctx->config->nan_datapath_ndi_channel);
85}
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070086
87/**
88 * hdd_nan_datapath_target_config() - Configure NAN datapath features
89 * @hdd_ctx: Pointer to HDD context
90 * @cfg: Pointer to target device capability information
91 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070092 * NAN datapath functionality is enabled if it is enabled in
93 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070094 *
95 * Return: None
96 */
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070097void hdd_nan_datapath_target_config(hdd_context_t *hdd_ctx,
98 struct wma_tgt_cfg *cfg)
99{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -0700100 hdd_ctx->nan_datapath_enabled =
101 hdd_ctx->config->enable_nan_datapath &&
102 cfg->nan_datapath_enabled;
Naveen Rawatba4f6612016-07-05 12:03:16 -0700103 hdd_info("enable_nan_datapath: %d", hdd_ctx->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -0700104}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700105
106/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700107 * hdd_close_ndi() - close NAN Data interface
108 * @adapter: adapter context
109 *
110 * Close the adapter if start BSS fails
111 *
112 * Returns: 0 on success, negative error code otherwise
113 */
114static int hdd_close_ndi(hdd_adapter_t *adapter)
115{
116 int rc;
117 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
118 uint32_t timeout = WLAN_WAIT_TIME_SESSIONOPENCLOSE;
119
120 ENTER();
121
122 /* check if the adapter is in NAN Data mode */
123 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700124 hdd_err("Interface is not in NDI mode");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700125 return -EINVAL;
126 }
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700127 wlan_hdd_netif_queue_control(adapter,
128 WLAN_NETIF_TX_DISABLE_N_CARRIER,
129 WLAN_CONTROL_PATH);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700130
131#ifdef WLAN_OPEN_SOURCE
132 cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
133#endif
134 hdd_deregister_tx_flow_control(adapter);
135
136#ifdef WLAN_NS_OFFLOAD
137#ifdef WLAN_OPEN_SOURCE
138 cancel_work_sync(&adapter->ipv6NotifierWorkQueue);
139#endif
140#endif
141 /* check if the session is open */
142 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
143 INIT_COMPLETION(adapter->session_close_comp_var);
144 if (QDF_STATUS_SUCCESS == sme_close_session(hdd_ctx->hHal,
145 adapter->sessionId,
146 hdd_sme_close_session_callback, adapter)) {
147 /* Block on a timed completion variable */
148 rc = wait_for_completion_timeout(
149 &adapter->session_close_comp_var,
150 msecs_to_jiffies(timeout));
151 if (!rc)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700152 hdd_err("session close timeout");
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530153
Rajeev Kumar9591d2b2017-01-13 16:05:06 -0800154 rc = hdd_release_and_destroy_vdev(adapter);
155 if (rc)
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530156 hdd_err("vdev delete failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700157 }
158 }
159
160 /* We are good to close the adapter */
161 hdd_close_adapter(hdd_ctx, adapter, true);
162
163 EXIT();
164 return 0;
165}
166
167/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700168 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
169 * @hdd_ctx: hdd context
170 *
171 * NDP is not allowed with any other role active except STA.
172 *
173 * Return: true if allowed, false otherwise
174 */
175static bool hdd_is_ndp_allowed(hdd_context_t *hdd_ctx)
176{
177 hdd_adapter_t *adapter;
178 hdd_station_ctx_t *sta_ctx;
179 QDF_STATUS status;
180 hdd_adapter_list_node_t *curr = NULL, *next = NULL;
181
182 status = hdd_get_front_adapter(hdd_ctx, &curr);
183 while (QDF_STATUS_SUCCESS == status) {
184 adapter = curr->pAdapter;
185 if (!adapter)
186 goto next_adapter;
187
188 switch (adapter->device_mode) {
189 case QDF_P2P_GO_MODE:
190 case QDF_SAP_MODE:
191 if (test_bit(SOFTAP_BSS_STARTED,
192 &adapter->event_flags))
193 return false;
194 break;
195 case QDF_P2P_CLIENT_MODE:
196 case QDF_IBSS_MODE:
197 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
198 if (hdd_conn_is_connected(sta_ctx) ||
199 hdd_is_connecting(sta_ctx))
200 return false;
201 break;
202 default:
203 break;
204 }
205next_adapter:
206 status = hdd_get_next_adapter(hdd_ctx, curr, &next);
207 curr = next;
208 }
209
210 return true;
211}
212
213/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700214 * hdd_ndi_start_bss() - Start BSS on NAN data interface
215 * @adapter: adapter context
216 * @operating_channel: channel on which the BSS to be started
217 *
218 * Return: 0 on success, error value on failure
219 */
220static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
221 uint8_t operating_channel)
222{
223 int ret;
224 uint32_t roam_id;
225 hdd_wext_state_t *wext_state =
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -0700226 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700227 tCsrRoamProfile *roam_profile = &wext_state->roamProfile;
228
229 ENTER();
230
231 if (!roam_profile) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700232 hdd_err("No valid roam profile");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700233 return -EINVAL;
234 }
235
236 if (HDD_WMM_USER_MODE_NO_QOS ==
237 (WLAN_HDD_GET_CTX(adapter))->config->WmmMode) {
238 /* QoS not enabled in cfg file*/
239 roam_profile->uapsd_mask = 0;
240 } else {
241 /* QoS enabled, update uapsd mask from cfg file*/
242 roam_profile->uapsd_mask =
243 (WLAN_HDD_GET_CTX(adapter))->config->UapsdMask;
244 }
245
246 roam_profile->csrPersona = adapter->device_mode;
247
248 roam_profile->ChannelInfo.numOfChannels = 1;
249 if (operating_channel) {
250 roam_profile->ChannelInfo.ChannelList = &operating_channel;
251 } else {
252 roam_profile->ChannelInfo.ChannelList[0] =
253 NAN_SOCIAL_CHANNEL_2_4GHZ;
254 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700255
256 roam_profile->SSIDs.numOfSSIDs = 1;
257 roam_profile->SSIDs.SSIDList->SSID.length = 0;
258
259 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
260 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
261 roam_profile->BSSIDs.numOfBSSIDs = 1;
262 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
263 &adapter->macAddressCurrent.bytes[0],
264 QDF_MAC_ADDR_SIZE);
265
266 roam_profile->AuthType.numEntries = 1;
267 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
268 roam_profile->EncryptionType.numEntries = 1;
269 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
270
271 ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
272 adapter->sessionId, roam_profile, &roam_id);
273 if (QDF_STATUS_SUCCESS != ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700274 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
275 adapter->sessionId, ret);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700276 /* change back to NotConnected */
277 hdd_conn_set_connection_state(adapter,
278 eConnectionState_NotConnected);
279 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700280 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700281 }
282
283 roam_profile->ChannelInfo.ChannelList = NULL;
284 roam_profile->ChannelInfo.numOfChannels = 0;
285
286 EXIT();
287
288 return ret;
289}
290
291
292/**
293 * hdd_ndi_create_req_handler() - NDI create request handler
294 * @hdd_ctx: hdd context
295 * @tb: parsed NL attribute list
296 *
297 * Return: 0 on success or error code on failure
298 */
299static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
300 struct nlattr **tb)
301{
302 hdd_adapter_t *adapter;
303 char *iface_name;
304 uint16_t transaction_id;
305 int ret;
306 struct nan_datapath_ctx *ndp_ctx;
307 uint8_t op_channel =
308 hdd_ctx->config->nan_datapath_ndi_channel;
309
310 ENTER();
311
312 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700313 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700314 return -EINVAL;
315 }
316 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
317
318 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700319 hdd_err("transaction id is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700320 return -EINVAL;
321 }
322 transaction_id =
323 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
324
325 /* Check for an existing interface of NDI type */
326 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
327 if (adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700328 hdd_err("Cannot support more than one NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700329 return -EEXIST;
330 }
331
332 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
333 wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
334 true);
335 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700336 hdd_err("hdd_open_adapter failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700337 return -ENOMEM;
338 }
339
340 /*
341 * Create transaction id is required to be saved since the firmware
342 * does not honor the transaction id for create request
343 */
344 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
345 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700346 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700347
348 /*
349 * The NAN data interface has been created at this point.
350 * Unlike traditional device modes, where the higher application
351 * layer initiates connect / join / start, the NAN data interface
352 * does not have any such formal requests. The NDI create request
353 * is responsible for starting the BSS as well.
354 */
355 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
356 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
357 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
358 /* start NDI on the default 2.4 GHz social channel */
359 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
360 }
361 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700362 if (0 > ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700363 hdd_err("NDI start bss failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700364 /* Start BSS failed, delete the interface */
365 hdd_close_ndi(adapter);
366 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700367
368 EXIT();
369 return ret;
370}
371
372/**
373 * hdd_ndi_delete_req_handler() - NDI delete request handler
374 * @hdd_ctx: hdd context
375 * @tb: parsed NL attribute list
376 *
377 * Return: 0 on success or error code on failure
378 */
379static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
380 struct nlattr **tb)
381{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700382 hdd_adapter_t *adapter;
383 char *iface_name;
384 uint16_t transaction_id;
385 struct nan_datapath_ctx *ndp_ctx;
386 int ret;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700387 hdd_station_ctx_t *sta_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700388
389 ENTER();
390
391 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700392 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700393 return -EINVAL;
394 }
395
396 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
397
398 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700399 hdd_err("Transaction id is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700400 return -EINVAL;
401 }
402
403 transaction_id =
404 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
405
406 /* Check if there is already an existing inteface with the same name */
407 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
408 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700409 hdd_err("NAN data interface %s is not available", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700410 return -EINVAL;
411 }
412
413 /* check if adapter is in NDI mode */
414 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700415 hdd_err("Interface %s is not in NDI mode", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700416 return -EINVAL;
417 }
418
419 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
420 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700421 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700422 return -EINVAL;
423 }
424
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700425 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
426 if (!sta_ctx) {
427 hdd_err("sta_ctx is NULL");
428 return -EINVAL;
429 }
430
Naveen Rawatf28315c2016-06-29 18:06:02 -0700431 /* check if there are active peers on the adapter */
432 if (ndp_ctx->active_ndp_peers > 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700433 hdd_err("NDP peers active: %d, cannot delete NDI",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700434 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700435 return -EINVAL;
436 }
437
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700438 /*
439 * Since, the interface is being deleted, remove the
440 * broadcast id.
441 */
442 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
443 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
444
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700445 ndp_ctx->ndp_delete_transaction_id = transaction_id;
446 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
447
448 /* Delete the interface */
449 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
450 if (ret < 0)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700451 hdd_err("NDI delete request failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700452 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700453 hdd_err("NDI delete request successfully issued");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700454
455 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700456}
457
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700458/**
459 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
460 * @hdd_ctx: hdd context
461 * @tb: parsed NL attribute list
462 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800463 * tb will contain following vendor attributes:
464 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
465 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
466 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
Ravi Joshi71e82f32017-02-09 23:15:16 -0800467 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG - optional
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800468 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
469 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
470 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
471 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
472 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
473 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
474 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700475 * Return: 0 on success or error code on failure
476 */
477static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx,
478 struct nlattr **tb)
479{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700480 hdd_adapter_t *adapter;
481 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700482 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700483 QDF_STATUS status;
484 uint32_t ndp_qos_cfg;
485 tHalHandle hal = hdd_ctx->hHal;
486 struct nan_datapath_ctx *ndp_ctx;
487
488 ENTER();
489
490 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700491 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700492 return -EINVAL;
493 }
494
495 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
496 /* Check for interface in NDI mode */
497 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
498 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700499 hdd_err("NAN data interface %s not available", iface_name);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700500 return -EINVAL;
501 }
502
503 /* NAN data path coexists only with STA interface */
504 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700505 hdd_err("Unsupported concurrency for NAN datapath");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700506 return -EPERM;
507 }
508
509 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
510
511 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
512 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
513 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700514 hdd_err("Data request not allowed in NDI current state: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700515 ndp_ctx->state);
516 return -EINVAL;
517 }
518
519 req.vdev_id = adapter->sessionId;
520
521 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700522 hdd_err("Transaction ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700523 return -EINVAL;
524 }
525 req.transaction_id =
526 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
527
Naveen Rawat0a017052016-10-19 14:17:07 -0700528 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL])
529 req.channel =
530 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
531
Ravi Joshi71e82f32017-02-09 23:15:16 -0800532 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG])
Naveen Rawat0a017052016-10-19 14:17:07 -0700533 req.channel_cfg =
534 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700535
536 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700537 hdd_err("NDP service instance ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700538 return -EINVAL;
539 }
540 req.service_instance_id =
Naveen Rawat19da3d12016-08-16 12:39:38 -0700541 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700542
543 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
544 adapter->macAddressCurrent.bytes, QDF_MAC_ADDR_SIZE);
545
546 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700547 hdd_err("NDI peer discovery mac addr is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700548 return -EINVAL;
549 }
550 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
551 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
552 QDF_MAC_ADDR_SIZE);
553
Naveen Rawat90ae3082016-06-29 18:22:59 -0700554 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
555 req.ndp_info.ndp_app_info_len =
556 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
557 req.ndp_info.ndp_app_info =
558 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700559 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700560
561 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
562 /* at present ndp config stores 4 bytes QOS info only */
563 req.ndp_config.ndp_cfg_len = 4;
564 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
565 ndp_qos_cfg =
566 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
567 }
568
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800569 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
570 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
571 hdd_err("PMK cannot be absent when CSID is present.");
572 return -EINVAL;
573 }
574
575 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
576 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
577 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
578 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
579 QDF_TRACE_LEVEL_DEBUG,
580 req.pmk.pmk, req.pmk.pmk_len);
581 }
582
583 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
584 req.ncs_sk_type =
585 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
586
587 }
588
Ravi Joshi71e82f32017-02-09 23:15:16 -0800589 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",
590 req.vdev_id, req.transaction_id, req.channel, req.channel_cfg,
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700591 req.service_instance_id, req.ndp_info.ndp_app_info_len,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800592 req.ncs_sk_type, req.peer_discovery_mac_addr.bytes);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700593 status = sme_ndp_initiator_req_handler(hal, &req);
594 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700595 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700596 status);
597 return -ECOMM;
598 }
599 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700600 return 0;
601}
602
603/**
604 * hdd_ndp_responder_req_handler() - NDP responder request handler
605 * @hdd_ctx: hdd context
606 * @tb: parsed NL attribute list
607 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800608 * tb includes following vendor attributes:
609 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
610 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
611 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
612 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
613 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
614 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
615 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
616 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
617 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700618 * Return: 0 on success or error code on failure
619 */
620static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx,
621 struct nlattr **tb)
622{
Abhishek Singh4fef7472016-06-06 11:36:03 -0700623 hdd_adapter_t *adapter;
624 char *iface_name;
625 struct ndp_responder_req req = {0};
626 QDF_STATUS status;
627 int ret = 0;
628 struct nan_datapath_ctx *ndp_ctx;
629 uint32_t ndp_qos_cfg;
630
631 ENTER();
632
633 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700634 hdd_err("Interface name string is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700635 return -EINVAL;
636 }
637
638 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
639 /* Check if there is already an existing NAN interface */
640 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
641 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700642 hdd_err("NAN data interface %s not available", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700643 return -EINVAL;
644 }
645
646 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700647 hdd_err("Interface %s not in NDI mode", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700648 return -EINVAL;
649 }
650
651 /* NAN data path coexists only with STA interface */
652 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700653 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700654 return -EINVAL;
655 }
656
657 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
658
659 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
660 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
661 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700662 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700663 ndp_ctx->state);
664 return -EAGAIN;
665 }
666
667 req.vdev_id = adapter->sessionId;
668
669 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700670 hdd_err("Transaction ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700671 return -EINVAL;
672 }
673 req.transaction_id =
674 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
675
676 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700677 hdd_err("Instance ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700678 return -EINVAL;
679 }
680 req.ndp_instance_id =
681 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
682
683 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700684 hdd_err("ndp_rsp is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700685 return -EINVAL;
686 }
687 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
688
689 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
690 req.ndp_info.ndp_app_info_len =
691 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
692 if (req.ndp_info.ndp_app_info_len) {
693 req.ndp_info.ndp_app_info =
694 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
695 }
696 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700697 hdd_info("NDP app info is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700698 }
699 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
700 /* at present ndp config stores 4 bytes QOS info only */
701 req.ndp_config.ndp_cfg_len = 4;
702 ndp_qos_cfg =
703 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
704 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
705 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700706 hdd_info("NDP config data is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700707 }
708
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800709 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
710 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
711 hdd_err("PMK cannot be absent when CSID is present.");
712 return -EINVAL;
713 }
714
715 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
716 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
717 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
718 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
719 QDF_TRACE_LEVEL_DEBUG,
720 req.pmk.pmk, req.pmk.pmk_len);
721 }
722
723 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
724 req.ncs_sk_type =
725 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
726
727 }
728
729 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 -0700730 req.vdev_id, req.transaction_id, req.ndp_rsp,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800731 req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
732 req.ncs_sk_type);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700733
734 status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req);
735 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700736 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700737 status);
738 ret = -EINVAL;
739 }
740
741 EXIT();
742 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700743}
744
745/**
746 * hdd_ndp_end_req_handler() - NDP end request handler
747 * @hdd_ctx: hdd context
748 * @tb: parsed NL attribute list
749 *
750 * Return: 0 on success or error code on failure
751 */
Naveen Rawatf28315c2016-06-29 18:06:02 -0700752static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700753{
Naveen Rawatf28315c2016-06-29 18:06:02 -0700754 struct ndp_end_req req = {0};
755 QDF_STATUS status;
756 tHalHandle hal = hdd_ctx->hHal;
757
758 ENTER();
759
760 /* NAN data path coexists only with STA interface */
761 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700762 hdd_err("Unsupported concurrency for NAN datapath");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700763 return -EINVAL;
764 }
765
766 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700767 hdd_err("Transaction ID is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700768 return -EINVAL;
769 }
770 req.transaction_id =
771 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
772
773 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700774 hdd_err("NDP instance ID array is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700775 return -EINVAL;
776 }
777
778 req.num_ndp_instances =
779 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
780 sizeof(uint32_t);
781 if (0 >= req.num_ndp_instances) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700782 hdd_err("Num NDP instances is 0");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700783 return -EINVAL;
784 }
785 req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
786
Naveen Rawatba4f6612016-07-05 12:03:16 -0700787 hdd_info("sending ndp_end_req to SME, transaction_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700788 req.transaction_id);
789
790 status = sme_ndp_end_req_handler(hal, &req);
791 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700792 hdd_err("sme_ndp_end_req_handler failed, status: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700793 status);
794 return -ECOMM;
795 }
796 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700797 return 0;
798}
799
800/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700801 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
802 * @adapter: pointer to adapter context
803 * @rsp_params: response parameters
804 *
805 * The function is expected to send a response back to the user space
806 * even if the creation of BSS has failed
807 *
808 * Following vendor event is sent to cfg80211:
809 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
810 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
811 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800812 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700813 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
814 *
815 * Return: none
816 */
817static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
818 void *rsp_params)
819{
820 struct sk_buff *vendor_event;
821 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
822 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
823 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
824 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
825 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700826 bool create_fail = false;
827 uint8_t create_transaction_id = 0;
Naveen Rawate21103f2016-07-08 14:18:00 -0700828 uint32_t create_status = NDP_RSP_STATUS_ERROR;
829 uint32_t create_reason = NDP_NAN_DATA_IFACE_CREATE_FAILED;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700830 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
831 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
832 tCsrRoamInfo roam_info = {0};
833 tSirBssDescription tmp_bss_descp = {0};
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700834
835 ENTER();
836
837 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700838 /* No way the driver can send response back to user space */
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700839 return;
840
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700841 if (ndi_rsp) {
842 create_status = ndi_rsp->status;
Naveen Rawate21103f2016-07-08 14:18:00 -0700843 create_reason = ndi_rsp->reason;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700844 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700845 hdd_err("Invalid ndi create response");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700846 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700847 }
848
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700849 if (ndp_ctx) {
850 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
851 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700852 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700853 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700854 }
855
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700856 if (!sta_ctx) {
857 hdd_err("sta_ctx is NULL");
858 create_fail = true;
859 }
860
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700861 /* notify response to the upper layer */
862 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
863 NULL,
864 data_len,
865 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
866 cds_get_gfp_flags());
867
868 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700869 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700870 create_fail = true;
871 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700872 }
873
874 /* Sub vendor command */
875 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
876 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700877 hdd_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700878 goto nla_put_failure;
879 }
880
881 /* Transaction id */
882 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700883 create_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700884 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700885 goto nla_put_failure;
886 }
887
888 /* Status code */
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800889 if (nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700891 create_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700892 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700893 goto nla_put_failure;
894 }
895
896 /* Status return value */
897 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700898 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawate21103f2016-07-08 14:18:00 -0700899 create_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700900 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700901 goto nla_put_failure;
902 }
903
Naveen Rawatba4f6612016-07-05 12:03:16 -0700904 hdd_info("sub command: %d, value: %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700905 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
906 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700907 hdd_info("create transaction id: %d, value: %d",
908 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
909 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800910 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
911 create_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700912 hdd_info("Return value: %d, value: %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700913 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700914
915 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
916
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700917 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700918 hdd_err("NDI interface successfully created");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700919 ndp_ctx->ndp_create_transaction_id = 0;
920 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700921 wlan_hdd_netif_queue_control(adapter,
922 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
923 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700924 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700925 hdd_err("NDI interface creation failed with reason %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700926 create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700927 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700928
929 /* Something went wrong while starting the BSS */
930 if (create_fail)
931 goto close_ndi;
932
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700933 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
934 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
935 hdd_roam_register_sta(adapter, &roam_info,
936 sta_ctx->broadcast_staid,
937 &bc_mac_addr, &tmp_bss_descp);
938 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
939
940
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700941 EXIT();
942 return;
943
944nla_put_failure:
945 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700946close_ndi:
947 hdd_close_ndi(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700948 return;
949}
950
951/**
952 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
953 * @adapter: pointer to adapter context
954 * @rsp_params: response parameters
955 *
956 * Return: none
957 */
958static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
959 void *rsp_params)
960{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700961 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
962 struct ndi_delete_rsp *ndi_rsp = rsp_params;
Naveen Rawat8d63a592016-06-29 18:30:59 -0700963 struct nan_datapath_ctx *ndp_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700964
965 if (wlan_hdd_validate_context(hdd_ctx))
966 return;
967
968 if (!ndi_rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700969 hdd_err("Invalid ndi delete response");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700970 return;
971 }
972
Naveen Rawat8d63a592016-06-29 18:30:59 -0700973 if (ndi_rsp->status == NDP_RSP_STATUS_SUCCESS)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700974 hdd_err("NDI BSS successfully stopped");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700975 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700976 hdd_err("NDI BSS stop failed with reason %d", ndi_rsp->reason);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700977
978 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
979 ndp_ctx->ndi_delete_rsp_reason = ndi_rsp->reason;
980 ndp_ctx->ndi_delete_rsp_status = ndi_rsp->status;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700981 wlan_hdd_netif_queue_control(adapter,
982 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
983 WLAN_CONTROL_PATH);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700984
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700985 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700986 return;
987}
988
989/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700990 * hdd_ndp_session_end_handler() - NDI session termination handler
991 * @adapter: pointer to adapter context
992 *
993 * Following vendor event is sent to cfg80211:
994 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
995 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
996 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800997 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700998 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
999 *
1000 * Return: none
1001 */
1002void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
1003{
1004 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1005 struct sk_buff *vendor_event;
1006 struct nan_datapath_ctx *ndp_ctx;
1007 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
1008 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
1009
1010 ENTER();
1011
1012 if (wlan_hdd_validate_context(hdd_ctx))
1013 return;
1014
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001015 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1016 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001017 hdd_err("ndp context is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001018 return;
1019 }
1020
1021 /*
1022 * The virtual adapters are stopped and closed even during
1023 * driver unload or stop, the service layer is not required
1024 * to be informed in that case (response is not expected)
1025 */
1026 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001027 hdd_err("NDI interface %s deleted", adapter->dev->name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001028 return;
1029 }
1030
1031 /* notify response to the upper layer */
1032 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1033 NULL,
1034 data_len,
1035 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1036 GFP_KERNEL);
1037
1038 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001039 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001040 return;
1041 }
1042
1043 /* Sub vendor command goes first */
1044 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1045 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001046 hdd_err("VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001047 goto failure;
1048 }
1049
1050 /* Transaction id */
1051 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1052 ndp_ctx->ndp_delete_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001053 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001054 goto failure;
1055 }
1056
1057 /* Status code */
1058 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001059 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001060 ndp_ctx->ndi_delete_rsp_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001061 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001062 goto failure;
1063 }
1064
1065 /* Status return value */
1066 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001067 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1068 ndp_ctx->ndi_delete_rsp_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001069 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001070 goto failure;
1071 }
1072
Naveen Rawatba4f6612016-07-05 12:03:16 -07001073 hdd_info("sub command: %d, value: %d", QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001074 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001075 hdd_info("delete transaction id: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001076 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1077 ndp_ctx->ndp_delete_transaction_id);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001078 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001079 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001080 ndp_ctx->ndi_delete_rsp_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001081 hdd_info("Return value: %d, value: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001082 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1083 ndp_ctx->ndi_delete_rsp_reason);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001084
1085 ndp_ctx->ndp_delete_transaction_id = 0;
1086 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
1087
1088 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1089
1090 EXIT();
1091 return;
1092
1093failure:
1094 kfree_skb(vendor_event);
1095}
1096
1097
1098/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001099 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
1100 * @adapter: pointer to adapter context
1101 * @rsp_params: response parameters
1102 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001103 * Following vendor event is sent to cfg80211:
1104 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1105 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1106 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1107 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001108 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001109 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1110 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001111 * Return: none
1112 */
1113static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter,
1114 void *rsp_params)
1115{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001116 struct sk_buff *vendor_event;
1117 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1118 struct ndp_initiator_rsp *rsp = rsp_params;
1119 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
1120 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
1121
1122 ENTER();
1123
1124 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001125 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001126 return;
1127 }
1128
1129 if (0 != wlan_hdd_validate_context(hdd_ctx))
1130 return;
1131
1132 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1133 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1134 GFP_KERNEL);
1135 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001136 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001137 return;
1138 }
1139
1140 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1141 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1142 goto ndp_initiator_rsp_nla_failed;
1143
1144 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1145 rsp->transaction_id))
1146 goto ndp_initiator_rsp_nla_failed;
1147
1148 if (nla_put_u32(vendor_event,
1149 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1150 rsp->ndp_instance_id))
1151 goto ndp_initiator_rsp_nla_failed;
1152
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001153 if (nla_put_u32(vendor_event,
1154 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001155 rsp->status))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001156 goto ndp_initiator_rsp_nla_failed;
1157
1158 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001159 rsp->reason))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001160 goto ndp_initiator_rsp_nla_failed;
1161
Naveen Rawatba4f6612016-07-05 12:03:16 -07001162 hdd_info("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001163 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1164 rsp->reason);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001165 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1166 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001167 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001168ndp_initiator_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001169 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001170 kfree_skb(vendor_event);
1171 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001172}
1173
1174/**
1175 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
1176 * @adapter: pointer to adapter context
1177 * @ind_params: indication parameters
1178 *
1179 * Return: none
1180 */
1181static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
1182 void *ind_params)
1183{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001184 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
1185 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1186 tSirBssDescription tmp_bss_descp = {0};
1187 tCsrRoamInfo roam_info = {0};
1188 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1189 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1190
1191 ENTER();
1192
1193 if (NULL == ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001194 hdd_err("Invalid new NDP peer params");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001195 return;
1196 }
Naveen Rawatba4f6612016-07-05 12:03:16 -07001197 hdd_info("session_id: %d, peer_mac: %pM, sta_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001198 new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
1199 new_peer_ind->sta_id);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001200
1201 /* save peer in ndp ctx */
1202 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
1203 &new_peer_ind->peer_mac_addr)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001204 hdd_err("Ndp peer table full. cannot save new peer");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001205 return;
1206 }
1207
1208 /* this function is called for each new peer */
1209 ndp_ctx->active_ndp_peers++;
Naveen Rawatba4f6612016-07-05 12:03:16 -07001210 hdd_info("vdev_id: %d, num_peers: %d", adapter->sessionId,
1211 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001212
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001213 hdd_roam_register_sta(adapter, &roam_info, new_peer_ind->sta_id,
1214 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
1215 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
1216 /* perform following steps for first new peer ind */
1217 if (ndp_ctx->active_ndp_peers == 1) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001218 hdd_info("Set ctx connection state to connected");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001219 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
1220 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001221 wlan_hdd_netif_queue_control(adapter,
1222 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001223 }
1224 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001225}
1226
1227/**
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001228 * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001229 * @adapter: pointer to adapter context
1230 * @ind_params: indication parameters
1231 *
1232 * Return: none
1233 */
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001234static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter,
1235 void *ind_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001236{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001237 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1238 struct sme_ndp_peer_ind *peer_ind = ind_params;
1239 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1240 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1241
1242 hdd_roam_deregister_sta(adapter, peer_ind->sta_id);
1243 hdd_delete_peer(sta_ctx, peer_ind->sta_id);
1244 hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
1245
1246 if (--ndp_ctx->active_ndp_peers == 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001247 hdd_info("No more ndp peers.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001248 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
1249 hdd_conn_set_connection_state(adapter,
1250 eConnectionState_NdiDisconnected);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001251 hdd_info("Stop netif tx queues.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001252 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
1253 WLAN_CONTROL_PATH);
1254 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001255}
1256
1257/**
1258 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1259 * @adapter: pointer to adapter context
1260 * @ind_params: indication parameters
1261 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001262 * Following vendor event is sent to cfg80211:
1263 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1264 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1265 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1266 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1267 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1268 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1269 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1270 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1271 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001272 * Return: none
1273 */
1274static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
1275 void *ind_params)
1276{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001277 int idx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001278 uint32_t ndp_qos_config = 0;
1279 struct ndp_confirm_event *ndp_confirm = ind_params;
1280 struct sk_buff *vendor_event;
1281 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1282 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Naveen Rawatf28315c2016-06-29 18:06:02 -07001283 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001284 uint32_t data_len;
1285
1286 ENTER();
1287 if (!ndp_confirm) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001288 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001289 return;
1290 }
1291
1292 if (0 != wlan_hdd_validate_context(hdd_ctx))
1293 return;
1294
Naveen Rawatf28315c2016-06-29 18:06:02 -07001295 /* ndp_confirm is called each time user generated ndp req succeeds */
1296 idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
1297 if (idx == INVALID_PEER_IDX)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001298 hdd_err("can't find addr: %pM in vdev_id: %d, peer table.",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001299 &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId);
Naveen Rawat460be782016-06-29 18:26:22 -07001300 else if (ndp_confirm->rsp_code == NDP_RESPONSE_ACCEPT)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001301 ndp_ctx->active_ndp_sessions[idx]++;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001302
1303 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
Naveen Rawat90ae3082016-06-29 18:22:59 -07001304 + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001305 ndp_confirm->ndp_info.ndp_app_info_len;
1306
Naveen Rawat8d63a592016-06-29 18:30:59 -07001307 if (ndp_confirm->ndp_info.ndp_app_info_len)
1308 data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
1309
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001310 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1311 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1312 GFP_KERNEL);
1313 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001314 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001315 return;
1316 }
1317
1318 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1319 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1320 goto ndp_confirm_nla_failed;
1321
1322 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1323 ndp_confirm->ndp_instance_id))
1324 goto ndp_confirm_nla_failed;
1325
1326 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1327 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1328 goto ndp_confirm_nla_failed;
1329
1330 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1331 IFNAMSIZ, adapter->dev->name))
1332 goto ndp_confirm_nla_failed;
1333
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001334 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001335 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1336 ndp_confirm->ndp_info.ndp_app_info_len,
1337 ndp_confirm->ndp_info.ndp_app_info))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001338 goto ndp_confirm_nla_failed;
1339
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001340 if (nla_put_u32(vendor_event,
1341 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1342 ndp_confirm->rsp_code))
1343 goto ndp_confirm_nla_failed;
1344
Naveen Rawat8d63a592016-06-29 18:30:59 -07001345 if (nla_put_u32(vendor_event,
1346 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1347 ndp_confirm->reason_code))
1348 goto ndp_confirm_nla_failed;
1349
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001350 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001351 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 -07001352 ndp_confirm->ndp_instance_id,
1353 ndp_confirm->peer_ndi_mac_addr.bytes,
Naveen Rawat460be782016-06-29 18:26:22 -07001354 ndp_qos_config, ndp_confirm->rsp_code,
1355 ndp_confirm->reason_code);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001356
Naveen Rawatba4f6612016-07-05 12:03:16 -07001357 hdd_info("NDP confim, ndp app info dump");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001358 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1359 ndp_confirm->ndp_info.ndp_app_info,
1360 ndp_confirm->ndp_info.ndp_app_info_len);
1361 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001362 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001363ndp_confirm_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001364 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001365 kfree_skb(vendor_event);
1366 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001367}
1368
1369/**
1370 * hdd_ndp_indication_handler() - NDP indication handler
1371 * @adapter: pointer to adapter context
1372 * @ind_params: indication parameters
1373 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001374 * Following vendor event is sent to cfg80211:
1375 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1376 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1377 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
Naveen Rawat19da3d12016-08-16 12:39:38 -07001378 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001379 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1380 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1381 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1382 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1383 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001384 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes)
1385 * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001386 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001387 * Return: none
1388 */
1389static void hdd_ndp_indication_handler(hdd_adapter_t *adapter,
1390 void *ind_params)
1391{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001392 struct sk_buff *vendor_event;
1393 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1394 struct ndp_indication_event *event = ind_params;
1395 uint32_t ndp_qos_config;
1396 struct nan_datapath_ctx *ndp_ctx;
1397 uint16_t data_len;
1398
1399 ENTER();
1400 if (!ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001401 hdd_err("Invalid NDP Indication");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001402 return;
1403 }
1404
1405 if (0 != wlan_hdd_validate_context(hdd_ctx))
1406 return;
1407
1408 /* Handle only if adapter is in NDI mode */
1409 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001410 hdd_err("Adapter is not in NDI mode");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001411 return;
1412 }
1413
Naveen Rawatba4f6612016-07-05 12:03:16 -07001414 hdd_info("NDP Indication, policy: %d", event->policy);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001415
1416 /* Policy check */
1417 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001418 hdd_err("NAN datapath is not suported");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001419 return;
1420 }
1421
1422 /* NAN data path coexists only with STA interface */
1423 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001424 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001425 return;
1426 }
1427
1428 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1429
1430 /* check if we are in middle of deleting/creating the interface */
1431 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
1432 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
1433 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001434 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001435 ndp_ctx->state);
1436 return;
1437 }
1438
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001439 data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
1440 event->ndp_info.ndp_app_info_len + event->scid.scid_len +
1441 (10 * NLA_HDRLEN) + NLMSG_HDRLEN;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001442
1443 /* notify response to the upper layer */
1444 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1445 NULL, data_len,
1446 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1447 GFP_KERNEL);
1448 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001449 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001450 return;
1451 }
1452
1453 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1454 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1455 goto ndp_indication_nla_failed;
1456
1457 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1458 IFNAMSIZ, adapter->dev->name))
1459 goto ndp_indication_nla_failed;
1460
Naveen Rawat19da3d12016-08-16 12:39:38 -07001461 if (nla_put_u32(vendor_event,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001462 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1463 event->service_instance_id))
1464 goto ndp_indication_nla_failed;
1465
1466 if (nla_put(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1468 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1469 goto ndp_indication_nla_failed;
1470
1471 if (nla_put(vendor_event,
Jeff Johnson03294f12016-12-09 17:10:24 -08001472 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001473 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1474 goto ndp_indication_nla_failed;
1475
1476 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1477 event->ndp_instance_id))
1478 goto ndp_indication_nla_failed;
1479
1480 if (event->ndp_info.ndp_app_info_len)
1481 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1482 event->ndp_info.ndp_app_info_len,
1483 event->ndp_info.ndp_app_info))
1484 goto ndp_indication_nla_failed;
1485
1486 if (event->ndp_config.ndp_cfg_len) {
1487 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1488 /* at present ndp config stores 4 bytes QOS info only */
1489 if (nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1491 ndp_qos_config))
1492 goto ndp_indication_nla_failed;
1493 }
1494
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001495 if (event->scid.scid_len) {
1496 if (nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE,
1498 event->ncs_sk_type))
1499 goto ndp_indication_nla_failed;
1500
1501 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
1502 event->scid.scid_len,
1503 event->scid.scid))
1504 goto ndp_indication_nla_failed;
1505
1506 hdd_info("csid: %d, scid_len: %d",
1507 event->ncs_sk_type, event->scid.scid_len);
1508
1509 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1510 event->scid.scid, event->scid.scid_len);
1511 }
1512
Abhishek Singh4fef7472016-06-06 11:36:03 -07001513 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1514 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001515 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001516ndp_indication_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001517 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001518 kfree_skb(vendor_event);
1519 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001520}
1521
1522/**
1523 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1524 * @adapter: pointer to adapter context
1525 * @rsp_params: response parameters
1526 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001527 * Following vendor event is sent to cfg80211:
1528 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1529 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1530 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001531 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1532 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001533 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001534 * Return: none
1535 */
1536static void hdd_ndp_responder_rsp_handler(hdd_adapter_t *adapter,
1537 void *rsp_params)
1538{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001539 struct sk_buff *vendor_event;
1540 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1541 struct ndp_responder_rsp_event *rsp = rsp_params;
1542 uint16_t data_len;
1543
1544 ENTER();
1545 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001546 hdd_err("Invalid NDP Responder response");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001547 return;
1548 }
1549
1550 if (0 != wlan_hdd_validate_context(hdd_ctx))
1551 return;
1552
Naveen Rawatba4f6612016-07-05 12:03:16 -07001553 hdd_info("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001554 rsp->vdev_id, rsp->transaction_id,
1555 rsp->status, rsp->reason);
1556
1557 data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
1558 4 * NLA_HDRLEN + NLMSG_HDRLEN;
1559 /* notify response to the upper layer */
1560 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1561 NULL, data_len,
1562 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1563 GFP_KERNEL);
1564 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001565 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001566 return;
1567 }
1568
1569 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1570 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1571 goto ndp_responder_rsp_nla_failed;
1572
1573 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1574 rsp->transaction_id))
1575 goto ndp_responder_rsp_nla_failed;
1576
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001577 if (nla_put_u32(vendor_event,
1578 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001579 rsp->status))
1580 goto ndp_responder_rsp_nla_failed;
1581
1582 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001583 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001584 rsp->reason))
1585 goto ndp_responder_rsp_nla_failed;
1586
1587 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1588 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001589 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001590ndp_responder_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001591 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001592 kfree_skb(vendor_event);
1593 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001594}
1595
1596/**
1597 * hdd_ndp_end_rsp_handler() - NDP end response handler
1598 * @adapter: pointer to adapter context
1599 * @rsp_params: response parameters
1600 *
Naveen Rawatf28315c2016-06-29 18:06:02 -07001601 * Following vendor event is sent to cfg80211:
1602 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1603 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001604 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001605 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1606 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1607 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001608 * Return: none
1609 */
Naveen Rawatf28315c2016-06-29 18:06:02 -07001610static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, void *rsp_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001611{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001612 struct sk_buff *vendor_event;
1613 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1614 struct ndp_end_rsp_event *rsp = rsp_params;
Rakesh Sunkiae936b62016-07-28 16:01:45 -07001615 uint32_t data_len;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001616
1617 ENTER();
1618
1619 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001620 hdd_err("Invalid ndp end response");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001621 return;
1622 }
1623
1624 if (0 != wlan_hdd_validate_context(hdd_ctx))
1625 return;
1626
Naveen Rawatf28315c2016-06-29 18:06:02 -07001627 data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
1628 sizeof(uint16_t);
1629
1630 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1631 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1632 GFP_KERNEL);
1633 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001634 hdd_err("cfg80211_vendor_event_alloc failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001635 return;
1636 }
1637
1638 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1639 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1640 goto ndp_end_rsp_nla_failed;
1641
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001642 if (nla_put_u32(vendor_event,
1643 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001644 rsp->status))
1645 goto ndp_end_rsp_nla_failed;
1646
1647 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1648 rsp->reason))
1649 goto ndp_end_rsp_nla_failed;
1650
1651 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1652 rsp->transaction_id))
1653 goto ndp_end_rsp_nla_failed;
1654
Naveen Rawatba4f6612016-07-05 12:03:16 -07001655 hdd_info("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001656 rsp->transaction_id, rsp->status, rsp->reason);
1657 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1658 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001659 return;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001660
1661ndp_end_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001662 hdd_err("nla_put api failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001663 kfree_skb(vendor_event);
1664 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001665}
1666
1667/**
1668 * hdd_ndp_end_ind_handler() - NDP end indication handler
1669 * @adapter: pointer to adapter context
1670 * @ind_params: indication parameters
1671 *
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001672 * Following vendor event is sent to cfg80211:
1673 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1674 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001675 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1676 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001677 * Return: none
1678 */
1679static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
1680 void *ind_params)
1681{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001682 struct sk_buff *vendor_event;
1683 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1684 struct ndp_end_indication_event *end_ind = ind_params;
1685 uint32_t data_len, i;
1686 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1687 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1688 uint32_t *ndp_instance_array;
Naveen Rawate21103f2016-07-08 14:18:00 -07001689 hdd_adapter_t *ndi_adapter;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001690
1691 ENTER();
1692
1693 if (!end_ind) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001694 hdd_err("Invalid ndp end indication");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001695 return;
1696 }
1697
1698 if (0 != wlan_hdd_validate_context(hdd_ctx))
1699 return;
1700
1701 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1702 sizeof(*ndp_instance_array));
1703 if (!ndp_instance_array) {
1704 hdd_err("Failed to allocate ndp_instance_array");
1705 return;
1706 }
1707 for (i = 0; i < end_ind->num_ndp_ids; i++) {
1708 int idx;
1709
1710 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
Naveen Rawate21103f2016-07-08 14:18:00 -07001711 ndi_adapter = hdd_get_adapter_by_vdev(hdd_ctx,
1712 end_ind->ndp_map[i].vdev_id);
1713 if (ndi_adapter == NULL) {
1714 hdd_err("Adapter not found for vdev_id: %d",
1715 end_ind->ndp_map[i].vdev_id);
1716 continue;
1717 }
1718 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
Govind Singhb8475942016-08-12 11:07:09 +05301719 if (!ndp_ctx) {
1720 hdd_err("ndp_ctx is NULL for vdev id: %d",
1721 end_ind->ndp_map[i].vdev_id);
1722 continue;
1723 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001724 idx = hdd_get_peer_idx(sta_ctx,
1725 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1726 if (idx == INVALID_PEER_IDX) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001727 hdd_err("can't find addr: %pM in sta_ctx.",
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001728 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1729 continue;
1730 }
1731 /* save the value of active sessions on each peer */
1732 ndp_ctx->active_ndp_sessions[idx] =
1733 end_ind->ndp_map[i].num_active_ndp_sessions;
1734 }
1735
Naveen Rawat90ae3082016-06-29 18:22:59 -07001736 data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001737 end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
1738
1739 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1740 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1741 GFP_KERNEL);
1742 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001743 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001744 return;
1745 }
1746
1747 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1748 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1749 goto ndp_end_ind_nla_failed;
1750
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001751 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1752 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1753 ndp_instance_array))
1754 goto ndp_end_ind_nla_failed;
1755
1756 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1757 qdf_mem_free(ndp_instance_array);
1758 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001759 return;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001760
1761ndp_end_ind_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001762 hdd_err("nla_put api failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001763 kfree_skb(vendor_event);
1764 qdf_mem_free(ndp_instance_array);
1765 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001766}
1767
1768/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001769 * hdd_ndp_event_handler() - ndp response and indication handler
1770 * @adapter: adapter context
1771 * @roam_info: pointer to roam_info structure
1772 * @roam_id: roam id as indicated by SME
1773 * @roam_status: roam status
1774 * @roam_result: roam result
1775 *
1776 * Return: none
1777 */
1778void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1779 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1780 eCsrRoamResult roam_result)
1781{
1782 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1783 switch (roam_result) {
Naveen Rawat8d63a592016-06-29 18:30:59 -07001784 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001785 hdd_ndp_iface_create_rsp_handler(adapter,
1786 &roam_info->ndp.ndi_create_params);
1787 break;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001788 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001789 hdd_ndp_iface_delete_rsp_handler(adapter,
1790 &roam_info->ndp.ndi_delete_params);
1791 break;
1792 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1793 hdd_ndp_initiator_rsp_handler(adapter,
1794 &roam_info->ndp.ndp_init_rsp_params);
1795 break;
1796 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1797 hdd_ndp_new_peer_ind_handler(adapter,
1798 &roam_info->ndp.ndp_peer_ind_params);
1799 break;
1800 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1801 hdd_ndp_confirm_ind_handler(adapter,
1802 &roam_info->ndp.ndp_confirm_params);
1803 break;
1804 case eCSR_ROAM_RESULT_NDP_INDICATION:
1805 hdd_ndp_indication_handler(adapter,
1806 &roam_info->ndp.ndp_indication_params);
1807 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001808 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1809 hdd_ndp_responder_rsp_handler(adapter,
1810 &roam_info->ndp.ndp_responder_rsp_params);
1811 break;
1812 case eCSR_ROAM_RESULT_NDP_END_RSP:
1813 hdd_ndp_end_rsp_handler(adapter,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001814 roam_info->ndp.ndp_end_rsp_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001815 break;
1816 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1817 hdd_ndp_peer_departed_ind_handler(adapter,
1818 &roam_info->ndp.ndp_peer_ind_params);
1819 break;
1820 case eCSR_ROAM_RESULT_NDP_END_IND:
1821 hdd_ndp_end_ind_handler(adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001822 roam_info->ndp.ndp_end_ind_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001823 break;
1824 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001825 hdd_err("Unknown NDP response event from SME %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001826 roam_result);
1827 break;
1828 }
1829 }
1830}
1831
1832/**
1833 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1834 * @wiphy: pointer to wireless wiphy structure.
1835 * @wdev: pointer to wireless_dev structure.
1836 * @data: Pointer to the data to be passed via vendor interface
1837 * @data_len:Length of the data to be passed
1838 *
1839 * This function is invoked to handle vendor command
1840 *
1841 * Return: 0 on success, negative errno on failure
1842 */
1843static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1844 struct wireless_dev *wdev, const void *data, int data_len)
1845{
1846 uint32_t ndp_cmd_type;
1847 uint16_t transaction_id;
1848 int ret_val;
1849 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1850 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1851 char *iface_name;
1852
1853 ENTER();
1854
1855 ret_val = wlan_hdd_validate_context(hdd_ctx);
1856 if (ret_val)
1857 return ret_val;
1858
1859 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001860 hdd_err("Command not allowed in FTM mode");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001861 return -EPERM;
1862 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07001863 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001864 hdd_err("NAN datapath is not enabled");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001865 return -EPERM;
1866 }
1867 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1868 data, data_len,
1869 qca_wlan_vendor_ndp_policy)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001870 hdd_err("Invalid NDP vendor command attributes");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001871 return -EINVAL;
1872 }
1873
1874 /* Parse and fetch NDP Command Type*/
1875 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001876 hdd_err("NAN datapath cmd type failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001877 return -EINVAL;
1878 }
1879 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1880
1881 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001882 hdd_err("attr transaction id failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001883 return -EINVAL;
1884 }
1885 transaction_id = nla_get_u16(
1886 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1887
Naveen Rawatf28315c2016-06-29 18:06:02 -07001888 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
1889 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001890 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: %s",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001891 transaction_id, ndp_cmd_type, iface_name);
1892 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001893 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: unspecified",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001894 transaction_id, ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001895 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001896
1897 switch (ndp_cmd_type) {
1898 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
1899 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
1900 break;
1901 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
1902 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
1903 break;
1904 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
1905 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
1906 break;
1907 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
1908 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
1909 break;
1910 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
1911 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
1912 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001913 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001914 hdd_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001915 ret_val = -EINVAL;
1916 break;
1917 }
1918
1919 return ret_val;
1920}
1921
1922/**
1923 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
1924 * @wiphy: pointer to wireless wiphy structure.
1925 * @wdev: pointer to wireless_dev structure.
1926 * @data: Pointer to the data to be passed via vendor interface
1927 * @data_len:Length of the data to be passed
1928 *
1929 * This function is called to send a NAN request to
1930 * firmware. This is an SSR-protected wrapper function.
1931 *
1932 * Return: 0 on success, negative errno on failure
1933 */
1934int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1935 struct wireless_dev *wdev, const void *data, int data_len)
1936{
1937 int ret;
1938
1939 cds_ssr_protect(__func__);
1940 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
1941 cds_ssr_unprotect(__func__);
1942
1943 return ret;
1944}
1945
1946/**
1947 * hdd_init_nan_data_mode() - initialize nan data mode
1948 * @adapter: adapter context
1949 *
1950 * Returns: 0 on success negative error code on error
1951 */
1952int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
1953{
1954 struct net_device *wlan_dev = adapter->dev;
1955 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1956 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1957 QDF_STATUS status;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001958 int32_t ret_val = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001959
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001960 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001961
Dustin Brownd28772b2017-03-17 14:16:07 -07001962 ret_val = hdd_vdev_create(adapter);
1963 if (ret_val) {
1964 hdd_err("failed to create vdev: %d", ret_val);
1965 return ret_val;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001966 }
1967
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001968 /* Register wireless extensions */
1969 ret_val = hdd_register_wext(wlan_dev);
1970 if (0 > ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001971 hdd_err("Wext registration failed with status code %d",
1972 ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001973 ret_val = -EAGAIN;
1974 goto error_register_wext;
1975 }
1976
1977 status = hdd_init_tx_rx(adapter);
1978 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001979 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001980 ret_val = -EAGAIN;
1981 goto error_init_txrx;
1982 }
1983
1984 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
1985
1986 status = hdd_wmm_adapter_init(adapter);
1987 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001988 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001989 ret_val = -EAGAIN;
1990 goto error_wmm_init;
1991 }
1992
1993 set_bit(WMM_INIT_DONE, &adapter->event_flags);
1994
1995 ret_val = wma_cli_set_command((int)adapter->sessionId,
1996 (int)WMI_PDEV_PARAM_BURST_ENABLE,
1997 (int)hdd_ctx->config->enableSifsBurst,
1998 PDEV_CMD);
1999 if (0 != ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002000 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002001 }
2002
2003 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
2004 return ret_val;
2005
2006error_wmm_init:
2007 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2008 hdd_deinit_tx_rx(adapter);
2009
2010error_init_txrx:
2011 hdd_unregister_wext(wlan_dev);
2012
2013error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07002014 QDF_BUG(!hdd_vdev_destroy(adapter));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002015
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002016 return ret_val;
2017}