Răsfoiți Sursa

qcacmn: Handle assoc disallowed in MBO OCE IE

Handle the assoc disallowed case in MBO OCE IE
and remove candidate from the candidate list.

Change-Id: Ieb5ebdd9528a3179a215dcd5ce8083178ab68ae8
CRs-Fixed: 2753508
gaurank kathpalia 4 ani în urmă
părinte
comite
1c65e1b75b

+ 48 - 0
umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h

@@ -43,6 +43,7 @@
 #define MBO_OCE_OUI 0x506f9a16
 #define MBO_OCE_OUI_SIZE 4
 #define REDUCED_WAN_METRICS_ATTR 103
+#define OCE_DISALLOW_ASSOC_ATTR  0x4
 #define AP_TX_PWR_ATTR 107
 #define OCE_SUBNET_ID_ATTR 108
 #define OCE_SUBNET_ID_LEN 6
@@ -1619,6 +1620,53 @@ wlan_parse_oce_subnet_id_ie(uint8_t *mbo_oce_ie)
 	return false;
 }
 
+/**
+ * wlan_parse_oce_assoc_disallowed_ie() - parse oce assoc disallowed IE
+ * @mbo_oce_ie: MBO/OCE ie ptr
+ * @reason: reason for disallowing assoc.
+ *
+ * API, function to parse OCE assoc disallowed param from the OCE MBO IE
+ *
+ * Return: true if assoc disallowed field is present in the IE
+ */
+static inline bool
+wlan_parse_oce_assoc_disallowed_ie(uint8_t *mbo_oce_ie, uint8_t *reason)
+{
+	uint8_t len, attribute_len, attribute_id;
+	uint8_t *ie;
+
+	if (!mbo_oce_ie)
+		return false;
+
+	ie = mbo_oce_ie;
+	len = ie[1];
+	ie += 2;
+
+	if (len <= MBO_OCE_OUI_SIZE)
+		return false;
+
+	ie += MBO_OCE_OUI_SIZE;
+	len -= MBO_OCE_OUI_SIZE;
+
+	while (len > 2) {
+		attribute_id = ie[0];
+		attribute_len = ie[1];
+		len -= 2;
+		if (attribute_len > len)
+			return false;
+
+		if (attribute_id == OCE_DISALLOW_ASSOC_ATTR) {
+			*reason = ie[2];
+			return true;
+		}
+
+		ie += (attribute_len + 2);
+		len -= attribute_len;
+	}
+
+	return false;
+}
+
 /*
  * wlan_parse_oce_ap_tx_pwr_ie() - parse oce ap tx pwr
  * @mbo_oce_ie: MBO/OCE ie ptr

+ 51 - 5
umac/mlme/connection_mgr/core/src/wlan_cm_bss_scoring.c

@@ -971,6 +971,29 @@ static void cm_list_insert_sorted(qdf_list_t *scan_list,
 		qdf_list_insert_back(scan_list, &scan_entry->node);
 }
 
+static bool cm_is_assoc_allowed(struct psoc_mlme_obj *mlme_psoc_obj,
+				struct scan_cache_entry *entry)
+{
+	uint8_t reason;
+	uint8_t *mbo_oce;
+	bool check_assoc_disallowed;
+
+	mbo_oce = util_scan_entry_mbo_oce(entry);
+
+	check_assoc_disallowed =
+	   mlme_psoc_obj->psoc_cfg.score_config.check_assoc_disallowed;
+
+	if (check_assoc_disallowed &&
+	    wlan_parse_oce_assoc_disallowed_ie(mbo_oce, &reason)) {
+		mlme_nofl_debug("Candidate(%pM freq %d): rssi %d, assoc disallowed set in MBO/OCE IE reason %d",
+				entry->bssid.bytes, entry->channel.chan_freq,
+				entry->rssi_raw, reason);
+		return false;
+	}
+
+	return true;
+}
+
 void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 				 struct pcl_freq_weight_list *pcl_lst,
 				 qdf_list_t *scan_list,
@@ -985,6 +1008,7 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 	struct psoc_phy_config *config;
 	enum cm_blacklist_action blacklist_action;
 	struct wlan_objmgr_psoc *psoc;
+	bool assoc_allowed;
 
 	psoc = wlan_pdev_get_psoc(pdev);
 
@@ -1023,8 +1047,15 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 		scan_entry = qdf_container_of(cur_node, struct scan_cache_node,
 					      node);
 
-		blacklist_action =
-			wlan_blacklist_action_on_bssid(pdev, scan_entry->entry);
+		assoc_allowed = cm_is_assoc_allowed(mlme_psoc_obj,
+						    scan_entry->entry);
+
+		if (assoc_allowed)
+			blacklist_action = wlan_blacklist_action_on_bssid(pdev,
+							scan_entry->entry);
+		else
+			blacklist_action = CM_BLM_REMOVE;
+
 		if (blacklist_action == CM_BLM_NO_ACTION &&
 		    pcl_lst && pcl_lst->num_of_pcl_channels &&
 		    scan_entry->entry->rssi_raw > CM_PCL_RSSI_THRESHOLD &&
@@ -1059,12 +1090,14 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 				 scan_entry->entry->bssid.bytes);
 			return;
 		}
+
 		/*
-		 * If CM_BLM_REMOVE ie blacklisted then free the entry
-		 * else add back to the list sorted
+		 * If CM_BLM_REMOVE ie blacklisted or assoc not allowed then
+		 * free the entry else add back to the list sorted
 		 */
 		if (blacklist_action == CM_BLM_REMOVE) {
-			mlme_nofl_debug("Candidate(%pM freq %d): rssi %d, is in Blacklist, remove entry",
+			if (assoc_allowed)
+				mlme_nofl_debug("Candidate(%pM freq %d): rssi %d, is in Blacklist, remove entry",
 					scan_entry->entry->bssid.bytes,
 					scan_entry->entry->channel.chan_freq,
 					scan_entry->entry->rssi_raw);
@@ -1073,6 +1106,7 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
 		} else {
 			cm_list_insert_sorted(scan_list, scan_entry);
 		}
+
 		cur_node = next_node;
 		next_node = NULL;
 	}
