blob: 61b2ae52995b65a410722ef36fb1ce38d7e95524 [file] [log] [blame]
Ravi Joshia063dd92016-05-25 16:43:13 -07001/*
Dustin Brown4ea21db2018-01-05 14:13:17 -08002 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
Ravi Joshia063dd92016-05-25 16:43:13 -07003 *
Ravi Joshia063dd92016-05-25 16:43:13 -07004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/**
20 * DOC: wlan_hdd_nan_datapath.c
21 *
22 * WLAN Host Device Driver nan datapath API implementation
23 */
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070024#include <wlan_hdd_includes.h>
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070025#include <linux/if.h>
26#include <linux/netdevice.h>
27#include <linux/skbuff.h>
28#include <linux/etherdevice.h>
29#include "wlan_hdd_includes.h"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070030#include "wlan_hdd_p2p.h"
31#include "wma_api.h"
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070032#include "wlan_hdd_assoc.h"
33#include "sme_nan_datapath.h"
Rajeev Kumar699debf2017-01-06 14:17:00 -080034#include "wlan_hdd_object_manager.h"
Sandeep Puligillafdd201e2017-02-02 18:43:46 -080035#include <qca_vendor.h>
Naveen Rawat63de5422017-03-22 11:03:56 -070036#include "os_if_nan.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -070037#include "wlan_nan_api.h"
38#include "nan_public_structs.h"
Manikandan Mohandcd0fdf2018-08-02 18:13:37 -070039#include "cfg_nan_api.h"
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053040#include "wlan_mlme_ucfg_api.h"
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070041
42/**
43 * hdd_nan_datapath_target_config() - Configure NAN datapath features
44 * @hdd_ctx: Pointer to HDD context
45 * @cfg: Pointer to target device capability information
46 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070047 * NAN datapath functionality is enabled if it is enabled in
48 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070049 *
50 * Return: None
51 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -070052void hdd_nan_datapath_target_config(struct hdd_context *hdd_ctx,
Manikandan Mohandcd0fdf2018-08-02 18:13:37 -070053 struct wma_tgt_cfg *tgt_cfg)
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070054{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -070055 hdd_ctx->nan_datapath_enabled =
Dustin Brown05d81302018-09-11 16:49:22 -070056 cfg_nan_get_datapath_enable(hdd_ctx->psoc) &&
Manikandan Mohandcd0fdf2018-08-02 18:13:37 -070057 tgt_cfg->nan_datapath_enabled;
58 hdd_debug("NAN Datapath Enable: %d (Host: %d FW: %d)",
Dustin Brown7e761c72018-07-31 13:50:17 -070059 hdd_ctx->nan_datapath_enabled,
Dustin Brown05d81302018-09-11 16:49:22 -070060 cfg_nan_get_datapath_enable(hdd_ctx->psoc),
Manikandan Mohandcd0fdf2018-08-02 18:13:37 -070061 tgt_cfg->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070062}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070063
64/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070065 * hdd_close_ndi() - close NAN Data interface
66 * @adapter: adapter context
67 *
68 * Close the adapter if start BSS fails
69 *
70 * Returns: 0 on success, negative error code otherwise
71 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -070072static int hdd_close_ndi(struct hdd_adapter *adapter)
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070073{
Dustin Brown0d2eeae2017-03-24 15:21:32 -070074 int errno;
Jeff Johnson88dc4f92017-08-28 11:51:34 -070075 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070076
Dustin Brown491d54b2018-03-14 12:39:11 -070077 hdd_enter();
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070078
79 /* check if the adapter is in NAN Data mode */
80 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -070081 hdd_err("Interface is not in NDI mode");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070082 return -EINVAL;
83 }
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -070084 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +053085 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -070086 WLAN_CONTROL_PATH);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070087
88#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -070089 cancel_work_sync(&adapter->ipv4_notifier_work);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070090#endif
91 hdd_deregister_tx_flow_control(adapter);
92
93#ifdef WLAN_NS_OFFLOAD
94#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -070095 cancel_work_sync(&adapter->ipv6_notifier_work);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070096#endif
97#endif
Dustin Brown0d2eeae2017-03-24 15:21:32 -070098 errno = hdd_vdev_destroy(adapter);
99 if (errno)
100 hdd_err("failed to destroy vdev: %d", errno);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700101
102 /* We are good to close the adapter */
103 hdd_close_adapter(hdd_ctx, adapter, true);
104
Dustin Browne74003f2018-03-14 12:51:58 -0700105 hdd_exit();
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700106 return 0;
107}
108
109/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700110 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
111 * @hdd_ctx: hdd context
112 *
113 * NDP is not allowed with any other role active except STA.
114 *
115 * Return: true if allowed, false otherwise
116 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700117static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700118{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700119 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700120 struct hdd_station_ctx *sta_ctx;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700121
Dustin Brown920397d2017-12-13 16:27:50 -0800122 hdd_for_each_adapter(hdd_ctx, adapter) {
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700123 switch (adapter->device_mode) {
124 case QDF_P2P_GO_MODE:
125 case QDF_SAP_MODE:
126 if (test_bit(SOFTAP_BSS_STARTED,
127 &adapter->event_flags))
128 return false;
129 break;
130 case QDF_P2P_CLIENT_MODE:
131 case QDF_IBSS_MODE:
132 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
133 if (hdd_conn_is_connected(sta_ctx) ||
134 hdd_is_connecting(sta_ctx))
135 return false;
136 break;
137 default:
138 break;
139 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700140 }
141
142 return true;
143}
144
145/**
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700146 * hdd_ndi_start_bss() - Start BSS on NAN data interface
147 * @adapter: adapter context
148 * @operating_channel: channel on which the BSS to be started
149 *
150 * Return: 0 on success, error value on failure
151 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700152static int hdd_ndi_start_bss(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700153 uint8_t operating_channel)
154{
Jeff Johnson32833f12018-06-13 20:26:34 -0700155 QDF_STATUS status;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700156 uint32_t roam_id;
Jeff Johnson641839e2018-03-18 14:50:39 -0700157 struct csr_roam_profile *roam_profile;
Jeff Johnson32833f12018-06-13 20:26:34 -0700158 mac_handle_t mac_handle;
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +0530159 uint8_t wmm_mode = 0;
160 struct hdd_context *hdd_ctx;
161 uint8_t value = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700162
Dustin Brown491d54b2018-03-14 12:39:11 -0700163 hdd_enter();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700164
Jeff Johnson641839e2018-03-18 14:50:39 -0700165 roam_profile = hdd_roam_profile(adapter);
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +0530166 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700167
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +0530168 status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc, &wmm_mode);
169 if (!QDF_IS_STATUS_SUCCESS(status)) {
170 hdd_err("Get wmm_mode failed");
171 return -EINVAL;
172 }
173
174 if (HDD_WMM_USER_MODE_NO_QOS == wmm_mode) {
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700175 /* QoS not enabled in cfg file*/
176 roam_profile->uapsd_mask = 0;
177 } else {
178 /* QoS enabled, update uapsd mask from cfg file*/
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +0530179 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc, &value);
180 if (!QDF_IS_STATUS_SUCCESS(status)) {
181 hdd_err("Get uapsd_mask failed");
182 return -EINVAL;
183 }
184 roam_profile->uapsd_mask = value;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700185 }
186
187 roam_profile->csrPersona = adapter->device_mode;
188
Naveen Rawat709c0cb2018-03-14 17:04:15 -0700189 if (!operating_channel)
190 operating_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
191
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700192 roam_profile->ChannelInfo.numOfChannels = 1;
Naveen Rawat709c0cb2018-03-14 17:04:15 -0700193 roam_profile->ChannelInfo.ChannelList = &operating_channel;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700194
195 roam_profile->SSIDs.numOfSSIDs = 1;
196 roam_profile->SSIDs.SSIDList->SSID.length = 0;
197
198 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
199 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
200 roam_profile->BSSIDs.numOfBSSIDs = 1;
201 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
Jeff Johnson1e851a12017-10-28 14:36:12 -0700202 &adapter->mac_addr.bytes[0],
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700203 QDF_MAC_ADDR_SIZE);
204
205 roam_profile->AuthType.numEntries = 1;
206 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
207 roam_profile->EncryptionType.numEntries = 1;
208 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
209
Jeff Johnson32833f12018-06-13 20:26:34 -0700210 mac_handle = hdd_adapter_get_mac_handle(adapter);
211 status = sme_roam_connect(mac_handle, adapter->session_id,
212 roam_profile, &roam_id);
213 if (QDF_IS_STATUS_ERROR(status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700214 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
Jeff Johnson32833f12018-06-13 20:26:34 -0700215 adapter->session_id, status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700216 /* change back to NotConnected */
217 hdd_conn_set_connection_state(adapter,
Jeff Johnson32833f12018-06-13 20:26:34 -0700218 eConnectionState_NotConnected);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700219 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700220 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700221 }
222
223 roam_profile->ChannelInfo.ChannelList = NULL;
224 roam_profile->ChannelInfo.numOfChannels = 0;
225
Dustin Browne74003f2018-03-14 12:51:58 -0700226 hdd_exit();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700227
Jeff Johnson32833f12018-06-13 20:26:34 -0700228 return 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700229}
230
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700231/**
232 * hdd_get_random_nan_mac_addr() - generate random non pre-existent mac address
233 * @hdd_ctx: hdd context pointer
234 * @mac_addr: mac address buffer to populate
235 *
236 * Return: status of operation
237 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700238static int hdd_get_random_nan_mac_addr(struct hdd_context *hdd_ctx,
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700239 struct qdf_mac_addr *mac_addr)
240{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700241 struct hdd_adapter *adapter;
Naveen Rawatea1ece82018-02-09 14:22:52 -0800242 uint8_t pos, bit_pos, byte_pos, mask;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700243 uint8_t i, attempts, max_attempt = 16;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700244
245 for (attempts = 0; attempts < max_attempt; attempts++) {
Naveen Rawatea1ece82018-02-09 14:22:52 -0800246 /* if NDI is present next addr is required to be 1 bit apart */
247 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
248 if (adapter) {
249 hdd_debug("NDI already exists, deriving next mac");
250 qdf_mem_copy(mac_addr, &adapter->mac_addr,
251 sizeof(*mac_addr));
252 cds_rand_get_bytes(0, &pos, sizeof(pos));
253 /* skipping byte 0, 5 leaves 8*4=32 positions */
254 pos = pos % 32;
255 bit_pos = pos % 8;
256 byte_pos = pos / 8;
257 mask = 1 << bit_pos;
258 /* flip the required bit */
259 mac_addr->bytes[byte_pos + 1] ^= mask;
260 } else {
261 cds_rand_get_bytes(0, (uint8_t *)mac_addr,
262 sizeof(*mac_addr));
263 /*
264 * Reset multicast bit (bit-0) and set
265 * locally-administered bit
266 */
267 mac_addr->bytes[0] = 0x2;
Ravi Joshi04a1c992017-06-11 19:47:54 -0700268
Naveen Rawatea1ece82018-02-09 14:22:52 -0800269 /*
270 * to avoid potential conflict with FW's generated NMI
271 * mac addr, host sets LSB if 6th byte to 0
272 */
273 mac_addr->bytes[5] &= 0xFE;
274 }
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700275 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
276 if (!qdf_mem_cmp(hdd_ctx->config->intfMacAddr[i].bytes,
277 mac_addr, sizeof(*mac_addr)))
278 continue;
279 }
280
281 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
282 if (!adapter)
283 return 0;
284 }
285
286 hdd_err("unable to get non-pre-existing mac address in %d attempts",
287 max_attempt);
288
289 return -EINVAL;
290}
291
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700292void hdd_ndp_event_handler(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -0800293 struct csr_roam_info *roam_info,
294 uint32_t roam_id, eRoamCmdStatus roam_status,
295 eCsrRoamResult roam_result)
Naveen Rawat97500352017-03-22 10:07:58 -0700296{
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700297 bool success;
Dustin Brown89fa06e2018-09-07 10:47:27 -0700298 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(adapter->vdev);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700299
300 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
301 switch (roam_result) {
302 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
303 success = (roam_info->ndp.ndi_create_params.status ==
304 NAN_DATAPATH_RSP_STATUS_SUCCESS);
305 hdd_debug("posting ndi create status: %d to umac",
306 success);
Jeff Johnson1b780e42017-10-31 14:11:45 -0700307 os_if_nan_post_ndi_create_rsp(psoc, adapter->session_id,
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700308 success);
309 return;
310 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
311 success = (roam_info->ndp.ndi_create_params.status ==
312 NAN_DATAPATH_RSP_STATUS_SUCCESS);
313 hdd_debug("posting ndi delete status: %d to umac",
314 success);
Jeff Johnson1b780e42017-10-31 14:11:45 -0700315 os_if_nan_post_ndi_delete_rsp(psoc, adapter->session_id,
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700316 success);
317 return;
318 default:
319 hdd_err("in correct roam_result: %d", roam_result);
320 return;
321 }
322 } else {
323 hdd_err("in correct roam_status: %d", roam_status);
324 return;
325 }
Naveen Rawat97500352017-03-22 10:07:58 -0700326}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700327
328/**
329 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
330 * @wiphy: pointer to wireless wiphy structure.
331 * @wdev: pointer to wireless_dev structure.
332 * @data: Pointer to the data to be passed via vendor interface
333 * @data_len:Length of the data to be passed
334 *
335 * This function is invoked to handle vendor command
336 *
337 * Return: 0 on success, negative errno on failure
338 */
Naveen Rawat63de5422017-03-22 11:03:56 -0700339static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
340 struct wireless_dev *wdev, const void *data, int data_len)
341{
342 int ret_val;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700343 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Naveen Rawat63de5422017-03-22 11:03:56 -0700344
Dustin Brown491d54b2018-03-14 12:39:11 -0700345 hdd_enter();
Naveen Rawat63de5422017-03-22 11:03:56 -0700346
347 ret_val = wlan_hdd_validate_context(hdd_ctx);
348 if (ret_val)
349 return ret_val;
350
351 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Rajeev Kumar3872a5b2018-10-02 11:47:38 -0700352 hdd_err_rl("Command not allowed in FTM mode");
Naveen Rawat63de5422017-03-22 11:03:56 -0700353 return -EPERM;
354 }
355
356 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Nachiket Kukaded29b6c82018-11-27 12:28:22 +0530357 hdd_err_rl("NAN datapath is not enabled");
Naveen Rawat63de5422017-03-22 11:03:56 -0700358 return -EPERM;
359 }
360 /* NAN data path coexists only with STA interface */
361 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Nachiket Kukaded29b6c82018-11-27 12:28:22 +0530362 hdd_err_rl("Unsupported concurrency for NAN datapath");
Naveen Rawat63de5422017-03-22 11:03:56 -0700363 return -EPERM;
364 }
365
366 /* NAN data path coexists only with STA interface */
367 if (false == hdd_is_ndp_allowed(hdd_ctx)) {
Nachiket Kukaded29b6c82018-11-27 12:28:22 +0530368 hdd_err_rl("Unsupported concurrency for NAN datapath");
Naveen Rawat63de5422017-03-22 11:03:56 -0700369 return -EPERM;
370 }
371
Dustin Brown05d81302018-09-11 16:49:22 -0700372 return os_if_nan_process_ndp_cmd(hdd_ctx->psoc,
Naveen Rawat63de5422017-03-22 11:03:56 -0700373 data, data_len);
374}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700375
376/**
377 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
378 * @wiphy: pointer to wireless wiphy structure.
379 * @wdev: pointer to wireless_dev structure.
380 * @data: Pointer to the data to be passed via vendor interface
381 * @data_len:Length of the data to be passed
382 *
383 * This function is called to send a NAN request to
384 * firmware. This is an SSR-protected wrapper function.
385 *
386 * Return: 0 on success, negative errno on failure
387 */
388int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
389 struct wireless_dev *wdev, const void *data, int data_len)
390{
391 int ret;
392
393 cds_ssr_protect(__func__);
394 ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
395 cds_ssr_unprotect(__func__);
396
397 return ret;
398}
399
Jeff Johnson85b5c112017-08-11 15:15:23 -0700400static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700401{
Dustin Brown89fa06e2018-09-07 10:47:27 -0700402 return os_if_nan_set_ndi_state(adapter->vdev, state);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700403}
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700404
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700405/**
406 * hdd_init_nan_data_mode() - initialize nan data mode
407 * @adapter: adapter context
408 *
409 * Returns: 0 on success negative error code on error
410 */
Jeff Johnson85b5c112017-08-11 15:15:23 -0700411int hdd_init_nan_data_mode(struct hdd_adapter *adapter)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700412{
413 struct net_device *wlan_dev = adapter->dev;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700414 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700415 QDF_STATUS status;
Jeff Johnson32833f12018-06-13 20:26:34 -0700416 int32_t ret_val;
417 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +0530418 bool bval = false;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700419
Krunal Sonib51eec72017-11-20 21:53:01 -0800420 ret_val = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -0700421 if (ret_val) {
422 hdd_err("failed to create vdev: %d", ret_val);
423 return ret_val;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700424 }
425
Jeff Johnson32833f12018-06-13 20:26:34 -0700426 mac_handle = hdd_ctx->mac_handle;
427
Ravi Joshi8eb65f92017-07-20 16:30:19 -0700428 /* Configure self HT/VHT capabilities */
Jeff Johnson32833f12018-06-13 20:26:34 -0700429 sme_set_curr_device_mode(mac_handle, adapter->device_mode);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +0530430
431 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
432 if (!QDF_IS_STATUS_SUCCESS(status))
433 hdd_err("unable to get vht_enable2x2");
434
435 sme_set_pdev_ht_vht_ies(mac_handle, bval);
Jeff Johnson32833f12018-06-13 20:26:34 -0700436 sme_set_vdev_ies_per_band(mac_handle, adapter->session_id);
Ravi Joshi8eb65f92017-07-20 16:30:19 -0700437
Jeff Johnson7f2c5912018-03-23 11:42:28 -0700438 hdd_roam_profile_init(adapter);
439 hdd_register_wext(wlan_dev);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700440
441 status = hdd_init_tx_rx(adapter);
442 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700443 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700444 ret_val = -EAGAIN;
445 goto error_init_txrx;
446 }
447
448 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
449
450 status = hdd_wmm_adapter_init(adapter);
451 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700452 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700453 ret_val = -EAGAIN;
454 goto error_wmm_init;
455 }
456
457 set_bit(WMM_INIT_DONE, &adapter->event_flags);
458
Jeff Johnson1b780e42017-10-31 14:11:45 -0700459 ret_val = wma_cli_set_command((int)adapter->session_id,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700460 (int)WMI_PDEV_PARAM_BURST_ENABLE,
Dundi Raviteja3aa01be2018-05-21 18:58:59 +0530461 (int)HDD_ENABLE_SIFS_BURST_DEFAULT,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700462 PDEV_CMD);
Arunk Khandavalli15664e42017-06-29 15:56:14 +0530463 if (0 != ret_val)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700464 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Arunk Khandavalli15664e42017-06-29 15:56:14 +0530465
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700466
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700467 update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700468 return ret_val;
469
470error_wmm_init:
471 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
472 hdd_deinit_tx_rx(adapter);
473
474error_init_txrx:
475 hdd_unregister_wext(wlan_dev);
476
Dustin Brownd28772b2017-03-17 14:16:07 -0700477 QDF_BUG(!hdd_vdev_destroy(adapter));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700478
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700479 return ret_val;
480}
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700481
Naveen Rawat23a3b912018-05-30 17:45:52 -0700482int hdd_ndi_open(char *iface_name)
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700483{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700484 struct hdd_adapter *adapter;
Ravi Joshi9771d432017-06-26 13:58:12 -0700485 struct qdf_mac_addr random_ndi_mac;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700486 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Ravi Joshi9771d432017-06-26 13:58:12 -0700487 uint8_t *ndi_mac_addr;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700488
Dustin Brown491d54b2018-03-14 12:39:11 -0700489 hdd_enter();
Naveen Rawatf9391622017-12-20 17:06:01 -0800490 if (!hdd_ctx) {
491 hdd_err("hdd_ctx null");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700492 return -EINVAL;
Naveen Rawatf9391622017-12-20 17:06:01 -0800493 }
494
Dustin Brown05d81302018-09-11 16:49:22 -0700495 if (cfg_nan_get_ndi_mac_randomize(hdd_ctx->psoc)) {
Ravi Joshi9771d432017-06-26 13:58:12 -0700496 if (hdd_get_random_nan_mac_addr(hdd_ctx, &random_ndi_mac)) {
497 hdd_err("get random mac address failed");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700498 return -EFAULT;
Ravi Joshi9771d432017-06-26 13:58:12 -0700499 }
500 ndi_mac_addr = &random_ndi_mac.bytes[0];
501 } else {
502 ndi_mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
503 if (!ndi_mac_addr) {
504 hdd_err("get intf address failed");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700505 return -EFAULT;
Ravi Joshi9771d432017-06-26 13:58:12 -0700506 }
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700507 }
508
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700509 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
Ravi Joshi9771d432017-06-26 13:58:12 -0700510 ndi_mac_addr, NET_NAME_UNKNOWN, true);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700511 if (!adapter) {
512 hdd_err("hdd_open_adapter failed");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700513 return -EINVAL;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700514 }
515
Dustin Browne74003f2018-03-14 12:51:58 -0700516 hdd_exit();
Naveen Rawat23a3b912018-05-30 17:45:52 -0700517 return 0;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700518}
519
Naveen Rawat23a3b912018-05-30 17:45:52 -0700520int hdd_ndi_start(char *iface_name, uint16_t transaction_id)
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700521{
Naveen Rawat23a3b912018-05-30 17:45:52 -0700522 int ret;
Naveen Rawatf9391622017-12-20 17:06:01 -0800523 uint8_t op_channel;
Naveen Rawat23a3b912018-05-30 17:45:52 -0700524 QDF_STATUS status;
Naveen Rawatf9391622017-12-20 17:06:01 -0800525 struct hdd_adapter *adapter;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700526 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700527
Dustin Brown491d54b2018-03-14 12:39:11 -0700528 hdd_enter();
Naveen Rawatf9391622017-12-20 17:06:01 -0800529 if (!hdd_ctx) {
530 hdd_err("hdd_ctx is null");
531 return -EINVAL;
532 }
533
Dustin Brown05d81302018-09-11 16:49:22 -0700534 op_channel = cfg_nan_get_ndi_channel(hdd_ctx->psoc);
Naveen Rawat23a3b912018-05-30 17:45:52 -0700535 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, iface_name);
Naveen Rawatf9391622017-12-20 17:06:01 -0800536 if (!adapter) {
537 hdd_err("adapter is null");
538 return -EINVAL;
539 }
540
Naveen Rawat23a3b912018-05-30 17:45:52 -0700541 /* create nan vdev */
542 status = hdd_init_nan_data_mode(adapter);
543 if (QDF_STATUS_SUCCESS != status) {
544 hdd_err("failed to init nan data intf, status :%d", status);
545 ret = -EFAULT;
546 goto err_handler;
547 }
548
549 /*
550 * Create transaction id is required to be saved since the firmware
551 * does not honor the transaction id for create request
552 */
Dustin Brown89fa06e2018-09-07 10:47:27 -0700553 ucfg_nan_set_ndp_create_transaction_id(adapter->vdev,
Naveen Rawat23a3b912018-05-30 17:45:52 -0700554 transaction_id);
Dustin Brown89fa06e2018-09-07 10:47:27 -0700555 ucfg_nan_set_ndi_state(adapter->vdev,
Naveen Rawat23a3b912018-05-30 17:45:52 -0700556 NAN_DATA_NDI_CREATING_STATE);
557
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700558 /*
559 * The NAN data interface has been created at this point.
560 * Unlike traditional device modes, where the higher application
561 * layer initiates connect / join / start, the NAN data
562 * interface does not have any such formal requests. The NDI
563 * create request is responsible for starting the BSS as well.
564 */
jitiphil31cf1ba2018-05-11 15:54:38 +0530565 if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ &&
566 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND &&
567 op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700568 /* start NDI on the default 2.4 GHz social channel */
569 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
570 }
Naveen Rawat23a3b912018-05-30 17:45:52 -0700571
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700572 if (hdd_ndi_start_bss(adapter, op_channel)) {
573 hdd_err("NDI start bss failed");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700574 ret = -EFAULT;
575 goto err_handler;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700576 }
577
Dustin Browne74003f2018-03-14 12:51:58 -0700578 hdd_exit();
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700579 return 0;
Naveen Rawat23a3b912018-05-30 17:45:52 -0700580
581err_handler:
582
583 /* Start BSS failed, delete the interface */
584 hdd_close_ndi(adapter);
585 return ret;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700586}
587
588int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id)
589{
590 int ret;
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700591 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700592 struct hdd_station_ctx *sta_ctx;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700593 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700594
Naveen Rawatf9391622017-12-20 17:06:01 -0800595 if (!hdd_ctx) {
596 hdd_err("hdd_ctx is null");
597 return -EINVAL;
598 }
599
Naveen Rawatc4b045c2017-06-30 16:11:42 -0700600 /* check if adapter by vdev_id is valid NDI */
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700601 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
602 if (!adapter || !WLAN_HDD_IS_NDI(adapter)) {
603 hdd_err("NAN data interface %s is not available", iface_name);
604 return -EINVAL;
605 }
606
607 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
608 if (!sta_ctx) {
609 hdd_err("sta_ctx is NULL");
610 return -EINVAL;
611 }
612
613 /* Since, the interface is being deleted, remove the broadcast id. */
614 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
615 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
616
Dustin Brown89fa06e2018-09-07 10:47:27 -0700617 os_if_nan_set_ndp_delete_transaction_id(adapter->vdev,
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700618 transaction_id);
Dustin Brown89fa06e2018-09-07 10:47:27 -0700619 os_if_nan_set_ndi_state(adapter->vdev, NAN_DATA_NDI_DELETING_STATE);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700620
621 /* Delete the interface */
622 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
623 if (ret)
624 hdd_err("NDI delete request failed");
625 else
626 hdd_err("NDI delete request successfully issued");
627
628 return ret;
629}
630
631void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id,
632 struct nan_datapath_inf_create_rsp *ndi_rsp)
633{
Naveen Rawatf9391622017-12-20 17:06:01 -0800634 struct hdd_context *hdd_ctx;
635 struct hdd_adapter *adapter;
636 struct hdd_station_ctx *sta_ctx;
Jeff Johnson172237b2017-11-07 15:32:59 -0800637 struct csr_roam_info roam_info = {0};
Jeff Johnson4ba73cb2017-10-06 11:12:33 -0700638 struct bss_description tmp_bss_descp = {0};
Dustin Brownce5b3d32018-01-17 15:07:38 -0800639 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BCAST_INIT;
Naveen Rawatf9391622017-12-20 17:06:01 -0800640
641 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
642 if (!hdd_ctx) {
643 hdd_err("hdd_ctx is null");
644 return;
645 }
646
647 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
648 if (!adapter) {
649 hdd_err("adapter is null");
650 return;
651 }
652
653 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
654 if (!sta_ctx) {
655 hdd_err("sta_ctx is null");
656 return;
657 }
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700658
659 if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
660 hdd_alert("NDI interface successfully created");
Dustin Brown89fa06e2018-09-07 10:47:27 -0700661 os_if_nan_set_ndp_create_transaction_id(adapter->vdev, 0);
662 os_if_nan_set_ndi_state(adapter->vdev,
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700663 NAN_DATA_NDI_CREATED_STATE);
664 wlan_hdd_netif_queue_control(adapter,
665 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
666 WLAN_CONTROL_PATH);
667 } else {
668 hdd_alert("NDI interface creation failed with reason %d",
669 ndi_rsp->reason /* create_reason */);
670 }
671
672 sta_ctx->broadcast_staid = ndi_rsp->sta_id;
673 hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
674 hdd_roam_register_sta(adapter, &roam_info,
675 sta_ctx->broadcast_staid,
676 &bc_mac_addr, &tmp_bss_descp);
677 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
678}
679
680void hdd_ndi_close(uint8_t vdev_id)
681{
Naveen Rawatf9391622017-12-20 17:06:01 -0800682 struct hdd_context *hdd_ctx;
683 struct hdd_adapter *adapter;
684
685 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
686 if (!hdd_ctx) {
687 hdd_err("hdd_ctx is null");
688 return;
689 }
690
691 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
692 if (!adapter) {
693 hdd_err("adapter is null");
694 return;
695 }
Jeff Johnson4f7f7c62017-10-05 08:53:41 -0700696
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700697 hdd_close_ndi(adapter);
698}
699
700void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id)
701{
Naveen Rawatf9391622017-12-20 17:06:01 -0800702 struct hdd_context *hdd_ctx;
703 struct hdd_adapter *adapter;
704 struct hdd_station_ctx *sta_ctx;
705
706 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
707 if (!hdd_ctx) {
708 hdd_err("hdd_ctx is null");
709 return;
710 }
711
712 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
713 if (!adapter) {
714 hdd_err("adapter is null");
715 return;
716 }
717
718 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
719 if (!sta_ctx) {
720 hdd_err("sta_ctx is null");
721 return;
722 }
Naveen Rawatb7be1ed2017-11-16 16:52:08 -0800723
724 hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = NULL;
725 hdd_roam_deregister_sta(adapter, sta_ctx->broadcast_staid);
726 hdd_delete_peer(sta_ctx, sta_ctx->broadcast_staid);
727 sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700728
729 wlan_hdd_netif_queue_control(adapter,
730 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
731 WLAN_CONTROL_PATH);
732
733 complete(&adapter->disconnect_comp_var);
734}
735
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700736void hdd_ndp_session_end_handler(struct hdd_adapter *adapter)
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700737{
Dustin Brown89fa06e2018-09-07 10:47:27 -0700738 os_if_nan_ndi_session_end(adapter->vdev);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700739}
740
Naveen Rawat37f62c82017-03-26 22:24:43 -0700741int hdd_ndp_get_peer_idx(uint8_t vdev_id, struct qdf_mac_addr *addr)
742{
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700743 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700744 struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700745 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson4f7f7c62017-10-05 08:53:41 -0700746
Naveen Rawat37f62c82017-03-26 22:24:43 -0700747 return hdd_get_peer_idx(sta_ctx, addr);
748}
749
750/**
751 * hdd_ndp_new_peer_handler() - NDP new peer indication handler
752 * @adapter: pointer to adapter context
753 * @ind_params: indication parameters
754 *
755 * Return: none
756 */
757int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id,
758 struct qdf_mac_addr *peer_mac_addr, bool fist_peer)
759{
Naveen Rawatf9391622017-12-20 17:06:01 -0800760 struct hdd_context *hdd_ctx;
761 struct hdd_adapter *adapter;
762 struct hdd_station_ctx *sta_ctx;
Jeff Johnson4ba73cb2017-10-06 11:12:33 -0700763 struct bss_description tmp_bss_descp = {0};
Jeff Johnson172237b2017-11-07 15:32:59 -0800764 struct csr_roam_info roam_info = {0};
Naveen Rawat37f62c82017-03-26 22:24:43 -0700765
Dustin Brown491d54b2018-03-14 12:39:11 -0700766 hdd_enter();
Naveen Rawatf9391622017-12-20 17:06:01 -0800767
768 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
769 if (!hdd_ctx) {
770 hdd_err("hdd_ctx is null");
771 return -EINVAL;
772 }
773
774 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
775 if (!adapter) {
776 hdd_err("adapter is null");
777 return -EINVAL;
778 }
779
780 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
781 if (!sta_ctx) {
782 hdd_err("sta_ctx is null");
783 return -EINVAL;
784 }
785
Naveen Rawat37f62c82017-03-26 22:24:43 -0700786 /* save peer in ndp ctx */
787 if (false == hdd_save_peer(sta_ctx, sta_id, peer_mac_addr)) {
788 hdd_err("Ndp peer table full. cannot save new peer");
789 return -EPERM;
790 }
791
792 /* this function is called for each new peer */
793 hdd_roam_register_sta(adapter, &roam_info, sta_id,
794 peer_mac_addr, &tmp_bss_descp);
795 hdd_ctx->sta_to_adapter[sta_id] = adapter;
796 /* perform following steps for first new peer ind */
797 if (fist_peer) {
798 hdd_info("Set ctx connection state to connected");
799 sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
800 hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
801 wlan_hdd_netif_queue_control(adapter,
802 WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
803 }
Dustin Browne74003f2018-03-14 12:51:58 -0700804 hdd_exit();
Naveen Rawat37f62c82017-03-26 22:24:43 -0700805 return 0;
806}
807
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700808
809/**
810 * hdd_ndp_peer_departed_handler() - Handle NDP peer departed indication
811 * @adapter: pointer to adapter context
812 * @ind_params: indication parameters
813 *
814 * Return: none
815 */
816void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id,
817 struct qdf_mac_addr *peer_mac_addr, bool last_peer)
818{
Naveen Rawatf9391622017-12-20 17:06:01 -0800819 struct hdd_context *hdd_ctx;
820 struct hdd_adapter *adapter;
821 struct hdd_station_ctx *sta_ctx;
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700822
Dustin Brown491d54b2018-03-14 12:39:11 -0700823 hdd_enter();
Naveen Rawatf9391622017-12-20 17:06:01 -0800824
825 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
826 if (!hdd_ctx) {
827 hdd_err("hdd_ctx is null");
828 return;
829 }
830
831 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
832 if (!adapter) {
833 hdd_err("adapter is null");
834 return;
835 }
836
837 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
838 if (!sta_ctx) {
839 hdd_err("sta_ctx is null");
840 return;
841 }
842
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700843 hdd_roam_deregister_sta(adapter, sta_id);
844 hdd_delete_peer(sta_ctx, sta_id);
845 hdd_ctx->sta_to_adapter[sta_id] = NULL;
846
847 if (last_peer) {
848 hdd_info("No more ndp peers.");
849 sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
850 hdd_conn_set_connection_state(adapter,
851 eConnectionState_NdiDisconnected);
852 hdd_info("Stop netif tx queues.");
853 wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
854 WLAN_CONTROL_PATH);
855 }
Dustin Browne74003f2018-03-14 12:51:58 -0700856 hdd_exit();
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700857}