Browse Source

Merge "qcacmn: Attach 2x2+1x1 action tables"

Linux Build Service Account 6 years ago
parent
commit
c5517c51b6

+ 20 - 3
qdf/inc/qdf_debugfs.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 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
@@ -111,10 +111,21 @@ void qdf_debugfs_printf(qdf_debugfs_file_t file, const char *f, ...);
  * @file: debugfs file handle passed in fops->show() function.
  * @buf: data
  * @len: data length
+ * @rowsize: row size in bytes to dump
+ * @groupsize: group size in bytes to dump
  *
  */
 void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf,
-			 qdf_size_t len);
+			 qdf_size_t len, int rowsize, int groupsize);
+
+/**
+ * qdf_debugfs_overflow() - check overflow occurrence in debugfs buffer
+ * @file: debugfs file handle passed in fops->show() function.
+ *
+ * Return: 1 on overflow occurrence else 0
+ *
+ */
+bool qdf_debugfs_overflow(qdf_debugfs_file_t file);
 
 /**
  * qdf_debugfs_write() - write data into debugfs file
@@ -260,8 +271,14 @@ static inline void qdf_debugfs_printf(qdf_debugfs_file_t file, const char *f,
 }
 
 static inline void qdf_debugfs_hexdump(qdf_debugfs_file_t file,
-				       const uint8_t *buf, qdf_size_t len)
+				       const uint8_t *buf, qdf_size_t len,
+				       int rowsize, int groupsize)
+{
+}
+
+static inline bool qdf_debugfs_overflow(qdf_debugfs_file_t file)
 {
+	return 0;
 }
 
 static inline void qdf_debugfs_write(qdf_debugfs_file_t file,

+ 9 - 5
qdf/linux/src/qdf_debugfs.c

@@ -170,18 +170,17 @@ void qdf_debugfs_printf(qdf_debugfs_file_t file, const char *f, ...)
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
 
 void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf,
-			 qdf_size_t len)
+			 qdf_size_t len, int rowsize, int groupsize)
 {
-	seq_hex_dump(file, "", DUMP_PREFIX_OFFSET, 16, 4, buf, len, false);
+	seq_hex_dump(file, "", DUMP_PREFIX_OFFSET, rowsize, groupsize, buf, len,
+		     false);
 }
 
 #else
 
 void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf,
-			 qdf_size_t len)
+			 qdf_size_t len, int rowsize, int groupsize)
 {
-	const size_t rowsize = 16;
-	const size_t groupsize = 4;
 	char *dst;
 	size_t dstlen, readlen;
 	int prefix = 0;
@@ -206,6 +205,11 @@ void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf,
 
 #endif
 
+bool qdf_debugfs_overflow(qdf_debugfs_file_t file)
+{
+	return seq_has_overflowed(file);
+}
+
 void qdf_debugfs_write(qdf_debugfs_file_t file, const uint8_t *buf,
 		       qdf_size_t len)
 {

+ 9 - 3
qdf/linux/src/qdf_lock.c

@@ -315,7 +315,13 @@ qdf_export_symbol(qdf_wake_lock_acquire);
  * QDF status success: if wake lock is acquired
  * QDF status failure: if wake lock was not acquired
  */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+QDF_STATUS qdf_wake_lock_timeout_acquire(qdf_wake_lock_t *lock, uint32_t msec)
