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