blob: 3c95d1636ebc2b9cbd83474f69b20f832dc4b32e [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 },
Jeff Johnson438ff422017-06-15 14:56:45 -070048 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_NUL_STRING,
49 .len = IFNAMSIZ - 1 },
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{
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -070086 hdd_debug("Name = [%s] Value = [%u]", CFG_ENABLE_NAN_DATAPATH_NAME,
Deepak Dhamdhere3385d752016-05-25 20:36:47 -070087 hdd_ctx->config->enable_nan_datapath);
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -070088 hdd_debug("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,
Himanshu Agarwal865201d2017-04-12 15:45:31 +0530135 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700136 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 Rawat5a6f8402017-07-03 16:00:11 -0700283/**
284 * hdd_get_random_nan_mac_addr() - generate random non pre-existent mac address
285 * @hdd_ctx: hdd context pointer
286 * @mac_addr: mac address buffer to populate
287 *
288 * Return: status of operation
289 */
290static int hdd_get_random_nan_mac_addr(hdd_context_t *hdd_ctx,
291 struct qdf_mac_addr *mac_addr)
292{
293 hdd_adapter_t *adapter;
294 uint8_t i, attempts, max_attempt = 16;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700295
296 for (attempts = 0; attempts < max_attempt; attempts++) {
297 cds_rand_get_bytes(0, (uint8_t *)mac_addr, sizeof(*mac_addr));
Ravi Joshi04a1c992017-06-11 19:47:54 -0700298
299 /*
300 * Reset multicast bit (bit-0) and set locally-administered bit
301 */
302 mac_addr->bytes[0] = 0x2;
303
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700304 /*
305 * to avoid potential conflict with FW's generated NMI mac addr,
306 * host sets LSB if 6th byte to 0
307 */
308 mac_addr->bytes[5] &= 0xFE;
309
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700310 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
311 if (!qdf_mem_cmp(hdd_ctx->config->intfMacAddr[i].bytes,
312 mac_addr, sizeof(*mac_addr)))
313 continue;
314 }
315
316 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
317 if (!adapter)
318 return 0;
319 }
320
321 hdd_err("unable to get non-pre-existing mac address in %d attempts",
322 max_attempt);
323
324 return -EINVAL;
325}
326
Naveen Rawat97500352017-03-22 10:07:58 -0700327#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700328/**
329 * hdd_ndi_create_req_handler() - NDI create request handler
330 * @hdd_ctx: hdd context
331 * @tb: parsed NL attribute list
332 *
333 * Return: 0 on success or error code on failure
334 */
335static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
336 struct nlattr **tb)
337{
338 hdd_adapter_t *adapter;
339 char *iface_name;
340 uint16_t transaction_id;
341 int ret;
342 struct nan_datapath_ctx *ndp_ctx;
343 uint8_t op_channel =
344 hdd_ctx->config->nan_datapath_ndi_channel;
345
346 ENTER();
347
348 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700349 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700350 return -EINVAL;
351 }
352 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
353
354 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700355 hdd_err("transaction id is unavailable");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700356 return -EINVAL;
357 }
358 transaction_id =
359 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
360
361 /* Check for an existing interface of NDI type */
362 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
363 if (adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700364 hdd_err("Cannot support more than one NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700365 return -EEXIST;
366 }
367
368 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
369 wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
370 true);
371 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700372 hdd_err("hdd_open_adapter failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700373 return -ENOMEM;
374 }
375
376 /*
377 * Create transaction id is required to be saved since the firmware
378 * does not honor the transaction id for create request
379 */
380 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
381 ndp_ctx->ndp_create_transaction_id = transaction_id;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700382 ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700383
384 /*
385 * The NAN data interface has been created at this point.
386 * Unlike traditional device modes, where the higher application
387 * layer initiates connect / join / start, the NAN data interface
388 * does not have any such formal requests. The NDI create request
389 * is responsible for starting the BSS as well.
390 */
391 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
392 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
393 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
394 /* start NDI on the default 2.4 GHz social channel */
395 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
396 }
397 ret = hdd_ndi_start_bss(adapter, op_channel);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700398 if (0 > ret) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700399 hdd_err("NDI start bss failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700400 /* Start BSS failed, delete the interface */
401 hdd_close_ndi(adapter);
402 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700403
404 EXIT();
405 return ret;
406}
407
408/**
409 * hdd_ndi_delete_req_handler() - NDI delete request handler
410 * @hdd_ctx: hdd context
411 * @tb: parsed NL attribute list
412 *
413 * Return: 0 on success or error code on failure
414 */
415static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
416 struct nlattr **tb)
417{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700418 hdd_adapter_t *adapter;
419 char *iface_name;
420 uint16_t transaction_id;
421 struct nan_datapath_ctx *ndp_ctx;
422 int ret;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700423 hdd_station_ctx_t *sta_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700424
425 ENTER();
426
427 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700428 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700429 return -EINVAL;
430 }
431
432 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
433
434 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700435 hdd_err("Transaction id is unavailable");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700436 return -EINVAL;
437 }
438
439 transaction_id =
440 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
441
442 /* Check if there is already an existing inteface with the same name */
443 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
444 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700445 hdd_err("NAN data interface %s is not available", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700446 return -EINVAL;
447 }
448
449 /* check if adapter is in NDI mode */
450 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700451 hdd_err("Interface %s is not in NDI mode", iface_name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700452 return -EINVAL;
453 }
454
455 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
456 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700457 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700458 return -EINVAL;
459 }
460
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700461 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
462 if (!sta_ctx) {
463 hdd_err("sta_ctx is NULL");
464 return -EINVAL;
465 }
466
Naveen Rawatf28315c2016-06-29 18:06:02 -0700467 /* check if there are active peers on the adapter */
468 if (ndp_ctx->active_ndp_peers > 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700469 hdd_err("NDP peers active: %d, cannot delete NDI",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700470 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700471 return -EINVAL;
472 }
473
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700474 /*
475 * Since, the interface is being deleted, remove the
476 * broadcast id.
477 */
478 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
479 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
480
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700481 ndp_ctx->ndp_delete_transaction_id = transaction_id;
482 ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
483
484 /* Delete the interface */
485 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
486 if (ret < 0)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700487 hdd_err("NDI delete request failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700488 else
Naveen Rawatba4f6612016-07-05 12:03:16 -0700489 hdd_err("NDI delete request successfully issued");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700490
491 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700492}
493
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700494/**
495 * hdd_ndp_initiator_req_handler() - NDP initiator request handler
496 * @hdd_ctx: hdd context
497 * @tb: parsed NL attribute list
498 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800499 * tb will contain following vendor attributes:
500 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
501 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
502 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
Ravi Joshi71e82f32017-02-09 23:15:16 -0800503 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG - optional
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800504 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
505 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
506 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
507 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
508 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
509 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
510 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700511 * Return: 0 on success or error code on failure
512 */
513static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx,
514 struct nlattr **tb)
515{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700516 hdd_adapter_t *adapter;
517 char *iface_name;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700518 struct ndp_initiator_req req = {0};
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700519 QDF_STATUS status;
520 uint32_t ndp_qos_cfg;
521 tHalHandle hal = hdd_ctx->hHal;
522 struct nan_datapath_ctx *ndp_ctx;
523
524 ENTER();
525
526 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700527 hdd_err("Interface name string is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700528 return -EINVAL;
529 }
530
531 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
532 /* Check for interface in NDI mode */
533 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
534 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700535 hdd_err("NAN data interface %s not available", iface_name);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700536 return -EINVAL;
537 }
538
539 /* NAN data path coexists only with STA interface */
540 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700541 hdd_err("Unsupported concurrency for NAN datapath");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700542 return -EPERM;
543 }
544
545 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
546
547 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
548 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
549 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700550 hdd_err("Data request not allowed in NDI current state: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700551 ndp_ctx->state);
552 return -EINVAL;
553 }
554
555 req.vdev_id = adapter->sessionId;
556
557 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700558 hdd_err("Transaction ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700559 return -EINVAL;
560 }
561 req.transaction_id =
562 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
563
Naveen Rawat0a017052016-10-19 14:17:07 -0700564 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL])
565 req.channel =
566 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
567
Ravi Joshi71e82f32017-02-09 23:15:16 -0800568 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG])
Naveen Rawat0a017052016-10-19 14:17:07 -0700569 req.channel_cfg =
570 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700571
572 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700573 hdd_err("NDP service instance ID is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700574 return -EINVAL;
575 }
576 req.service_instance_id =
Naveen Rawat19da3d12016-08-16 12:39:38 -0700577 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700578
579 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
580 adapter->macAddressCurrent.bytes, QDF_MAC_ADDR_SIZE);
581
582 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700583 hdd_err("NDI peer discovery mac addr is unavailable");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700584 return -EINVAL;
585 }
586 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
587 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
588 QDF_MAC_ADDR_SIZE);
589
Naveen Rawat90ae3082016-06-29 18:22:59 -0700590 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
591 req.ndp_info.ndp_app_info_len =
592 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
593 req.ndp_info.ndp_app_info =
594 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700595 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700596
597 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
598 /* at present ndp config stores 4 bytes QOS info only */
599 req.ndp_config.ndp_cfg_len = 4;
600 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
601 ndp_qos_cfg =
602 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
603 }
604
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800605 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
606 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
607 hdd_err("PMK cannot be absent when CSID is present.");
608 return -EINVAL;
609 }
610
611 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
612 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
613 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
614 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
615 QDF_TRACE_LEVEL_DEBUG,
616 req.pmk.pmk, req.pmk.pmk_len);
617 }
618
619 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
620 req.ncs_sk_type =
621 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
622
623 }
624
Ravi Joshi71e82f32017-02-09 23:15:16 -0800625 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",
626 req.vdev_id, req.transaction_id, req.channel, req.channel_cfg,
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700627 req.service_instance_id, req.ndp_info.ndp_app_info_len,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800628 req.ncs_sk_type, req.peer_discovery_mac_addr.bytes);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700629 status = sme_ndp_initiator_req_handler(hal, &req);
630 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700631 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700632 status);
633 return -ECOMM;
634 }
635 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700636 return 0;
637}
638
639/**
640 * hdd_ndp_responder_req_handler() - NDP responder request handler
641 * @hdd_ctx: hdd context
642 * @tb: parsed NL attribute list
643 *
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800644 * tb includes following vendor attributes:
645 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
646 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
647 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
648 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
649 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
650 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
651 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
652 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
653 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700654 * Return: 0 on success or error code on failure
655 */
656static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx,
657 struct nlattr **tb)
658{
Abhishek Singh4fef7472016-06-06 11:36:03 -0700659 hdd_adapter_t *adapter;
660 char *iface_name;
661 struct ndp_responder_req req = {0};
662 QDF_STATUS status;
663 int ret = 0;
664 struct nan_datapath_ctx *ndp_ctx;
665 uint32_t ndp_qos_cfg;
666
667 ENTER();
668
669 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700670 hdd_err("Interface name string is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700671 return -EINVAL;
672 }
673
674 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
675 /* Check if there is already an existing NAN interface */
676 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
677 if (!adapter) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700678 hdd_err("NAN data interface %s not available", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700679 return -EINVAL;
680 }
681
682 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700683 hdd_err("Interface %s not in NDI mode", iface_name);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700684 return -EINVAL;
685 }
686
687 /* NAN data path coexists only with STA interface */
688 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700689 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700690 return -EINVAL;
691 }
692
693 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
694
695 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
696 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
697 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700698 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700699 ndp_ctx->state);
700 return -EAGAIN;
701 }
702
703 req.vdev_id = adapter->sessionId;
704
705 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700706 hdd_err("Transaction ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700707 return -EINVAL;
708 }
709 req.transaction_id =
710 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
711
712 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700713 hdd_err("Instance ID is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700714 return -EINVAL;
715 }
716 req.ndp_instance_id =
717 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
718
719 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700720 hdd_err("ndp_rsp is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700721 return -EINVAL;
722 }
723 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
724
725 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
726 req.ndp_info.ndp_app_info_len =
727 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
728 if (req.ndp_info.ndp_app_info_len) {
729 req.ndp_info.ndp_app_info =
730 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
731 }
732 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700733 hdd_info("NDP app info is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700734 }
735 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
736 /* at present ndp config stores 4 bytes QOS info only */
737 req.ndp_config.ndp_cfg_len = 4;
738 ndp_qos_cfg =
739 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
740 req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
741 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700742 hdd_info("NDP config data is unavailable");
Abhishek Singh4fef7472016-06-06 11:36:03 -0700743 }
744
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800745 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] &&
746 !tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
747 hdd_err("PMK cannot be absent when CSID is present.");
748 return -EINVAL;
749 }
750
751 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
752 req.pmk.pmk = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
753 req.pmk.pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
754 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
755 QDF_TRACE_LEVEL_DEBUG,
756 req.pmk.pmk, req.pmk.pmk_len);
757 }
758
759 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
760 req.ncs_sk_type =
761 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
762
763 }
764
765 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 -0700766 req.vdev_id, req.transaction_id, req.ndp_rsp,
Naveen Rawat4f3983e2016-11-29 16:12:09 -0800767 req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
768 req.ncs_sk_type);
Abhishek Singh4fef7472016-06-06 11:36:03 -0700769
770 status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req);
771 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700772 hdd_err("sme_ndp_initiator_req_handler failed, status: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -0700773 status);
774 ret = -EINVAL;
775 }
776
777 EXIT();
778 return ret;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700779}
780
781/**
782 * hdd_ndp_end_req_handler() - NDP end request handler
783 * @hdd_ctx: hdd context
784 * @tb: parsed NL attribute list
785 *
786 * Return: 0 on success or error code on failure
787 */
Naveen Rawatf28315c2016-06-29 18:06:02 -0700788static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700789{
Naveen Rawatf28315c2016-06-29 18:06:02 -0700790 struct ndp_end_req req = {0};
791 QDF_STATUS status;
792 tHalHandle hal = hdd_ctx->hHal;
793
794 ENTER();
795
796 /* NAN data path coexists only with STA interface */
797 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700798 hdd_err("Unsupported concurrency for NAN datapath");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700799 return -EINVAL;
800 }
801
802 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700803 hdd_err("Transaction ID is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700804 return -EINVAL;
805 }
806 req.transaction_id =
807 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
808
809 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700810 hdd_err("NDP instance ID array is unavailable");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700811 return -EINVAL;
812 }
813
814 req.num_ndp_instances =
815 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
816 sizeof(uint32_t);
817 if (0 >= req.num_ndp_instances) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700818 hdd_err("Num NDP instances is 0");
Naveen Rawatf28315c2016-06-29 18:06:02 -0700819 return -EINVAL;
820 }
821 req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
822
Naveen Rawatba4f6612016-07-05 12:03:16 -0700823 hdd_info("sending ndp_end_req to SME, transaction_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700824 req.transaction_id);
825
826 status = sme_ndp_end_req_handler(hal, &req);
827 if (status != QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700828 hdd_err("sme_ndp_end_req_handler failed, status: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -0700829 status);
830 return -ECOMM;
831 }
832 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700833 return 0;
834}
835
836/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700837 * hdd_ndp_iface_create_rsp_handler() - NDP iface create response handler
838 * @adapter: pointer to adapter context
839 * @rsp_params: response parameters
840 *
841 * The function is expected to send a response back to the user space
842 * even if the creation of BSS has failed
843 *
844 * Following vendor event is sent to cfg80211:
845 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
846 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
847 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800848 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700849 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
850 *
851 * Return: none
852 */
853static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
854 void *rsp_params)
855{
856 struct sk_buff *vendor_event;
857 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
858 struct ndi_create_rsp *ndi_rsp = (struct ndi_create_rsp *)rsp_params;
859 uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
860 NLMSG_HDRLEN + (4 * NLA_HDRLEN);
861 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700862 bool create_fail = false;
863 uint8_t create_transaction_id = 0;
Naveen Rawate21103f2016-07-08 14:18:00 -0700864 uint32_t create_status = NDP_RSP_STATUS_ERROR;
865 uint32_t create_reason = NDP_NAN_DATA_IFACE_CREATE_FAILED;
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700866 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
867 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
868 tCsrRoamInfo roam_info = {0};
869 tSirBssDescription tmp_bss_descp = {0};
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700870
871 ENTER();
872
873 if (wlan_hdd_validate_context(hdd_ctx))
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700874 /* No way the driver can send response back to user space */
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700875 return;
876
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700877 if (ndi_rsp) {
878 create_status = ndi_rsp->status;
Naveen Rawate21103f2016-07-08 14:18:00 -0700879 create_reason = ndi_rsp->reason;
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700880 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700881 hdd_err("Invalid ndi create response");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700882 create_fail = true;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700883 }
884
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700885 if (ndp_ctx) {
886 create_transaction_id = ndp_ctx->ndp_create_transaction_id;
887 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700888 hdd_err("ndp_ctx is NULL");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700889 create_fail = true;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700890 }
891
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700892 if (!sta_ctx) {
893 hdd_err("sta_ctx is NULL");
894 create_fail = true;
895 }
896
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700897 /* notify response to the upper layer */
898 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
899 NULL,
900 data_len,
901 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
902 cds_get_gfp_flags());
903
904 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700905 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700906 create_fail = true;
907 goto close_ndi;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700908 }
909
910 /* Sub vendor command */
911 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
912 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700913 hdd_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700914 goto nla_put_failure;
915 }
916
917 /* Transaction id */
918 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700919 create_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700920 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700921 goto nla_put_failure;
922 }
923
924 /* Status code */
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800925 if (nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700927 create_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700928 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700929 goto nla_put_failure;
930 }
931
932 /* Status return value */
933 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -0700934 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawate21103f2016-07-08 14:18:00 -0700935 create_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700936 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700937 goto nla_put_failure;
938 }
939
Naveen Rawatba4f6612016-07-05 12:03:16 -0700940 hdd_info("sub command: %d, value: %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700941 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
942 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700943 hdd_info("create transaction id: %d, value: %d",
944 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
945 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -0800946 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
947 create_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -0700948 hdd_info("Return value: %d, value: %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700949 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700950
951 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
952
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700953 if (!create_fail && ndi_rsp->status == QDF_STATUS_SUCCESS) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700954 hdd_err("NDI interface successfully created");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700955 ndp_ctx->ndp_create_transaction_id = 0;
956 ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -0700957 wlan_hdd_netif_queue_control(adapter,
958 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
959 WLAN_CONTROL_PATH);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700960 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700961 hdd_err("NDI interface creation failed with reason %d",
Naveen Rawate21103f2016-07-08 14:18:00 -0700962 create_reason);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700963 }
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700964
965 /* Something went wrong while starting the BSS */
966 if (create_fail)
967 goto close_ndi;
968
Rakesh Sunkicf1c9ab2016-08-25 14:11:25 -0700969 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
970 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
971 hdd_roam_register_sta(adapter, &roam_info,
972 sta_ctx->broadcast_staid,
973 &bc_mac_addr, &tmp_bss_descp);
974 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
975
976
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700977 EXIT();
978 return;
979
980nla_put_failure:
981 kfree_skb(vendor_event);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700982close_ndi:
983 hdd_close_ndi(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700984 return;
985}
986
987/**
988 * hdd_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
989 * @adapter: pointer to adapter context
990 * @rsp_params: response parameters
991 *
992 * Return: none
993 */
994static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
995 void *rsp_params)
996{
Deepak Dhamdhere13983f22016-05-31 19:06:09 -0700997 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
998 struct ndi_delete_rsp *ndi_rsp = rsp_params;
Naveen Rawat8d63a592016-06-29 18:30:59 -0700999 struct nan_datapath_ctx *ndp_ctx;
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001000
1001 if (wlan_hdd_validate_context(hdd_ctx))
1002 return;
1003
1004 if (!ndi_rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001005 hdd_err("Invalid ndi delete response");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001006 return;
1007 }
1008
Naveen Rawat8d63a592016-06-29 18:30:59 -07001009 if (ndi_rsp->status == NDP_RSP_STATUS_SUCCESS)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001010 hdd_err("NDI BSS successfully stopped");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001011 else
Naveen Rawatba4f6612016-07-05 12:03:16 -07001012 hdd_err("NDI BSS stop failed with reason %d", ndi_rsp->reason);
Naveen Rawat8d63a592016-06-29 18:30:59 -07001013
1014 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1015 ndp_ctx->ndi_delete_rsp_reason = ndi_rsp->reason;
1016 ndp_ctx->ndi_delete_rsp_status = ndi_rsp->status;
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001017 wlan_hdd_netif_queue_control(adapter,
1018 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
1019 WLAN_CONTROL_PATH);
Naveen Rawat8d63a592016-06-29 18:30:59 -07001020
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001021 complete(&adapter->disconnect_comp_var);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001022}
1023
1024/**
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001025 * hdd_ndp_session_end_handler() - NDI session termination handler
1026 * @adapter: pointer to adapter context
1027 *
1028 * Following vendor event is sent to cfg80211:
1029 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1030 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
1031 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001032 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001033 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1034 *
1035 * Return: none
1036 */
1037void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
1038{
1039 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1040 struct sk_buff *vendor_event;
1041 struct nan_datapath_ctx *ndp_ctx;
1042 uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
1043 (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
1044
1045 ENTER();
1046
1047 if (wlan_hdd_validate_context(hdd_ctx))
1048 return;
1049
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001050 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1051 if (!ndp_ctx) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001052 hdd_err("ndp context is NULL");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001053 return;
1054 }
1055
1056 /*
1057 * The virtual adapters are stopped and closed even during
1058 * driver unload or stop, the service layer is not required
1059 * to be informed in that case (response is not expected)
1060 */
1061 if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001062 hdd_err("NDI interface %s deleted", adapter->dev->name);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001063 return;
1064 }
1065
1066 /* notify response to the upper layer */
1067 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1068 NULL,
1069 data_len,
1070 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1071 GFP_KERNEL);
1072
1073 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001074 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001075 return;
1076 }
1077
1078 /* Sub vendor command goes first */
1079 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1080 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001081 hdd_err("VENDOR_ATTR_NDP_SUBCMD put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001082 goto failure;
1083 }
1084
1085 /* Transaction id */
1086 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1087 ndp_ctx->ndp_delete_transaction_id)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001088 hdd_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001089 goto failure;
1090 }
1091
1092 /* Status code */
1093 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001094 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001095 ndp_ctx->ndi_delete_rsp_status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001096 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001097 goto failure;
1098 }
1099
1100 /* Status return value */
1101 if (nla_put_u32(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001102 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1103 ndp_ctx->ndi_delete_rsp_reason)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001104 hdd_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001105 goto failure;
1106 }
1107
Naveen Rawatba4f6612016-07-05 12:03:16 -07001108 hdd_info("sub command: %d, value: %d", QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001109 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001110 hdd_info("delete transaction id: %d, value: %d",
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001111 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1112 ndp_ctx->ndp_delete_transaction_id);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001113 hdd_info("status code: %d, value: %d",
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001114 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001115 ndp_ctx->ndi_delete_rsp_status);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001116 hdd_info("Return value: %d, value: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001117 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1118 ndp_ctx->ndi_delete_rsp_reason);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07001119
1120 ndp_ctx->ndp_delete_transaction_id = 0;
1121 ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
1122
1123 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1124
1125 EXIT();
1126 return;
1127
1128failure:
1129 kfree_skb(vendor_event);
1130}
1131
1132
1133/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001134 * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
1135 * @adapter: pointer to adapter context
1136 * @rsp_params: response parameters
1137 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001138 * Following vendor event is sent to cfg80211:
1139 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1140 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1141 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1142 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001143 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001144 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1145 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001146 * Return: none
1147 */
1148static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter,
1149 void *rsp_params)
1150{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001151 struct sk_buff *vendor_event;
1152 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1153 struct ndp_initiator_rsp *rsp = rsp_params;
1154 uint32_t data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
1155 NLMSG_HDRLEN + (5 * NLA_HDRLEN);
1156
1157 ENTER();
1158
1159 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001160 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001161 return;
1162 }
1163
1164 if (0 != wlan_hdd_validate_context(hdd_ctx))
1165 return;
1166
1167 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1168 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1169 GFP_KERNEL);
1170 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001171 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001172 return;
1173 }
1174
1175 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1176 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1177 goto ndp_initiator_rsp_nla_failed;
1178
1179 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1180 rsp->transaction_id))
1181 goto ndp_initiator_rsp_nla_failed;
1182
1183 if (nla_put_u32(vendor_event,
1184 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1185 rsp->ndp_instance_id))
1186 goto ndp_initiator_rsp_nla_failed;
1187
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001188 if (nla_put_u32(vendor_event,
1189 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001190 rsp->status))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001191 goto ndp_initiator_rsp_nla_failed;
1192
1193 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001194 rsp->reason))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001195 goto ndp_initiator_rsp_nla_failed;
1196
Naveen Rawatba4f6612016-07-05 12:03:16 -07001197 hdd_info("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
Naveen Rawat8d63a592016-06-29 18:30:59 -07001198 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1199 rsp->reason);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001200 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1201 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001202 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001203ndp_initiator_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001204 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001205 kfree_skb(vendor_event);
1206 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001207}
1208
1209/**
1210 * hdd_ndp_new_peer_ind_handler() - NDP new peer indication handler
1211 * @adapter: pointer to adapter context
1212 * @ind_params: indication parameters
1213 *
1214 * Return: none
1215 */
1216static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
1217 void *ind_params)
1218{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001219 struct sme_ndp_peer_ind *new_peer_ind = ind_params;
1220 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1221 tSirBssDescription tmp_bss_descp = {0};
1222 tCsrRoamInfo roam_info = {0};
1223 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1224 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1225
1226 ENTER();
1227
1228 if (NULL == ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001229 hdd_err("Invalid new NDP peer params");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001230 return;
1231 }
Naveen Rawatba4f6612016-07-05 12:03:16 -07001232 hdd_info("session_id: %d, peer_mac: %pM, sta_id: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001233 new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
1234 new_peer_ind->sta_id);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001235
1236 /* save peer in ndp ctx */
1237 if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
1238 &new_peer_ind->peer_mac_addr)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001239 hdd_err("Ndp peer table full. cannot save new peer");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001240 return;
1241 }
1242
1243 /* this function is called for each new peer */
1244 ndp_ctx->active_ndp_peers++;
Naveen Rawatba4f6612016-07-05 12:03:16 -07001245 hdd_info("vdev_id: %d, num_peers: %d", adapter->sessionId,
1246 ndp_ctx->active_ndp_peers);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001247
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001248 hdd_roam_register_sta(adapter, &roam_info, new_peer_ind->sta_id,
1249 &new_peer_ind->peer_mac_addr, &tmp_bss_descp);
1250 hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
1251 /* perform following steps for first new peer ind */
1252 if (ndp_ctx->active_ndp_peers == 1) {
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07001253 hdd_conn_set_connection_state(adapter,
1254 eConnectionState_NdiConnected);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001255 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001256 wlan_hdd_netif_queue_control(adapter,
1257 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001258 }
1259 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001260}
1261
1262/**
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001263 * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001264 * @adapter: pointer to adapter context
1265 * @ind_params: indication parameters
1266 *
1267 * Return: none
1268 */
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001269static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter,
1270 void *ind_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001271{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001272 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1273 struct sme_ndp_peer_ind *peer_ind = ind_params;
1274 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1275 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1276
1277 hdd_roam_deregister_sta(adapter, peer_ind->sta_id);
1278 hdd_delete_peer(sta_ctx, peer_ind->sta_id);
1279 hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
1280
1281 if (--ndp_ctx->active_ndp_peers == 0) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001282 hdd_info("No more ndp peers.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001283 hdd_conn_set_connection_state(adapter,
1284 eConnectionState_NdiDisconnected);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001285 hdd_info("Stop netif tx queues.");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001286 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
1287 WLAN_CONTROL_PATH);
1288 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001289}
1290
1291/**
1292 * hdd_ndp_confirm_ind_handler() - NDP confirm indication handler
1293 * @adapter: pointer to adapter context
1294 * @ind_params: indication parameters
1295 *
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001296 * Following vendor event is sent to cfg80211:
1297 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1298 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1299 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1300 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1301 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1302 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1303 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1304 * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
1305 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001306 * Return: none
1307 */
1308static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
1309 void *ind_params)
1310{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001311 int idx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001312 uint32_t ndp_qos_config = 0;
1313 struct ndp_confirm_event *ndp_confirm = ind_params;
1314 struct sk_buff *vendor_event;
1315 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1316 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
Naveen Rawatf28315c2016-06-29 18:06:02 -07001317 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001318 uint32_t data_len;
1319
1320 ENTER();
1321 if (!ndp_confirm) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001322 hdd_err("Invalid NDP Initator response");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001323 return;
1324 }
1325
1326 if (0 != wlan_hdd_validate_context(hdd_ctx))
1327 return;
1328
Naveen Rawatf28315c2016-06-29 18:06:02 -07001329 /* ndp_confirm is called each time user generated ndp req succeeds */
1330 idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
1331 if (idx == INVALID_PEER_IDX)
Naveen Rawatba4f6612016-07-05 12:03:16 -07001332 hdd_err("can't find addr: %pM in vdev_id: %d, peer table.",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001333 &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId);
Naveen Rawat460be782016-06-29 18:26:22 -07001334 else if (ndp_confirm->rsp_code == NDP_RESPONSE_ACCEPT)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001335 ndp_ctx->active_ndp_sessions[idx]++;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001336
1337 data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
Naveen Rawat90ae3082016-06-29 18:22:59 -07001338 + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001339 ndp_confirm->ndp_info.ndp_app_info_len;
1340
Naveen Rawat8d63a592016-06-29 18:30:59 -07001341 if (ndp_confirm->ndp_info.ndp_app_info_len)
1342 data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
1343
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001344 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1345 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1346 GFP_KERNEL);
1347 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001348 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001349 return;
1350 }
1351
1352 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1353 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1354 goto ndp_confirm_nla_failed;
1355
1356 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1357 ndp_confirm->ndp_instance_id))
1358 goto ndp_confirm_nla_failed;
1359
1360 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1361 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1362 goto ndp_confirm_nla_failed;
1363
1364 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1365 IFNAMSIZ, adapter->dev->name))
1366 goto ndp_confirm_nla_failed;
1367
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001368 if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
Naveen Rawat8d63a592016-06-29 18:30:59 -07001369 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1370 ndp_confirm->ndp_info.ndp_app_info_len,
1371 ndp_confirm->ndp_info.ndp_app_info))
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001372 goto ndp_confirm_nla_failed;
1373
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001374 if (nla_put_u32(vendor_event,
1375 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1376 ndp_confirm->rsp_code))
1377 goto ndp_confirm_nla_failed;
1378
Naveen Rawat8d63a592016-06-29 18:30:59 -07001379 if (nla_put_u32(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1381 ndp_confirm->reason_code))
1382 goto ndp_confirm_nla_failed;
1383
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001384 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001385 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 -07001386 ndp_confirm->ndp_instance_id,
1387 ndp_confirm->peer_ndi_mac_addr.bytes,
Naveen Rawat460be782016-06-29 18:26:22 -07001388 ndp_qos_config, ndp_confirm->rsp_code,
1389 ndp_confirm->reason_code);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001390
Naveen Rawatba4f6612016-07-05 12:03:16 -07001391 hdd_info("NDP confim, ndp app info dump");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001392 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1393 ndp_confirm->ndp_info.ndp_app_info,
1394 ndp_confirm->ndp_info.ndp_app_info_len);
1395 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001396 return;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001397ndp_confirm_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001398 hdd_err("nla_put api failed");
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001399 kfree_skb(vendor_event);
1400 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001401}
1402
1403/**
1404 * hdd_ndp_indication_handler() - NDP indication handler
1405 * @adapter: pointer to adapter context
1406 * @ind_params: indication parameters
1407 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001408 * Following vendor event is sent to cfg80211:
1409 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1410 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1411 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
Naveen Rawat19da3d12016-08-16 12:39:38 -07001412 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001413 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1414 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1415 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1416 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1417 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001418 * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes)
1419 * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001420 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001421 * Return: none
1422 */
1423static void hdd_ndp_indication_handler(hdd_adapter_t *adapter,
1424 void *ind_params)
1425{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001426 struct sk_buff *vendor_event;
1427 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1428 struct ndp_indication_event *event = ind_params;
1429 uint32_t ndp_qos_config;
1430 struct nan_datapath_ctx *ndp_ctx;
1431 uint16_t data_len;
1432
1433 ENTER();
1434 if (!ind_params) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001435 hdd_err("Invalid NDP Indication");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001436 return;
1437 }
1438
1439 if (0 != wlan_hdd_validate_context(hdd_ctx))
1440 return;
1441
1442 /* Handle only if adapter is in NDI mode */
1443 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001444 hdd_err("Adapter is not in NDI mode");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001445 return;
1446 }
1447
Naveen Rawatba4f6612016-07-05 12:03:16 -07001448 hdd_info("NDP Indication, policy: %d", event->policy);
Abhishek Singh4fef7472016-06-06 11:36:03 -07001449
1450 /* Policy check */
1451 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001452 hdd_err("NAN datapath is not suported");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001453 return;
1454 }
1455
1456 /* NAN data path coexists only with STA interface */
1457 if (!hdd_is_ndp_allowed(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001458 hdd_err("Unsupported concurrency for NAN datapath");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001459 return;
1460 }
1461
1462 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1463
1464 /* check if we are in middle of deleting/creating the interface */
1465 if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE ||
1466 ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE ||
1467 ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001468 hdd_err("Data request not allowed in current NDI state: %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001469 ndp_ctx->state);
1470 return;
1471 }
1472
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001473 data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
1474 event->ndp_info.ndp_app_info_len + event->scid.scid_len +
1475 (10 * NLA_HDRLEN) + NLMSG_HDRLEN;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001476
1477 /* notify response to the upper layer */
1478 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1479 NULL, data_len,
1480 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1481 GFP_KERNEL);
1482 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001483 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001484 return;
1485 }
1486
1487 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1488 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1489 goto ndp_indication_nla_failed;
1490
1491 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1492 IFNAMSIZ, adapter->dev->name))
1493 goto ndp_indication_nla_failed;
1494
Naveen Rawat19da3d12016-08-16 12:39:38 -07001495 if (nla_put_u32(vendor_event,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001496 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1497 event->service_instance_id))
1498 goto ndp_indication_nla_failed;
1499
1500 if (nla_put(vendor_event,
1501 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1502 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1503 goto ndp_indication_nla_failed;
1504
1505 if (nla_put(vendor_event,
Jeff Johnson03294f12016-12-09 17:10:24 -08001506 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001507 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1508 goto ndp_indication_nla_failed;
1509
1510 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1511 event->ndp_instance_id))
1512 goto ndp_indication_nla_failed;
1513
1514 if (event->ndp_info.ndp_app_info_len)
1515 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1516 event->ndp_info.ndp_app_info_len,
1517 event->ndp_info.ndp_app_info))
1518 goto ndp_indication_nla_failed;
1519
1520 if (event->ndp_config.ndp_cfg_len) {
1521 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1522 /* at present ndp config stores 4 bytes QOS info only */
1523 if (nla_put_u32(vendor_event,
1524 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1525 ndp_qos_config))
1526 goto ndp_indication_nla_failed;
1527 }
1528
Naveen Rawat4f3983e2016-11-29 16:12:09 -08001529 if (event->scid.scid_len) {
1530 if (nla_put_u32(vendor_event,
1531 QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE,
1532 event->ncs_sk_type))
1533 goto ndp_indication_nla_failed;
1534
1535 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
1536 event->scid.scid_len,
1537 event->scid.scid))
1538 goto ndp_indication_nla_failed;
1539
1540 hdd_info("csid: %d, scid_len: %d",
1541 event->ncs_sk_type, event->scid.scid_len);
1542
1543 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1544 event->scid.scid, event->scid.scid_len);
1545 }
1546
Abhishek Singh4fef7472016-06-06 11:36:03 -07001547 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1548 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001549 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001550ndp_indication_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001551 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001552 kfree_skb(vendor_event);
1553 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001554}
1555
1556/**
1557 * hdd_ndp_responder_rsp_handler() - NDP responder response handler
1558 * @adapter: pointer to adapter context
1559 * @rsp_params: response parameters
1560 *
Abhishek Singh4fef7472016-06-06 11:36:03 -07001561 * Following vendor event is sent to cfg80211:
1562 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1563 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1564 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001565 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1566 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
Abhishek Singh4fef7472016-06-06 11:36:03 -07001567 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001568 * Return: none
1569 */
1570static void hdd_ndp_responder_rsp_handler(hdd_adapter_t *adapter,
1571 void *rsp_params)
1572{
Abhishek Singh4fef7472016-06-06 11:36:03 -07001573 struct sk_buff *vendor_event;
1574 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1575 struct ndp_responder_rsp_event *rsp = rsp_params;
1576 uint16_t data_len;
1577
1578 ENTER();
1579 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001580 hdd_err("Invalid NDP Responder response");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001581 return;
1582 }
1583
1584 if (0 != wlan_hdd_validate_context(hdd_ctx))
1585 return;
1586
Naveen Rawatba4f6612016-07-05 12:03:16 -07001587 hdd_info("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
Abhishek Singh4fef7472016-06-06 11:36:03 -07001588 rsp->vdev_id, rsp->transaction_id,
1589 rsp->status, rsp->reason);
1590
1591 data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
1592 4 * NLA_HDRLEN + NLMSG_HDRLEN;
1593 /* notify response to the upper layer */
1594 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1595 NULL, data_len,
1596 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1597 GFP_KERNEL);
1598 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001599 hdd_err("cfg80211_vendor_event_alloc failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001600 return;
1601 }
1602
1603 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1604 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1605 goto ndp_responder_rsp_nla_failed;
1606
1607 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1608 rsp->transaction_id))
1609 goto ndp_responder_rsp_nla_failed;
1610
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001611 if (nla_put_u32(vendor_event,
1612 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001613 rsp->status))
1614 goto ndp_responder_rsp_nla_failed;
1615
1616 if (nla_put_u32(vendor_event,
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001617 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
Abhishek Singh4fef7472016-06-06 11:36:03 -07001618 rsp->reason))
1619 goto ndp_responder_rsp_nla_failed;
1620
1621 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1622 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001623 return;
Abhishek Singh4fef7472016-06-06 11:36:03 -07001624ndp_responder_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001625 hdd_err("nla_put api failed");
Abhishek Singh4fef7472016-06-06 11:36:03 -07001626 kfree_skb(vendor_event);
1627 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001628}
1629
1630/**
1631 * hdd_ndp_end_rsp_handler() - NDP end response handler
1632 * @adapter: pointer to adapter context
1633 * @rsp_params: response parameters
1634 *
Naveen Rawatf28315c2016-06-29 18:06:02 -07001635 * Following vendor event is sent to cfg80211:
1636 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1637 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001638 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
Naveen Rawatf28315c2016-06-29 18:06:02 -07001639 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1640 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1641 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001642 * Return: none
1643 */
Naveen Rawatf28315c2016-06-29 18:06:02 -07001644static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, void *rsp_params)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001645{
Naveen Rawatf28315c2016-06-29 18:06:02 -07001646 struct sk_buff *vendor_event;
1647 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1648 struct ndp_end_rsp_event *rsp = rsp_params;
Rakesh Sunkiae936b62016-07-28 16:01:45 -07001649 uint32_t data_len;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001650
1651 ENTER();
1652
1653 if (!rsp) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001654 hdd_err("Invalid ndp end response");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001655 return;
1656 }
1657
1658 if (0 != wlan_hdd_validate_context(hdd_ctx))
1659 return;
1660
Naveen Rawatf28315c2016-06-29 18:06:02 -07001661 data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
1662 sizeof(uint16_t);
1663
1664 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1665 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1666 GFP_KERNEL);
1667 if (!vendor_event) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001668 hdd_err("cfg80211_vendor_event_alloc failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001669 return;
1670 }
1671
1672 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1673 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1674 goto ndp_end_rsp_nla_failed;
1675
Rakesh Sunkid92d1082017-01-04 15:14:28 -08001676 if (nla_put_u32(vendor_event,
1677 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001678 rsp->status))
1679 goto ndp_end_rsp_nla_failed;
1680
1681 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1682 rsp->reason))
1683 goto ndp_end_rsp_nla_failed;
1684
1685 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1686 rsp->transaction_id))
1687 goto ndp_end_rsp_nla_failed;
1688
Naveen Rawatba4f6612016-07-05 12:03:16 -07001689 hdd_info("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
Naveen Rawatf28315c2016-06-29 18:06:02 -07001690 rsp->transaction_id, rsp->status, rsp->reason);
1691 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1692 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001693 return;
Naveen Rawatf28315c2016-06-29 18:06:02 -07001694
1695ndp_end_rsp_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001696 hdd_err("nla_put api failed");
Naveen Rawatf28315c2016-06-29 18:06:02 -07001697 kfree_skb(vendor_event);
1698 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001699}
1700
1701/**
1702 * hdd_ndp_end_ind_handler() - NDP end indication handler
1703 * @adapter: pointer to adapter context
1704 * @ind_params: indication parameters
1705 *
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001706 * Following vendor event is sent to cfg80211:
1707 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1708 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001709 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1710 *
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001711 * Return: none
1712 */
1713static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
1714 void *ind_params)
1715{
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001716 struct sk_buff *vendor_event;
1717 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1718 struct ndp_end_indication_event *end_ind = ind_params;
1719 uint32_t data_len, i;
1720 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
1721 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1722 uint32_t *ndp_instance_array;
Naveen Rawate21103f2016-07-08 14:18:00 -07001723 hdd_adapter_t *ndi_adapter;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001724
1725 ENTER();
1726
1727 if (!end_ind) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001728 hdd_err("Invalid ndp end indication");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001729 return;
1730 }
1731
1732 if (0 != wlan_hdd_validate_context(hdd_ctx))
1733 return;
1734
1735 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1736 sizeof(*ndp_instance_array));
1737 if (!ndp_instance_array) {
1738 hdd_err("Failed to allocate ndp_instance_array");
1739 return;
1740 }
1741 for (i = 0; i < end_ind->num_ndp_ids; i++) {
1742 int idx;
1743
1744 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
Naveen Rawate21103f2016-07-08 14:18:00 -07001745 ndi_adapter = hdd_get_adapter_by_vdev(hdd_ctx,
1746 end_ind->ndp_map[i].vdev_id);
1747 if (ndi_adapter == NULL) {
1748 hdd_err("Adapter not found for vdev_id: %d",
1749 end_ind->ndp_map[i].vdev_id);
1750 continue;
1751 }
1752 ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(ndi_adapter);
Govind Singhb8475942016-08-12 11:07:09 +05301753 if (!ndp_ctx) {
1754 hdd_err("ndp_ctx is NULL for vdev id: %d",
1755 end_ind->ndp_map[i].vdev_id);
1756 continue;
1757 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001758 idx = hdd_get_peer_idx(sta_ctx,
1759 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1760 if (idx == INVALID_PEER_IDX) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001761 hdd_err("can't find addr: %pM in sta_ctx.",
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001762 &end_ind->ndp_map[i].peer_ndi_mac_addr);
1763 continue;
1764 }
1765 /* save the value of active sessions on each peer */
1766 ndp_ctx->active_ndp_sessions[idx] =
1767 end_ind->ndp_map[i].num_active_ndp_sessions;
1768 }
1769
Naveen Rawat90ae3082016-06-29 18:22:59 -07001770 data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001771 end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
1772
1773 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
1774 data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
1775 GFP_KERNEL);
1776 if (!vendor_event) {
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05301777 qdf_mem_free(ndp_instance_array);
Naveen Rawatba4f6612016-07-05 12:03:16 -07001778 hdd_err("cfg80211_vendor_event_alloc failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001779 return;
1780 }
1781
1782 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1783 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1784 goto ndp_end_ind_nla_failed;
1785
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001786 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1787 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1788 ndp_instance_array))
1789 goto ndp_end_ind_nla_failed;
1790
1791 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1792 qdf_mem_free(ndp_instance_array);
1793 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001794 return;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001795
1796ndp_end_ind_nla_failed:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001797 hdd_err("nla_put api failed");
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001798 kfree_skb(vendor_event);
1799 qdf_mem_free(ndp_instance_array);
1800 EXIT();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001801}
1802
1803/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001804 * hdd_ndp_event_handler() - ndp response and indication handler
1805 * @adapter: adapter context
1806 * @roam_info: pointer to roam_info structure
1807 * @roam_id: roam id as indicated by SME
1808 * @roam_status: roam status
1809 * @roam_result: roam result
1810 *
1811 * Return: none
1812 */
1813void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1814 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1815 eCsrRoamResult roam_result)
1816{
1817 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1818 switch (roam_result) {
Naveen Rawat8d63a592016-06-29 18:30:59 -07001819 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001820 hdd_ndp_iface_create_rsp_handler(adapter,
1821 &roam_info->ndp.ndi_create_params);
1822 break;
Naveen Rawat8d63a592016-06-29 18:30:59 -07001823 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001824 hdd_ndp_iface_delete_rsp_handler(adapter,
1825 &roam_info->ndp.ndi_delete_params);
1826 break;
1827 case eCSR_ROAM_RESULT_NDP_INITIATOR_RSP:
1828 hdd_ndp_initiator_rsp_handler(adapter,
1829 &roam_info->ndp.ndp_init_rsp_params);
1830 break;
1831 case eCSR_ROAM_RESULT_NDP_NEW_PEER_IND:
1832 hdd_ndp_new_peer_ind_handler(adapter,
1833 &roam_info->ndp.ndp_peer_ind_params);
1834 break;
1835 case eCSR_ROAM_RESULT_NDP_CONFIRM_IND:
1836 hdd_ndp_confirm_ind_handler(adapter,
1837 &roam_info->ndp.ndp_confirm_params);
1838 break;
1839 case eCSR_ROAM_RESULT_NDP_INDICATION:
1840 hdd_ndp_indication_handler(adapter,
1841 &roam_info->ndp.ndp_indication_params);
1842 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001843 case eCSR_ROAM_RESULT_NDP_RESPONDER_RSP:
1844 hdd_ndp_responder_rsp_handler(adapter,
1845 &roam_info->ndp.ndp_responder_rsp_params);
1846 break;
1847 case eCSR_ROAM_RESULT_NDP_END_RSP:
1848 hdd_ndp_end_rsp_handler(adapter,
Naveen Rawatf28315c2016-06-29 18:06:02 -07001849 roam_info->ndp.ndp_end_rsp_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001850 break;
1851 case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
1852 hdd_ndp_peer_departed_ind_handler(adapter,
1853 &roam_info->ndp.ndp_peer_ind_params);
1854 break;
1855 case eCSR_ROAM_RESULT_NDP_END_IND:
1856 hdd_ndp_end_ind_handler(adapter,
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07001857 roam_info->ndp.ndp_end_ind_params);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001858 break;
1859 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07001860 hdd_err("Unknown NDP response event from SME %d",
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001861 roam_result);
1862 break;
1863 }
1864 }
1865}
Naveen Rawat97500352017-03-22 10:07:58 -07001866#else
1867void hdd_ndp_event_handler(hdd_adapter_t *adapter,
1868 tCsrRoamInfo *roam_info, uint32_t roam_id, eRoamCmdStatus roam_status,
1869 eCsrRoamResult roam_result)
1870{
Naveen Rawatcb5c5402017-03-22 10:12:19 -07001871 bool success;
1872 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(adapter->hdd_vdev);
1873
1874 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
1875 switch (roam_result) {
1876 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
1877 success = (roam_info->ndp.ndi_create_params.status ==
1878 NAN_DATAPATH_RSP_STATUS_SUCCESS);
1879 hdd_debug("posting ndi create status: %d to umac",
1880 success);
1881 os_if_nan_post_ndi_create_rsp(psoc, adapter->sessionId,
1882 success);
1883 return;
1884 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
1885 success = (roam_info->ndp.ndi_create_params.status ==
1886 NAN_DATAPATH_RSP_STATUS_SUCCESS);
1887 hdd_debug("posting ndi delete status: %d to umac",
1888 success);
1889 os_if_nan_post_ndi_delete_rsp(psoc, adapter->sessionId,
1890 success);
1891 return;
1892 default:
1893 hdd_err("in correct roam_result: %d", roam_result);
1894 return;
1895 }
1896 } else {
1897 hdd_err("in correct roam_status: %d", roam_status);
1898 return;
1899 }
Naveen Rawat97500352017-03-22 10:07:58 -07001900}
1901#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001902
1903/**
1904 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
1905 * @wiphy: pointer to wireless wiphy structure.
1906 * @wdev: pointer to wireless_dev structure.
1907 * @data: Pointer to the data to be passed via vendor interface
1908 * @data_len:Length of the data to be passed
1909 *
1910 * This function is invoked to handle vendor command
1911 *
1912 * Return: 0 on success, negative errno on failure
1913 */
Naveen Rawat63de5422017-03-22 11:03:56 -07001914#ifdef WLAN_FEATURE_NAN_CONVERGENCE
1915static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1916 struct wireless_dev *wdev, const void *data, int data_len)
1917{
1918 int ret_val;
1919 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1920
1921 ENTER();
1922
1923 ret_val = wlan_hdd_validate_context(hdd_ctx);
1924 if (ret_val)
1925 return ret_val;
1926
1927 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1928 hdd_err("Command not allowed in FTM mode");
1929 return -EPERM;
1930 }
1931
1932 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
1933 hdd_err("NAN datapath is not enabled");
1934 return -EPERM;
1935 }
1936 /* NAN data path coexists only with STA interface */
1937 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
1938 hdd_err("Unsupported concurrency for NAN datapath");
1939 return -EPERM;
1940 }
1941
1942 /* NAN data path coexists only with STA interface */
1943 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
1944 hdd_err("Unsupported concurrency for NAN datapath");
1945 return -EPERM;
1946 }
1947
1948 return os_if_nan_process_ndp_cmd(hdd_ctx->hdd_psoc,
1949 data, data_len);
1950}
1951#else
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001952static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
1953 struct wireless_dev *wdev, const void *data, int data_len)
1954{
1955 uint32_t ndp_cmd_type;
1956 uint16_t transaction_id;
1957 int ret_val;
1958 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1959 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1960 char *iface_name;
1961
1962 ENTER();
1963
1964 ret_val = wlan_hdd_validate_context(hdd_ctx);
1965 if (ret_val)
1966 return ret_val;
1967
1968 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001969 hdd_err("Command not allowed in FTM mode");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001970 return -EPERM;
1971 }
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -07001972 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001973 hdd_err("NAN datapath is not enabled");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001974 return -EPERM;
1975 }
1976 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1977 data, data_len,
1978 qca_wlan_vendor_ndp_policy)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001979 hdd_err("Invalid NDP vendor command attributes");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001980 return -EINVAL;
1981 }
1982
1983 /* Parse and fetch NDP Command Type*/
1984 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001985 hdd_err("NAN datapath cmd type failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001986 return -EINVAL;
1987 }
1988 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1989
1990 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07001991 hdd_err("attr transaction id failed");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001992 return -EINVAL;
1993 }
1994 transaction_id = nla_get_u16(
1995 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1996
Naveen Rawatf28315c2016-06-29 18:06:02 -07001997 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
1998 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001999 hdd_debug("Transaction Id: %d NDP Cmd: %d iface_name: %s",
Naveen Rawatf28315c2016-06-29 18:06:02 -07002000 transaction_id, ndp_cmd_type, iface_name);
2001 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002002 hdd_debug("Transaction Id: %d NDP Cmd: %d iface_name: unspecified",
Naveen Rawatf28315c2016-06-29 18:06:02 -07002003 transaction_id, ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002004 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002005
2006 switch (ndp_cmd_type) {
2007 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
2008 ret_val = hdd_ndi_create_req_handler(hdd_ctx, tb);
2009 break;
2010 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
2011 ret_val = hdd_ndi_delete_req_handler(hdd_ctx, tb);
2012 break;
2013 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
2014 ret_val = hdd_ndp_initiator_req_handler(hdd_ctx, tb);
2015 break;
2016 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
2017 ret_val = hdd_ndp_responder_req_handler(hdd_ctx, tb);
2018 break;
2019 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
2020 ret_val = hdd_ndp_end_req_handler(hdd_ctx, tb);
2021 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002022 default:
Naveen Rawatba4f6612016-07-05 12:03:16 -07002023 hdd_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002024 ret_val = -EINVAL;
2025 break;
2026 }
2027
2028 return ret_val;
2029}
Naveen Rawat63de5422017-03-22 11:03:56 -07002030#endif
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002031
2032/**
2033 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
2034 * @wiphy: pointer to wireless wiphy structure.
2035 * @wdev: pointer to wireless_dev structure.
2036 * @data: Pointer to the data to be passed via vendor interface
2037 * @data_len:Length of the data to be passed
2038 *
2039 * This function is called to send a NAN request to
2040 * firmware. This is an SSR-protected wrapper function.
2041 *
2042 * Return: 0 on success, negative errno on failure
2043 */
2044int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
2045 struct wireless_dev *wdev, const void *data, int data_len)
2046{
2047 int ret;
2048
2049 cds_ssr_protect(__func__);
2050 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
2051 cds_ssr_unprotect(__func__);
2052
2053 return ret;
2054}
2055
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002056#ifndef WLAN_FEATURE_NAN_CONVERGENCE
Jeff Johnson85b5c112017-08-11 15:15:23 -07002057static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002058{
2059 struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
2060
2061 ndp_ctx->state = state;
2062 return 0;
2063}
2064#else
Jeff Johnson85b5c112017-08-11 15:15:23 -07002065static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002066{
2067 return os_if_nan_set_ndi_state(adapter->hdd_vdev, state);
2068}
2069#endif
2070
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002071/**
2072 * hdd_init_nan_data_mode() - initialize nan data mode
2073 * @adapter: adapter context
2074 *
2075 * Returns: 0 on success negative error code on error
2076 */
Jeff Johnson85b5c112017-08-11 15:15:23 -07002077int hdd_init_nan_data_mode(struct hdd_adapter *adapter)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002078{
2079 struct net_device *wlan_dev = adapter->dev;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002080 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2081 QDF_STATUS status;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002082 int32_t ret_val = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002083
Dustin Brownd28772b2017-03-17 14:16:07 -07002084 ret_val = hdd_vdev_create(adapter);
2085 if (ret_val) {
2086 hdd_err("failed to create vdev: %d", ret_val);
2087 return ret_val;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002088 }
2089
Ravi Joshi8eb65f92017-07-20 16:30:19 -07002090 /* Configure self HT/VHT capabilities */
2091 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
2092 sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
2093 sme_set_vdev_ies_per_band(hdd_ctx->hHal, adapter->sessionId);
2094
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002095 /* Register wireless extensions */
2096 ret_val = hdd_register_wext(wlan_dev);
2097 if (0 > ret_val) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002098 hdd_err("Wext registration failed with status code %d",
2099 ret_val);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002100 ret_val = -EAGAIN;
2101 goto error_register_wext;
2102 }
2103
2104 status = hdd_init_tx_rx(adapter);
2105 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002106 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002107 ret_val = -EAGAIN;
2108 goto error_init_txrx;
2109 }
2110
2111 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2112
2113 status = hdd_wmm_adapter_init(adapter);
2114 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -07002115 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002116 ret_val = -EAGAIN;
2117 goto error_wmm_init;
2118 }
2119
2120 set_bit(WMM_INIT_DONE, &adapter->event_flags);
2121
2122 ret_val = wma_cli_set_command((int)adapter->sessionId,
2123 (int)WMI_PDEV_PARAM_BURST_ENABLE,
2124 (int)hdd_ctx->config->enableSifsBurst,
2125 PDEV_CMD);
Arunk Khandavalli15664e42017-06-29 15:56:14 +05302126 if (0 != ret_val)
Naveen Rawatba4f6612016-07-05 12:03:16 -07002127 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Arunk Khandavalli15664e42017-06-29 15:56:14 +05302128
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002129
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002130 update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002131 return ret_val;
2132
2133error_wmm_init:
2134 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2135 hdd_deinit_tx_rx(adapter);
2136
2137error_init_txrx:
2138 hdd_unregister_wext(wlan_dev);
2139
2140error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07002141 QDF_BUG(!hdd_vdev_destroy(adapter));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002142
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07002143 return ret_val;
2144}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002145
2146#ifdef WLAN_FEATURE_NAN_CONVERGENCE
2147struct wlan_objmgr_vdev *hdd_ndi_open(char *iface_name)
2148{
2149 hdd_adapter_t *adapter;
Naveen Rawat5a6f8402017-07-03 16:00:11 -07002150 struct qdf_mac_addr ndi_mac_addr;
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002151 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2152
2153 ENTER();
Naveen Rawat5a6f8402017-07-03 16:00:11 -07002154
2155 if (hdd_get_random_nan_mac_addr(hdd_ctx, &ndi_mac_addr)) {
2156 hdd_err("get random mac address failed");
2157 return NULL;
2158 }
2159
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002160 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
Naveen Rawat5a6f8402017-07-03 16:00:11 -07002161 ndi_mac_addr.bytes, NET_NAME_UNKNOWN, true);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002162 if (!adapter) {
2163 hdd_err("hdd_open_adapter failed");
2164 return NULL;
2165 }
2166
2167 EXIT();
2168 return adapter->hdd_vdev;
2169}
2170
2171int hdd_ndi_start(uint8_t vdev_id)
2172{
2173 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2174 uint8_t op_channel = hdd_ctx->config->nan_datapath_ndi_channel;
2175 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2176
2177 ENTER();
2178 /*
2179 * The NAN data interface has been created at this point.
2180 * Unlike traditional device modes, where the higher application
2181 * layer initiates connect / join / start, the NAN data
2182 * interface does not have any such formal requests. The NDI
2183 * create request is responsible for starting the BSS as well.
2184 */
2185 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ ||
2186 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND ||
2187 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
2188 /* start NDI on the default 2.4 GHz social channel */
2189 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
2190 }
2191 if (hdd_ndi_start_bss(adapter, op_channel)) {
2192 hdd_err("NDI start bss failed");
2193 /* Start BSS failed, delete the interface */
2194 hdd_close_ndi(adapter);
2195 EXIT();
2196 return -EINVAL;
2197 }
2198
2199 return 0;
2200}
2201
2202int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id)
2203{
2204 int ret;
2205 hdd_adapter_t *adapter;
2206 hdd_station_ctx_t *sta_ctx;
2207 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2208
Naveen Rawatc4b045c2017-06-30 16:11:42 -07002209 /* check if adapter by vdev_id is valid NDI */
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002210 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2211 if (!adapter || !WLAN_HDD_IS_NDI(adapter)) {
2212 hdd_err("NAN data interface %s is not available", iface_name);
2213 return -EINVAL;
2214 }
2215
2216 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2217 if (!sta_ctx) {
2218 hdd_err("sta_ctx is NULL");
2219 return -EINVAL;
2220 }
2221
2222 /* Since, the interface is being deleted, remove the broadcast id. */
2223 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
2224 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
2225
2226 os_if_nan_set_ndp_delete_transaction_id(adapter->hdd_vdev,
2227 transaction_id);
2228 os_if_nan_set_ndi_state(adapter->hdd_vdev, NAN_DATA_NDI_DELETING_STATE);
2229
2230 /* Delete the interface */
2231 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
2232 if (ret)
2233 hdd_err("NDI delete request failed");
2234 else
2235 hdd_err("NDI delete request successfully issued");
2236
2237 return ret;
2238}
2239
2240void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id,
2241 struct nan_datapath_inf_create_rsp *ndi_rsp)
2242{
2243 tCsrRoamInfo roam_info = {0};
2244 tSirBssDescription tmp_bss_descp = {0};
2245 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2246 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2247 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
2248 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2249
2250 if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
2251 hdd_alert("NDI interface successfully created");
2252 os_if_nan_set_ndp_create_transaction_id(adapter->hdd_vdev, 0);
2253 os_if_nan_set_ndi_state(adapter->hdd_vdev,
2254 NAN_DATA_NDI_CREATED_STATE);
2255 wlan_hdd_netif_queue_control(adapter,
2256 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2257 WLAN_CONTROL_PATH);
2258 } else {
2259 hdd_alert("NDI interface creation failed with reason %d",
2260 ndi_rsp->reason /* create_reason */);
2261 }
2262
2263 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
2264 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
2265 hdd_roam_register_sta(adapter, &roam_info,
2266 sta_ctx->broadcast_staid,
2267 &bc_mac_addr, &tmp_bss_descp);
2268 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
2269}
2270
2271void hdd_ndi_close(uint8_t vdev_id)
2272{
2273 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2274 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2275 hdd_close_ndi(adapter);
2276}
2277
2278void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id)
2279{
2280 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2281 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2282
2283 wlan_hdd_netif_queue_control(adapter,
2284 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
2285 WLAN_CONTROL_PATH);
2286
2287 complete(&adapter->disconnect_comp_var);
2288}
2289
2290void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
2291{
2292 os_if_nan_ndi_session_end(adapter->hdd_vdev);
2293}
2294
Naveen Rawat37f62c82017-03-26 22:24:43 -07002295int hdd_ndp_get_peer_idx(uint8_t vdev_id, struct qdf_mac_addr *addr)
2296{
2297 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2298 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2299 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2300 return hdd_get_peer_idx(sta_ctx, addr);
2301}
2302
2303/**
2304 * hdd_ndp_new_peer_handler() - NDP new peer indication handler
2305 * @adapter: pointer to adapter context
2306 * @ind_params: indication parameters
2307 *
2308 * Return: none
2309 */
2310int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id,
2311 struct qdf_mac_addr *peer_mac_addr, bool fist_peer)
2312{
2313 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2314 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2315 tSirBssDescription tmp_bss_descp = {0};
2316 tCsrRoamInfo roam_info = {0};
2317 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2318
2319 ENTER();
2320 /* save peer in ndp ctx */
2321 if (false == hdd_save_peer(sta_ctx, sta_id, peer_mac_addr)) {
2322 hdd_err("Ndp peer table full. cannot save new peer");
2323 return -EPERM;
2324 }
2325
2326 /* this function is called for each new peer */
2327 hdd_roam_register_sta(adapter, &roam_info, sta_id,
2328 peer_mac_addr, &tmp_bss_descp);
2329 hdd_ctx->sta_to_adapter[sta_id] = adapter;
2330 /* perform following steps for first new peer ind */
2331 if (fist_peer) {
2332 hdd_info("Set ctx connection state to connected");
2333 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
2334 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
2335 wlan_hdd_netif_queue_control(adapter,
2336 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
2337 }
2338 EXIT();
2339 return 0;
2340}
2341
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002342
2343/**
2344 * hdd_ndp_peer_departed_handler() - Handle NDP peer departed indication
2345 * @adapter: pointer to adapter context
2346 * @ind_params: indication parameters
2347 *
2348 * Return: none
2349 */
2350void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id,
2351 struct qdf_mac_addr *peer_mac_addr, bool last_peer)
2352{
2353 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2354 hdd_adapter_t *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2355 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
2356
2357 ENTER();
2358 hdd_roam_deregister_sta(adapter, sta_id);
2359 hdd_delete_peer(sta_ctx, sta_id);
2360 hdd_ctx->sta_to_adapter[sta_id] = NULL;
2361
2362 if (last_peer) {
2363 hdd_info("No more ndp peers.");
2364 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
2365 hdd_conn_set_connection_state(adapter,
2366 eConnectionState_NdiDisconnected);
2367 hdd_info("Stop netif tx queues.");
2368 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
2369 WLAN_CONTROL_PATH);
2370 }
2371 EXIT();
2372}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002373#endif