+{
+	pm_wakeup_ws_event(lock, msec, true);
+	return QDF_STATUS_SUCCESS;
+}
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
 QDF_STATUS qdf_wake_lock_timeout_acquire(qdf_wake_lock_t *lock, uint32_t msec)
 {
 	/* Wakelock for Rx is frequent.
@@ -324,12 +330,12 @@ QDF_STATUS qdf_wake_lock_timeout_acquire(qdf_wake_lock_t *lock, uint32_t msec)
 	__pm_wakeup_event(lock, msec);
 	return QDF_STATUS_SUCCESS;
 }
-#else
+#else /* LINUX_VERSION_CODE */
 QDF_STATUS qdf_wake_lock_timeout_acquire(qdf_wake_lock_t *lock, uint32_t msec)
 {
 	return QDF_STATUS_SUCCESS;
 }
-#endif
+#endif /* LINUX_VERSION_CODE */
 qdf_export_symbol(qdf_wake_lock_timeout_acquire);
 
 /**

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

@@ -546,6 +546,33 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
 bool policy_mgr_is_dbs_allowed_for_concurrency(
 		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode);
 
+/**
+ * policy_mgr_get_preferred_dbs_action_table() - get dbs action table type
+ * @psoc: Pointer to psoc
+ * @vdev_id: vdev Id
+ * @channel: channel of vdev.
+ * @reason: reason of request
+ *
+ * 1. Based on band preferred and vdev priority setting to choose the preferred
+ * dbs action.
+ * 2. This routine will be used to get DBS switching action tables.
+ * In Genoa, two action tables for DBS1 (2x2 5G + 1x1 2G), DBS2
+ *  (2x2 2G + 1x1 5G).
+ * 3. It can be used in mode change case in CSA channel switching or Roaming,
+ * opportunistic upgrade. If needs switch to DBS, we needs to query this
+ * function to get preferred DBS mode.
+ * 4. This is mainly used for dual dbs mode HW. For Legacy HW, there is
+ * only single DBS mode. This function will return PM_NOP.
+ *
+ * return : PM_NOP, PM_DBS1, PM_DBS2
+ */
+enum policy_mgr_conc_next_action
+policy_mgr_get_preferred_dbs_action_table(
+	struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id,
+	uint8_t channel,
+	enum policy_mgr_conn_update_reason reason);
+
 /**
  * policy_mgr_is_ibss_conn_exist() - to check if IBSS connection already present
  * @psoc: PSOC object information

+ 32 - 0
umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h

@@ -1031,6 +1031,25 @@ struct dual_mac_config {
 	uint32_t req_fw_mode_config;
 };
 
+/**
+ * enum policy_mgr_pri_id - vdev type priority id
+ * @PM_STA_PRI_ID: station vdev type priority id
+ * @PM_SAP_PRI_ID: sap vdev type priority id
+ * @PM_P2P_GO_PRI_ID: p2p go vdev type priority id
+ * @PM_P2P_CLI_PRI_ID: p2p cli vdev type priority id
+ * @PM_MAX_PRI_ID: vdev type priority id max value
+ */
+enum policy_mgr_pri_id {
+	PM_STA_PRI_ID = 1,
+	PM_SAP_PRI_ID,
+	PM_P2P_GO_PRI_ID,
+	PM_P2P_CLI_PRI_ID,
+	PM_MAX_PRI_ID = 0xF,
+};
+
+#define PM_GET_BAND_PREFERRED(_policy_) ((_policy_) & 0x1)
+#define PM_GET_VDEV_PRIORITY_ENABLED(_policy_) (((_policy_) & 0x2) >> 1)
+
 /**
  * struct policy_mgr_user_cfg - Policy manager user config variables
  * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler
@@ -1040,6 +1059,17 @@ struct dual_mac_config {
  * @enable2x2: 2x2 chain mask user config
  * @mcc_to_scc_switch_mode: Control SAP channel in concurrency
  * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled
+ * @dbs_selection_policy: band preference or Vdev preference
+ *      bit[0] = 0: 5G 2x2 preferred to select 2x2 5G + 1x1 2G DBS mode.
+ *      bit[0] = 1: 2G 2x2 preferred to select 2x2 2G + 1x1 5G DBS mode.
+ *      bit[1] = 1: vdev priority enabled.
+ *      bit[1] = 0: vdev priority disabled.
+ * @vdev_priority_list: vdev priority list
+ *      bit[0-3]: pri_id (policy_mgr_pri_id) of highest priority
+ *      bit[4-7]: pri_id (policy_mgr_pri_id) of second priority
+ *      bit[8-11]: pri_id (policy_mgr_pri_id) of third priority
+ *      bit[12-15]: pri_id (policy_mgr_pri_id) of fourth priority
+ *      example: 0x4321 - CLI < GO < SAP < STA
  */
 struct policy_mgr_user_cfg {
 	uint8_t enable_mcc_adaptive_scheduler;
@@ -1051,6 +1081,8 @@ struct policy_mgr_user_cfg {
 	bool is_sta_sap_scc_allowed_on_dfs_chan;
 	uint32_t channel_select_logic_conc;
 	uint32_t sta_sap_scc_on_lte_coex_chan;
+	uint32_t dbs_selection_policy;
+	uint32_t vdev_priority_list;
 };
 
 /**

+ 244 - 4
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -513,6 +513,242 @@ bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
 	return true;
 }
 
+/**
+ * policy_mgr_pri_id_to_con_mode() - convert policy_mgr_pri_id to
+ * policy_mgr_con_mode
+ * @pri_id: policy_mgr_pri_id
+ *
+ * The help function converts policy_mgr_pri_id type to  policy_mgr_con_mode
+ * type.
+ *
+ * Return: policy_mgr_con_mode type.
+ */
+static
+enum policy_mgr_con_mode policy_mgr_pri_id_to_con_mode(
+	enum policy_mgr_pri_id pri_id)
+{
+	switch (pri_id) {
+	case PM_STA_PRI_ID:
+		return PM_STA_MODE;
+	case PM_SAP_PRI_ID:
+		return PM_SAP_MODE;
+	case PM_P2P_GO_PRI_ID:
+		return PM_P2P_GO_MODE;
+	case PM_P2P_CLI_PRI_ID:
+		return PM_P2P_CLIENT_MODE;
+	default:
+		return PM_MAX_NUM_OF_MODE;
+	}
+}
+
+enum policy_mgr_conc_next_action
+policy_mgr_get_preferred_dbs_action_table(
+	struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id,
+	uint8_t channel,
+	enum policy_mgr_conn_update_reason reason)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum policy_mgr_con_mode pri_conn_mode = PM_MAX_NUM_OF_MODE;
+	enum policy_mgr_con_mode new_conn_mode = PM_MAX_NUM_OF_MODE;
+	enum QDF_OPMODE new_conn_op_mode = QDF_MAX_NO_OF_MODE;
+	bool band_pref_5g = true;
+	bool vdev_priority_enabled = false;
+	bool dbs_2x2_5g_1x1_2g_supported;
+	bool dbs_2x2_2g_1x1_5g_supported;
+	uint32_t vdev_pri_list, vdev_pri_id;
+	uint8_t chan_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
+	uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
+	uint32_t vdev_count = 0;
+	uint32_t i;
+	bool found;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return PM_NOP;
+	}
+	dbs_2x2_5g_1x1_2g_supported =
+		policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc);
+	dbs_2x2_2g_1x1_5g_supported =
+		policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc);
+	policy_mgr_debug("target support DBS1 %d DBS2 %d",
+			 dbs_2x2_5g_1x1_2g_supported,
+			 dbs_2x2_2g_1x1_5g_supported);
+	/*
+	 * If both DBS1 and DBS2 not supported, this should be Legacy Single
+	 * DBS mode HW. The policy_mgr_psoc_enable has setup the correct
+	 * action tables.
+	 */
+	if (!dbs_2x2_5g_1x1_2g_supported && !dbs_2x2_2g_1x1_5g_supported)
+		return PM_NOP;
+	if (!dbs_2x2_5g_1x1_2g_supported) {
+		band_pref_5g = false;
+		policy_mgr_debug("target only supports DBS2!");
+		goto DONE;
+	}
+	if (!dbs_2x2_2g_1x1_5g_supported) {
+		policy_mgr_debug("target only supports DBS1!");
+		goto DONE;
+	}
+	if (PM_GET_BAND_PREFERRED(pm_ctx->user_cfg.dbs_selection_policy) == 1)
+		band_pref_5g = false;
+
+	if (PM_GET_VDEV_PRIORITY_ENABLED(
+	    pm_ctx->user_cfg.dbs_selection_policy) == 1 &&
+	    pm_ctx->user_cfg.vdev_priority_list)
+		vdev_priority_enabled = true;
+
+	if (!vdev_priority_enabled)
+		goto DONE;
+
+	if (vdev_id != INVALID_VDEV_ID && channel) {
+		if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
+			new_conn_op_mode = pm_ctx->hdd_cbacks.
+					hdd_get_device_mode(vdev_id);
+
+		new_conn_mode = policy_mgr_convert_device_mode_to_qdf_type(
+			new_conn_op_mode);
+		if (new_conn_mode == PM_MAX_NUM_OF_MODE)
+			policy_mgr_debug("new vdev %d op_mode %d chan %d reason %d: not prioritized",
+					 vdev_id, new_conn_op_mode,
+					 channel, reason);
+		else
+			policy_mgr_debug("new vdev %d op_mode %d chan %d : reason %d",
+					 vdev_id, new_conn_op_mode, channel,
+					 reason);
+	}
+	vdev_pri_list = pm_ctx->user_cfg.vdev_priority_list;
+	while (vdev_pri_list) {
+		vdev_pri_id = vdev_pri_list & 0xF;
+		pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id);
+		if (pri_conn_mode == PM_MAX_NUM_OF_MODE) {
+			policy_mgr_debug("vdev_pri_id %d prioritization not supported",
+					 vdev_pri_id);
+			goto NEXT;
+		}
+		vdev_count = policy_mgr_get_mode_specific_conn_info(
+				psoc, chan_list, vdev_list, pri_conn_mode);
+		/**
+		 * Take care of duplication case, the vdev id may
+		 * exist in the conn list already with old chan.
+		 * Replace with new chan before make decision.
+		 */
+		found = false;
+		for (i = 0; i < vdev_count; i++) {
+			policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d",
+					 i, vdev_list[i], chan_list[i],
+					 pri_conn_mode);
+
+			if (new_conn_mode == pri_conn_mode &&
+			    vdev_list[i] == vdev_id) {
+				chan_list[i] = channel;
+				found = true;
+			}
+		}
+		/**
+		 * The new coming vdev should be added to the list to
+		 * make decision if it is prioritized.
+		 */
+		if (!found && new_conn_mode == pri_conn_mode) {
+			chan_list[vdev_count] = channel;
+			vdev_list[vdev_count++] = vdev_id;
+		}
+		/**
+		 * if more than one vdev has same priority, keep "band_pref_5g"
+		 * value as default band preference setting.
+		 */
+		if (vdev_count > 1)
+			break;
+		/**
+		 * select the only active vdev (or new coming vdev) chan as
+		 * preferred band.
+		 */
+		if (vdev_count > 0) {
+			band_pref_5g = WLAN_REG_IS_5GHZ_CH(chan_list[0]);
+			break;
+		}
+NEXT:
+		vdev_pri_list >>= 4;
+	}
+DONE:
+	policy_mgr_debug("band_pref_5g %d", band_pref_5g);
+	if (band_pref_5g)
+		return PM_DBS1;
+	else
+		return PM_DBS2;
+}
+
+/**
+ * policy_mgr_get_second_conn_action_table() - get second conn action table
+ * @psoc: Pointer to psoc
+ * @vdev_id: vdev Id
+ * @channel: channel of vdev.
+ * @reason: reason of request
+ *
+ * Get the action table based on current HW Caps and INI user preference.
+ * This function will be called by policy_mgr_current_connections_update during
+ * DBS action decision.
+ *
+ * return : action table address
+ */
+static policy_mgr_next_action_two_connection_table_type *
+policy_mgr_get_second_conn_action_table(
+	struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id,
+	uint8_t channel,
+	enum policy_mgr_conn_update_reason reason)
+{
+	enum policy_mgr_conc_next_action preferred_action;
+
+	if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
+		return next_action_two_connection_table;
+
+	preferred_action = policy_mgr_get_preferred_dbs_action_table(
+				psoc, vdev_id, channel, reason);
+	switch (preferred_action) {
+	case PM_DBS2:
+		return next_action_two_connection_2x2_2g_1x1_5g_table;
+	default:
+		return next_action_two_connection_table;
+	}
+}
+
+/**
+ * policy_mgr_get_third_conn_action_table() - get third connection action table
+ * @psoc: Pointer to psoc
+ * @vdev_id: vdev Id
+ * @channel: channel of vdev.
+ * @reason: reason of request
+ *
+ * Get the action table based on current HW Caps and INI user preference.
+ * This function will be called by policy_mgr_current_connections_update during
+ * DBS action decision.
+ *
+ * return : action table address
+ */
+static policy_mgr_next_action_three_connection_table_type *
+policy_mgr_get_third_conn_action_table(
+	struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id,
+	uint8_t channel,
+	enum policy_mgr_conn_update_reason reason)
+{
+	enum policy_mgr_conc_next_action preferred_action;
+
+	if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
+		return next_action_three_connection_table;
+
+	preferred_action = policy_mgr_get_preferred_dbs_action_table(
+				psoc, vdev_id, channel, reason);
+	switch (preferred_action) {
+	case PM_DBS2:
+		return next_action_three_connection_2x2_2g_1x1_5g_table;
+	default:
+		return next_action_three_connection_table;
+	}
+}
+
 QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
 		uint32_t session_id,
 		uint8_t channel,
