blob: 0361fb944f404e65cf7fa643b8b254fb9bc42e4e [file] [log] [blame]
Ravi Joshia063dd92016-05-25 16:43:13 -07001/*
2 * Copyright (c) 2016 The Linux Foundation. All rights reserved.
3 *
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"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070036
37/* NLA policy */
38static const struct nla_policy
39qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
40 [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 },
41 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 },
42 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_STRING,
43 .len = IFNAMSIZ },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070044 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U16 },
45 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070046 [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = {
47 .type = NLA_BINARY,
48 .len = QDF_MAC_ADDR_SIZE },
49 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 },
50 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY,
51 .len = NDP_QOS_INFO_LEN },
52 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN] = { .type = NLA_U16 },
53 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY,
54 .len = NDP_APP_INFO_LEN },
55 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070056 [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070057 [QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_STATUS_CODE] = { .type = NLA_U16 },
58 [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY,
59 .len = QDF_MAC_ADDR_SIZE },
60};
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070061
62/**
63 * hdd_ndp_print_ini_config()- Print nan datapath specific INI configuration
64 * @hdd_ctx: handle to hdd context
65 *
66 * Return: None
67 */
68void hdd_ndp_print_ini_config(hdd_context_t *hdd_ctx)
69{
70 hddLog(LOG2, "Name = [%s] Value = [%u]",
71 CFG_ENABLE_NAN_DATAPATH_NAME,
72 hdd_ctx->config->enable_nan_datapath);
73 hddLog(LOG2, "Name = [%s] Value = [%u]",
74 CFG_ENABLE_NAN_NDI_CHANNEL_NAME,
75 hdd_ctx->config->nan_datapath_ndi_channel);
76}
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070077
78/**
79 * hdd_nan_datapath_target_config() - Configure NAN datapath features
80 * @hdd_ctx: Pointer to HDD context
81 * @cfg: Pointer to target device capability information
82 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070083 * NAN datapath functionality is enabled if it is enabled in
84 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070085 *
86 * Return: None
87 */
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070088void hdd_nan_datapath_target_config(hdd_context_t *hdd_ctx,
89 struct wma_tgt_cfg *cfg)
90{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -070091 hdd_ctx->nan_datapath_enabled =
92 hdd_ctx->config->enable_nan_datapath &&
93 cfg->nan_datapath_enabled;
94 hdd_info(FL("enable_nan_datapath: %d"), hdd_ctx->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070095}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070096
97/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070098 * hdd_close_ndi() - close NAN Data interface
99 * @adapter: adapter context
100 *
101 * Close the adapter if start BSS fails
102 *
103 * Returns: 0 on success, negative error code otherwise
104 */
105static int hdd_close_ndi(hdd_adapter_t *adapter)
106{
107 int rc;
108 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
109 uint32_t timeout = WLAN_WAIT_TIME_SESSIONOPENCLOSE;
110
111 ENTER();
112
113 /* check if the adapter is in NAN Data mode */
114 if (QDF_NDI_MODE != adapter->device_mode) {
115 hdd_err(FL("Interface is not in NDI mode"));
116 return -EINVAL;
117 }
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700118 wlan_hdd_netif_queue_control(adapter,
119 WLAN_NETIF_TX_DISABLE_N_CARRIER,
120 WLAN_CONTROL_PATH);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700121
122#ifdef WLAN_OPEN_SOURCE
123 cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
124#endif
125 hdd_deregister_tx_flow_control(adapter);
126
127#ifdef WLAN_NS_OFFLOAD
128#ifdef WLAN_OPEN_SOURCE
129 cancel_work_sync(&adapter->ipv6NotifierWorkQueue);
130#endif
131#endif
132 /* check if the session is open */
133 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
134 INIT_COMPLETION(adapter->session_close_comp_var);
135 if (QDF_STATUS_SUCCESS == sme_close_session(hdd_ctx->hHal,
136 adapter->sessionId,
137 hdd_sme_close_session_callback, adapter)) {
138 /* Block on a timed completion variable */
139 rc = wait_for_completion_timeout(
140 &adapter->session_close_comp_var,
141 msecs_to_jiffies(timeout));
142 if (!rc)
143 hdd_err(FL("session close timeout"));
144 }
145 }
146
147 /* We are good to close the adapter */
148 hdd_close_adapter(hdd_ctx, adapter, true);
149
150 EXIT();
151 return 0;
152}
153
154/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700155 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
156 * @hdd_ctx: hdd context
157 *
158 * NDP is not allowed with any other role active except STA.
159 *
160 * Return: true if allowed, false otherwise
161 */
162static bool hdd_is_ndp_allowed(hdd_context_t *hdd_ctx)
163{
164 hdd_adapter_t *adapter;
165 hdd_station_ctx_t *sta_ctx;
166 QDF_STATUS status;
167 hdd_adapter_list_node_t *curr = NULL, *next = NULL;
168
169 status = hdd_get_front_adapter(hdd_ctx, &curr);
170 while (QDF_STATUS_SUCCESS == status) {
171 adapter = curr->pAdapter;
172 if (!adapter)
173 goto next_adapter;
174
175 switch (adapter->device_mode) {
176 case QDF_P2P_GO_MODE:
177 case QDF_SAP_MODE:
178 if (test_bit(SOFTAP_BSS_STARTED,
179 &adapter->event_flags))
180 return false;
181 break;
182 case QDF_P2P_CLIENT_MODE:
183 case QDF_IBSS_MODE:
184 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
185 if (hdd_conn_is_connected(sta_ctx) ||
186 hdd_is_connecting(sta_ctx))
187 return false;
188 break;
189 default:
190 break;
191 }
192next_adapter:
193 status = hdd_get_next_adapter(hdd_ctx, curr, &next);
194 curr = next;
195 }
196
197 return true;
198}
199
200/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700201 * hdd_ndi_start_bss() - Start BSS on NAN data interface
202 * @adapter: adapter context
203 * @operating_channel: channel on which the BSS to be started
204 *
205 * Return: 0 on success, error value on failure
206 */
207static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
208 uint8_t operating_channel)
209{
210 int ret;
211 uint32_t roam_id;
212 hdd_wext_state_t *wext_state =
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -0700213 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700214 tCsrRoamProfile *roam_profile = &wext_state->roamProfile;
215
216 ENTER();
217
218 if (!roam_profile) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700219 hdd_err(FL("No valid roam profile"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700220 return -EINVAL;
221 }
222
223 if (HDD_WMM_USER_MODE_NO_QOS ==
224 (WLAN_HDD_GET_CTX(adapter))->config->WmmMode) {
225 /* QoS not enabled in cfg file*/
226 roam_profile->uapsd_mask = 0;
227 } else {
228 /* QoS enabled, update uapsd mask from cfg file*/
229 roam_profile->uapsd_mask =
230 (WLAN_HDD_GET_CTX(adapter))->config->UapsdMask;
231 }
232
233 roam_profile->csrPersona = adapter->device_mode;
234
235 roam_profile->ChannelInfo.numOfChannels = 1;
236 if (operating_channel) {
237 roam_profile->ChannelInfo.ChannelList = &operating_channel;
238 } else {
239 roam_profile->ChannelInfo.ChannelList[0] =
240 NAN_SOCIAL_CHANNEL_2_4GHZ;
241 }
242 hdd_select_cbmode(adapter, operating_channel);
243
244 roam_profile->SSIDs.numOfSSIDs = 1;
245 roam_profile->SSIDs.SSIDList->SSID.length = 0;
246
247 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
248 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
249 roam_profile->BSSIDs.numOfBSSIDs = 1;
250 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
251 &adapter->macAddressCurrent.bytes[0],
252 QDF_MAC_ADDR_SIZE);
253
254 roam_profile->AuthType.numEntries = 1;
255 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
256 roam_profile->EncryptionType.numEntries = 1;
257 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
258
259 ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
260 adapter->sessionId, roam_profile, &roam_id);
261 if (QDF_STATUS_SUCCESS != ret) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700262 hdd_err(
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700263 FL("NDI sme_RoamConnect session %d failed with status %d -> NotConnected"),
264 adapter->sessionId, ret);
265 /* change back to NotConnected */
266 hdd_conn_set_connection_state(adapter,
267 eConnectionState_NotConnected);
268 } else {
269 hddLog(LOG2, FL("sme_RoamConnect issued successfully for NDI"));
270 }
271
272 roam_profile->ChannelInfo.ChannelList = NULL;
273 roam_profile->ChannelInfo.numOfChannels = 0;
274
275 EXIT();
276
277 return ret;
278}
279
280
281/**
282 * hdd_ndi_create_req_handler() - NDI create request handler
283 * @hdd_ctx: hdd context
284 * @tb: parsed NL attribute list
285 *
286 * Return: 0 on success or error code on failure
287 */
288static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
289 struct nlattr **tb)
290{
291 hdd_adapter_t *adapter;
292 char *iface_name;
293 uint16_t transaction_id;
294 int ret;
295 struct nan_datapath_ctx *ndp_ctx;
296 uint8_t op_channel =
297 hdd_ctx->config->nan_datapath_ndi_channel;
298
299 ENTER();
300
301 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700302 hdd_err(FL("Interface name string is unavailable"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700303 return -EINVAL;
304 }
305 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
306
307 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700308 hdd_err(FL("transaction id is unavailable"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700309 return -EINVAL;
310 }
311 transaction_id =
312 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
313
314 /* Check for an existing interface of NDI type */
315 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
316 if (adapter) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700317 hdd_err(FL("Cannot support more than one NDI"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700318 return -EEXIST;
319 }
320
321 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
322 wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
323 true);
324 if (!adapter) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700325 hdd_err(FL("hdd_open_adapter failed"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700326 return -ENOMEM;
327 }
328
329 /*
330 * Create transaction id is required to be saved since the firmware
331 * does not honor the transaction id for create request
332 */
333 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
334 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700335 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700336
337 /*
338 * The NAN data interface has been created at this point.
339 * Unlike traditional device modes, where the higher application
340 * layer initiates connect / join / start, the NAN data interface
341 * does not have any such formal requests. The NDI create request
342 * is responsible for starting the BSS as well.
343 */
344 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
345 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
346 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
347 /* start NDI on the default 2.4 GHz social channel */
348 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
349 }
350 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700351 if (0 > ret) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700352 hdd_err(FL("NDI start bss failed"));
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700353 /* Start BSS failed, delete the interface */
354 hdd_close_ndi(adapter);
355 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700356
357 EXIT();
358 return ret;
359}
360
361/**
362 * hdd_ndi_delete_req_handler() - NDI delete request handler
363 * @hdd_ctx: hdd context
364 * @tb: parsed NL attribute list
365 *
366 * Return: 0 on success or error code on failure
367 */
368static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
369 struct nlattr **tb)
370{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700371 hdd_adapter_t *adapter;
372 char *iface_name;
373 uint16_t transaction_id;
374 struct nan_datapath_ctx *ndp_ctx;
375 int ret;
376
377 ENTER();
378
379 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
380 hdd_err(FL("Interface name string is unavailable"));
381 return -EINVAL;
382 }
383
384 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
385
386 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
387 hdd_err(FL("Transaction id is unavailable"));
388 return -EINVAL;
389 }
390
391 transaction_id =
392 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
393
394 /* Check if there is already an existing inteface with the same name */
395 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
396 if (!adapter) {
397 hdd_err(FL("NAN data interface %s is not available"),
398 iface_name);
399 return -EINVAL;
400 }
401
402 /* check if adapter is in NDI mode */
403 if (QDF_NDI_MODE != adapter->device_mode) {
404 hdd_err(FL("Interface %s is not in NDI mode"),
405 iface_name);
406 return -EINVAL;
407 }
408
409 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
410 if (!ndp_ctx) {
411 hdd_err(FL("ndp_ctx is NULL"));
412 return -EINVAL;
413 }
414
415 /* check if there are active NDP sessions on the adapter */
416 if (ndp_ctx->active_ndp_sessions > 0) {
417 hdd_err(FL("NDP sessions active %d, cannot delete NDI"),
418 ndp_ctx->active_ndp_sessions);
419 return -EINVAL;
420 }
421
422 ndp_ctx->ndp_delete_transaction_id = transaction_id;
423 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
424
425 /* Delete the interface */
426 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
427 if (ret < 0)
428 hdd_err(FL("NDI delete request failed"));
429 else
430 hdd_err(FL("NDI delete request successfully issued"));
431
432 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700433}
434
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700435/**
436 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
437 * @hdd_ctx: hdd context
438 * @tb: parsed NL attribute list
439 *
440 * Return: 0 on success or error code on failure
441 */
442static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx,
443 struct nlattr **tb)
444{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700445 hdd_adapter_t *adapter;
446 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700447 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700448 QDF_STATUS status;
449 uint32_t ndp_qos_cfg;
450 tHalHandle hal = hdd_ctx->hHal;
451 struct nan_datapath_ctx *ndp_ctx;
452
453 ENTER();
454
455 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
456 hdd_err(FL("Interface name string is unavailable"));
457 return -EINVAL;
458 }
459
460 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
461 /* Check for interface in NDI mode */
462 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
463 if (!adapter) {
464 hdd_err(FL("NAN data interface %s not available"),
465 iface_name);
466 return -EINVAL;
467 }
468
469 /* NAN data path coexists only with STA interface */
470 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
471 hdd_err(FL("Unsupported concurrency for NAN datapath"));
472 return -EPERM;
473 }
474
475 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
476
477 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
478 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
479 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
480 hdd_err(FL("Data request not allowed in NDI current state: %d"),
481 ndp_ctx->state);
482 return -EINVAL;
483 }
484
485 req.vdev_id = adapter->sessionId;
486
487 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
488 hdd_err(FL("Transaction ID is unavailable"));
489 return -EINVAL;
490 }
491 req.transaction_id =
492 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
493
494 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
495 hdd_err(FL("NDP channel is unavailable"));
496 return -EINVAL;
497 }
498 req.channel =
499 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
500
501 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
502 hdd_err(FL("NDP service instance ID is unavailable"));
503 return -EINVAL;
504 }
505 req.service_instance_id =
506 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
507
508 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
509 adapter->macAddressCurrent.bytes, QDF_MAC_ADDR_SIZE);
510
511 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
512 hdd_err(FL("NDI peer discovery mac addr is unavailable"));
513 return -EINVAL;
514 }
515 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
516 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
517 QDF_MAC_ADDR_SIZE);
518
519 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN]) {
520 hdd_err(FL("NDP app info len is unavailable"));
521 return -EINVAL;
522 }
523 req.ndp_info.ndp_app_info_len =
524 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN]);
525
526 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
527 hdd_err(FL("NDP app info is unavailable"));
528 return -EINVAL;
529 }
530 req.ndp_info.ndp_app_info =
531 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
532
533 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
534 /* at present ndp config stores 4 bytes QOS info only */
535 req.ndp_config.ndp_cfg_len = 4;
536 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
537 ndp_qos_cfg =
538 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
539 }
540
541 hddLog(LOG1,
542 FL("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, peer_discovery_mac_addr: %pM"),
543 req.vdev_id, req.transaction_id, req.channel,
544 req.service_instance_id, req.ndp_info.ndp_app_info_len,
545 req.peer_discovery_mac_addr.bytes);
546 status = sme_ndp_initiator_req_handler(hal, &req);
547 if (status != QDF_STATUS_SUCCESS) {
548 hdd_err(FL("sme_ndp_initiator_req_handler failed, status: %d"),
549 status);
550 return -ECOMM;
551 }
552 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700553 return 0;
554}
555
556/**
557 * hdd_ndp_responder_req_handler() - NDP responder request handler
558 * @hdd_ctx: hdd context
559 * @tb: parsed NL attribute list
560 *
561 * Return: 0 on success or error code on failure
562 */
563static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx,
564 struct nlattr **tb)
565{
566 return 0;
567}
568
569/**
570 * hdd_ndp_end_req_handler() - NDP end request handler
571 * @hdd_ctx: hdd context
572 * @tb: parsed NL attribute list
573 *
574 * Return: 0 on success or error code on failure
575 */
576static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx,
577 struct nlattr **tb)
578{
579 return 0;
580}
581
582/**
583 * hdd_ndp_schedule_req_handler() - NDP schedule request handler
584 * @hdd_ctx: hdd context
585 * @tb: parsed NL attribute list
586 *
587 * Return: 0 on success or error code on failure
588 */
589static int hdd_ndp_schedule_req_handler(hdd_context_t *hdd_ctx,
590 struct nlattr **tb)
591{
592 return 0;
593}
594
595
596/**
597 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
598 * @adapter: pointer to adapter context
599 * @rsp_params: response parameters
600 *
601 * The function is expected to send a response back to the user space
602 * even if the creation of BSS has failed
603 *
604 * Following vendor event is sent to cfg80211:
605 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
606 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
607 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
608 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
609 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
610 *
611 * Return: none
612 */
613static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
614 void *rsp_params)
615{
616 struct sk_buff *vendor_event;
617 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
618 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
619 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
620 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
621 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700622 bool create_fail = false;
623 uint8_t create_transaction_id = 0;
624 uint8_t create_status = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700625
626 ENTER();
627
628 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700629 /* No way the driver can send response back to user space */
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700630 return;
631
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700632 if (ndi_rsp) {
633 create_status = ndi_rsp->status;
634 } else {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700635 hdd_err(FL("Invalid ndi create response"));
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700636 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700637 }
638
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700639 if (ndp_ctx) {
640 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
641 } else {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700642 hdd_err(FL("ndp_ctx is NULL"));
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700643 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700644 }
645
646 /* notify response to the upper layer */
647 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
648 NULL,
649 data_len,
650 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
651 cds_get_gfp_flags());
652
653 if (!vendor_event) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700654 hdd_err(FL("cfg80211_vendor_event_alloc failed"));
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700655 create_fail = true;
656 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700657 }
658
659 /* Sub vendor command */
660 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
661 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700662 hdd_err(FL("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700663 goto nla_put_failure;
664 }
665
666 /* Transaction id */
667 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700668 create_transaction_id)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700669 hdd_err(FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700670 goto nla_put_failure;
671 }
672
673 /* Status code */
674 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700675 create_status)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700676 hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700677 goto nla_put_failure;
678 }
679
680 /* Status return value */
681 if (nla_put_u32(vendor_event,
682 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0xA5)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700683 hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700684 goto nla_put_failure;
685 }
686
687 hddLog(LOG2, FL("sub command: %d, value: %d"),
688 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
689 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
690 hddLog(LOG2, FL("create transaction id: %d, value: %d"),
691 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700692 create_transaction_id);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700693 hddLog(LOG2, FL("status code: %d, value: %d"),
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700694 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, create_status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700695 hddLog(LOG2, FL("Return value: %d, value: %d"),
696 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0xA5);
697
698 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
699
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700700 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700701 hdd_err(FL("NDI interface successfully created"));
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700702 ndp_ctx->ndp_create_transaction_id = 0;
703 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700704 wlan_hdd_netif_queue_control(adapter,
705 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
706 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700707 } else {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700708 hdd_err(FL("NDI interface creation failed with reason %d"),
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700709 ndi_rsp->reason);
710 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700711
712 /* Something went wrong while starting the BSS */
713 if (create_fail)
714 goto close_ndi;
715
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700716 EXIT();
717 return;
718
719nla_put_failure:
720 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700721close_ndi:
722 hdd_close_ndi(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700723 return;
724}
725
726/**
727 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
728 * @adapter: pointer to adapter context
729 * @rsp_params: response parameters
730 *
731 * Return: none
732 */
733static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
734 void *rsp_params)
735{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700736 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
737 struct ndi_delete_rsp *ndi_rsp = rsp_params;
738
739 if (wlan_hdd_validate_context(hdd_ctx))
740 return;
741
742 if (!ndi_rsp) {
743 hdd_err(FL("Invalid ndi delete response"));
744 return;
745 }
746
747 if (ndi_rsp->status == QDF_STATUS_SUCCESS)
748 hdd_err(FL("NDI BSS successfully stopped"));
749 else
750 hdd_err(FL("NDI BSS stop failed with reason %d"),
751 ndi_rsp->reason);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700752 wlan_hdd_netif_queue_control(adapter,
753 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
754 WLAN_CONTROL_PATH);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700755 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700756 return;
757}
758
759/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700760 * hdd_ndp_session_end_handler() - NDI session termination handler
761 * @adapter: pointer to adapter context
762 *
763 * Following vendor event is sent to cfg80211:
764 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
765 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
766 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
767 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
768 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
769 *
770 * Return: none
771 */
772void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
773{
774 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
775 struct sk_buff *vendor_event;
776 struct nan_datapath_ctx *ndp_ctx;
777 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
778 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
779
780 ENTER();
781
782 if (wlan_hdd_validate_context(hdd_ctx))
783 return;
784
785 /* Handle only if adapter is in NDI mode */
786 if (QDF_NDI_MODE != adapter->device_mode) {
787 hdd_err(FL("Adapter is not in NDI mode"));
788 return;
789 }
790
791 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
792 if (!ndp_ctx) {
793 hdd_err(FL("ndp context is NULL"));
794 return;
795 }
796
797 /*
798 * The virtual adapters are stopped and closed even during
799 * driver unload or stop, the service layer is not required
800 * to be informed in that case (response is not expected)
801 */
802 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
803 hdd_err(FL("NDI interface %s deleted"),
804 adapter->dev->name);
805 return;
806 }
807
808 /* notify response to the upper layer */
809 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
810 NULL,
811 data_len,
812 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
813 GFP_KERNEL);
814
815 if (!vendor_event) {
816 hdd_err(FL("cfg80211_vendor_event_alloc failed"));
817 return;
818 }
819
820 /* Sub vendor command goes first */
821 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
822 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
823 hdd_err(FL("VENDOR_ATTR_NDP_SUBCMD put fail"));
824 goto failure;
825 }
826
827 /* Transaction id */
828 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
829 ndp_ctx->ndp_delete_transaction_id)) {
830 hdd_err(FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"));
831 goto failure;
832 }
833
834 /* Status code */
835 if (nla_put_u32(vendor_event,
836 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, 0x0)) {
837 hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"));
838 goto failure;
839 }
840
841 /* Status return value */
842 if (nla_put_u32(vendor_event,
843 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0x0)) {
844 hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"));
845 goto failure;
846 }
847
848 hddLog(LOG2, FL("sub command: %d, value: %d"),
849 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
850 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
851 hddLog(LOG2, FL("delete transaction id: %d, value: %d"),
852 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
853 ndp_ctx->ndp_delete_transaction_id);
854 hddLog(LOG2, FL("status code: %d, value: %d"),
855 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
856 true);
857 hddLog(LOG2, FL("Return value: %d, value: %d"),
858 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0x5A);
859
860 ndp_ctx->ndp_delete_transaction_id = 0;
861 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
862
863 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
864
865 EXIT();
866 return;
867
868failure:
869 kfree_skb(vendor_event);
870}
871
872
873/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700874 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
875 * @adapter: pointer to adapter context
876 * @rsp_params: response parameters
877 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700878 * Following vendor event is sent to cfg80211:
879 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
880 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
881 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
882 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
883 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
884 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
885 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700886 * Return: none
887 */
888static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter,
889 void *rsp_params)
890{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700891 struct sk_buff *vendor_event;
892 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
893 struct ndp_initiator_rsp *rsp = rsp_params;
894 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
895 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
896
897 ENTER();
898
899 if (!rsp) {
900 hdd_err(FL("Invalid NDP Initator response"));
901 return;
902 }
903
904 if (0 != wlan_hdd_validate_context(hdd_ctx))
905 return;
906
907 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
908 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
909 GFP_KERNEL);
910 if (!vendor_event) {
911 hdd_err(FL("cfg80211_vendor_event_alloc failed"));
912 return;
913 }
914
915 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
916 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
917 goto ndp_initiator_rsp_nla_failed;
918
919 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
920 rsp->transaction_id))
921 goto ndp_initiator_rsp_nla_failed;
922
923 if (nla_put_u32(vendor_event,
924 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
925 rsp->ndp_instance_id))
926 goto ndp_initiator_rsp_nla_failed;
927
928 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
929 rsp->status))
930 goto ndp_initiator_rsp_nla_failed;
931
932 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
933 0))
934 goto ndp_initiator_rsp_nla_failed;
935
936 hddLog(LOG1,
937 FL("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d"),
938 rsp->transaction_id, rsp->ndp_instance_id, rsp->status);
939 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
940 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700941 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700942ndp_initiator_rsp_nla_failed:
943 hdd_err(FL("nla_put api failed"));
944 kfree_skb(vendor_event);
945 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700946}
947
948/**
949 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
950 * @adapter: pointer to adapter context
951 * @ind_params: indication parameters
952 *
953 * Return: none
954 */
955static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
956 void *ind_params)
957{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700958 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
959 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
960 tSirBssDescription tmp_bss_descp = {0};
961 tCsrRoamInfo roam_info = {0};
962 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
963 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700964 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700965
966 ENTER();
967
968 if (NULL == ind_params) {
969 hdd_err(FL("Invalid new NDP peer params"));
970 return;
971 }
972
973 /* save peer in ndp ctx */
974 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
975 &new_peer_ind->peer_mac_addr)) {
976 hdd_err(FL("Ndp peer table full. cannot save new peer"));
977 return;
978 }
979
980 /* this function is called for each new peer */
981 ndp_ctx->active_ndp_peers++;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700982
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700983 hdd_roam_register_sta(adapter, &roam_info, new_peer_ind->sta_id,
984 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
985 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
986 /* perform following steps for first new peer ind */
987 if (ndp_ctx->active_ndp_peers == 1) {
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700988 hdd_ctx->sta_to_adapter[NDP_BROADCAST_STAID] = adapter;
989 hdd_save_peer(sta_ctx, new_peer_ind->sta_id, &bc_mac_addr);
990 hdd_roam_register_sta(adapter, &roam_info, NDP_BROADCAST_STAID,
991 &bc_mac_addr, &tmp_bss_descp);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700992 hddLog(LOG1, FL("Set ctx connection state to connected"));
993 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
994 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700995 wlan_hdd_netif_queue_control(adapter,
996 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700997 }
998 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700999}
1000
1001/**
1002 * hdd_ndp_peer_departed_ind_handler() - NDP peer departed indication handler
1003 * @adapter: pointer to adapter context
1004 * @ind_params: indication parameters
1005 *
1006 * Return: none
1007 */
1008static void hdd_ndp_peer_departed_ind_handler(
1009 hdd_adapter_t *adapter, void *ind_params)
1010{
1011 return;
1012}
1013
1014/**
1015 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1016 * @adapter: pointer to adapter context
1017 * @ind_params: indication parameters
1018 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001019 * Following vendor event is sent to cfg80211:
1020 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1021 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1022 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1023 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1024 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1025 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1026 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1027 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1028 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001029 * Return: none
1030 */
1031static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
1032 void *ind_params)
1033{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001034 uint32_t ndp_qos_config = 0;
1035 struct ndp_confirm_event *ndp_confirm = ind_params;
1036 struct sk_buff *vendor_event;
1037 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1038 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1039 uint32_t data_len;
1040
1041 ENTER();
1042 if (!ndp_confirm) {
1043 hdd_err(FL("Invalid NDP Initator response"));
1044 return;
1045 }
1046
1047 if (0 != wlan_hdd_validate_context(hdd_ctx))
1048 return;
1049
1050 /* ndp_confirm is called each time user generated npd req succeeds */
1051 ndp_ctx->active_ndp_sessions++;
1052
1053 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
1054 sizeof(uint16_t) + NLMSG_HDRLEN + (8 * NLA_HDRLEN) +
1055 ndp_confirm->ndp_info.ndp_app_info_len;
1056
1057 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1058 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1059 GFP_KERNEL);
1060 if (!vendor_event) {
1061 hdd_err(FL("cfg80211_vendor_event_alloc failed"));
1062 return;
1063 }
1064
1065 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1066 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1067 goto ndp_confirm_nla_failed;
1068
1069 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1070 ndp_confirm->ndp_instance_id))
1071 goto ndp_confirm_nla_failed;
1072
1073 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1074 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1075 goto ndp_confirm_nla_failed;
1076
1077 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1078 IFNAMSIZ, adapter->dev->name))
1079 goto ndp_confirm_nla_failed;
1080
1081 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN,
1082 ndp_confirm->ndp_info.ndp_app_info_len))
1083 goto ndp_confirm_nla_failed;
1084
1085 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1087 ndp_confirm->ndp_info.ndp_app_info_len,
1088 ndp_confirm->ndp_info.ndp_app_info))
1089 goto ndp_confirm_nla_failed;
1090
1091 if (ndp_confirm->ndp_config.ndp_cfg_len) {
1092 ndp_qos_config = *((uint32_t *)ndp_confirm->ndp_config.ndp_cfg);
1093 /* at present ndp config stores 4 bytes QOS info only */
1094 if (nla_put_u32(vendor_event,
1095 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1096 ndp_qos_config))
1097 goto ndp_confirm_nla_failed;
1098 }
1099
1100 if (nla_put_u32(vendor_event,
1101 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1102 ndp_confirm->rsp_code))
1103 goto ndp_confirm_nla_failed;
1104
1105 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1106 hddLog(LOG1,
1107 FL("NDP confim sent, ndp instance id: %d, peer addr: %pM, ndp_cfg: %d, rsp_code: %d"),
1108 ndp_confirm->ndp_instance_id,
1109 ndp_confirm->peer_ndi_mac_addr.bytes,
1110 ndp_qos_config, ndp_confirm->rsp_code);
1111
1112 hddLog(LOG1, FL("NDP confim, ndp app info dump"));
1113 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1114 ndp_confirm->ndp_info.ndp_app_info,
1115 ndp_confirm->ndp_info.ndp_app_info_len);
1116 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001117 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001118ndp_confirm_nla_failed:
1119 hdd_err(FL("nla_put api failed"));
1120 kfree_skb(vendor_event);
1121 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001122}
1123
1124/**
1125 * hdd_ndp_indication_handler() - NDP indication handler
1126 * @adapter: pointer to adapter context
1127 * @ind_params: indication parameters
1128 *
1129 * Return: none
1130 */
1131static void hdd_ndp_indication_handler(hdd_adapter_t *adapter,
1132 void *ind_params)
1133{
1134 return;
1135}
1136
1137/**
1138 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1139 * @adapter: pointer to adapter context
1140 * @rsp_params: response parameters
1141 *
1142 * Return: none
1143 */
1144static void hdd_ndp_responder_rsp_handler(hdd_adapter_t *adapter,
1145 void *rsp_params)
1146{
1147 return;
1148}
1149
1150/**
1151 * hdd_ndp_end_rsp_handler() - NDP end response handler
1152 * @adapter: pointer to adapter context
1153 * @rsp_params: response parameters
1154 *
1155 * Return: none
1156 */
1157static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter,
1158 void *rsp_params)
1159{
1160 return;
1161}
1162
1163/**
1164 * hdd_ndp_end_ind_handler() - NDP end indication handler
1165 * @adapter: pointer to adapter context
1166 * @ind_params: indication parameters
1167 *
1168 * Return: none
1169 */
1170static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
1171 void *ind_params)
1172{
1173 return;
1174}
1175
1176/**
1177 * hdd_ndp_schedule_update_rsp_handler() - NDP schedule update response handler
1178 * @adapter: pointer to adapter context
1179 * @rsp_params: response parameters
1180 *
1181 * Return: none
1182 */
1183static void hdd_ndp_schedule_update_rsp_handler(
1184 hdd_adapter_t *adapter, void *rsp_params)
1185{
1186 return;
1187}
1188
1189/**
1190 * hdd_ndp_event_handler() - ndp response and indication handler
1191 * @adapter: adapter context
1192 * @roam_info: pointer to roam_info structure
1193 * @roam_id: roam id as indicated by SME
1194 * @roam_status: roam status
1195 * @roam_result: roam result
1196 *
1197 * Return: none
1198 */
1199void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1200 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1201 eCsrRoamResult roam_result)
1202{
1203 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1204 switch (roam_result) {
1205 case eCSR_ROAM_RESULT_NDP_CREATE_RSP:
1206 hdd_ndp_iface_create_rsp_handler(adapter,
1207 &roam_info->ndp.ndi_create_params);
1208 break;
1209 case eCSR_ROAM_RESULT_NDP_DELETE_RSP:
1210 hdd_ndp_iface_delete_rsp_handler(adapter,
1211 &roam_info->ndp.ndi_delete_params);
1212 break;
1213 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1214 hdd_ndp_initiator_rsp_handler(adapter,
1215 &roam_info->ndp.ndp_init_rsp_params);
1216 break;
1217 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1218 hdd_ndp_new_peer_ind_handler(adapter,
1219 &roam_info->ndp.ndp_peer_ind_params);
1220 break;
1221 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1222 hdd_ndp_confirm_ind_handler(adapter,
1223 &roam_info->ndp.ndp_confirm_params);
1224 break;
1225 case eCSR_ROAM_RESULT_NDP_INDICATION:
1226 hdd_ndp_indication_handler(adapter,
1227 &roam_info->ndp.ndp_indication_params);
1228 break;
1229 case eCSR_ROAM_RESULT_NDP_SCHED_UPDATE_RSP:
1230 hdd_ndp_schedule_update_rsp_handler(adapter,
1231 &roam_info->ndp.ndp_sched_upd_rsp_params);
1232 break;
1233 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1234 hdd_ndp_responder_rsp_handler(adapter,
1235 &roam_info->ndp.ndp_responder_rsp_params);
1236 break;
1237 case eCSR_ROAM_RESULT_NDP_END_RSP:
1238 hdd_ndp_end_rsp_handler(adapter,
1239 &roam_info->ndp.ndp_end_rsp_params);
1240 break;
1241 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1242 hdd_ndp_peer_departed_ind_handler(adapter,
1243 &roam_info->ndp.ndp_peer_ind_params);
1244 break;
1245 case eCSR_ROAM_RESULT_NDP_END_IND:
1246 hdd_ndp_end_ind_handler(adapter,
1247 &roam_info->ndp.ndp_end_ind_params);
1248 break;
1249 default:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001250 hdd_err(FL("Unknown NDP response event from SME %d"),
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001251 roam_result);
1252 break;
1253 }
1254 }
1255}
1256
1257/**
1258 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1259 * @wiphy: pointer to wireless wiphy structure.
1260 * @wdev: pointer to wireless_dev structure.
1261 * @data: Pointer to the data to be passed via vendor interface
1262 * @data_len:Length of the data to be passed
1263 *
1264 * This function is invoked to handle vendor command
1265 *
1266 * Return: 0 on success, negative errno on failure
1267 */
1268static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1269 struct wireless_dev *wdev, const void *data, int data_len)
1270{
1271 uint32_t ndp_cmd_type;
1272 uint16_t transaction_id;
1273 int ret_val;
1274 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1275 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1276 char *iface_name;
1277
1278 ENTER();
1279
1280 ret_val = wlan_hdd_validate_context(hdd_ctx);
1281 if (ret_val)
1282 return ret_val;
1283
1284 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001285 hdd_err(FL("Command not allowed in FTM mode"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001286 return -EPERM;
1287 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07001288 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
1289 hdd_err(FL("NAN datapath is not enabled"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001290 return -EPERM;
1291 }
1292 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1293 data, data_len,
1294 qca_wlan_vendor_ndp_policy)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001295 hdd_err(FL("Invalid NDP vendor command attributes"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001296 return -EINVAL;
1297 }
1298
1299 /* Parse and fetch NDP Command Type*/
1300 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001301 hdd_err(FL("NAN datapath cmd type failed"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001302 return -EINVAL;
1303 }
1304 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1305
1306 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001307 hdd_err(FL("attr transaction id failed"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001308 return -EINVAL;
1309 }
1310 transaction_id = nla_get_u16(
1311 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1312
1313 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001314 hdd_err(FL("Interface name string is unavailable"));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001315 return -EINVAL;
1316 }
1317 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
1318
1319 hddLog(LOG2, FL("Transaction Id: %d NDP Cmd: %d iface_name: %s"),
1320 transaction_id, ndp_cmd_type, iface_name);
1321
1322 switch (ndp_cmd_type) {
1323 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
1324 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
1325 break;
1326 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
1327 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
1328 break;
1329 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
1330 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
1331 break;
1332 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
1333 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
1334 break;
1335 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
1336 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
1337 break;
1338 case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REQUEST:
1339 ret_val = hdd_ndp_schedule_req_handler(hdd_ctx, tb);
1340 break;
1341 default:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001342 hdd_err(FL("Unrecognized NDP vendor cmd %d"),
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001343 ndp_cmd_type);
1344 ret_val = -EINVAL;
1345 break;
1346 }
1347
1348 return ret_val;
1349}
1350
1351/**
1352 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
1353 * @wiphy: pointer to wireless wiphy structure.
1354 * @wdev: pointer to wireless_dev structure.
1355 * @data: Pointer to the data to be passed via vendor interface
1356 * @data_len:Length of the data to be passed
1357 *
1358 * This function is called to send a NAN request to
1359 * firmware. This is an SSR-protected wrapper function.
1360 *
1361 * Return: 0 on success, negative errno on failure
1362 */
1363int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1364 struct wireless_dev *wdev, const void *data, int data_len)
1365{
1366 int ret;
1367
1368 cds_ssr_protect(__func__);
1369 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
1370 cds_ssr_unprotect(__func__);
1371
1372 return ret;
1373}
1374
1375/**
1376 * hdd_init_nan_data_mode() - initialize nan data mode
1377 * @adapter: adapter context
1378 *
1379 * Returns: 0 on success negative error code on error
1380 */
1381int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
1382{
1383 struct net_device *wlan_dev = adapter->dev;
1384 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1385 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1386 QDF_STATUS status;
1387 uint32_t type, sub_type;
1388 int32_t ret_val = 0;
1389 unsigned long rc;
1390 uint32_t timeout = WLAN_WAIT_TIME_SESSIONOPENCLOSE;
1391
1392 INIT_COMPLETION(adapter->session_open_comp_var);
1393 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
1394 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
1395 if (QDF_STATUS_SUCCESS != status) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001396 hdd_err("failed to get vdev type");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001397 goto error_sme_open;
1398 }
1399
1400 /* open sme session for future use */
1401 status = sme_open_session(hdd_ctx->hHal, hdd_sme_roam_callback,
1402 adapter, (uint8_t *)&adapter->macAddressCurrent,
1403 &adapter->sessionId, type, sub_type);
1404 if (QDF_STATUS_SUCCESS == status) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001405 hdd_err("sme_open_session() failed with status code %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001406 status);
1407 ret_val = -EAGAIN;
1408 goto error_sme_open;
1409 }
1410
1411 /* Block on a completion variable. Can't wait forever though */
1412 rc = wait_for_completion_timeout(
1413 &adapter->session_open_comp_var,
1414 msecs_to_jiffies(timeout));
1415 if (!rc) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001416 hdd_err(
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001417 FL("Failed to open session, timeout code: %ld"), rc);
1418 ret_val = -ETIMEDOUT;
1419 goto error_sme_open;
1420 }
1421
1422 /* Register wireless extensions */
1423 ret_val = hdd_register_wext(wlan_dev);
1424 if (0 > ret_val) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001425 hdd_err(FL("Wext registration failed with status code %d"),
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001426 ret_val);
1427 ret_val = -EAGAIN;
1428 goto error_register_wext;
1429 }
1430
1431 status = hdd_init_tx_rx(adapter);
1432 if (QDF_STATUS_SUCCESS != status) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001433 hdd_err(FL("hdd_init_tx_rx() init failed, status %d"),
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001434 status);
1435 ret_val = -EAGAIN;
1436 goto error_init_txrx;
1437 }
1438
1439 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
1440
1441 status = hdd_wmm_adapter_init(adapter);
1442 if (QDF_STATUS_SUCCESS != status) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001443 hdd_err(FL("hdd_wmm_adapter_init() failed, status %d"),
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001444 status);
1445 ret_val = -EAGAIN;
1446 goto error_wmm_init;
1447 }
1448
1449 set_bit(WMM_INIT_DONE, &adapter->event_flags);
1450
1451 ret_val = wma_cli_set_command((int)adapter->sessionId,
1452 (int)WMI_PDEV_PARAM_BURST_ENABLE,
1453 (int)hdd_ctx->config->enableSifsBurst,
1454 PDEV_CMD);
1455 if (0 != ret_val) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001456 hdd_err(FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"),
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001457 ret_val);
1458 }
1459
1460 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
1461 return ret_val;
1462
1463error_wmm_init:
1464 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
1465 hdd_deinit_tx_rx(adapter);
1466
1467error_init_txrx:
1468 hdd_unregister_wext(wlan_dev);
1469
1470error_register_wext:
1471 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
1472 INIT_COMPLETION(adapter->session_close_comp_var);
1473 if (QDF_STATUS_SUCCESS ==
1474 sme_close_session(hdd_ctx->hHal,
1475 adapter->sessionId,
1476 hdd_sme_close_session_callback,
1477 adapter)) {
1478 rc = wait_for_completion_timeout(
1479 &adapter->session_close_comp_var,
1480 msecs_to_jiffies(timeout));
1481 if (rc <= 0) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001482 hdd_err(FL("Session close failed status %ld"),
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001483 rc);
1484 ret_val = -ETIMEDOUT;
1485 }
1486 }
1487 }
1488
1489error_sme_open:
1490 return ret_val;
1491}