Selaa lähdekoodia

qcacmn: Use EHTOP IE to validate puncturing bitmap

When the STA finds a candidate AP to connect to, it checks if the
primary 20 MHz channel is punctured or not. This validation is currently
done using scan channel parameters. The scan channel parameters are
intersected to the STA's capability and might not reflect the original EHT
OP IE parameters. For example, consider an 11ax STA in HE160 MHz mode
trying to connect to a 11be AP operating in EHT320 MHz mode. The scan
channel parameters are intersected to the STA's capability of 160 MHz.
The scan channel parameters like 320 MHz center frequency and puncturing
bitmap are inconsistent with the CCFS1 and punturing bitmap received in
the EHT OP IE.

So, instead of using the intersected scan channel parameters stored in the
STA to validate puncturing bitmap of the AP, use the EHT OP IE received
from the AP to validate puncturing bitmap.

Change-Id: I0cdc56eea96f04eb96327506bfd61c0f3a9109bb
CRs-Fixed: 3364639
Vignesh U 2 vuotta sitten
vanhempi
sitoutus
bcbe6a3d15
1 muutettua tiedostoa jossa 49 lisäystä ja 6 poistoa
  1. 49 6
      umac/scan/core/src/wlan_scan_filter.c

+ 49 - 6
umac/scan/core/src/wlan_scan_filter.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. 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
@@ -765,7 +765,17 @@ static bool util_mlo_filter_match(struct wlan_objmgr_pdev *pdev,
 #endif
 
 #ifdef WLAN_FEATURE_11BE
-static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry)
+/**
+ * util_eht_puncture_valid(): The function finds the puncturing pattern from the
+ * IE. If the primary channel is in the punctured list then the channel cannot
+ * be used, and this function returns false/invalid.
+ * @pdev: pdev device.
+ * @db_entry: scan cache entry which will indicate EHT ops.
+ *
+ * Return - false if the primary channel is punctured and true if otherwise.
+ */
+static bool util_eht_puncture_valid(struct wlan_objmgr_pdev *pdev,
+				    struct scan_cache_entry *db_entry)
 {
 	struct wlan_ie_ehtops *eht_ops;
 	int8_t orig_width;
@@ -774,6 +784,8 @@ static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry)
 	uint16_t orig_puncture_bitmap;
 	uint16_t new_puncture_bitmap = 0;
 	QDF_STATUS status;
+	uint32_t cfreq1;
+	uint8_t band_mask = BIT(REG_BAND_6G);
 
 	eht_ops = (struct wlan_ie_ehtops *)util_scan_entry_ehtop(db_entry);
 	if (!eht_ops)
@@ -781,21 +793,41 @@ static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry)
 	if (!QDF_GET_BITS(eht_ops->ehtop_param,
 			  EHTOP_INFO_PRESENT_IDX, EHTOP_INFO_PRESENT_BITS))
 		return true;
-	orig_puncture_bitmap = db_entry->channel.puncture_bitmap;
+	if (QDF_GET_BITS(eht_ops->ehtop_param,
+			 EHTOP_PARAM_DISABLED_SC_BITMAP_PRESENT_IDX,
+			 EHTOP_PARAM_DISABLED_SC_BITMAP_PRESENT_BITS)) {
+		orig_puncture_bitmap =
+			QDF_GET_BITS(eht_ops->disabled_sub_chan_bitmap[0],
+				     0, 8);
+		orig_puncture_bitmap |=
+			QDF_GET_BITS(eht_ops->disabled_sub_chan_bitmap[1],
+				     0, 8) << 8;
+	} else {
+		orig_puncture_bitmap = 0;
+	}
 	if (!orig_puncture_bitmap)
 		return true;
 
 	orig_width = QDF_GET_BITS(eht_ops->control,
 				  EHTOP_INFO_CHAN_WIDTH_IDX,
 				  EHTOP_INFO_CHAN_WIDTH_BITS);
+	/* Check if CCFS bits are present */
+	if (QDF_GET_BITS(eht_ops->ehtop_param,
+			 EHTOP_INFO_PRESENT_IDX, EHTOP_INFO_PRESENT_BITS))
+		cfreq1 = wlan_reg_chan_band_to_freq(pdev, eht_ops->ccfs1,
+						    band_mask);
+	else
+		cfreq1 = 0;
+
 	if (orig_width == WLAN_EHT_CHWIDTH_320) {
 		width = CH_WIDTH_320MHZ;
-		center_freq_320m = db_entry->channel.cfreq1;
+		center_freq_320m = cfreq1;
 	} else {
 		width = orig_width;
 		center_freq_320m = 0;
 	}
 
+	/* Find if the primary channel is punctured */
 	status = wlan_reg_extract_puncture_by_bw(width,
 						 orig_puncture_bitmap,
 						 db_entry->channel.chan_freq,
@@ -813,7 +845,8 @@ static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry)
 	}
 }
 #else
-static bool util_eht_puncture_valid(struct scan_cache_entry *db_entry)
+static bool util_eht_puncture_valid(struct wlan_objmgr_pdev *pdev,
+				    struct scan_cache_entry *db_entry)
 {
 	return true;
 }
@@ -1002,8 +1035,18 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc,
 		return false;
 	}
 
-	if (!util_eht_puncture_valid(db_entry))
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, db_entry->pdev_id,
+					  WLAN_SCAN_ID);
+	if (!pdev) {
+		scm_err(QDF_MAC_ADDR_FMT ": Ignore as pdev not found",
+			QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
+		return false;
+	}
+	if (!util_eht_puncture_valid(pdev, db_entry)) {
+		wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
 		return false;
+	}
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
 
 	return true;
 }