@@ -522,6 +758,8 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
 	uint32_t num_connections = 0;
 	enum policy_mgr_one_connection_mode second_index = 0;
 	enum policy_mgr_two_connection_mode third_index = 0;
+	policy_mgr_next_action_two_connection_table_type *second_conn_table;
+	policy_mgr_next_action_three_connection_table_type *third_conn_table;
 	enum policy_mgr_band band;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
@@ -559,8 +797,9 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
 			"couldn't find index for 2nd connection next action table");
 			goto done;
 		}
-		next_action =
-			(*next_action_two_connection_table)[second_index][band];
+		second_conn_table = policy_mgr_get_second_conn_action_table(
+			psoc, session_id, channel, reason);
+		next_action = (*second_conn_table)[second_index][band];
 		break;
 	case 2:
 		third_index =
@@ -570,8 +809,9 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
 			"couldn't find index for 3rd connection next action table");
 			goto done;
 		}
-		next_action = (*next_action_three_connection_table)
-							[third_index][band];
+		third_conn_table = policy_mgr_get_third_conn_action_table(
+			psoc, session_id, channel, reason);
+		next_action = (*third_conn_table)[third_index][band];
 		break;
 	default:
 		policy_mgr_err("unexpected num_connections value %d",

+ 4 - 1
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -1984,7 +1984,10 @@ QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc,
 	}
 
 	pm_ctx->user_cfg = *user_cfg;
