Explorar el Código

qcacmn: Consider all power types to prepare client channel list

Currently driver prepares client channel list based on indoor ap
power type and this list is given to kernel. There are couple of
issues with this approach as mentioned below:
1. Based on this list kernel sends the scan requests because of
which there is a possibility that driver does not scan channels
which are not part of LPI channel list but are part of SP channel
list or VLP channel list.
2. Kernel sends start AP as well based on this channel list, since
all LPI channel are marked as NO_IR from driver and because of
which kernel dont send start AP on these chanels which leads to
SAP start failure even if there are VLP channels available.

Change-Id: I90174920df158c8b370e541034307a9a58448c29
CRs-Fixed: 3054543
Ashish Kumar Dhanotiya hace 3 años
padre
commit
47bc1e1781
Se han modificado 1 ficheros con 122 adiciones y 10 borrados
  1. 122 10
      umac/regulatory/core/src/reg_build_chan_list.c

+ 122 - 10
umac/regulatory/core/src/reg_build_chan_list.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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
@@ -1132,12 +1132,118 @@ reg_modify_disable_chan_list_for_unii1_and_unii2a(
 
 #ifdef CONFIG_BAND_6GHZ
 #ifdef CONFIG_REG_CLIENT
+
+#ifdef CONFIG_AFC_SUPPORT
+/**
+ * reg_append_mas_chan_list_for_6g_sp() - Append SP channels to the master
+ * channel list
+ * @pdev_priv_obj: Pointer to pdev private object
+ *
+ * This function appends SP channels to the master channel list
+ *
+ * Return: void.
+ */
+static void
+reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj
+			       *pdev_priv_obj)
+{
+	struct regulatory_channel *master_chan_list_6g_client_sp;
+
+	master_chan_list_6g_client_sp = pdev_priv_obj->afc_chan_list;
+
+	qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
+		     master_chan_list_6g_client_sp,
+		     NUM_6GHZ_CHANNELS *
+		     sizeof(struct regulatory_channel));
+}
+#else
+static inline void
+reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj
+			       *pdev_priv_obj)
+{
+}
+#endif
+
+/**
+ * reg_append_mas_chan_list_for_6g_lpi() - Append LPI channels to the master
+ * channel list
+ * @pdev_priv_obj: Pointer to pdev private object
+ *
+ * This function appends LPI channels to the master channel list
+ *
+ * Return: void.
+ */
+static void
+reg_append_mas_chan_list_for_6g_lpi(struct wlan_regulatory_pdev_priv_obj
+			       *pdev_priv_obj)
+{
+	struct regulatory_channel *master_chan_list_6g_client_lpi;
+	uint8_t i, j;
+
+	if (!pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP]) {
+		reg_debug("No LPI reg rules");
+		return;
+	}
+
+	master_chan_list_6g_client_lpi =
+		pdev_priv_obj->mas_chan_list_6g_client[REG_INDOOR_AP]
+			[pdev_priv_obj->reg_cur_6g_client_mobility_type];
+
+	for (i = MIN_6GHZ_CHANNEL, j = 0;
+	     i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
+		if ((pdev_priv_obj->mas_chan_list[i].state ==
+			CHANNEL_STATE_DISABLE) ||
+			(pdev_priv_obj->mas_chan_list[i].chan_flags &
+			REGULATORY_CHAN_DISABLED)) {
+			qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
+				     &master_chan_list_6g_client_lpi[j],
+				     sizeof(struct regulatory_channel));
+		}
+	}
+}
+
+/**
+ * reg_append_mas_chan_list_for_6g_VLP() - Append VLP channels to the master
+ * channel list
+ * @pdev_priv_obj: Pointer to pdev private object
+ *
+ * This function appends VLP channels to the master channel list
+ *
+ * Return: void.
+ */
+static void
+reg_append_mas_chan_list_for_6g_vlp(struct wlan_regulatory_pdev_priv_obj
+			       *pdev_priv_obj)
+{
+	struct regulatory_channel *master_chan_list_6g_client_vlp;
+	uint8_t i, j;
+
+	if (!pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_VERY_LOW_POWER_AP]) {
+		reg_debug("No VLP reg rules");
+		return;
+	}
+
+	master_chan_list_6g_client_vlp =
+		pdev_priv_obj->mas_chan_list_6g_client[REG_VERY_LOW_POWER_AP]
+			[pdev_priv_obj->reg_cur_6g_client_mobility_type];
+
+	for (i = MIN_6GHZ_CHANNEL, j = 0;
+	     i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
+		if ((pdev_priv_obj->mas_chan_list[i].state ==
+			CHANNEL_STATE_DISABLE) ||
+		    (pdev_priv_obj->mas_chan_list[i].chan_flags &
+		      REGULATORY_CHAN_DISABLED)) {
+			qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
+				     &master_chan_list_6g_client_vlp[j],
+				     sizeof(struct regulatory_channel));
+		}
+	}
+}
+
 static void
 reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj
 				*pdev_priv_obj)
 {
-	struct regulatory_channel *master_chan_list_6g_client;
-
 	if (pdev_priv_obj->reg_cur_6g_ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE ||
 	    pdev_priv_obj->reg_cur_6g_client_mobility_type >=
 	    REG_MAX_CLIENT_TYPE) {
@@ -1145,14 +1251,20 @@ reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj
 		return;
 	}
 
-	master_chan_list_6g_client =
-		pdev_priv_obj->mas_chan_list_6g_client[REG_INDOOR_AP]
-			[pdev_priv_obj->reg_cur_6g_client_mobility_type];
+	/* Client should be able to scan all types of APs, so prepare the
+	 * client list which has all the enabled channels, first priority is
+	 * given to AFC power type and then second priority is decided based on
+	 * gindoor_channel_support ini value
+	 */
+	reg_append_mas_chan_list_for_6g_sp(pdev_priv_obj);
 
-	qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
-		     master_chan_list_6g_client,
-		     NUM_6GHZ_CHANNELS *
-		     sizeof(struct regulatory_channel));
+	if (pdev_priv_obj->indoor_chan_enabled) {
+		reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj);
+		reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj);
+	} else {
+		reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj);
+		reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj);
+	}
 }
 
 static void