blob: c7235a1632c56752e3d7f5a7d462b9ad3fdcd75b [file] [log] [blame]
Ravi Joshia063dd92016-05-25 16:43:13 -07001/*
Bapiraju Alla797b21b2020-11-23 13:44:21 +05302 * Copyright (c) 2016-2021 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"
Dustin Brown6412d1f2019-02-05 14:52:29 -080031#include "osif_sync.h"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070032#include "wma_api.h"
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -070033#include "wlan_hdd_assoc.h"
34#include "sme_nan_datapath.h"
Rajeev Kumar699debf2017-01-06 14:17:00 -080035#include "wlan_hdd_object_manager.h"
Sandeep Puligillafdd201e2017-02-02 18:43:46 -080036#include <qca_vendor.h>
Naveen Rawat63de5422017-03-22 11:03:56 -070037#include "os_if_nan.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -070038#include "wlan_nan_api.h"
39#include "nan_public_structs.h"
Manikandan Mohandcd0fdf2018-08-02 18:13:37 -070040#include "cfg_nan_api.h"
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053041#include "wlan_mlme_ucfg_api.h"
Jeff Johnson51a80522018-12-11 20:19:44 -080042#include "qdf_util.h"
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +053043#include <cdp_txrx_misc.h>
Qun Zhang1b3c85c2019-08-27 16:31:49 +080044#include "wlan_fwol_ucfg_api.h"
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070045
46/**
47 * hdd_nan_datapath_target_config() - Configure NAN datapath features
48 * @hdd_ctx: Pointer to HDD context
49 * @cfg: Pointer to target device capability information
50 *
Deepak Dhamdhere13983f22016-05-31 19:06:09 -070051 * NAN datapath functionality is enabled if it is enabled in
52 * .ini file and also supported on target device.
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070053 *
54 * Return: None
55 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -070056void hdd_nan_datapath_target_config(struct hdd_context *hdd_ctx,
Manikandan Mohandcd0fdf2018-08-02 18:13:37 -070057 struct wma_tgt_cfg *tgt_cfg)
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070058{
Deepak Dhamdhere7e6016f2016-06-01 09:37:37 -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;
62 hdd_debug("NAN Datapath Enable: %d (Host: %d FW: %d)",
Dustin Brown7e761c72018-07-31 13:50:17 -070063 hdd_ctx->nan_datapath_enabled,
Dustin Brown05d81302018-09-11 16:49:22 -070064 cfg_nan_get_datapath_enable(hdd_ctx->psoc),
Manikandan Mohandcd0fdf2018-08-02 18:13:37 -070065 tgt_cfg->nan_datapath_enabled);
Deepak Dhamdhere13230d32016-05-26 00:46:53 -070066}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070067
68/**
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070069 * hdd_close_ndi() - close NAN Data interface
70 * @adapter: adapter context
71 *
72 * Close the adapter if start BSS fails
73 *
74 * Returns: 0 on success, negative error code otherwise
75 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -070076static int hdd_close_ndi(struct hdd_adapter *adapter)
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070077{
Dustin Brown0d2eeae2017-03-24 15:21:32 -070078 int errno;
Jeff Johnson88dc4f92017-08-28 11:51:34 -070079 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070080
Dustin Brown491d54b2018-03-14 12:39:11 -070081 hdd_enter();
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070082
83 /* check if the adapter is in NAN Data mode */
84 if (QDF_NDI_MODE != adapter->device_mode) {
Naveen Rawatba4f6612016-07-05 12:03:16 -070085 hdd_err("Interface is not in NDI mode");
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070086 return -EINVAL;
87 }
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -070088 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +053089 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -070090 WLAN_CONTROL_PATH);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070091
92#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -070093 cancel_work_sync(&adapter->ipv4_notifier_work);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070094#endif
Visweswara Tanukub5a61242019-03-26 12:24:13 +053095 hdd_deregister_hl_netdev_fc_timer(adapter);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -070096 hdd_deregister_tx_flow_control(adapter);
97
98#ifdef WLAN_NS_OFFLOAD
99#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -0700100 cancel_work_sync(&adapter->ipv6_notifier_work);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700101#endif
102#endif
Dustin Brown0d2eeae2017-03-24 15:21:32 -0700103 errno = hdd_vdev_destroy(adapter);
104 if (errno)
105 hdd_err("failed to destroy vdev: %d", errno);
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700106
107 /* We are good to close the adapter */
108 hdd_close_adapter(hdd_ctx, adapter, true);
109
Dustin Browne74003f2018-03-14 12:51:58 -0700110 hdd_exit();
Deepak Dhamdhere616d9c52016-06-01 12:39:51 -0700111 return 0;
112}
113
114/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700115 * hdd_is_ndp_allowed() - Indicates if NDP is allowed
116 * @hdd_ctx: hdd context
117 *
118 * NDP is not allowed with any other role active except STA.
119 *
120 * Return: true if allowed, false otherwise
121 */
Wu Gao18596ae2019-08-13 17:33:14 +0800122#ifdef NDP_SAP_CONCURRENCY_ENABLE
123static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx)
124{
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530125 struct hdd_adapter *adapter, *next_adapter = NULL;
Wu Gao18596ae2019-08-13 17:33:14 +0800126 struct hdd_station_ctx *sta_ctx;
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530127 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_NDP_ALLOWED;
Wu Gao18596ae2019-08-13 17:33:14 +0800128
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530129 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
130 dbgid) {
Wu Gao18596ae2019-08-13 17:33:14 +0800131 switch (adapter->device_mode) {
132 case QDF_P2P_GO_MODE:
133 if (test_bit(SOFTAP_BSS_STARTED,
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530134 &adapter->event_flags)) {
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530135 hdd_adapter_dev_put_debug(adapter, dbgid);
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530136 if (next_adapter)
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530137 hdd_adapter_dev_put_debug(next_adapter,
138 dbgid);
Wu Gao18596ae2019-08-13 17:33:14 +0800139 return false;
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530140 }
Wu Gao18596ae2019-08-13 17:33:14 +0800141 break;
142 case QDF_P2P_CLIENT_MODE:
143 case QDF_IBSS_MODE:
144 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
145 if (hdd_conn_is_connected(sta_ctx) ||
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530146 hdd_is_connecting(sta_ctx)) {
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530147 hdd_adapter_dev_put_debug(adapter, dbgid);
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530148 if (next_adapter)
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530149 hdd_adapter_dev_put_debug(next_adapter,
150 dbgid);
Wu Gao18596ae2019-08-13 17:33:14 +0800151 return false;
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530152 }
Wu Gao18596ae2019-08-13 17:33:14 +0800153 break;
154 default:
155 break;
156 }
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530157 hdd_adapter_dev_put_debug(adapter, dbgid);
Wu Gao18596ae2019-08-13 17:33:14 +0800158 }
159
160 return true;
161}
162#else
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700163static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx)
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700164{
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530165 struct hdd_adapter *adapter, *next_adapter = NULL;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700166 struct hdd_station_ctx *sta_ctx;
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530167 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_NDP_ALLOWED;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700168
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530169 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
170 dbgid) {
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700171 switch (adapter->device_mode) {
172 case QDF_P2P_GO_MODE:
173 case QDF_SAP_MODE:
174 if (test_bit(SOFTAP_BSS_STARTED,
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530175 &adapter->event_flags)) {
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530176 hdd_adapter_dev_put_debug(adapter, dbgid);
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530177 if (next_adapter)
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530178 hdd_adapter_dev_put_debug(next_adapter,
179 dbgid);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700180 return false;
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530181 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700182 break;
183 case QDF_P2P_CLIENT_MODE:
184 case QDF_IBSS_MODE:
185 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
186 if (hdd_conn_is_connected(sta_ctx) ||
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530187 hdd_is_connecting(sta_ctx)) {
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530188 hdd_adapter_dev_put_debug(adapter, dbgid);
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530189 if (next_adapter)
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530190 hdd_adapter_dev_put_debug(next_adapter,
191 dbgid);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700192 return false;
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530193 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700194 break;
195 default:
196 break;
197 }
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530198 hdd_adapter_dev_put_debug(adapter, dbgid);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700199 }
200
201 return true;
202}
Wu Gao18596ae2019-08-13 17:33:14 +0800203#endif /* NDP_SAP_CONCURRENCY_ENABLE */
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -0700204
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 */
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700212static int hdd_ndi_start_bss(struct hdd_adapter *adapter,
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700213 uint8_t operating_channel)
214{
Jeff Johnson32833f12018-06-13 20:26:34 -0700215 QDF_STATUS status;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700216 uint32_t roam_id;
Jeff Johnson641839e2018-03-18 14:50:39 -0700217 struct csr_roam_profile *roam_profile;
Jeff Johnson32833f12018-06-13 20:26:34 -0700218 mac_handle_t mac_handle;
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +0530219 uint8_t wmm_mode = 0;
220 struct hdd_context *hdd_ctx;
221 uint8_t value = 0;
wadesong24c869a2019-07-19 17:38:59 +0800222 uint32_t oper_freq;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700223
Dustin Brown491d54b2018-03-14 12:39:11 -0700224 hdd_enter();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700225
Jeff Johnson641839e2018-03-18 14:50:39 -0700226 roam_profile = hdd_roam_profile(adapter);
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +0530227 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700228
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +0530229 status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc, &wmm_mode);
230 if (!QDF_IS_STATUS_SUCCESS(status)) {
231 hdd_err("Get wmm_mode failed");
232 return -EINVAL;
233 }
234
235 if (HDD_WMM_USER_MODE_NO_QOS == wmm_mode) {
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700236 /* QoS not enabled in cfg file*/
237 roam_profile->uapsd_mask = 0;
238 } else {
239 /* QoS enabled, update uapsd mask from cfg file*/
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +0530240 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc, &value);
241 if (!QDF_IS_STATUS_SUCCESS(status)) {
242 hdd_err("Get uapsd_mask failed");
243 return -EINVAL;
244 }
245 roam_profile->uapsd_mask = value;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700246 }
247
248 roam_profile->csrPersona = adapter->device_mode;
249
Naveen Rawat709c0cb2018-03-14 17:04:15 -0700250 if (!operating_channel)
251 operating_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
wadesong24c869a2019-07-19 17:38:59 +0800252 oper_freq = wlan_reg_chan_to_freq(hdd_ctx->pdev, operating_channel);
Naveen Rawat709c0cb2018-03-14 17:04:15 -0700253
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700254 roam_profile->ChannelInfo.numOfChannels = 1;
wadesong24c869a2019-07-19 17:38:59 +0800255 roam_profile->ChannelInfo.freq_list = &oper_freq;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700256
257 roam_profile->SSIDs.numOfSSIDs = 1;
258 roam_profile->SSIDs.SSIDList->SSID.length = 0;
259
260 roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
261 roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
262 roam_profile->BSSIDs.numOfBSSIDs = 1;
263 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
Jeff Johnson1e851a12017-10-28 14:36:12 -0700264 &adapter->mac_addr.bytes[0],
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700265 QDF_MAC_ADDR_SIZE);
266
267 roam_profile->AuthType.numEntries = 1;
268 roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
269 roam_profile->EncryptionType.numEntries = 1;
270 roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
271
Jeff Johnson32833f12018-06-13 20:26:34 -0700272 mac_handle = hdd_adapter_get_mac_handle(adapter);
Jeff Johnson9597f3b2019-02-04 14:27:56 -0800273 status = sme_roam_connect(mac_handle, adapter->vdev_id,
Jeff Johnson32833f12018-06-13 20:26:34 -0700274 roam_profile, &roam_id);
275 if (QDF_IS_STATUS_ERROR(status)) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700276 hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
Jeff Johnson9597f3b2019-02-04 14:27:56 -0800277 adapter->vdev_id, status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700278 /* change back to NotConnected */
279 hdd_conn_set_connection_state(adapter,
Jeff Johnson32833f12018-06-13 20:26:34 -0700280 eConnectionState_NotConnected);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700281 } else {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700282 hdd_info("sme_RoamConnect issued successfully for NDI");
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700283 }
284
wadesong24c869a2019-07-19 17:38:59 +0800285 roam_profile->ChannelInfo.freq_list = NULL;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700286 roam_profile->ChannelInfo.numOfChannels = 0;
287
Dustin Browne74003f2018-03-14 12:51:58 -0700288 hdd_exit();
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700289
Jeff Johnson32833f12018-06-13 20:26:34 -0700290 return 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700291}
292
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700293/**
294 * hdd_get_random_nan_mac_addr() - generate random non pre-existent mac address
295 * @hdd_ctx: hdd context pointer
296 * @mac_addr: mac address buffer to populate
297 *
298 * Return: status of operation
299 */
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700300static int hdd_get_random_nan_mac_addr(struct hdd_context *hdd_ctx,
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700301 struct qdf_mac_addr *mac_addr)
302{
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700303 struct hdd_adapter *adapter;
Naveen Rawatea1ece82018-02-09 14:22:52 -0800304 uint8_t pos, bit_pos, byte_pos, mask;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700305 uint8_t i, attempts, max_attempt = 16;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +0530306 bool found;
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700307
308 for (attempts = 0; attempts < max_attempt; attempts++) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +0530309 found = false;
Naveen Rawatea1ece82018-02-09 14:22:52 -0800310 /* if NDI is present next addr is required to be 1 bit apart */
311 adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
312 if (adapter) {
313 hdd_debug("NDI already exists, deriving next mac");
314 qdf_mem_copy(mac_addr, &adapter->mac_addr,
315 sizeof(*mac_addr));
Jeff Johnson51a80522018-12-11 20:19:44 -0800316 qdf_get_random_bytes(&pos, sizeof(pos));
Naveen Rawatea1ece82018-02-09 14:22:52 -0800317 /* skipping byte 0, 5 leaves 8*4=32 positions */
318 pos = pos % 32;
319 bit_pos = pos % 8;
320 byte_pos = pos / 8;
321 mask = 1 << bit_pos;
322 /* flip the required bit */
323 mac_addr->bytes[byte_pos + 1] ^= mask;
324 } else {
Jeff Johnson51a80522018-12-11 20:19:44 -0800325 qdf_get_random_bytes(mac_addr, sizeof(*mac_addr));
Naveen Rawatea1ece82018-02-09 14:22:52 -0800326 /*
327 * Reset multicast bit (bit-0) and set
328 * locally-administered bit
329 */
330 mac_addr->bytes[0] = 0x2;
Ravi Joshi04a1c992017-06-11 19:47:54 -0700331
Naveen Rawatea1ece82018-02-09 14:22:52 -0800332 /*
333 * to avoid potential conflict with FW's generated NMI
334 * mac addr, host sets LSB if 6th byte to 0
335 */
336 mac_addr->bytes[5] &= 0xFE;
337 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +0530338 for (i = 0; i < hdd_ctx->num_provisioned_addr; i++) {
339 if ((!qdf_mem_cmp(hdd_ctx->
340 provisioned_mac_addr[i].bytes,
341 mac_addr, sizeof(*mac_addr)))) {
342 found = true;
343 break;
344 }
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700345 }
346
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +0530347 if (found)
348 continue;
349
350 for (i = 0; i < hdd_ctx->num_derived_addr; i++) {
351 if ((!qdf_mem_cmp(hdd_ctx->
352 derived_mac_addr[i].bytes,
353 mac_addr, sizeof(*mac_addr)))) {
354 found = true;
355 break;
356 }
357 }
358 if (found)
359 continue;
360
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700361 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
362 if (!adapter)
363 return 0;
364 }
365
366 hdd_err("unable to get non-pre-existing mac address in %d attempts",
367 max_attempt);
368
369 return -EINVAL;
370}
371
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700372void hdd_ndp_event_handler(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -0800373 struct csr_roam_info *roam_info,
374 uint32_t roam_id, eRoamCmdStatus roam_status,
375 eCsrRoamResult roam_result)
Naveen Rawat97500352017-03-22 10:07:58 -0700376{
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700377 bool success;
Dustin Brown89fa06e2018-09-07 10:47:27 -0700378 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(adapter->vdev);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700379
380 if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
381 switch (roam_result) {
382 case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
383 success = (roam_info->ndp.ndi_create_params.status ==
384 NAN_DATAPATH_RSP_STATUS_SUCCESS);
Srinivas Dasarie1898462020-03-16 18:33:29 +0530385 hdd_debug("posting ndi create status: %d (%s) to umac",
386 success, success ? "Success" : "Failure");
Jeff Johnson9597f3b2019-02-04 14:27:56 -0800387 os_if_nan_post_ndi_create_rsp(psoc, adapter->vdev_id,
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700388 success);
389 return;
390 case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
391 success = (roam_info->ndp.ndi_create_params.status ==
392 NAN_DATAPATH_RSP_STATUS_SUCCESS);
Srinivas Dasarie1898462020-03-16 18:33:29 +0530393 hdd_debug("posting ndi delete status: %d (%s) to umac",
394 success, success ? "Success" : "Failure");
Jeff Johnson9597f3b2019-02-04 14:27:56 -0800395 os_if_nan_post_ndi_delete_rsp(psoc, adapter->vdev_id,
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700396 success);
397 return;
398 default:
399 hdd_err("in correct roam_result: %d", roam_result);
400 return;
401 }
402 } else {
403 hdd_err("in correct roam_status: %d", roam_status);
404 return;
405 }
Naveen Rawat97500352017-03-22 10:07:58 -0700406}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700407
408/**
409 * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
410 * @wiphy: pointer to wireless wiphy structure.
411 * @wdev: pointer to wireless_dev structure.
412 * @data: Pointer to the data to be passed via vendor interface
413 * @data_len:Length of the data to be passed
414 *
415 * This function is invoked to handle vendor command
416 *
417 * Return: 0 on success, negative errno on failure
418 */
Naveen Rawat63de5422017-03-22 11:03:56 -0700419static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
420 struct wireless_dev *wdev, const void *data, int data_len)
421{
422 int ret_val;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700423 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Naveen Rawat63de5422017-03-22 11:03:56 -0700424
Naveen Rawat63de5422017-03-22 11:03:56 -0700425 ret_val = wlan_hdd_validate_context(hdd_ctx);
426 if (ret_val)
427 return ret_val;
428
429 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Rajeev Kumar3872a5b2018-10-02 11:47:38 -0700430 hdd_err_rl("Command not allowed in FTM mode");
Naveen Rawat63de5422017-03-22 11:03:56 -0700431 return -EPERM;
432 }
433
434 if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
Srinivas Dasari20bc5c62020-01-27 16:16:42 +0530435 hdd_debug("NAN datapath is not enabled");
Naveen Rawat63de5422017-03-22 11:03:56 -0700436 return -EPERM;
437 }
Naveen Rawat63de5422017-03-22 11:03:56 -0700438
Srinivas Dasari0610cc42019-10-29 18:23:54 +0530439 return os_if_nan_process_ndp_cmd(hdd_ctx->psoc, data, data_len,
440 hdd_is_ndp_allowed(hdd_ctx));
Naveen Rawat63de5422017-03-22 11:03:56 -0700441}
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700442
443/**
444 * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
445 * @wiphy: pointer to wireless wiphy structure.
446 * @wdev: pointer to wireless_dev structure.
447 * @data: Pointer to the data to be passed via vendor interface
448 * @data_len:Length of the data to be passed
449 *
450 * This function is called to send a NAN request to
451 * firmware. This is an SSR-protected wrapper function.
452 *
453 * Return: 0 on success, negative errno on failure
454 */
455int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
Dustin Brown0d17e012019-02-20 10:21:17 -0800456 struct wireless_dev *wdev,
457 const void *data, int data_len)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700458{
Dustin Brown0d17e012019-02-20 10:21:17 -0800459 /* This call is intentionally not protected by op_start/op_stop, due to
460 * the various protection needs of the callbacks dispatched within.
461 */
462 return __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev,
463 data, data_len);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700464}
465
Jeff Johnson85b5c112017-08-11 15:15:23 -0700466static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700467{
Dustin Brown89fa06e2018-09-07 10:47:27 -0700468 return os_if_nan_set_ndi_state(adapter->vdev, state);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700469}
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700470
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700471/**
472 * hdd_init_nan_data_mode() - initialize nan data mode
473 * @adapter: adapter context
474 *
475 * Returns: 0 on success negative error code on error
476 */
Jeff Johnson85b5c112017-08-11 15:15:23 -0700477int hdd_init_nan_data_mode(struct hdd_adapter *adapter)
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700478{
479 struct net_device *wlan_dev = adapter->dev;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700480 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700481 QDF_STATUS status;
Jeff Johnson32833f12018-06-13 20:26:34 -0700482 int32_t ret_val;
483 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +0530484 bool bval = false;
Qun Zhang1b3c85c2019-08-27 16:31:49 +0800485 uint8_t enable_sifs_burst = 0;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700486
Arun Kumar Khandavalli42b44872019-10-21 19:02:04 +0530487 ret_val = hdd_vdev_create(adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -0700488 if (ret_val) {
489 hdd_err("failed to create vdev: %d", ret_val);
490 return ret_val;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700491 }
492
Jeff Johnson32833f12018-06-13 20:26:34 -0700493 mac_handle = hdd_ctx->mac_handle;
494
Ravi Joshi8eb65f92017-07-20 16:30:19 -0700495 /* Configure self HT/VHT capabilities */
Jeff Johnson32833f12018-06-13 20:26:34 -0700496 sme_set_curr_device_mode(mac_handle, adapter->device_mode);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +0530497
498 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
499 if (!QDF_IS_STATUS_SUCCESS(status))
500 hdd_err("unable to get vht_enable2x2");
501
502 sme_set_pdev_ht_vht_ies(mac_handle, bval);
Kiran Kumar Lokere46ca7d72020-08-20 19:36:39 -0700503 sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id,
504 adapter->device_mode);
Ravi Joshi8eb65f92017-07-20 16:30:19 -0700505
Jeff Johnson7f2c5912018-03-23 11:42:28 -0700506 hdd_roam_profile_init(adapter);
507 hdd_register_wext(wlan_dev);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700508
509 status = hdd_init_tx_rx(adapter);
510 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700511 hdd_err("hdd_init_tx_rx() init failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700512 ret_val = -EAGAIN;
513 goto error_init_txrx;
514 }
515
516 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
517
518 status = hdd_wmm_adapter_init(adapter);
519 if (QDF_STATUS_SUCCESS != status) {
Naveen Rawatba4f6612016-07-05 12:03:16 -0700520 hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700521 ret_val = -EAGAIN;
522 goto error_wmm_init;
523 }
524
525 set_bit(WMM_INIT_DONE, &adapter->event_flags);
526
Qun Zhang1b3c85c2019-08-27 16:31:49 +0800527 status = ucfg_get_enable_sifs_burst(hdd_ctx->psoc, &enable_sifs_burst);
528 if (!QDF_IS_STATUS_SUCCESS(status))
529 hdd_err("Failed to get sifs burst value, use default");
530
Jeff Johnson9597f3b2019-02-04 14:27:56 -0800531 ret_val = wma_cli_set_command((int)adapter->vdev_id,
Qun Zhang1b3c85c2019-08-27 16:31:49 +0800532 (int)WMI_PDEV_PARAM_BURST_ENABLE,
533 enable_sifs_burst,
534 PDEV_CMD);
Arunk Khandavalli15664e42017-06-29 15:56:14 +0530535 if (0 != ret_val)
Naveen Rawatba4f6612016-07-05 12:03:16 -0700536 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Arunk Khandavalli15664e42017-06-29 15:56:14 +0530537
Mohit Khannad42aad82020-05-21 17:03:46 -0700538 hdd_set_netdev_flags(adapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700539
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700540 update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700541 return ret_val;
542
543error_wmm_init:
544 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
545 hdd_deinit_tx_rx(adapter);
546
547error_init_txrx:
548 hdd_unregister_wext(wlan_dev);
549
Dustin Brownd28772b2017-03-17 14:16:07 -0700550 QDF_BUG(!hdd_vdev_destroy(adapter));
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700551
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700552 return ret_val;
553}
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700554
Naveen Rawat23a3b912018-05-30 17:45:52 -0700555int hdd_ndi_open(char *iface_name)
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700556{
Abdul Muqtadeer Ahmed6a082c62021-01-07 17:19:48 +0530557 struct hdd_adapter *adapter, *next_adapter = NULL;
Ravi Joshi9771d432017-06-26 13:58:12 -0700558 struct qdf_mac_addr random_ndi_mac;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700559 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Nachiket Kukade413c5fa2019-02-19 17:57:19 +0530560 uint8_t ndi_adapter_count = 0;
Ravi Joshi9771d432017-06-26 13:58:12 -0700561 uint8_t *ndi_mac_addr;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700562
Dustin Brown491d54b2018-03-14 12:39:11 -0700563 hdd_enter();
Naveen Rawatf9391622017-12-20 17:06:01 -0800564 if (!hdd_ctx) {
565 hdd_err("hdd_ctx null");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700566 return -EINVAL;
Naveen Rawatf9391622017-12-20 17:06:01 -0800567 }
568
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530569 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
570 NET_DEV_HOLD_NDI_OPEN) {
Nachiket Kukade413c5fa2019-02-19 17:57:19 +0530571 if (WLAN_HDD_IS_NDI(adapter))
572 ndi_adapter_count++;
Bapiraju Alla797b21b2020-11-23 13:44:21 +0530573 hdd_adapter_dev_put_debug(adapter, NET_DEV_HOLD_NDI_OPEN);
Nachiket Kukade413c5fa2019-02-19 17:57:19 +0530574 }
575 if (ndi_adapter_count >= MAX_NDI_ADAPTERS) {
576 hdd_err("Can't allow more than %d NDI adapters",
577 MAX_NDI_ADAPTERS);
578 return -EINVAL;
579 }
580
Dustin Brown05d81302018-09-11 16:49:22 -0700581 if (cfg_nan_get_ndi_mac_randomize(hdd_ctx->psoc)) {
Ravi Joshi9771d432017-06-26 13:58:12 -0700582 if (hdd_get_random_nan_mac_addr(hdd_ctx, &random_ndi_mac)) {
583 hdd_err("get random mac address failed");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700584 return -EFAULT;
Ravi Joshi9771d432017-06-26 13:58:12 -0700585 }
586 ndi_mac_addr = &random_ndi_mac.bytes[0];
587 } else {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +0530588 ndi_mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NDI_MODE);
Ravi Joshi9771d432017-06-26 13:58:12 -0700589 if (!ndi_mac_addr) {
590 hdd_err("get intf address failed");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700591 return -EFAULT;
Ravi Joshi9771d432017-06-26 13:58:12 -0700592 }
Naveen Rawat5a6f8402017-07-03 16:00:11 -0700593 }
594
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700595 adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
Ravi Joshi9771d432017-06-26 13:58:12 -0700596 ndi_mac_addr, NET_NAME_UNKNOWN, true);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700597 if (!adapter) {
Li Fengad3d7422020-04-12 21:35:42 +0800598 if (!cfg_nan_get_ndi_mac_randomize(hdd_ctx->psoc))
599 wlan_hdd_release_intf_addr(hdd_ctx, ndi_mac_addr);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700600 hdd_err("hdd_open_adapter failed");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700601 return -EINVAL;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700602 }
603
Dustin Browne74003f2018-03-14 12:51:58 -0700604 hdd_exit();
Naveen Rawat23a3b912018-05-30 17:45:52 -0700605 return 0;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700606}
607
Naveen Rawat23a3b912018-05-30 17:45:52 -0700608int hdd_ndi_start(char *iface_name, uint16_t transaction_id)
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700609{
Naveen Rawat23a3b912018-05-30 17:45:52 -0700610 int ret;
Naveen Rawat23a3b912018-05-30 17:45:52 -0700611 QDF_STATUS status;
Nachiket Kukadec1bba2f2018-12-11 12:07:09 +0530612 uint8_t op_channel;
Naveen Rawatf9391622017-12-20 17:06:01 -0800613 struct hdd_adapter *adapter;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700614 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700615
Dustin Brown491d54b2018-03-14 12:39:11 -0700616 hdd_enter();
Naveen Rawatf9391622017-12-20 17:06:01 -0800617 if (!hdd_ctx) {
618 hdd_err("hdd_ctx is null");
619 return -EINVAL;
620 }
621
Naveen Rawat23a3b912018-05-30 17:45:52 -0700622 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, iface_name);
Naveen Rawatf9391622017-12-20 17:06:01 -0800623 if (!adapter) {
624 hdd_err("adapter is null");
625 return -EINVAL;
626 }
627
Naveen Rawat23a3b912018-05-30 17:45:52 -0700628 /* create nan vdev */
629 status = hdd_init_nan_data_mode(adapter);
630 if (QDF_STATUS_SUCCESS != status) {
631 hdd_err("failed to init nan data intf, status :%d", status);
632 ret = -EFAULT;
633 goto err_handler;
634 }
635
636 /*
637 * Create transaction id is required to be saved since the firmware
638 * does not honor the transaction id for create request
639 */
Dustin Brown89fa06e2018-09-07 10:47:27 -0700640 ucfg_nan_set_ndp_create_transaction_id(adapter->vdev,
Naveen Rawat23a3b912018-05-30 17:45:52 -0700641 transaction_id);
Dustin Brown89fa06e2018-09-07 10:47:27 -0700642 ucfg_nan_set_ndi_state(adapter->vdev,
Naveen Rawat23a3b912018-05-30 17:45:52 -0700643 NAN_DATA_NDI_CREATING_STATE);
644
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700645 /*
646 * The NAN data interface has been created at this point.
647 * Unlike traditional device modes, where the higher application
648 * layer initiates connect / join / start, the NAN data
649 * interface does not have any such formal requests. The NDI
650 * create request is responsible for starting the BSS as well.
Nachiket Kukadec1bba2f2018-12-11 12:07:09 +0530651 * Use the 5GHz Band NAN Social channel for BSS start if target
652 * supports it, since a 2.4GHz channel will require a DBS HW mode change
653 * first on a DBS 2x2 MAC target. Use a 2.4 GHz Band NAN Social channel
654 * if the target is not 5GHz capable.
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700655 */
Nachiket Kukadec1bba2f2018-12-11 12:07:09 +0530656
657 if (hdd_is_5g_supported(hdd_ctx))
658 op_channel = NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND;
659 else
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700660 op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
Naveen Rawat23a3b912018-05-30 17:45:52 -0700661
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700662 if (hdd_ndi_start_bss(adapter, op_channel)) {
663 hdd_err("NDI start bss failed");
Naveen Rawat23a3b912018-05-30 17:45:52 -0700664 ret = -EFAULT;
665 goto err_handler;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700666 }
667
Dustin Browne74003f2018-03-14 12:51:58 -0700668 hdd_exit();
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700669 return 0;
Naveen Rawat23a3b912018-05-30 17:45:52 -0700670
671err_handler:
672
673 /* Start BSS failed, delete the interface */
674 hdd_close_ndi(adapter);
675 return ret;
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700676}
677
678int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id)
679{
680 int ret;
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700681 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -0700682 struct hdd_station_ctx *sta_ctx;
Jeff Johnson88dc4f92017-08-28 11:51:34 -0700683 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700684
Naveen Rawatf9391622017-12-20 17:06:01 -0800685 if (!hdd_ctx) {
686 hdd_err("hdd_ctx is null");
687 return -EINVAL;
688 }
689
Naveen Rawatc4b045c2017-06-30 16:11:42 -0700690 /* check if adapter by vdev_id is valid NDI */
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700691 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
692 if (!adapter || !WLAN_HDD_IS_NDI(adapter)) {
693 hdd_err("NAN data interface %s is not available", iface_name);
694 return -EINVAL;
695 }
696
697 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
698 if (!sta_ctx) {
699 hdd_err("sta_ctx is NULL");
700 return -EINVAL;
701 }
702
Dustin Brown89fa06e2018-09-07 10:47:27 -0700703 os_if_nan_set_ndp_delete_transaction_id(adapter->vdev,
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700704 transaction_id);
Dustin Brown89fa06e2018-09-07 10:47:27 -0700705 os_if_nan_set_ndi_state(adapter->vdev, NAN_DATA_NDI_DELETING_STATE);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700706
707 /* Delete the interface */
708 ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
709 if (ret)
710 hdd_err("NDI delete request failed");
711 else
712 hdd_err("NDI delete request successfully issued");
713
714 return ret;
715}
716
717void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id,
718 struct nan_datapath_inf_create_rsp *ndi_rsp)
719{
Naveen Rawatf9391622017-12-20 17:06:01 -0800720 struct hdd_context *hdd_ctx;
721 struct hdd_adapter *adapter;
722 struct hdd_station_ctx *sta_ctx;
Min Liu3621ede2018-11-07 18:36:00 +0800723 struct csr_roam_info *roam_info;
Jeff Johnson4ba73cb2017-10-06 11:12:33 -0700724 struct bss_description tmp_bss_descp = {0};
Sourav Mohapatra3f02b6a2019-09-06 14:38:53 +0530725 uint16_t ndp_inactivity_timeout = 0;
Ashish Kumar Dhanotiyab3ae6462020-02-06 14:41:21 +0530726 uint16_t ndp_keep_alive_period;
Dustin Brownce5b3d32018-01-17 15:07:38 -0800727 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BCAST_INIT;
Naveen Rawatf9391622017-12-20 17:06:01 -0800728
729 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
730 if (!hdd_ctx) {
731 hdd_err("hdd_ctx is null");
732 return;
733 }
734
735 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
736 if (!adapter) {
737 hdd_err("adapter is null");
738 return;
739 }
740
741 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
742 if (!sta_ctx) {
743 hdd_err("sta_ctx is null");
744 return;
745 }
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700746
Min Liu3621ede2018-11-07 18:36:00 +0800747 roam_info = qdf_mem_malloc(sizeof(*roam_info));
748 if (!roam_info)
749 return;
750
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700751 if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
752 hdd_alert("NDI interface successfully created");
Dustin Brown89fa06e2018-09-07 10:47:27 -0700753 os_if_nan_set_ndp_create_transaction_id(adapter->vdev, 0);
754 os_if_nan_set_ndi_state(adapter->vdev,
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700755 NAN_DATA_NDI_CREATED_STATE);
756 wlan_hdd_netif_queue_control(adapter,
757 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
758 WLAN_CONTROL_PATH);
Sourav Mohapatra3f02b6a2019-09-06 14:38:53 +0530759
760 if (QDF_IS_STATUS_ERROR(cfg_nan_get_ndp_inactivity_timeout(
761 hdd_ctx->psoc, &ndp_inactivity_timeout)))
762 hdd_err("Failed to fetch inactivity timeout value");
763
764 sme_cli_set_command(adapter->vdev_id,
765 WMI_VDEV_PARAM_NDP_INACTIVITY_TIMEOUT,
766 ndp_inactivity_timeout, VDEV_CMD);
Ashish Kumar Dhanotiyab3ae6462020-02-06 14:41:21 +0530767
768 if (QDF_IS_STATUS_SUCCESS(cfg_nan_get_ndp_keepalive_period(
769 hdd_ctx->psoc,
770 &ndp_keep_alive_period)))
771 sme_cli_set_command(
772 adapter->vdev_id,
773 WMI_VDEV_PARAM_NDP_KEEPALIVE_TIMEOUT,
774 ndp_keep_alive_period, VDEV_CMD);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700775 } else {
776 hdd_alert("NDI interface creation failed with reason %d",
777 ndi_rsp->reason /* create_reason */);
778 }
779
Sourav Mohapatraa3cf12a2019-08-19 15:40:49 +0530780 hdd_save_peer(sta_ctx, &bc_mac_addr);
Bala Venkateshb184b772019-08-21 19:54:04 +0530781 qdf_copy_macaddr(&roam_info->bssid, &bc_mac_addr);
Sourav Mohapatraa3cf12a2019-08-19 15:40:49 +0530782 hdd_roam_register_sta(adapter, roam_info, &tmp_bss_descp);
Rajeev Kumar Sirasanagandla7172b492019-06-10 19:42:28 +0530783
Min Liu3621ede2018-11-07 18:36:00 +0800784 qdf_mem_free(roam_info);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700785}
786
787void hdd_ndi_close(uint8_t vdev_id)
788{
Naveen Rawatf9391622017-12-20 17:06:01 -0800789 struct hdd_context *hdd_ctx;
790 struct hdd_adapter *adapter;
791
792 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
793 if (!hdd_ctx) {
794 hdd_err("hdd_ctx is null");
795 return;
796 }
797
798 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
799 if (!adapter) {
800 hdd_err("adapter is null");
801 return;
802 }
Jeff Johnson4f7f7c62017-10-05 08:53:41 -0700803
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700804 hdd_close_ndi(adapter);
805}
806
807void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id)
808{
Naveen Rawatf9391622017-12-20 17:06:01 -0800809 struct hdd_context *hdd_ctx;
810 struct hdd_adapter *adapter;
811 struct hdd_station_ctx *sta_ctx;
Rajeev Kumar Sirasanagandlad320ac42019-11-11 10:49:18 -0800812 struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BCAST_INIT;
Naveen Rawatf9391622017-12-20 17:06:01 -0800813
814 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
815 if (!hdd_ctx) {
816 hdd_err("hdd_ctx is null");
817 return;
818 }
819
820 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
821 if (!adapter) {
822 hdd_err("adapter is null");
823 return;
824 }
825
826 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
827 if (!sta_ctx) {
828 hdd_err("sta_ctx is null");
829 return;
830 }
Naveen Rawatb7be1ed2017-11-16 16:52:08 -0800831
Rajeev Kumar Sirasanagandlad320ac42019-11-11 10:49:18 -0800832 hdd_delete_peer(sta_ctx, &bc_mac_addr);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700833
834 wlan_hdd_netif_queue_control(adapter,
835 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
836 WLAN_CONTROL_PATH);
837
Abhishek Ambure650f9922020-01-10 12:05:49 +0530838 /*
839 * For NAN Data interface, the close session results in the final
840 * indication to the userspace
841 */
842 if (adapter->device_mode == QDF_NDI_MODE)
843 hdd_ndp_session_end_handler(adapter);
844
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700845 complete(&adapter->disconnect_comp_var);
846}
847
Jeff Johnson8cb9df12017-08-29 14:28:45 -0700848void hdd_ndp_session_end_handler(struct hdd_adapter *adapter)
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700849{
Dustin Brown89fa06e2018-09-07 10:47:27 -0700850 os_if_nan_ndi_session_end(adapter->vdev);
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700851}
852
Naveen Rawat37f62c82017-03-26 22:24:43 -0700853/**
854 * hdd_ndp_new_peer_handler() - NDP new peer indication handler
855 * @adapter: pointer to adapter context
856 * @ind_params: indication parameters
857 *
858 * Return: none
859 */
860int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id,
861 struct qdf_mac_addr *peer_mac_addr, bool fist_peer)
862{
Naveen Rawatf9391622017-12-20 17:06:01 -0800863 struct hdd_context *hdd_ctx;
864 struct hdd_adapter *adapter;
865 struct hdd_station_ctx *sta_ctx;
Jeff Johnson4ba73cb2017-10-06 11:12:33 -0700866 struct bss_description tmp_bss_descp = {0};
Min Liu3621ede2018-11-07 18:36:00 +0800867 struct csr_roam_info *roam_info;
Naveen Rawat37f62c82017-03-26 22:24:43 -0700868
Naveen Rawatf9391622017-12-20 17:06:01 -0800869 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
870 if (!hdd_ctx) {
871 hdd_err("hdd_ctx is null");
872 return -EINVAL;
873 }
874
875 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
876 if (!adapter) {
877 hdd_err("adapter is null");
878 return -EINVAL;
879 }
880
881 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
882 if (!sta_ctx) {
883 hdd_err("sta_ctx is null");
884 return -EINVAL;
885 }
886
Naveen Rawat37f62c82017-03-26 22:24:43 -0700887 /* save peer in ndp ctx */
Sourav Mohapatraa3cf12a2019-08-19 15:40:49 +0530888 if (!hdd_save_peer(sta_ctx, peer_mac_addr)) {
Naveen Rawat37f62c82017-03-26 22:24:43 -0700889 hdd_err("Ndp peer table full. cannot save new peer");
890 return -EPERM;
891 }
892
Min Liu3621ede2018-11-07 18:36:00 +0800893 roam_info = qdf_mem_malloc(sizeof(*roam_info));
894 if (!roam_info)
895 return -ENOMEM;
Wu Gaocef8a742019-10-16 20:51:02 +0800896 qdf_copy_macaddr(&roam_info->bssid, peer_mac_addr);
Min Liu3621ede2018-11-07 18:36:00 +0800897
Naveen Rawat37f62c82017-03-26 22:24:43 -0700898 /* this function is called for each new peer */
Sourav Mohapatraa3cf12a2019-08-19 15:40:49 +0530899 hdd_roam_register_sta(adapter, roam_info, &tmp_bss_descp);
900
901 qdf_copy_macaddr(&roam_info->bssid, peer_mac_addr);
902
Naveen Rawat37f62c82017-03-26 22:24:43 -0700903 /* perform following steps for first new peer ind */
904 if (fist_peer) {
Srinivas Dasarie1898462020-03-16 18:33:29 +0530905 hdd_debug("Set ctx connection state to connected");
Karthik Kantamneni3d1f2a82020-12-02 20:30:08 +0530906 /* Disable LRO/GRO for NDI Mode */
907 if (hdd_ctx->ol_enable &&
908 !ucfg_is_nan_dbs_supported(hdd_ctx->psoc)) {
909 hdd_debug("Disable LRO/GRO in NDI Mode");
910 hdd_disable_rx_ol_in_concurrency(true);
911 }
912
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +0530913 hdd_bus_bw_compute_prev_txrx_stats(adapter);
914 hdd_bus_bw_compute_timer_start(hdd_ctx);
Jeff Johnsone7951512019-02-27 10:02:51 -0800915 sta_ctx->conn_info.conn_state = eConnectionState_NdiConnected;
Min Liu3621ede2018-11-07 18:36:00 +0800916 hdd_wmm_connect(adapter, roam_info, eCSR_BSS_TYPE_NDI);
Jinwei Chen08260c62020-09-01 10:52:48 +0800917 wlan_hdd_netif_queue_control(
918 adapter,
919 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
920 WLAN_CONTROL_PATH);
Naveen Rawat37f62c82017-03-26 22:24:43 -0700921 }
Min Liu3621ede2018-11-07 18:36:00 +0800922 qdf_mem_free(roam_info);
Naveen Rawat37f62c82017-03-26 22:24:43 -0700923 return 0;
924}
925
Srinivas Dasari2b424612020-03-04 17:55:16 +0530926void hdd_cleanup_ndi(struct hdd_context *hdd_ctx,
927 struct hdd_adapter *adapter)
928{
929 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
930
931 if (sta_ctx->conn_info.conn_state != eConnectionState_NdiConnected) {
932 hdd_debug("NDI has no NDPs");
933 return;
934 }
935 sta_ctx->conn_info.conn_state = eConnectionState_NdiDisconnected;
936 hdd_conn_set_connection_state(adapter,
937 eConnectionState_NdiDisconnected);
Srinivas Dasarie1898462020-03-16 18:33:29 +0530938 hdd_debug("Stop netif tx queues.");
Jinwei Chen08260c62020-09-01 10:52:48 +0800939 wlan_hdd_netif_queue_control(adapter,
940 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Srinivas Dasari2b424612020-03-04 17:55:16 +0530941 WLAN_CONTROL_PATH);
942 hdd_bus_bw_compute_reset_prev_txrx_stats(adapter);
943 hdd_bus_bw_compute_timer_try_stop(hdd_ctx);
Karthik Kantamneni3d1f2a82020-12-02 20:30:08 +0530944 if ((hdd_ctx->ol_enable &&
945 !ucfg_is_nan_dbs_supported(hdd_ctx->psoc)) &&
946 ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 0) ||
947 ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 1) &&
948 (policy_mgr_mode_specific_connection_count(
949 hdd_ctx->psoc,
950 PM_STA_MODE,
951 NULL) == 1)))) {
952 hdd_debug("Enable LRO/GRO");
953 hdd_disable_rx_ol_in_concurrency(false);
954 }
Srinivas Dasari2b424612020-03-04 17:55:16 +0530955}
956
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700957/**
958 * hdd_ndp_peer_departed_handler() - Handle NDP peer departed indication
959 * @adapter: pointer to adapter context
960 * @ind_params: indication parameters
961 *
962 * Return: none
963 */
964void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id,
965 struct qdf_mac_addr *peer_mac_addr, bool last_peer)
966{
Naveen Rawatf9391622017-12-20 17:06:01 -0800967 struct hdd_context *hdd_ctx;
968 struct hdd_adapter *adapter;
969 struct hdd_station_ctx *sta_ctx;
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700970
Naveen Rawatf9391622017-12-20 17:06:01 -0800971 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
972 if (!hdd_ctx) {
973 hdd_err("hdd_ctx is null");
974 return;
975 }
976
977 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
978 if (!adapter) {
979 hdd_err("adapter is null");
980 return;
981 }
982
983 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
984 if (!sta_ctx) {
985 hdd_err("sta_ctx is null");
986 return;
987 }
988
Rajeev Kumar Sirasanagandlad320ac42019-11-11 10:49:18 -0800989 hdd_delete_peer(sta_ctx, peer_mac_addr);
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700990
991 if (last_peer) {
Srinivas Dasarie1898462020-03-16 18:33:29 +0530992 hdd_debug("No more ndp peers.");
Srinivas Dasari2b424612020-03-04 17:55:16 +0530993 hdd_cleanup_ndi(hdd_ctx, adapter);
Srinivas Dasari766d2022020-04-21 20:06:14 +0530994 qdf_event_set(&adapter->peer_cleanup_done);
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700995 }
Naveen Rawatb3143ea2017-03-26 22:25:46 -0700996}