xref: /wlan-driver/qcacld-3.0/os_if/tdls/src/wlan_cfg80211_tdls.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: defines driver functions interfacing with linux kernel
22  */
23 
24 #include <qdf_list.h>
25 #include <qdf_status.h>
26 #include <linux/wireless.h>
27 #include <linux/netdevice.h>
28 #include <net/cfg80211.h>
29 #include <wlan_cfg80211.h>
30 #include <wlan_cfg80211_tdls.h>
31 #include <wlan_osif_priv.h>
32 #include <wlan_tdls_public_structs.h>
33 #include <wlan_tdls_ucfg_api.h>
34 #include <qdf_mem.h>
35 #include <wlan_utility.h>
36 #include <wlan_reg_services_api.h>
37 #include "wlan_cfg80211_mc_cp_stats.h"
38 #include "sir_api.h"
39 #include "wlan_tdls_ucfg_api.h"
40 #include "wlan_cm_roam_api.h"
41 #include "wlan_mlo_mgr_sta.h"
42 #include "wlan_hdd_main.h"
43 #include "wlan_hdd_object_manager.h"
44 
wlan_cfg80211_tdls_validate_mac_addr(const uint8_t * mac)45 static int wlan_cfg80211_tdls_validate_mac_addr(const uint8_t *mac)
46 {
47 	static const uint8_t temp_mac[QDF_MAC_ADDR_SIZE] = {0};
48 
49 	if (!qdf_mem_cmp(mac, temp_mac, QDF_MAC_ADDR_SIZE)) {
50 		osif_debug("Invalid Mac address " QDF_MAC_ADDR_FMT
51 			   " cmd declined.",
52 			   QDF_MAC_ADDR_REF(mac));
53 		return -EINVAL;
54 	}
55 
56 	return 0;
57 }
58 
wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev * vdev)59 QDF_STATUS wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev *vdev)
60 {
61 	struct osif_tdls_vdev *tdls_priv;
62 	struct vdev_osif_priv *osif_priv;
63 
64 	osif_priv = wlan_vdev_get_ospriv(vdev);
65 	if (!osif_priv) {
66 		osif_err("osif_priv is NULL!");
67 		return QDF_STATUS_E_FAULT;
68 	}
69 
70 	osif_debug("initialize tdls os if layer private structure");
71 	tdls_priv = qdf_mem_malloc(sizeof(*tdls_priv));
72 	if (!tdls_priv)
73 		return QDF_STATUS_E_NOMEM;
74 
75 	init_completion(&tdls_priv->tdls_add_peer_comp);
76 	init_completion(&tdls_priv->tdls_del_peer_comp);
77 	init_completion(&tdls_priv->tdls_mgmt_comp);
78 	init_completion(&tdls_priv->tdls_link_establish_req_comp);
79 	init_completion(&tdls_priv->tdls_teardown_comp);
80 	init_completion(&tdls_priv->tdls_user_cmd_comp);
81 	init_completion(&tdls_priv->tdls_antenna_switch_comp);
82 
83 	osif_priv->osif_tdls = tdls_priv;
84 
85 	return QDF_STATUS_SUCCESS;
86 }
87 
wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev * vdev)88 void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
89 {
90 	struct vdev_osif_priv *osif_priv;
91 
92 	osif_priv = wlan_vdev_get_ospriv(vdev);
93 	if (!osif_priv) {
94 		osif_err("osif_priv is NULL!");
95 		return;
96 	}
97 
98 	osif_debug("deinitialize tdls os if layer private structure");
99 	if (osif_priv->osif_tdls)
100 		qdf_mem_free(osif_priv->osif_tdls);
101 	osif_priv->osif_tdls = NULL;
102 }
103 
hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev * vdev)104 void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev)
105 {
106 	ucfg_tdls_notify_reset_adapter(vdev);
107 }
108 
wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev * vdev,const uint8_t * mac)109 static int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
110 				       const uint8_t *mac)
111 {
112 	struct tdls_add_peer_params *add_peer_req;
113 	int status;
114 	struct vdev_osif_priv *osif_priv;
115 	struct osif_tdls_vdev *tdls_priv;
116 	unsigned long rc;
117 
118 	status = wlan_cfg80211_tdls_validate_mac_addr(mac);
119 
120 	if (status)
121 		return status;
122 
123 	osif_debug("Add TDLS peer " QDF_MAC_ADDR_FMT,
124 		   QDF_MAC_ADDR_REF(mac));
125 
126 	add_peer_req = qdf_mem_malloc(sizeof(*add_peer_req));
127 	if (!add_peer_req)
128 		return -EINVAL;
129 
130 	osif_priv = wlan_vdev_get_ospriv(vdev);
131 	if (!osif_priv || !osif_priv->osif_tdls) {
132 		osif_err("osif_tdls_vdev or osif_priv is NULL for the current vdev");
133 		status = -EINVAL;
134 		goto error;
135 	}
136 	tdls_priv = osif_priv->osif_tdls;
137 	add_peer_req->vdev_id = wlan_vdev_get_id(vdev);
138 
139 	qdf_mem_copy(add_peer_req->peer_addr, mac, QDF_MAC_ADDR_SIZE);
140 
141 	reinit_completion(&tdls_priv->tdls_add_peer_comp);
142 	status = ucfg_tdls_add_peer(vdev, add_peer_req);
143 	if (QDF_IS_STATUS_ERROR(status)) {
144 		osif_err("ucfg_tdls_add_peer returned err %d", status);
145 		status = -EIO;
146 		goto error;
147 	}
148 
149 	rc = wait_for_completion_timeout(
150 	    &tdls_priv->tdls_add_peer_comp,
151 	    msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
152 	if (!rc) {
153 		osif_err("timeout for tdls add peer indication %ld", rc);
154 		status = -EPERM;
155 		goto error;
156 	}
157 
158 	if (QDF_IS_STATUS_ERROR(tdls_priv->tdls_add_peer_status)) {
159 		osif_err("tdls add peer failed, status:%d",
160 			 tdls_priv->tdls_add_peer_status);
161 		status = -EPERM;
162 	}
163 error:
164 	qdf_mem_free(add_peer_req);
165 	return status;
166 }
167 
wlan_cfg80211_tdls_add_peer_mlo(struct hdd_adapter * adapter,const uint8_t * mac,uint8_t link_id)168 int wlan_cfg80211_tdls_add_peer_mlo(struct hdd_adapter *adapter,
169 				    const uint8_t *mac, uint8_t link_id)
170 {
171 	struct wlan_objmgr_vdev *vdev;
172 	bool is_mlo_vdev;
173 	int status;
174 
175 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_TDLS_ID);
176 	if (!vdev)
177 		return -EINVAL;
178 
179 	if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) {
180 		osif_debug("sta is not connected or disconnecting");
181 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
182 		return -EINVAL;
183 	}
184 
185 	is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
186 	if (is_mlo_vdev) {
187 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
188 
189 		vdev = wlan_key_get_link_vdev(adapter, WLAN_OSIF_TDLS_ID,
190 					      link_id);
191 		if (!vdev)
192 			return -EINVAL;
193 
194 		if (!ucfg_tdls_link_vdev_is_matching(vdev)) {
195 			wlan_key_put_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
196 			return -EINVAL;
197 		}
198 
199 		osif_debug("tdls add peer for vdev %d", wlan_vdev_get_id(vdev));
200 		status = wlan_cfg80211_tdls_add_peer(vdev, mac);
201 		wlan_key_put_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
202 	} else {
203 		status = wlan_cfg80211_tdls_add_peer(vdev, mac);
204 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
205 	}
206 
207 	return status;
208 }
209 
210 static bool
is_duplicate_freq(qdf_freq_t * arr,uint8_t index,qdf_freq_t freq)211 is_duplicate_freq(qdf_freq_t *arr, uint8_t index, qdf_freq_t freq)
212 {
213 	int i;
214 
215 	for (i = 0; i < index; i++) {
216 		if (arr[i] == freq)
217 			return true;
218 	}
219 	return false;
220 }
221 
222 static uint8_t
tdls_fill_chan_freq_from_supported_ch_list(struct wlan_objmgr_pdev * pdev,const uint8_t * country,const uint8_t * src_chans,uint8_t src_chan_num,uint8_t src_opclass,uint8_t * num_freq,qdf_freq_t * freq_lst)223 tdls_fill_chan_freq_from_supported_ch_list(struct wlan_objmgr_pdev *pdev,
224 					   const uint8_t *country,
225 					   const uint8_t *src_chans,
226 					   uint8_t src_chan_num,
227 					   uint8_t src_opclass,
228 					   uint8_t *num_freq,
229 					   qdf_freq_t *freq_lst)
230 {
231 	uint8_t i = 0, j = 0, num_unique_freq = *num_freq;
232 	uint8_t chan_count;
233 	uint8_t wifi_chan_index;
234 	uint8_t next_ch;
235 	qdf_freq_t freq;
236 
237 	for (i = 0; i < src_chan_num &&
238 	     num_unique_freq < WLAN_MAC_MAX_SUPP_CHANNELS; i += 2) {
239 		freq = wlan_reg_country_chan_opclass_to_freq(pdev, country,
240 							     src_chans[i],
241 							     src_opclass,
242 							     false);
243 
244 		if (!freq || is_duplicate_freq(freq_lst, num_unique_freq, freq))
245 			continue;
246 
247 		if (wlan_reg_is_6ghz_chan_freq(freq) &&
248 		    !wlan_reg_is_6ghz_psc_chan_freq(freq)) {
249 			osif_debug("skipping non-psc channel %d", freq);
250 			continue;
251 		}
252 
253 		chan_count = src_chans[i + 1];
254 		wifi_chan_index = ((src_chans[i] <= WLAN_CHANNEL_14) ? 1 : 4);
255 		freq_lst[num_unique_freq] = freq;
256 		num_unique_freq++;
257 		next_ch = src_chans[i];
258 		osif_debug("freq %d index %d ", freq, num_unique_freq);
259 
260 		for (j = 1; j < chan_count &&
261 		     num_unique_freq < WLAN_MAC_MAX_SUPP_CHANNELS; j++) {
262 			next_ch += wifi_chan_index;
263 			freq = wlan_reg_country_chan_opclass_to_freq(
264 							pdev, country, next_ch,
265 							src_opclass, false);
266 
267 			if (!freq ||
268 			    is_duplicate_freq(freq_lst, num_unique_freq, freq))
269 				continue;
270 
271 			if (wlan_reg_is_6ghz_chan_freq(freq) &&
272 			    !wlan_reg_is_6ghz_psc_chan_freq(freq)) {
273 				osif_debug("skipping non-psc channel %d", freq);
274 				continue;
275 			}
276 
277 			freq_lst[num_unique_freq] = freq;
278 			osif_debug("freq %d index %d ", freq, num_unique_freq);
279 			num_unique_freq++;
280 
281 			if (num_unique_freq > NUM_CHANNELS) {
282 				osif_debug("num_unique_freq more than max num");
283 				break;
284 			}
285 		}
286 	}
287 	*num_freq = num_unique_freq;
288 
289 	return num_unique_freq;
290 }
291 
292 static void
tdls_calc_channels_from_staparams(struct wlan_objmgr_vdev * vdev,struct tdls_update_peer_params * req_info,struct station_parameters * params)293 tdls_calc_channels_from_staparams(struct wlan_objmgr_vdev *vdev,
294 				  struct tdls_update_peer_params *req_info,
295 				  struct station_parameters *params)
296 {
297 	uint8_t i = 0;
298 	uint8_t num_unique_freq = 0;
299 	const uint8_t *src_chans, *src_opclass;
300 	qdf_freq_t *dest_freq;
301 	uint8_t country[REG_ALPHA2_LEN + 1];
302 	QDF_STATUS status;
303 	struct wlan_objmgr_pdev *pdev;
304 
305 	if (!vdev) {
306 		osif_err("null vdev");
307 		return;
308 	}
309 
310 	pdev = wlan_vdev_get_pdev(vdev);
311 	if (!pdev) {
312 		osif_err("null pdev");
313 		return;
314 	}
315 	src_chans = params->supported_channels;
316 	src_opclass = params->supported_oper_classes;
317 	dest_freq = req_info->supported_chan_freq;
318 	pdev = wlan_vdev_get_pdev(vdev);
319 	status = wlan_cm_get_country_code(pdev, wlan_vdev_get_id(vdev),
320 					  country);
321 
322 	osif_debug("Country info from AP:%c%c 0x%x", country[0],
323 		   country[1], country[2]);
324 
325 	for (i = 0; i < params->supported_oper_classes_len; i++)
326 		tdls_fill_chan_freq_from_supported_ch_list(
327 						pdev, country, src_chans,
328 						params->supported_channels_len,
329 						src_opclass[i],
330 						&num_unique_freq,
331 						dest_freq);
332 
333 	osif_debug("Unique Channel List: supported_channels ");
334 	for (i = 0; i < num_unique_freq; i++)
335 		osif_debug(" %d,", dest_freq[i]);
336 
337 	req_info->supported_channels_len = num_unique_freq;
338 	osif_debug("After removing duplcates supported_channels_len: %d",
339 		   req_info->supported_channels_len);
340 }
341 
342 #ifdef WLAN_FEATURE_11AX
343 #if defined(WLAN_LINK_STA_PARAMS_PRESENT) && defined(CONFIG_BAND_6GHZ)
344 static void
wlan_cfg80211_tdls_extract_6ghz_params(struct tdls_update_peer_params * req_info,struct station_parameters * params)345 wlan_cfg80211_tdls_extract_6ghz_params(struct tdls_update_peer_params *req_info,
346 				       struct station_parameters *params)
347 {
348 	if (!params->link_sta_params.he_6ghz_capa) {
349 		osif_debug("6 Ghz he_capa not present");
350 		return;
351 	}
352 
353 	qdf_mem_copy(&req_info->he_6ghz_cap,
354 		     params->link_sta_params.he_6ghz_capa,
355 		     sizeof(req_info->he_6ghz_cap));
356 }
357 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && defined(CONFIG_BAND_6GHZ)
358 static void
wlan_cfg80211_tdls_extract_6ghz_params(struct tdls_update_peer_params * req_info,struct station_parameters * params)359 wlan_cfg80211_tdls_extract_6ghz_params(struct tdls_update_peer_params *req_info,
360 				       struct station_parameters *params)
361 {
362 	if (!params->he_6ghz_capa) {
363 		osif_debug("6 Ghz he_capa not present");
364 		return;
365 	}
366 
367 	qdf_mem_copy(&req_info->he_6ghz_cap, params->he_6ghz_capa,
368 		     sizeof(req_info->he_6ghz_cap));
369 }
370 #else
371 static void
wlan_cfg80211_tdls_extract_6ghz_params(struct tdls_update_peer_params * req_info,struct station_parameters * params)372 wlan_cfg80211_tdls_extract_6ghz_params(struct tdls_update_peer_params *req_info,
373 				       struct station_parameters *params)
374 {
375 	osif_debug("kernel don't support tdls 6 ghz band");
376 }
377 #endif
378 
379 #ifdef WLAN_LINK_STA_PARAMS_PRESENT
380 static void
wlan_cfg80211_tdls_extract_he_params(struct tdls_update_peer_params * req_info,struct station_parameters * params,bool tdls_6g_support)381 wlan_cfg80211_tdls_extract_he_params(struct tdls_update_peer_params *req_info,
382 				     struct station_parameters *params,
383 				     bool tdls_6g_support)
384 {
385 	if (params->link_sta_params.he_capa_len < MIN_TDLS_HE_CAP_LEN) {
386 		osif_debug("he_capa_len %d less than MIN_TDLS_HE_CAP_LEN",
387 			   params->link_sta_params.he_capa_len);
388 		return;
389 	}
390 
391 	if (!params->link_sta_params.he_capa) {
392 		osif_debug("he_capa not present");
393 		return;
394 	}
395 
396 	req_info->he_cap_len = params->link_sta_params.he_capa_len;
397 	if (req_info->he_cap_len > MAX_TDLS_HE_CAP_LEN)
398 		req_info->he_cap_len = MAX_TDLS_HE_CAP_LEN;
399 
400 	qdf_mem_copy(&req_info->he_cap, params->link_sta_params.he_capa,
401 		     req_info->he_cap_len);
402 
403 	if (tdls_6g_support)
404 		wlan_cfg80211_tdls_extract_6ghz_params(req_info, params);
405 }
406 #else
407 static void
wlan_cfg80211_tdls_extract_he_params(struct tdls_update_peer_params * req_info,struct station_parameters * params,bool tdls_6g_support)408 wlan_cfg80211_tdls_extract_he_params(struct tdls_update_peer_params *req_info,
409 				     struct station_parameters *params,
410 				     bool tdls_6g_support)
411 {
412 	if (params->he_capa_len < MIN_TDLS_HE_CAP_LEN) {
413 		osif_debug("he_capa_len %d less than MIN_TDLS_HE_CAP_LEN",
414 			   params->he_capa_len);
415 		return;
416 	}
417 
418 	if (!params->he_capa) {
419 		osif_debug("he_capa not present");
420 		return;
421 	}
422 
423 	req_info->he_cap_len = params->he_capa_len;
424 	if (req_info->he_cap_len > MAX_TDLS_HE_CAP_LEN)
425 		req_info->he_cap_len = MAX_TDLS_HE_CAP_LEN;
426 
427 	qdf_mem_copy(&req_info->he_cap, params->he_capa,
428 		     req_info->he_cap_len);
429 
430 	if (tdls_6g_support)
431 		wlan_cfg80211_tdls_extract_6ghz_params(req_info, params);
432 }
433 #endif
434 #else
435 static inline void
wlan_cfg80211_tdls_extract_he_params(struct tdls_update_peer_params * req_info,struct station_parameters * params,bool tdls_6g_support)436 wlan_cfg80211_tdls_extract_he_params(struct tdls_update_peer_params *req_info,
437 				     struct station_parameters *params,
438 				     bool tdls_6g_support)
439 {
440 }
441 #endif
442 
443 #ifdef WLAN_FEATURE_11BE
444 #ifdef WLAN_LINK_STA_PARAMS_PRESENT
445 static void
wlan_cfg80211_tdls_extract_eht_params(struct tdls_update_peer_params * req_info,struct station_parameters * params)446 wlan_cfg80211_tdls_extract_eht_params(struct tdls_update_peer_params *req_info,
447 				      struct station_parameters *params)
448 {
449 	if (params->link_sta_params.eht_capa) {
450 		osif_debug("eht capa is present");
451 		req_info->ehtcap_present = 1;
452 		req_info->eht_cap_len = params->link_sta_params.eht_capa_len;
453 		qdf_mem_copy(&req_info->eht_cap,
454 			     params->link_sta_params.eht_capa,
455 			     sizeof(struct ehtcap));
456 	} else {
457 		req_info->ehtcap_present = 0;
458 	}
459 }
460 #elif defined(WLAN_EHT_CAPABILITY_PRESENT)
461 static void
wlan_cfg80211_tdls_extract_eht_params(struct tdls_update_peer_params * req_info,struct station_parameters * params)462 wlan_cfg80211_tdls_extract_eht_params(struct tdls_update_peer_params *req_info,
463 				      struct station_parameters *params)
464 {
465 	if (params->eht_capa) {
466 		osif_debug("eht capa is present");
467 		req_info->ehtcap_present = 1;
468 		req_info->eht_cap_len = params->eht_capa_len;
469 		qdf_mem_copy(&req_info->eht_cap, params->eht_capa,
470 			     sizeof(struct ehtcap));
471 	} else {
472 		req_info->ehtcap_present = 0;
473 	}
474 }
475 #else
476 static inline void
wlan_cfg80211_tdls_extract_eht_params(struct tdls_update_peer_params * req_info,struct station_parameters * params)477 wlan_cfg80211_tdls_extract_eht_params(struct tdls_update_peer_params *req_info,
478 				      struct station_parameters *params)
479 {
480 }
481 #endif
482 #else
483 static inline void
wlan_cfg80211_tdls_extract_eht_params(struct tdls_update_peer_params * req_info,struct station_parameters * params)484 wlan_cfg80211_tdls_extract_eht_params(struct tdls_update_peer_params *req_info,
485 				      struct station_parameters *params)
486 {
487 }
488 #endif
489 
490 #ifdef WLAN_LINK_STA_PARAMS_PRESENT
491 static void
wlan_cfg80211_tdls_extract_params(struct wlan_objmgr_vdev * vdev,struct tdls_update_peer_params * req_info,struct station_parameters * params,bool tdls_11ax_support,bool tdls_6g_support)492 wlan_cfg80211_tdls_extract_params(struct wlan_objmgr_vdev *vdev,
493 				  struct tdls_update_peer_params *req_info,
494 				  struct station_parameters *params,
495 				  bool tdls_11ax_support, bool tdls_6g_support)
496 {
497 	int i;
498 
499 	osif_debug("sta cap %d, uapsd_queue %d, max_sp %d",
500 		   params->capability,
501 		   params->uapsd_queues, params->max_sp);
502 
503 	if (!req_info) {
504 		osif_err("reg_info is NULL");
505 		return;
506 	}
507 	req_info->capability = params->capability;
508 	req_info->uapsd_queues = params->uapsd_queues;
509 	req_info->max_sp = params->max_sp;
510 
511 	if (params->supported_oper_classes_len > WLAN_MAX_SUPP_OPER_CLASSES) {
512 		osif_debug("received oper classes:%d, resetting it to max supported: %d",
513 			   params->supported_oper_classes_len,
514 			   WLAN_MAX_SUPP_OPER_CLASSES);
515 		params->supported_oper_classes_len = WLAN_MAX_SUPP_OPER_CLASSES;
516 	}
517 
518 	qdf_mem_copy(req_info->supported_oper_classes,
519 		     params->supported_oper_classes,
520 		     params->supported_oper_classes_len);
521 	req_info->supported_oper_classes_len =
522 		params->supported_oper_classes_len;
523 
524 	if (params->supported_channels_len)
525 		tdls_calc_channels_from_staparams(vdev, req_info, params);
526 
527 	if (params->ext_capab_len)
528 		qdf_mem_copy(req_info->extn_capability, params->ext_capab,
529 			     sizeof(req_info->extn_capability));
530 
531 	if (params->link_sta_params.ht_capa) {
532 		req_info->htcap_present = 1;
533 		qdf_mem_copy(&req_info->ht_cap, params->link_sta_params.ht_capa,
534 			     sizeof(struct htcap_cmn_ie));
535 	}
536 
537 	req_info->supported_rates_len =
538 				params->link_sta_params.supported_rates_len;
539 
540 	/* Note: The Maximum size of supported_rates sent by the Supplicant is
541 	 * 32. The supported_rates array, for all the structures propagating
542 	 * until Add Sta to the firmware, has to be modified if the supplicant
543 	 * (ieee80211) is modified to send more rates.
544 	 */
545 
546 	/* To avoid Data Corruption, set to max length to SIR_MAC_MAX_SUPP_RATES
547 	 */
548 	if (req_info->supported_rates_len > WLAN_MAC_MAX_SUPP_RATES)
549 		req_info->supported_rates_len = WLAN_MAC_MAX_SUPP_RATES;
550 
551 	if (req_info->supported_rates_len) {
552 		qdf_mem_copy(req_info->supported_rates,
553 			     params->link_sta_params.supported_rates,
554 			     req_info->supported_rates_len);
555 		osif_debug("Supported Rates with Length %d",
556 			   req_info->supported_rates_len);
557 
558 		for (i = 0; i < req_info->supported_rates_len; i++)
559 			osif_debug("[%d]: %0x", i,
560 				   req_info->supported_rates[i]);
561 	}
562 
563 	if (params->link_sta_params.vht_capa) {
564 		req_info->vhtcap_present = 1;
565 		qdf_mem_copy(&req_info->vht_cap,
566 			     params->link_sta_params.vht_capa,
567 			     sizeof(struct vhtcap));
568 	}
569 
570 	if (params->link_sta_params.ht_capa ||
571 	    params->link_sta_params.vht_capa ||
572 	    (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
573 		req_info->is_qos_wmm_sta = true;
574 	if (params->sta_flags_set & BIT(NL80211_STA_FLAG_MFP)) {
575 		osif_debug("TDLS peer pmf capable");
576 		req_info->is_pmf = 1;
577 	}
578 	if (tdls_11ax_support)
579 		wlan_cfg80211_tdls_extract_he_params(req_info, params,
580 						     tdls_6g_support);
581 	else
582 		osif_debug("tdls ax disabled");
583 
584 	wlan_cfg80211_tdls_extract_eht_params(req_info, params);
585 }
586 #else
587 static void
wlan_cfg80211_tdls_extract_params(struct wlan_objmgr_vdev * vdev,struct tdls_update_peer_params * req_info,struct station_parameters * params,bool tdls_11ax_support,bool tdls_6g_support)588 wlan_cfg80211_tdls_extract_params(struct wlan_objmgr_vdev *vdev,
589 				  struct tdls_update_peer_params *req_info,
590 				  struct station_parameters *params,
591 				  bool tdls_11ax_support, bool tdls_6g_support)
592 {
593 	int i;
594 
595 	osif_debug("sta cap %d, uapsd_queue %d, max_sp %d",
596 		   params->capability,
597 		   params->uapsd_queues, params->max_sp);
598 
599 	if (!req_info) {
600 		osif_err("reg_info is NULL");
601 		return;
602 	}
603 	req_info->capability = params->capability;
604 	req_info->uapsd_queues = params->uapsd_queues;
605 	req_info->max_sp = params->max_sp;
606 
607 	if (params->supported_oper_classes_len > WLAN_MAX_SUPP_OPER_CLASSES) {
608 		osif_debug("received oper classes:%d, resetting it to max supported: %d",
609 			   params->supported_oper_classes_len,
610 			   WLAN_MAX_SUPP_OPER_CLASSES);
611 		params->supported_oper_classes_len = WLAN_MAX_SUPP_OPER_CLASSES;
612 	}
613 
614 	qdf_mem_copy(req_info->supported_oper_classes,
615 		     params->supported_oper_classes,
616 		     params->supported_oper_classes_len);
617 	req_info->supported_oper_classes_len =
618 		params->supported_oper_classes_len;
619 
620 	if (params->supported_channels_len)
621 		tdls_calc_channels_from_staparams(vdev, req_info, params);
622 
623 	if (params->ext_capab_len)
624 		qdf_mem_copy(req_info->extn_capability, params->ext_capab,
625 			     sizeof(req_info->extn_capability));
626 
627 	if (params->ht_capa) {
628 		req_info->htcap_present = 1;
629 		qdf_mem_copy(&req_info->ht_cap, params->ht_capa,
630 			     sizeof(struct htcap_cmn_ie));
631 	}
632 
633 	req_info->supported_rates_len = params->supported_rates_len;
634 
635 	/* Note : The Maximum sizeof supported_rates sent by the Supplicant is
636 	 * 32. The supported_rates array , for all the structures propagating
637 	 * till Add Sta to the firmware has to be modified , if the supplicant
638 	 * (ieee80211) is modified to send more rates.
639 	 */
640 
641 	/* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
642 	 */
643 	if (req_info->supported_rates_len > WLAN_MAC_MAX_SUPP_RATES)
644 		req_info->supported_rates_len = WLAN_MAC_MAX_SUPP_RATES;
645 
646 	if (req_info->supported_rates_len) {
647 		qdf_mem_copy(req_info->supported_rates,
648 			     params->supported_rates,
649 			     req_info->supported_rates_len);
650 		osif_debug("Supported Rates with Length %d",
651 			   req_info->supported_rates_len);
652 
653 		for (i = 0; i < req_info->supported_rates_len; i++)
654 			osif_debug("[%d]: %0x", i,
655 				   req_info->supported_rates[i]);
656 	}
657 
658 	if (params->vht_capa) {
659 		req_info->vhtcap_present = 1;
660 		qdf_mem_copy(&req_info->vht_cap, params->vht_capa,
661 			     sizeof(struct vhtcap));
662 	}
663 
664 	if (params->ht_capa || params->vht_capa ||
665 	    (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
666 		req_info->is_qos_wmm_sta = true;
667 	if (params->sta_flags_set & BIT(NL80211_STA_FLAG_MFP)) {
668 		osif_debug("TDLS peer pmf capable");
669 		req_info->is_pmf = 1;
670 	}
671 	if (tdls_11ax_support)
672 		wlan_cfg80211_tdls_extract_he_params(req_info, params,
673 						     tdls_6g_support);
674 	else
675 		osif_debug("tdls ax disabled");
676 
677 	wlan_cfg80211_tdls_extract_eht_params(req_info, params);
678 }
679 #endif
680 
wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev * vdev,const uint8_t * mac,struct station_parameters * params)681 int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
682 				   const uint8_t *mac,
683 				   struct station_parameters *params)
684 {
685 	struct tdls_update_peer_params *req_info;
686 	int status;
687 	struct vdev_osif_priv *osif_priv;
688 	struct osif_tdls_vdev *tdls_priv;
689 	unsigned long rc;
690 	struct wlan_objmgr_psoc *psoc;
691 	bool tdls_11ax_support = false;
692 	bool tdls_6g_support = false;
693 	bool is_mlo_vdev;
694 
695 	status = wlan_cfg80211_tdls_validate_mac_addr(mac);
696 
697 	if (status)
698 		return status;
699 
700 	osif_debug("Update TDLS peer " QDF_MAC_ADDR_FMT,
701 		   QDF_MAC_ADDR_REF(mac));
702 
703 	is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
704 	if (is_mlo_vdev) {
705 		vdev = ucfg_tdls_get_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
706 		if (!vdev) {
707 			osif_err("no tdls link vdev");
708 			return -EINVAL;
709 		}
710 	}
711 
712 	psoc = wlan_vdev_get_psoc(vdev);
713 	if (!psoc) {
714 		osif_err_rl("Invalid psoc");
715 		goto relref;
716 	}
717 
718 	req_info = qdf_mem_malloc(sizeof(*req_info));
719 	if (!req_info) {
720 		status = -EINVAL;
721 		goto relref;
722 	}
723 
724 	tdls_11ax_support = ucfg_tdls_is_fw_11ax_capable(psoc);
725 	tdls_6g_support = ucfg_tdls_is_fw_6g_capable(psoc);
726 	wlan_cfg80211_tdls_extract_params(vdev, req_info, params,
727 					  tdls_11ax_support,
728 					  tdls_6g_support);
729 
730 	osif_priv = wlan_vdev_get_ospriv(vdev);
731 	if (!osif_priv || !osif_priv->osif_tdls) {
732 		osif_err("osif priv or tdls priv is NULL");
733 		status = -EINVAL;
734 		goto error;
735 	}
736 	tdls_priv = osif_priv->osif_tdls;
737 	req_info->vdev_id = wlan_vdev_get_id(vdev);
738 	qdf_mem_copy(req_info->peer_addr, mac, QDF_MAC_ADDR_SIZE);
739 
740 	reinit_completion(&tdls_priv->tdls_add_peer_comp);
741 	status = ucfg_tdls_update_peer(vdev, req_info);
742 	if (QDF_IS_STATUS_ERROR(status)) {
743 		osif_err("ucfg_tdls_update_peer returned err %d", status);
744 		status = -EIO;
745 		goto error;
746 	}
747 
748 	rc = wait_for_completion_timeout(
749 		&tdls_priv->tdls_add_peer_comp,
750 		msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
751 	if (!rc) {
752 		osif_err("timeout for tdls update peer indication %ld", rc);
753 		status = -EPERM;
754 		goto error;
755 	}
756 
757 	if (QDF_IS_STATUS_ERROR(tdls_priv->tdls_add_peer_status)) {
758 		osif_err("tdls update peer failed, status:%d",
759 			 tdls_priv->tdls_add_peer_status);
760 		status = -EPERM;
761 	}
762 error:
763 	qdf_mem_free(req_info);
764 relref:
765 	if (is_mlo_vdev)
766 		ucfg_tdls_put_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
767 	return status;
768 }
769 
tdls_oper_to_str(enum nl80211_tdls_operation oper)770 static char *tdls_oper_to_str(enum nl80211_tdls_operation oper)
771 {
772 	switch (oper) {
773 	case NL80211_TDLS_ENABLE_LINK:
774 		return "TDLS_ENABLE_LINK";
775 	case NL80211_TDLS_DISABLE_LINK:
776 		return "TDLS_DISABLE_LINK";
777 	case NL80211_TDLS_TEARDOWN:
778 		return "TDLS_TEARDOWN";
779 	case NL80211_TDLS_SETUP:
780 		return "TDLS_SETUP";
781 	default:
782 		return "UNKNOWN:ERR";
783 	}
784 }
785 
tdls_oper_to_cmd(enum nl80211_tdls_operation oper)786 static enum tdls_command_type tdls_oper_to_cmd(enum nl80211_tdls_operation oper)
787 {
788 	if (oper == NL80211_TDLS_ENABLE_LINK)
789 		return TDLS_CMD_ENABLE_LINK;
790 	else if (oper == NL80211_TDLS_DISABLE_LINK)
791 		return TDLS_CMD_DISABLE_LINK;
792 	else if (oper == NL80211_TDLS_TEARDOWN)
793 		return TDLS_CMD_REMOVE_FORCE_PEER;
794 	else if (oper == NL80211_TDLS_SETUP)
795 		return TDLS_CMD_CONFIG_FORCE_PEER;
796 	else
797 		return 0;
798 }
799 
wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev * vdev,uint32_t trigger_mode)800 int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev,
801 						uint32_t trigger_mode)
802 {
803 	enum tdls_feature_mode tdls_mode;
804 	struct tdls_set_mode_params set_mode_params;
805 	int status;
806 
807 	if (!vdev)
808 		return -EINVAL;
809 
810 	switch (trigger_mode) {
811 	case WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT:
812 		tdls_mode = TDLS_SUPPORT_EXP_TRIG_ONLY;
813 		return 0;
814 	case WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL:
815 		tdls_mode = TDLS_SUPPORT_EXT_CONTROL;
816 		break;
817 	case WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT:
818 		tdls_mode = TDLS_SUPPORT_IMP_MODE;
819 		return 0;
820 	default:
821 		osif_err("Invalid TDLS trigger mode");
822 		return -EINVAL;
823 	}
824 
825 	osif_notice("cfg80211 tdls trigger mode %d", trigger_mode);
826 	set_mode_params.source = TDLS_SET_MODE_SOURCE_USER;
827 	set_mode_params.tdls_mode = tdls_mode;
828 	set_mode_params.update_last = false;
829 	set_mode_params.vdev = vdev;
830 
831 	status = ucfg_tdls_set_operating_mode(&set_mode_params);
832 	return status;
833 }
834 
wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev * vdev,const uint8_t * peer,enum nl80211_tdls_operation oper)835 int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev,
836 			    const uint8_t *peer,
837 			    enum nl80211_tdls_operation oper)
838 {
839 	struct vdev_osif_priv *osif_priv;
840 	struct osif_tdls_vdev *tdls_priv;
841 	int status;
842 	unsigned long rc;
843 	enum tdls_command_type cmd;
844 	bool is_mlo_vdev;
845 
846 	status = wlan_cfg80211_tdls_validate_mac_addr(peer);
847 
848 	if (status)
849 		return status;
850 
851 	if (NL80211_TDLS_DISCOVERY_REQ == oper) {
852 		osif_warn(
853 			"We don't support in-driver setup/teardown/discovery");
854 		return -ENOTSUPP;
855 	}
856 
857 	is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
858 	if (is_mlo_vdev) {
859 		vdev = ucfg_tdls_get_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
860 		if (!vdev) {
861 			osif_err("no tdls link vdev");
862 			return -EINVAL;
863 		}
864 	}
865 
866 	osif_debug("%s start", tdls_oper_to_str(oper));
867 	cmd = tdls_oper_to_cmd(oper);
868 	switch (oper) {
869 	case NL80211_TDLS_ENABLE_LINK:
870 	case NL80211_TDLS_TEARDOWN:
871 	case NL80211_TDLS_SETUP:
872 		status = ucfg_tdls_oper(vdev, peer, cmd);
873 		if (QDF_IS_STATUS_ERROR(status)) {
874 			osif_err("%s fail %d",
875 				 tdls_oper_to_str(oper), status);
876 			status = -EIO;
877 			goto error;
878 		}
879 		break;
880 	case NL80211_TDLS_DISABLE_LINK:
881 		wlan_vdev_mlme_feat_ext2_cap_clear(vdev,
882 						   WLAN_VDEV_FEXT2_MLO_STA_TDLS);
883 
884 		osif_priv = wlan_vdev_get_ospriv(vdev);
885 
886 		if (!osif_priv || !osif_priv->osif_tdls) {
887 			osif_err("osif priv or tdls priv is NULL");
888 			status = -EINVAL;
889 			goto error;
890 		}
891 		tdls_priv = osif_priv->osif_tdls;
892 		reinit_completion(&tdls_priv->tdls_del_peer_comp);
893 		status = ucfg_tdls_oper(vdev, peer, cmd);
894 		if (QDF_IS_STATUS_ERROR(status)) {
895 			osif_err("ucfg_tdls_disable_link fail %d", status);
896 			status = -EIO;
897 			goto error;
898 		}
899 
900 		rc = wait_for_completion_timeout(
901 			&tdls_priv->tdls_del_peer_comp,
902 			msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
903 		if (!rc) {
904 			osif_err("timeout for tdls disable link %ld", rc);
905 			status = -EPERM;
906 		}
907 		break;
908 	default:
909 		osif_err("unsupported event %d", oper);
910 		status = -ENOTSUPP;
911 	}
912 
913 error:
914 	if (is_mlo_vdev)
915 		ucfg_tdls_put_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
916 	return status;
917 }
918 
wlan_cfg80211_tdls_rx_callback(void * user_data,struct tdls_rx_mgmt_frame * rx_frame)919 void wlan_cfg80211_tdls_rx_callback(void *user_data,
920 	struct tdls_rx_mgmt_frame *rx_frame)
921 {
922 	struct wlan_objmgr_psoc *psoc;
923 	struct wlan_objmgr_vdev *vdev, *assoc_vdev;
924 	struct vdev_osif_priv *osif_priv;
925 	struct wireless_dev *wdev;
926 	enum QDF_OPMODE opmode;
927 
928 	psoc = user_data;
929 	if (!psoc) {
930 		osif_err("psoc is null");
931 		return;
932 	}
933 
934 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
935 		rx_frame->vdev_id, WLAN_TDLS_NB_ID);
936 	if (!vdev) {
937 		osif_err("vdev is null");
938 		return;
939 	}
940 
941 	assoc_vdev = vdev;
942 	opmode = wlan_vdev_mlme_get_opmode(vdev);
943 
944 	if ((opmode == QDF_STA_MODE || opmode == QDF_TDLS_MODE) &&
945 	    wlan_vdev_mlme_is_mlo_vdev(vdev)) {
946 		assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
947 		if (!assoc_vdev) {
948 			osif_err("assoc vdev is null");
949 			goto fail;
950 		}
951 	}
952 
953 	osif_priv = wlan_vdev_get_ospriv(assoc_vdev);
954 	if (!osif_priv) {
955 		osif_err("osif_priv is null");
956 		goto fail;
957 	}
958 
959 	wdev = osif_priv->wdev;
960 	if (!wdev) {
961 		osif_err("wdev is null");
962 		goto fail;
963 	}
964 
965 	osif_notice("Indicate frame over nl80211, vdev id:%d, idx:%d",
966 		    rx_frame->vdev_id, wdev->netdev->ifindex);
967 
968 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
969 	cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100,
970 			 rx_frame->buf, rx_frame->frame_len,
971 			 NL80211_RXMGMT_FLAG_ANSWERED);
972 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
973 	cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100,
974 			 rx_frame->buf, rx_frame->frame_len,
975 			 NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC);
976 #else
977 	cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100,
978 			 rx_frame->buf, rx_frame->frame_len, GFP_ATOMIC);
979 #endif /* LINUX_VERSION_CODE */
980 fail:
981 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
982 }
983 
wlan_cfg80211_update_tdls_peers_rssi(struct wlan_objmgr_vdev * vdev)984 static void wlan_cfg80211_update_tdls_peers_rssi(struct wlan_objmgr_vdev *vdev)
985 {
986 	int ret = 0, i;
987 	struct stats_event *rssi_info;
988 	struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
989 
990 	rssi_info = wlan_cfg80211_mc_cp_stats_get_peer_rssi(
991 			vdev, bcast_mac.bytes,
992 			&ret);
993 	if (ret || !rssi_info) {
994 		osif_err("get peer rssi fail");
995 		wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
996 		return;
997 	}
998 
999 	for (i = 0; i < rssi_info->num_peer_stats; i++)
1000 		ucfg_tdls_set_rssi(vdev, rssi_info->peer_stats[i].peer_macaddr,
1001 				   rssi_info->peer_stats[i].peer_rssi);
1002 
1003 	wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
1004 }
1005 
wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev * vdev,char * buf,int buflen)1006 int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
1007 				char *buf, int buflen)
1008 {
1009 	struct vdev_osif_priv *osif_priv;
1010 	struct osif_tdls_vdev *tdls_priv;
1011 	int32_t len;
1012 	QDF_STATUS status;
1013 	unsigned long rc;
1014 
1015 	osif_priv = wlan_vdev_get_ospriv(vdev);
1016 	if (!osif_priv || !osif_priv->osif_tdls) {
1017 		osif_err("osif_tdls_vdev or osif_priv is NULL for the current vdev");
1018 		return -EINVAL;
1019 	}
1020 
1021 	tdls_priv = osif_priv->osif_tdls;
1022 
1023 	/*
1024 	 * We shouldn't use completion_done here for checking for completion
1025 	 * as this will always return false, as tdls_user_cmd_comp.done will
1026 	 * remain in init state always. So, the very first command will also
1027 	 * not work.
1028 	 * In general completion_done is used to check if there are multiple
1029 	 * threads waiting on the complete event that's why it will return true
1030 	 * only when tdls_user_cmd_comp.done is set with complete()
1031 	 * In general completion_done will return true only when
1032 	 * tdls_user_cmd_comp.done is set that will happen in complete().
1033 	 * Also, if there is already a thread waiting for wait_for_completion,
1034 	 * this function will
1035 	 * return true only after the wait timer is over or condition is
1036 	 * met as wait_for_completion will hold out the hold lock and will
1037 	 * will prevent completion_done from returning.
1038 	 * Better to use a flag to determine command condition.
1039 	 */
1040 	if (tdls_priv->tdls_user_cmd_in_progress) {
1041 		osif_err("TDLS user cmd still in progress, reject this one");
1042 		return -EBUSY;
1043 	}
1044 
1045 	tdls_priv->tdls_user_cmd_in_progress = true;
1046 	wlan_cfg80211_update_tdls_peers_rssi(vdev);
1047 
1048 	reinit_completion(&tdls_priv->tdls_user_cmd_comp);
1049 	status = ucfg_tdls_get_all_peers(vdev, buf, buflen);
1050 	if (QDF_IS_STATUS_ERROR(status)) {
1051 		osif_err("ucfg_tdls_get_all_peers failed err %d", status);
1052 		len = scnprintf(buf, buflen,
1053 				"\nucfg_tdls_send_mgmt failed\n");
1054 		goto error_get_tdls_peers;
1055 	}
1056 
1057 	osif_debug("Wait for tdls_user_cmd_comp. Timeout %u ms",
1058 		   WAIT_TIME_FOR_TDLS_USER_CMD);
1059 
1060 	rc = wait_for_completion_timeout(
1061 		&tdls_priv->tdls_user_cmd_comp,
1062 		msecs_to_jiffies(WAIT_TIME_FOR_TDLS_USER_CMD));
1063 
1064 	if (0 == rc) {
1065 		osif_err("TDLS user cmd get all peers timed out rc %ld",
1066 			 rc);
1067 		len = scnprintf(buf, buflen,
1068 				"\nTDLS user cmd get all peers timed out\n");
1069 		goto error_get_tdls_peers;
1070 	}
1071 
1072 	len = tdls_priv->tdls_user_cmd_len;
1073 
1074 error_get_tdls_peers:
1075 	tdls_priv->tdls_user_cmd_in_progress = false;
1076 	return len;
1077 }
1078 
wlan_cfg80211_tdls_is_fw_wideband_capable(struct wlan_objmgr_vdev * vdev)1079 bool wlan_cfg80211_tdls_is_fw_wideband_capable(struct wlan_objmgr_vdev *vdev)
1080 {
1081 	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
1082 
1083 	if (!psoc)
1084 		return false;
1085 
1086 	return ucfg_tdls_is_fw_wideband_capable(psoc);
1087 }
1088 
1089 #ifdef WLAN_FEATURE_11AX
wlan_cfg80211_tdls_is_fw_6ghz_capable(struct wlan_objmgr_vdev * vdev)1090 bool wlan_cfg80211_tdls_is_fw_6ghz_capable(struct wlan_objmgr_vdev *vdev)
1091 {
1092 	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
1093 
1094 	if (!psoc)
1095 		return false;
1096 
1097 	return ucfg_tdls_is_fw_6g_capable(psoc);
1098 }
1099 #endif
1100 
1101 static int
wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev * vdev,const uint8_t * peer_mac,uint8_t action_code,uint8_t dialog_token,uint16_t status_code,uint32_t peer_capability,const uint8_t * buf,size_t len,int link_id)1102 wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev,
1103 			const uint8_t *peer_mac,
1104 			uint8_t action_code, uint8_t dialog_token,
1105 			uint16_t status_code, uint32_t peer_capability,
1106 			const uint8_t *buf, size_t len, int link_id)
1107 {
1108 	struct tdls_action_frame_request mgmt_req;
1109 	struct vdev_osif_priv *osif_priv;
1110 	struct osif_tdls_vdev *tdls_priv;
1111 	int status;
1112 	unsigned long rc;
1113 	struct tdls_set_responder_req set_responder;
1114 
1115 	status = wlan_cfg80211_tdls_validate_mac_addr(peer_mac);
1116 
1117 	if (status)
1118 		return status;
1119 
1120 	osif_priv = wlan_vdev_get_ospriv(vdev);
1121 
1122 	if (!osif_priv || !osif_priv->osif_tdls) {
1123 		osif_err("osif priv or tdls priv is NULL");
1124 		return -EINVAL;
1125 	}
1126 
1127 	tdls_priv = osif_priv->osif_tdls;
1128 
1129 	/* make sure doesn't call send_mgmt() while it is pending */
1130 	if (TDLS_VDEV_MAGIC == tdls_priv->mgmt_tx_completion_status) {
1131 		osif_err(QDF_MAC_ADDR_FMT " action %d couldn't sent, as one is pending. return EBUSY",
1132 			 QDF_MAC_ADDR_REF(peer_mac), action_code);
1133 		return -EBUSY;
1134 	}
1135 
1136 	/* Reset TDLS VDEV magic */
1137 	tdls_priv->mgmt_tx_completion_status = TDLS_VDEV_MAGIC;
1138 
1139 
1140 	/*prepare the request */
1141 
1142 	/* Validate the management Request */
1143 	mgmt_req.chk_frame.action_code = action_code;
1144 	qdf_mem_copy(mgmt_req.chk_frame.peer_mac, peer_mac, QDF_MAC_ADDR_SIZE);
1145 	mgmt_req.chk_frame.dialog_token = dialog_token;
1146 	mgmt_req.chk_frame.action_code = action_code;
1147 	mgmt_req.chk_frame.status_code = status_code;
1148 	mgmt_req.chk_frame.len = len;
1149 
1150 	mgmt_req.vdev = vdev;
1151 	mgmt_req.vdev_id = wlan_vdev_get_id(vdev);
1152 	mgmt_req.session_id = mgmt_req.vdev_id;
1153 	/* populate management req params */
1154 	qdf_mem_copy(mgmt_req.tdls_mgmt.peer_mac.bytes,
1155 		     peer_mac, QDF_MAC_ADDR_SIZE);
1156 	mgmt_req.tdls_mgmt.dialog = dialog_token;
1157 	mgmt_req.tdls_mgmt.frame_type = action_code;
1158 	mgmt_req.tdls_mgmt.len = len;
1159 	mgmt_req.tdls_mgmt.peer_capability = peer_capability;
1160 	mgmt_req.tdls_mgmt.status_code = mgmt_req.chk_frame.status_code;
1161 
1162 	mgmt_req.link_active = false;
1163 	mgmt_req.link_id = link_id;
1164 	/*populate the additional IE's */
1165 	mgmt_req.cmd_buf = buf;
1166 	mgmt_req.len = len;
1167 
1168 	reinit_completion(&tdls_priv->tdls_mgmt_comp);
1169 	status = ucfg_tdls_send_mgmt_frame(&mgmt_req);
1170 	if (QDF_IS_STATUS_ERROR(status)) {
1171 		osif_err("ucfg_tdls_send_mgmt failed err %d", status);
1172 		status = -EIO;
1173 		tdls_priv->mgmt_tx_completion_status = false;
1174 		goto error_mgmt_req;
1175 	}
1176 
1177 	osif_debug("Wait for tdls_mgmt_comp. Timeout %u ms",
1178 		   WAIT_TIME_FOR_TDLS_MGMT);
1179 
1180 	rc = wait_for_completion_timeout(
1181 		&tdls_priv->tdls_mgmt_comp,
1182 		msecs_to_jiffies(WAIT_TIME_FOR_TDLS_MGMT));
1183 
1184 	if ((0 == rc) || (QDF_STATUS_SUCCESS !=
1185 				tdls_priv->mgmt_tx_completion_status)) {
1186 		osif_err("%s rc %ld mgmtTxCompletionStatus %u",
1187 			 !rc ? "Mgmt Tx Completion timed out" :
1188 			 "Mgmt Tx Completion failed",
1189 			 rc, tdls_priv->mgmt_tx_completion_status);
1190 
1191 		tdls_priv->mgmt_tx_completion_status = false;
1192 		status = -EINVAL;
1193 		goto error_mgmt_req;
1194 	}
1195 
1196 	osif_debug("Mgmt Tx Completion status %ld TxCompletion %u",
1197 		   rc, tdls_priv->mgmt_tx_completion_status);
1198 
1199 	if (TDLS_SETUP_RESPONSE == action_code ||
1200 	    TDLS_SETUP_CONFIRM == action_code) {
1201 		qdf_mem_copy(set_responder.peer_mac, peer_mac,
1202 			     QDF_MAC_ADDR_SIZE);
1203 		set_responder.vdev = vdev;
1204 		if (TDLS_SETUP_RESPONSE == action_code)
1205 			set_responder.responder = false;
1206 		if (TDLS_SETUP_CONFIRM == action_code)
1207 			set_responder.responder = true;
1208 		ucfg_tdls_responder(&set_responder);
1209 	}
1210 
1211 error_mgmt_req:
1212 	return status;
1213 }
1214 
1215 int
wlan_cfg80211_tdls_mgmt_mlo(struct hdd_adapter * adapter,const uint8_t * peer,uint8_t action_code,uint8_t dialog_token,uint16_t status_code,uint32_t peer_capability,const uint8_t * buf,size_t len,int link_id)1216 wlan_cfg80211_tdls_mgmt_mlo(struct hdd_adapter *adapter, const uint8_t *peer,
1217 			    uint8_t action_code, uint8_t dialog_token,
1218 			    uint16_t status_code, uint32_t peer_capability,
1219 			    const uint8_t *buf, size_t len, int link_id)
1220 {
1221 	struct wlan_objmgr_vdev *tdls_link_vdev = NULL;
1222 	struct wlan_objmgr_vdev *mlo_vdev = NULL;
1223 	struct wlan_objmgr_vdev *vdev;
1224 	bool is_mlo_vdev;
1225 	bool link_id_vdev = false;
1226 	bool dis_req_more = false;
1227 	uint8_t i;
1228 	int ret = 0;
1229 
1230 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_TDLS_ID);
1231 	if (!vdev)
1232 		return -EINVAL;
1233 
1234 	/* STA should be connected before sending any TDLS frame */
1235 	if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) {
1236 		osif_err("STA is not connected");
1237 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
1238 		return -EAGAIN;
1239 	}
1240 
1241 	is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
1242 	if (is_mlo_vdev) {
1243 		tdls_link_vdev =
1244 			ucfg_tdls_get_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
1245 		if (!tdls_link_vdev) {
1246 			if (action_code == TDLS_DISCOVERY_RESPONSE) {
1247 				hdd_objmgr_put_vdev_by_user(vdev,
1248 							    WLAN_OSIF_TDLS_ID);
1249 				if (link_id < 0) {
1250 					osif_err("link id is invalid");
1251 					return -EINVAL;
1252 				}
1253 				/* Get the candidate vdev per link id */
1254 				link_id_vdev = true;
1255 				vdev = wlan_key_get_link_vdev(adapter,
1256 							      WLAN_OSIF_TDLS_ID,
1257 							      link_id);
1258 				if (!vdev) {
1259 					osif_err("vdev is null");
1260 					return -EINVAL;
1261 				}
1262 			} else if (action_code == TDLS_DISCOVERY_REQUEST) {
1263 				if (ucfg_tdls_discovery_on_going(vdev)) {
1264 					osif_err("discovery request is going");
1265 					hdd_objmgr_put_vdev_by_user(vdev,
1266 							     WLAN_OSIF_TDLS_ID);
1267 					return -EAGAIN;
1268 				}
1269 				dis_req_more = true;
1270 			}
1271 		} else {
1272 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
1273 			vdev = tdls_link_vdev;
1274 		}
1275 	}
1276 
1277 	if (dis_req_more) {
1278 		/* it needs to send discovery request on each vdev */
1279 		for (i = 0 ;  i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
1280 			mlo_vdev = ucfg_tdls_get_mlo_vdev(vdev, i,
1281 							  WLAN_OSIF_TDLS_ID);
1282 			if (!mlo_vdev) {
1283 				osif_err("mlo vdev is NULL");
1284 				continue;
1285 			}
1286 			ret = wlan_cfg80211_tdls_mgmt(mlo_vdev, peer,
1287 						      action_code,
1288 						      dialog_token, status_code,
1289 						      peer_capability, buf, len,
1290 						      link_id);
1291 			ucfg_tdls_release_mlo_vdev(mlo_vdev, WLAN_OSIF_TDLS_ID);
1292 		}
1293 	} else {
1294 		ret = wlan_cfg80211_tdls_mgmt(vdev, peer,
1295 					      action_code, dialog_token,
1296 					      status_code, peer_capability,
1297 					      buf, len, link_id);
1298 	}
1299 
1300 	if (vdev && link_id_vdev)
1301 		wlan_key_put_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
1302 	else if (tdls_link_vdev)
1303 		ucfg_tdls_put_tdls_link_vdev(tdls_link_vdev, WLAN_OSIF_TDLS_ID);
1304 	else
1305 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
1306 
1307 	return ret;
1308 }
1309 
wlan_tdls_antenna_switch(struct wlan_objmgr_vdev * vdev,uint32_t mode)1310 int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode)
1311 {
1312 	struct vdev_osif_priv *osif_priv;
1313 	struct osif_tdls_vdev *tdls_priv;
1314 	int ret;
1315 	unsigned long rc;
1316 
1317 	if (!vdev) {
1318 		osif_err("vdev is NULL");
1319 		return -EAGAIN;
1320 	}
1321 
1322 	osif_priv = wlan_vdev_get_ospriv(vdev);
1323 	if (!osif_priv || !osif_priv->osif_tdls) {
1324 		osif_err("osif priv or tdls priv is NULL");
1325 		ret = -EINVAL;
1326 		goto error;
1327 	}
1328 	tdls_priv = osif_priv->osif_tdls;
1329 
1330 	reinit_completion(&tdls_priv->tdls_antenna_switch_comp);
1331 	ret = ucfg_tdls_antenna_switch(vdev, mode);
1332 	if (QDF_IS_STATUS_ERROR(ret)) {
1333 		osif_err("ucfg_tdls_antenna_switch failed err %d", ret);
1334 		ret = -EAGAIN;
1335 		goto error;
1336 	}
1337 
1338 	rc = wait_for_completion_timeout(
1339 		&tdls_priv->tdls_antenna_switch_comp,
1340 		msecs_to_jiffies(WAIT_TIME_FOR_TDLS_ANTENNA_SWITCH));
1341 	if (!rc) {
1342 		osif_err("timeout for tdls antenna switch %ld", rc);
1343 		ret = -EAGAIN;
1344 		goto error;
1345 	}
1346 
1347 	ret = tdls_priv->tdls_antenna_switch_status;
1348 	osif_debug("tdls antenna switch status:%d", ret);
1349 error:
1350 	return ret;
1351 }
1352 
1353 #ifdef TDLS_MGMT_VERSION5
1354 static void
wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication * ind)1355 wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication *ind)
1356 {
1357 	struct vdev_osif_priv *osif_vdev;
1358 
1359 	osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
1360 
1361 	cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
1362 				   ind->peer_mac, -1,
1363 				   NL80211_TDLS_DISCOVERY_REQ,
1364 				   false, GFP_KERNEL);
1365 }
1366 
1367 static void
wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication * ind)1368 wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication *ind)
1369 {
1370 	struct vdev_osif_priv *osif_vdev;
1371 	int link_id = -1;
1372 
1373 	osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
1374 	if (wlan_vdev_mlme_is_mlo_vdev(ind->vdev))
1375 		link_id = wlan_vdev_get_link_id(ind->vdev);
1376 
1377 	osif_debug("Indication to request TDLS setup on link id %d", link_id);
1378 	cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
1379 				   ind->peer_mac, link_id,
1380 				   NL80211_TDLS_SETUP, false,
1381 				   GFP_KERNEL);
1382 }
1383 
1384 static void
wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication * ind)1385 wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication *ind)
1386 {
1387 	struct vdev_osif_priv *osif_vdev;
1388 
1389 	osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
1390 
1391 	osif_debug("Teardown reason %d", ind->reason);
1392 	cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
1393 				   ind->peer_mac, -1, NL80211_TDLS_TEARDOWN,
1394 				   ind->reason, GFP_KERNEL);
1395 }
1396 #else
1397 static void
wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication * ind)1398 wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication *ind)
1399 {
1400 	struct vdev_osif_priv *osif_vdev;
1401 
1402 	osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
1403 
1404 	cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
1405 				   ind->peer_mac, NL80211_TDLS_DISCOVERY_REQ,
1406 				   false, GFP_KERNEL);
1407 }
1408 
1409 static void
wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication * ind)1410 wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication *ind)
1411 {
1412 	struct vdev_osif_priv *osif_vdev;
1413 
1414 	osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
1415 
1416 	osif_debug("Indication to request TDLS setup");
1417 	cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
1418 				   ind->peer_mac, NL80211_TDLS_SETUP, false,
1419 				   GFP_KERNEL);
1420 }
1421 
1422 static void
wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication * ind)1423 wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication *ind)
1424 {
1425 	struct vdev_osif_priv *osif_vdev;
1426 
1427 	osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
1428 
1429 	osif_debug("Teardown reason %d", ind->reason);
1430 	cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
1431 				   ind->peer_mac, NL80211_TDLS_TEARDOWN,
1432 				   ind->reason, GFP_KERNEL);
1433 }
1434 #endif
1435 
wlan_cfg80211_tdls_event_callback(void * user_data,enum tdls_event_type type,struct tdls_osif_indication * ind)1436 void wlan_cfg80211_tdls_event_callback(void *user_data,
1437 				       enum tdls_event_type type,
1438 				       struct tdls_osif_indication *ind)
1439 {
1440 	struct vdev_osif_priv *osif_vdev;
1441 	struct osif_tdls_vdev *tdls_priv;
1442 
1443 	if (!ind || !ind->vdev) {
1444 		osif_err("ind: %pK", ind);
1445 		return;
1446 	}
1447 	osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
1448 
1449 	if (!osif_vdev || !osif_vdev->osif_tdls) {
1450 		osif_err("osif priv or tdls priv is NULL");
1451 		return;
1452 	}
1453 
1454 	tdls_priv = osif_vdev->osif_tdls;
1455 
1456 	switch (type) {
1457 	case TDLS_EVENT_MGMT_TX_ACK_CNF:
1458 		tdls_priv->mgmt_tx_completion_status = ind->status;
1459 		complete(&tdls_priv->tdls_mgmt_comp);
1460 		break;
1461 	case TDLS_EVENT_ADD_PEER:
1462 		tdls_priv->tdls_add_peer_status = ind->status;
1463 		complete(&tdls_priv->tdls_add_peer_comp);
1464 		break;
1465 	case TDLS_EVENT_DEL_PEER:
1466 		complete(&tdls_priv->tdls_del_peer_comp);
1467 		break;
1468 	case TDLS_EVENT_DISCOVERY_REQ:
1469 		wlan_cfg80211_tdls_indicate_discovery(ind);
1470 		break;
1471 	case TDLS_EVENT_TEARDOWN_REQ:
1472 		wlan_cfg80211_tdls_indicate_teardown(ind);
1473 		break;
1474 	case TDLS_EVENT_SETUP_REQ:
1475 		wlan_cfg80211_tdls_indicate_setup(ind);
1476 		break;
1477 	case TDLS_EVENT_USER_CMD:
1478 		tdls_priv->tdls_user_cmd_len = ind->status;
1479 		complete(&tdls_priv->tdls_user_cmd_comp);
1480 		break;
1481 
1482 	case TDLS_EVENT_ANTENNA_SWITCH:
1483 		tdls_priv->tdls_antenna_switch_status = ind->status;
1484 		complete(&tdls_priv->tdls_antenna_switch_comp);
1485 		break;
1486 	default:
1487 		break;
1488 	}
1489 }
1490