@@ -1232,5 +1266,17 @@ void wlan_cm_init_score_config(struct wlan_objmgr_psoc *psoc,
 			cfg_get(psoc, CFG_SCORING_BAND_WEIGHT_PER_IDX));
 	score_cfg->is_bssid_hint_priority =
 			cfg_get(psoc, CFG_IS_BSSID_HINT_PRIORITY);
+	score_cfg->check_assoc_disallowed = false;
 }
 
+void wlan_cm_set_check_assoc_disallowed(struct wlan_objmgr_psoc *psoc,
+					bool value)
+{
+	struct psoc_mlme_obj *mlme_psoc_obj;
+
+	mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc);
+	if (!mlme_psoc_obj)
+		return;
+
+	mlme_psoc_obj->psoc_cfg.score_config.check_assoc_disallowed = value;
+}

+ 13 - 0
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_bss_score_param.h

@@ -124,6 +124,7 @@ struct per_slot_score {
  * @nss_weight_per_index: nss weight per index
  * @band_weight_per_index: band weight per index
  * @is_bssid_hint_priority: True if bssid_hint is given priority
+ * @check_assoc_disallowed: Should assoc be disallowed if MBO OCE IE indicate so
  */
 struct scoring_cfg {
 	struct weight_cfg weight_config;
@@ -134,6 +135,7 @@ struct scoring_cfg {
 	uint32_t nss_weight_per_index;
 	uint32_t band_weight_per_index;
 	bool is_bssid_hint_priority;
+	bool check_assoc_disallowed;
 };
 
 /**
@@ -197,4 +199,15 @@ void wlan_cm_calculate_bss_score(struct wlan_objmgr_pdev *pdev,
  */
 void wlan_cm_init_score_config(struct wlan_objmgr_psoc *psoc,
 			       struct scoring_cfg *score_cfg);
+
+/**
+ * wlan_cm_set_check_assoc_disallowed() - Set check assoc disallowed param
+ * @psoc: pointer to psoc object
+ * @value: value to be set
+ *
+ * Return: void
+ */
+void wlan_cm_set_check_assoc_disallowed(struct wlan_objmgr_psoc *psoc,
+					bool value);
+
 #endif