From 153ae93cf82cec3eb82328a1fcf96a342e4361d3 Mon Sep 17 00:00:00 2001 From: Vignesh Viswanathan Date: Wed, 11 Apr 2018 14:24:13 +0530 Subject: [PATCH] qcacld-3.0: Handle beacon frames from Scan module for SAP protection Register a callback to scan module for beacon frames and handle the beacon with the mac_ctx bcn/probe filter for SAP sessions. This will allow beacon frames from the same channel as active SAP sessions to be processed by the ap_beacon_process for SAP protection mechanism implementation. Change-Id: Idb0c1e22ba55fa683a7514d70ba5abe609263829 CRs-Fixed: 2226228 --- core/mac/src/pe/include/lim_api.h | 24 ++-- core/mac/src/pe/include/sch_api.h | 33 +++-- core/mac/src/pe/lim/lim_api.c | 49 +++++++ .../src/pe/lim/lim_process_message_queue.c | 132 ++++++++++++++++-- .../src/pe/lim/lim_process_sme_req_messages.c | 4 + core/mac/src/pe/sch/sch_beacon_process.c | 87 ++++++------ .../src/sys/legacy/src/utils/src/parser_api.c | 11 -- 7 files changed, 256 insertions(+), 84 deletions(-) diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h index 1d1c85c4a6d1..ea80e5963c38 100644 --- a/core/mac/src/pe/include/lim_api.h +++ b/core/mac/src/pe/include/lim_api.h @@ -1,9 +1,6 @@ /* * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /* * * This file lim_api.h contains the definitions exported by @@ -373,5 +364,20 @@ static inline void lim_fill_join_rsp_ht_caps(tpPESession session, QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx, uint8_t *ie_data, uint8_t *local_ie_buf, uint16_t *local_ie_len); +/** + * lim_handle_sap_beacon(): Handle the beacon received from scan module for SAP + * @pdev: pointer to the pdev object + * @scan_entry: pointer to the scan cache entry for the beacon + * + * Registered as callback to the scan module for handling beacon frames. + * This API filters the and allows beacons for SAP protection mechanisms + * if there are active SAP sessions and the received beacon's channel + * matches the SAP active channel + * + * Return: None + */ +void lim_handle_sap_beacon(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_entry); + /************************************************************/ #endif /* __LIM_API_H */ diff --git a/core/mac/src/pe/include/sch_api.h b/core/mac/src/pe/include/sch_api.h index 1ef9e2892971..895d48c5b637 100644 --- a/core/mac/src/pe/include/sch_api.h +++ b/core/mac/src/pe/include/sch_api.h @@ -1,8 +1,5 @@ /* - * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * + * Copyright (c) 2011-2015, 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /* * * Author: Sandesh Goel @@ -99,4 +90,26 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal, tpPESession, uint32_ int sch_gen_timing_advert_frame(tpAniSirGlobal pMac, tSirMacAddr self_addr, uint8_t **buf, uint32_t *timestamp_offset, uint32_t *time_value_offset); +/* + * sch_beacon_process_for_ap() - process the beacon frame for AP sessions + * @mac_ctx: pointer to the global mac_ctx + * @rx_pkt_info: pointer to the frame Rx Meta + * @bcn: pointer to the beacon struct + * + * Process the beacon in the context of any existing AP or BTAP + * session. This takes cares of following two scenarios: + * - session = NULL: + * e.g. beacon received from a neighboring BSS, you want to apply the + * protection settings to BTAP/InfraAP beacons + * - session is non NULL: + * e.g. beacon received is from the INFRA AP to which you are connected + * on another concurrent link. In this case also, we want to apply the + * protection settings(as advertised by Infra AP) to BTAP beacons + * + * Return: None + */ +void sch_beacon_process_for_ap(tpAniSirGlobal mac_ctx, + uint8_t *rx_pkt_info, + tSchBeaconStruct *bcn); + #endif diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index f8afcce40060..3ff5e7b27b78 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -853,6 +853,53 @@ static void p2p_register_callbacks(tpAniSirGlobal mac_ctx) ucfg_p2p_register_callbacks(mac_ctx->psoc, &p2p_cb); } +/* + * lim_register_sap_bcn_callback(): Register a callback with scan module for SAP + * @mac_ctx: pointer to the global mac context + * + * Registers the function lim_handle_sap_beacon as callback with the Scan + * module to handle beacon frames for SAP sessions + * + * Return: QDF Status + */ +static QDF_STATUS lim_register_sap_bcn_callback(tpAniSirGlobal mac_ctx) +{ + QDF_STATUS status; + + status = ucfg_scan_register_bcn_cb(mac_ctx->psoc, + lim_handle_sap_beacon, + SCAN_CB_TYPE_UPDATE_BCN); + if (!QDF_IS_STATUS_SUCCESS(status)) { + pe_err("failed with status code %08d [x%08x]", + status, status); + } + + return status; +} + +/* + * lim_unregister_sap_bcn_callback(): Unregister the callback with scan module + * @mac_ctx: pointer to the global mac context + * + * Unregisters the callback registered with the Scan + * module to handle beacon frames for SAP sessions + * + * Return: QDF Status + */ +static QDF_STATUS lim_unregister_sap_bcn_callback(tpAniSirGlobal mac_ctx) +{ + QDF_STATUS status; + + status = ucfg_scan_register_bcn_cb(mac_ctx->psoc, + NULL, SCAN_CB_TYPE_UPDATE_BCN); + if (!QDF_IS_STATUS_SUCCESS(status)) { + pe_err("failed with status code %08d [x%08x]", + status, status); + } + + return status; +} + /** ------------------------------------------------------------- \fn pe_open \brief will be called in Open sequence from mac_open @@ -910,6 +957,7 @@ tSirRetStatus pe_open(tpAniSirGlobal pMac, struct cds_config_info *cds_cfg) lim_register_debug_callback(); lim_nan_register_callbacks(pMac); p2p_register_callbacks(pMac); + lim_register_sap_bcn_callback(pMac); if (!QDF_IS_STATUS_SUCCESS( cds_shutdown_notifier_register(pe_shutdown_notifier_cb, pMac))) { @@ -943,6 +991,7 @@ tSirRetStatus pe_close(tpAniSirGlobal pMac) return eSIR_SUCCESS; lim_cleanup(pMac); + lim_unregister_sap_bcn_callback(pMac); if (pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq) { qdf_mem_free(pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq); diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index c8229bff3630..2e0c5044bdbc 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1,9 +1,6 @@ /* * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /* * This file lim ProcessMessageQueue.cc contains the code * for processing LIM message Queue. @@ -739,6 +730,129 @@ __lim_handle_beacon(tpAniSirGlobal pMac, struct scheduler_msg *pMsg, return; } +/* + * lim_fill_sap_bcn_pkt_meta(): Fills essential fields in Rx Pkt Meta + * @scan_entry: pointer to the scan cache entry of the beacon + * @rx_pkt: pointer to the cds pkt allocated + * + * This API fills only the essential paramters in the Rx Pkt Meta which are + * required while converting the beacon frame to struct and while handling + * the beacon for implementation of SAP protection mechanisms. + * + * Return: None + */ +static void lim_fill_sap_bcn_pkt_meta(struct scan_cache_entry *scan_entry, + cds_pkt_t *rx_pkt) +{ + rx_pkt->pkt_meta.channel = scan_entry->channel.chan_idx; + + rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame); + rx_pkt->pkt_meta.mpdu_len = scan_entry->raw_frame.len; + rx_pkt->pkt_meta.mpdu_data_len = rx_pkt->pkt_meta.mpdu_len - + rx_pkt->pkt_meta.mpdu_hdr_len; + + rx_pkt->pkt_meta.mpdu_hdr_ptr = scan_entry->raw_frame.ptr; + rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr + + rx_pkt->pkt_meta.mpdu_hdr_len; + + /* + * The scan_entry->raw_frame contains the qdf_nbuf->data from the SKB + * of the beacon. We set the rx_pkt->pkt_meta.mpdu_hdr_ptr to point + * to this memory directly. However we do not have the pointer to + * the SKB itself here which is usually is pointed by rx_pkt->pkt_buf. + * Also, we always get the pkt data using WMA_GET_RX_MPDU_DATA and + * dont actually use the pkt_buf. So setting this to NULL. + */ + rx_pkt->pkt_buf = NULL; +} + +void lim_handle_sap_beacon(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_entry) +{ + tpAniSirGlobal mac_ctx; + cds_pkt_t *pkt = NULL; + struct mgmt_beacon_probe_filter *filter; + tSchBeaconStruct *bcn = NULL; + bool allow_frame = false; + QDF_STATUS qdf_status; + uint8_t *rx_pkt_info; + int session_id; + + if (!scan_entry) { + pe_err("scan_entry is NULL"); + return; + } + + if (scan_entry->frm_subtype != SIR_MAC_MGMT_BEACON) + return; + + mac_ctx = cds_get_context(QDF_MODULE_ID_PE); + if (!mac_ctx) { + pe_err("Failed to get mac_ctx"); + return; + } + + filter = &mac_ctx->bcn_filter; + + if (!filter->num_sap_sessions) { + return; + } + + for (session_id = 0; session_id < SIR_MAX_SUPPORTED_BSS; session_id++) { + if (filter->sap_channel[session_id] && + (filter->sap_channel[session_id] == + scan_entry->channel.chan_idx)) { + allow_frame = true; + break; + } + } + + if (!allow_frame) + return; + + pkt = qdf_mem_malloc(sizeof(*pkt)); + if (!pkt) { + pe_err("Failed to allocate rx packet"); + goto free; + } + + lim_fill_sap_bcn_pkt_meta(scan_entry, pkt); + + qdf_status = + wma_ds_peek_rx_packet_info(pkt, (void *)&rx_pkt_info, false); + + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + pe_err("Failed to peek rx pkt info"); + goto free; + } + + bcn = qdf_mem_malloc(sizeof(tSchBeaconStruct)); + if (!bcn) { + pe_err("Failed to allocate bcn struct"); + goto free; + } + + /* Convert the beacon frame into a structure */ + if (sir_convert_beacon_frame2_struct(mac_ctx, (uint8_t *) rx_pkt_info, + bcn) != eSIR_SUCCESS) { + pe_err_rl("beacon parsing failed"); + goto free; + } + + sch_beacon_process_for_ap(mac_ctx, rx_pkt_info, bcn); + +free: + /* + * Free only the pkt memory we allocated and not the pkt->pkt_buf. + * The actual SKB buffer is freed in the scan module from where + * this API is invoked via callback + */ + if (bcn) + qdf_mem_free(bcn); + if (pkt) + qdf_mem_free(pkt); +} + /** * lim_defer_msg() * diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 83d21c5198e2..b01cfa51e044 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -4874,6 +4874,10 @@ static void lim_process_sme_channel_change_request(tpAniSirGlobal mac_ctx, ch_change_req->targetChannel; session_entry->limRFBand = lim_get_rf_band(session_entry->currentOperChannel); + + /* Update the global beacon filter */ + lim_update_bcn_probe_filter(mac_ctx, session_entry); + /* Initialize 11h Enable Flag */ if (CHAN_HOP_ALL_BANDS_ENABLE || BAND_5G == session_entry->limRFBand) { diff --git a/core/mac/src/pe/sch/sch_beacon_process.c b/core/mac/src/pe/sch/sch_beacon_process.c index b04a752472cf..ddf9acbd0613 100644 --- a/core/mac/src/pe/sch/sch_beacon_process.c +++ b/core/mac/src/pe/sch/sch_beacon_process.c @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /* * This file sch_beacon_process.cc contains beacon processing related * functions @@ -1014,48 +1005,29 @@ static void sch_check_bss_color_ie(tpAniSirGlobal mac_ctx, } #endif -/** - * sch_beacon_process() - process the beacon frame - * @mac_ctx: mac global context - * @rx_pkt_info: pointer to buffer descriptor - * - * Return: None - */ -void -sch_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, - tpPESession session) +void sch_beacon_process_for_ap(tpAniSirGlobal mac_ctx, + uint8_t *rx_pkt_info, + tSchBeaconStruct *bcn) { - static tSchBeaconStruct bcn; - tUpdateBeaconParams bcn_prm; - tpPESession ap_session = NULL; uint8_t i; + tpPESession ap_session = NULL; + tUpdateBeaconParams bcn_prm; - qdf_mem_zero(&bcn_prm, sizeof(tUpdateBeaconParams)); - bcn_prm.paramChangeBitmap = 0; - /* Convert the beacon frame into a structure */ - if (sir_convert_beacon_frame2_struct(mac_ctx, (uint8_t *) rx_pkt_info, - &bcn) != eSIR_SUCCESS) { - pe_err("beacon parsing failed"); + if (!bcn || !rx_pkt_info) { + pe_err_rl("bcn %pK or rx_pkt_info %pK NULL", + bcn, rx_pkt_info); return; } - if (bcn.ssidPresent) - bcn.ssId.ssId[bcn.ssId.length] = 0; - /* - * First process the beacon in the context of any existing AP or BTAP - * session. This takes cares of following two scenarios: - * - session = NULL: - * e.g. beacon received from a neighboring BSS, you want to apply the - * protection settings to BTAP/InfraAP beacons - * - session is non NULL: - * e.g. beacon received is from the INFRA AP to which you are connected - * on another concurrent link. In this case also, we want to apply the - * protection settings(as advertised by Infra AP) to BTAP beacons - */ + qdf_mem_zero(&bcn_prm, sizeof(tUpdateBeaconParams)); + bcn_prm.paramChangeBitmap = 0; + + if (bcn->ssidPresent) + bcn->ssId.ssId[bcn->ssId.length] = 0; + for (i = 0; i < mac_ctx->lim.maxBssId; i++) { ap_session = pe_find_session_by_session_id(mac_ctx, i); - if (!((ap_session != NULL) && - (!(WMA_GET_OFFLOADSCANLEARN(rx_pkt_info))))) + if (!ap_session) continue; if (!LIM_IS_AP_ROLE(ap_session)) @@ -1065,13 +1037,13 @@ sch_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, if (!ap_session->is_session_obss_color_collision_det_enabled) sch_check_bss_color_ie(mac_ctx, ap_session, - &bcn, &bcn_prm); + bcn, &bcn_prm); if ((ap_session->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) && !ap_session->is_session_obss_offload_enabled) ap_beacon_process(mac_ctx, rx_pkt_info, - &bcn, &bcn_prm, ap_session); + bcn, &bcn_prm, ap_session); if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) && bcn_prm.paramChangeBitmap) { @@ -1084,6 +1056,31 @@ sch_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, lim_send_beacon_params(mac_ctx, &bcn_prm, ap_session); } } +} + +/** + * sch_beacon_process() - process the beacon frame + * @mac_ctx: mac global context + * @rx_pkt_info: pointer to buffer descriptor + * @session: pointer to the PE session + * + * Return: None + */ +void +sch_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, + tpPESession session) +{ + static tSchBeaconStruct bcn; + + /* Convert the beacon frame into a structure */ + if (sir_convert_beacon_frame2_struct(mac_ctx, (uint8_t *) rx_pkt_info, + &bcn) != eSIR_SUCCESS) { + pe_err_rl("beacon parsing failed"); + return; + } + + if (bcn.ssidPresent) + bcn.ssId.ssId[bcn.ssId.length] = 0; /* * Now process the beacon in the context of the BSS which is diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 4df9dc5a159a..b9dd2ab3bdbb 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /* * This file parser_api.cc contains the code for parsing * 802.11 messages. @@ -4013,13 +4004,11 @@ sir_convert_beacon_frame2_struct(tpAniSirGlobal pMac, uint8_t *pPayload; tpSirMacMgmtHdr pHdr; uint8_t mappedRXCh; - uint8_t rfBand; pPayload = WMA_GET_RX_MPDU_DATA(pFrame); nPayload = WMA_GET_RX_PAYLOAD_LEN(pFrame); pHdr = WMA_GET_RX_MAC_HEADER(pFrame); mappedRXCh = WMA_GET_RX_CH(pFrame); - rfBand = WMA_GET_RX_RFBAND(pFrame); /* Zero-init our [out] parameter, */ qdf_mem_set((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0);