Browse Source

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
Vignesh Viswanathan 7 years ago
parent
commit
153ae93cf8

+ 15 - 9
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 */

+ 23 - 10
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

+ 49 - 0
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);

+ 123 - 9
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()
  *

+ 4 - 0
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) {

+ 42 - 45
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

+ 0 - 11
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);