-
+	policy_mgr_debug("dbs_selection_policy 0x%x",
+			 user_cfg->dbs_selection_policy);
+	policy_mgr_debug("vdev_priority_list 0x%x",
+			 user_cfg->vdev_priority_list);
 	pm_ctx->cur_conc_system_pref = pm_ctx->user_cfg.conc_system_pref;
 
 	return QDF_STATUS_SUCCESS;

+ 5 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -195,6 +195,11 @@ extern policy_mgr_next_action_two_connection_table_type
 		*next_action_two_connection_table;
 extern policy_mgr_next_action_three_connection_table_type
 		*next_action_three_connection_table;
+extern policy_mgr_next_action_two_connection_table_type
+		*next_action_two_connection_2x2_2g_1x1_5g_table;
+extern policy_mgr_next_action_three_connection_table_type
+		*next_action_three_connection_2x2_2g_1x1_5g_table;
+
 extern enum policy_mgr_conc_next_action
 	(*policy_mgr_get_current_pref_hw_mode_ptr)
 	(struct wlan_objmgr_psoc *psoc);

+ 30 - 6
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -28,6 +28,8 @@
 #include "wlan_policy_mgr_api.h"
 #include "wlan_policy_mgr_tables_1x1_dbs_i.h"
 #include "wlan_policy_mgr_tables_2x2_dbs_i.h"
