blob: 64ee8f085da76d9cae9d76e7e6d4f258ec809f29 [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 },
Naveen Rawat19da3d12016-08-16 12:39:38 -070044 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070045 [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] = {
Naveen Rawatf28315c2016-06-29 18:06:02 -070047 .type = NLA_BINARY,
48 .len = QDF_MAC_ADDR_SIZE },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070049 [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 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070052 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY,
53 .len = NDP_APP_INFO_LEN },
54 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070055 [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070056 [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY,
57 .len = QDF_MAC_ADDR_SIZE },
Naveen Rawatf28315c2016-06-29 18:06:02 -070058 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY,
59 .len = NDP_NUM_INSTANCE_ID },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070060};
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{
Naveen Rawatba4f6612016-07-05 12:03:16 -070070 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_DATAPATH_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070071 hdd_ctx->config->enable_nan_datapath);
Naveen Rawatba4f6612016-07-05 12:03:16 -070072 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_NDI_CHANNEL_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070073 hdd_ctx->config->nan_datapath_ndi_channel);
74}
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070075
76/**
77 * hdd_nan_datapath_target_config() - Configure NAN datapath features
78 * @hdd_ctx: Pointer to HDD context
79 * @cfg: Pointer to target device capability information
80 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070081 * NAN datapath functionality is enabled if it is enabled in
82 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070083 *
84 * Return: None
85 */
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070086void hdd_nan_datapath_target_config(hdd_context_t *hdd_ctx,
87 struct wma_tgt_cfg *cfg)
88{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -070089 hdd_ctx->nan_datapath_enabled =
90 hdd_ctx->config->enable_nan_datapath &&
91 cfg->nan_datapath_enabled;
Naveen Rawatba4f6612016-07-05 12:03:16 -070092 hdd_info("enable_nan_datapath: %d", hdd_ctx->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070093}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070094
95/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070096 * hdd_close_ndi() - close NAN Data interface
97 * @adapter: adapter context
98 *
99 * Close the adapter if start BSS fails
100 *
101 * Returns: 0 on success, negative error code otherwise
102 */
103static int hdd_close_ndi(hdd_adapter_t *adapter)
104{
105 int rc;
106 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
107 uint32_t timeout = WLAN_WAIT_TIME_SESSIONOPENCLOSE;
108
109 ENTER();
110
111 /* check if the adapter is in NAN Data mode */
112 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700113 hdd_err("Interface is not in NDI mode");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700114 return -EINVAL;
115 }
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700116 wlan_hdd_netif_queue_control(adapter,
117 WLAN_NETIF_TX_DISABLE_N_CARRIER,
118 WLAN_CONTROL_PATH);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700119
120#ifdef WLAN_OPEN_SOURCE
121 cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
122#endif
123 hdd_deregister_tx_flow_control(adapter);
124
125#ifdef WLAN_NS_OFFLOAD
126#ifdef WLAN_OPEN_SOURCE
127 cancel_work_sync(&adapter->ipv6NotifierWorkQueue);
128#endif
129#endif
130 /* check if the session is open */
131 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
132 INIT_COMPLETION(adapter->session_close_comp_var);
133 if (QDF_STATUS_SUCCESS == sme_close_session(hdd_ctx->hHal,
134 adapter->sessionId,
135 hdd_sme_close_session_callback, adapter)) {
136 /* Block on a timed completion variable */
137 rc = wait_for_completion_timeout(
138 &adapter->session_close_comp_var,
139 msecs_to_jiffies(timeout));
140 if (!rc)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700141 hdd_err("session close timeout");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700142 }
143 }
144
145 /* We are good to close the adapter */
146 hdd_close_adapter(hdd_ctx, adapter, true);
147
148 EXIT();
149 return 0;
150}
151
152/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700153 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
154 * @hdd_ctx: hdd context
155 *
156 * NDP is not allowed with any other role active except STA.
157 *
158 * Return: true if allowed, false otherwise
159 */
160static bool hdd_is_ndp_allowed(hdd_context_t *hdd_ctx)
161{
162 hdd_adapter_t *adapter;
163 hdd_station_ctx_t *sta_ctx;
164 QDF_STATUS status;
165 hdd_adapter_list_node_t *curr = NULL, *next = NULL;
166
167 status = hdd_get_front_adapter(hdd_ctx, &curr);
168 while (QDF_STATUS_SUCCESS == status) {
169 adapter = curr->pAdapter;
170 if (!adapter)
171 goto next_adapter;
172
173 switch (adapter->device_mode) {
174 case QDF_P2P_GO_MODE:
175 case QDF_SAP_MODE:
176 if (test_bit(SOFTAP_BSS_STARTED,
177 &adapter->event_flags))
178 return false;
179 break;
180 case QDF_P2P_CLIENT_MODE:
181 case QDF_IBSS_MODE:
182 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
183 if (hdd_conn_is_connected(sta_ctx) ||
184 hdd_is_connecting(sta_ctx))
185 return false;
186 break;
187 default:
188 break;
189 }
190next_adapter:
191 status = hdd_get_next_adapter(hdd_ctx, curr, &next);
192 curr = next;
193 }
194
195 return true;
196}
197
198/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700199 * hdd_ndi_start_bss() - Start BSS on NAN data interface
200 * @adapter: adapter context
201 * @operating_channel: channel on which the BSS to be started
202 *
203 * Return: 0 on success, error value on failure
204 */
205static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
206 uint8_t operating_channel)
207{
208 int ret;
209 uint32_t roam_id;
210 hdd_wext_state_t *wext_state =
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -0700211 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700212 tCsrRoamProfile *roam_profile = &wext_state->roamProfile;
213
214 ENTER();
215
216 if (!roam_profile) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700217 hdd_err("No valid roam profile");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700218 return -EINVAL;
219 }
220
221 if (HDD_WMM_USER_MODE_NO_QOS ==
222 (WLAN_HDD_GET_CTX(adapter))->config->WmmMode) {
223 /* QoS not enabled in cfg file*/
224 roam_profile->uapsd_mask = 0;
225 } else {
226 /* QoS enabled, update uapsd mask from cfg file*/
227 roam_profile->uapsd_mask =
228 (WLAN_HDD_GET_CTX(adapter))->config->UapsdMask;
229 }
230
231 roam_profile->csrPersona = adapter->device_mode;
232
233 roam_profile->ChannelInfo.numOfChannels = 1;
234 if (operating_channel) {
235 roam_profile->ChannelInfo.ChannelList = &operating_channel;
236 } else {
237 roam_profile->ChannelInfo.ChannelList[0] =
238 NAN_SOCIAL_CHANNEL_2_4GHZ;
239 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700240
241 roam_profile->SSIDs.numOfSSIDs = 1;
242 roam_profile->SSIDs.SSIDList->SSID.length = 0;
243
244 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
245 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
246 roam_profile->BSSIDs.numOfBSSIDs = 1;
247 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
248 &adapter->macAddressCurrent.bytes[0],
249 QDF_MAC_ADDR_SIZE);
250
251 roam_profile->AuthType.numEntries = 1;
252 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
253 roam_profile->EncryptionType.numEntries = 1;
254 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
255
256 ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
257 adapter->sessionId, roam_profile, &roam_id);
258 if (QDF_STATUS_SUCCESS != ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700259 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
260 adapter->sessionId, ret);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700261 /* change back to NotConnected */
262 hdd_conn_set_connection_state(adapter,
263 eConnectionState_NotConnected);
264 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700265 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700266 }
267
268 roam_profile->ChannelInfo.ChannelList = NULL;
269 roam_profile->ChannelInfo.numOfChannels = 0;
270
271 EXIT();
272
273 return ret;
274}
275
276
277/**
278 * hdd_ndi_create_req_handler() - NDI create request handler
279 * @hdd_ctx: hdd context
280 * @tb: parsed NL attribute list
281 *
282 * Return: 0 on success or error code on failure
283 */
284static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
285 struct nlattr **tb)
286{
287 hdd_adapter_t *adapter;
288 char *iface_name;
289 uint16_t transaction_id;
290 int ret;
291 struct nan_datapath_ctx *ndp_ctx;
292 uint8_t op_channel =
293 hdd_ctx->config->nan_datapath_ndi_channel;
294
295 ENTER();
296
297 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700298 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700299 return -EINVAL;
300 }
301 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
302
303 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700304 hdd_err("transaction id is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700305 return -EINVAL;
306 }
307 transaction_id =
308 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
309
310 /* Check for an existing interface of NDI type */
311 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
312 if (adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700313 hdd_err("Cannot support more than one NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700314 return -EEXIST;
315 }
316
317 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
318 wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
319 true);
320 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700321 hdd_err("hdd_open_adapter failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700322 return -ENOMEM;
323 }
324
325 /*
326 * Create transaction id is required to be saved since the firmware
327 * does not honor the transaction id for create request
328 */
329 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
330 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700331 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700332
333 /*
334 * The NAN data interface has been created at this point.
335 * Unlike traditional device modes, where the higher application
336 * layer initiates connect / join / start, the NAN data interface
337 * does not have any such formal requests. The NDI create request
338 * is responsible for starting the BSS as well.
339 */
340 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
341 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
342 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
343 /* start NDI on the default 2.4 GHz social channel */
344 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
345 }
346 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700347 if (0 > ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700348 hdd_err("NDI start bss failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700349 /* Start BSS failed, delete the interface */
350 hdd_close_ndi(adapter);
351 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700352
353 EXIT();
354 return ret;
355}
356
357/**
358 * hdd_ndi_delete_req_handler() - NDI delete request handler
359 * @hdd_ctx: hdd context
360 * @tb: parsed NL attribute list
361 *
362 * Return: 0 on success or error code on failure
363 */
364static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
365 struct nlattr **tb)
366{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700367 hdd_adapter_t *adapter;
368 char *iface_name;
369 uint16_t transaction_id;
370 struct nan_datapath_ctx *ndp_ctx;
371 int ret;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700372 hdd_station_ctx_t *sta_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700373
374 ENTER();
375
376 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700377 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700378 return -EINVAL;
379 }
380
381 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
382
383 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700384 hdd_err("Transaction id is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700385 return -EINVAL;
386 }
387
388 transaction_id =
389 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
390
391 /* Check if there is already an existing inteface with the same name */
392 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
393 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700394 hdd_err("NAN data interface %s is not available", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700395 return -EINVAL;
396 }
397
398 /* check if adapter is in NDI mode */
399 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700400 hdd_err("Interface %s is not in NDI mode", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700401 return -EINVAL;
402 }
403
404 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
405 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700406 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700407 return -EINVAL;
408 }
409
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700410 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
411 if (!sta_ctx) {
412 hdd_err("sta_ctx is NULL");
413 return -EINVAL;
414 }
415
Naveen Rawatf28315c2016-06-29 18:06:02 -0700416 /* check if there are active peers on the adapter */
417 if (ndp_ctx->active_ndp_peers > 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700418 hdd_err("NDP peers active: %d, cannot delete NDI",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700419 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700420 return -EINVAL;
421 }
422
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700423 /*
424 * Since, the interface is being deleted, remove the
425 * broadcast id.
426 */
427 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
428 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
429
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700430 ndp_ctx->ndp_delete_transaction_id = transaction_id;
431 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
432
433 /* Delete the interface */
434 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
435 if (ret < 0)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700436 hdd_err("NDI delete request failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700437 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700438 hdd_err("NDI delete request successfully issued");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700439
440 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700441}
442
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700443/**
444 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
445 * @hdd_ctx: hdd context
446 * @tb: parsed NL attribute list
447 *
448 * Return: 0 on success or error code on failure
449 */
450static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx,
451 struct nlattr **tb)
452{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700453 hdd_adapter_t *adapter;
454 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700455 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700456 QDF_STATUS status;
457 uint32_t ndp_qos_cfg;
458 tHalHandle hal = hdd_ctx->hHal;
459 struct nan_datapath_ctx *ndp_ctx;
460
461 ENTER();
462
463 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700464 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700465 return -EINVAL;
466 }
467
468 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
469 /* Check for interface in NDI mode */
470 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
471 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700472 hdd_err("NAN data interface %s not available", iface_name);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700473 return -EINVAL;
474 }
475
476 /* NAN data path coexists only with STA interface */
477 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700478 hdd_err("Unsupported concurrency for NAN datapath");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700479 return -EPERM;
480 }
481
482 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
483
484 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
485 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
486 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700487 hdd_err("Data request not allowed in NDI current state: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700488 ndp_ctx->state);
489 return -EINVAL;
490 }
491
492 req.vdev_id = adapter->sessionId;
493
494 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700495 hdd_err("Transaction ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700496 return -EINVAL;
497 }
498 req.transaction_id =
499 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
500
501 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700502 hdd_err("NDP channel is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700503 return -EINVAL;
504 }
505 req.channel =
506 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
507
508 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700509 hdd_err("NDP service instance ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700510 return -EINVAL;
511 }
512 req.service_instance_id =
Naveen Rawat19da3d12016-08-16 12:39:38 -0700513 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700514
515 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
516 adapter->macAddressCurrent.bytes, QDF_MAC_ADDR_SIZE);
517
518 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700519 hdd_err("NDI peer discovery mac addr is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700520 return -EINVAL;
521 }
522 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
523 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
524 QDF_MAC_ADDR_SIZE);
525
Naveen Rawat90ae3082016-06-29 18:22:59 -0700526 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
527 req.ndp_info.ndp_app_info_len =
528 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
529 req.ndp_info.ndp_app_info =
530 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700531 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700532
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
Naveen Rawatba4f6612016-07-05 12:03:16 -0700541 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 -0700542 req.vdev_id, req.transaction_id, req.channel,
543 req.service_instance_id, req.ndp_info.ndp_app_info_len,
544 req.peer_discovery_mac_addr.bytes);
545 status = sme_ndp_initiator_req_handler(hal, &req);
546 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700547 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700548 status);
549 return -ECOMM;
550 }
551 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700552 return 0;
553}
554
555/**
556 * hdd_ndp_responder_req_handler() - NDP responder request handler
557 * @hdd_ctx: hdd context
558 * @tb: parsed NL attribute list
559 *
560 * Return: 0 on success or error code on failure
561 */
562static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx,
563 struct nlattr **tb)
564{
Abhishek Singh4fef7472016-06-06 11:36:03 -0700565 hdd_adapter_t *adapter;
566 char *iface_name;
567 struct ndp_responder_req req = {0};
568 QDF_STATUS status;
569 int ret = 0;
570 struct nan_datapath_ctx *ndp_ctx;
571 uint32_t ndp_qos_cfg;
572
573 ENTER();
574
575 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700576 hdd_err("Interface name string is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700577 return -EINVAL;
578 }
579
580 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
581 /* Check if there is already an existing NAN interface */
582 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
583 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700584 hdd_err("NAN data interface %s not available", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700585 return -EINVAL;
586 }
587
588 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700589 hdd_err("Interface %s not in NDI mode", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700590 return -EINVAL;
591 }
592
593 /* NAN data path coexists only with STA interface */
594 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700595 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700596 return -EINVAL;
597 }
598
599 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
600
601 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
602 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
603 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700604 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700605 ndp_ctx->state);
606 return -EAGAIN;
607 }
608
609 req.vdev_id = adapter->sessionId;
610
611 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700612 hdd_err("Transaction ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700613 return -EINVAL;
614 }
615 req.transaction_id =
616 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
617
618 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700619 hdd_err("Instance ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700620 return -EINVAL;
621 }
622 req.ndp_instance_id =
623 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
624
625 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700626 hdd_err("ndp_rsp is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700627 return -EINVAL;
628 }
629 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
630
631 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
632 req.ndp_info.ndp_app_info_len =
633 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
634 if (req.ndp_info.ndp_app_info_len) {
635 req.ndp_info.ndp_app_info =
636 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
637 }
638 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700639 hdd_info("NDP app info is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700640 }
641 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
642 /* at present ndp config stores 4 bytes QOS info only */
643 req.ndp_config.ndp_cfg_len = 4;
644 ndp_qos_cfg =
645 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
646 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
647 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700648 hdd_info("NDP config data is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700649 }
650
Naveen Rawatba4f6612016-07-05 12:03:16 -0700651 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 -0700652 req.vdev_id, req.transaction_id, req.ndp_rsp,
653 req.ndp_instance_id, req.ndp_info.ndp_app_info_len);
654
655 status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req);
656 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700657 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700658 status);
659 ret = -EINVAL;
660 }
661
662 EXIT();
663 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700664}
665
666/**
667 * hdd_ndp_end_req_handler() - NDP end request handler
668 * @hdd_ctx: hdd context
669 * @tb: parsed NL attribute list
670 *
671 * Return: 0 on success or error code on failure
672 */
Naveen Rawatf28315c2016-06-29 18:06:02 -0700673static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700674{
Naveen Rawatf28315c2016-06-29 18:06:02 -0700675 struct ndp_end_req req = {0};
676 QDF_STATUS status;
677 tHalHandle hal = hdd_ctx->hHal;
678
679 ENTER();
680
681 /* NAN data path coexists only with STA interface */
682 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700683 hdd_err("Unsupported concurrency for NAN datapath");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700684 return -EINVAL;
685 }
686
687 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700688 hdd_err("Transaction ID is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700689 return -EINVAL;
690 }
691 req.transaction_id =
692 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
693
694 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700695 hdd_err("NDP instance ID array is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700696 return -EINVAL;
697 }
698
699 req.num_ndp_instances =
700 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
701 sizeof(uint32_t);
702 if (0 >= req.num_ndp_instances) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700703 hdd_err("Num NDP instances is 0");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700704 return -EINVAL;
705 }
706 req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
707
Naveen Rawatba4f6612016-07-05 12:03:16 -0700708 hdd_info("sending ndp_end_req to SME, transaction_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700709 req.transaction_id);
710
711 status = sme_ndp_end_req_handler(hal, &req);
712 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700713 hdd_err("sme_ndp_end_req_handler failed, status: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700714 status);
715 return -ECOMM;
716 }
717 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700718 return 0;
719}
720
721/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700722 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
723 * @adapter: pointer to adapter context
724 * @rsp_params: response parameters
725 *
726 * The function is expected to send a response back to the user space
727 * even if the creation of BSS has failed
728 *
729 * Following vendor event is sent to cfg80211:
730 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
731 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
732 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
733 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
734 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
735 *
736 * Return: none
737 */
738static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
739 void *rsp_params)
740{
741 struct sk_buff *vendor_event;
742 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
743 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
744 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
745 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
746 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700747 bool create_fail = false;
748 uint8_t create_transaction_id = 0;
Naveen Rawate21103f2016-07-08 14:18:00 -0700749 uint32_t create_status = NDP_RSP_STATUS_ERROR;
750 uint32_t create_reason = NDP_NAN_DATA_IFACE_CREATE_FAILED;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700751 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
752 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
753 tCsrRoamInfo roam_info = {0};
754 tSirBssDescription tmp_bss_descp = {0};
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700755
756 ENTER();
757
758 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700759 /* No way the driver can send response back to user space */
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700760 return;
761
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700762 if (ndi_rsp) {
763 create_status = ndi_rsp->status;
Naveen Rawate21103f2016-07-08 14:18:00 -0700764 create_reason = ndi_rsp->reason;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700765 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700766 hdd_err("Invalid ndi create response");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700767 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700768 }
769
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700770 if (ndp_ctx) {
771 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
772 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700773 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700774 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700775 }
776
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700777 if (!sta_ctx) {
778 hdd_err("sta_ctx is NULL");
779 create_fail = true;
780 }
781
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700782 /* notify response to the upper layer */
783 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
784 NULL,
785 data_len,
786 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
787 cds_get_gfp_flags());
788
789 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700790 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700791 create_fail = true;
792 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700793 }
794
795 /* Sub vendor command */
796 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
797 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700798 hdd_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700799 goto nla_put_failure;
800 }
801
802 /* Transaction id */
803 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700804 create_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700805 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700806 goto nla_put_failure;
807 }
808
809 /* Status code */
810 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700811 create_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700812 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700813 goto nla_put_failure;
814 }
815
816 /* Status return value */
817 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700818 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawate21103f2016-07-08 14:18:00 -0700819 create_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700820 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700821 goto nla_put_failure;
822 }
823
Naveen Rawatba4f6612016-07-05 12:03:16 -0700824 hdd_info("sub command: %d, value: %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700825 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
826 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700827 hdd_info("create transaction id: %d, value: %d",
828 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
829 hdd_info("status code: %d, value: %d",
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700830 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, create_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700831 hdd_info("Return value: %d, value: %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700832 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700833
834 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
835
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700836 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700837 hdd_err("NDI interface successfully created");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700838 ndp_ctx->ndp_create_transaction_id = 0;
839 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700840 wlan_hdd_netif_queue_control(adapter,
841 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
842 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700843 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700844 hdd_err("NDI interface creation failed with reason %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700845 create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700846 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700847
848 /* Something went wrong while starting the BSS */
849 if (create_fail)
850 goto close_ndi;
851
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700852 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
853 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
854 hdd_roam_register_sta(adapter, &roam_info,
855 sta_ctx->broadcast_staid,
856 &bc_mac_addr, &tmp_bss_descp);
857 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
858
859
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700860 EXIT();
861 return;
862
863nla_put_failure:
864 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700865close_ndi:
866 hdd_close_ndi(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700867 return;
868}
869
870/**
871 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
872 * @adapter: pointer to adapter context
873 * @rsp_params: response parameters
874 *
875 * Return: none
876 */
877static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
878 void *rsp_params)
879{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700880 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
881 struct ndi_delete_rsp *ndi_rsp = rsp_params;
Naveen Rawat8d63a592016-06-29 18:30:59 -0700882 struct nan_datapath_ctx *ndp_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700883
884 if (wlan_hdd_validate_context(hdd_ctx))
885 return;
886
887 if (!ndi_rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700888 hdd_err("Invalid ndi delete response");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700889 return;
890 }
891
Naveen Rawat8d63a592016-06-29 18:30:59 -0700892 if (ndi_rsp->status == NDP_RSP_STATUS_SUCCESS)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700893 hdd_err("NDI BSS successfully stopped");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700894 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700895 hdd_err("NDI BSS stop failed with reason %d", ndi_rsp->reason);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700896
897 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
898 ndp_ctx->ndi_delete_rsp_reason = ndi_rsp->reason;
899 ndp_ctx->ndi_delete_rsp_status = ndi_rsp->status;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700900 wlan_hdd_netif_queue_control(adapter,
901 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
902 WLAN_CONTROL_PATH);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700903
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700904 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700905 return;
906}
907
908/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700909 * hdd_ndp_session_end_handler() - NDI session termination handler
910 * @adapter: pointer to adapter context
911 *
912 * Following vendor event is sent to cfg80211:
913 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
914 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
915 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
916 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
917 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
918 *
919 * Return: none
920 */
921void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
922{
923 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
924 struct sk_buff *vendor_event;
925 struct nan_datapath_ctx *ndp_ctx;
926 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
927 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
928
929 ENTER();
930
931 if (wlan_hdd_validate_context(hdd_ctx))
932 return;
933
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700934 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
935 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700936 hdd_err("ndp context is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700937 return;
938 }
939
940 /*
941 * The virtual adapters are stopped and closed even during
942 * driver unload or stop, the service layer is not required
943 * to be informed in that case (response is not expected)
944 */
945 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700946 hdd_err("NDI interface %s deleted", adapter->dev->name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700947 return;
948 }
949
950 /* notify response to the upper layer */
951 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
952 NULL,
953 data_len,
954 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
955 GFP_KERNEL);
956
957 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700958 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700959 return;
960 }
961
962 /* Sub vendor command goes first */
963 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
964 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700965 hdd_err("VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700966 goto failure;
967 }
968
969 /* Transaction id */
970 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
971 ndp_ctx->ndp_delete_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700972 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700973 goto failure;
974 }
975
976 /* Status code */
977 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700978 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
979 ndp_ctx->ndi_delete_rsp_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700980 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700981 goto failure;
982 }
983
984 /* Status return value */
985 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700986 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
987 ndp_ctx->ndi_delete_rsp_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700988 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700989 goto failure;
990 }
991
Naveen Rawatba4f6612016-07-05 12:03:16 -0700992 hdd_info("sub command: %d, value: %d", QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700993 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700994 hdd_info("delete transaction id: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700995 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
996 ndp_ctx->ndp_delete_transaction_id);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700997 hdd_info("status code: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700998 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700999 ndp_ctx->ndi_delete_rsp_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001000 hdd_info("Return value: %d, value: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001001 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1002 ndp_ctx->ndi_delete_rsp_reason);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001003
1004 ndp_ctx->ndp_delete_transaction_id = 0;
1005 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
1006
1007 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1008
1009 EXIT();
1010 return;
1011
1012failure:
1013 kfree_skb(vendor_event);
1014}
1015
1016
1017/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001018 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
1019 * @adapter: pointer to adapter context
1020 * @rsp_params: response parameters
1021 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001022 * Following vendor event is sent to cfg80211:
1023 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1024 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1025 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1026 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1027 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
1028 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1029 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001030 * Return: none
1031 */
1032static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter,
1033 void *rsp_params)
1034{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001035 struct sk_buff *vendor_event;
1036 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1037 struct ndp_initiator_rsp *rsp = rsp_params;
1038 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
1039 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
1040
1041 ENTER();
1042
1043 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001044 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001045 return;
1046 }
1047
1048 if (0 != wlan_hdd_validate_context(hdd_ctx))
1049 return;
1050
1051 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1052 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1053 GFP_KERNEL);
1054 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001055 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001056 return;
1057 }
1058
1059 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1060 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1061 goto ndp_initiator_rsp_nla_failed;
1062
1063 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1064 rsp->transaction_id))
1065 goto ndp_initiator_rsp_nla_failed;
1066
1067 if (nla_put_u32(vendor_event,
1068 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1069 rsp->ndp_instance_id))
1070 goto ndp_initiator_rsp_nla_failed;
1071
1072 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001073 rsp->status))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001074 goto ndp_initiator_rsp_nla_failed;
1075
1076 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001077 rsp->reason))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001078 goto ndp_initiator_rsp_nla_failed;
1079
Naveen Rawatba4f6612016-07-05 12:03:16 -07001080 hdd_info("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001081 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1082 rsp->reason);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001083 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1084 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001085 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001086ndp_initiator_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001087 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001088 kfree_skb(vendor_event);
1089 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001090}
1091
1092/**
1093 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
1094 * @adapter: pointer to adapter context
1095 * @ind_params: indication parameters
1096 *
1097 * Return: none
1098 */
1099static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
1100 void *ind_params)
1101{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001102 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
1103 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1104 tSirBssDescription tmp_bss_descp = {0};
1105 tCsrRoamInfo roam_info = {0};
1106 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1107 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1108
1109 ENTER();
1110
1111 if (NULL == ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001112 hdd_err("Invalid new NDP peer params");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001113 return;
1114 }
Naveen Rawatba4f6612016-07-05 12:03:16 -07001115 hdd_info("session_id: %d, peer_mac: %pM, sta_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001116 new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
1117 new_peer_ind->sta_id);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001118
1119 /* save peer in ndp ctx */
1120 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
1121 &new_peer_ind->peer_mac_addr)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001122 hdd_err("Ndp peer table full. cannot save new peer");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001123 return;
1124 }
1125
1126 /* this function is called for each new peer */
1127 ndp_ctx->active_ndp_peers++;
Naveen Rawatba4f6612016-07-05 12:03:16 -07001128 hdd_info("vdev_id: %d, num_peers: %d", adapter->sessionId,
1129 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001130
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001131 hdd_roam_register_sta(adapter, &roam_info, new_peer_ind->sta_id,
1132 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
1133 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
1134 /* perform following steps for first new peer ind */
1135 if (ndp_ctx->active_ndp_peers == 1) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001136 hdd_info("Set ctx connection state to connected");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001137 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
1138 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001139 wlan_hdd_netif_queue_control(adapter,
1140 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001141 }
1142 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001143}
1144
1145/**
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001146 * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001147 * @adapter: pointer to adapter context
1148 * @ind_params: indication parameters
1149 *
1150 * Return: none
1151 */
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001152static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter,
1153 void *ind_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001154{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001155 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1156 struct sme_ndp_peer_ind *peer_ind = ind_params;
1157 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1158 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1159
1160 hdd_roam_deregister_sta(adapter, peer_ind->sta_id);
1161 hdd_delete_peer(sta_ctx, peer_ind->sta_id);
1162 hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
1163
1164 if (--ndp_ctx->active_ndp_peers == 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001165 hdd_info("No more ndp peers.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001166 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
1167 hdd_conn_set_connection_state(adapter,
1168 eConnectionState_NdiDisconnected);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001169 hdd_info("Stop netif tx queues.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001170 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
1171 WLAN_CONTROL_PATH);
1172 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001173}
1174
1175/**
1176 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1177 * @adapter: pointer to adapter context
1178 * @ind_params: indication parameters
1179 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001180 * Following vendor event is sent to cfg80211:
1181 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1182 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1183 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1184 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1185 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1186 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1187 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1188 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1189 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001190 * Return: none
1191 */
1192static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
1193 void *ind_params)
1194{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001195 int idx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001196 uint32_t ndp_qos_config = 0;
1197 struct ndp_confirm_event *ndp_confirm = ind_params;
1198 struct sk_buff *vendor_event;
1199 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1200 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Naveen Rawatf28315c2016-06-29 18:06:02 -07001201 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001202 uint32_t data_len;
1203
1204 ENTER();
1205 if (!ndp_confirm) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001206 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001207 return;
1208 }
1209
1210 if (0 != wlan_hdd_validate_context(hdd_ctx))
1211 return;
1212
Naveen Rawatf28315c2016-06-29 18:06:02 -07001213 /* ndp_confirm is called each time user generated ndp req succeeds */
1214 idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
1215 if (idx == INVALID_PEER_IDX)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001216 hdd_err("can't find addr: %pM in vdev_id: %d, peer table.",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001217 &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId);
Naveen Rawat460be782016-06-29 18:26:22 -07001218 else if (ndp_confirm->rsp_code == NDP_RESPONSE_ACCEPT)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001219 ndp_ctx->active_ndp_sessions[idx]++;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001220
1221 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
Naveen Rawat90ae3082016-06-29 18:22:59 -07001222 + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001223 ndp_confirm->ndp_info.ndp_app_info_len;
1224
Naveen Rawat8d63a592016-06-29 18:30:59 -07001225 if (ndp_confirm->ndp_info.ndp_app_info_len)
1226 data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
1227
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001228 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1229 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1230 GFP_KERNEL);
1231 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001232 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001233 return;
1234 }
1235
1236 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1237 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1238 goto ndp_confirm_nla_failed;
1239
1240 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1241 ndp_confirm->ndp_instance_id))
1242 goto ndp_confirm_nla_failed;
1243
1244 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1245 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1246 goto ndp_confirm_nla_failed;
1247
1248 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1249 IFNAMSIZ, adapter->dev->name))
1250 goto ndp_confirm_nla_failed;
1251
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001252 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001253 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1254 ndp_confirm->ndp_info.ndp_app_info_len,
1255 ndp_confirm->ndp_info.ndp_app_info))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001256 goto ndp_confirm_nla_failed;
1257
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001258 if (nla_put_u32(vendor_event,
1259 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1260 ndp_confirm->rsp_code))
1261 goto ndp_confirm_nla_failed;
1262
Naveen Rawat8d63a592016-06-29 18:30:59 -07001263 if (nla_put_u32(vendor_event,
1264 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1265 ndp_confirm->reason_code))
1266 goto ndp_confirm_nla_failed;
1267
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001268 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001269 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 -07001270 ndp_confirm->ndp_instance_id,
1271 ndp_confirm->peer_ndi_mac_addr.bytes,
Naveen Rawat460be782016-06-29 18:26:22 -07001272 ndp_qos_config, ndp_confirm->rsp_code,
1273 ndp_confirm->reason_code);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001274
Naveen Rawatba4f6612016-07-05 12:03:16 -07001275 hdd_info("NDP confim, ndp app info dump");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001276 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1277 ndp_confirm->ndp_info.ndp_app_info,
1278 ndp_confirm->ndp_info.ndp_app_info_len);
1279 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001280 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001281ndp_confirm_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001282 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001283 kfree_skb(vendor_event);
1284 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001285}
1286
1287/**
1288 * hdd_ndp_indication_handler() - NDP indication handler
1289 * @adapter: pointer to adapter context
1290 * @ind_params: indication parameters
1291 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001292 * Following vendor event is sent to cfg80211:
1293 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1294 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1295 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
Naveen Rawat19da3d12016-08-16 12:39:38 -07001296 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001297 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1298 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1299 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1300 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1301 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
1302 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001303 * Return: none
1304 */
1305static void hdd_ndp_indication_handler(hdd_adapter_t *adapter,
1306 void *ind_params)
1307{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001308 struct sk_buff *vendor_event;
1309 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1310 struct ndp_indication_event *event = ind_params;
1311 uint32_t ndp_qos_config;
1312 struct nan_datapath_ctx *ndp_ctx;
1313 uint16_t data_len;
1314
1315 ENTER();
1316 if (!ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001317 hdd_err("Invalid NDP Indication");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001318 return;
1319 }
1320
1321 if (0 != wlan_hdd_validate_context(hdd_ctx))
1322 return;
1323
1324 /* Handle only if adapter is in NDI mode */
1325 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001326 hdd_err("Adapter is not in NDI mode");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001327 return;
1328 }
1329
Naveen Rawatba4f6612016-07-05 12:03:16 -07001330 hdd_info("NDP Indication, policy: %d", event->policy);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001331
1332 /* Policy check */
1333 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001334 hdd_err("NAN datapath is not suported");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001335 return;
1336 }
1337
1338 /* NAN data path coexists only with STA interface */
1339 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001340 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001341 return;
1342 }
1343
1344 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1345
1346 /* check if we are in middle of deleting/creating the interface */
1347 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
1348 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
1349 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001350 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001351 ndp_ctx->state);
1352 return;
1353 }
1354
Naveen Rawat19da3d12016-08-16 12:39:38 -07001355 data_len = (4 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
1356 event->ndp_info.ndp_app_info_len + (8 * NLA_HDRLEN) +
Abhishek Singh4fef7472016-06-06 11:36:03 -07001357 NLMSG_HDRLEN;
1358
1359 /* notify response to the upper layer */
1360 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1361 NULL, data_len,
1362 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1363 GFP_KERNEL);
1364 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001365 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001366 return;
1367 }
1368
1369 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1370 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1371 goto ndp_indication_nla_failed;
1372
1373 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1374 IFNAMSIZ, adapter->dev->name))
1375 goto ndp_indication_nla_failed;
1376
Naveen Rawat19da3d12016-08-16 12:39:38 -07001377 if (nla_put_u32(vendor_event,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001378 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1379 event->service_instance_id))
1380 goto ndp_indication_nla_failed;
1381
1382 if (nla_put(vendor_event,
1383 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1384 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1385 goto ndp_indication_nla_failed;
1386
1387 if (nla_put(vendor_event,
1388 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR ,
1389 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1390 goto ndp_indication_nla_failed;
1391
1392 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1393 event->ndp_instance_id))
1394 goto ndp_indication_nla_failed;
1395
1396 if (event->ndp_info.ndp_app_info_len)
1397 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1398 event->ndp_info.ndp_app_info_len,
1399 event->ndp_info.ndp_app_info))
1400 goto ndp_indication_nla_failed;
1401
1402 if (event->ndp_config.ndp_cfg_len) {
1403 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1404 /* at present ndp config stores 4 bytes QOS info only */
1405 if (nla_put_u32(vendor_event,
1406 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1407 ndp_qos_config))
1408 goto ndp_indication_nla_failed;
1409 }
1410
1411 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1412 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001413 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001414ndp_indication_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001415 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001416 kfree_skb(vendor_event);
1417 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001418}
1419
1420/**
1421 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1422 * @adapter: pointer to adapter context
1423 * @rsp_params: response parameters
1424 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001425 * Following vendor event is sent to cfg80211:
1426 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1427 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1428 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1429 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
1430 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1431 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001432 * Return: none
1433 */
1434static void hdd_ndp_responder_rsp_handler(hdd_adapter_t *adapter,
1435 void *rsp_params)
1436{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001437 struct sk_buff *vendor_event;
1438 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1439 struct ndp_responder_rsp_event *rsp = rsp_params;
1440 uint16_t data_len;
1441
1442 ENTER();
1443 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001444 hdd_err("Invalid NDP Responder response");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001445 return;
1446 }
1447
1448 if (0 != wlan_hdd_validate_context(hdd_ctx))
1449 return;
1450
Naveen Rawatba4f6612016-07-05 12:03:16 -07001451 hdd_info("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001452 rsp->vdev_id, rsp->transaction_id,
1453 rsp->status, rsp->reason);
1454
1455 data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
1456 4 * NLA_HDRLEN + NLMSG_HDRLEN;
1457 /* notify response to the upper layer */
1458 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1459 NULL, data_len,
1460 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1461 GFP_KERNEL);
1462 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001463 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001464 return;
1465 }
1466
1467 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1468 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1469 goto ndp_responder_rsp_nla_failed;
1470
1471 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1472 rsp->transaction_id))
1473 goto ndp_responder_rsp_nla_failed;
1474
1475 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
1476 rsp->status))
1477 goto ndp_responder_rsp_nla_failed;
1478
1479 if (nla_put_u32(vendor_event,
1480 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1481 rsp->reason))
1482 goto ndp_responder_rsp_nla_failed;
1483
1484 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1485 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001486 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001487ndp_responder_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001488 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001489 kfree_skb(vendor_event);
1490 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001491}
1492
1493/**
1494 * hdd_ndp_end_rsp_handler() - NDP end response handler
1495 * @adapter: pointer to adapter context
1496 * @rsp_params: response parameters
1497 *
Naveen Rawatf28315c2016-06-29 18:06:02 -07001498 * Following vendor event is sent to cfg80211:
1499 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1500 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
1501 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
1502 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1503 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1504 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001505 * Return: none
1506 */
Naveen Rawatf28315c2016-06-29 18:06:02 -07001507static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, void *rsp_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001508{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001509 struct sk_buff *vendor_event;
1510 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1511 struct ndp_end_rsp_event *rsp = rsp_params;
Rakesh Sunkiae936b62016-07-28 16:01:45 -07001512 uint32_t data_len;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001513
1514 ENTER();
1515
1516 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001517 hdd_err("Invalid ndp end response");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001518 return;
1519 }
1520
1521 if (0 != wlan_hdd_validate_context(hdd_ctx))
1522 return;
1523
Naveen Rawatf28315c2016-06-29 18:06:02 -07001524 data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
1525 sizeof(uint16_t);
1526
1527 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1528 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1529 GFP_KERNEL);
1530 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001531 hdd_err("cfg80211_vendor_event_alloc failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001532 return;
1533 }
1534
1535 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1536 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1537 goto ndp_end_rsp_nla_failed;
1538
1539 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
1540 rsp->status))
1541 goto ndp_end_rsp_nla_failed;
1542
1543 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1544 rsp->reason))
1545 goto ndp_end_rsp_nla_failed;
1546
1547 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1548 rsp->transaction_id))
1549 goto ndp_end_rsp_nla_failed;
1550
Naveen Rawatba4f6612016-07-05 12:03:16 -07001551 hdd_info("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001552 rsp->transaction_id, rsp->status, rsp->reason);
1553 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1554 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001555 return;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001556
1557ndp_end_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001558 hdd_err("nla_put api failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001559 kfree_skb(vendor_event);
1560 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001561}
1562
1563/**
1564 * hdd_ndp_end_ind_handler() - NDP end indication handler
1565 * @adapter: pointer to adapter context
1566 * @ind_params: indication parameters
1567 *
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001568 * Following vendor event is sent to cfg80211:
1569 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1570 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001571 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1572 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001573 * Return: none
1574 */
1575static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
1576 void *ind_params)
1577{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001578 struct sk_buff *vendor_event;
1579 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1580 struct ndp_end_indication_event *end_ind = ind_params;
1581 uint32_t data_len, i;
1582 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1583 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1584 uint32_t *ndp_instance_array;
Naveen Rawate21103f2016-07-08 14:18:00 -07001585 hdd_adapter_t *ndi_adapter;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001586
1587 ENTER();
1588
1589 if (!end_ind) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001590 hdd_err("Invalid ndp end indication");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001591 return;
1592 }
1593
1594 if (0 != wlan_hdd_validate_context(hdd_ctx))
1595 return;
1596
1597 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1598 sizeof(*ndp_instance_array));
1599 if (!ndp_instance_array) {
1600 hdd_err("Failed to allocate ndp_instance_array");
1601 return;
1602 }
1603 for (i = 0; i < end_ind->num_ndp_ids; i++) {
1604 int idx;
1605
1606 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
Naveen Rawate21103f2016-07-08 14:18:00 -07001607 ndi_adapter = hdd_get_adapter_by_vdev(hdd_ctx,
1608 end_ind->ndp_map[i].vdev_id);
1609 if (ndi_adapter == NULL) {
1610 hdd_err("Adapter not found for vdev_id: %d",
1611 end_ind->ndp_map[i].vdev_id);
1612 continue;
1613 }
1614 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
Govind Singhb8475942016-08-12 11:07:09 +05301615 if (!ndp_ctx) {
1616 hdd_err("ndp_ctx is NULL for vdev id: %d",
1617 end_ind->ndp_map[i].vdev_id);
1618 continue;
1619 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001620 idx = hdd_get_peer_idx(sta_ctx,
1621 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1622 if (idx == INVALID_PEER_IDX) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001623 hdd_err("can't find addr: %pM in sta_ctx.",
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001624 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1625 continue;
1626 }
1627 /* save the value of active sessions on each peer */
1628 ndp_ctx->active_ndp_sessions[idx] =
1629 end_ind->ndp_map[i].num_active_ndp_sessions;
1630 }
1631
Naveen Rawat90ae3082016-06-29 18:22:59 -07001632 data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001633 end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
1634
1635 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1636 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1637 GFP_KERNEL);
1638 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001639 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001640 return;
1641 }
1642
1643 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1644 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1645 goto ndp_end_ind_nla_failed;
1646
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001647 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1648 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1649 ndp_instance_array))
1650 goto ndp_end_ind_nla_failed;
1651
1652 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1653 qdf_mem_free(ndp_instance_array);
1654 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001655 return;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001656
1657ndp_end_ind_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001658 hdd_err("nla_put api failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001659 kfree_skb(vendor_event);
1660 qdf_mem_free(ndp_instance_array);
1661 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001662}
1663
1664/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001665 * hdd_ndp_event_handler() - ndp response and indication handler
1666 * @adapter: adapter context
1667 * @roam_info: pointer to roam_info structure
1668 * @roam_id: roam id as indicated by SME
1669 * @roam_status: roam status
1670 * @roam_result: roam result
1671 *
1672 * Return: none
1673 */
1674void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1675 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1676 eCsrRoamResult roam_result)
1677{
1678 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1679 switch (roam_result) {
Naveen Rawat8d63a592016-06-29 18:30:59 -07001680 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001681 hdd_ndp_iface_create_rsp_handler(adapter,
1682 &roam_info->ndp.ndi_create_params);
1683 break;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001684 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001685 hdd_ndp_iface_delete_rsp_handler(adapter,
1686 &roam_info->ndp.ndi_delete_params);
1687 break;
1688 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1689 hdd_ndp_initiator_rsp_handler(adapter,
1690 &roam_info->ndp.ndp_init_rsp_params);
1691 break;
1692 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1693 hdd_ndp_new_peer_ind_handler(adapter,
1694 &roam_info->ndp.ndp_peer_ind_params);
1695 break;
1696 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1697 hdd_ndp_confirm_ind_handler(adapter,
1698 &roam_info->ndp.ndp_confirm_params);
1699 break;
1700 case eCSR_ROAM_RESULT_NDP_INDICATION:
1701 hdd_ndp_indication_handler(adapter,
1702 &roam_info->ndp.ndp_indication_params);
1703 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001704 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1705 hdd_ndp_responder_rsp_handler(adapter,
1706 &roam_info->ndp.ndp_responder_rsp_params);
1707 break;
1708 case eCSR_ROAM_RESULT_NDP_END_RSP:
1709 hdd_ndp_end_rsp_handler(adapter,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001710 roam_info->ndp.ndp_end_rsp_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001711 break;
1712 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1713 hdd_ndp_peer_departed_ind_handler(adapter,
1714 &roam_info->ndp.ndp_peer_ind_params);
1715 break;
1716 case eCSR_ROAM_RESULT_NDP_END_IND:
1717 hdd_ndp_end_ind_handler(adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001718 roam_info->ndp.ndp_end_ind_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001719 break;
1720 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001721 hdd_err("Unknown NDP response event from SME %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001722 roam_result);
1723 break;
1724 }
1725 }
1726}
1727
1728/**
1729 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1730 * @wiphy: pointer to wireless wiphy structure.
1731 * @wdev: pointer to wireless_dev structure.
1732 * @data: Pointer to the data to be passed via vendor interface
1733 * @data_len:Length of the data to be passed
1734 *
1735 * This function is invoked to handle vendor command
1736 *
1737 * Return: 0 on success, negative errno on failure
1738 */
1739static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1740 struct wireless_dev *wdev, const void *data, int data_len)
1741{
1742 uint32_t ndp_cmd_type;
1743 uint16_t transaction_id;
1744 int ret_val;
1745 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1746 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1747 char *iface_name;
1748
1749 ENTER();
1750
1751 ret_val = wlan_hdd_validate_context(hdd_ctx);
1752 if (ret_val)
1753 return ret_val;
1754
1755 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001756 hdd_err("Command not allowed in FTM mode");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001757 return -EPERM;
1758 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07001759 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001760 hdd_err("NAN datapath is not enabled");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001761 return -EPERM;
1762 }
1763 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1764 data, data_len,
1765 qca_wlan_vendor_ndp_policy)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001766 hdd_err("Invalid NDP vendor command attributes");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001767 return -EINVAL;
1768 }
1769
1770 /* Parse and fetch NDP Command Type*/
1771 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001772 hdd_err("NAN datapath cmd type failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001773 return -EINVAL;
1774 }
1775 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1776
1777 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001778 hdd_err("attr transaction id failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001779 return -EINVAL;
1780 }
1781 transaction_id = nla_get_u16(
1782 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1783
Naveen Rawatf28315c2016-06-29 18:06:02 -07001784 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
1785 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001786 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: %s",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001787 transaction_id, ndp_cmd_type, iface_name);
1788 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001789 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: unspecified",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001790 transaction_id, ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001791 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001792
1793 switch (ndp_cmd_type) {
1794 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
1795 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
1796 break;
1797 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
1798 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
1799 break;
1800 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
1801 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
1802 break;
1803 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
1804 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
1805 break;
1806 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
1807 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
1808 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001809 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001810 hdd_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001811 ret_val = -EINVAL;
1812 break;
1813 }
1814
1815 return ret_val;
1816}
1817
1818/**
1819 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
1820 * @wiphy: pointer to wireless wiphy structure.
1821 * @wdev: pointer to wireless_dev structure.
1822 * @data: Pointer to the data to be passed via vendor interface
1823 * @data_len:Length of the data to be passed
1824 *
1825 * This function is called to send a NAN request to
1826 * firmware. This is an SSR-protected wrapper function.
1827 *
1828 * Return: 0 on success, negative errno on failure
1829 */
1830int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1831 struct wireless_dev *wdev, const void *data, int data_len)
1832{
1833 int ret;
1834
1835 cds_ssr_protect(__func__);
1836 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
1837 cds_ssr_unprotect(__func__);
1838
1839 return ret;
1840}
1841
1842/**
1843 * hdd_init_nan_data_mode() - initialize nan data mode
1844 * @adapter: adapter context
1845 *
1846 * Returns: 0 on success negative error code on error
1847 */
1848int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
1849{
1850 struct net_device *wlan_dev = adapter->dev;
1851 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1852 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1853 QDF_STATUS status;
1854 uint32_t type, sub_type;
1855 int32_t ret_val = 0;
1856 unsigned long rc;
1857 uint32_t timeout = WLAN_WAIT_TIME_SESSIONOPENCLOSE;
1858
1859 INIT_COMPLETION(adapter->session_open_comp_var);
1860 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
1861 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
1862 if (QDF_STATUS_SUCCESS != status) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001863 hdd_err("failed to get vdev type");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001864 goto error_sme_open;
1865 }
1866
1867 /* open sme session for future use */
1868 status = sme_open_session(hdd_ctx->hHal, hdd_sme_roam_callback,
1869 adapter, (uint8_t *)&adapter->macAddressCurrent,
1870 &adapter->sessionId, type, sub_type);
Naveen Rawatcb186cf2016-07-11 13:47:19 -07001871 if (QDF_STATUS_SUCCESS != status) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001872 hdd_err("sme_open_session() failed with status code %d",
Naveen Rawatba4f6612016-07-05 12:03:16 -07001873 status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001874 ret_val = -EAGAIN;
1875 goto error_sme_open;
1876 }
1877
1878 /* Block on a completion variable. Can't wait forever though */
1879 rc = wait_for_completion_timeout(
1880 &adapter->session_open_comp_var,
1881 msecs_to_jiffies(timeout));
1882 if (!rc) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001883 hdd_err("Failed to open session, timeout code: %ld", rc);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001884 ret_val = -ETIMEDOUT;
1885 goto error_sme_open;
1886 }
1887
1888 /* Register wireless extensions */
1889 ret_val = hdd_register_wext(wlan_dev);
1890 if (0 > ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001891 hdd_err("Wext registration failed with status code %d",
1892 ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001893 ret_val = -EAGAIN;
1894 goto error_register_wext;
1895 }
1896
1897 status = hdd_init_tx_rx(adapter);
1898 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001899 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001900 ret_val = -EAGAIN;
1901 goto error_init_txrx;
1902 }
1903
1904 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
1905
1906 status = hdd_wmm_adapter_init(adapter);
1907 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001908 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001909 ret_val = -EAGAIN;
1910 goto error_wmm_init;
1911 }
1912
1913 set_bit(WMM_INIT_DONE, &adapter->event_flags);
1914
1915 ret_val = wma_cli_set_command((int)adapter->sessionId,
1916 (int)WMI_PDEV_PARAM_BURST_ENABLE,
1917 (int)hdd_ctx->config->enableSifsBurst,
1918 PDEV_CMD);
1919 if (0 != ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001920 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001921 }
1922
1923 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
1924 return ret_val;
1925
1926error_wmm_init:
1927 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
1928 hdd_deinit_tx_rx(adapter);
1929
1930error_init_txrx:
1931 hdd_unregister_wext(wlan_dev);
1932
1933error_register_wext:
1934 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
1935 INIT_COMPLETION(adapter->session_close_comp_var);
1936 if (QDF_STATUS_SUCCESS ==
1937 sme_close_session(hdd_ctx->hHal,
1938 adapter->sessionId,
1939 hdd_sme_close_session_callback,
1940 adapter)) {
1941 rc = wait_for_completion_timeout(
1942 &adapter->session_close_comp_var,
1943 msecs_to_jiffies(timeout));
1944 if (rc <= 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001945 hdd_err("Session close failed status %ld", rc);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001946 ret_val = -ETIMEDOUT;
1947 }
1948 }
1949 }
1950
1951error_sme_open:
1952 return ret_val;
1953}