1 /*
2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-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 * This file lim_process_action_frame.cc contains the code
22 * for processing Action Frame.
23 * Author: Michael Lui
24 * Date: 05/23/03
25 * History:-
26 * Date Modified by Modification Information
27 * --------------------------------------------------------------------
28 *
29 */
30 #include "cds_api.h"
31 #include "wni_api.h"
32 #include "sir_api.h"
33 #include "ani_global.h"
34 #include "wni_cfg.h"
35 #include "sch_api.h"
36 #include "utils_api.h"
37 #include "lim_types.h"
38 #include "lim_utils.h"
39 #include "lim_assoc_utils.h"
40 #include "lim_security_utils.h"
41 #include "lim_ser_des_utils.h"
42 #include "lim_send_sme_rsp_messages.h"
43 #include "parser_api.h"
44 #include "lim_admit_control.h"
45 #include "wmm_apsd.h"
46 #include "lim_send_messages.h"
47 #include "rrm_api.h"
48 #include "lim_session_utils.h"
49 #include "wlan_policy_mgr_api.h"
50 #include "wma_types.h"
51 #include "wma.h"
52 #include <cdp_txrx_cmn.h>
53 #include <cdp_txrx_peer_ops.h>
54 #include "dot11f.h"
55 #include "wlan_p2p_cfg_api.h"
56 #include "son_api.h"
57 #include "wlan_t2lm_api.h"
58 #include "wlan_epcs_api.h"
59 #include <wlan_mlo_mgr_sta.h>
60 #include "wlan_mlo_mgr_public_structs.h"
61 #include "wlan_p2p_api.h"
62
63 #define SA_QUERY_REQ_MIN_LEN \
64 (DOT11F_FF_CATEGORY_LEN + DOT11F_FF_ACTION_LEN + DOT11F_FF_TRANSACTIONID_LEN)
65 #define SA_QUERY_RESP_MIN_LEN \
66 (DOT11F_FF_CATEGORY_LEN + DOT11F_FF_ACTION_LEN + DOT11F_FF_TRANSACTIONID_LEN)
67 #define SA_QUERY_IE_OFFSET (4)
68
69 #define MIN_OCI_IE_LEN 6
70 #define OCI_IE_OUI_SIZE 1
71 #define OCI_IE_OP_CLS_OFFSET 3
72 #define ELE_ID_EXT_LEN 1
73
74 static last_processed_msg rrm_link_action_frm;
75
76 /**-----------------------------------------------------------------
77 \fn lim_stop_tx_and_switch_channel
78 \brief Stops the transmission if channel switch mode is silent and
79 starts the channel switch timer.
80
81 \param mac
82 \return NONE
83 -----------------------------------------------------------------*/
lim_stop_tx_and_switch_channel(struct mac_context * mac,uint8_t sessionId)84 void lim_stop_tx_and_switch_channel(struct mac_context *mac, uint8_t sessionId)
85 {
86 struct pe_session *pe_session;
87 QDF_STATUS status;
88
89 pe_session = pe_find_session_by_session_id(mac, sessionId);
90
91 if (!pe_session) {
92 pe_err("Session: %d not active", sessionId);
93 return;
94 }
95
96 if (pe_session->ftPEContext.pFTPreAuthReq) {
97 pe_debug("Avoid Switch Channel req during pre auth");
98 return;
99 }
100
101 status = policy_mgr_check_and_set_hw_mode_for_channel_switch(mac->psoc,
102 pe_session->smeSessionId,
103 pe_session->gLimChannelSwitch.sw_target_freq,
104 POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA);
105
106 /*
107 * If status is QDF_STATUS_E_FAILURE, mean HW mode change was required
108 * but driver failed to set HW mode so ignore CSA for the channel.
109 * If status is QDF_STATUS_SUCCESS mean HW mode change was required
110 * and was successfully changed so the channel switch will continue after
111 * HW mode change completion.
112 * If status is QDF_STATUS_E_NOSUPPORT or QDF_STATUS_E_ALREADY, mean
113 * DBS is not supported or required HW mode is already set, so
114 * So contunue with CSA from here.
115 */
116 if (status == QDF_STATUS_E_FAILURE) {
117 pe_err("Failed to set required HW mode for channel %d freq %d, ignore CSA",
118 pe_session->gLimChannelSwitch.primaryChannel,
119 pe_session->gLimChannelSwitch.sw_target_freq);
120 return;
121 }
122
123 if (QDF_IS_STATUS_SUCCESS(status)) {
124 pe_info("Channel change will continue after HW mode change");
125 return;
126 }
127
128 lim_process_channel_switch(mac, pe_session->smeSessionId);
129
130 return;
131 }
132
133 /**
134 * lim_process_ext_channel_switch_action_frame()- Process ECSA Action
135 * Frames.
136 * @mac_ctx: pointer to global mac structure
137 * @rx_packet_info: rx packet meta information
138 * @session_entry: Session entry.
139 *
140 * This function is called when ECSA action frame is received.
141 *
142 * Return: void
143 */
144 static void
lim_process_ext_channel_switch_action_frame(struct mac_context * mac_ctx,uint8_t * rx_packet_info,struct pe_session * session_entry)145 lim_process_ext_channel_switch_action_frame(struct mac_context *mac_ctx,
146 uint8_t *rx_packet_info, struct pe_session *session_entry)
147 {
148
149 tpSirMacMgmtHdr hdr;
150 uint8_t *body;
151 tDot11fext_channel_switch_action_frame *ext_channel_switch_frame;
152 uint32_t frame_len;
153 uint32_t status;
154 uint32_t target_freq;
155
156 hdr = WMA_GET_RX_MAC_HEADER(rx_packet_info);
157 body = WMA_GET_RX_MPDU_DATA(rx_packet_info);
158 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_packet_info);
159
160 pe_debug("Received EXT Channel switch action frame");
161
162 ext_channel_switch_frame =
163 qdf_mem_malloc(sizeof(*ext_channel_switch_frame));
164 if (!ext_channel_switch_frame)
165 return;
166
167 /* Unpack channel switch frame */
168 status = dot11f_unpack_ext_channel_switch_action_frame(mac_ctx,
169 body, frame_len, ext_channel_switch_frame, false);
170
171 if (DOT11F_FAILED(status)) {
172 pe_err("Failed to parse CHANSW action frame (0x%08x, len %d):",
173 status, frame_len);
174 qdf_mem_free(ext_channel_switch_frame);
175 return;
176 } else if (DOT11F_WARNED(status)) {
177 pe_debug("There were warnings while unpacking CHANSW Request (0x%08x, %d bytes):",
178 status, frame_len);
179 }
180
181 if (!wlan_reg_is_6ghz_supported(mac_ctx->psoc) &&
182 (wlan_reg_is_6ghz_op_class(mac_ctx->pdev,
183 ext_channel_switch_frame->
184 ext_chan_switch_ann_action.op_class))) {
185 pe_err("channel belongs to 6 ghz spectrum, abort");
186 qdf_mem_free(ext_channel_switch_frame);
187 return;
188 }
189
190 target_freq =
191 wlan_reg_chan_opclass_to_freq(ext_channel_switch_frame->ext_chan_switch_ann_action.new_channel,
192 ext_channel_switch_frame->ext_chan_switch_ann_action.op_class,
193 false);
194
195 /* Free ext_channel_switch_frame here as its no longer needed */
196 qdf_mem_free(ext_channel_switch_frame);
197 /*
198 * Now, validate if channel change is required for the passed
199 * channel and if is valid in the current regulatory domain,
200 * and no concurrent session is running.
201 */
202 if (!(session_entry->curr_op_freq != target_freq &&
203 ((wlan_reg_get_channel_state_for_pwrmode(mac_ctx->pdev,
204 target_freq,
205 REG_CURRENT_PWR_MODE) == CHANNEL_STATE_ENABLE) ||
206 (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, target_freq) &&
207 !policy_mgr_concurrent_open_sessions_running(
208 mac_ctx->psoc))))) {
209 pe_err("Channel freq: %d is not valid", target_freq);
210 return;
211 }
212
213 if (session_entry->opmode == QDF_P2P_GO_MODE) {
214
215 struct sir_sme_ext_cng_chan_ind *ext_cng_chan_ind;
216 struct scheduler_msg mmh_msg = {0};
217
218 ext_cng_chan_ind = qdf_mem_malloc(sizeof(*ext_cng_chan_ind));
219 if (!ext_cng_chan_ind)
220 return;
221
222 ext_cng_chan_ind->session_id =
223 session_entry->smeSessionId;
224
225 /* No need to extract op mode as BW will be decided in
226 * in SAP FSM depending on previous BW.
227 */
228 ext_cng_chan_ind->new_chan_freq = target_freq;
229
230 mmh_msg.type = eWNI_SME_EXT_CHANGE_CHANNEL_IND;
231 mmh_msg.bodyptr = ext_cng_chan_ind;
232 mmh_msg.bodyval = 0;
233 lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg);
234 }
235 return;
236 } /*** end lim_process_ext_channel_switch_action_frame() ***/
237
238 /**
239 * __lim_process_operating_mode_action_frame() - To process op mode frames
240 * @mac_ctx: pointer to mac context
241 * @rx_pkt_info: pointer to received packet info
242 * @session: pointer to session
243 *
244 * This routine is called to process operating mode action frames
245 *
246 * Return: None
247 */
__lim_process_operating_mode_action_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)248 static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ctx,
249 uint8_t *rx_pkt_info, struct pe_session *session)
250 {
251
252 tpSirMacMgmtHdr mac_hdr;
253 uint8_t *body_ptr;
254 tDot11fOperatingMode *operating_mode_frm;
255 uint32_t frame_len;
256 uint32_t status;
257 tpDphHashNode sta_ptr;
258 uint16_t aid;
259 enum phy_ch_width ch_bw = 0;
260
261 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
262 body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
263 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
264
265 pe_debug("Received Operating Mode action frame");
266
267 /*
268 * Ignore opmode change during channel change The opmode will be updated
269 * with the beacons on new channel once the AP move to new channel.
270 */
271 if (session->ch_switch_in_progress) {
272 pe_debug("Ignore opmode change as channel switch is in progress");
273 return;
274 }
275 operating_mode_frm = qdf_mem_malloc(sizeof(*operating_mode_frm));
276 if (!operating_mode_frm)
277 return;
278
279 /* Unpack channel switch frame */
280 status = dot11f_unpack_operating_mode(mac_ctx, body_ptr, frame_len,
281 operating_mode_frm, false);
282 if (DOT11F_FAILED(status)) {
283 pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
284 status, frame_len);
285 qdf_mem_free(operating_mode_frm);
286 return;
287 } else if (DOT11F_WARNED(status)) {
288 pe_warn("warnings while unpacking (0x%08x, %d bytes):",
289 status, frame_len);
290 }
291 sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
292 &session->dph.dphHashTable);
293
294 if (!sta_ptr) {
295 pe_err("Station context not found");
296 goto end;
297 }
298
299 lim_update_nss(mac_ctx, sta_ptr,
300 operating_mode_frm->OperatingMode.rxNSS, session);
301
302 if (lim_update_channel_width(mac_ctx, sta_ptr, session,
303 operating_mode_frm->OperatingMode.chanWidth,
304 &ch_bw))
305 wlan_son_deliver_opmode(session->vdev,
306 ch_bw,
307 sta_ptr->vhtSupportedRxNss,
308 mac_hdr->sa);
309
310 end:
311 qdf_mem_free(operating_mode_frm);
312 return;
313 }
314
315 /**
316 * __lim_process_gid_management_action_frame() - To process group-id mgmt frames
317 * @mac_ctx: Pointer to mac context
318 * @rx_pkt_info: Rx packet info
319 * @session: pointer to session
320 *
321 * This routine will be called to process group id management frames
322 *
323 * Return: none
324 */
325 static void
__lim_process_gid_management_action_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)326 __lim_process_gid_management_action_frame(struct mac_context *mac_ctx,
327 uint8_t *rx_pkt_info,
328 struct pe_session *session)
329 {
330 uint8_t *body_ptr;
331 uint16_t aid;
332 uint32_t frame_len, status, membership = 0, usr_position = 0;
333 uint32_t *mem_lower, *mem_upper, *mem_cur;
334 tpSirMacMgmtHdr mac_hdr;
335 tDot11fVHTGidManagementActionFrame *gid_mgmt_frame;
336 tpDphHashNode sta_ptr;
337 struct sDot11fFfVhtMembershipStatusArray *vht_member_status = NULL;
338 struct sDot11fFfVhtUserPositionArray *vht_user_position = NULL;
339
340 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
341 body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
342 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
343
344 pe_debug("Received GID Management action frame");
345 gid_mgmt_frame = qdf_mem_malloc(sizeof(*gid_mgmt_frame));
346 if (!gid_mgmt_frame)
347 return;
348
349 /* Unpack Gid Management Action frame */
350 status = dot11f_unpack_vht_gid_management_action_frame(mac_ctx,
351 body_ptr, frame_len, gid_mgmt_frame, false);
352 if (DOT11F_FAILED(status)) {
353 pe_err("Fail to parse an Grp id frame (0x%08x, %d bytes):",
354 status, frame_len);
355 qdf_mem_free(gid_mgmt_frame);
356 return;
357 } else if (DOT11F_WARNED(status)) {
358 pe_warn("warnings while unpacking Grp id frm (0x%08x, %d bytes):",
359 status, frame_len);
360 }
361 sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
362 &session->dph.dphHashTable);
363 if (!sta_ptr) {
364 pe_err("Failed to get STA entry from hash table");
365 goto out;
366 }
367
368 pe_debug(" MAC: %0x:%0x:%0x:%0x:%0x:%0x",
369 mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2],
370 mac_hdr->sa[3], mac_hdr->sa[4], mac_hdr->sa[5]);
371 vht_member_status = &gid_mgmt_frame->VhtMembershipStatusArray;
372 mem_lower = (uint32_t *) vht_member_status->membershipStatusArray;
373 mem_upper = (uint32_t *) &vht_member_status->membershipStatusArray[4];
374
375 if (*mem_lower && *mem_upper) {
376 pe_err("rcved frame with mult group ID set");
377 goto out;
378 }
379 if (*mem_lower) {
380 mem_cur = mem_lower;
381 } else if (*mem_upper) {
382 mem_cur = mem_upper;
383 membership += sizeof(uint32_t);
384 } else {
385 pe_err("rcved Gid frame with no group ID set");
386 goto out;
387 }
388 while (!(*mem_cur & 1)) {
389 *mem_cur >>= 1;
390 ++membership;
391 }
392 if (*mem_cur) {
393 pe_err("rcved frame with mult group ID set");
394 goto out;
395 }
396
397 /*Just read the last two bits */
398 vht_user_position = &gid_mgmt_frame->VhtUserPositionArray;
399 usr_position = vht_user_position->userPositionArray[membership] & 0x3;
400 lim_check_membership_user_position(mac_ctx, session, membership,
401 usr_position);
402 out:
403 qdf_mem_free(gid_mgmt_frame);
404 return;
405 }
406
407 static void
__lim_process_add_ts_req(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)408 __lim_process_add_ts_req(struct mac_context *mac, uint8_t *pRxPacketInfo,
409 struct pe_session *pe_session)
410 {
411 }
412
413 /**
414 * lim_is_medium_time_valid() - To check whether AP sends ADD TS response for
415 * an AC with zero medium time and ACM is enabled
416 * @mac_ctx: Pointer to mac context
417 * @pe_session: pointer to session
418 * @addts: Add TS resp buffer
419 *
420 * Return: false if ADD TS response frame for an AC has 0 as medium time.
421 */
422 static bool
lim_is_medium_time_valid(struct mac_context * mac,struct pe_session * pe_session,tSirAddtsRspInfo addts)423 lim_is_medium_time_valid(struct mac_context *mac, struct pe_session *pe_session,
424 tSirAddtsRspInfo addts)
425 {
426 struct mac_ts_info *ts_info = &addts.tspec.tsinfo;
427 uint16_t user_priority = ts_info->traffic.userPrio;
428 uint8_t ac = upToAc(user_priority);
429 bool is_acm = false;
430
431 if (pe_session->wmm_params.present) {
432 switch (ac) {
433 case QCA_WLAN_AC_BE:
434 if (pe_session->wmm_params.acbe_acm)
435 is_acm = true;
436 break;
437 case QCA_WLAN_AC_BK:
438 if (pe_session->wmm_params.acbk_acm)
439 is_acm = true;
440 break;
441 case QCA_WLAN_AC_VI:
442 if (pe_session->wmm_params.acvi_acm)
443 is_acm = true;
444 break;
445 case QCA_WLAN_AC_VO:
446 if (pe_session->wmm_params.acvo_acm)
447 is_acm = true;
448 break;
449 default:
450 pe_debug("Unknown AC:%d", ac);
451 break;
452 }
453 }
454 /*
455 * If AP sends ADD TS response for an AC with medium time as 0
456 * and acm disabled treat it as ADD TS failure.
457 */
458 if (!addts.tspec.mediumTime && is_acm) {
459 pe_debug("medium time 0 and ACM is mandatory. ADDTS failed");
460 return false;
461 }
462
463 return true;
464 }
465
466 /**
467 * __lim_process_add_ts_rsp() - To process add ts response frame
468 * @mac_ctx: pointer to mac context
469 * @rx_pkt_info: Received packet info
470 * @session: pointer to session
471 *
472 * This routine is to handle add ts response frame
473 *
474 * Return: none
475 */
__lim_process_add_ts_rsp(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)476 static void __lim_process_add_ts_rsp(struct mac_context *mac_ctx,
477 uint8_t *rx_pkt_info, struct pe_session *session)
478 {
479 tSirAddtsRspInfo addts;
480 QDF_STATUS retval;
481 tpSirMacMgmtHdr mac_hdr;
482 tpDphHashNode sta_ptr;
483 uint16_t aid;
484 uint32_t frameLen;
485 uint8_t *body_ptr;
486 tpLimTspecInfo tspec_info;
487 uint8_t ac;
488 tpDphHashNode sta_ds_ptr = NULL;
489 uint8_t rsp_reqd = 1;
490 uint32_t cfg_len;
491 tSirMacAddr peer_macaddr;
492
493 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
494 body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
495 frameLen = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
496
497 pe_warn("Recv AddTs Response");
498 if (LIM_IS_AP_ROLE(session)) {
499 pe_warn("AddTsRsp recvd at AP: ignoring");
500 return;
501 }
502
503 sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
504 &session->dph.dphHashTable);
505 if (!sta_ptr) {
506 pe_err("Station context not found - ignoring AddTsRsp");
507 return;
508 }
509
510 retval = sir_convert_addts_rsp2_struct(mac_ctx, body_ptr,
511 frameLen, &addts);
512 if (retval != QDF_STATUS_SUCCESS) {
513 pe_err("AddTsRsp parsing failed %d", retval);
514 return;
515 }
516 /*
517 * don't have to check for qos/wme capabilities since we wouldn't have
518 * this flag set otherwise
519 */
520 if (!mac_ctx->lim.gLimAddtsSent) {
521 /* we never sent an addts request! */
522 pe_warn("rx AddTsRsp but no req was ever sent-ignoring");
523 return;
524 }
525
526 if (mac_ctx->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken) {
527 pe_warn("token mismatch got: %d exp: %d - ignoring",
528 addts.dialogToken,
529 mac_ctx->lim.gLimAddtsReq.req.dialogToken);
530 return;
531 }
532
533 /*
534 * for successful addts response, try to add the classifier.
535 * if this fails for any reason, we should send a delts request to the
536 * ap for now, its ok not to send a delts since we are going to add
537 * support for multiple tclas soon and until then we won't send any
538 * addts requests with multiple tclas elements anyway.
539 * In case of addClassifier failure, we just let the addts timer run out
540 */
541 if (((addts.tspec.tsinfo.traffic.accessPolicy ==
542 SIR_MAC_ACCESSPOLICY_HCCA) ||
543 (addts.tspec.tsinfo.traffic.accessPolicy ==
544 SIR_MAC_ACCESSPOLICY_BOTH)) &&
545 (addts.status == STATUS_SUCCESS)) {
546 /* add the classifier - this should always succeed */
547 if (addts.numTclas > 1) {
548 /* currently no support for multiple tclas elements */
549 pe_err("Sta: %d Too many Tclas: %d 1 supported",
550 aid, addts.numTclas);
551 return;
552 } else if (addts.numTclas == 1) {
553 pe_debug("Response from STA: %d tsid: %d UP: %d OK!",
554 aid, addts.tspec.tsinfo.traffic.tsid,
555 addts.tspec.tsinfo.traffic.userPrio);
556 }
557 }
558
559 pe_debug("Recv AddTsRsp: tsid: %d UP: %d status: %d",
560 addts.tspec.tsinfo.traffic.tsid,
561 addts.tspec.tsinfo.traffic.userPrio, addts.status);
562
563 /*
564 * Change the status to failure and fallthrough to send response
565 * to SME to cleanup the flow.
566 */
567 if (addts.tspec.tsinfo.traffic.direction != SIR_MAC_DIRECTION_DNLINK &&
568 !lim_is_medium_time_valid(mac_ctx, session, addts))
569 addts.status = STATUS_UNSPECIFIED_FAILURE;
570
571 /* deactivate the response timer */
572 lim_deactivate_and_change_timer(mac_ctx, eLIM_ADDTS_RSP_TIMER);
573
574 if (addts.status != STATUS_SUCCESS) {
575 pe_debug("Recv AddTsRsp: tsid: %d UP: %d status: %d",
576 addts.tspec.tsinfo.traffic.tsid,
577 addts.tspec.tsinfo.traffic.userPrio, addts.status);
578 lim_send_sme_addts_rsp(mac_ctx, true, addts.status, session,
579 addts.tspec, session->smeSessionId);
580
581 /* clear the addts flag */
582 mac_ctx->lim.gLimAddtsSent = false;
583
584 return;
585 }
586 #ifdef FEATURE_WLAN_ESE
587 if (addts.tsmPresent) {
588 pe_debug("TSM IE Present");
589 session->eseContext.tsm.tid =
590 addts.tspec.tsinfo.traffic.userPrio;
591 qdf_mem_copy(&session->eseContext.tsm.tsmInfo,
592 &addts.tsmIE, sizeof(struct ese_tsm_ie));
593 lim_send_sme_tsm_ie_ind(mac_ctx, session, addts.tsmIE.tsid,
594 addts.tsmIE.state,
595 addts.tsmIE.msmt_interval);
596 }
597 #endif
598 /*
599 * Since AddTS response was successful, check for the PSB flag
600 * and directional flag inside the TS Info field.
601 * An AC is trigger enabled AC if the PSB subfield is set to 1
602 * in the uplink direction.
603 * An AC is delivery enabled AC if the PSB subfield is set to 1
604 * in the downlink direction.
605 * An AC is trigger and delivery enabled AC if the PSB subfield
606 * is set to 1 in the bi-direction field.
607 */
608 if (addts.tspec.tsinfo.traffic.psb == 1)
609 lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
610 &addts.tspec.tsinfo,
611 SET_UAPSD_MASK);
612 else
613 lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
614 &addts.tspec.tsinfo,
615 CLEAR_UAPSD_MASK);
616
617 /*
618 * ADDTS success, so AC is now admitted. We shall now use the default
619 * EDCA parameters as advertised by AP and send the updated EDCA params
620 * to HAL.
621 */
622 ac = upToAc(addts.tspec.tsinfo.traffic.userPrio);
623 if (addts.tspec.tsinfo.traffic.direction ==
624 SIR_MAC_DIRECTION_UPLINK) {
625 session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |=
626 (1 << ac);
627 } else if (addts.tspec.tsinfo.traffic.direction ==
628 SIR_MAC_DIRECTION_DNLINK) {
629 session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |=
630 (1 << ac);
631 } else if (addts.tspec.tsinfo.traffic.direction ==
632 SIR_MAC_DIRECTION_BIDIR) {
633 session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |=
634 (1 << ac);
635 session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |=
636 (1 << ac);
637 }
638 lim_set_active_edca_params(mac_ctx, session->gLimEdcaParams,
639 session);
640 sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
641 &session->dph.dphHashTable);
642 if (sta_ds_ptr)
643 lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
644 session->vdev_id, false);
645 else
646 pe_err("Self entry missing in Hash Table");
647 sir_copy_mac_addr(peer_macaddr, session->bssId);
648 /* if schedule is not present then add TSPEC with svcInterval as 0. */
649 if (!addts.schedulePresent)
650 addts.schedule.svcInterval = 0;
651 if (QDF_STATUS_SUCCESS !=
652 lim_tspec_add(mac_ctx, sta_ptr->staAddr, sta_ptr->assocId,
653 &addts.tspec, addts.schedule.svcInterval, &tspec_info)) {
654 pe_err("Adding entry in lim Tspec Table failed");
655 lim_send_delts_req_action_frame(mac_ctx, peer_macaddr, rsp_reqd,
656 &addts.tspec.tsinfo,
657 &addts.tspec, session);
658 mac_ctx->lim.gLimAddtsSent = false;
659 return;
660 /*
661 * Error handling. send the response with error status.
662 * need to send DelTS to tear down the TSPEC status.
663 */
664 }
665 if ((addts.tspec.tsinfo.traffic.accessPolicy !=
666 SIR_MAC_ACCESSPOLICY_EDCA) ||
667 ((upToAc(addts.tspec.tsinfo.traffic.userPrio) < QCA_WLAN_AC_ALL))) {
668 #ifdef FEATURE_WLAN_ESE
669 retval = lim_send_hal_msg_add_ts(mac_ctx,
670 tspec_info->idx,
671 addts.tspec, session->peSessionId,
672 addts.tsmIE.msmt_interval);
673 #else
674 retval = lim_send_hal_msg_add_ts(mac_ctx,
675 tspec_info->idx,
676 addts.tspec, session->peSessionId);
677 #endif
678 if (QDF_STATUS_SUCCESS != retval) {
679 lim_admit_control_delete_ts(mac_ctx, sta_ptr->assocId,
680 &addts.tspec.tsinfo, NULL, &tspec_info->idx);
681
682 /* Send DELTS action frame to AP */
683 cfg_len = sizeof(tSirMacAddr);
684 lim_send_delts_req_action_frame(mac_ctx, peer_macaddr,
685 rsp_reqd, &addts.tspec.tsinfo,
686 &addts.tspec, session);
687 lim_send_sme_addts_rsp(mac_ctx, true, retval,
688 session, addts.tspec,
689 session->smeSessionId);
690 mac_ctx->lim.gLimAddtsSent = false;
691 return;
692 }
693 pe_debug("AddTsRsp received successfully UP: %d TSID: %d",
694 addts.tspec.tsinfo.traffic.userPrio,
695 addts.tspec.tsinfo.traffic.tsid);
696 } else {
697 pe_debug("AddTsRsp received successfully UP: %d TSID: %d",
698 addts.tspec.tsinfo.traffic.userPrio,
699 addts.tspec.tsinfo.traffic.tsid);
700 pe_debug("no ACM: Bypass sending WMA_ADD_TS_REQ to HAL");
701 lim_send_sme_addts_rsp(mac_ctx, true, eSIR_SME_SUCCESS,
702 session, addts.tspec,
703 session->smeSessionId);
704 }
705 /* clear the addts flag */
706 mac_ctx->lim.gLimAddtsSent = false;
707 return;
708 }
709
710 /**
711 * __lim_process_del_ts_req() - To process del ts response frame
712 * @mac_ctx: pointer to mac context
713 * @rx_pkt_info: Received packet info
714 * @session: pointer to session
715 *
716 * This routine is to handle del ts request frame
717 *
718 * Return: none
719 */
__lim_process_del_ts_req(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)720 static void __lim_process_del_ts_req(struct mac_context *mac_ctx,
721 uint8_t *rx_pkt_info, struct pe_session *session)
722 {
723 QDF_STATUS retval;
724 struct delts_req_info delts;
725 tpSirMacMgmtHdr mac_hdr;
726 tpDphHashNode sta_ptr;
727 uint32_t frame_len;
728 uint16_t aid;
729 uint8_t *body_ptr;
730 uint8_t ts_status;
731 struct mac_ts_info *tsinfo;
732 uint8_t tspec_idx;
733 uint8_t ac;
734 tpDphHashNode sta_ds_ptr = NULL;
735
736 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
737 body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
738 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
739
740 sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
741 &session->dph.dphHashTable);
742 if (!sta_ptr) {
743 pe_err("Station context not found - ignoring DelTs");
744 return;
745 }
746 /* parse the delts request */
747 retval = sir_convert_delts_req2_struct(mac_ctx, body_ptr,
748 frame_len, &delts);
749 if (retval != QDF_STATUS_SUCCESS) {
750 pe_err("DelTs parsing failed %d", retval);
751 return;
752 }
753
754 if (delts.wmeTspecPresent) {
755 if ((!session->limWmeEnabled) || (!sta_ptr->wmeEnabled)) {
756 pe_warn("Ignore delts req: wme not enabled");
757 return;
758 }
759 pe_debug("WME Delts received");
760 } else if ((session->limQosEnabled) && sta_ptr->lleEnabled) {
761 pe_debug("11e QoS Delts received");
762 } else if ((session->limWsmEnabled) && sta_ptr->wsmEnabled) {
763 pe_debug("WSM Delts received");
764 } else {
765 pe_warn("Ignoring delts request: qos not enabled/capable");
766 return;
767 }
768
769 tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo;
770
771 /* if no Admit Control, ignore the request */
772 if (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) {
773 if (upToAc(tsinfo->traffic.userPrio) >= QCA_WLAN_AC_ALL) {
774 pe_warn("DelTs with UP: %d has no AC - ignoring req",
775 tsinfo->traffic.userPrio);
776 return;
777 }
778 }
779
780 if (!LIM_IS_AP_ROLE(session))
781 lim_send_sme_delts_ind(mac_ctx, &delts, aid, session);
782
783 /* try to delete the TS */
784 if (QDF_STATUS_SUCCESS !=
785 lim_admit_control_delete_ts(mac_ctx, sta_ptr->assocId, tsinfo,
786 &ts_status, &tspec_idx)) {
787 pe_warn("Unable to Delete TS");
788 return;
789 } else if (!((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA)
790 || (tsinfo->traffic.accessPolicy ==
791 SIR_MAC_ACCESSPOLICY_BOTH))){
792 /* send message to HAL to delete TS */
793 if (QDF_STATUS_SUCCESS != lim_send_hal_msg_del_ts(mac_ctx,
794 tspec_idx,
795 delts, session->peSessionId,
796 session->bssId)) {
797 pe_warn("DelTs with UP: %d failed ignoring request",
798 tsinfo->traffic.userPrio);
799 return;
800 }
801 }
802 /*
803 * We successfully deleted the TSPEC. Update the dynamic UAPSD Mask.
804 * The AC for this TSPEC is no longer trigger enabled if this Tspec
805 * was set-up in uplink direction only.
806 * The AC for this TSPEC is no longer delivery enabled if this Tspec
807 * was set-up in downlink direction only.
808 * The AC for this TSPEC is no longer triiger enabled and delivery
809 * enabled if this Tspec was a bidirectional TSPEC.
810 */
811 lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
812 tsinfo, CLEAR_UAPSD_MASK);
813 /*
814 * We're deleting the TSPEC.
815 * The AC for this TSPEC is no longer admitted in uplink/downlink
816 * direction if this TSPEC was set-up in uplink/downlink direction only.
817 * The AC for this TSPEC is no longer admitted in both uplink and
818 * downlink directions if this TSPEC was a bi-directional TSPEC.
819 * If ACM is set for this AC and this AC is admitted only in downlink
820 * direction, PE needs to downgrade the EDCA parameter
821 * (for the AC for which TS is being deleted) to the
822 * next best AC for which ACM is not enabled, and send the
823 * updated values to HAL.
824 */
825 ac = upToAc(tsinfo->traffic.userPrio);
826 if (tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) {
827 session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
828 ~(1 << ac);
829 } else if (tsinfo->traffic.direction ==
830 SIR_MAC_DIRECTION_DNLINK) {
831 session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
832 ~(1 << ac);
833 } else if (tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) {
834 session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
835 ~(1 << ac);
836 session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
837 ~(1 << ac);
838 }
839 lim_set_active_edca_params(mac_ctx, session->gLimEdcaParams,
840 session);
841 sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
842 &session->dph.dphHashTable);
843 if (sta_ds_ptr)
844 lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
845 session->vdev_id, false);
846 else
847 pe_err("Self entry missing in Hash Table");
848
849 pe_debug("DeleteTS succeeded");
850 #ifdef FEATURE_WLAN_ESE
851 lim_send_sme_tsm_ie_ind(mac_ctx, session, 0, 0, 0);
852 #endif
853 }
854
855 /**
856 * __lim_process_qos_map_configure_frame() - to process QoS map configure frame
857 * @mac_ctx: pointer to mac context
858 * @rx_pkt_info: pointer to received packet info
859 * @session: pointer to session
860 *
861 * This routine will called to process qos map configure frame
862 *
863 * Return: none
864 */
__lim_process_qos_map_configure_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)865 static void __lim_process_qos_map_configure_frame(struct mac_context *mac_ctx,
866 uint8_t *rx_pkt_info, struct pe_session *session)
867 {
868 tpSirMacMgmtHdr mac_hdr;
869 uint32_t frame_len;
870 uint8_t *body_ptr;
871 QDF_STATUS retval;
872
873 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
874 body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
875 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
876 retval = sir_convert_qos_map_configure_frame2_struct(mac_ctx,
877 body_ptr, frame_len, &session->QosMapSet);
878 if (retval != QDF_STATUS_SUCCESS) {
879 pe_err("QosMapConfigure frame parsing fail %d", retval);
880 return;
881 }
882 lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
883 (uint8_t *)mac_hdr,
884 frame_len + sizeof(tSirMacMgmtHdr), 0,
885 WMA_GET_RX_FREQ(rx_pkt_info),
886 WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
887 RXMGMT_FLAG_NONE);
888 }
889
890 #ifdef ANI_SUPPORT_11H
891 static void
__lim_process_basic_meas_req(struct mac_context * mac,tpSirMacMeasReqActionFrame pMeasReqFrame,tSirMacAddr peerMacAddr,struct pe_session * pe_session)892 __lim_process_basic_meas_req(struct mac_context *mac,
893 tpSirMacMeasReqActionFrame pMeasReqFrame,
894 tSirMacAddr peerMacAddr, struct pe_session *pe_session)
895 {
896 if (lim_send_meas_report_frame(mac, pMeasReqFrame,
897 peerMacAddr, pe_session) !=
898 QDF_STATUS_SUCCESS) {
899 pe_err("fail to send Basic Meas report");
900 return;
901 }
902 }
903 static void
__lim_process_cca_meas_req(struct mac_context * mac,tpSirMacMeasReqActionFrame pMeasReqFrame,tSirMacAddr peerMacAddr,struct pe_session * pe_session)904 __lim_process_cca_meas_req(struct mac_context *mac,
905 tpSirMacMeasReqActionFrame pMeasReqFrame,
906 tSirMacAddr peerMacAddr, struct pe_session *pe_session)
907 {
908 if (lim_send_meas_report_frame(mac, pMeasReqFrame,
909 peerMacAddr, pe_session) !=
910 QDF_STATUS_SUCCESS) {
911 pe_err("fail to send CCA Meas report");
912 return;
913 }
914 }
915 static void
__lim_process_rpi_meas_req(struct mac_context * mac,tpSirMacMeasReqActionFrame pMeasReqFrame,tSirMacAddr peerMacAddr,struct pe_session * pe_session)916 __lim_process_rpi_meas_req(struct mac_context *mac,
917 tpSirMacMeasReqActionFrame pMeasReqFrame,
918 tSirMacAddr peerMacAddr, struct pe_session *pe_session)
919 {
920 if (lim_send_meas_report_frame(mac, pMeasReqFrame,
921 peerMacAddr, pe_session) !=
922 QDF_STATUS_SUCCESS) {
923 pe_err("fail to send RPI Meas report");
924 return;
925 }
926 }
927 static void
__lim_process_measurement_request_frame(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)928 __lim_process_measurement_request_frame(struct mac_context *mac,
929 uint8_t *pRxPacketInfo,
930 struct pe_session *pe_session)
931 {
932 tpSirMacMgmtHdr pHdr;
933 uint8_t *pBody;
934 tpSirMacMeasReqActionFrame pMeasReqFrame;
935 uint32_t frameLen;
936
937 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
938 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
939 frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
940
941 pMeasReqFrame = qdf_mem_malloc(sizeof(tSirMacMeasReqActionFrame));
942 if (!pMeasReqFrame)
943 return;
944
945 if (sir_convert_meas_req_frame2_struct(mac, pBody, pMeasReqFrame, frameLen)
946 != QDF_STATUS_SUCCESS) {
947 pe_warn("Rcv invalid Measurement Request Action Frame");
948 return;
949 }
950 switch (pMeasReqFrame->measReqIE.measType) {
951 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
952 __lim_process_basic_meas_req(mac, pMeasReqFrame, pHdr->sa,
953 pe_session);
954 break;
955 case SIR_MAC_CCA_MEASUREMENT_TYPE:
956 __lim_process_cca_meas_req(mac, pMeasReqFrame, pHdr->sa,
957 pe_session);
958 break;
959 case SIR_MAC_RPI_MEASUREMENT_TYPE:
960 __lim_process_rpi_meas_req(mac, pMeasReqFrame, pHdr->sa,
961 pe_session);
962 break;
963 default:
964 pe_warn("Unknown Measurement Type: %d",
965 pMeasReqFrame->measReqIE.measType);
966 break;
967 }
968 } /*** end limProcessMeasurementRequestFrame ***/
969 static void
__lim_process_tpc_request_frame(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)970 __lim_process_tpc_request_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
971 struct pe_session *pe_session)
972 {
973 tpSirMacMgmtHdr pHdr;
974 uint8_t *pBody;
975 tpSirMacTpcReqActionFrame pTpcReqFrame;
976 uint32_t frameLen;
977
978 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
979 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
980 frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
981 pe_debug("****LIM: Processing TPC Request from peer ****");
982
983 pTpcReqFrame = qdf_mem_malloc(sizeof(tSirMacTpcReqActionFrame));
984 if (!pTpcReqFrame)
985 return;
986
987 if (sir_convert_tpc_req_frame2_struct(mac, pBody, pTpcReqFrame, frameLen) !=
988 QDF_STATUS_SUCCESS) {
989 pe_warn("Rcv invalid TPC Req Action Frame");
990 return;
991 }
992 if (lim_send_tpc_report_frame(mac,
993 pTpcReqFrame,
994 pHdr->sa, pe_session) != QDF_STATUS_SUCCESS) {
995 pe_err("fail to send TPC Report Frame");
996 return;
997 }
998 }
999 #endif
1000
1001 static void
__lim_process_sm_power_save_update(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)1002 __lim_process_sm_power_save_update(struct mac_context *mac, uint8_t *pRxPacketInfo,
1003 struct pe_session *pe_session)
1004 {
1005
1006 tpSirMacMgmtHdr pHdr;
1007 tDot11fSMPowerSave frmSMPower;
1008 tSirMacHTMIMOPowerSaveState state;
1009 tpDphHashNode pSta;
1010 uint16_t aid;
1011 uint32_t frameLen, nStatus;
1012 uint8_t *pBody;
1013
1014 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
1015 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
1016 frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1017
1018 pSta =
1019 dph_lookup_hash_entry(mac, pHdr->sa, &aid,
1020 &pe_session->dph.dphHashTable);
1021 if (!pSta) {
1022 pe_err("STA context not found - ignoring UpdateSM PSave Mode from SA: "QDF_MAC_ADDR_FMT,
1023 QDF_MAC_ADDR_REF(pHdr->sa));
1024 return;
1025 }
1026
1027 /**Unpack the received frame */
1028 nStatus = dot11f_unpack_sm_power_save(mac, pBody, frameLen,
1029 &frmSMPower, false);
1030
1031 if (DOT11F_FAILED(nStatus)) {
1032 pe_err("Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):",
1033 nStatus, frameLen);
1034 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
1035 pBody, frameLen);
1036 return;
1037 } else if (DOT11F_WARNED(nStatus)) {
1038 pe_debug("There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):",
1039 nStatus, frameLen);
1040 }
1041
1042 pe_debug("Received SM Power save Mode update Frame with PS_Enable: %d"
1043 "PS Mode: %d", frmSMPower.SMPowerModeSet.PowerSave_En,
1044 frmSMPower.SMPowerModeSet.Mode);
1045
1046 /** Update in the DPH Table about the Update in the SM Power Save mode*/
1047 if (frmSMPower.SMPowerModeSet.PowerSave_En
1048 && frmSMPower.SMPowerModeSet.Mode)
1049 state = eSIR_HT_MIMO_PS_DYNAMIC;
1050 else if ((frmSMPower.SMPowerModeSet.PowerSave_En)
1051 && (frmSMPower.SMPowerModeSet.Mode == 0))
1052 state = eSIR_HT_MIMO_PS_STATIC;
1053 else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0)
1054 && (frmSMPower.SMPowerModeSet.Mode == 0))
1055 state = eSIR_HT_MIMO_PS_NO_LIMIT;
1056 else {
1057 pe_warn("Received SM Power save Mode update Frame with invalid mode");
1058 return;
1059 }
1060
1061 if (state == pSta->htMIMOPSState) {
1062 pe_err("The PEER is already set in the same mode");
1063 return;
1064 }
1065
1066 /** Update in the HAL Station Table for the Update of the Protection Mode */
1067 pSta->htMIMOPSState = state;
1068 lim_post_sm_state_update(mac, pSta->htMIMOPSState,
1069 pSta->staAddr, pe_session->smeSessionId);
1070 wlan_son_deliver_smps(pe_session->vdev,
1071 (eSIR_HT_MIMO_PS_STATIC == state) ? 1 : 0,
1072 pSta->staAddr);
1073 }
1074
1075
1076 static void
__lim_process_radio_measure_request(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)1077 __lim_process_radio_measure_request(struct mac_context *mac, uint8_t *pRxPacketInfo,
1078 struct pe_session *pe_session)
1079 {
1080 tpSirMacMgmtHdr pHdr;
1081 tDot11fRadioMeasurementRequest *frm;
1082 uint32_t frameLen, nStatus;
1083 uint8_t *pBody;
1084 uint16_t curr_seq_num;
1085
1086 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
1087 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
1088 frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1089
1090 if (!pe_session) {
1091 return;
1092 }
1093
1094 curr_seq_num = ((pHdr->seqControl.seqNumHi <<
1095 HIGH_SEQ_NUM_OFFSET) |
1096 pHdr->seqControl.seqNumLo);
1097 if (curr_seq_num == mac->rrm.rrmPEContext.prev_rrm_report_seq_num &&
1098 (mac->rrm.rrmPEContext.pCurrentReq[DEFAULT_RRM_IDX] ||
1099 mac->rrm.rrmPEContext.pCurrentReq[DEFAULT_RRM_IDX + 1])) {
1100 pe_err("rrm report req frame, seq num: %d is already in progress, drop it",
1101 curr_seq_num);
1102 return;
1103 }
1104 /* Save seq no of currently processing rrm report req frame */
1105 mac->rrm.rrmPEContext.prev_rrm_report_seq_num = curr_seq_num;
1106
1107 frm = qdf_mem_malloc(sizeof(*frm));
1108 if (!frm)
1109 return;
1110
1111 /**Unpack the received frame */
1112 nStatus = dot11f_unpack_radio_measurement_request(mac, pBody,
1113 frameLen, frm, false);
1114
1115 if (DOT11F_FAILED(nStatus)) {
1116 pe_err("Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):",
1117 nStatus, frameLen);
1118 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
1119 pBody, frameLen);
1120 goto err;
1121 } else if (DOT11F_WARNED(nStatus)) {
1122 pe_debug("Warnings while unpacking a Radio Measure request (0x%08x, %d bytes):",
1123 nStatus, frameLen);
1124 }
1125 /* Call rrm function to handle the request. */
1126
1127 pe_debug("vdev: %d Received rrm req from sa addr:"QDF_MAC_ADDR_FMT" bssId:"QDF_MAC_ADDR_FMT" session addr:"QDF_MAC_ADDR_FMT" session self addr:"QDF_MAC_ADDR_FMT"",
1128 pe_session->vdev_id,
1129 QDF_MAC_ADDR_REF(pHdr->sa),
1130 QDF_MAC_ADDR_REF(pHdr->bssId),
1131 QDF_MAC_ADDR_REF(pe_session->bssId),
1132 QDF_MAC_ADDR_REF(pe_session->self_mac_addr));
1133
1134 pe_debug("RX RRM - type %hu, sub type %hu, seq num[%d]",
1135 pHdr->fc.type, pHdr->fc.subType, curr_seq_num);
1136
1137 rrm_process_radio_measurement_request(mac, pe_session->bssId, frm,
1138 pe_session);
1139 err:
1140 qdf_mem_free(frm);
1141 }
1142
1143 static QDF_STATUS
__lim_process_link_measurement_req(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)1144 __lim_process_link_measurement_req(struct mac_context *mac, uint8_t *pRxPacketInfo,
1145 struct pe_session *pe_session)
1146 {
1147 tpSirMacMgmtHdr pHdr;
1148 tDot11fLinkMeasurementRequest frm;
1149 uint32_t frameLen, nStatus;
1150 uint8_t *pBody;
1151
1152 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
1153 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
1154 frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1155
1156 if (!pe_session) {
1157 return QDF_STATUS_E_FAILURE;
1158 }
1159
1160 /**Unpack the received frame */
1161 nStatus =
1162 dot11f_unpack_link_measurement_request(mac, pBody, frameLen,
1163 &frm, false);
1164
1165 if (DOT11F_FAILED(nStatus)) {
1166 pe_err("Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):",
1167 nStatus, frameLen);
1168 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
1169 pBody, frameLen);
1170 return QDF_STATUS_E_FAILURE;
1171 } else if (DOT11F_WARNED(nStatus)) {
1172 pe_debug("There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):",
1173 nStatus, frameLen);
1174 }
1175
1176 if (pe_session->sta_follows_sap_power) {
1177 pe_debug("STA power has changed, reject the link measurement request");
1178 return QDF_STATUS_E_FAILURE;
1179 }
1180 /* Call rrm function to handle the request. */
1181 return rrm_process_link_measurement_request(mac, pRxPacketInfo, &frm,
1182 pe_session);
1183
1184 }
1185
1186 static void
__lim_process_neighbor_report(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)1187 __lim_process_neighbor_report(struct mac_context *mac, uint8_t *pRxPacketInfo,
1188 struct pe_session *pe_session)
1189 {
1190 tpSirMacMgmtHdr pHdr;
1191 tDot11fNeighborReportResponse *pFrm;
1192 uint32_t frameLen, nStatus;
1193 uint8_t *pBody;
1194
1195 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
1196 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
1197 frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1198
1199 pFrm = qdf_mem_malloc(sizeof(tDot11fNeighborReportResponse));
1200 if (!pFrm)
1201 return;
1202
1203 if (!pe_session) {
1204 qdf_mem_free(pFrm);
1205 return;
1206 }
1207
1208 /**Unpack the received frame */
1209 nStatus =
1210 dot11f_unpack_neighbor_report_response(mac, pBody,
1211 frameLen, pFrm, false);
1212
1213 if (DOT11F_FAILED(nStatus)) {
1214 pe_err("Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):",
1215 nStatus, frameLen);
1216 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
1217 pBody, frameLen);
1218 qdf_mem_free(pFrm);
1219 return;
1220 } else if (DOT11F_WARNED(nStatus)) {
1221 pe_debug("There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):",
1222 nStatus, frameLen);
1223 }
1224
1225 /* Call rrm function to handle the request. */
1226 rrm_process_neighbor_report_response(mac, pFrm, pe_session);
1227
1228 qdf_mem_free(pFrm);
1229 }
1230
1231 static bool
lim_check_oci_match(struct mac_context * mac,struct pe_session * pe_session,uint8_t * ie,uint8_t * peer,uint32_t ie_len)1232 lim_check_oci_match(struct mac_context *mac, struct pe_session *pe_session,
1233 uint8_t *ie, uint8_t *peer, uint32_t ie_len)
1234 {
1235 const uint8_t *oci_ie, ext_id_param = WLAN_EXTN_ELEMID_OCI;
1236 tDot11fIEoci self_oci, peer_oci = {0};
1237 uint16_t peer_chan_width;
1238 uint16_t local_peer_chan_width = 0;
1239 uint8_t country_code[CDS_COUNTRY_CODE_LEN + 1];
1240 uint32_t status = DOT11F_PARSE_SUCCESS;
1241
1242 if (!lim_is_self_and_peer_ocv_capable(mac, peer, pe_session))
1243 return true;
1244
1245 if (ie_len < MIN_OCI_IE_LEN)
1246 return false;
1247
1248 oci_ie = wlan_get_ext_ie_ptr_from_ext_id(&ext_id_param,
1249 OCI_IE_OUI_SIZE,
1250 ie, ie_len);
1251 if (!oci_ie) {
1252 pe_err("OCV not found OCI in SA Query frame!");
1253 return false;
1254 }
1255
1256 /* OCV enabled, check the OCI information:
1257 * Element ID : 1 byte
1258 * Packet length : 1 byte
1259 * Element ID extension : 1 byte
1260 * Operating class : 1 byte
1261 * Primary channel : 1 byte
1262 * Freq_seg_1_ch_num : 1 byte
1263 */
1264 status = dot11f_unpack_ie_oci(mac,
1265 (uint8_t *)&oci_ie[OCI_IE_OP_CLS_OFFSET],
1266 oci_ie[SIR_MAC_IE_LEN_OFFSET] -
1267 ELE_ID_EXT_LEN,
1268 &peer_oci, false);
1269 if (!DOT11F_SUCCEEDED(status) || !peer_oci.present)
1270 return false;
1271
1272 wlan_reg_read_current_country(mac->psoc, country_code);
1273 peer_chan_width =
1274 wlan_reg_dmn_get_chanwidth_from_opclass_auto(
1275 country_code,
1276 peer_oci.prim_ch_num,
1277 peer_oci.op_class);
1278
1279 lim_fill_oci_params(mac, pe_session, &self_oci, peer,
1280 &local_peer_chan_width);
1281 if ((self_oci.op_class != peer_oci.op_class &&
1282 local_peer_chan_width > peer_chan_width) ||
1283 self_oci.prim_ch_num != peer_oci.prim_ch_num ||
1284 self_oci.freq_seg_1_ch_num != peer_oci.freq_seg_1_ch_num) {
1285 pe_err("OCI mismatch,self %d %d %d %d, peer %d %d %d %d",
1286 self_oci.op_class,
1287 self_oci.prim_ch_num,
1288 self_oci.freq_seg_1_ch_num,
1289 local_peer_chan_width,
1290 peer_oci.op_class,
1291 peer_oci.prim_ch_num,
1292 peer_oci.freq_seg_1_ch_num,
1293 peer_chan_width);
1294 return false;
1295 }
1296
1297 return true;
1298 }
1299
1300 /**
1301 * limProcessSAQueryRequestActionFrame
1302 *
1303 ***FUNCTION:
1304 * This function is called by lim_process_action_frame() upon
1305 * SA query request Action frame reception.
1306 *
1307 ***LOGIC:
1308 *
1309 ***ASSUMPTIONS:
1310 *
1311 ***NOTE:
1312 *
1313 * @param mac - Pointer to Global MAC structure
1314 * @param *pRxPacketInfo - Handle to the Rx packet info
1315 * @param pe_session - PE session entry
1316 *
1317 * @return None
1318 */
__lim_process_sa_query_request_action_frame(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)1319 static void __lim_process_sa_query_request_action_frame(struct mac_context *mac,
1320 uint8_t *pRxPacketInfo,
1321 struct pe_session *pe_session)
1322 {
1323 tpSirMacMgmtHdr mac_header;
1324 uint8_t *p_body;
1325 uint32_t frame_len;
1326 uint8_t transId[2];
1327 tpDphHashNode sta_ds;
1328 uint16_t aid;
1329
1330 /* Prima --- Below Macro not available in prima
1331 pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd);
1332 pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */
1333
1334 mac_header = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
1335 p_body = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
1336 frame_len = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1337
1338 if (frame_len < SA_QUERY_REQ_MIN_LEN) {
1339 pe_err("Invalid frame length %d", frame_len);
1340 return;
1341 }
1342 /* If this is an unprotected SA Query Request, then ignore it. */
1343 if (mac_header->fc.wep == 0)
1344 return;
1345
1346 /* 11w offload is enabled then firmware should not fwd this frame */
1347 if (LIM_IS_STA_ROLE(pe_session) && mac->pmf_offload) {
1348 pe_err("11w offload enabled, SA Query req isn't expected");
1349 return;
1350 }
1351
1352 /*Extract 11w trsansId from SA query request action frame
1353 In SA query response action frame we will send same transId
1354 In SA query request action frame:
1355 Category : 1 byte
1356 Action : 1 byte
1357 Transaction ID : 2 bytes */
1358 qdf_mem_copy(&transId[0], &p_body[2], 2);
1359
1360 sta_ds = dph_lookup_hash_entry(mac, mac_header->sa, &aid,
1361 &pe_session->dph.dphHashTable);
1362
1363 if (!lim_check_oci_match(mac, pe_session,
1364 p_body + SA_QUERY_IE_OFFSET,
1365 mac_header->sa,
1366 frame_len - SA_QUERY_IE_OFFSET)) {
1367 /*
1368 * In case of channel switch, last ocv frequency will be
1369 * different from current frquency.
1370 * If there is channel switch and OCI is invalid in sa_query,
1371 * deauth STA on new channel.
1372 */
1373 if (sta_ds && sta_ds->ocv_enabled &&
1374 sta_ds->last_ocv_done_freq != pe_session->curr_op_freq)
1375 lim_send_deauth_mgmt_frame(mac, REASON_OCI_MISMATCH,
1376 mac_header->sa, pe_session,
1377 false);
1378 return;
1379 }
1380
1381 /*
1382 * Update the last ocv done freq when OCI is valid.
1383 * To support above algo, if it is moved to the current freq.
1384 */
1385 if (sta_ds && sta_ds->ocv_enabled)
1386 sta_ds->last_ocv_done_freq = pe_session->curr_op_freq;
1387
1388 /* Send 11w SA query response action frame */
1389 if (lim_send_sa_query_response_frame(mac,
1390 transId,
1391 mac_header->sa,
1392 pe_session) != QDF_STATUS_SUCCESS) {
1393 pe_err("fail to send SA query response action frame");
1394 return;
1395 }
1396 }
1397
1398 /**
1399 * __lim_process_sa_query_response_action_frame
1400 *
1401 ***FUNCTION:
1402 * This function is called by lim_process_action_frame() upon
1403 * SA query response Action frame reception.
1404 *
1405 ***LOGIC:
1406 *
1407 ***ASSUMPTIONS:
1408 *
1409 ***NOTE:
1410 *
1411 * @param mac - Pointer to Global MAC structure
1412 * @param *pRxPacketInfo - Handle to the Rx packet info
1413 * @param pe_session - PE session entry
1414 * @return None
1415 */
__lim_process_sa_query_response_action_frame(struct mac_context * mac,uint8_t * pRxPacketInfo,struct pe_session * pe_session)1416 static void __lim_process_sa_query_response_action_frame(struct mac_context *mac,
1417 uint8_t *pRxPacketInfo,
1418 struct pe_session *pe_session)
1419 {
1420 tpSirMacMgmtHdr m_hdr;
1421 uint32_t frame_len;
1422 uint8_t *p_body;
1423 tpDphHashNode pSta;
1424 uint16_t aid;
1425 uint16_t transId;
1426 uint8_t retryNum;
1427
1428 m_hdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
1429 frame_len = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1430 p_body = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
1431 pe_debug("SA Query Response received");
1432
1433 if (frame_len < SA_QUERY_RESP_MIN_LEN) {
1434 pe_err("Invalid frame length %d", frame_len);
1435 return;
1436 }
1437 /* When a station, supplicant handles SA Query Response.
1438 * Forward to SME to HDD to wpa_supplicant.
1439 */
1440 if (LIM_IS_STA_ROLE(pe_session)) {
1441 lim_send_sme_mgmt_frame_ind(mac, m_hdr->fc.subType,
1442 (uint8_t *)m_hdr,
1443 frame_len + sizeof(tSirMacMgmtHdr),
1444 0,
1445 WMA_GET_RX_FREQ(pRxPacketInfo),
1446 WMA_GET_RX_RSSI_NORMALIZED(
1447 pRxPacketInfo), RXMGMT_FLAG_NONE);
1448 return;
1449 }
1450
1451 /* If this is an unprotected SA Query Response, then ignore it. */
1452 if (m_hdr->fc.wep == 0)
1453 return;
1454
1455 pSta =
1456 dph_lookup_hash_entry(mac, m_hdr->sa, &aid,
1457 &pe_session->dph.dphHashTable);
1458 if (!pSta)
1459 return;
1460
1461 pe_debug("SA Query Response source addr: %0x:%0x:%0x:%0x:%0x:%0x",
1462 m_hdr->sa[0], m_hdr->sa[1], m_hdr->sa[2], m_hdr->sa[3],
1463 m_hdr->sa[4], m_hdr->sa[5]);
1464 pe_debug("SA Query state for station: %d", pSta->pmfSaQueryState);
1465
1466 if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState)
1467 return;
1468
1469 /* Extract 11w trsansId from SA query response action frame
1470 In SA query response action frame:
1471 Category : 1 byte
1472 Action : 1 byte
1473 Transaction ID : 2 bytes */
1474 qdf_mem_copy(&transId, &p_body[2], 2);
1475
1476 /* If SA Query is in progress with the station and the station
1477 responds then the association request that triggered the SA
1478 query is from a rogue station, just go back to initial state. */
1479 for (retryNum = 0; retryNum <= pSta->pmfSaQueryRetryCount; retryNum++)
1480 if (transId == pSta->pmfSaQueryStartTransId + retryNum) {
1481 if (!lim_check_oci_match(mac, pe_session,
1482 p_body + SA_QUERY_IE_OFFSET,
1483 m_hdr->sa,
1484 frame_len -
1485 SA_QUERY_IE_OFFSET))
1486 return;
1487 pe_debug("Found matching SA Query Request - transaction ID: %d",
1488 transId);
1489 tx_timer_deactivate(&pSta->pmfSaQueryTimer);
1490 pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
1491 break;
1492 }
1493 }
1494
1495 /**
1496 * lim_drop_unprotected_action_frame
1497 *
1498 ***FUNCTION:
1499 * This function checks if an Action frame should be dropped since it is
1500 * a Robust Management Frame, it is unprotected, and it is received on a
1501 * connection where PMF is enabled.
1502 *
1503 ***LOGIC:
1504 *
1505 ***ASSUMPTIONS:
1506 *
1507 ***NOTE:
1508 *
1509 * @param mac - Global MAC structure
1510 * @param pe_session - PE session entry
1511 * @param pHdr - Frame header
1512 * @param category - Action frame category
1513 * @return true if frame should be dropped
1514 */
1515
1516 static bool
lim_drop_unprotected_action_frame(struct mac_context * mac,struct pe_session * pe_session,tpSirMacMgmtHdr pHdr,uint8_t category)1517 lim_drop_unprotected_action_frame(struct mac_context *mac, struct pe_session *pe_session,
1518 tpSirMacMgmtHdr pHdr, uint8_t category)
1519 {
1520 uint16_t aid;
1521 tpDphHashNode sta;
1522 bool rmfConnection = false;
1523
1524 sta = dph_lookup_hash_entry(mac, pHdr->sa, &aid,
1525 &pe_session->dph.dphHashTable);
1526 if (sta && sta->rmfEnabled)
1527 rmfConnection = true;
1528
1529 if (rmfConnection && (pHdr->fc.wep == 0)) {
1530 pe_err("Dropping unprotected Action category: %d frame since RMF is enabled",
1531 category);
1532 return true;
1533 }
1534
1535 return false;
1536 }
1537
1538 /**
1539 * lim_process_addba_req() - process ADDBA Request
1540 * @mac_ctx: Pointer to Global MAC structure
1541 * @rx_pkt_info: A pointer to packet info structure
1542 * @session: PE session pointer
1543 *
1544 * This routine will be called to process ADDBA request action frame
1545 *
1546 * Return: None
1547 */
lim_process_addba_req(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)1548 static void lim_process_addba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
1549 struct pe_session *session)
1550 {
1551 tpSirMacMgmtHdr mac_hdr;
1552 uint8_t *body_ptr;
1553 tDot11faddba_req *addba_req;
1554 uint32_t frame_len, status;
1555 QDF_STATUS qdf_status;
1556 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1557 tpDphHashNode sta_ds;
1558 uint16_t aid, buff_size;
1559 bool he_cap = false;
1560 bool eht_cap = false;
1561 uint8_t extd_buff_size = 0;
1562
1563 if (mlo_is_any_link_disconnecting(session->vdev)) {
1564 pe_err("Ignore ADDBA, vdev is in not in conncted state");
1565 return;
1566 }
1567
1568 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1569 body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
1570 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
1571
1572 QDF_TRACE_HEX_DUMP_DEBUG_RL(QDF_MODULE_ID_PE, body_ptr, frame_len);
1573
1574 addba_req = qdf_mem_malloc(sizeof(*addba_req));
1575 if (!addba_req)
1576 return;
1577
1578 /* Unpack ADDBA request frame */
1579 status = dot11f_unpack_addba_req(mac_ctx, body_ptr, frame_len,
1580 addba_req, false);
1581
1582 if (DOT11F_FAILED(status)) {
1583 pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
1584 status, frame_len);
1585 goto error;
1586 } else if (DOT11F_WARNED(status)) {
1587 pe_warn("warning: unpack addba Req(0x%08x, %d bytes)",
1588 status, frame_len);
1589 }
1590
1591 sta_ds = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
1592 &session->dph.dphHashTable);
1593 if (sta_ds &&
1594 (lim_is_session_he_capable(session) ||
1595 sta_ds->staType == STA_ENTRY_TDLS_PEER))
1596 he_cap = lim_is_sta_he_capable(sta_ds);
1597
1598 if (sta_ds &&
1599 (lim_is_session_eht_capable(session) ||
1600 sta_ds->staType == STA_ENTRY_TDLS_PEER))
1601 eht_cap = lim_is_sta_eht_capable(sta_ds);
1602
1603 if (sta_ds && sta_ds->staType == STA_ENTRY_NDI_PEER)
1604 he_cap = lim_is_session_he_capable(session);
1605
1606 if (eht_cap)
1607 buff_size = MAX_EHT_BA_BUFF_SIZE;
1608 else if (he_cap)
1609 buff_size = MAX_BA_BUFF_SIZE;
1610 else
1611 buff_size = SIR_MAC_BA_DEFAULT_BUFF_SIZE;
1612
1613 if (mac_ctx->usr_cfg_ba_buff_size)
1614 buff_size = mac_ctx->usr_cfg_ba_buff_size;
1615
1616 if (addba_req->addba_extn_element.present)
1617 extd_buff_size = addba_req->addba_extn_element.extd_buff_size;
1618
1619 if (addba_req->addba_param_set.buff_size)
1620 buff_size = QDF_MIN(buff_size,
1621 addba_req->addba_param_set.buff_size);
1622 else if (extd_buff_size)
1623 /* limit the buff size */
1624 buff_size = QDF_MIN(buff_size, MAX_EHT_BA_BUFF_SIZE);
1625
1626 pe_debug("token %d tid %d timeout %d buff_size in frame %d buf_size calculated %d ssn %d, extd buff size %d",
1627 addba_req->DialogToken.token, addba_req->addba_param_set.tid,
1628 addba_req->ba_timeout.timeout,
1629 addba_req->addba_param_set.buff_size, buff_size,
1630 addba_req->ba_start_seq_ctrl.ssn, extd_buff_size);
1631
1632 qdf_status = cdp_addba_requestprocess(
1633 soc, mac_hdr->sa,
1634 session->vdev_id,
1635 addba_req->DialogToken.token,
1636 addba_req->addba_param_set.tid,
1637 addba_req->ba_timeout.timeout,
1638 buff_size,
1639 addba_req->ba_start_seq_ctrl.ssn);
1640
1641 if (QDF_STATUS_SUCCESS == qdf_status) {
1642 qdf_status = lim_send_addba_response_frame(mac_ctx,
1643 mac_hdr->sa,
1644 addba_req->addba_param_set.tid,
1645 session,
1646 addba_req->addba_extn_element.present,
1647 addba_req->addba_param_set.amsdu_supp,
1648 mac_hdr->fc.wep, buff_size, mac_hdr->bssId);
1649 if (qdf_status != QDF_STATUS_SUCCESS) {
1650 pe_err("Failed to send addba response frame");
1651 cdp_addba_resp_tx_completion(
1652 soc, mac_hdr->sa, session->vdev_id,
1653 addba_req->addba_param_set.tid,
1654 WMI_MGMT_TX_COMP_TYPE_DISCARD);
1655 }
1656 } else {
1657 pe_debug_rl("Failed to process addba request");
1658 }
1659
1660 error:
1661 qdf_mem_free(addba_req);
1662 return;
1663 }
1664
1665 /**
1666 * lim_process_delba_req() - process DELBA Request
1667 * @mac_ctx: Pointer to Global MAC structure
1668 * @rx_pkt_info: A pointer to packet info structure
1669 * @session: PE session pointer
1670 *
1671 * This routine will be called to process ADDBA request action frame
1672 *
1673 * Return: None
1674 */
lim_process_delba_req(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)1675 static void lim_process_delba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
1676 struct pe_session *session)
1677 {
1678 tpSirMacMgmtHdr mac_hdr;
1679 uint8_t *body_ptr;
1680 tDot11fdelba_req *delba_req;
1681 uint32_t frame_len, status;
1682 QDF_STATUS qdf_status;
1683 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1684
1685 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1686 body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
1687 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
1688
1689 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1690 body_ptr, frame_len);
1691
1692 delba_req = qdf_mem_malloc(sizeof(*delba_req));
1693 if (!delba_req)
1694 return;
1695
1696 /* Unpack DELBA request frame */
1697 status = dot11f_unpack_delba_req(mac_ctx, body_ptr, frame_len,
1698 delba_req, false);
1699
1700 if (DOT11F_FAILED(status)) {
1701 pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
1702 status, frame_len);
1703 goto error;
1704 } else if (DOT11F_WARNED(status)) {
1705 pe_warn("warning: unpack addba Req(0x%08x, %d bytes)",
1706 status, frame_len);
1707 }
1708
1709 qdf_status = cdp_delba_process(soc, mac_hdr->sa, session->vdev_id,
1710 delba_req->delba_param_set.tid, delba_req->Reason.code);
1711
1712 if (QDF_STATUS_SUCCESS != qdf_status)
1713 pe_err_rl("Failed to process delba request");
1714
1715 error:
1716 qdf_mem_free(delba_req);
1717 return;
1718 }
1719
1720 /**
1721 * lim_process_action_frame() - to process action frames
1722 * @mac_ctx: Pointer to Global MAC structure
1723 * @rx_pkt_info: A pointer to packet info structure
1724 *
1725 * This function is called by limProcessMessageQueue() upon
1726 * Action frame reception.
1727 *
1728 * Return: none
1729 */
1730
lim_process_action_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)1731 void lim_process_action_frame(struct mac_context *mac_ctx,
1732 uint8_t *rx_pkt_info, struct pe_session *session)
1733 {
1734 uint8_t *body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
1735 tpSirMacActionFrameHdr action_hdr = (tpSirMacActionFrameHdr) body_ptr;
1736 tpSirMacMgmtHdr mac_hdr_11w = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1737 tpSirMacMgmtHdr mac_hdr = NULL;
1738 int8_t rssi;
1739 uint32_t frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
1740 tpSirMacVendorSpecificFrameHdr vendor_specific;
1741 uint8_t dpp_oui[] = { 0x50, 0x6F, 0x9A, 0x1A };
1742 tpSirMacVendorSpecificPublicActionFrameHdr pub_action;
1743 enum wlan_t2lm_resp_frm_type status_code;
1744 uint8_t token = 0;
1745 struct wlan_objmgr_peer *peer = NULL;
1746 QDF_STATUS status;
1747
1748 if (frame_len < sizeof(*action_hdr)) {
1749 pe_debug("frame_len %d less than Action Frame Hdr size",
1750 frame_len);
1751 return;
1752 }
1753
1754 if (wlan_mgmt_is_rmf_mgmt_action_frame(action_hdr->category) &&
1755 lim_drop_unprotected_action_frame(mac_ctx, session,
1756 mac_hdr_11w, action_hdr->category))
1757 return;
1758
1759 switch (action_hdr->category) {
1760 case ACTION_CATEGORY_QOS:
1761 if ((session->limQosEnabled) ||
1762 (action_hdr->actionID == QOS_MAP_CONFIGURE)) {
1763 switch (action_hdr->actionID) {
1764 case QOS_ADD_TS_REQ:
1765 __lim_process_add_ts_req(mac_ctx,
1766 (uint8_t *) rx_pkt_info,
1767 session);
1768 break;
1769
1770 case QOS_ADD_TS_RSP:
1771 __lim_process_add_ts_rsp(mac_ctx,
1772 (uint8_t *) rx_pkt_info,
1773 session);
1774 break;
1775
1776 case QOS_DEL_TS_REQ:
1777 __lim_process_del_ts_req(mac_ctx,
1778 (uint8_t *) rx_pkt_info,
1779 session);
1780 break;
1781
1782 case QOS_MAP_CONFIGURE:
1783 __lim_process_qos_map_configure_frame(mac_ctx,
1784 (uint8_t *)rx_pkt_info,
1785 session);
1786 break;
1787 default:
1788 pe_warn("Qos action: %d not handled",
1789 action_hdr->actionID);
1790 break;
1791 }
1792 break;
1793 }
1794 break;
1795
1796 case ACTION_CATEGORY_SPECTRUM_MGMT:
1797 switch (action_hdr->actionID) {
1798 #ifdef ANI_SUPPORT_11H
1799 case ACTION_SPCT_MSR_REQ:
1800 if (session->lim11hEnable)
1801 __lim_process_measurement_request_frame(mac_ctx,
1802 rx_pkt_info,
1803 session);
1804 break;
1805 case ACTION_SPCT_TPC_REQ:
1806 if ((LIM_IS_STA_ROLE(session) ||
1807 LIM_IS_AP_ROLE(session)) &&
1808 session->lim11hEnable)
1809 __lim_process_tpc_request_frame(mac_ctx,
1810 rx_pkt_info, session);
1811 break;
1812 #endif
1813 default:
1814 pe_warn("Spectrum mgmt action id: %d not handled",
1815 action_hdr->actionID);
1816 break;
1817 }
1818 break;
1819
1820 case ACTION_CATEGORY_WMM:
1821 if (!session->limWmeEnabled) {
1822 pe_warn("WME mode disabled - dropping frame: %d",
1823 action_hdr->actionID);
1824 break;
1825 }
1826 switch (action_hdr->actionID) {
1827 case QOS_ADD_TS_REQ:
1828 __lim_process_add_ts_req(mac_ctx,
1829 (uint8_t *) rx_pkt_info, session);
1830 break;
1831
1832 case QOS_ADD_TS_RSP:
1833 __lim_process_add_ts_rsp(mac_ctx,
1834 (uint8_t *) rx_pkt_info, session);
1835 break;
1836
1837 case QOS_DEL_TS_REQ:
1838 __lim_process_del_ts_req(mac_ctx,
1839 (uint8_t *) rx_pkt_info, session);
1840 break;
1841
1842 case QOS_MAP_CONFIGURE:
1843 __lim_process_qos_map_configure_frame(mac_ctx,
1844 (uint8_t *)rx_pkt_info, session);
1845 break;
1846
1847 default:
1848 pe_warn("WME action: %d not handled",
1849 action_hdr->actionID);
1850 break;
1851 }
1852 break;
1853
1854 case ACTION_CATEGORY_HT:
1855 /** Type of HT Action to be performed*/
1856 switch (action_hdr->actionID) {
1857 case HT_ACTION_SMPS:
1858 if (LIM_IS_AP_ROLE(session))
1859 __lim_process_sm_power_save_update(mac_ctx,
1860 (uint8_t *)rx_pkt_info,
1861 session);
1862 break;
1863 default:
1864 pe_warn("Action ID: %d not handled in HT category",
1865 action_hdr->actionID);
1866 break;
1867 }
1868 break;
1869
1870 case ACTION_CATEGORY_WNM:
1871 pe_debug("WNM Action category: %d action: %d",
1872 action_hdr->category, action_hdr->actionID);
1873 switch (action_hdr->actionID) {
1874 case WNM_BSS_TM_QUERY:
1875 case WNM_BSS_TM_REQUEST:
1876 case WNM_BSS_TM_RESPONSE:
1877 if (cfg_p2p_is_roam_config_disabled(mac_ctx->psoc) &&
1878 session && LIM_IS_STA_ROLE(session) &&
1879 (policy_mgr_mode_specific_connection_count(
1880 mac_ctx->psoc, PM_P2P_CLIENT_MODE, NULL) ||
1881 policy_mgr_mode_specific_connection_count(
1882 mac_ctx->psoc, PM_P2P_GO_MODE, NULL))) {
1883 pe_debug("p2p session active drop BTM frame");
1884 break;
1885 }
1886 fallthrough;
1887 case WNM_NOTIF_REQUEST:
1888 case WNM_NOTIF_RESPONSE:
1889 rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
1890 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1891 /* Forward to the SME to HDD to wpa_supplicant */
1892 lim_send_sme_mgmt_frame_ind(mac_ctx,
1893 mac_hdr->fc.subType,
1894 (uint8_t *) mac_hdr,
1895 frame_len + sizeof(tSirMacMgmtHdr),
1896 session->vdev_id,
1897 WMA_GET_RX_FREQ(rx_pkt_info),
1898 rssi, RXMGMT_FLAG_NONE);
1899 break;
1900 default:
1901 pe_debug("Action ID: %d not handled in WNM category",
1902 action_hdr->actionID);
1903 break;
1904 }
1905 break;
1906
1907 case ACTION_CATEGORY_RRM:
1908
1909 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1910 LIM_IS_AP_ROLE(session) &&
1911 action_hdr->actionID == RRM_RADIO_MEASURE_RPT) {
1912 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1913 wlan_son_deliver_rrm_rpt(session->vdev,
1914 mac_hdr->sa,
1915 body_ptr + sizeof(tSirMacActionFrameHdr),
1916 frame_len - sizeof(tSirMacActionFrameHdr));
1917 }
1918
1919 /* Ignore RRM measurement request until DHCP is set */
1920 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1921 mac_ctx->roam.roamSession[session->smeSessionId].dhcp_done) {
1922 switch (action_hdr->actionID) {
1923 case RRM_RADIO_MEASURE_REQ:
1924 __lim_process_radio_measure_request(mac_ctx,
1925 (uint8_t *)rx_pkt_info,
1926 session);
1927 break;
1928 case RRM_LINK_MEASUREMENT_REQ:
1929 if (!lim_is_valid_frame(
1930 &rrm_link_action_frm,
1931 rx_pkt_info))
1932 break;
1933
1934 if (__lim_process_link_measurement_req(
1935 mac_ctx,
1936 (uint8_t *)rx_pkt_info,
1937 session) == QDF_STATUS_SUCCESS)
1938 lim_update_last_processed_frame(
1939 &rrm_link_action_frm,
1940 rx_pkt_info);
1941
1942 break;
1943 case RRM_NEIGHBOR_RPT:
1944 __lim_process_neighbor_report(mac_ctx,
1945 (uint8_t *)rx_pkt_info,
1946 session);
1947 break;
1948 default:
1949 pe_warn("Action ID: %d not handled in RRM",
1950 action_hdr->actionID);
1951 break;
1952
1953 }
1954 } else if (LIM_IS_AP_ROLE(session)) {
1955 switch (action_hdr->actionID) {
1956 case RRM_NEIGHBOR_REQ:
1957 case RRM_RADIO_MEASURE_RPT:
1958 rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
1959 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1960 lim_send_sme_mgmt_frame_ind(mac_ctx,
1961 mac_hdr->fc.subType,
1962 (uint8_t *)mac_hdr,
1963 frame_len + sizeof(tSirMacMgmtHdr),
1964 session->smeSessionId,
1965 WMA_GET_RX_FREQ(rx_pkt_info),
1966 rssi, RXMGMT_FLAG_NONE);
1967 break;
1968 default:
1969 pe_warn("Action ID: %d not handled in RRM",
1970 action_hdr->actionID);
1971 break;
1972 }
1973 } else {
1974 /* Else we will just ignore the RRM messages. */
1975 pe_debug("RRM frm ignored, it is disabled in cfg: %d or DHCP not completed: %d",
1976 mac_ctx->rrm.rrmPEContext.rrmEnable,
1977 mac_ctx->roam.roamSession[session->smeSessionId].dhcp_done);
1978 }
1979 break;
1980
1981 case ACTION_CATEGORY_VENDOR_SPECIFIC:
1982 case ACTION_CATEGORY_VENDOR_SPECIFIC_PROTECTED:
1983 vendor_specific = (tpSirMacVendorSpecificFrameHdr) action_hdr;
1984 mac_hdr = NULL;
1985
1986 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1987
1988 if (frame_len < sizeof(*vendor_specific)) {
1989 pe_debug("frame len %d less than Vendor Specific Hdr len",
1990 frame_len);
1991 return;
1992 }
1993
1994 /* Forward all vendor specific action frames. */
1995 if (!qdf_mem_cmp(session->self_mac_addr,
1996 &mac_hdr->da[0], sizeof(tSirMacAddr))) {
1997 pe_debug("Rcvd Vendor specific frame OUI: %x %x %x",
1998 vendor_specific->Oui[0],
1999 vendor_specific->Oui[1],
2000 vendor_specific->Oui[2]);
2001 /*
2002 * Forward to the SME to HDD to wpa_supplicant
2003 * type is ACTION
2004 */
2005 lim_send_sme_mgmt_frame_ind(mac_ctx,
2006 mac_hdr->fc.subType, (uint8_t *)mac_hdr,
2007 frame_len + sizeof(tSirMacMgmtHdr),
2008 session->vdev_id,
2009 WMA_GET_RX_FREQ(rx_pkt_info),
2010 WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
2011 RXMGMT_FLAG_NONE);
2012 } else {
2013 pe_debug("Dropping the vendor specific action frame SelfSta address system role: %d",
2014 GET_LIM_SYSTEM_ROLE(session));
2015 }
2016 break;
2017 case ACTION_CATEGORY_PUBLIC:
2018 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
2019
2020 switch (action_hdr->actionID) {
2021 case PUB_ACTION_EXT_CHANNEL_SWITCH_ID:
2022 lim_process_ext_channel_switch_action_frame(mac_ctx,
2023 rx_pkt_info, session);
2024 break;
2025 case TDLS_DISCOVERY_RESPONSE:
2026 /* do not forward the tdls discovery response frame,
2027 * it is handled by
2028 * tgt_mgmt_txrx_rx_frame_handler ->
2029 * tgt_tdls_mgmt_frame_rx_cb ->
2030 * tdls_process_rx_frame
2031 */
2032 break;
2033 case PUB_ACTION_VENDOR_SPECIFIC:
2034 pub_action =
2035 (tpSirMacVendorSpecificPublicActionFrameHdr)
2036 action_hdr;
2037 if (frame_len < sizeof(*pub_action)) {
2038 pe_debug("Received vendor specific public action frame of invalid len %d",
2039 frame_len);
2040 return;
2041 }
2042 /*
2043 * Check if it is a DPP public action frame and fall
2044 * thru, else drop the frame.
2045 */
2046 if (qdf_mem_cmp(pub_action->Oui, dpp_oui, 4)) {
2047 pe_debug("Unhandled public action frame (Vendor specific) OUI: %x %x %x %x",
2048 pub_action->Oui[0], pub_action->Oui[1],
2049 pub_action->Oui[2], pub_action->Oui[3]);
2050 break;
2051 }
2052 /* send the frame to supplicant */
2053 fallthrough;
2054 case ACTION_CATEGORY_VENDOR_SPECIFIC:
2055 case ACTION_CATEGORY_VENDOR_SPECIFIC_PROTECTED:
2056 case PUB_ACTION_2040_BSS_COEXISTENCE:
2057 case PUB_ACTION_GAS_INITIAL_REQUEST:
2058 if (action_hdr->actionID ==
2059 PUB_ACTION_GAS_INITIAL_REQUEST) {
2060 wlan_son_anqp_frame(session->vdev,
2061 mac_hdr->fc.subType,
2062 (uint8_t *)mac_hdr,
2063 (uint16_t)(frame_len +
2064 sizeof(tSirMacMgmtHdr)),
2065 (void *)action_hdr,
2066 &mac_hdr->sa[0]);
2067 }
2068 fallthrough;
2069 case PUB_ACTION_GAS_INITIAL_RESPONSE:
2070 case PUB_ACTION_GAS_COMEBACK_REQUEST:
2071 case PUB_ACTION_GAS_COMEBACK_RESPONSE:
2072 default:
2073 pe_debug("Public action frame: %d",
2074 action_hdr->actionID);
2075 /*
2076 * Forward to the SME to HDD to wpa_supplicant
2077 * type is ACTION
2078 */
2079 lim_send_sme_mgmt_frame_ind(mac_ctx,
2080 mac_hdr->fc.subType, (uint8_t *)mac_hdr,
2081 frame_len + sizeof(tSirMacMgmtHdr),
2082 session->vdev_id,
2083 WMA_GET_RX_FREQ(rx_pkt_info),
2084 WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
2085 RXMGMT_FLAG_NONE);
2086 break;
2087 }
2088 break;
2089
2090 case ACTION_CATEGORY_SA_QUERY:
2091 pe_debug("SA Query Action category: %d action: %d",
2092 action_hdr->category, action_hdr->actionID);
2093 switch (action_hdr->actionID) {
2094 case SA_QUERY_REQUEST:
2095 /**11w SA query request action frame received**/
2096 /* Respond directly to the incoming request in LIM */
2097 __lim_process_sa_query_request_action_frame(mac_ctx,
2098 (uint8_t *)rx_pkt_info,
2099 session);
2100 break;
2101 case SA_QUERY_RESPONSE:
2102 /**11w SA query response action frame received**/
2103 /* Handle based on the current SA Query state */
2104 __lim_process_sa_query_response_action_frame(mac_ctx,
2105 (uint8_t *)rx_pkt_info,
2106 session);
2107 break;
2108 default:
2109 break;
2110 }
2111 break;
2112
2113 case ACTION_CATEGORY_VHT:
2114 if (!session->vhtCapability)
2115 break;
2116 switch (action_hdr->actionID) {
2117 case VHT_ACTION_OPMODE_NOTIF:
2118 __lim_process_operating_mode_action_frame(mac_ctx,
2119 rx_pkt_info, session);
2120 break;
2121 case VHT_ACTION_GID_NOTIF:
2122 /* Only if ini supports it */
2123 if (session->enableVhtGid)
2124 __lim_process_gid_management_action_frame(
2125 mac_ctx, rx_pkt_info, session);
2126 break;
2127 default:
2128 break;
2129 }
2130 break;
2131 case ACTION_CATEGORY_RVS:
2132 case ACTION_CATEGORY_FST: {
2133 tpSirMacMgmtHdr hdr;
2134
2135 hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
2136
2137 pe_debug("Received %s MGMT action frame",
2138 (action_hdr->category == ACTION_CATEGORY_FST) ?
2139 "FST" : "RVS");
2140
2141 /* Forward to the SME to HDD */
2142 lim_send_sme_mgmt_frame_ind(mac_ctx, hdr->fc.subType,
2143 (uint8_t *)hdr,
2144 frame_len + sizeof(tSirMacMgmtHdr),
2145 session->vdev_id,
2146 WMA_GET_RX_FREQ(rx_pkt_info),
2147 WMA_GET_RX_RSSI_NORMALIZED(
2148 rx_pkt_info), RXMGMT_FLAG_NONE);
2149 break;
2150 }
2151 case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION:
2152 pe_debug("Rcvd Protected Dual of Public Action: %d",
2153 action_hdr->actionID);
2154 switch (action_hdr->actionID) {
2155 case PDPA_GAS_INIT_REQ:
2156 case PDPA_GAS_INIT_RSP:
2157 case PDPA_GAS_COMEBACK_REQ:
2158 case PDPA_GAS_COMEBACK_RSP:
2159 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
2160 rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
2161 lim_send_sme_mgmt_frame_ind(mac_ctx,
2162 mac_hdr->fc.subType, (uint8_t *) mac_hdr,
2163 frame_len + sizeof(tSirMacMgmtHdr),
2164 session->vdev_id,
2165 WMA_GET_RX_FREQ(rx_pkt_info), rssi,
2166 RXMGMT_FLAG_NONE);
2167 break;
2168 default:
2169 pe_debug("Unhandled - Protected Dual Public Action");
2170 break;
2171 }
2172 break;
2173 case ACTION_CATEGORY_BACK:
2174 pe_debug("Rcvd Block Ack for "QDF_MAC_ADDR_FMT"; action: %d",
2175 QDF_MAC_ADDR_REF(session->self_mac_addr),
2176 action_hdr->actionID);
2177 switch (action_hdr->actionID) {
2178 case ADDBA_REQUEST:
2179 lim_process_addba_req(mac_ctx, rx_pkt_info, session);
2180 break;
2181 case DELBA:
2182 lim_process_delba_req(mac_ctx, rx_pkt_info, session);
2183 break;
2184 default:
2185 pe_err("Unhandle BA action frame");
2186 break;
2187 }
2188 break;
2189 case ACTION_CATEGORY_PROTECTED_EHT:
2190 pe_debug("EHT T2LM/EPCS action category: %d action: %d",
2191 action_hdr->category, action_hdr->actionID);
2192 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
2193 body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
2194 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
2195 peer = wlan_objmgr_get_peer_by_mac(mac_ctx->psoc,
2196 mac_hdr->sa,
2197 WLAN_LEGACY_MAC_ID);
2198 if (!peer) {
2199 pe_err("Peer is null");
2200 break;
2201 }
2202 switch (action_hdr->actionID) {
2203 case EHT_T2LM_REQUEST:
2204 status = wlan_t2lm_deliver_event(
2205 session->vdev, peer,
2206 WLAN_T2LM_EV_ACTION_FRAME_RX_REQ,
2207 (void *)body_ptr, frame_len,
2208 &token);
2209 if (QDF_IS_STATUS_SUCCESS(status))
2210 status_code = WLAN_T2LM_RESP_TYPE_SUCCESS;
2211 else
2212 status_code =
2213 WLAN_T2LM_RESP_TYPE_DENIED_TID_TO_LINK_MAPPING;
2214
2215 if (status == QDF_STATUS_E_NOSUPPORT)
2216 pe_err("STA does not support T2LM drop frame");
2217 else if (lim_send_t2lm_action_rsp_frame(
2218 mac_ctx, mac_hdr->sa, session, token,
2219 status_code) != QDF_STATUS_SUCCESS) {
2220 pe_err("T2LM action response frame not sent");
2221 } else {
2222 wlan_send_peer_level_tid_to_link_mapping(
2223 session->vdev,
2224 peer);
2225 wlan_connectivity_t2lm_status_event(
2226 session->vdev);
2227 }
2228 break;
2229 case EHT_T2LM_RESPONSE:
2230 wlan_t2lm_deliver_event(
2231 session->vdev, peer,
2232 WLAN_T2LM_EV_ACTION_FRAME_RX_RESP,
2233 (void *)body_ptr, frame_len, &token);
2234 break;
2235 case EHT_T2LM_TEARDOWN:
2236 wlan_t2lm_deliver_event(
2237 session->vdev, peer,
2238 WLAN_T2LM_EV_ACTION_FRAME_RX_TEARDOWN,
2239 (void *)body_ptr, frame_len, NULL);
2240 break;
2241 case EHT_EPCS_REQUEST:
2242 wlan_epcs_deliver_event(
2243 session->vdev, peer,
2244 WLAN_EPCS_EV_ACTION_FRAME_RX_REQ,
2245 (void *)body_ptr, frame_len);
2246 break;
2247 case EHT_EPCS_RESPONSE:
2248 wlan_epcs_deliver_event(
2249 session->vdev, peer,
2250 WLAN_EPCS_EV_ACTION_FRAME_RX_RESP,
2251 (void *)body_ptr, frame_len);
2252 break;
2253 case EHT_EPCS_TEARDOWN:
2254 wlan_epcs_deliver_event(
2255 session->vdev, peer,
2256 WLAN_EPCS_EV_ACTION_FRAME_RX_TEARDOWN,
2257 (void *)body_ptr, frame_len);
2258 break;
2259 default:
2260 pe_err("Unhandled T2LM/EPCS action frame");
2261 break;
2262 }
2263 break;
2264 default:
2265 pe_warn_rl("Action category: %d not handled",
2266 action_hdr->category);
2267 break;
2268 }
2269
2270 if (peer)
2271 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
2272 }
2273
2274 /**
2275 * lim_process_action_frame_no_session
2276 *
2277 ***FUNCTION:
2278 * This function is called by limProcessMessageQueue() upon
2279 * Action frame reception and no session.
2280 * Currently only public action frames can be received from
2281 * a non-associated station.
2282 *
2283 ***LOGIC:
2284 *
2285 ***ASSUMPTIONS:
2286 *
2287 ***NOTE:
2288 *
2289 * @param mac - Pointer to Global MAC structure
2290 * @param *pBd - A pointer to Buffer descriptor + associated PDUs
2291 * @return None
2292 */
lim_process_action_frame_no_session(struct mac_context * mac,uint8_t * pBd)2293 void lim_process_action_frame_no_session(struct mac_context *mac, uint8_t *pBd)
2294 {
2295 tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(pBd);
2296 uint32_t frame_len = WMA_GET_RX_PAYLOAD_LEN(pBd);
2297 uint8_t *pBody = WMA_GET_RX_MPDU_DATA(pBd);
2298 tpSirMacActionFrameHdr action_hdr = (tpSirMacActionFrameHdr) pBody;
2299 tpSirMacVendorSpecificPublicActionFrameHdr vendor_specific;
2300
2301 pe_debug("Received an action frame category: %d action_id: %d",
2302 action_hdr->category, (action_hdr->category ==
2303 ACTION_CATEGORY_PUBLIC || action_hdr->category ==
2304 ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION) ?
2305 action_hdr->actionID : 255);
2306
2307 if (frame_len < sizeof(*action_hdr)) {
2308 pe_debug("frame_len %d less than action frame header len",
2309 frame_len);
2310 return;
2311 }
2312
2313 switch (action_hdr->category) {
2314 case ACTION_CATEGORY_PUBLIC:
2315 case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION:
2316 if (action_hdr->actionID == PUB_ACTION_VENDOR_SPECIFIC) {
2317 vendor_specific =
2318 (tpSirMacVendorSpecificPublicActionFrameHdr)
2319 action_hdr;
2320
2321 if (frame_len < sizeof(*vendor_specific)) {
2322 pe_debug("Received vendor specific public action frame of invalid len %d",
2323 frame_len);
2324 return;
2325 }
2326
2327 pe_debug("public action frame (Vendor specific) OUI: %x %x %x %x",
2328 vendor_specific->Oui[0],
2329 vendor_specific->Oui[1],
2330 vendor_specific->Oui[2],
2331 vendor_specific->Oui[3]);
2332
2333 /* Drop P2P frames as they are handled by P2P module */
2334 if (wlan_p2p_is_action_frame_of_p2p_type(
2335 (uint8_t *)mac_hdr,
2336 WMA_GET_RX_MPDU_LEN(pBd))) {
2337 pe_debug("Drop P2P public action frame as already handled in p2p module");
2338 return;
2339 }
2340 }
2341
2342 /*
2343 * Forward all public action frame with no session to
2344 * wpa_supplicant
2345 */
2346 lim_send_sme_mgmt_frame_ind(mac, mac_hdr->fc.subType,
2347 (uint8_t *)mac_hdr,
2348 frame_len + sizeof(tSirMacMgmtHdr),
2349 0, WMA_GET_RX_FREQ(pBd),
2350 WMA_GET_RX_RSSI_NORMALIZED(pBd),
2351 RXMGMT_FLAG_NONE);
2352
2353 break;
2354 default:
2355 pe_info_rl("Unhandled action frame without session: %x",
2356 action_hdr->category);
2357 break;
2358 }
2359 }
2360