blob: 947a86bc6d857a58f10f5583ecdd2c595037fbc0 [file] [log] [blame]
Ravi Joshia063dd92016-05-25 16:43:13 -07001/*
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302 * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
Ravi Joshia063dd92016-05-25 16:43:13 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for
7 * any purpose with or without fee is hereby granted, provided that the
8 * above copyright notice and this permission notice appear in all
9 * copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18 * PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/**
22 * DOC: wlan_hdd_nan_datapath.c
23 *
24 * WLAN Host Device Driver nan datapath API implementation
25 */
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070026#include <wlan_hdd_includes.h>
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070027#include <linux/if.h>
28#include <linux/netdevice.h>
29#include <linux/skbuff.h>
30#include <linux/etherdevice.h>
31#include "wlan_hdd_includes.h"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070032#include "wlan_hdd_p2p.h"
33#include "wma_api.h"
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070034#include "wlan_hdd_assoc.h"
35#include "sme_nan_datapath.h"
Rajeev Kumar699debf2017-01-06 14:17:00 -080036#include "wlan_hdd_object_manager.h"
Sandeep Puligillafdd201e2017-02-02 18:43:46 -080037#include <qca_vendor.h>
Naveen Rawat63de5422017-03-22 11:03:56 -070038#include "os_if_nan.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -070039#include "wlan_nan_api.h"
40#include "nan_public_structs.h"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070041
Naveen Rawat97500352017-03-22 10:07:58 -070042#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070043/* NLA policy */
44static const struct nla_policy
45qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
46 [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 },
47 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 },
48 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_STRING,
49 .len = IFNAMSIZ },
Naveen Rawat19da3d12016-08-16 12:39:38 -070050 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070051 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070052 [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = {
Naveen Rawatf28315c2016-06-29 18:06:02 -070053 .type = NLA_BINARY,
54 .len = QDF_MAC_ADDR_SIZE },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070055 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 },
56 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY,
57 .len = NDP_QOS_INFO_LEN },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070058 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY,
59 .len = NDP_APP_INFO_LEN },
60 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 },
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070061 [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070062 [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY,
63 .len = QDF_MAC_ADDR_SIZE },
Naveen Rawatf28315c2016-06-29 18:06:02 -070064 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY,
65 .len = NDP_NUM_INSTANCE_ID },
Naveen Rawat0a017052016-10-19 14:17:07 -070066 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { .type = NLA_U32 },
Naveen Rawat4f3983e2016-11-29 16:12:09 -080067 [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { .type = NLA_U32 },
68 [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { .type = NLA_BINARY,
69 .len = NDP_PMK_LEN },
70 [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { .type = NLA_BINARY,
71 .len = NDP_SCID_BUF_LEN },
Rakesh Sunkid92d1082017-01-04 15:14:28 -080072 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { .type =
73 NLA_U32 },
74 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 },
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070075};
Naveen Rawat97500352017-03-22 10:07:58 -070076#endif
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070077
78/**
79 * hdd_ndp_print_ini_config()- Print nan datapath specific INI configuration
80 * @hdd_ctx: handle to hdd context
81 *
82 * Return: None
83 */
84void hdd_ndp_print_ini_config(hdd_context_t *hdd_ctx)
85{
Naveen Rawatba4f6612016-07-05 12:03:16 -070086 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_DATAPATH_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070087 hdd_ctx->config->enable_nan_datapath);
Naveen Rawatba4f6612016-07-05 12:03:16 -070088 hdd_info("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_NDI_CHANNEL_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070089 hdd_ctx->config->nan_datapath_ndi_channel);
90}
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070091
92/**
93 * hdd_nan_datapath_target_config() - Configure NAN datapath features
94 * @hdd_ctx: Pointer to HDD context
95 * @cfg: Pointer to target device capability information
96 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070097 * NAN datapath functionality is enabled if it is enabled in
98 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070099 *
100 * Return: None
101 */
Deepak Dhamdhere13230d32016-05-26 00:46:53 -0700102void hdd_nan_datapath_target_config(hdd_context_t *hdd_ctx,
103 struct wma_tgt_cfg *cfg)
104{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -0700105 hdd_ctx->nan_datapath_enabled =
106 hdd_ctx->config->enable_nan_datapath &&
107 cfg->nan_datapath_enabled;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700108 hdd_info("enable_nan_datapath: final: %d, host: %d, fw: %d",
109 hdd_ctx->nan_datapath_enabled,
110 hdd_ctx->config->enable_nan_datapath,
111 cfg->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -0700112}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700113
114/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700115 * hdd_close_ndi() - close NAN Data interface
116 * @adapter: adapter context
117 *
118 * Close the adapter if start BSS fails
119 *
120 * Returns: 0 on success, negative error code otherwise
121 */
122static int hdd_close_ndi(hdd_adapter_t *adapter)
123{
Dustin Brown0d2eeae2017-03-24 15:21:32 -0700124 int errno;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700125 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700126
127 ENTER();
128
129 /* check if the adapter is in NAN Data mode */
130 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700131 hdd_err("Interface is not in NDI mode");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700132 return -EINVAL;
133 }
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700134 wlan_hdd_netif_queue_control(adapter,
135 WLAN_NETIF_TX_DISABLE_N_CARRIER,
136 WLAN_CONTROL_PATH);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700137
138#ifdef WLAN_OPEN_SOURCE
139 cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
140#endif
141 hdd_deregister_tx_flow_control(adapter);
142
143#ifdef WLAN_NS_OFFLOAD
144#ifdef WLAN_OPEN_SOURCE
145 cancel_work_sync(&adapter->ipv6NotifierWorkQueue);
146#endif
147#endif
Dustin Brown0d2eeae2017-03-24 15:21:32 -0700148 errno = hdd_vdev_destroy(adapter);
149 if (errno)
150 hdd_err("failed to destroy vdev: %d", errno);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700151
152 /* We are good to close the adapter */
153 hdd_close_adapter(hdd_ctx, adapter, true);
154
155 EXIT();
156 return 0;
157}
158
159/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700160 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
161 * @hdd_ctx: hdd context
162 *
163 * NDP is not allowed with any other role active except STA.
164 *
165 * Return: true if allowed, false otherwise
166 */
167static bool hdd_is_ndp_allowed(hdd_context_t *hdd_ctx)
168{
169 hdd_adapter_t *adapter;
170 hdd_station_ctx_t *sta_ctx;
171 QDF_STATUS status;
172 hdd_adapter_list_node_t *curr = NULL, *next = NULL;
173
174 status = hdd_get_front_adapter(hdd_ctx, &curr);
175 while (QDF_STATUS_SUCCESS == status) {
176 adapter = curr->pAdapter;
177 if (!adapter)
178 goto next_adapter;
179
180 switch (adapter->device_mode) {
181 case QDF_P2P_GO_MODE:
182 case QDF_SAP_MODE:
183 if (test_bit(SOFTAP_BSS_STARTED,
184 &adapter->event_flags))
185 return false;
186 break;
187 case QDF_P2P_CLIENT_MODE:
188 case QDF_IBSS_MODE:
189 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
190 if (hdd_conn_is_connected(sta_ctx) ||
191 hdd_is_connecting(sta_ctx))
192 return false;
193 break;
194 default:
195 break;
196 }
197next_adapter:
198 status = hdd_get_next_adapter(hdd_ctx, curr, &next);
199 curr = next;
200 }
201
202 return true;
203}
204
205/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700206 * hdd_ndi_start_bss() - Start BSS on NAN data interface
207 * @adapter: adapter context
208 * @operating_channel: channel on which the BSS to be started
209 *
210 * Return: 0 on success, error value on failure
211 */
212static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
213 uint8_t operating_channel)
214{
215 int ret;
216 uint32_t roam_id;
217 hdd_wext_state_t *wext_state =
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -0700218 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700219 tCsrRoamProfile *roam_profile = &wext_state->roamProfile;
220
221 ENTER();
222
223 if (!roam_profile) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700224 hdd_err("No valid roam profile");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700225 return -EINVAL;
226 }
227
228 if (HDD_WMM_USER_MODE_NO_QOS ==
229 (WLAN_HDD_GET_CTX(adapter))->config->WmmMode) {
230 /* QoS not enabled in cfg file*/
231 roam_profile->uapsd_mask = 0;
232 } else {
233 /* QoS enabled, update uapsd mask from cfg file*/
234 roam_profile->uapsd_mask =
235 (WLAN_HDD_GET_CTX(adapter))->config->UapsdMask;
236 }
237
238 roam_profile->csrPersona = adapter->device_mode;
239
240 roam_profile->ChannelInfo.numOfChannels = 1;
241 if (operating_channel) {
242 roam_profile->ChannelInfo.ChannelList = &operating_channel;
243 } else {
244 roam_profile->ChannelInfo.ChannelList[0] =
245 NAN_SOCIAL_CHANNEL_2_4GHZ;
246 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700247
248 roam_profile->SSIDs.numOfSSIDs = 1;
249 roam_profile->SSIDs.SSIDList->SSID.length = 0;
250
251 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
252 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
253 roam_profile->BSSIDs.numOfBSSIDs = 1;
254 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
255 &adapter->macAddressCurrent.bytes[0],
256 QDF_MAC_ADDR_SIZE);
257
258 roam_profile->AuthType.numEntries = 1;
259 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
260 roam_profile->EncryptionType.numEntries = 1;
261 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
262
263 ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
264 adapter->sessionId, roam_profile, &roam_id);
265 if (QDF_STATUS_SUCCESS != ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700266 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
267 adapter->sessionId, ret);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700268 /* change back to NotConnected */
269 hdd_conn_set_connection_state(adapter,
270 eConnectionState_NotConnected);
271 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700272 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700273 }
274
275 roam_profile->ChannelInfo.ChannelList = NULL;
276 roam_profile->ChannelInfo.numOfChannels = 0;
277
278 EXIT();
279
280 return ret;
281}
282
Naveen Rawat97500352017-03-22 10:07:58 -0700283#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700284/**
285 * hdd_ndi_create_req_handler() - NDI create request handler
286 * @hdd_ctx: hdd context
287 * @tb: parsed NL attribute list
288 *
289 * Return: 0 on success or error code on failure
290 */
291static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
292 struct nlattr **tb)
293{
294 hdd_adapter_t *adapter;
295 char *iface_name;
296 uint16_t transaction_id;
297 int ret;
298 struct nan_datapath_ctx *ndp_ctx;
299 uint8_t op_channel =
300 hdd_ctx->config->nan_datapath_ndi_channel;
301
302 ENTER();
303
304 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700305 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700306 return -EINVAL;
307 }
308 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
309
310 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700311 hdd_err("transaction id is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700312 return -EINVAL;
313 }
314 transaction_id =
315 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
316
317 /* Check for an existing interface of NDI type */
318 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
319 if (adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700320 hdd_err("Cannot support more than one NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700321 return -EEXIST;
322 }
323
324 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
325 wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
326 true);
327 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700328 hdd_err("hdd_open_adapter failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700329 return -ENOMEM;
330 }
331
332 /*
333 * Create transaction id is required to be saved since the firmware
334 * does not honor the transaction id for create request
335 */
336 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
337 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700338 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700339
340 /*
341 * The NAN data interface has been created at this point.
342 * Unlike traditional device modes, where the higher application
343 * layer initiates connect / join / start, the NAN data interface
344 * does not have any such formal requests. The NDI create request
345 * is responsible for starting the BSS as well.
346 */
347 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
348 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
349 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
350 /* start NDI on the default 2.4 GHz social channel */
351 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
352 }
353 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700354 if (0 > ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700355 hdd_err("NDI start bss failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700356 /* Start BSS failed, delete the interface */
357 hdd_close_ndi(adapter);
358 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700359
360 EXIT();
361 return ret;
362}
363
364/**
365 * hdd_ndi_delete_req_handler() - NDI delete request handler
366 * @hdd_ctx: hdd context
367 * @tb: parsed NL attribute list
368 *
369 * Return: 0 on success or error code on failure
370 */
371static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
372 struct nlattr **tb)
373{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700374 hdd_adapter_t *adapter;
375 char *iface_name;
376 uint16_t transaction_id;
377 struct nan_datapath_ctx *ndp_ctx;
378 int ret;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700379 hdd_station_ctx_t *sta_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700380
381 ENTER();
382
383 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700384 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700385 return -EINVAL;
386 }
387
388 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
389
390 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700391 hdd_err("Transaction id is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700392 return -EINVAL;
393 }
394
395 transaction_id =
396 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
397
398 /* Check if there is already an existing inteface with the same name */
399 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
400 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700401 hdd_err("NAN data interface %s is not available", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700402 return -EINVAL;
403 }
404
405 /* check if adapter is in NDI mode */
406 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700407 hdd_err("Interface %s is not in NDI mode", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700408 return -EINVAL;
409 }
410
411 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
412 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700413 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700414 return -EINVAL;
415 }
416
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700417 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
418 if (!sta_ctx) {
419 hdd_err("sta_ctx is NULL");
420 return -EINVAL;
421 }
422
Naveen Rawatf28315c2016-06-29 18:06:02 -0700423 /* check if there are active peers on the adapter */
424 if (ndp_ctx->active_ndp_peers > 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700425 hdd_err("NDP peers active: %d, cannot delete NDI",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700426 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700427 return -EINVAL;
428 }
429
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700430 /*
431 * Since, the interface is being deleted, remove the
432 * broadcast id.
433 */
434 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
435 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
436
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700437 ndp_ctx->ndp_delete_transaction_id = transaction_id;
438 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
439
440 /* Delete the interface */
441 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
442 if (ret < 0)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700443 hdd_err("NDI delete request failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700444 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700445 hdd_err("NDI delete request successfully issued");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700446
447 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700448}
449
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700450/**
451 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
452 * @hdd_ctx: hdd context
453 * @tb: parsed NL attribute list
454 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800455 * tb will contain following vendor attributes:
456 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
457 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
458 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
Ravi Joshi71e82f32017-02-09 23:15:16 -0800459 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG - optional
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800460 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
461 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
462 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
463 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
464 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
465 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
466 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700467 * Return: 0 on success or error code on failure
468 */
469static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx,
470 struct nlattr **tb)
471{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700472 hdd_adapter_t *adapter;
473 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700474 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700475 QDF_STATUS status;
476 uint32_t ndp_qos_cfg;
477 tHalHandle hal = hdd_ctx->hHal;
478 struct nan_datapath_ctx *ndp_ctx;
479
480 ENTER();
481
482 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700483 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700484 return -EINVAL;
485 }
486
487 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
488 /* Check for interface in NDI mode */
489 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
490 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700491 hdd_err("NAN data interface %s not available", iface_name);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700492 return -EINVAL;
493 }
494
495 /* NAN data path coexists only with STA interface */
496 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700497 hdd_err("Unsupported concurrency for NAN datapath");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700498 return -EPERM;
499 }
500
501 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
502
503 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
504 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
505 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700506 hdd_err("Data request not allowed in NDI current state: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700507 ndp_ctx->state);
508 return -EINVAL;
509 }
510
511 req.vdev_id = adapter->sessionId;
512
513 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700514 hdd_err("Transaction ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700515 return -EINVAL;
516 }
517 req.transaction_id =
518 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
519
Naveen Rawat0a017052016-10-19 14:17:07 -0700520 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL])
521 req.channel =
522 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
523
Ravi Joshi71e82f32017-02-09 23:15:16 -0800524 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG])
Naveen Rawat0a017052016-10-19 14:17:07 -0700525 req.channel_cfg =
526 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700527
528 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700529 hdd_err("NDP service instance ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700530 return -EINVAL;
531 }
532 req.service_instance_id =
Naveen Rawat19da3d12016-08-16 12:39:38 -0700533 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700534
535 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
536 adapter->macAddressCurrent.bytes, QDF_MAC_ADDR_SIZE);
537
538 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700539 hdd_err("NDI peer discovery mac addr is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700540 return -EINVAL;
541 }
542 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
543 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
544 QDF_MAC_ADDR_SIZE);
545
Naveen Rawat90ae3082016-06-29 18:22:59 -0700546 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
547 req.ndp_info.ndp_app_info_len =
548 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
549 req.ndp_info.ndp_app_info =
550 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700551 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700552
553 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
554 /* at present ndp config stores 4 bytes QOS info only */
555 req.ndp_config.ndp_cfg_len = 4;
556 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
557 ndp_qos_cfg =
558 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
559 }
560
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800561 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
562 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
563 hdd_err("PMK cannot be absent when CSID is present.");
564 return -EINVAL;
565 }
566
567 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
568 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
569 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
570 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
571 QDF_TRACE_LEVEL_DEBUG,
572 req.pmk.pmk, req.pmk.pmk_len);
573 }
574
575 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
576 req.ncs_sk_type =
577 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
578
579 }
580
Ravi Joshi71e82f32017-02-09 23:15:16 -0800581 hdd_info("vdev_id: %d, transaction_id: %d, channel: %d, channel_cfg: %d, service_instance_id: %d, ndp_app_info_len: %d, csid: %d, peer_discovery_mac_addr: %pM",
582 req.vdev_id, req.transaction_id, req.channel, req.channel_cfg,
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700583 req.service_instance_id, req.ndp_info.ndp_app_info_len,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800584 req.ncs_sk_type, req.peer_discovery_mac_addr.bytes);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700585 status = sme_ndp_initiator_req_handler(hal, &req);
586 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700587 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700588 status);
589 return -ECOMM;
590 }
591 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700592 return 0;
593}
594
595/**
596 * hdd_ndp_responder_req_handler() - NDP responder request handler
597 * @hdd_ctx: hdd context
598 * @tb: parsed NL attribute list
599 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800600 * tb includes following vendor attributes:
601 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
602 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
603 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
604 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
605 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
606 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
607 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
608 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
609 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700610 * Return: 0 on success or error code on failure
611 */
612static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx,
613 struct nlattr **tb)
614{
Abhishek Singh4fef7472016-06-06 11:36:03 -0700615 hdd_adapter_t *adapter;
616 char *iface_name;
617 struct ndp_responder_req req = {0};
618 QDF_STATUS status;
619 int ret = 0;
620 struct nan_datapath_ctx *ndp_ctx;
621 uint32_t ndp_qos_cfg;
622
623 ENTER();
624
625 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700626 hdd_err("Interface name string is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700627 return -EINVAL;
628 }
629
630 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
631 /* Check if there is already an existing NAN interface */
632 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
633 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700634 hdd_err("NAN data interface %s not available", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700635 return -EINVAL;
636 }
637
638 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700639 hdd_err("Interface %s not in NDI mode", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700640 return -EINVAL;
641 }
642
643 /* NAN data path coexists only with STA interface */
644 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700645 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700646 return -EINVAL;
647 }
648
649 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
650
651 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
652 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
653 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700654 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700655 ndp_ctx->state);
656 return -EAGAIN;
657 }
658
659 req.vdev_id = adapter->sessionId;
660
661 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700662 hdd_err("Transaction ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700663 return -EINVAL;
664 }
665 req.transaction_id =
666 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
667
668 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700669 hdd_err("Instance ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700670 return -EINVAL;
671 }
672 req.ndp_instance_id =
673 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
674
675 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700676 hdd_err("ndp_rsp is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700677 return -EINVAL;
678 }
679 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
680
681 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
682 req.ndp_info.ndp_app_info_len =
683 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
684 if (req.ndp_info.ndp_app_info_len) {
685 req.ndp_info.ndp_app_info =
686 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
687 }
688 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700689 hdd_info("NDP app info is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700690 }
691 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
692 /* at present ndp config stores 4 bytes QOS info only */
693 req.ndp_config.ndp_cfg_len = 4;
694 ndp_qos_cfg =
695 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
696 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
697 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700698 hdd_info("NDP config data is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700699 }
700
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800701 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
702 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
703 hdd_err("PMK cannot be absent when CSID is present.");
704 return -EINVAL;
705 }
706
707 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
708 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
709 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
710 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
711 QDF_TRACE_LEVEL_DEBUG,
712 req.pmk.pmk, req.pmk.pmk_len);
713 }
714
715 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
716 req.ncs_sk_type =
717 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
718
719 }
720
721 hdd_info("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700722 req.vdev_id, req.transaction_id, req.ndp_rsp,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800723 req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
724 req.ncs_sk_type);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700725
726 status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req);
727 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700728 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700729 status);
730 ret = -EINVAL;
731 }
732
733 EXIT();
734 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700735}
736
737/**
738 * hdd_ndp_end_req_handler() - NDP end request handler
739 * @hdd_ctx: hdd context
740 * @tb: parsed NL attribute list
741 *
742 * Return: 0 on success or error code on failure
743 */
Naveen Rawatf28315c2016-06-29 18:06:02 -0700744static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700745{
Naveen Rawatf28315c2016-06-29 18:06:02 -0700746 struct ndp_end_req req = {0};
747 QDF_STATUS status;
748 tHalHandle hal = hdd_ctx->hHal;
749
750 ENTER();
751
752 /* NAN data path coexists only with STA interface */
753 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700754 hdd_err("Unsupported concurrency for NAN datapath");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700755 return -EINVAL;
756 }
757
758 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700759 hdd_err("Transaction ID is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700760 return -EINVAL;
761 }
762 req.transaction_id =
763 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
764
765 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700766 hdd_err("NDP instance ID array is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700767 return -EINVAL;
768 }
769
770 req.num_ndp_instances =
771 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
772 sizeof(uint32_t);
773 if (0 >= req.num_ndp_instances) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700774 hdd_err("Num NDP instances is 0");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700775 return -EINVAL;
776 }
777 req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
778
Naveen Rawatba4f6612016-07-05 12:03:16 -0700779 hdd_info("sending ndp_end_req to SME, transaction_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700780 req.transaction_id);
781
782 status = sme_ndp_end_req_handler(hal, &req);
783 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700784 hdd_err("sme_ndp_end_req_handler failed, status: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700785 status);
786 return -ECOMM;
787 }
788 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700789 return 0;
790}
791
792/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700793 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
794 * @adapter: pointer to adapter context
795 * @rsp_params: response parameters
796 *
797 * The function is expected to send a response back to the user space
798 * even if the creation of BSS has failed
799 *
800 * Following vendor event is sent to cfg80211:
801 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
802 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
803 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800804 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700805 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
806 *
807 * Return: none
808 */
809static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
810 void *rsp_params)
811{
812 struct sk_buff *vendor_event;
813 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
814 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
815 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
816 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
817 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700818 bool create_fail = false;
819 uint8_t create_transaction_id = 0;
Naveen Rawate21103f2016-07-08 14:18:00 -0700820 uint32_t create_status = NDP_RSP_STATUS_ERROR;
821 uint32_t create_reason = NDP_NAN_DATA_IFACE_CREATE_FAILED;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700822 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
823 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
824 tCsrRoamInfo roam_info = {0};
825 tSirBssDescription tmp_bss_descp = {0};
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700826
827 ENTER();
828
829 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700830 /* No way the driver can send response back to user space */
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700831 return;
832
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700833 if (ndi_rsp) {
834 create_status = ndi_rsp->status;
Naveen Rawate21103f2016-07-08 14:18:00 -0700835 create_reason = ndi_rsp->reason;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700836 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700837 hdd_err("Invalid ndi create response");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700838 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700839 }
840
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700841 if (ndp_ctx) {
842 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
843 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700844 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700845 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700846 }
847
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700848 if (!sta_ctx) {
849 hdd_err("sta_ctx is NULL");
850 create_fail = true;
851 }
852
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700853 /* notify response to the upper layer */
854 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
855 NULL,
856 data_len,
857 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
858 cds_get_gfp_flags());
859
860 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700861 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700862 create_fail = true;
863 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700864 }
865
866 /* Sub vendor command */
867 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
868 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700869 hdd_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700870 goto nla_put_failure;
871 }
872
873 /* Transaction id */
874 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700875 create_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700876 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700877 goto nla_put_failure;
878 }
879
880 /* Status code */
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800881 if (nla_put_u32(vendor_event,
882 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700883 create_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700884 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700885 goto nla_put_failure;
886 }
887
888 /* Status return value */
889 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700890 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawate21103f2016-07-08 14:18:00 -0700891 create_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700892 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700893 goto nla_put_failure;
894 }
895
Naveen Rawatba4f6612016-07-05 12:03:16 -0700896 hdd_info("sub command: %d, value: %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700897 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
898 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700899 hdd_info("create transaction id: %d, value: %d",
900 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
901 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800902 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
903 create_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700904 hdd_info("Return value: %d, value: %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700905 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700906
907 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
908
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700909 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700910 hdd_err("NDI interface successfully created");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700911 ndp_ctx->ndp_create_transaction_id = 0;
912 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700913 wlan_hdd_netif_queue_control(adapter,
914 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
915 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700916 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700917 hdd_err("NDI interface creation failed with reason %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700918 create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700919 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700920
921 /* Something went wrong while starting the BSS */
922 if (create_fail)
923 goto close_ndi;
924
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700925 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
926 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
927 hdd_roam_register_sta(adapter, &roam_info,
928 sta_ctx->broadcast_staid,
929 &bc_mac_addr, &tmp_bss_descp);
930 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
931
932
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700933 EXIT();
934 return;
935
936nla_put_failure:
937 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700938close_ndi:
939 hdd_close_ndi(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700940 return;
941}
942
943/**
944 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
945 * @adapter: pointer to adapter context
946 * @rsp_params: response parameters
947 *
948 * Return: none
949 */
950static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
951 void *rsp_params)
952{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700953 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
954 struct ndi_delete_rsp *ndi_rsp = rsp_params;
Naveen Rawat8d63a592016-06-29 18:30:59 -0700955 struct nan_datapath_ctx *ndp_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700956
957 if (wlan_hdd_validate_context(hdd_ctx))
958 return;
959
960 if (!ndi_rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700961 hdd_err("Invalid ndi delete response");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700962 return;
963 }
964
Naveen Rawat8d63a592016-06-29 18:30:59 -0700965 if (ndi_rsp->status == NDP_RSP_STATUS_SUCCESS)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700966 hdd_err("NDI BSS successfully stopped");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700967 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700968 hdd_err("NDI BSS stop failed with reason %d", ndi_rsp->reason);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700969
970 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
971 ndp_ctx->ndi_delete_rsp_reason = ndi_rsp->reason;
972 ndp_ctx->ndi_delete_rsp_status = ndi_rsp->status;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700973 wlan_hdd_netif_queue_control(adapter,
974 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
975 WLAN_CONTROL_PATH);
Naveen Rawat8d63a592016-06-29 18:30:59 -0700976
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700977 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700978 return;
979}
980
981/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700982 * hdd_ndp_session_end_handler() - NDI session termination handler
983 * @adapter: pointer to adapter context
984 *
985 * Following vendor event is sent to cfg80211:
986 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
987 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
988 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800989 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700990 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
991 *
992 * Return: none
993 */
994void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
995{
996 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
997 struct sk_buff *vendor_event;
998 struct nan_datapath_ctx *ndp_ctx;
999 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
1000 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
1001
1002 ENTER();
1003
1004 if (wlan_hdd_validate_context(hdd_ctx))
1005 return;
1006
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001007 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1008 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001009 hdd_err("ndp context is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001010 return;
1011 }
1012
1013 /*
1014 * The virtual adapters are stopped and closed even during
1015 * driver unload or stop, the service layer is not required
1016 * to be informed in that case (response is not expected)
1017 */
1018 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001019 hdd_err("NDI interface %s deleted", adapter->dev->name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001020 return;
1021 }
1022
1023 /* notify response to the upper layer */
1024 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1025 NULL,
1026 data_len,
1027 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1028 GFP_KERNEL);
1029
1030 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001031 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001032 return;
1033 }
1034
1035 /* Sub vendor command goes first */
1036 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1037 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001038 hdd_err("VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001039 goto failure;
1040 }
1041
1042 /* Transaction id */
1043 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1044 ndp_ctx->ndp_delete_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001045 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001046 goto failure;
1047 }
1048
1049 /* Status code */
1050 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001051 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001052 ndp_ctx->ndi_delete_rsp_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001053 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001054 goto failure;
1055 }
1056
1057 /* Status return value */
1058 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001059 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1060 ndp_ctx->ndi_delete_rsp_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001061 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001062 goto failure;
1063 }
1064
Naveen Rawatba4f6612016-07-05 12:03:16 -07001065 hdd_info("sub command: %d, value: %d", QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001066 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001067 hdd_info("delete transaction id: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001068 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1069 ndp_ctx->ndp_delete_transaction_id);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001070 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001071 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001072 ndp_ctx->ndi_delete_rsp_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001073 hdd_info("Return value: %d, value: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001074 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1075 ndp_ctx->ndi_delete_rsp_reason);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001076
1077 ndp_ctx->ndp_delete_transaction_id = 0;
1078 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
1079
1080 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1081
1082 EXIT();
1083 return;
1084
1085failure:
1086 kfree_skb(vendor_event);
1087}
1088
1089
1090/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001091 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
1092 * @adapter: pointer to adapter context
1093 * @rsp_params: response parameters
1094 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001095 * Following vendor event is sent to cfg80211:
1096 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1097 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1098 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1099 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001100 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001101 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1102 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001103 * Return: none
1104 */
1105static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter,
1106 void *rsp_params)
1107{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001108 struct sk_buff *vendor_event;
1109 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1110 struct ndp_initiator_rsp *rsp = rsp_params;
1111 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
1112 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
1113
1114 ENTER();
1115
1116 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001117 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001118 return;
1119 }
1120
1121 if (0 != wlan_hdd_validate_context(hdd_ctx))
1122 return;
1123
1124 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1125 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1126 GFP_KERNEL);
1127 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001128 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001129 return;
1130 }
1131
1132 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1133 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1134 goto ndp_initiator_rsp_nla_failed;
1135
1136 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1137 rsp->transaction_id))
1138 goto ndp_initiator_rsp_nla_failed;
1139
1140 if (nla_put_u32(vendor_event,
1141 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1142 rsp->ndp_instance_id))
1143 goto ndp_initiator_rsp_nla_failed;
1144
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001145 if (nla_put_u32(vendor_event,
1146 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001147 rsp->status))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001148 goto ndp_initiator_rsp_nla_failed;
1149
1150 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001151 rsp->reason))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001152 goto ndp_initiator_rsp_nla_failed;
1153
Naveen Rawatba4f6612016-07-05 12:03:16 -07001154 hdd_info("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001155 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1156 rsp->reason);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001157 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1158 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001159 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001160ndp_initiator_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001161 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001162 kfree_skb(vendor_event);
1163 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001164}
1165
1166/**
1167 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
1168 * @adapter: pointer to adapter context
1169 * @ind_params: indication parameters
1170 *
1171 * Return: none
1172 */
1173static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
1174 void *ind_params)
1175{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001176 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
1177 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1178 tSirBssDescription tmp_bss_descp = {0};
1179 tCsrRoamInfo roam_info = {0};
1180 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1181 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1182
1183 ENTER();
1184
1185 if (NULL == ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001186 hdd_err("Invalid new NDP peer params");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001187 return;
1188 }
Naveen Rawatba4f6612016-07-05 12:03:16 -07001189 hdd_info("session_id: %d, peer_mac: %pM, sta_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001190 new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
1191 new_peer_ind->sta_id);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001192
1193 /* save peer in ndp ctx */
1194 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
1195 &new_peer_ind->peer_mac_addr)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001196 hdd_err("Ndp peer table full. cannot save new peer");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001197 return;
1198 }
1199
1200 /* this function is called for each new peer */
1201 ndp_ctx->active_ndp_peers++;
Naveen Rawatba4f6612016-07-05 12:03:16 -07001202 hdd_info("vdev_id: %d, num_peers: %d", adapter->sessionId,
1203 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001204
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001205 hdd_roam_register_sta(adapter, &roam_info, new_peer_ind->sta_id,
1206 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
1207 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
1208 /* perform following steps for first new peer ind */
1209 if (ndp_ctx->active_ndp_peers == 1) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001210 hdd_info("Set ctx connection state to connected");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001211 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
1212 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001213 wlan_hdd_netif_queue_control(adapter,
1214 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001215 }
1216 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001217}
1218
1219/**
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001220 * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001221 * @adapter: pointer to adapter context
1222 * @ind_params: indication parameters
1223 *
1224 * Return: none
1225 */
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001226static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter,
1227 void *ind_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001228{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001229 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1230 struct sme_ndp_peer_ind *peer_ind = ind_params;
1231 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1232 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1233
1234 hdd_roam_deregister_sta(adapter, peer_ind->sta_id);
1235 hdd_delete_peer(sta_ctx, peer_ind->sta_id);
1236 hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
1237
1238 if (--ndp_ctx->active_ndp_peers == 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001239 hdd_info("No more ndp peers.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001240 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
1241 hdd_conn_set_connection_state(adapter,
1242 eConnectionState_NdiDisconnected);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001243 hdd_info("Stop netif tx queues.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001244 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
1245 WLAN_CONTROL_PATH);
1246 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001247}
1248
1249/**
1250 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1251 * @adapter: pointer to adapter context
1252 * @ind_params: indication parameters
1253 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001254 * Following vendor event is sent to cfg80211:
1255 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1256 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1257 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1258 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1259 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1260 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1261 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1262 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1263 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001264 * Return: none
1265 */
1266static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
1267 void *ind_params)
1268{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001269 int idx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001270 uint32_t ndp_qos_config = 0;
1271 struct ndp_confirm_event *ndp_confirm = ind_params;
1272 struct sk_buff *vendor_event;
1273 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1274 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Naveen Rawatf28315c2016-06-29 18:06:02 -07001275 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001276 uint32_t data_len;
1277
1278 ENTER();
1279 if (!ndp_confirm) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001280 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001281 return;
1282 }
1283
1284 if (0 != wlan_hdd_validate_context(hdd_ctx))
1285 return;
1286
Naveen Rawatf28315c2016-06-29 18:06:02 -07001287 /* ndp_confirm is called each time user generated ndp req succeeds */
1288 idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
1289 if (idx == INVALID_PEER_IDX)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001290 hdd_err("can't find addr: %pM in vdev_id: %d, peer table.",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001291 &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId);
Naveen Rawat460be782016-06-29 18:26:22 -07001292 else if (ndp_confirm->rsp_code == NDP_RESPONSE_ACCEPT)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001293 ndp_ctx->active_ndp_sessions[idx]++;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001294
1295 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
Naveen Rawat90ae3082016-06-29 18:22:59 -07001296 + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001297 ndp_confirm->ndp_info.ndp_app_info_len;
1298
Naveen Rawat8d63a592016-06-29 18:30:59 -07001299 if (ndp_confirm->ndp_info.ndp_app_info_len)
1300 data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
1301
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001302 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1303 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1304 GFP_KERNEL);
1305 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001306 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001307 return;
1308 }
1309
1310 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1311 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1312 goto ndp_confirm_nla_failed;
1313
1314 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1315 ndp_confirm->ndp_instance_id))
1316 goto ndp_confirm_nla_failed;
1317
1318 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1319 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1320 goto ndp_confirm_nla_failed;
1321
1322 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1323 IFNAMSIZ, adapter->dev->name))
1324 goto ndp_confirm_nla_failed;
1325
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001326 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001327 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1328 ndp_confirm->ndp_info.ndp_app_info_len,
1329 ndp_confirm->ndp_info.ndp_app_info))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001330 goto ndp_confirm_nla_failed;
1331
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001332 if (nla_put_u32(vendor_event,
1333 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1334 ndp_confirm->rsp_code))
1335 goto ndp_confirm_nla_failed;
1336
Naveen Rawat8d63a592016-06-29 18:30:59 -07001337 if (nla_put_u32(vendor_event,
1338 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1339 ndp_confirm->reason_code))
1340 goto ndp_confirm_nla_failed;
1341
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001342 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001343 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 -07001344 ndp_confirm->ndp_instance_id,
1345 ndp_confirm->peer_ndi_mac_addr.bytes,
Naveen Rawat460be782016-06-29 18:26:22 -07001346 ndp_qos_config, ndp_confirm->rsp_code,
1347 ndp_confirm->reason_code);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001348
Naveen Rawatba4f6612016-07-05 12:03:16 -07001349 hdd_info("NDP confim, ndp app info dump");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001350 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1351 ndp_confirm->ndp_info.ndp_app_info,
1352 ndp_confirm->ndp_info.ndp_app_info_len);
1353 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001354 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001355ndp_confirm_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001356 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001357 kfree_skb(vendor_event);
1358 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001359}
1360
1361/**
1362 * hdd_ndp_indication_handler() - NDP indication handler
1363 * @adapter: pointer to adapter context
1364 * @ind_params: indication parameters
1365 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001366 * Following vendor event is sent to cfg80211:
1367 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1368 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1369 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
Naveen Rawat19da3d12016-08-16 12:39:38 -07001370 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001371 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1372 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1373 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1374 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1375 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001376 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes)
1377 * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001378 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001379 * Return: none
1380 */
1381static void hdd_ndp_indication_handler(hdd_adapter_t *adapter,
1382 void *ind_params)
1383{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001384 struct sk_buff *vendor_event;
1385 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1386 struct ndp_indication_event *event = ind_params;
1387 uint32_t ndp_qos_config;
1388 struct nan_datapath_ctx *ndp_ctx;
1389 uint16_t data_len;
1390
1391 ENTER();
1392 if (!ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001393 hdd_err("Invalid NDP Indication");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001394 return;
1395 }
1396
1397 if (0 != wlan_hdd_validate_context(hdd_ctx))
1398 return;
1399
1400 /* Handle only if adapter is in NDI mode */
1401 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001402 hdd_err("Adapter is not in NDI mode");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001403 return;
1404 }
1405
Naveen Rawatba4f6612016-07-05 12:03:16 -07001406 hdd_info("NDP Indication, policy: %d", event->policy);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001407
1408 /* Policy check */
1409 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001410 hdd_err("NAN datapath is not suported");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001411 return;
1412 }
1413
1414 /* NAN data path coexists only with STA interface */
1415 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001416 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001417 return;
1418 }
1419
1420 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1421
1422 /* check if we are in middle of deleting/creating the interface */
1423 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
1424 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
1425 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001426 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001427 ndp_ctx->state);
1428 return;
1429 }
1430
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001431 data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
1432 event->ndp_info.ndp_app_info_len + event->scid.scid_len +
1433 (10 * NLA_HDRLEN) + NLMSG_HDRLEN;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001434
1435 /* notify response to the upper layer */
1436 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1437 NULL, data_len,
1438 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1439 GFP_KERNEL);
1440 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001441 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001442 return;
1443 }
1444
1445 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1446 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1447 goto ndp_indication_nla_failed;
1448
1449 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1450 IFNAMSIZ, adapter->dev->name))
1451 goto ndp_indication_nla_failed;
1452
Naveen Rawat19da3d12016-08-16 12:39:38 -07001453 if (nla_put_u32(vendor_event,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001454 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1455 event->service_instance_id))
1456 goto ndp_indication_nla_failed;
1457
1458 if (nla_put(vendor_event,
1459 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1460 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1461 goto ndp_indication_nla_failed;
1462
1463 if (nla_put(vendor_event,
Jeff Johnson03294f12016-12-09 17:10:24 -08001464 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001465 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1466 goto ndp_indication_nla_failed;
1467
1468 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1469 event->ndp_instance_id))
1470 goto ndp_indication_nla_failed;
1471
1472 if (event->ndp_info.ndp_app_info_len)
1473 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1474 event->ndp_info.ndp_app_info_len,
1475 event->ndp_info.ndp_app_info))
1476 goto ndp_indication_nla_failed;
1477
1478 if (event->ndp_config.ndp_cfg_len) {
1479 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1480 /* at present ndp config stores 4 bytes QOS info only */
1481 if (nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1483 ndp_qos_config))
1484 goto ndp_indication_nla_failed;
1485 }
1486
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001487 if (event->scid.scid_len) {
1488 if (nla_put_u32(vendor_event,
1489 QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE,
1490 event->ncs_sk_type))
1491 goto ndp_indication_nla_failed;
1492
1493 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
1494 event->scid.scid_len,
1495 event->scid.scid))
1496 goto ndp_indication_nla_failed;
1497
1498 hdd_info("csid: %d, scid_len: %d",
1499 event->ncs_sk_type, event->scid.scid_len);
1500
1501 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1502 event->scid.scid, event->scid.scid_len);
1503 }
1504
Abhishek Singh4fef7472016-06-06 11:36:03 -07001505 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1506 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001507 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001508ndp_indication_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001509 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001510 kfree_skb(vendor_event);
1511 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001512}
1513
1514/**
1515 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1516 * @adapter: pointer to adapter context
1517 * @rsp_params: response parameters
1518 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001519 * Following vendor event is sent to cfg80211:
1520 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1521 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1522 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001523 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1524 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001525 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001526 * Return: none
1527 */
1528static void hdd_ndp_responder_rsp_handler(hdd_adapter_t *adapter,
1529 void *rsp_params)
1530{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001531 struct sk_buff *vendor_event;
1532 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1533 struct ndp_responder_rsp_event *rsp = rsp_params;
1534 uint16_t data_len;
1535
1536 ENTER();
1537 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001538 hdd_err("Invalid NDP Responder response");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001539 return;
1540 }
1541
1542 if (0 != wlan_hdd_validate_context(hdd_ctx))
1543 return;
1544
Naveen Rawatba4f6612016-07-05 12:03:16 -07001545 hdd_info("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001546 rsp->vdev_id, rsp->transaction_id,
1547 rsp->status, rsp->reason);
1548
1549 data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
1550 4 * NLA_HDRLEN + NLMSG_HDRLEN;
1551 /* notify response to the upper layer */
1552 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1553 NULL, data_len,
1554 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1555 GFP_KERNEL);
1556 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001557 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001558 return;
1559 }
1560
1561 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1562 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1563 goto ndp_responder_rsp_nla_failed;
1564
1565 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1566 rsp->transaction_id))
1567 goto ndp_responder_rsp_nla_failed;
1568
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001569 if (nla_put_u32(vendor_event,
1570 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001571 rsp->status))
1572 goto ndp_responder_rsp_nla_failed;
1573
1574 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001575 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001576 rsp->reason))
1577 goto ndp_responder_rsp_nla_failed;
1578
1579 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1580 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001581 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001582ndp_responder_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001583 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001584 kfree_skb(vendor_event);
1585 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001586}
1587
1588/**
1589 * hdd_ndp_end_rsp_handler() - NDP end response handler
1590 * @adapter: pointer to adapter context
1591 * @rsp_params: response parameters
1592 *
Naveen Rawatf28315c2016-06-29 18:06:02 -07001593 * Following vendor event is sent to cfg80211:
1594 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1595 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001596 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001597 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1598 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1599 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001600 * Return: none
1601 */
Naveen Rawatf28315c2016-06-29 18:06:02 -07001602static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, void *rsp_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001603{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001604 struct sk_buff *vendor_event;
1605 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1606 struct ndp_end_rsp_event *rsp = rsp_params;
Rakesh Sunkiae936b62016-07-28 16:01:45 -07001607 uint32_t data_len;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001608
1609 ENTER();
1610
1611 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001612 hdd_err("Invalid ndp end response");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001613 return;
1614 }
1615
1616 if (0 != wlan_hdd_validate_context(hdd_ctx))
1617 return;
1618
Naveen Rawatf28315c2016-06-29 18:06:02 -07001619 data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
1620 sizeof(uint16_t);
1621
1622 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1623 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1624 GFP_KERNEL);
1625 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001626 hdd_err("cfg80211_vendor_event_alloc failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001627 return;
1628 }
1629
1630 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1631 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1632 goto ndp_end_rsp_nla_failed;
1633
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001634 if (nla_put_u32(vendor_event,
1635 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001636 rsp->status))
1637 goto ndp_end_rsp_nla_failed;
1638
1639 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1640 rsp->reason))
1641 goto ndp_end_rsp_nla_failed;
1642
1643 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1644 rsp->transaction_id))
1645 goto ndp_end_rsp_nla_failed;
1646
Naveen Rawatba4f6612016-07-05 12:03:16 -07001647 hdd_info("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001648 rsp->transaction_id, rsp->status, rsp->reason);
1649 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1650 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001651 return;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001652
1653ndp_end_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001654 hdd_err("nla_put api failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001655 kfree_skb(vendor_event);
1656 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001657}
1658
1659/**
1660 * hdd_ndp_end_ind_handler() - NDP end indication handler
1661 * @adapter: pointer to adapter context
1662 * @ind_params: indication parameters
1663 *
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001664 * Following vendor event is sent to cfg80211:
1665 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1666 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001667 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1668 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001669 * Return: none
1670 */
1671static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
1672 void *ind_params)
1673{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001674 struct sk_buff *vendor_event;
1675 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1676 struct ndp_end_indication_event *end_ind = ind_params;
1677 uint32_t data_len, i;
1678 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1679 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1680 uint32_t *ndp_instance_array;
Naveen Rawate21103f2016-07-08 14:18:00 -07001681 hdd_adapter_t *ndi_adapter;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001682
1683 ENTER();
1684
1685 if (!end_ind) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001686 hdd_err("Invalid ndp end indication");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001687 return;
1688 }
1689
1690 if (0 != wlan_hdd_validate_context(hdd_ctx))
1691 return;
1692
1693 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1694 sizeof(*ndp_instance_array));
1695 if (!ndp_instance_array) {
1696 hdd_err("Failed to allocate ndp_instance_array");
1697 return;
1698 }
1699 for (i = 0; i < end_ind->num_ndp_ids; i++) {
1700 int idx;
1701
1702 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
Naveen Rawate21103f2016-07-08 14:18:00 -07001703 ndi_adapter = hdd_get_adapter_by_vdev(hdd_ctx,
1704 end_ind->ndp_map[i].vdev_id);
1705 if (ndi_adapter == NULL) {
1706 hdd_err("Adapter not found for vdev_id: %d",
1707 end_ind->ndp_map[i].vdev_id);
1708 continue;
1709 }
1710 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
Govind Singhb8475942016-08-12 11:07:09 +05301711 if (!ndp_ctx) {
1712 hdd_err("ndp_ctx is NULL for vdev id: %d",
1713 end_ind->ndp_map[i].vdev_id);
1714 continue;
1715 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001716 idx = hdd_get_peer_idx(sta_ctx,
1717 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1718 if (idx == INVALID_PEER_IDX) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001719 hdd_err("can't find addr: %pM in sta_ctx.",
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001720 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1721 continue;
1722 }
1723 /* save the value of active sessions on each peer */
1724 ndp_ctx->active_ndp_sessions[idx] =
1725 end_ind->ndp_map[i].num_active_ndp_sessions;
1726 }
1727
Naveen Rawat90ae3082016-06-29 18:22:59 -07001728 data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001729 end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
1730
1731 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1732 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1733 GFP_KERNEL);
1734 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001735 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001736 return;
1737 }
1738
1739 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1740 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1741 goto ndp_end_ind_nla_failed;
1742
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001743 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1744 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1745 ndp_instance_array))
1746 goto ndp_end_ind_nla_failed;
1747
1748 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1749 qdf_mem_free(ndp_instance_array);
1750 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001751 return;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001752
1753ndp_end_ind_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001754 hdd_err("nla_put api failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001755 kfree_skb(vendor_event);
1756 qdf_mem_free(ndp_instance_array);
1757 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001758}
1759
1760/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001761 * hdd_ndp_event_handler() - ndp response and indication handler
1762 * @adapter: adapter context
1763 * @roam_info: pointer to roam_info structure
1764 * @roam_id: roam id as indicated by SME
1765 * @roam_status: roam status
1766 * @roam_result: roam result
1767 *
1768 * Return: none
1769 */
1770void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1771 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1772 eCsrRoamResult roam_result)
1773{
1774 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1775 switch (roam_result) {
Naveen Rawat8d63a592016-06-29 18:30:59 -07001776 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001777 hdd_ndp_iface_create_rsp_handler(adapter,
1778 &roam_info->ndp.ndi_create_params);
1779 break;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001780 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001781 hdd_ndp_iface_delete_rsp_handler(adapter,
1782 &roam_info->ndp.ndi_delete_params);
1783 break;
1784 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1785 hdd_ndp_initiator_rsp_handler(adapter,
1786 &roam_info->ndp.ndp_init_rsp_params);
1787 break;
1788 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1789 hdd_ndp_new_peer_ind_handler(adapter,
1790 &roam_info->ndp.ndp_peer_ind_params);
1791 break;
1792 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1793 hdd_ndp_confirm_ind_handler(adapter,
1794 &roam_info->ndp.ndp_confirm_params);
1795 break;
1796 case eCSR_ROAM_RESULT_NDP_INDICATION:
1797 hdd_ndp_indication_handler(adapter,
1798 &roam_info->ndp.ndp_indication_params);
1799 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001800 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1801 hdd_ndp_responder_rsp_handler(adapter,
1802 &roam_info->ndp.ndp_responder_rsp_params);
1803 break;
1804 case eCSR_ROAM_RESULT_NDP_END_RSP:
1805 hdd_ndp_end_rsp_handler(adapter,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001806 roam_info->ndp.ndp_end_rsp_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001807 break;
1808 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1809 hdd_ndp_peer_departed_ind_handler(adapter,
1810 &roam_info->ndp.ndp_peer_ind_params);
1811 break;
1812 case eCSR_ROAM_RESULT_NDP_END_IND:
1813 hdd_ndp_end_ind_handler(adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001814 roam_info->ndp.ndp_end_ind_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001815 break;
1816 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001817 hdd_err("Unknown NDP response event from SME %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001818 roam_result);
1819 break;
1820 }
1821 }
1822}
Naveen Rawat97500352017-03-22 10:07:58 -07001823#else
1824void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1825 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1826 eCsrRoamResult roam_result)
1827{
Naveen Rawatcb5c5402017-03-22 10:12:19 -07001828 bool success;
1829 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(adapter->hdd_vdev);
1830
1831 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1832 switch (roam_result) {
1833 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
1834 success = (roam_info->ndp.ndi_create_params.status ==
1835 NAN_DATAPATH_RSP_STATUS_SUCCESS);
1836 hdd_debug("posting ndi create status: %d to umac",
1837 success);
1838 os_if_nan_post_ndi_create_rsp(psoc, adapter->sessionId,
1839 success);
1840 return;
1841 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
1842 success = (roam_info->ndp.ndi_create_params.status ==
1843 NAN_DATAPATH_RSP_STATUS_SUCCESS);
1844 hdd_debug("posting ndi delete status: %d to umac",
1845 success);
1846 os_if_nan_post_ndi_delete_rsp(psoc, adapter->sessionId,
1847 success);
1848 return;
1849 default:
1850 hdd_err("in correct roam_result: %d", roam_result);
1851 return;
1852 }
1853 } else {
1854 hdd_err("in correct roam_status: %d", roam_status);
1855 return;
1856 }
Naveen Rawat97500352017-03-22 10:07:58 -07001857}
1858#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001859
1860/**
1861 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1862 * @wiphy: pointer to wireless wiphy structure.
1863 * @wdev: pointer to wireless_dev structure.
1864 * @data: Pointer to the data to be passed via vendor interface
1865 * @data_len:Length of the data to be passed
1866 *
1867 * This function is invoked to handle vendor command
1868 *
1869 * Return: 0 on success, negative errno on failure
1870 */
Naveen Rawat63de5422017-03-22 11:03:56 -07001871#ifdef WLAN_FEATURE_NAN_CONVERGENCE
1872static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1873 struct wireless_dev *wdev, const void *data, int data_len)
1874{
1875 int ret_val;
1876 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1877
1878 ENTER();
1879
1880 ret_val = wlan_hdd_validate_context(hdd_ctx);
1881 if (ret_val)
1882 return ret_val;
1883
1884 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1885 hdd_err("Command not allowed in FTM mode");
1886 return -EPERM;
1887 }
1888
1889 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
1890 hdd_err("NAN datapath is not enabled");
1891 return -EPERM;
1892 }
1893 /* NAN data path coexists only with STA interface */
1894 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
1895 hdd_err("Unsupported concurrency for NAN datapath");
1896 return -EPERM;
1897 }
1898
1899 /* NAN data path coexists only with STA interface */
1900 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
1901 hdd_err("Unsupported concurrency for NAN datapath");
1902 return -EPERM;
1903 }
1904
1905 return os_if_nan_process_ndp_cmd(hdd_ctx->hdd_psoc,
1906 data, data_len);
1907}
1908#else
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001909static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1910 struct wireless_dev *wdev, const void *data, int data_len)
1911{
1912 uint32_t ndp_cmd_type;
1913 uint16_t transaction_id;
1914 int ret_val;
1915 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1916 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1917 char *iface_name;
1918
1919 ENTER();
1920
1921 ret_val = wlan_hdd_validate_context(hdd_ctx);
1922 if (ret_val)
1923 return ret_val;
1924
1925 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001926 hdd_err("Command not allowed in FTM mode");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001927 return -EPERM;
1928 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07001929 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001930 hdd_err("NAN datapath is not enabled");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001931 return -EPERM;
1932 }
1933 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1934 data, data_len,
1935 qca_wlan_vendor_ndp_policy)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001936 hdd_err("Invalid NDP vendor command attributes");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001937 return -EINVAL;
1938 }
1939
1940 /* Parse and fetch NDP Command Type*/
1941 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001942 hdd_err("NAN datapath cmd type failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001943 return -EINVAL;
1944 }
1945 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1946
1947 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001948 hdd_err("attr transaction id failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001949 return -EINVAL;
1950 }
1951 transaction_id = nla_get_u16(
1952 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1953
Naveen Rawatf28315c2016-06-29 18:06:02 -07001954 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
1955 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001956 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: %s",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001957 transaction_id, ndp_cmd_type, iface_name);
1958 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001959 hdd_err("Transaction Id: %d NDP Cmd: %d iface_name: unspecified",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001960 transaction_id, ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001961 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001962
1963 switch (ndp_cmd_type) {
1964 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
1965 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
1966 break;
1967 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
1968 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
1969 break;
1970 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
1971 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
1972 break;
1973 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
1974 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
1975 break;
1976 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
1977 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
1978 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001979 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001980 hdd_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001981 ret_val = -EINVAL;
1982 break;
1983 }
1984
1985 return ret_val;
1986}
Naveen Rawat63de5422017-03-22 11:03:56 -07001987#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001988
1989/**
1990 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
1991 * @wiphy: pointer to wireless wiphy structure.
1992 * @wdev: pointer to wireless_dev structure.
1993 * @data: Pointer to the data to be passed via vendor interface
1994 * @data_len:Length of the data to be passed
1995 *
1996 * This function is called to send a NAN request to
1997 * firmware. This is an SSR-protected wrapper function.
1998 *
1999 * Return: 0 on success, negative errno on failure
2000 */
2001int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
2002 struct wireless_dev *wdev, const void *data, int data_len)
2003{
2004 int ret;
2005
2006 cds_ssr_protect(__func__);
2007 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
2008 cds_ssr_unprotect(__func__);
2009
2010 return ret;
2011}
2012
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002013#ifndef WLAN_FEATURE_NAN_CONVERGENCE
2014static int update_ndi_state(struct hdd_adapter_s *adapter, uint32_t state)
2015{
2016 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
2017
2018 ndp_ctx->state = state;
2019 return 0;
2020}
2021#else
2022static int update_ndi_state(struct hdd_adapter_s *adapter, uint32_t state)
2023{
2024 return os_if_nan_set_ndi_state(adapter->hdd_vdev, state);
2025}
2026#endif
2027
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002028/**
2029 * hdd_init_nan_data_mode() - initialize nan data mode
2030 * @adapter: adapter context
2031 *
2032 * Returns: 0 on success negative error code on error
2033 */
2034int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
2035{
2036 struct net_device *wlan_dev = adapter->dev;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002037 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2038 QDF_STATUS status;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002039 int32_t ret_val = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002040
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002041 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002042
Dustin Brownd28772b2017-03-17 14:16:07 -07002043 ret_val = hdd_vdev_create(adapter);
2044 if (ret_val) {
2045 hdd_err("failed to create vdev: %d", ret_val);
2046 return ret_val;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002047 }
2048
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002049 /* Register wireless extensions */
2050 ret_val = hdd_register_wext(wlan_dev);
2051 if (0 > ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002052 hdd_err("Wext registration failed with status code %d",
2053 ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002054 ret_val = -EAGAIN;
2055 goto error_register_wext;
2056 }
2057
2058 status = hdd_init_tx_rx(adapter);
2059 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002060 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002061 ret_val = -EAGAIN;
2062 goto error_init_txrx;
2063 }
2064
2065 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2066
2067 status = hdd_wmm_adapter_init(adapter);
2068 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002069 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002070 ret_val = -EAGAIN;
2071 goto error_wmm_init;
2072 }
2073
2074 set_bit(WMM_INIT_DONE, &adapter->event_flags);
2075
2076 ret_val = wma_cli_set_command((int)adapter->sessionId,
2077 (int)WMI_PDEV_PARAM_BURST_ENABLE,
2078 (int)hdd_ctx->config->enableSifsBurst,
2079 PDEV_CMD);
2080 if (0 != ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002081 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002082 }
2083
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002084 update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002085 return ret_val;
2086
2087error_wmm_init:
2088 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2089 hdd_deinit_tx_rx(adapter);
2090
2091error_init_txrx:
2092 hdd_unregister_wext(wlan_dev);
2093
2094error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07002095 QDF_BUG(!hdd_vdev_destroy(adapter));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002096
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002097 return ret_val;
2098}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002099
2100#ifdef WLAN_FEATURE_NAN_CONVERGENCE
2101struct wlan_objmgr_vdev *hdd_ndi_open(char *iface_name)
2102{
2103 hdd_adapter_t *adapter;
2104 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2105
2106 ENTER();
2107 /* Check for an existing interface of NDI type */
2108 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
2109 if (adapter) {
2110 hdd_err("Cannot support more than one NDI");
2111 return NULL;
2112 }
2113
2114 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
2115 wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
2116 true);
2117 if (!adapter) {
2118 hdd_err("hdd_open_adapter failed");
2119 return NULL;
2120 }
2121
2122 EXIT();
2123 return adapter->hdd_vdev;
2124}
2125
2126int hdd_ndi_start(uint8_t vdev_id)
2127{
2128 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2129 uint8_t op_channel = hdd_ctx->config->nan_datapath_ndi_channel;
2130 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2131
2132 ENTER();
2133 /*
2134 * The NAN data interface has been created at this point.
2135 * Unlike traditional device modes, where the higher application
2136 * layer initiates connect / join / start, the NAN data
2137 * interface does not have any such formal requests. The NDI
2138 * create request is responsible for starting the BSS as well.
2139 */
2140 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
2141 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
2142 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
2143 /* start NDI on the default 2.4 GHz social channel */
2144 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
2145 }
2146 if (hdd_ndi_start_bss(adapter, op_channel)) {
2147 hdd_err("NDI start bss failed");
2148 /* Start BSS failed, delete the interface */
2149 hdd_close_ndi(adapter);
2150 EXIT();
2151 return -EINVAL;
2152 }
2153
2154 return 0;
2155}
2156
2157int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id)
2158{
2159 int ret;
2160 hdd_adapter_t *adapter;
2161 hdd_station_ctx_t *sta_ctx;
2162 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2163
2164 /* Check if there is already an existing inteface with the same name */
2165 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2166 if (!adapter || !WLAN_HDD_IS_NDI(adapter)) {
2167 hdd_err("NAN data interface %s is not available", iface_name);
2168 return -EINVAL;
2169 }
2170
2171 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2172 if (!sta_ctx) {
2173 hdd_err("sta_ctx is NULL");
2174 return -EINVAL;
2175 }
2176
2177 /* Since, the interface is being deleted, remove the broadcast id. */
2178 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
2179 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
2180
2181 os_if_nan_set_ndp_delete_transaction_id(adapter->hdd_vdev,
2182 transaction_id);
2183 os_if_nan_set_ndi_state(adapter->hdd_vdev, NAN_DATA_NDI_DELETING_STATE);
2184
2185 /* Delete the interface */
2186 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
2187 if (ret)
2188 hdd_err("NDI delete request failed");
2189 else
2190 hdd_err("NDI delete request successfully issued");
2191
2192 return ret;
2193}
2194
2195void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id,
2196 struct nan_datapath_inf_create_rsp *ndi_rsp)
2197{
2198 tCsrRoamInfo roam_info = {0};
2199 tSirBssDescription tmp_bss_descp = {0};
2200 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2201 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2202 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
2203 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2204
2205 if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
2206 hdd_alert("NDI interface successfully created");
2207 os_if_nan_set_ndp_create_transaction_id(adapter->hdd_vdev, 0);
2208 os_if_nan_set_ndi_state(adapter->hdd_vdev,
2209 NAN_DATA_NDI_CREATED_STATE);
2210 wlan_hdd_netif_queue_control(adapter,
2211 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2212 WLAN_CONTROL_PATH);
2213 } else {
2214 hdd_alert("NDI interface creation failed with reason %d",
2215 ndi_rsp->reason /* create_reason */);
2216 }
2217
2218 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
2219 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
2220 hdd_roam_register_sta(adapter, &roam_info,
2221 sta_ctx->broadcast_staid,
2222 &bc_mac_addr, &tmp_bss_descp);
2223 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
2224}
2225
2226void hdd_ndi_close(uint8_t vdev_id)
2227{
2228 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2229 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2230 hdd_close_ndi(adapter);
2231}
2232
2233void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id)
2234{
2235 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2236 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2237
2238 wlan_hdd_netif_queue_control(adapter,
2239 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
2240 WLAN_CONTROL_PATH);
2241
2242 complete(&adapter->disconnect_comp_var);
2243}
2244
2245void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
2246{
2247 os_if_nan_ndi_session_end(adapter->hdd_vdev);
2248}
2249
2250#endif