+#include "wlan_policy_mgr_tables_2x2_5g_1x1_2g.h"
+#include "wlan_policy_mgr_tables_2x2_2g_1x1_5g.h"
 #include "wlan_policy_mgr_i.h"
 #include "qdf_types.h"
 #include "qdf_trace.h"
@@ -425,33 +427,55 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc)
 		policy_mgr_get_current_pref_hw_mode_ptr =
 		policy_mgr_get_current_pref_hw_mode_dbs_1x1;
 
-	if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
+	if (policy_mgr_is_hw_dbs_2x2_capable(psoc) ||
+	    policy_mgr_is_2x2_1x1_dbs_capable(psoc))
 		second_connection_pcl_dbs_table =
 		&pm_second_connection_pcl_dbs_2x2_table;
 	else
 		second_connection_pcl_dbs_table =
 		&pm_second_connection_pcl_dbs_1x1_table;
 
-	if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
+	if (policy_mgr_is_hw_dbs_2x2_capable(psoc) ||
+	    policy_mgr_is_2x2_1x1_dbs_capable(psoc))
 		third_connection_pcl_dbs_table =
 		&pm_third_connection_pcl_dbs_2x2_table;
 	else
 		third_connection_pcl_dbs_table =
 		&pm_third_connection_pcl_dbs_1x1_table;
 
