blob: 699214f13d86874a63d94d883f80e3605f458a0a [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"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070037
38/* NLA policy */
39static const struct nla_policy
40qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
41 [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 },
42 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 },
43 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_STRING,
44 .len = IFNAMSIZ },
Naveen Rawat19da3d12016-08-16 12:39:38 -070045 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070046 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070047 [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = {
Naveen Rawatf28315c2016-06-29 18:06:02 -070048 .type = NLA_BINARY,
49 .len = QDF_MAC_ADDR_SIZE },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070050 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 },
51 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY,
52 .len = NDP_QOS_INFO_LEN },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070053 [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_NDI_MAC_ADDR] = { .type = NLA_BINARY,
58 .len = QDF_MAC_ADDR_SIZE },
Naveen Rawatf28315c2016-06-29 18:06:02 -070059 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY,
60 .len = NDP_NUM_INSTANCE_ID },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070061};
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070062
63/**
64 * hdd_ndp_print_ini_config()- Print nan datapath specific INI configuration
65 * @hdd_ctx: handle to hdd context
66 *
67 * Return: None
68 */
69void hdd_ndp_print_ini_config(hdd_context_t *hdd_ctx)
70{
Naveen Rawatba4f6612016-07-05 12:03:16 -070071 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_DATAPATH_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070072 hdd_ctx->config->enable_nan_datapath);
Naveen Rawatba4f6612016-07-05 12:03:16 -070073 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_NDI_CHANNEL_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070074 hdd_ctx->config->nan_datapath_ndi_channel);
75}
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070076
77/**
78 * hdd_nan_datapath_target_config() - Configure NAN datapath features
79 * @hdd_ctx: Pointer to HDD context
80 * @cfg: Pointer to target device capability information
81 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070082 * NAN datapath functionality is enabled if it is enabled in
83 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070084 *
85 * Return: None
86 */
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070087void hdd_nan_datapath_target_config(hdd_context_t *hdd_ctx,
88 struct wma_tgt_cfg *cfg)
89{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -070090 hdd_ctx->nan_datapath_enabled =
91 hdd_ctx->config->enable_nan_datapath &&
92 cfg->nan_datapath_enabled;
Naveen Rawatba4f6612016-07-05 12:03:16 -070093 hdd_info("enable_nan_datapath: %d", hdd_ctx->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070094}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070095
96/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070097 * hdd_close_ndi() - close NAN Data interface
98 * @adapter: adapter context
99 *
100 * Close the adapter if start BSS fails
101 *
102 * Returns: 0 on success, negative error code otherwise
103 */
104static int hdd_close_ndi(hdd_adapter_t *adapter)
105{
106 int rc;
107 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
108 uint32_t timeout = WLAN_WAIT_TIME_SESSIONOPENCLOSE;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530109 QDF_STATUS qdf_status;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700110
111 ENTER();
112
113 /* check if the adapter is in NAN Data mode */
114 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700115 hdd_err("Interface is not in NDI mode");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700116 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)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700143 hdd_err("session close timeout");
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530144
Rajeev Kumarba778852017-01-06 13:23:04 -0800145 qdf_status = hdd_release_and_destroy_vdev(adapter);
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +0530146 if (QDF_IS_STATUS_ERROR(qdf_status))
147 hdd_err("vdev delete failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700148 }
149 }
150
151 /* We are good to close the adapter */
152 hdd_close_adapter(hdd_ctx, adapter, true);
153
154 EXIT();
155 return 0;
156}
157
158/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700159 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
160 * @hdd_ctx: hdd context
161 *
162 * NDP is not allowed with any other role active except STA.
163 *
164 * Return: true if allowed, false otherwise
165 */
166static bool hdd_is_ndp_allowed(hdd_context_t *hdd_ctx)
167{
168 hdd_adapter_t *adapter;
169 hdd_station_ctx_t *sta_ctx;
170 QDF_STATUS status;
171 hdd_adapter_list_node_t *curr = NULL, *next = NULL;
172
173 status = hdd_get_front_adapter(hdd_ctx, &curr);
174 while (QDF_STATUS_SUCCESS == status) {
175 adapter = curr->pAdapter;
176 if (!adapter)
177 goto next_adapter;
178
179 switch (adapter->device_mode) {
180 case QDF_P2P_GO_MODE:
181 case QDF_SAP_MODE:
182 if (test_bit(SOFTAP_BSS_STARTED,
183 &adapter->event_flags))
184 return false;
185 break;
186 case QDF_P2P_CLIENT_MODE:
187 case QDF_IBSS_MODE:
188 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
189 if (hdd_conn_is_connected(sta_ctx) ||
190 hdd_is_connecting(sta_ctx))
191 return false;
192 break;
193 default:
194 break;
195 }
196next_adapter:
197 status = hdd_get_next_adapter(hdd_ctx, curr, &next);
198 curr = next;
199 }
200
201 return true;
202}
203
204/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700205 * hdd_ndi_start_bss() - Start BSS on NAN data interface
206 * @adapter: adapter context
207 * @operating_channel: channel on which the BSS to be started
208 *
209 * Return: 0 on success, error value on failure
210 */
211static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
212 uint8_t operating_channel)
213{
214 int ret;
215 uint32_t roam_id;
216 hdd_wext_state_t *wext_state =
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -0700217 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700218 tCsrRoamProfile *roam_profile = &wext_state->roamProfile;
219
220 ENTER();
221
222 if (!roam_profile) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700223 hdd_err("No valid roam profile");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700224 return -EINVAL;
225 }
226
227 if (HDD_WMM_USER_MODE_NO_QOS ==
228 (WLAN_HDD_GET_CTX(adapter))->config->WmmMode) {
229 /* QoS not enabled in cfg file*/
230 roam_profile->uapsd_mask = 0;
231 } else {
232 /* QoS enabled, update uapsd mask from cfg file*/
233 roam_profile->uapsd_mask =
234 (WLAN_HDD_GET_CTX(adapter))->config->UapsdMask;
235 }
236
237 roam_profile->csrPersona = adapter->device_mode;
238
239 roam_profile->ChannelInfo.numOfChannels = 1;
240 if (operating_channel) {
241 roam_profile->ChannelInfo.ChannelList = &operating_channel;
242 } else {
243 roam_profile->ChannelInfo.ChannelList[0] =
244 NAN_SOCIAL_CHANNEL_2_4GHZ;
245 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700246
247 roam_profile->SSIDs.numOfSSIDs = 1;
248 roam_profile->SSIDs.SSIDList->SSID.length = 0;
249
250 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
251 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
252 roam_profile->BSSIDs.numOfBSSIDs = 1;
253 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
254 &adapter->macAddressCurrent.bytes[0],
255 QDF_MAC_ADDR_SIZE);
256
257 roam_profile->AuthType.numEntries = 1;
258 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
259 roam_profile->EncryptionType.numEntries = 1;
260 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
261
262 ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
263 adapter->sessionId, roam_profile, &roam_id);
264 if (QDF_STATUS_SUCCESS != ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700265 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
266 adapter->sessionId, ret);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700267 /* change back to NotConnected */
268 hdd_conn_set_connection_state(adapter,
269 eConnectionState_NotConnected);
270 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700271 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700272 }
273
274 roam_profile->ChannelInfo.ChannelList = NULL;
275 roam_profile->ChannelInfo.numOfChannels = 0;
276
277 EXIT();
278
279 return ret;
280}
281
282
283/**
284 * hdd_ndi_create_req_handler() - NDI create request handler
285 * @hdd_ctx: hdd context
286 * @tb: parsed NL attribute list
287 *
288 * Return: 0 on success or error code on failure
289 */
290static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
291 struct nlattr **tb)
292{
293 hdd_adapter_t *adapter;
294 char *iface_name;
295 uint16_t transaction_id;
296 int ret;
297 struct nan_datapath_ctx *ndp_ctx;
298 uint8_t op_channel =
299 hdd_ctx->config->nan_datapath_ndi_channel;
300
301 ENTER();
302
303 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700304 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700305 return -EINVAL;
306 }
307 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
308
309 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700310 hdd_err("transaction id is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700311 return -EINVAL;
312 }
313 transaction_id =
314 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
315
316 /* Check for an existing interface of NDI type */
317 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
318 if (adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700319 hdd_err("Cannot support more than one NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700320 return -EEXIST;
321 }
322
323 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
324 wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
325 true);
326 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700327 hdd_err("hdd_open_adapter failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700328 return -ENOMEM;
329 }
330
331 /*
332 * Create transaction id is required to be saved since the firmware
333 * does not honor the transaction id for create request
334 */
335 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
336 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700337 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700338
339 /*
340 * The NAN data interface has been created at this point.
341 * Unlike traditional device modes, where the higher application
342 * layer initiates connect / join / start, the NAN data interface
343 * does not have any such formal requests. The NDI create request
344 * is responsible for starting the BSS as well.
345 */
346 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
347 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
348 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
349 /* start NDI on the default 2.4 GHz social channel */
350 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
351 }
352 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700353 if (0 > ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700354 hdd_err("NDI start bss failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700355 /* Start BSS failed, delete the interface */
356 hdd_close_ndi(adapter);
357 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700358
359 EXIT();
360 return ret;
361}
362
363/**
364 * hdd_ndi_delete_req_handler() - NDI delete request handler
365 * @hdd_ctx: hdd context
366 * @tb: parsed NL attribute list
367 *
368 * Return: 0 on success or error code on failure
369 */
370static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
371 struct nlattr **tb)
372{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700373 hdd_adapter_t *adapter;
374 char *iface_name;
375 uint16_t transaction_id;
376 struct nan_datapath_ctx *ndp_ctx;
377 int ret;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700378 hdd_station_ctx_t *sta_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700379
380 ENTER();
381
382 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700383 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700384 return -EINVAL;
385 }
386
387 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
388
389 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700390 hdd_err("Transaction id is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700391 return -EINVAL;
392 }
393
394 transaction_id =
395 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
396
397 /* Check if there is already an existing inteface with the same name */
398 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
399 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700400 hdd_err("NAN data interface %s is not available", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700401 return -EINVAL;
402 }
403
404 /* check if adapter is in NDI mode */
405 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700406 hdd_err("Interface %s is not in NDI mode", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700407 return -EINVAL;
408 }
409
410 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
411 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700412 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700413 return -EINVAL;
414 }
415
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700416 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
417 if (!sta_ctx) {
418 hdd_err("sta_ctx is NULL");
419 return -EINVAL;
420 }
421
Naveen Rawatf28315c2016-06-29 18:06:02 -0700422 /* check if there are active peers on the adapter */
423 if (ndp_ctx->active_ndp_peers > 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700424 hdd_err("NDP peers active: %d, cannot delete NDI",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700425 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700426 return -EINVAL;
427 }
428
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700429 /*
430 * Since, the interface is being deleted, remove the
431 * broadcast id.
432 */
433 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
434 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
435
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700436 ndp_ctx->ndp_delete_transaction_id = transaction_id;
437 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
438
439 /* Delete the interface */
440 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
441 if (ret < 0)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700442 hdd_err("NDI delete request failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700443 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700444 hdd_err("NDI delete request successfully issued");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700445
446 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700447}
448
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700449/**
450 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
451 * @hdd_ctx: hdd context
452 * @tb: parsed NL attribute list
453 *
454 * Return: 0 on success or error code on failure
455 */
456static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx,
457 struct nlattr **tb)
458{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700459 hdd_adapter_t *adapter;
460 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700461 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700462 QDF_STATUS status;
463 uint32_t ndp_qos_cfg;
464 tHalHandle hal = hdd_ctx->hHal;
465 struct nan_datapath_ctx *ndp_ctx;
466
467 ENTER();
468
469 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700470 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700471 return -EINVAL;
472 }
473
474 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
475 /* Check for interface in NDI mode */
476 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
477 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700478 hdd_err("NAN data interface %s not available", iface_name);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700479 return -EINVAL;
480 }
481
482 /* NAN data path coexists only with STA interface */
483 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700484 hdd_err("Unsupported concurrency for NAN datapath");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700485 return -EPERM;
486 }
487
488 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
489
490 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
491 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
492 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700493 hdd_err("Data request not allowed in NDI current state: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700494 ndp_ctx->state);
495 return -EINVAL;
496 }
497
498 req.vdev_id = adapter->sessionId;
499
500 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700501 hdd_err("Transaction ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700502 return -EINVAL;
503 }
504 req.transaction_id =
505 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
506
507 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700508 hdd_err("NDP channel is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700509 return -EINVAL;
510 }
511 req.channel =
512 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
513
514 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700515 hdd_err("NDP service instance ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700516 return -EINVAL;
517 }
518 req.service_instance_id =
Naveen Rawat19da3d12016-08-16 12:39:38 -0700519 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700520
521 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
522 adapter->macAddressCurrent.bytes, QDF_MAC_ADDR_SIZE);
523
524 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700525 hdd_err("NDI peer discovery mac addr is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700526 return -EINVAL;
527 }
528 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
529 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
530 QDF_MAC_ADDR_SIZE);
531
Naveen Rawat90ae3082016-06-29 18:22:59 -0700532 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
533 req.ndp_info.ndp_app_info_len =
534 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
535 req.ndp_info.ndp_app_info =
536 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700537 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700538
539 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
540 /* at present ndp config stores 4 bytes QOS info only */
541 req.ndp_config.ndp_cfg_len = 4;
542 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
543 ndp_qos_cfg =
544 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
545 }
546
Naveen Rawatba4f6612016-07-05 12:03:16 -0700547 hdd_info("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, peer_discovery_mac_addr: %pM",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700548 req.vdev_id, req.transaction_id, req.channel,
549 req.service_instance_id, req.ndp_info.ndp_app_info_len,
550 req.peer_discovery_mac_addr.bytes);
551 status = sme_ndp_initiator_req_handler(hal, &req);
552 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700553 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700554 status);
555 return -ECOMM;
556 }
557 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700558 return 0;
559}
560
561/**
562 * hdd_ndp_responder_req_handler() - NDP responder request handler
563 * @hdd_ctx: hdd context
564 * @tb: parsed NL attribute list
565 *
566 * Return: 0 on success or error code on failure
567 */
568static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx,
569 struct nlattr **tb)
570{
Abhishek Singh4fef7472016-06-06 11:36:03 -0700571 hdd_adapter_t *adapter;
572 char *iface_name;
573 struct ndp_responder_req req = {0};
574 QDF_STATUS status;
575 int ret = 0;
576 struct nan_datapath_ctx *ndp_ctx;
577 uint32_t ndp_qos_cfg;
578
579 ENTER();
580
581 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700582 hdd_err("Interface name string is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700583 return -EINVAL;
584 }
585
586 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
587 /* Check if there is already an existing NAN interface */
588 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
589 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700590 hdd_err("NAN data interface %s not available", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700591 return -EINVAL;
592 }
593
594 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700595 hdd_err("Interface %s not in NDI mode", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700596 return -EINVAL;
597 }
598
599 /* NAN data path coexists only with STA interface */
600 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700601 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700602 return -EINVAL;
603 }
604
605 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
606
607 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
608 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
609 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700610 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700611 ndp_ctx->state);
612 return -EAGAIN;
613 }
614
615 req.vdev_id = adapter->sessionId;
616
617 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700618 hdd_err("Transaction ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700619 return -EINVAL;
620 }
621 req.transaction_id =
622 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
623
624 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700625 hdd_err("Instance ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700626 return -EINVAL;
627 }
628 req.ndp_instance_id =
629 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
630
631 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700632 hdd_err("ndp_rsp is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700633 return -EINVAL;
634 }
635 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
636
637 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
638 req.ndp_info.ndp_app_info_len =
639 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
640 if (req.ndp_info.ndp_app_info_len) {
641 req.ndp_info.ndp_app_info =
642 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
643 }
644 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700645 hdd_info("NDP app info is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700646 }
647 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
648 /* at present ndp config stores 4 bytes QOS info only */
649 req.ndp_config.ndp_cfg_len = 4;
650 ndp_qos_cfg =
651 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
652 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
653 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700654 hdd_info("NDP config data is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700655 }
656
Naveen Rawatba4f6612016-07-05 12:03:16 -0700657 hdd_info("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700658 req.vdev_id, req.transaction_id, req.ndp_rsp,
659 req.ndp_instance_id, req.ndp_info.ndp_app_info_len);
660
661 status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req);
662 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700663 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700664 status);
665 ret = -EINVAL;
666 }
667
668 EXIT();
669 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700670}
671
672/**
673 * hdd_ndp_end_req_handler() - NDP end request handler
674 * @hdd_ctx: hdd context
675 * @tb: parsed NL attribute list
676 *
677 * Return: 0 on success or error code on failure
678 */
Naveen Rawatf28315c2016-06-29 18:06:02 -0700679static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700680{
Naveen Rawatf28315c2016-06-29 18:06:02 -0700681 struct ndp_end_req req = {0};
682 QDF_STATUS status;
683 tHalHandle hal = hdd_ctx->hHal;
684
685 ENTER();
686
687 /* NAN data path coexists only with STA interface */
688 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700689 hdd_err("Unsupported concurrency for NAN datapath");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700690 return -EINVAL;
691 }
692
693 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700694 hdd_err("Transaction ID is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700695 return -EINVAL;
696 }
697 req.transaction_id =
698 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
699
700 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700701 hdd_err("NDP instance ID array is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700702 return -EINVAL;
703 }
704
705 req.num_ndp_instances =
706 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
707 sizeof(uint32_t);
708 if (0 >= req.num_ndp_instances) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700709 hdd_err("Num NDP instances is 0");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700710 return -EINVAL;
711 }
712 req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
713
Naveen Rawatba4f6612016-07-05 12:03:16 -0700714 hdd_info("sending ndp_end_req to SME, transaction_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700715 req.transaction_id);
716
717 status = sme_ndp_end_req_handler(hal, &req);
718 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700719 hdd_err("sme_ndp_end_req_handler failed, status: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700720 status);
721 return -ECOMM;
722 }
723 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700724 return 0;
725}
726
727/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700728 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
729 * @adapter: pointer to adapter context
730 * @rsp_params: response parameters
731 *
732 * The function is expected to send a response back to the user space
733 * even if the creation of BSS has failed
734 *
735 * Following vendor event is sent to cfg80211:
736 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
737 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
738 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
739 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
740 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
741 *
742 * Return: none
743 */
744static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
745 void *rsp_params)
746{
747 struct sk_buff *vendor_event;
748 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
749 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
750 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
751 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
752 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700753 bool create_fail = false;
754 uint8_t create_transaction_id = 0;
Naveen Rawate21103f2016-07-08 14:18:00 -0700755 uint32_t create_status = NDP_RSP_STATUS_ERROR;
756 uint32_t create_reason = NDP_NAN_DATA_IFACE_CREATE_FAILED;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700757 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
758 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
759 tCsrRoamInfo roam_info = {0};
760 tSirBssDescription tmp_bss_descp = {0};
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700761
762 ENTER();
763
764 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700765 /* No way the driver can send response back to user space */
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700766 return;
767
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700768 if (ndi_rsp) {
769 create_status = ndi_rsp->status;
Naveen Rawate21103f2016-07-08 14:18:00 -0700770 create_reason = ndi_rsp->reason;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700771 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700772 hdd_err("Invalid ndi create response");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700773 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700774 }
775
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700776 if (ndp_ctx) {
777 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
778 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700779 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700780 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700781 }
782
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700783 if (!sta_ctx) {
784 hdd_err("sta_ctx is NULL");
785 create_fail = true;
786 }
787
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700788 /* notify response to the upper layer */
789 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
790 NULL,
791 data_len,
792 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
793 cds_get_gfp_flags());
794
795 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700796 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700797 create_fail = true;
798 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700799 }
800
801 /* Sub vendor command */
802 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
803 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700804 hdd_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700805 goto nla_put_failure;
806 }
807
808 /* Transaction id */
809 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700810 create_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700811 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700812 goto nla_put_failure;
813 }
814
815 /* Status code */
816 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700817 create_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700818 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700819 goto nla_put_failure;
820 }
821
822 /* Status return value */
823 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700824 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawate21103f2016-07-08 14:18:00 -0700825 create_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700826 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700827 goto nla_put_failure;
828 }
829
Naveen Rawatba4f6612016-07-05 12:03:16 -0700830 hdd_info("sub command: %d, value: %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700831 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
832 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700833 hdd_info("create transaction id: %d, value: %d",
834 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
835 hdd_info("status code: %d, value: %d",
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700836 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, create_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700837 hdd_info("Return value: %d, value: %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700838 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700839
840 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
841
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700842 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700843 hdd_err("NDI interface successfully created");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700844 ndp_ctx->ndp_create_transaction_id = 0;
845 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700846 wlan_hdd_netif_queue_control(adapter,
847 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
848 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700849 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700850 hdd_err("NDI interface creation failed with reason %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700851 create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700852 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700853
854 /* Something went wrong while starting the BSS */
855 if (create_fail)
856 goto close_ndi;
857
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700858 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
859 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
860 hdd_roam_register_sta(adapter, &roam_info,
861 sta_ctx->broadcast_staid,
862 &bc_mac_addr, &tmp_bss_descp);
863 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
864
865
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700866 EXIT();
867 return;
868
869nla_put_failure:
870 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700871close_ndi:
872 hdd_close_ndi(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700873 return;
874}
875
876/**
877 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
878 * @adapter: pointer to adapter context
879 * @rsp_params: response parameters
880 *
881 * Return: none
882 */
883static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
884 void *rsp_params)
885{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700886 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
887 struct ndi_delete_rsp *ndi_rsp = rsp_params;
Naveen Rawat8d63a592016-06-29 18:30:59 -0700888 struct nan_datapath_ctx *ndp_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700889
890 if (wlan_hdd_validate_context(hdd_ctx))
891 return;
892
893 if (!ndi_rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700894 hdd_err("Invalid ndi delete response");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700895 return;
896 }
897
Naveen Rawat8d63a592016-06-29 18:30:59 -0700898 if (ndi_rsp->status == NDP_RSP_STATUS_SUCCESS)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700899 hdd_err("NDI BSS successfully stopped");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700900 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700901 hdd_err("NDI BSS stop failed with reason %d", ndi_rsp->reason);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700902
903 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
904 ndp_ctx->ndi_delete_rsp_reason = ndi_rsp->reason;
905 ndp_ctx->ndi_delete_rsp_status = ndi_rsp->status;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700906 wlan_hdd_netif_queue_control(adapter,
907 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
908 WLAN_CONTROL_PATH);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700909
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700910 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700911 return;
912}
913
914/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700915 * hdd_ndp_session_end_handler() - NDI session termination handler
916 * @adapter: pointer to adapter context
917 *
918 * Following vendor event is sent to cfg80211:
919 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
920 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
921 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
922 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
923 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
924 *
925 * Return: none
926 */
927void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
928{
929 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
930 struct sk_buff *vendor_event;
931 struct nan_datapath_ctx *ndp_ctx;
932 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
933 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
934
935 ENTER();
936
937 if (wlan_hdd_validate_context(hdd_ctx))
938 return;
939
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700940 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
941 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700942 hdd_err("ndp context is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700943 return;
944 }
945
946 /*
947 * The virtual adapters are stopped and closed even during
948 * driver unload or stop, the service layer is not required
949 * to be informed in that case (response is not expected)
950 */
951 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700952 hdd_err("NDI interface %s deleted", adapter->dev->name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700953 return;
954 }
955
956 /* notify response to the upper layer */
957 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
958 NULL,
959 data_len,
960 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
961 GFP_KERNEL);
962
963 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700964 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700965 return;
966 }
967
968 /* Sub vendor command goes first */
969 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
970 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700971 hdd_err("VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700972 goto failure;
973 }
974
975 /* Transaction id */
976 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
977 ndp_ctx->ndp_delete_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700978 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700979 goto failure;
980 }
981
982 /* Status code */
983 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700984 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
985 ndp_ctx->ndi_delete_rsp_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700986 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700987 goto failure;
988 }
989
990 /* Status return value */
991 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700992 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
993 ndp_ctx->ndi_delete_rsp_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700994 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700995 goto failure;
996 }
997
Naveen Rawatba4f6612016-07-05 12:03:16 -0700998 hdd_info("sub command: %d, value: %d", QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700999 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001000 hdd_info("delete transaction id: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001001 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1002 ndp_ctx->ndp_delete_transaction_id);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001003 hdd_info("status code: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001004 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001005 ndp_ctx->ndi_delete_rsp_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001006 hdd_info("Return value: %d, value: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001007 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1008 ndp_ctx->ndi_delete_rsp_reason);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001009
1010 ndp_ctx->ndp_delete_transaction_id = 0;
1011 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
1012
1013 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1014
1015 EXIT();
1016 return;
1017
1018failure:
1019 kfree_skb(vendor_event);
1020}
1021
1022
1023/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001024 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
1025 * @adapter: pointer to adapter context
1026 * @rsp_params: response parameters
1027 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001028 * Following vendor event is sent to cfg80211:
1029 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1030 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1031 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1032 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1033 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
1034 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1035 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001036 * Return: none
1037 */
1038static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter,
1039 void *rsp_params)
1040{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001041 struct sk_buff *vendor_event;
1042 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1043 struct ndp_initiator_rsp *rsp = rsp_params;
1044 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
1045 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
1046
1047 ENTER();
1048
1049 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001050 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001051 return;
1052 }
1053
1054 if (0 != wlan_hdd_validate_context(hdd_ctx))
1055 return;
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) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001061 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001062 return;
1063 }
1064
1065 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1066 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1067 goto ndp_initiator_rsp_nla_failed;
1068
1069 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1070 rsp->transaction_id))
1071 goto ndp_initiator_rsp_nla_failed;
1072
1073 if (nla_put_u32(vendor_event,
1074 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1075 rsp->ndp_instance_id))
1076 goto ndp_initiator_rsp_nla_failed;
1077
1078 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001079 rsp->status))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001080 goto ndp_initiator_rsp_nla_failed;
1081
1082 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001083 rsp->reason))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001084 goto ndp_initiator_rsp_nla_failed;
1085
Naveen Rawatba4f6612016-07-05 12:03:16 -07001086 hdd_info("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001087 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1088 rsp->reason);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001089 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1090 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001091 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001092ndp_initiator_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001093 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001094 kfree_skb(vendor_event);
1095 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001096}
1097
1098/**
1099 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
1100 * @adapter: pointer to adapter context
1101 * @ind_params: indication parameters
1102 *
1103 * Return: none
1104 */
1105static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
1106 void *ind_params)
1107{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001108 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
1109 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1110 tSirBssDescription tmp_bss_descp = {0};
1111 tCsrRoamInfo roam_info = {0};
1112 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1113 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1114
1115 ENTER();
1116
1117 if (NULL == ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001118 hdd_err("Invalid new NDP peer params");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001119 return;
1120 }
Naveen Rawatba4f6612016-07-05 12:03:16 -07001121 hdd_info("session_id: %d, peer_mac: %pM, sta_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001122 new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
1123 new_peer_ind->sta_id);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001124
1125 /* save peer in ndp ctx */
1126 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
1127 &new_peer_ind->peer_mac_addr)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001128 hdd_err("Ndp peer table full. cannot save new peer");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001129 return;
1130 }
1131
1132 /* this function is called for each new peer */
1133 ndp_ctx->active_ndp_peers++;
Naveen Rawatba4f6612016-07-05 12:03:16 -07001134 hdd_info("vdev_id: %d, num_peers: %d", adapter->sessionId,
1135 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001136
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001137 hdd_roam_register_sta(adapter, &roam_info, new_peer_ind->sta_id,
1138 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
1139 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
1140 /* perform following steps for first new peer ind */
1141 if (ndp_ctx->active_ndp_peers == 1) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001142 hdd_info("Set ctx connection state to connected");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001143 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
1144 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001145 wlan_hdd_netif_queue_control(adapter,
1146 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001147 }
1148 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001149}
1150
1151/**
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001152 * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001153 * @adapter: pointer to adapter context
1154 * @ind_params: indication parameters
1155 *
1156 * Return: none
1157 */
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001158static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter,
1159 void *ind_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001160{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001161 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1162 struct sme_ndp_peer_ind *peer_ind = ind_params;
1163 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1164 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1165
1166 hdd_roam_deregister_sta(adapter, peer_ind->sta_id);
1167 hdd_delete_peer(sta_ctx, peer_ind->sta_id);
1168 hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
1169
1170 if (--ndp_ctx->active_ndp_peers == 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001171 hdd_info("No more ndp peers.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001172 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
1173 hdd_conn_set_connection_state(adapter,
1174 eConnectionState_NdiDisconnected);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001175 hdd_info("Stop netif tx queues.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001176 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
1177 WLAN_CONTROL_PATH);
1178 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001179}
1180
1181/**
1182 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1183 * @adapter: pointer to adapter context
1184 * @ind_params: indication parameters
1185 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001186 * Following vendor event is sent to cfg80211:
1187 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1188 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1189 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1190 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1191 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1192 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1193 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1194 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1195 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001196 * Return: none
1197 */
1198static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
1199 void *ind_params)
1200{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001201 int idx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001202 uint32_t ndp_qos_config = 0;
1203 struct ndp_confirm_event *ndp_confirm = ind_params;
1204 struct sk_buff *vendor_event;
1205 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1206 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Naveen Rawatf28315c2016-06-29 18:06:02 -07001207 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001208 uint32_t data_len;
1209
1210 ENTER();
1211 if (!ndp_confirm) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001212 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001213 return;
1214 }
1215
1216 if (0 != wlan_hdd_validate_context(hdd_ctx))
1217 return;
1218
Naveen Rawatf28315c2016-06-29 18:06:02 -07001219 /* ndp_confirm is called each time user generated ndp req succeeds */
1220 idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
1221 if (idx == INVALID_PEER_IDX)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001222 hdd_err("can't find addr: %pM in vdev_id: %d, peer table.",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001223 &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId);
Naveen Rawat460be782016-06-29 18:26:22 -07001224 else if (ndp_confirm->rsp_code == NDP_RESPONSE_ACCEPT)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001225 ndp_ctx->active_ndp_sessions[idx]++;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001226
1227 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
Naveen Rawat90ae3082016-06-29 18:22:59 -07001228 + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001229 ndp_confirm->ndp_info.ndp_app_info_len;
1230
Naveen Rawat8d63a592016-06-29 18:30:59 -07001231 if (ndp_confirm->ndp_info.ndp_app_info_len)
1232 data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
1233
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001234 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1235 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1236 GFP_KERNEL);
1237 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001238 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001239 return;
1240 }
1241
1242 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1243 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1244 goto ndp_confirm_nla_failed;
1245
1246 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1247 ndp_confirm->ndp_instance_id))
1248 goto ndp_confirm_nla_failed;
1249
1250 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1251 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1252 goto ndp_confirm_nla_failed;
1253
1254 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1255 IFNAMSIZ, adapter->dev->name))
1256 goto ndp_confirm_nla_failed;
1257
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001258 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001259 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1260 ndp_confirm->ndp_info.ndp_app_info_len,
1261 ndp_confirm->ndp_info.ndp_app_info))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001262 goto ndp_confirm_nla_failed;
1263
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001264 if (nla_put_u32(vendor_event,
1265 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1266 ndp_confirm->rsp_code))
1267 goto ndp_confirm_nla_failed;
1268
Naveen Rawat8d63a592016-06-29 18:30:59 -07001269 if (nla_put_u32(vendor_event,
1270 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1271 ndp_confirm->reason_code))
1272 goto ndp_confirm_nla_failed;
1273
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001274 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001275 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 -07001276 ndp_confirm->ndp_instance_id,
1277 ndp_confirm->peer_ndi_mac_addr.bytes,
Naveen Rawat460be782016-06-29 18:26:22 -07001278 ndp_qos_config, ndp_confirm->rsp_code,
1279 ndp_confirm->reason_code);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001280
Naveen Rawatba4f6612016-07-05 12:03:16 -07001281 hdd_info("NDP confim, ndp app info dump");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001282 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1283 ndp_confirm->ndp_info.ndp_app_info,
1284 ndp_confirm->ndp_info.ndp_app_info_len);
1285 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001286 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001287ndp_confirm_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001288 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001289 kfree_skb(vendor_event);
1290 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001291}
1292
1293/**
1294 * hdd_ndp_indication_handler() - NDP indication handler
1295 * @adapter: pointer to adapter context
1296 * @ind_params: indication parameters
1297 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001298 * Following vendor event is sent to cfg80211:
1299 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1300 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1301 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
Naveen Rawat19da3d12016-08-16 12:39:38 -07001302 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001303 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1304 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1305 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1306 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1307 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
1308 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001309 * Return: none
1310 */
1311static void hdd_ndp_indication_handler(hdd_adapter_t *adapter,
1312 void *ind_params)
1313{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001314 struct sk_buff *vendor_event;
1315 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1316 struct ndp_indication_event *event = ind_params;
1317 uint32_t ndp_qos_config;
1318 struct nan_datapath_ctx *ndp_ctx;
1319 uint16_t data_len;
1320
1321 ENTER();
1322 if (!ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001323 hdd_err("Invalid NDP Indication");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001324 return;
1325 }
1326
1327 if (0 != wlan_hdd_validate_context(hdd_ctx))
1328 return;
1329
1330 /* Handle only if adapter is in NDI mode */
1331 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001332 hdd_err("Adapter is not in NDI mode");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001333 return;
1334 }
1335
Naveen Rawatba4f6612016-07-05 12:03:16 -07001336 hdd_info("NDP Indication, policy: %d", event->policy);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001337
1338 /* Policy check */
1339 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001340 hdd_err("NAN datapath is not suported");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001341 return;
1342 }
1343
1344 /* NAN data path coexists only with STA interface */
1345 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001346 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001347 return;
1348 }
1349
1350 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1351
1352 /* check if we are in middle of deleting/creating the interface */
1353 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
1354 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
1355 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001356 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001357 ndp_ctx->state);
1358 return;
1359 }
1360
Naveen Rawat19da3d12016-08-16 12:39:38 -07001361 data_len = (4 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
1362 event->ndp_info.ndp_app_info_len + (8 * NLA_HDRLEN) +
Abhishek Singh4fef7472016-06-06 11:36:03 -07001363 NLMSG_HDRLEN;
1364
1365 /* notify response to the upper layer */
1366 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1367 NULL, data_len,
1368 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1369 GFP_KERNEL);
1370 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001371 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001372 return;
1373 }
1374
1375 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1376 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1377 goto ndp_indication_nla_failed;
1378
1379 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1380 IFNAMSIZ, adapter->dev->name))
1381 goto ndp_indication_nla_failed;
1382
Naveen Rawat19da3d12016-08-16 12:39:38 -07001383 if (nla_put_u32(vendor_event,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001384 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1385 event->service_instance_id))
1386 goto ndp_indication_nla_failed;
1387
1388 if (nla_put(vendor_event,
1389 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1390 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1391 goto ndp_indication_nla_failed;
1392
1393 if (nla_put(vendor_event,
Jeff Johnson03294f12016-12-09 17:10:24 -08001394 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001395 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1396 goto ndp_indication_nla_failed;
1397
1398 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1399 event->ndp_instance_id))
1400 goto ndp_indication_nla_failed;
1401
1402 if (event->ndp_info.ndp_app_info_len)
1403 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1404 event->ndp_info.ndp_app_info_len,
1405 event->ndp_info.ndp_app_info))
1406 goto ndp_indication_nla_failed;
1407
1408 if (event->ndp_config.ndp_cfg_len) {
1409 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1410 /* at present ndp config stores 4 bytes QOS info only */
1411 if (nla_put_u32(vendor_event,
1412 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1413 ndp_qos_config))
1414 goto ndp_indication_nla_failed;
1415 }
1416
1417 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1418 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001419 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001420ndp_indication_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001421 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001422 kfree_skb(vendor_event);
1423 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001424}
1425
1426/**
1427 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1428 * @adapter: pointer to adapter context
1429 * @rsp_params: response parameters
1430 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001431 * Following vendor event is sent to cfg80211:
1432 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1433 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1434 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1435 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
1436 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1437 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001438 * Return: none
1439 */
1440static void hdd_ndp_responder_rsp_handler(hdd_adapter_t *adapter,
1441 void *rsp_params)
1442{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001443 struct sk_buff *vendor_event;
1444 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1445 struct ndp_responder_rsp_event *rsp = rsp_params;
1446 uint16_t data_len;
1447
1448 ENTER();
1449 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001450 hdd_err("Invalid NDP Responder response");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001451 return;
1452 }
1453
1454 if (0 != wlan_hdd_validate_context(hdd_ctx))
1455 return;
1456
Naveen Rawatba4f6612016-07-05 12:03:16 -07001457 hdd_info("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001458 rsp->vdev_id, rsp->transaction_id,
1459 rsp->status, rsp->reason);
1460
1461 data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
1462 4 * NLA_HDRLEN + NLMSG_HDRLEN;
1463 /* notify response to the upper layer */
1464 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1465 NULL, data_len,
1466 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1467 GFP_KERNEL);
1468 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001469 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001470 return;
1471 }
1472
1473 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1474 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1475 goto ndp_responder_rsp_nla_failed;
1476
1477 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1478 rsp->transaction_id))
1479 goto ndp_responder_rsp_nla_failed;
1480
1481 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
1482 rsp->status))
1483 goto ndp_responder_rsp_nla_failed;
1484
1485 if (nla_put_u32(vendor_event,
1486 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1487 rsp->reason))
1488 goto ndp_responder_rsp_nla_failed;
1489
1490 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1491 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001492 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001493ndp_responder_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001494 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001495 kfree_skb(vendor_event);
1496 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001497}
1498
1499/**
1500 * hdd_ndp_end_rsp_handler() - NDP end response handler
1501 * @adapter: pointer to adapter context
1502 * @rsp_params: response parameters
1503 *
Naveen Rawatf28315c2016-06-29 18:06:02 -07001504 * Following vendor event is sent to cfg80211:
1505 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1506 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
1507 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
1508 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1509 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1510 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001511 * Return: none
1512 */
Naveen Rawatf28315c2016-06-29 18:06:02 -07001513static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, void *rsp_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001514{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001515 struct sk_buff *vendor_event;
1516 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1517 struct ndp_end_rsp_event *rsp = rsp_params;
Rakesh Sunkiae936b62016-07-28 16:01:45 -07001518 uint32_t data_len;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001519
1520 ENTER();
1521
1522 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001523 hdd_err("Invalid ndp end response");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001524 return;
1525 }
1526
1527 if (0 != wlan_hdd_validate_context(hdd_ctx))
1528 return;
1529
Naveen Rawatf28315c2016-06-29 18:06:02 -07001530 data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
1531 sizeof(uint16_t);
1532
1533 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1534 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1535 GFP_KERNEL);
1536 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001537 hdd_err("cfg80211_vendor_event_alloc failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001538 return;
1539 }
1540
1541 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1542 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1543 goto ndp_end_rsp_nla_failed;
1544
1545 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
1546 rsp->status))
1547 goto ndp_end_rsp_nla_failed;
1548
1549 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1550 rsp->reason))
1551 goto ndp_end_rsp_nla_failed;
1552
1553 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1554 rsp->transaction_id))
1555 goto ndp_end_rsp_nla_failed;
1556
Naveen Rawatba4f6612016-07-05 12:03:16 -07001557 hdd_info("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001558 rsp->transaction_id, rsp->status, rsp->reason);
1559 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1560 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001561 return;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001562
1563ndp_end_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001564 hdd_err("nla_put api failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001565 kfree_skb(vendor_event);
1566 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001567}
1568
1569/**
1570 * hdd_ndp_end_ind_handler() - NDP end indication handler
1571 * @adapter: pointer to adapter context
1572 * @ind_params: indication parameters
1573 *
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001574 * Following vendor event is sent to cfg80211:
1575 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1576 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001577 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1578 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001579 * Return: none
1580 */
1581static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
1582 void *ind_params)
1583{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001584 struct sk_buff *vendor_event;
1585 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1586 struct ndp_end_indication_event *end_ind = ind_params;
1587 uint32_t data_len, i;
1588 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1589 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1590 uint32_t *ndp_instance_array;
Naveen Rawate21103f2016-07-08 14:18:00 -07001591 hdd_adapter_t *ndi_adapter;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001592
1593 ENTER();
1594
1595 if (!end_ind) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001596 hdd_err("Invalid ndp end indication");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001597 return;
1598 }
1599
1600 if (0 != wlan_hdd_validate_context(hdd_ctx))
1601 return;
1602
1603 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1604 sizeof(*ndp_instance_array));
1605 if (!ndp_instance_array) {
1606 hdd_err("Failed to allocate ndp_instance_array");
1607 return;
1608 }
1609 for (i = 0; i < end_ind->num_ndp_ids; i++) {
1610 int idx;
1611
1612 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
Naveen Rawate21103f2016-07-08 14:18:00 -07001613 ndi_adapter = hdd_get_adapter_by_vdev(hdd_ctx,
1614 end_ind->ndp_map[i].vdev_id);
1615 if (ndi_adapter == NULL) {
1616 hdd_err("Adapter not found for vdev_id: %d",
1617 end_ind->ndp_map[i].vdev_id);
1618 continue;
1619 }
1620 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
Govind Singhb8475942016-08-12 11:07:09 +05301621 if (!ndp_ctx) {
1622 hdd_err("ndp_ctx is NULL for vdev id: %d",
1623 end_ind->ndp_map[i].vdev_id);
1624 continue;
1625 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001626 idx = hdd_get_peer_idx(sta_ctx,
1627 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1628 if (idx == INVALID_PEER_IDX) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001629 hdd_err("can't find addr: %pM in sta_ctx.",
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001630 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1631 continue;
1632 }
1633 /* save the value of active sessions on each peer */
1634 ndp_ctx->active_ndp_sessions[idx] =
1635 end_ind->ndp_map[i].num_active_ndp_sessions;
1636 }
1637
Naveen Rawat90ae3082016-06-29 18:22:59 -07001638 data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001639 end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
1640
1641 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1642 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1643 GFP_KERNEL);
1644 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001645 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001646 return;
1647 }
1648
1649 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1650 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1651 goto ndp_end_ind_nla_failed;
1652
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001653 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1654 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1655 ndp_instance_array))
1656 goto ndp_end_ind_nla_failed;
1657
1658 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1659 qdf_mem_free(ndp_instance_array);
1660 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001661 return;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001662
1663ndp_end_ind_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001664 hdd_err("nla_put api failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001665 kfree_skb(vendor_event);
1666 qdf_mem_free(ndp_instance_array);
1667 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001668}
1669
1670/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001671 * hdd_ndp_event_handler() - ndp response and indication handler
1672 * @adapter: adapter context
1673 * @roam_info: pointer to roam_info structure
1674 * @roam_id: roam id as indicated by SME
1675 * @roam_status: roam status
1676 * @roam_result: roam result
1677 *
1678 * Return: none
1679 */
1680void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1681 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1682 eCsrRoamResult roam_result)
1683{
1684 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1685 switch (roam_result) {
Naveen Rawat8d63a592016-06-29 18:30:59 -07001686 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001687 hdd_ndp_iface_create_rsp_handler(adapter,
1688 &roam_info->ndp.ndi_create_params);
1689 break;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001690 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001691 hdd_ndp_iface_delete_rsp_handler(adapter,
1692 &roam_info->ndp.ndi_delete_params);
1693 break;
1694 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1695 hdd_ndp_initiator_rsp_handler(adapter,
1696 &roam_info->ndp.ndp_init_rsp_params);
1697 break;
1698 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1699 hdd_ndp_new_peer_ind_handler(adapter,
1700 &roam_info->ndp.ndp_peer_ind_params);
1701 break;
1702 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1703 hdd_ndp_confirm_ind_handler(adapter,
1704 &roam_info->ndp.ndp_confirm_params);
1705 break;
1706 case eCSR_ROAM_RESULT_NDP_INDICATION:
1707 hdd_ndp_indication_handler(adapter,
1708 &roam_info->ndp.ndp_indication_params);
1709 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001710 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1711 hdd_ndp_responder_rsp_handler(adapter,
1712 &roam_info->ndp.ndp_responder_rsp_params);
1713 break;
1714 case eCSR_ROAM_RESULT_NDP_END_RSP:
1715 hdd_ndp_end_rsp_handler(adapter,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001716 roam_info->ndp.ndp_end_rsp_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001717 break;
1718 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1719 hdd_ndp_peer_departed_ind_handler(adapter,
1720 &roam_info->ndp.ndp_peer_ind_params);
1721 break;
1722 case eCSR_ROAM_RESULT_NDP_END_IND:
1723 hdd_ndp_end_ind_handler(adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001724 roam_info->ndp.ndp_end_ind_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001725 break;
1726 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001727 hdd_err("Unknown NDP response event from SME %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001728 roam_result);
1729 break;
1730 }
1731 }
1732}
1733
1734/**
1735 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1736 * @wiphy: pointer to wireless wiphy structure.
1737 * @wdev: pointer to wireless_dev structure.
1738 * @data: Pointer to the data to be passed via vendor interface
1739 * @data_len:Length of the data to be passed
1740 *
1741 * This function is invoked to handle vendor command
1742 *
1743 * Return: 0 on success, negative errno on failure
1744 */
1745static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1746 struct wireless_dev *wdev, const void *data, int data_len)
1747{
1748 uint32_t ndp_cmd_type;
1749 uint16_t transaction_id;
1750 int ret_val;
1751 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1752 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1753 char *iface_name;
1754
1755 ENTER();
1756
1757 ret_val = wlan_hdd_validate_context(hdd_ctx);
1758 if (ret_val)
1759 return ret_val;
1760
1761 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001762 hdd_err("Command not allowed in FTM mode");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001763 return -EPERM;
1764 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07001765 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001766 hdd_err("NAN datapath is not enabled");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001767 return -EPERM;
1768 }
1769 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1770 data, data_len,
1771 qca_wlan_vendor_ndp_policy)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001772 hdd_err("Invalid NDP vendor command attributes");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001773 return -EINVAL;
1774 }
1775
1776 /* Parse and fetch NDP Command Type*/
1777 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001778 hdd_err("NAN datapath cmd type failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001779 return -EINVAL;
1780 }
1781 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1782
1783 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001784 hdd_err("attr transaction id failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001785 return -EINVAL;
1786 }
1787 transaction_id = nla_get_u16(
1788 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1789
Naveen Rawatf28315c2016-06-29 18:06:02 -07001790 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
1791 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001792 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: %s",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001793 transaction_id, ndp_cmd_type, iface_name);
1794 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001795 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: unspecified",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001796 transaction_id, ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001797 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001798
1799 switch (ndp_cmd_type) {
1800 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
1801 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
1802 break;
1803 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
1804 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
1805 break;
1806 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
1807 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
1808 break;
1809 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
1810 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
1811 break;
1812 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
1813 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
1814 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001815 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001816 hdd_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001817 ret_val = -EINVAL;
1818 break;
1819 }
1820
1821 return ret_val;
1822}
1823
1824/**
1825 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
1826 * @wiphy: pointer to wireless wiphy structure.
1827 * @wdev: pointer to wireless_dev structure.
1828 * @data: Pointer to the data to be passed via vendor interface
1829 * @data_len:Length of the data to be passed
1830 *
1831 * This function is called to send a NAN request to
1832 * firmware. This is an SSR-protected wrapper function.
1833 *
1834 * Return: 0 on success, negative errno on failure
1835 */
1836int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1837 struct wireless_dev *wdev, const void *data, int data_len)
1838{
1839 int ret;
1840
1841 cds_ssr_protect(__func__);
1842 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
1843 cds_ssr_unprotect(__func__);
1844
1845 return ret;
1846}
1847
1848/**
1849 * hdd_init_nan_data_mode() - initialize nan data mode
1850 * @adapter: adapter context
1851 *
1852 * Returns: 0 on success negative error code on error
1853 */
1854int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
1855{
1856 struct net_device *wlan_dev = adapter->dev;
1857 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1858 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1859 QDF_STATUS status;
1860 uint32_t type, sub_type;
1861 int32_t ret_val = 0;
1862 unsigned long rc;
1863 uint32_t timeout = WLAN_WAIT_TIME_SESSIONOPENCLOSE;
1864
1865 INIT_COMPLETION(adapter->session_open_comp_var);
1866 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
1867 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
1868 if (QDF_STATUS_SUCCESS != status) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001869 hdd_err("failed to get vdev type");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001870 goto error_sme_open;
1871 }
1872
1873 /* open sme session for future use */
1874 status = sme_open_session(hdd_ctx->hHal, hdd_sme_roam_callback,
1875 adapter, (uint8_t *)&adapter->macAddressCurrent,
1876 &adapter->sessionId, type, sub_type);
Naveen Rawatcb186cf2016-07-11 13:47:19 -07001877 if (QDF_STATUS_SUCCESS != status) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001878 hdd_err("sme_open_session() failed with status code %d",
Naveen Rawatba4f6612016-07-05 12:03:16 -07001879 status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001880 ret_val = -EAGAIN;
1881 goto error_sme_open;
1882 }
1883
1884 /* Block on a completion variable. Can't wait forever though */
1885 rc = wait_for_completion_timeout(
1886 &adapter->session_open_comp_var,
1887 msecs_to_jiffies(timeout));
1888 if (!rc) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001889 hdd_err("Failed to open session, timeout code: %ld", rc);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001890 ret_val = -ETIMEDOUT;
1891 goto error_sme_open;
1892 }
1893
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301894 status = hdd_create_and_store_vdev(hdd_ctx->hdd_pdev, adapter);
1895 if (QDF_IS_STATUS_ERROR(status)) {
1896 ret_val = -EAGAIN;
1897 goto error_vdev_create;
1898 }
1899
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001900 /* Register wireless extensions */
1901 ret_val = hdd_register_wext(wlan_dev);
1902 if (0 > ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001903 hdd_err("Wext registration failed with status code %d",
1904 ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001905 ret_val = -EAGAIN;
1906 goto error_register_wext;
1907 }
1908
1909 status = hdd_init_tx_rx(adapter);
1910 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001911 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001912 ret_val = -EAGAIN;
1913 goto error_init_txrx;
1914 }
1915
1916 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
1917
1918 status = hdd_wmm_adapter_init(adapter);
1919 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001920 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001921 ret_val = -EAGAIN;
1922 goto error_wmm_init;
1923 }
1924
1925 set_bit(WMM_INIT_DONE, &adapter->event_flags);
1926
1927 ret_val = wma_cli_set_command((int)adapter->sessionId,
1928 (int)WMI_PDEV_PARAM_BURST_ENABLE,
1929 (int)hdd_ctx->config->enableSifsBurst,
1930 PDEV_CMD);
1931 if (0 != ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001932 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001933 }
1934
1935 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
1936 return ret_val;
1937
1938error_wmm_init:
1939 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
1940 hdd_deinit_tx_rx(adapter);
1941
1942error_init_txrx:
1943 hdd_unregister_wext(wlan_dev);
1944
1945error_register_wext:
Rajeev Kumarba778852017-01-06 13:23:04 -08001946 status = hdd_release_and_destroy_vdev(adapter);
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301947 if (QDF_IS_STATUS_ERROR(status))
1948 hdd_err("vdev delete failed");
1949error_vdev_create:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001950 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
1951 INIT_COMPLETION(adapter->session_close_comp_var);
1952 if (QDF_STATUS_SUCCESS ==
1953 sme_close_session(hdd_ctx->hHal,
1954 adapter->sessionId,
1955 hdd_sme_close_session_callback,
1956 adapter)) {
1957 rc = wait_for_completion_timeout(
1958 &adapter->session_close_comp_var,
1959 msecs_to_jiffies(timeout));
1960 if (rc <= 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001961 hdd_err("Session close failed status %ld", rc);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001962 ret_val = -ETIMEDOUT;
1963 }
1964 }
1965 }
1966
1967error_sme_open:
1968 return ret_val;
1969}