Quellcode durchsuchen

qcacmn: Check chip capability when enable AP+AP

Check capability of dbs, mcc and scc on single band when enable
AP+AP, then same driver code can support different chip and
firmware.
Add wmi_service_dual_beacon_on_single_mac_(mcc/scc)_support

Change-Id: I505747122504b2a89813e7bdfcd27dc07539f39e
CRs-Fixed: 2214237
Zhu Jianmin vor 7 Jahren
Ursprung
Commit
da1d4517f4

+ 35 - 0
umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -2297,4 +2297,39 @@ QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc,
  */
 QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * policy_mgr_allow_sap_go_concurrency() - check whether multiple SAP/GO
+ * interfaces are allowed
+ * @psoc: pointer to soc
+ * @policy_mgr_con_mode: operating mode of the new interface
+ * @channel: operating channel of the new interface
+ * This function checks whether second SAP/GO interface is allowed on the same
+ * MAC.
+ *
+ * Return: true or false
+ */
+bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc,
+					 enum policy_mgr_con_mode mode,
+					 uint8_t channel);
+
+/**
+ * policy_mgr_dual_beacon_on_single_mac_scc_capable() - get capability that
+ * whether support dual beacon on same channel on single MAC
+ * @psoc: pointer to soc
+ *
+ *  Return: bool: capable
+ */
+bool policy_mgr_dual_beacon_on_single_mac_scc_capable(
+	struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_dual_beacon_on_single_mac_mcc_capable() - get capability that
+ * whether support dual beacon on different channel on single MAC
+ * @psoc: pointer to soc
+ *
+ *  Return: bool: capable
+ */
+bool policy_mgr_dual_beacon_on_single_mac_mcc_capable(
+	struct wlan_objmgr_psoc *psoc);
+
 #endif /* __WLAN_POLICY_MGR_API_H */

+ 119 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -1693,6 +1693,11 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
 		}
 	}
 
+	if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, channel)) {
+		policy_mgr_err("This concurrency combination is not allowed");
+		goto done;
+	}
+
 	/* don't allow two P2P GO on same band */
 	if (channel && (mode == PM_P2P_GO_MODE) && num_connections) {
 		index = 0;
@@ -2950,3 +2955,117 @@ uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc,
 
 	return count;
 }
+
+bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc,
+					 enum policy_mgr_con_mode mode,
+					 uint8_t channel)
+{
+	uint32_t sap_cnt;
+	uint32_t go_cnt;
+	enum policy_mgr_con_mode con_mode;
+	uint8_t con_chan;
+	int id;
+
+	sap_cnt = policy_mgr_mode_specific_connection_count(psoc,
+							    PM_SAP_MODE,
+							    NULL);
+	go_cnt = policy_mgr_mode_specific_connection_count(psoc,
+							   PM_P2P_GO_MODE,
+							   NULL);
+
+	if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) &&
+	    (sap_cnt || go_cnt)) {
+		if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc))
+			return true;
+		if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc)) {
+			for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS;
+				id++) {
+				if (pm_conc_connection_list[id].in_use) {
+					con_mode =
+					    pm_conc_connection_list[id].mode;
+					con_chan =
+					    pm_conc_connection_list[id].chan;
+					if (((con_mode == PM_SAP_MODE) ||
+					     (con_mode == PM_P2P_GO_MODE)) &&
+					    (channel != con_chan)) {
+						policy_mgr_debug("Scc is supported, but first SAP and second SAP are not in same channel, So don't allow second SAP interface");
+						return false;
+					}
+				}
+			}
+			return true;
+		}
+		if (!policy_mgr_is_hw_dbs_capable(psoc)) {
+			policy_mgr_debug("DBS is not supported, mcc and scc are not supported too, don't allow second SAP interface");
+			return false;
+		}
+		/* If DBS is supported then allow second SAP/GO session only if
+		 * the freq band of the second SAP/GO interface is different
+		 * than the first SAP/GO interface.
+		 */
+		for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) {
+			if (pm_conc_connection_list[id].in_use) {
+				con_mode = pm_conc_connection_list[id].mode;
+				con_chan = pm_conc_connection_list[id].chan;
+				if (((con_mode == PM_SAP_MODE) ||
+				     (con_mode == PM_P2P_GO_MODE)) &&
+				    (WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
+					con_chan))) {
+					policy_mgr_debug("DBS is supported, but first SAP and second SAP are on same band, So don't allow second SAP interface");
+					return false;
+				}
+			}
+		}
+	}
+
+	/* Don't block the second interface */
+	return true;
+}
+
+bool policy_mgr_dual_beacon_on_single_mac_scc_capable(
+		struct wlan_objmgr_psoc *psoc)
+{
+	void *wmi_handle = NULL;
+
+	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+	if (!wmi_handle) {
+		policy_mgr_debug("Invalid WMI handle");
+		return false;
+	}
+
+	if (wmi_service_enabled(
+			wmi_handle,
+			wmi_service_dual_beacon_on_single_mac_scc_support)) {
+		policy_mgr_debug("Support dual beacon on same channel on single MAC");
+		return true;
+	}
+	if (wmi_service_enabled(
+			wmi_handle,
+			wmi_service_dual_beacon_on_single_mac_mcc_support)) {
+		policy_mgr_debug("Support dual beacon on both different and same channel on single MAC");
+		return true;
+	}
+	policy_mgr_debug("Not support dual beacon on same channel on single MAC");
+	return false;
+}
+
+bool policy_mgr_dual_beacon_on_single_mac_mcc_capable(
+		struct wlan_objmgr_psoc *psoc)
+{
+	void *wmi_handle = NULL;
+
+	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+	if (!wmi_handle) {
+		policy_mgr_debug("Invalid WMI handle");
+		return false;
+	}
+
+	if (wmi_service_enabled(
+			wmi_handle,
+			wmi_service_dual_beacon_on_single_mac_mcc_support)) {
+		policy_mgr_debug("Support dual beacon on different channel on single MAC");
+		return true;
+	}
+	policy_mgr_debug("Not support dual beacon on different channel on single MAC");
+	return false;
+}

+ 2 - 0
wmi/inc/wmi_unified_param.h

@@ -5951,6 +5951,8 @@ typedef enum {
 	wmi_service_bss_color_offload,
 	wmi_service_gmac_offload_support,
 	wmi_service_host_dfs_check_support,
+	wmi_service_dual_beacon_on_single_mac_scc_support,
+	wmi_service_dual_beacon_on_single_mac_mcc_support,
 
 	wmi_services_max,
 } wmi_conv_service_ids;

+ 10 - 0
wmi/src/wmi_unified_tlv.c

@@ -18019,6 +18019,12 @@ static bool is_service_enabled_tlv(wmi_unified_t wmi_handle,
 				soc->wmi_ext_service_bitmap,
 				service_id);
 
+	if (service_id >= WMI_MAX_SERVICE) {
+		WMI_LOGE("Service id %d but WMI ext service bitmap is NULL",
+			 service_id);
+		return false;
+	}
+
 	return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap,
 				service_id);
 }
@@ -23559,6 +23565,10 @@ static void populate_tlv_service(uint32_t *wmi_service)
 				WMI_SERVICE_BSS_COLOR_OFFLOAD;
 	wmi_service[wmi_service_gmac_offload_support] =
 				WMI_SERVICE_GMAC_OFFLOAD_SUPPORT;
+	wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] =
+			WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT;
+	wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] =
+			WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT;
 
 }