1 /*
2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2023-2024 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: wlan_tdls_mgmt.c
22 *
23 * TDLS management frames implementation
24 */
25
26 #include "wlan_tdls_main.h"
27 #include "wlan_tdls_tgt_api.h"
28 #include <wlan_serialization_api.h>
29 #include "wlan_mgmt_txrx_utils_api.h"
30 #include "wlan_tdls_peer.h"
31 #include "wlan_tdls_ct.h"
32 #include "wlan_tdls_mgmt.h"
33 #include "wlan_policy_mgr_api.h"
34 #include <wlan_reg_services_api.h>
35 #include <wlan_mlo_mgr_sta.h>
36 #include "wlan_mlo_link_force.h"
37
38 static
39 const char *const tdls_action_frames_type[] = { "TDLS Setup Request",
40 "TDLS Setup Response",
41 "TDLS Setup Confirm",
42 "TDLS Teardown",
43 "TDLS Peer Traffic Indication",
44 "TDLS Channel Switch Request",
45 "TDLS Channel Switch Response",
46 "TDLS Peer PSM Request",
47 "TDLS Peer PSM Response",
48 "TDLS Peer Traffic Response",
49 "TDLS Discovery Request"};
50
tdls_set_rssi(struct wlan_objmgr_vdev * vdev,uint8_t * mac,int8_t rssi)51 QDF_STATUS tdls_set_rssi(struct wlan_objmgr_vdev *vdev,
52 uint8_t *mac, int8_t rssi)
53 {
54 struct tdls_vdev_priv_obj *tdls_vdev;
55 struct tdls_peer *curr_peer;
56
57 if (!vdev || !mac) {
58 tdls_err("null pointer");
59 return QDF_STATUS_E_INVAL;
60 }
61
62 tdls_debug("rssi %d, peer " QDF_MAC_ADDR_FMT,
63 rssi, QDF_MAC_ADDR_REF(mac));
64
65 tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj(
66 vdev, WLAN_UMAC_COMP_TDLS);
67
68 if (!tdls_vdev) {
69 tdls_err("null tdls vdev");
70 return QDF_STATUS_E_EXISTS;
71 }
72
73 curr_peer = tdls_find_peer(tdls_vdev, mac);
74 if (!curr_peer) {
75 tdls_debug("null peer");
76 return QDF_STATUS_E_EXISTS;
77 }
78
79 curr_peer->rssi = rssi;
80
81 return QDF_STATUS_SUCCESS;
82 }
83
84 #ifdef WLAN_FEATURE_11BE_MLO
85 struct wlan_objmgr_vdev *
tdls_mlo_get_tdls_link_vdev(struct wlan_objmgr_vdev * vdev)86 tdls_mlo_get_tdls_link_vdev(struct wlan_objmgr_vdev *vdev)
87 {
88 return wlan_mlo_get_tdls_link_vdev(vdev);
89 }
90
91 void
tdls_set_remain_links_unforce(struct wlan_objmgr_vdev * vdev)92 tdls_set_remain_links_unforce(struct wlan_objmgr_vdev *vdev)
93 {
94 struct wlan_mlo_dev_context *mlo_dev_ctx;
95 struct wlan_objmgr_vdev *mlo_vdev;
96 int i;
97
98 /* TDLS link is selected, unforce link for other vdevs */
99 mlo_dev_ctx = vdev->mlo_dev_ctx;
100 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
101 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i];
102 if (!mlo_vdev || mlo_vdev == vdev)
103 continue;
104
105 tdls_debug("try to set vdev %d to unforce",
106 wlan_vdev_get_id(mlo_vdev));
107 tdls_set_link_unforce(mlo_vdev);
108 }
109 }
110
111 QDF_STATUS
tdls_process_mlo_cal_tdls_link_score(struct wlan_objmgr_vdev * vdev)112 tdls_process_mlo_cal_tdls_link_score(struct wlan_objmgr_vdev *vdev)
113 {
114 struct wlan_mlo_dev_context *mlo_dev_ctx;
115 struct wlan_objmgr_vdev *mlo_vdev;
116 struct tdls_vdev_priv_obj *tdls_vdev;
117 struct tdls_rx_mgmt_frame *rx_mgmt;
118 uint32_t score;
119 int i;
120 QDF_STATUS status = QDF_STATUS_E_FAILURE;
121
122 mlo_dev_ctx = vdev->mlo_dev_ctx;
123 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
124 score = 0;
125 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i];
126 if (!mlo_vdev)
127 continue;
128 tdls_vdev =
129 wlan_objmgr_vdev_get_comp_private_obj(mlo_vdev,
130 WLAN_UMAC_COMP_TDLS);
131 tdls_vdev->link_score = 0;
132 rx_mgmt = tdls_vdev->rx_mgmt;
133 if (!rx_mgmt)
134 continue;
135
136 switch (wlan_reg_freq_to_band(rx_mgmt->rx_freq)) {
137 case REG_BAND_2G:
138 score += 50;
139 break;
140 case REG_BAND_5G:
141 score += 70;
142 break;
143 case REG_BAND_6G:
144 score += 80;
145 break;
146 default:
147 score += 40;
148 break;
149 }
150
151 tdls_vdev->link_score = score;
152 status = QDF_STATUS_SUCCESS;
153 }
154
155 return status;
156 }
157
158 /**
159 * tdls_check_wait_more() - wait until the timer timeout if necessary
160 * @vdev: vdev object
161 *
162 * Return: true if need to wait else false
163 */
tdls_check_wait_more(struct wlan_objmgr_vdev * vdev)164 static bool tdls_check_wait_more(struct wlan_objmgr_vdev *vdev)
165 {
166 struct wlan_mlo_dev_context *mlo_dev_ctx;
167 struct wlan_objmgr_vdev *mlo_vdev;
168 struct tdls_vdev_priv_obj *tdls_vdev;
169 /* expect response number */
170 int expect_num;
171 /* received response number */
172 int receive_num;
173 int i;
174
175 expect_num = 0;
176 receive_num = 0;
177 mlo_dev_ctx = vdev->mlo_dev_ctx;
178 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
179 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i];
180 if (!mlo_vdev)
181 continue;
182
183 expect_num++;
184
185 tdls_vdev =
186 wlan_objmgr_vdev_get_comp_private_obj(mlo_vdev,
187 WLAN_UMAC_COMP_TDLS);
188 if (tdls_vdev->rx_mgmt)
189 receive_num++;
190 }
191
192 /* +1 means the one received last has not been recorded */
193 if (expect_num > receive_num + 1)
194 return true;
195 else
196 return false;
197 }
198
199 struct wlan_objmgr_vdev *
tdls_process_mlo_choice_tdls_vdev(struct wlan_objmgr_vdev * vdev)200 tdls_process_mlo_choice_tdls_vdev(struct wlan_objmgr_vdev *vdev)
201 {
202 struct wlan_mlo_dev_context *mlo_dev_ctx;
203 struct wlan_objmgr_vdev *mlo_vdev;
204 struct wlan_objmgr_vdev *select_vdev = NULL;
205 struct tdls_vdev_priv_obj *tdls_vdev;
206 uint32_t score = 0;
207 int i;
208
209 mlo_dev_ctx = vdev->mlo_dev_ctx;
210 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
211 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i];
212 if (!mlo_vdev)
213 continue;
214 tdls_vdev =
215 wlan_objmgr_vdev_get_comp_private_obj(mlo_vdev,
216 WLAN_UMAC_COMP_TDLS);
217 if (score < tdls_vdev->link_score) {
218 select_vdev = mlo_vdev;
219 score = tdls_vdev->link_score;
220 }
221 }
222
223 /* free the memory except the choice one */
224 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
225 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i];
226 if (!mlo_vdev || mlo_vdev == select_vdev)
227 continue;
228
229 tdls_vdev =
230 wlan_objmgr_vdev_get_comp_private_obj(mlo_vdev,
231 WLAN_UMAC_COMP_TDLS);
232 qdf_mem_free(tdls_vdev->rx_mgmt);
233 tdls_vdev->rx_mgmt = NULL;
234 tdls_vdev->link_score = 0;
235 }
236
237 return select_vdev;
238 }
239
240 static struct tdls_vdev_priv_obj
tdls_get_correct_vdev(struct tdls_vdev_priv_obj * tdls_vdev,struct tdls_rx_mgmt_frame * rx_mgmt)241 *tdls_get_correct_vdev(struct tdls_vdev_priv_obj *tdls_vdev,
242 struct tdls_rx_mgmt_frame *rx_mgmt)
243 {
244 struct wlan_objmgr_pdev *pdev;
245 struct wlan_objmgr_vdev *vdev;
246 struct tdls_link_identifier *linkid_ie;
247 uint8_t vdev_id;
248 uint8_t *ies;
249 uint32_t ie_len;
250 uint8_t elem_id_param = WLAN_ELEMID_LINK_IDENTIFIER;
251
252 if (!tdls_vdev || !rx_mgmt)
253 return NULL;
254
255 ies = &rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_TDLS_IE_OFFSET];
256 ie_len = rx_mgmt->frame_len - TDLS_PUBLIC_ACTION_FRAME_TDLS_IE_OFFSET;
257
258 linkid_ie =
259 (struct tdls_link_identifier *)wlan_get_ie_ptr_from_eid(elem_id_param,
260 ies, ie_len);
261 if (!linkid_ie)
262 return tdls_vdev;
263
264 pdev = wlan_vdev_get_pdev(tdls_vdev->vdev);
265 if (!pdev)
266 return tdls_vdev;
267
268 if (!wlan_get_connected_vdev_by_bssid(pdev,
269 linkid_ie->bssid, &vdev_id))
270 return tdls_vdev;
271
272 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
273 WLAN_TDLS_NB_ID);
274 if (!vdev)
275 return tdls_vdev;
276
277 tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj(vdev,
278 WLAN_UMAC_COMP_TDLS);
279 rx_mgmt->vdev_id = vdev_id;
280
281 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
282 tdls_debug("received discovery response on vdev %d", rx_mgmt->vdev_id);
283
284 return tdls_vdev;
285 }
286
tdls_check_peer_mlo_dev(struct wlan_objmgr_vdev * vdev,struct tdls_rx_mgmt_frame * rx_mgmt)287 static bool tdls_check_peer_mlo_dev(struct wlan_objmgr_vdev *vdev,
288 struct tdls_rx_mgmt_frame *rx_mgmt)
289 {
290 uint8_t *ies;
291 const uint8_t *ie;
292 uint32_t ie_len;
293 const uint8_t ext_id_param = WLAN_EXTN_ELEMID_MULTI_LINK;
294 uint8_t elem_id_param = WLAN_ELEMID_LINK_IDENTIFIER;
295
296 if (!vdev || !rx_mgmt)
297 return QDF_STATUS_E_INVAL;
298
299 ies = &rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_TDLS_IE_OFFSET];
300 ie_len = rx_mgmt->frame_len - TDLS_PUBLIC_ACTION_FRAME_TDLS_IE_OFFSET;
301
302 ie = wlan_get_ie_ptr_from_eid(elem_id_param, ies, ie_len);
303 if (ie)
304 qdf_trace_hex_dump(QDF_MODULE_ID_TDLS, QDF_TRACE_LEVEL_DEBUG,
305 (void *)&ie[0], ie[1] + 2);
306
307 ie = wlan_get_ext_ie_ptr_from_ext_id(&ext_id_param,
308 1, ies, ie_len);
309 if (ie)
310 return true;
311
312 return false;
313 }
314
315 static QDF_STATUS
tdls_process_mlo_rx_mgmt_sync(struct tdls_soc_priv_obj * tdls_soc,struct tdls_vdev_priv_obj * tdls_vdev,struct tdls_rx_mgmt_frame * rx_mgmt)316 tdls_process_mlo_rx_mgmt_sync(struct tdls_soc_priv_obj *tdls_soc,
317 struct tdls_vdev_priv_obj *tdls_vdev,
318 struct tdls_rx_mgmt_frame *rx_mgmt)
319 {
320 QDF_STATUS status;
321 struct wlan_objmgr_vdev *vdev;
322 struct wlan_objmgr_vdev *mlo_vdev;
323 struct wlan_mlo_dev_context *mlo_dev_ctx;
324 bool peer_mlo;
325 bool waitmore = false;
326 uint8_t i;
327
328 vdev = tdls_vdev->vdev;
329 peer_mlo = tdls_check_peer_mlo_dev(vdev, rx_mgmt);
330 if (!peer_mlo) {
331 mlo_dev_ctx = vdev->mlo_dev_ctx;
332 /* stop all timers */
333 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
334 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i];
335 if (!mlo_vdev)
336 continue;
337
338 tdls_vdev =
339 wlan_objmgr_vdev_get_comp_private_obj(mlo_vdev,
340 WLAN_UMAC_COMP_TDLS);
341 tdls_vdev->discovery_sent_cnt = 0;
342 if (QDF_TIMER_STATE_RUNNING ==
343 qdf_mc_timer_get_current_state(
344 &tdls_vdev->peer_discovery_timer)) {
345 qdf_mc_timer_stop(
346 &tdls_vdev->peer_discovery_timer);
347 qdf_atomic_dec(&tdls_soc->timer_cnt);
348 }
349 }
350 tdls_debug("peer is legacy device, timer_cnt %d",
351 qdf_atomic_read(&tdls_soc->timer_cnt));
352
353 status = QDF_STATUS_E_INVAL;
354 } else {
355 tdls_debug("peer is mlo device, timer_cnt %d",
356 qdf_atomic_read(&tdls_soc->timer_cnt));
357
358 /* If peer is MLD, it uses ml mac address to send the
359 * disconvery response, it needs to find out the
360 * corresponding vdev per the bssid in link identifier ie.
361 */
362 tdls_vdev = tdls_get_correct_vdev(tdls_vdev, rx_mgmt);
363 status = QDF_STATUS_TDLS_MLO_SYNC;
364 if (!tdls_vdev || tdls_vdev->rx_mgmt) {
365 tdls_err("rx dup tdls discovery resp on same vdev.");
366 goto exit;
367 }
368
369 if (qdf_atomic_read(&tdls_soc->timer_cnt) == 1)
370 waitmore = tdls_check_wait_more(vdev);
371
372 if (waitmore) {
373 /* do not stop the timer */
374 tdls_debug("wait more tdls response");
375 } else {
376 tdls_vdev->discovery_sent_cnt = 0;
377 qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer);
378 qdf_atomic_dec(&tdls_soc->timer_cnt);
379 }
380
381 tdls_vdev->rx_mgmt = qdf_mem_malloc_atomic(sizeof(*rx_mgmt) +
382 rx_mgmt->frame_len);
383 if (tdls_vdev->rx_mgmt) {
384 tdls_vdev->rx_mgmt->frame_len = rx_mgmt->frame_len;
385 tdls_vdev->rx_mgmt->rx_freq = rx_mgmt->rx_freq;
386 tdls_vdev->rx_mgmt->vdev_id = rx_mgmt->vdev_id;
387 tdls_vdev->rx_mgmt->frm_type = rx_mgmt->frm_type;
388 tdls_vdev->rx_mgmt->rx_rssi = rx_mgmt->rx_rssi;
389 qdf_mem_copy(tdls_vdev->rx_mgmt->buf,
390 rx_mgmt->buf, rx_mgmt->frame_len);
391 } else {
392 tdls_err("alloc rx mgmt buf error");
393 }
394
395 if (qdf_atomic_read(&tdls_soc->timer_cnt) == 0) {
396 tdls_process_mlo_cal_tdls_link_score(vdev);
397 status = QDF_STATUS_SUCCESS;
398 }
399 }
400
401 exit:
402 return status;
403 }
404
tdls_set_no_force_vdev(struct wlan_objmgr_vdev * vdev,bool flag)405 void tdls_set_no_force_vdev(struct wlan_objmgr_vdev *vdev, bool flag)
406 {
407 uint8_t i;
408 struct wlan_objmgr_psoc *psoc;
409 struct wlan_objmgr_vdev *mlo_vdev;
410 struct wlan_mlo_dev_context *mlo_dev_ctx;
411 bool is_mlo_vdev;
412 struct ml_nlink_change_event data;
413 QDF_STATUS status;
414
415 if (!vdev)
416 return;
417
418 is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
419 if (!is_mlo_vdev)
420 return;
421
422 psoc = wlan_vdev_get_psoc(vdev);
423 if (!psoc)
424 return;
425
426 qdf_mem_zero(&data, sizeof(data));
427
428 mlo_dev_ctx = vdev->mlo_dev_ctx;
429 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
430 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i];
431 if (!mlo_vdev)
432 continue;
433
434 /* flag: true means no force all vdevs,
435 * false means except the current one
436 */
437 if (!flag && (mlo_vdev == vdev))
438 continue;
439 data.evt.tdls.link_bitmap |=
440 1 << wlan_vdev_get_link_id(mlo_vdev);
441 data.evt.tdls.mlo_vdev_lst[data.evt.tdls.vdev_count] =
442 wlan_vdev_get_id(mlo_vdev);
443 data.evt.tdls.vdev_count++;
444 }
445
446 data.evt.tdls.mode = MLO_LINK_FORCE_MODE_NO_FORCE;
447 data.evt.tdls.reason = MLO_LINK_FORCE_REASON_TDLS;
448 status = ml_nlink_conn_change_notify(psoc,
449 wlan_vdev_get_id(vdev),
450 ml_nlink_tdls_request_evt,
451 &data);
452 }
453 #else
454 struct wlan_objmgr_vdev *
tdls_mlo_get_tdls_link_vdev(struct wlan_objmgr_vdev * vdev)455 tdls_mlo_get_tdls_link_vdev(struct wlan_objmgr_vdev *vdev)
456 {
457 return NULL;
458 }
459
460 void
tdls_set_remain_links_unforce(struct wlan_objmgr_vdev * vdev)461 tdls_set_remain_links_unforce(struct wlan_objmgr_vdev *vdev)
462 {
463 }
464
465 QDF_STATUS
tdls_process_mlo_cal_tdls_link_score(struct wlan_objmgr_vdev * vdev)466 tdls_process_mlo_cal_tdls_link_score(struct wlan_objmgr_vdev *vdev)
467 {
468 return QDF_STATUS_SUCCESS;
469 }
470
471 struct wlan_objmgr_vdev *
tdls_process_mlo_choice_tdls_vdev(struct wlan_objmgr_vdev * vdev)472 tdls_process_mlo_choice_tdls_vdev(struct wlan_objmgr_vdev *vdev)
473 {
474 return NULL;
475 }
476
477 static struct tdls_vdev_priv_obj
tdls_get_correct_vdev(struct tdls_vdev_priv_obj * tdls_vdev,struct tdls_rx_mgmt_frame * rx_mgmt)478 *tdls_get_correct_vdev(struct tdls_vdev_priv_obj *tdls_vdev,
479 struct tdls_rx_mgmt_frame *rx_mgmt)
480 {
481 return NULL;
482 }
483
484 static QDF_STATUS
tdls_process_mlo_rx_mgmt_sync(struct tdls_soc_priv_obj * tdls_soc,struct tdls_vdev_priv_obj * tdls_vdev,struct tdls_rx_mgmt_frame * rx_mgmt)485 tdls_process_mlo_rx_mgmt_sync(struct tdls_soc_priv_obj *tdls_soc,
486 struct tdls_vdev_priv_obj *tdls_vdev,
487 struct tdls_rx_mgmt_frame *rx_mgmt)
488 {
489 return QDF_STATUS_SUCCESS;
490 }
491
tdls_set_no_force_vdev(struct wlan_objmgr_vdev * vdev,bool flag)492 void tdls_set_no_force_vdev(struct wlan_objmgr_vdev *vdev, bool flag)
493 {
494 }
495 #endif
496
497 static bool
tdls_needs_wait_discovery_response(struct wlan_objmgr_vdev * vdev,struct tdls_soc_priv_obj * tdls_soc)498 tdls_needs_wait_discovery_response(struct wlan_objmgr_vdev *vdev,
499 struct tdls_soc_priv_obj *tdls_soc)
500 {
501 bool is_mlo_vdev;
502 bool wait = false;
503
504 is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
505 if (is_mlo_vdev && qdf_atomic_read(&tdls_soc->timer_cnt))
506 wait = true;
507
508 return wait;
509 }
510
511 /**
512 * tdls_process_rx_mgmt() - process tdls rx mgmt frames
513 * @rx_mgmt_event: tdls rx mgmt event
514 * @tdls_vdev: tdls vdev object
515 *
516 * Return: QDF_STATUS
517 */
tdls_process_rx_mgmt(struct tdls_rx_mgmt_event * rx_mgmt_event,struct tdls_vdev_priv_obj * tdls_vdev)518 static QDF_STATUS tdls_process_rx_mgmt(
519 struct tdls_rx_mgmt_event *rx_mgmt_event,
520 struct tdls_vdev_priv_obj *tdls_vdev)
521 {
522 struct tdls_rx_mgmt_frame *rx_mgmt;
523 struct tdls_soc_priv_obj *tdls_soc_obj;
524 uint8_t *mac;
525 enum tdls_actioncode action_frame_type;
526 struct wlan_objmgr_vdev *vdev;
527 struct wlan_objmgr_vdev *tdls_link_vdev;
528 bool tdls_vdev_select = false;
529 QDF_STATUS status = QDF_STATUS_E_INVAL;
530
531 if (!rx_mgmt_event)
532 return QDF_STATUS_E_INVAL;
533
534 tdls_soc_obj = rx_mgmt_event->tdls_soc_obj;
535 rx_mgmt = rx_mgmt_event->rx_mgmt;
536
537 if (!tdls_soc_obj || !rx_mgmt) {
538 tdls_err("invalid psoc object or rx mgmt");
539 return QDF_STATUS_E_INVAL;
540 }
541
542 vdev = tdls_vdev->vdev;
543 tdls_debug("received mgmt on vdev %d", wlan_vdev_get_id(vdev));
544 tdls_debug("soc:%pK, frame_len:%d, rx_freq:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK",
545 tdls_soc_obj->soc, rx_mgmt->frame_len,
546 rx_mgmt->rx_freq, rx_mgmt->vdev_id, rx_mgmt->frm_type,
547 rx_mgmt->rx_rssi, rx_mgmt->buf);
548
549 if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1] ==
550 TDLS_PUBLIC_ACTION_DISC_RESP) {
551 if (tdls_needs_wait_discovery_response(vdev, tdls_soc_obj)) {
552 status = tdls_process_mlo_rx_mgmt_sync(tdls_soc_obj,
553 tdls_vdev,
554 rx_mgmt);
555 if (status == QDF_STATUS_TDLS_MLO_SYNC) {
556 return QDF_STATUS_SUCCESS;
557 } else if (status == QDF_STATUS_SUCCESS) {
558 vdev = tdls_process_mlo_choice_tdls_vdev(vdev);
559 if (!vdev)
560 return QDF_STATUS_SUCCESS;
561 tdls_vdev =
562 wlan_objmgr_vdev_get_comp_private_obj(vdev,
563 WLAN_UMAC_COMP_TDLS);
564 if (!tdls_vdev)
565 return QDF_STATUS_E_EXISTS;
566 rx_mgmt = tdls_vdev->rx_mgmt;
567 tdls_vdev_select = true;
568 tdls_debug("choice vdev %d as tdls vdev",
569 wlan_vdev_get_id(vdev));
570 } else {
571 tdls_vdev = tdls_get_correct_vdev(tdls_vdev,
572 rx_mgmt);
573 if (!tdls_vdev)
574 return QDF_STATUS_SUCCESS;
575 vdev = tdls_vdev->vdev;
576 }
577 } else {
578 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
579 tdls_link_vdev =
580 tdls_mlo_get_tdls_link_vdev(vdev);
581 tdls_vdev =
582 tdls_get_correct_vdev(tdls_vdev, rx_mgmt);
583 if (!tdls_link_vdev || !tdls_vdev) {
584 tdls_debug("not expected frame");
585 return QDF_STATUS_SUCCESS;
586 }
587 if (tdls_link_vdev != tdls_vdev->vdev) {
588 tdls_debug("not forward to userspace");
589 return QDF_STATUS_SUCCESS;
590 }
591 rx_mgmt->vdev_id =
592 wlan_vdev_get_id(tdls_link_vdev);
593 vdev = tdls_link_vdev;
594 }
595 }
596
597 /* this is mld mac address for mlo case*/
598 mac = &rx_mgmt->buf[TDLS_80211_PEER_ADDR_OFFSET];
599 tdls_notice("[TDLS] TDLS Discovery Response,"
600 QDF_MAC_ADDR_FMT " RSSI[%d] <--- OTA",
601 QDF_MAC_ADDR_REF(mac), rx_mgmt->rx_rssi);
602
603 tdls_debug("discovery resp on vdev %d", wlan_vdev_get_id(vdev));
604 tdls_recv_discovery_resp(tdls_vdev, mac);
605 tdls_set_rssi(tdls_vdev->vdev, mac, rx_mgmt->rx_rssi);
606 }
607
608 if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET] ==
609 TDLS_ACTION_FRAME) {
610 action_frame_type =
611 rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1];
612 if (action_frame_type >= TDLS_ACTION_FRAME_TYPE_MAX) {
613 tdls_debug("[TDLS] unknown[%d] <--- OTA",
614 action_frame_type);
615 } else {
616 tdls_notice("[TDLS] %s <--- OTA",
617 tdls_action_frames_type[action_frame_type]);
618 }
619 }
620
621 /* tdls_soc_obj->tdls_rx_cb ==> wlan_cfg80211_tdls_rx_callback() */
622 if (tdls_soc_obj && tdls_soc_obj->tdls_rx_cb)
623 tdls_soc_obj->tdls_rx_cb(tdls_soc_obj->tdls_rx_cb_data,
624 rx_mgmt);
625 else
626 tdls_debug("rx mgmt, but no valid up layer callback");
627
628 if (tdls_vdev_select && tdls_vdev->rx_mgmt) {
629 qdf_mem_free(tdls_vdev->rx_mgmt);
630 tdls_vdev->rx_mgmt = NULL;
631 tdls_vdev->link_score = 0;
632 }
633
634 return QDF_STATUS_SUCCESS;
635 }
636
tdls_process_rx_frame(struct scheduler_msg * msg)637 QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg)
638 {
639 struct wlan_objmgr_vdev *vdev;
640 struct tdls_rx_mgmt_event *tdls_rx;
641 struct tdls_vdev_priv_obj *tdls_vdev;
642 QDF_STATUS status = QDF_STATUS_E_FAILURE;
643
644 if (!(msg->bodyptr)) {
645 tdls_err("invalid message body");
646 return QDF_STATUS_E_INVAL;
647 }
648
649 tdls_rx = (struct tdls_rx_mgmt_event *) msg->bodyptr;
650
651 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(tdls_rx->tdls_soc_obj->soc,
652 tdls_rx->rx_mgmt->vdev_id, WLAN_TDLS_NB_ID);
653
654 if (vdev) {
655 tdls_debug("tdls rx mgmt frame received");
656 tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj(vdev,
657 WLAN_UMAC_COMP_TDLS);
658 if (tdls_vdev)
659 status = tdls_process_rx_mgmt(tdls_rx, tdls_vdev);
660 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
661 }
662
663 qdf_mem_free(tdls_rx->rx_mgmt);
664 qdf_mem_free(msg->bodyptr);
665 msg->bodyptr = NULL;
666
667 return status;
668 }
669
tdls_mgmt_rx_ops(struct wlan_objmgr_psoc * psoc,bool isregister)670 QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc,
671 bool isregister)
672 {
673 struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info;
674 QDF_STATUS status;
675 int num_of_entries;
676
677 tdls_debug("psoc:%pK, is register rx:%d", psoc, isregister);
678
679 frm_cb_info.frm_type = MGMT_ACTION_TDLS_DISCRESP;
680 frm_cb_info.mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb;
681 num_of_entries = 1;
682
683 if (isregister)
684 status = wlan_mgmt_txrx_register_rx_cb(psoc,
685 WLAN_UMAC_COMP_TDLS, &frm_cb_info,
686 num_of_entries);
687 else
688 status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
689 WLAN_UMAC_COMP_TDLS, &frm_cb_info,
690 num_of_entries);
691
692 return status;
693 }
694
695 static QDF_STATUS
tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request * req,QDF_STATUS status)696 tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request *req,
697 QDF_STATUS status)
698 {
699 struct tdls_soc_priv_obj *tdls_soc_obj;
700 struct tdls_osif_indication indication;
701
702 if (!req || !req->vdev)
703 return QDF_STATUS_E_NULL_VALUE;
704
705 indication.status = status;
706 indication.vdev = req->vdev;
707 tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev);
708 if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb)
709 tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data,
710 TDLS_EVENT_MGMT_TX_ACK_CNF, &indication);
711 return QDF_STATUS_SUCCESS;
712 }
713
tdls_activate_send_mgmt_request_flush_cb(struct scheduler_msg * msg)714 static QDF_STATUS tdls_activate_send_mgmt_request_flush_cb(
715 struct scheduler_msg *msg)
716 {
717 struct tdls_send_mgmt_request *tdls_mgmt_req;
718
719 tdls_mgmt_req = msg->bodyptr;
720
721 qdf_mem_free(tdls_mgmt_req);
722 msg->bodyptr = NULL;
723
724 return QDF_STATUS_SUCCESS;
725 }
726
727 static QDF_STATUS
tdls_activate_send_mgmt_request(struct tdls_action_frame_request * action_req)728 tdls_activate_send_mgmt_request(struct tdls_action_frame_request *action_req)
729 {
730 struct tdls_soc_priv_obj *tdls_soc_obj;
731 QDF_STATUS status;
732 struct tdls_send_mgmt_request *tdls_mgmt_req;
733 struct wlan_objmgr_peer *peer;
734 struct scheduler_msg msg = {0};
735 struct tdls_vdev_priv_obj *tdls_vdev;
736
737 if (!action_req || !action_req->vdev)
738 return QDF_STATUS_E_NULL_VALUE;
739
740 tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(action_req->vdev);
741 if (!tdls_soc_obj) {
742 status = QDF_STATUS_E_NULL_VALUE;
743 goto release_cmd;
744 }
745
746 tdls_mgmt_req = qdf_mem_malloc(sizeof(struct tdls_send_mgmt_request) +
747 action_req->tdls_mgmt.len);
748 if (!tdls_mgmt_req) {
749 status = QDF_STATUS_E_NOMEM;
750 goto release_cmd;
751 }
752
753 tdls_debug("session_id %d "
754 "tdls_mgmt.dialog %d "
755 "tdls_mgmt.frame_type %d "
756 "tdls_mgmt.status_code %d "
757 "tdls_mgmt.responder %d "
758 "tdls_mgmt.peer_capability %d",
759 action_req->session_id,
760 action_req->tdls_mgmt.dialog,
761 action_req->tdls_mgmt.frame_type,
762 action_req->tdls_mgmt.status_code,
763 action_req->tdls_mgmt.responder,
764 action_req->tdls_mgmt.peer_capability);
765
766 tdls_mgmt_req->session_id = action_req->session_id;
767 tdls_mgmt_req->req_type = action_req->tdls_mgmt.frame_type;
768 tdls_mgmt_req->dialog = action_req->tdls_mgmt.dialog;
769 tdls_mgmt_req->status_code = action_req->tdls_mgmt.status_code;
770 tdls_mgmt_req->responder = action_req->tdls_mgmt.responder;
771 tdls_mgmt_req->peer_capability = action_req->tdls_mgmt.peer_capability;
772
773 peer = wlan_objmgr_vdev_try_get_bsspeer(action_req->vdev,
774 WLAN_TDLS_SB_ID);
775 if (!peer) {
776 tdls_err("bss peer is null");
777 qdf_mem_free(tdls_mgmt_req);
778 status = QDF_STATUS_E_NULL_VALUE;
779 goto release_cmd;
780 }
781
782 qdf_mem_copy(tdls_mgmt_req->bssid.bytes,
783 wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE);
784
785 wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
786
787 qdf_mem_copy(tdls_mgmt_req->peer_mac.bytes,
788 action_req->tdls_mgmt.peer_mac.bytes, QDF_MAC_ADDR_SIZE);
789
790 if (action_req->tdls_mgmt.len) {
791 qdf_mem_copy(tdls_mgmt_req->add_ie, action_req->tdls_mgmt.buf,
792 action_req->tdls_mgmt.len);
793 }
794
795 tdls_mgmt_req->length = sizeof(struct tdls_send_mgmt_request) +
796 action_req->tdls_mgmt.len;
797 if (action_req->use_default_ac)
798 tdls_mgmt_req->ac = WIFI_AC_VI;
799 else
800 tdls_mgmt_req->ac = WIFI_AC_BK;
801
802 if (wlan_vdev_mlme_is_mlo_vdev(action_req->vdev) &&
803 !tdls_mlo_get_tdls_link_vdev(action_req->vdev) &&
804 tdls_mgmt_req->req_type == TDLS_DISCOVERY_REQUEST) {
805 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(action_req->vdev);
806 if (QDF_TIMER_STATE_RUNNING !=
807 qdf_mc_timer_get_current_state(
808 &tdls_vdev->peer_discovery_timer)) {
809 tdls_timer_restart(tdls_vdev->vdev,
810 &tdls_vdev->peer_discovery_timer,
811 tdls_vdev->threshold_config.tx_period_t -
812 TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE);
813 qdf_atomic_inc(&tdls_soc_obj->timer_cnt);
814 } else {
815 qdf_mem_free(tdls_mgmt_req);
816 status = QDF_STATUS_E_NULL_VALUE;
817 goto release_cmd;
818 }
819 }
820
821 /* Send the request to PE. */
822 qdf_mem_zero(&msg, sizeof(msg));
823
824 tdls_debug("sending TDLS Mgmt Frame req to PE ");
825 tdls_mgmt_req->message_type = tdls_soc_obj->tdls_send_mgmt_req;
826
827 msg.type = tdls_soc_obj->tdls_send_mgmt_req;
828 msg.bodyptr = tdls_mgmt_req;
829 msg.flush_callback = tdls_activate_send_mgmt_request_flush_cb;
830
831 status = scheduler_post_message(QDF_MODULE_ID_TDLS,
832 QDF_MODULE_ID_TDLS,
833 QDF_MODULE_ID_PE, &msg);
834 if (QDF_IS_STATUS_ERROR(status))
835 qdf_mem_free(tdls_mgmt_req);
836
837 release_cmd:
838 /*update tdls nss infornation based on action code */
839 tdls_reset_nss(tdls_soc_obj, action_req->chk_frame.action_code);
840 if (QDF_IS_STATUS_ERROR(status)) {
841 tdls_internal_send_mgmt_tx_done(action_req, status);
842 tdls_release_serialization_command(action_req->vdev,
843 WLAN_SER_CMD_TDLS_SEND_MGMT);
844 }
845
846 return status;
847 }
848
849 static QDF_STATUS
tdls_send_mgmt_serialize_callback(struct wlan_serialization_command * cmd,enum wlan_serialization_cb_reason reason)850 tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd,
851 enum wlan_serialization_cb_reason reason)
852 {
853 struct tdls_action_frame_request *req;
854 QDF_STATUS status = QDF_STATUS_SUCCESS;
855
856 if (!cmd || !cmd->umac_cmd) {
857 tdls_err("invalid params cmd: %pK, ", cmd);
858 return QDF_STATUS_E_NULL_VALUE;
859 }
860 req = cmd->umac_cmd;
861
862 switch (reason) {
863 case WLAN_SER_CB_ACTIVATE_CMD:
864 /* command moved to active list */
865 status = tdls_activate_send_mgmt_request(req);
866 break;
867
868 case WLAN_SER_CB_CANCEL_CMD:
869 case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
870 /* command removed from pending list.
871 * notify status complete with failure
872 */
873 status = tdls_internal_send_mgmt_tx_done(req,
874 QDF_STATUS_E_FAILURE);
875 break;
876
877 case WLAN_SER_CB_RELEASE_MEM_CMD:
878 /* command successfully completed.
879 * release tdls_action_frame_request memory
880 */
881 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID);
882 qdf_mem_free(req);
883 break;
884
885 default:
886 /* Do nothing but logging */
887 QDF_ASSERT(0);
888 status = QDF_STATUS_E_INVAL;
889 break;
890 }
891
892 return status;
893 }
894
895 #ifdef WLAN_FEATURE_11BE_MLO
tdls_set_link_mode(struct tdls_action_frame_request * req)896 QDF_STATUS tdls_set_link_mode(struct tdls_action_frame_request *req)
897 {
898 struct wlan_objmgr_psoc *psoc;
899 struct wlan_objmgr_vdev *mlo_tdls_vdev;
900 bool is_mlo_vdev;
901 QDF_STATUS status = QDF_STATUS_SUCCESS;
902 struct ml_nlink_change_event data;
903 uint8_t num_ml_sta = 0;
904 uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
905
906 is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(req->vdev);
907 if (!is_mlo_vdev)
908 return status;
909
910 psoc = wlan_vdev_get_psoc(req->vdev);
911 if (!psoc) {
912 tdls_err("psoc is NULL");
913 return QDF_STATUS_E_NULL_VALUE;
914 }
915
916
917 if (req->tdls_mgmt.frame_type == TDLS_DISCOVERY_RESPONSE ||
918 req->tdls_mgmt.frame_type == TDLS_DISCOVERY_REQUEST) {
919 mlo_tdls_vdev = wlan_mlo_get_tdls_link_vdev(req->vdev);
920 if (mlo_tdls_vdev)
921 return status;
922
923 status = policy_mgr_is_ml_links_in_mcc_allowed(
924 psoc, req->vdev,
925 ml_sta_vdev_lst,
926 &num_ml_sta);
927 if (QDF_IS_STATUS_SUCCESS(status)) {
928 tdls_err("ML STA Links in MCC, so don't send the TDLS frames");
929 return QDF_STATUS_E_FAILURE;
930 }
931
932 qdf_mem_zero(&data, sizeof(data));
933 data.evt.tdls.link_bitmap =
934 1 << wlan_vdev_get_link_id(req->vdev);
935 data.evt.tdls.mlo_vdev_lst[0] = wlan_vdev_get_id(req->vdev);
936 data.evt.tdls.vdev_count = 1;
937 data.evt.tdls.mode = MLO_LINK_FORCE_MODE_ACTIVE;
938 data.evt.tdls.reason = MLO_LINK_FORCE_REASON_TDLS;
939 status =
940 ml_nlink_conn_change_notify(psoc,
941 wlan_vdev_get_id(req->vdev),
942 ml_nlink_tdls_request_evt,
943 &data);
944 if (status == QDF_STATUS_SUCCESS ||
945 status == QDF_STATUS_E_PENDING)
946 req->link_active = true;
947 } else if (req->tdls_mgmt.frame_type == TDLS_MAX_ACTION_CODE) {
948 qdf_mem_zero(&data, sizeof(data));
949 data.evt.tdls.link_bitmap =
950 1 << wlan_vdev_get_link_id(req->vdev);
951 data.evt.tdls.mlo_vdev_lst[0] = wlan_vdev_get_id(req->vdev);
952 data.evt.tdls.vdev_count = 1;
953 data.evt.tdls.mode = MLO_LINK_FORCE_MODE_NO_FORCE;
954 data.evt.tdls.reason = MLO_LINK_FORCE_REASON_TDLS;
955 status =
956 ml_nlink_conn_change_notify(psoc,
957 wlan_vdev_get_id(req->vdev),
958 ml_nlink_tdls_request_evt,
959 &data);
960 }
961 if (status == QDF_STATUS_E_PENDING)
962 status = QDF_STATUS_SUCCESS;
963
964 return status;
965 }
966 #else
tdls_set_link_mode(struct tdls_action_frame_request * req)967 QDF_STATUS tdls_set_link_mode(struct tdls_action_frame_request *req)
968 {
969 return QDF_STATUS_SUCCESS;
970 }
971 #endif
972
tdls_process_mgmt_req(struct tdls_action_frame_request * tdls_mgmt_req)973 QDF_STATUS tdls_process_mgmt_req(
974 struct tdls_action_frame_request *tdls_mgmt_req)
975 {
976 QDF_STATUS status = QDF_STATUS_SUCCESS;
977 struct wlan_serialization_command cmd = {0, };
978 enum wlan_serialization_status ser_cmd_status;
979
980 /* If connected and in Infra. Only then allow this */
981 status = tdls_validate_mgmt_request(tdls_mgmt_req);
982 if (status != QDF_STATUS_SUCCESS) {
983 status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
984 status);
985 goto error_mgmt;
986 }
987
988 status = tdls_set_link_mode(tdls_mgmt_req);
989 if (status != QDF_STATUS_SUCCESS) {
990 tdls_err("failed to set link:%d active",
991 wlan_vdev_get_link_id(tdls_mgmt_req->vdev));
992 status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
993 status);
994 goto error_mgmt;
995 }
996
997 /* update the responder, status code information
998 * after the cmd validation
999 */
1000 tdls_mgmt_req->tdls_mgmt.responder =
1001 !tdls_mgmt_req->chk_frame.responder;
1002 tdls_mgmt_req->tdls_mgmt.status_code =
1003 tdls_mgmt_req->chk_frame.status_code;
1004
1005 cmd.cmd_type = WLAN_SER_CMD_TDLS_SEND_MGMT;
1006 /* Cmd Id not applicable for non scan cmds */
1007 cmd.cmd_id = 0;
1008 cmd.cmd_cb = tdls_send_mgmt_serialize_callback;
1009 cmd.umac_cmd = tdls_mgmt_req;
1010 cmd.source = WLAN_UMAC_COMP_TDLS;
1011 cmd.is_high_priority = false;
1012 cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT;
1013
1014 cmd.vdev = tdls_mgmt_req->vdev;
1015 cmd.is_blocking = true;
1016
1017 ser_cmd_status = wlan_serialization_request(&cmd);
1018 tdls_debug("wlan_serialization_request status:%d", ser_cmd_status);
1019
1020 switch (ser_cmd_status) {
1021 case WLAN_SER_CMD_PENDING:
1022 /* command moved to pending list.Do nothing */
1023 break;
1024 case WLAN_SER_CMD_ACTIVE:
1025 /* command moved to active list. Do nothing */
1026 break;
1027 case WLAN_SER_CMD_DENIED_LIST_FULL:
1028 case WLAN_SER_CMD_DENIED_RULES_FAILED:
1029 case WLAN_SER_CMD_DENIED_UNSPECIFIED:
1030 status = QDF_STATUS_E_FAILURE;
1031 goto error_mgmt;
1032 default:
1033 QDF_ASSERT(0);
1034 status = QDF_STATUS_E_INVAL;
1035 goto error_mgmt;
1036 }
1037 return status;
1038
1039 error_mgmt:
1040 wlan_objmgr_vdev_release_ref(tdls_mgmt_req->vdev, WLAN_TDLS_NB_ID);
1041 qdf_mem_free(tdls_mgmt_req);
1042 return status;
1043 }
1044