-	if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
+	if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) {
 		next_action_two_connection_table =
 		&pm_next_action_two_connection_dbs_2x2_table;
-	else
+	} else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) {
+		next_action_two_connection_table =
+		&pm_next_action_two_connection_dbs_2x2_5g_1x1_2g_table;
+		next_action_two_connection_2x2_2g_1x1_5g_table =
+		&pm_next_action_two_connection_dbs_2x2_2g_1x1_5g_table;
+	} else {
 		next_action_two_connection_table =
 		&pm_next_action_two_connection_dbs_1x1_table;
+	}
 
-	if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
+	if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) {
 		next_action_three_connection_table =
 		&pm_next_action_three_connection_dbs_2x2_table;
-	else
+	} else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) {
+		next_action_three_connection_table =
+		&pm_next_action_three_connection_dbs_2x2_5g_1x1_2g_table;
+		next_action_three_connection_2x2_2g_1x1_5g_table =
+		&pm_next_action_three_connection_dbs_2x2_2g_1x1_5g_table;
+	} else {
 		next_action_three_connection_table =
 		&pm_next_action_three_connection_dbs_1x1_table;
+	}
+	policy_mgr_debug("is DBS Capable %d, is SBS Capable %d",
+			 policy_mgr_is_hw_dbs_capable(psoc),
+			 policy_mgr_is_hw_sbs_capable(psoc));
+	policy_mgr_debug("is2x2 %d, is2x2+1x1 %d, is2x2_5g+1x1_2g %d, is2x2_2g+1x1_5g %d",
+			 policy_mgr_is_hw_dbs_2x2_capable(psoc),
+			 policy_mgr_is_2x2_1x1_dbs_capable(psoc),
+			 policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc),
+			 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc));
 
 	return QDF_STATUS_SUCCESS;
 }

+ 4 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -55,6 +55,10 @@ policy_mgr_next_action_two_connection_table_type
 		*next_action_two_connection_table;
 policy_mgr_next_action_three_connection_table_type
 		*next_action_three_connection_table;
+policy_mgr_next_action_two_connection_table_type
+		*next_action_two_connection_2x2_2g_1x1_5g_table;
+policy_mgr_next_action_three_connection_table_type
+		*next_action_three_connection_2x2_2g_1x1_5g_table;
 
 QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc,
 		enum policy_mgr_con_mode mode,