Quellcode durchsuchen

Merge branch 'wlan-cmn.driver.lnx.2.0' of ../qca-wifi-host-cmn into HEAD

Linux Build Service Account vor 6 Jahren
Ursprung
Commit
bf95f89d58

+ 2781 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -0,0 +1,2781 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WLAN_POLICY_MGR_API_H
+#define __WLAN_POLICY_MGR_API_H
+
+/**
+ * DOC: wlan_policy_mgr_api.h
+ *
+ * Concurrenct Connection Management entity
+ */
+
+/* Include files */
+#include "qdf_types.h"
+#include "qdf_status.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_policy_mgr_public_struct.h"
+
+struct target_psoc_info;
+
+typedef const enum policy_mgr_pcl_type
+	pm_dbs_pcl_second_connection_table_type
+	[PM_MAX_ONE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE]
+	[PM_MAX_CONC_PRIORITY_MODE];
+
+typedef const enum policy_mgr_pcl_type
+	pm_dbs_pcl_third_connection_table_type
+	[PM_MAX_TWO_CONNECTION_MODE][PM_MAX_NUM_OF_MODE]
+	[PM_MAX_CONC_PRIORITY_MODE];
+
+typedef const enum policy_mgr_conc_next_action
+	policy_mgr_next_action_two_connection_table_type
+	[PM_MAX_ONE_CONNECTION_MODE][POLICY_MGR_MAX_BAND];
+
+typedef const enum policy_mgr_conc_next_action
+	policy_mgr_next_action_three_connection_table_type
+	[PM_MAX_TWO_CONNECTION_MODE][POLICY_MGR_MAX_BAND];
+
+#define PM_FW_MODE_STA_STA_BIT_POS       0
+#define PM_FW_MODE_STA_P2P_BIT_POS       1
+
+#define PM_FW_MODE_STA_STA_BIT_MASK      (0x1 << PM_FW_MODE_STA_STA_BIT_POS)
+#define PM_FW_MODE_STA_P2P_BIT_MASK      (0x1 << PM_FW_MODE_STA_P2P_BIT_POS)
+
+#define PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(channel_select_logic_conc)  \
+	((channel_select_logic_conc & PM_FW_MODE_STA_STA_BIT_MASK) >>   \
+	 PM_FW_MODE_STA_STA_BIT_POS)
+#define PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(channel_select_logic_conc)  \
+	((channel_select_logic_conc & PM_FW_MODE_STA_P2P_BIT_MASK) >>   \
+	 PM_FW_MODE_STA_P2P_BIT_POS)
+
+/**
+ * policy_mgr_get_mcc_scc_switch() - To mcc to scc switch setting from INI
+ * @psoc: pointer to psoc
+ * @mcc_scc_switch: value to be filled
+ *
+ * This API pulls mcc to scc switch setting which is given as part of INI and
+ * stored in policy manager's CFGs.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *mcc_scc_switch);
+/**
+ * policy_mgr_get_sys_pref() - to get system preference
+ * @psoc: pointer to psoc
+ * @sys_pref: value to be filled
+ *
+ * This API pulls the system preference for policy manager to provide
+ * PCL
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc,
+					uint8_t *sys_pref);
+/**
+ * policy_mgr_set_sys_pref() - to set system preference
+ * @psoc: pointer to psoc
+ * @sys_pref: value to be applied as new INI setting
+ *
+ * This API is meant to override original INI setting for system pref
+ * with new value which is used by policy manager to provide PCL
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc,
+				   uint8_t sys_pref);
+/**
+ * policy_mgr_get_max_conc_cxns() - to get max num of conc connections
+ * @psoc: pointer to psoc
+ * @max_conc_cxns: value to be filled
+ *
+ * This API pulls max number of active connections which can be allowed
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
+						uint8_t *max_conc_cxns);
+/**
+ * policy_mgr_get_conc_rule1() - to find out if conc rule1 is enabled
+ * @psoc: pointer to psoc
+ * @conc_rule1: value to be filled
+ *
+ * This API is used to find out if conc rule-1 is enabled by user
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc,
+						uint8_t *conc_rule1);
+/**
+ * policy_mgr_get_conc_rule2() - to find out if conc rule2 is enabled
+ * @psoc: pointer to psoc
+ * @conc_rule2: value to be filled
+ *
+ * This API is used to find out if conc rule-2 is enabled by user
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc,
+						uint8_t *conc_rule2);
+/**
+ * policy_mgr_get_dbs_selection_plcy() - DBS HW mode selection setting
+ * @psoc: pointer to psoc
+ * @dbs_selection_plcy: value to be filled
+ *
+ * This API is used to find out DBS HW mode preference.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc,
+						uint32_t *dbs_selection_plcy);
+/**
+ * policy_mgr_get_vdev_priority_list() - to get vdev priority list
+ * @psoc: pointer to psoc
+ * @vdev_priority_list: value to be filled
+ *
+ * This API is used to find out vdev_priority_list setting
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc,
+						uint32_t *vdev_priority_list);
+/**
+ * policy_mgr_get_chnl_select_plcy() - to get channel selection policy
+ * @psoc: pointer to psoc
+ * @chnl_select_plcy: value to be filled
+ *
+ * This API is used to find out which channel selection policy has been
+ * configured
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc,
+						uint32_t *chnl_select_plcy);
+
+/**
+ * policy_mgr_get_mcc_adaptive_sch() - to get mcc adaptive scheduler
+ * @psoc: pointer to psoc
+ * @enable_mcc_adaptive_sch: value to be filled
+ *
+ * This API is used to find out if mcc adaptive scheduler enabled or disabled
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
+					   uint8_t *enable_mcc_adaptive_sch);
+
+/**
+ * policy_mgr_get_sta_cxn_5g_band() - to get STA's connection in 5G config
+ *
+ * @psoc: pointer to psoc
+ * @enable_sta_cxn_5g_band: value to be filled
+ *
+ * This API is used to find out if STA connection in 5G band is allowed or
+ * disallowed.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc,
+					   uint8_t *enable_sta_cxn_5g_band);
+/**
+ * policy_mgr_set_concurrency_mode() - To set concurrency mode
+ * @psoc: PSOC object data
+ * @mode: device mode
+ *
+ * This routine is called to set the concurrency mode
+ *
+ * Return: NONE
+ */
+void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc,
+				     enum QDF_OPMODE mode);
+
+/**
+ * policy_mgr_clear_concurrency_mode() - To clear concurrency mode
+ * @psoc: PSOC object data
+ * @mode: device mode
+ *
+ * This routine is called to clear the concurrency mode
+ *
+ * Return: NONE
+ */
+void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc,
+				       enum QDF_OPMODE mode);
+
+/**
+ * policy_mgr_get_connection_count() - provides the count of
+ * current connections
+ * @psoc: PSOC object information
+ *
+ * This function provides the count of current connections
+ *
+ * Return: connection count
+ */
+uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_concurrency_mode() - return concurrency mode
+ * @psoc: PSOC object information
+ *
+ * This routine is used to retrieve concurrency mode
+ *
+ * Return: uint32_t value of concurrency mask
+ */
+uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_search_and_check_for_session_conc() - Checks if
+ * concurrecy is allowed
+ * @psoc: PSOC object information
+ * @session_id: Session id
+ * @roam_profile: Pointer to the roam profile
+ *
+ * Searches and gets the channel number from the scan results and checks if
+ * concurrency is allowed for the given session ID
+ *
+ * Non zero channel number if concurrency is allowed, zero otherwise
+ */
+uint8_t policy_mgr_search_and_check_for_session_conc(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t session_id, void *roam_profile);
+
+/**
+ * policy_mgr_is_chnl_in_diff_band() - to check that given channel
+ * is in diff band from existing channel or not
+ * @psoc: pointer to psoc
+ * @channel: given channel
+ *
+ * This API will check that if the passed channel is in diff band than the
+ * already existing connections or not.
+ *
+ * Return: true if channel is in diff band
+ */
+bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
+					    uint8_t channel);
+
+/**
+ * policy_mgr_check_for_session_conc() - Check if concurrency is
+ * allowed for a session
+ * @psoc: PSOC object information
+ * @session_id: Session ID
+ * @channel: Channel number
+ *
+ * Checks if connection is allowed for a given session_id
+ *
+ * True if the concurrency is allowed, false otherwise
+ */
+bool policy_mgr_check_for_session_conc(
+	struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel);
+
+/**
+ * policy_mgr_handle_conc_multiport() - to handle multiport concurrency
+ * @session_id: Session ID
+ * @channel: Channel number
+ *
+ * This routine will handle STA side concurrency when policy manager
+ * is enabled.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_handle_conc_multiport(
+	struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel);
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
+ * concurrent change intf
+ * @psoc: PSOC object information
+ * @operation_channel: operation channel
+ * @vdev_id: vdev id of SAP
+ *
+ * Checks the concurrent change interface and restarts SAP
+ *
+ * Return: None
+ */
+void policy_mgr_check_concurrent_intf_and_restart_sap(
+		struct wlan_objmgr_psoc *psoc);
+#else
+static inline void policy_mgr_check_concurrent_intf_and_restart_sap(
+		struct wlan_objmgr_psoc *psoc)
+{
+
+}
+#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
+
+/**
+ * policy_mgr_is_mcc_in_24G() - Function to check for MCC in 2.4GHz
+ * @psoc: PSOC object information
+ *
+ * This function is used to check for MCC operation in 2.4GHz band.
+ * STA, P2P and SAP adapters are only considered.
+ *
+ * Return: True if mcc is detected in 2.4 Ghz, false otherwise
+ *
+ */
+bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @dev_mode: device mode
+ *
+ * Updates the beacon parameters of the GO in MCC scenario
+ *
+ * Return: Success or Failure depending on the overall function behavior
+ */
+QDF_STATUS policy_mgr_change_mcc_go_beacon_interval(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id, enum QDF_OPMODE dev_mode);
+
+#if defined(FEATURE_WLAN_MCC_TO_SCC_SWITCH)
+/**
+ * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ * @channel: Channel to change
+ * @ch_width: channel width to change
+ * @forced: Force to switch channel, ignore SCC/MCC check
+ *
+ * Invoke the callback function to change SAP channel using (E)CSA
+ *
+ * Return: None
+ */
+void policy_mgr_change_sap_channel_with_csa(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id, uint32_t channel,
+		uint32_t ch_width,
+		bool forced);
+#else
+static inline void policy_mgr_change_sap_channel_with_csa(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id, uint32_t channel,
+		uint32_t ch_width,
+		bool forced)
+{
+
+}
+#endif
+
+/**
+ * policy_mgr_set_pcl_for_existing_combo() - SET PCL for existing combo
+ * @psoc: PSOC object information
+ * @mode: Adapter mode
+ *
+ * Return: None
+ */
+void policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc *psoc,
+					   enum policy_mgr_con_mode mode);
+/**
+ * policy_mgr_incr_active_session() - increments the number of active sessions
+ * @psoc: PSOC object information
+ * @mode:	Adapter mode
+ * @session_id: session ID for the connection session
+ *
+ * This function increments the number of active sessions maintained per device
+ * mode. In the case of STA/P2P CLI/IBSS upon connection indication it is
+ * incremented; In the case of SAP/P2P GO upon bss start it is incremented
+ *
+ * Return: None
+ */
+void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc,
+		enum QDF_OPMODE mode, uint8_t session_id);
+
+/**
+ * policy_mgr_decr_active_session() - decrements the number of active sessions
+ * @psoc: PSOC object information
+ * @mode: Adapter mode
+ * @session_id: session ID for the connection session
+ *
+ * This function decrements the number of active sessions maintained per device
+ * mode. In the case of STA/P2P CLI/IBSS upon disconnection it is decremented
+ * In the case of SAP/P2P GO upon bss stop it is decremented
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc,
+		enum QDF_OPMODE mode, uint8_t session_id);
+
+/**
+ * policy_mgr_decr_session_set_pcl() - Decrement session count and set PCL
+ * @psoc: PSOC object information
+ * @mode: Adapter mode
+ * @session_id: Session id
+ *
+ * Decrements the active session count and sets the PCL if a STA connection
+ * exists
+ *
+ * Return: None
+ */
+void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc,
+		enum QDF_OPMODE mode, uint8_t session_id);
+
+/**
+ * policy_mgr_get_channel() - provide channel number of given mode and vdevid
+ * @psoc: PSOC object information
+ * @mode: given  mode
+ * @vdev_id: pointer to vdev_id
+ *
+ * This API will provide channel number of matching mode and vdevid.
+ * If vdev_id is NULL then it will match only mode
+ * If vdev_id is not NULL the it will match both mode and vdev_id
+ *
+ * Return: channel number
+ */
+uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode, uint32_t *vdev_id);
+
+/**
+ * policy_mgr_get_pcl() - provides the preferred channel list for
+ * new connection
+ * @psoc: PSOC object information
+ * @mode:	Device mode
+ * @pcl_channels: PCL channels
+ * @len: length of the PCL
+ * @pcl_weight: Weights of the PCL
+ * @weight_len: Max length of the weights list
+ *
+ * This function provides the preferred channel list on which
+ * policy manager wants the new connection to come up. Various
+ * connection decision making entities will using this function
+ * to query the PCL info
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode,
+		uint8_t *pcl_channels, uint32_t *len,
+		uint8_t *pcl_weight, uint32_t weight_len);
+
+/**
+ * policy_mgr_update_with_safe_channel_list() - provides the safe
+ * channel list
+ * @psoc: PSOC object information
+ * @pcl_channels: channel list
+ * @len: length of the list
+ * @weight_list: Weights of the PCL
+ * @weight_len: Max length of the weights list
+ *
+ * This function provides the safe channel list from the list
+ * provided after consulting the channel avoidance list
+ *
+ * Return: None
+ */
+void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc,
+		uint8_t *pcl_channels, uint32_t *len,
+		uint8_t *weight_list, uint32_t weight_len);
+
+/**
+ * policy_mgr_get_nondfs_preferred_channel() - to get non-dfs preferred channel
+ *                                           for given mode
+ * @psoc: PSOC object information
+ * @mode: mode for which preferred non-dfs channel is requested
+ * @for_existing_conn: flag to indicate if preferred channel is requested
+ *                     for existing connection
+ *
+ * this routine will return non-dfs channel
+ * 1) for getting non-dfs preferred channel, first we check if there are any
+ *    other connection exist whose channel is non-dfs. if yes then return that
+ *    channel so that we can accommodate upto 3 mode concurrency.
+ * 2) if there no any other connection present then query concurrency module
+ *    to give preferred channel list. once we get preferred channel list, loop
+ *    through list to find first non-dfs channel from ascending order.
+ *
+ * Return: uint8_t non-dfs channel
+ */
+uint8_t policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode, bool for_existing_conn);
+
+/**
+ * policy_mgr_is_any_nondfs_chnl_present() - Find any non-dfs
+ * channel from conc table
+ * @psoc: PSOC object information
+ * @channel: pointer to channel which needs to be filled
+ *
+ * In-case if any connection is already present whose channel is none dfs then
+ * return that channel
+ *
+ * Return: true up-on finding non-dfs channel else false
+ */
+bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc,
+		uint8_t *channel);
+
+/**
+ * policy_mgr_is_any_dfs_beaconing_session_present() - to find
+ * if any DFS session
+ * @psoc: PSOC object information
+ * @channel: pointer to channel number that needs to filled
+ *
+ * If any beaconing session such as SAP or GO present and it is on DFS channel
+ * then this function will return true
+ *
+ * Return: true if session is on DFS or false if session is on non-dfs channel
+ */
+bool policy_mgr_is_any_dfs_beaconing_session_present(
+		struct wlan_objmgr_psoc *psoc, uint8_t *channel);
+
+/**
+ * policy_mgr_allow_concurrency() - Check for allowed concurrency
+ * combination consulting the PCL
+ * @psoc: PSOC object information
+ * @mode:	new connection mode
+ * @channel: channel on which new connection is coming up
+ * @bw: Bandwidth requested by the connection (optional)
+ *
+ * When a new connection is about to come up check if current
+ * concurrency combination including the new connection is
+ * allowed or not based on the HW capability
+ *
+ * Return: True/False
+ */
+bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode,
+		uint8_t channel, enum hw_mode_bandwidth bw);
+
+/**
+ * policy_mgr_allow_concurrency_csa() - Check for allowed concurrency
+ * combination when channel switch
+ * @psoc:	PSOC object information
+ * @mode:	connection mode
+ * @channel:	target channel to switch
+ * @vdev_id:	vdev id of channel switch interface
+ *
+ * There is already existing SAP+GO combination but due to upper layer
+ * notifying LTE-COEX event or sending command to move one of the connections
+ * to different channel. In such cases before moving existing connection to new
+ * channel, check if new channel can co-exist with the other existing
+ * connection. For example, one SAP1 is on channel-6 and second SAP2 is on
+ * channel-36 and lets say they are doing DBS, and lets say upper layer sends
+ * LTE-COEX to move SAP1 from channel-6 to channel-149. In this case, SAP1 and
+ * SAP2 will end up doing MCC which may not be desirable result. such cases
+ * will be prevented with this API.
+ *
+ * Return: True/False
+ */
+bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
+				      enum policy_mgr_con_mode mode,
+				      uint8_t channel,
+				      uint32_t vdev_id);
+
+/**
+ * policy_mgr_get_first_connection_pcl_table_index() - provides the
+ * row index to firstConnectionPclTable to get to the correct
+ * pcl
+ * @psoc: PSOC object information
+ *
+ * This function provides the row index to
+ * firstConnectionPclTable. The index is the preference config.
+ *
+ * Return: table index
+ */
+enum policy_mgr_conc_priority_mode
+	policy_mgr_get_first_connection_pcl_table_index(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_second_connection_pcl_table_index() - provides the
+ * row index to secondConnectionPclTable to get to the correct
+ * pcl
+ * @psoc: PSOC object information
+ *
+ * This function provides the row index to
+ * secondConnectionPclTable. The index is derived based on
+ * current connection, band on which it is on & chain mask it is
+ * using, as obtained from pm_conc_connection_list.
+ *
+ * Return: table index
+ */
+enum policy_mgr_one_connection_mode
+	policy_mgr_get_second_connection_pcl_table_index(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_third_connection_pcl_table_index() - provides the
+ * row index to thirdConnectionPclTable to get to the correct
+ * pcl
+ * @psoc: PSOC object information
+ *
+ * This function provides the row index to
+ * thirdConnectionPclTable. The index is derived based on
+ * current connection, band on which it is on & chain mask it is
+ * using, as obtained from pm_conc_connection_list.
+ *
+ * Return: table index
+ */
+enum policy_mgr_two_connection_mode
+	policy_mgr_get_third_connection_pcl_table_index(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_incr_connection_count() - adds the new connection to
+ * the current connections list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ *
+ *
+ * This function adds the new connection to the current
+ * connections list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_incr_connection_count(struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id);
+
+/**
+ * policy_mgr_update_connection_info() - updates the existing
+ * connection in the current connections list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ *
+ *
+ * This function adds the new connection to the current
+ * connections list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id);
+
+/**
+ * policy_mgr_decr_connection_count() - remove the old connection
+ * from the current connections list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id of the old connection
+ *
+ *
+ * This function removes the old connection from the current
+ * connections list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id);
+
+/**
+ * policy_mgr_current_connections_update() - initiates actions
+ * needed on current connections once channel has been decided
+ * for the new connection
+ * @psoc: PSOC object information
+ * @session_id: Session id
+ * @channel: Channel on which new connection will be
+ * @reason: Reason for which connection update is required
+ *
+ * This function initiates initiates actions
+ * needed on current connections once channel has been decided
+ * for the new connection. Notifies UMAC & FW as well
+ *
+ * Return: QDF_STATUS enum
+ */
+QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
+		uint32_t session_id, uint8_t channel,
+		enum policy_mgr_conn_update_reason);
+
+/**
+ * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
+ * concurreny
+ * @new_conn_mode: new connection mode
+ *
+ * When a new connection is about to come up, check if dbs is allowed for
+ * STA+STA or STA+P2P
+ *
+ * Return: true if dbs is allowed for STA+STA or STA+P2P else false
+ */
+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
+ * @ibss_channel: pointer to ibss channel which needs to be filled
+ *
+ * this routine will check if IBSS connection already exist or no. If it
+ * exist then this routine will return true and fill the ibss_channel value.
+ *
+ * Return: true if ibss connection exist else false
+ */
+bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc,
+		uint8_t *ibss_channel);
+
+/**
+ * policy_mgr_get_conn_info() - get the current connections list
+ * @len: length of the list
+ *
+ * This function returns a pointer to the current connections
+ * list
+ *
+ * Return: pointer to connection list
+ */
+struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(
+		uint32_t *len);
+#ifdef MPC_UT_FRAMEWORK
+/**
+ * policy_mgr_incr_connection_count_utfw() - adds the new
+ * connection to the current connections list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @tx_streams: number of transmit spatial streams
+ * @rx_streams: number of receive spatial streams
+ * @chain_mask: chain mask
+ * @type: connection type
+ * @sub_type: connection subtype
+ * @channelid: channel number
+ * @mac_id: mac id
+ *
+ * This function adds the new connection to the current
+ * connections list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
+		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
+		uint32_t channelid, uint32_t mac_id);
+
+/**
+ * policy_mgr_update_connection_info_utfw() - updates the
+ * existing connection in the current connections list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @tx_streams: number of transmit spatial streams
+ * @rx_streams: number of receive spatial streams
+ * @chain_mask: chain mask
+ * @type: connection type
+ * @sub_type: connection subtype
+ * @channelid: channel number
+ * @mac_id: mac id
+ *
+ * This function updates the connection to the current
+ * connections list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_update_connection_info_utfw(struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
+		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
+		uint32_t channelid, uint32_t mac_id);
+
+/**
+ * policy_mgr_decr_connection_count_utfw() - remove the old
+ * connection from the current connections list
+ * @psoc: PSOC object information
+ * @del_all: delete all entries
+ * @vdev_id: vdev id
+ *
+ * This function removes the old connection from the current
+ * connections list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
+		uint32_t del_all, uint32_t vdev_id);
+
+/**
+ * policy_mgr_get_pcl_from_first_conn_table() - Get PCL for new
+ * connection from first connection table
+ * @type: Connection mode of type 'policy_mgr_con_mode'
+ * @sys_pref: System preference
+ *
+ * Get the PCL for a new connection
+ *
+ * Return: PCL channels enum
+ */
+enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table(
+		enum policy_mgr_con_mode type,
+		enum policy_mgr_conc_priority_mode sys_pref);
+
+/**
+ * policy_mgr_get_pcl_from_second_conn_table() - Get PCL for new
+ * connection from second connection table
+ * @idx: index into first connection table
+ * @type: Connection mode of type 'policy_mgr_con_mode'
+ * @sys_pref: System preference
+ * @dbs_capable: if HW DBS capable
+ *
+ * Get the PCL for a new connection
+ *
+ * Return: PCL channels enum
+ */
+enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table(
+	enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type,
+	enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable);
+
+/**
+ * policy_mgr_get_pcl_from_third_conn_table() - Get PCL for new
+ * connection from third connection table
+ * @idx: index into second connection table
+ * @type: Connection mode of type 'policy_mgr_con_mode'
+ * @sys_pref: System preference
+ * @dbs_capable: if HW DBS capable
+ *
+ * Get the PCL for a new connection
+ *
+ * Return: PCL channels enum
+ */
+enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table(
+	enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type,
+	enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable);
+#else
+static inline QDF_STATUS policy_mgr_incr_connection_count_utfw(
+		struct wlan_objmgr_psoc *psoc, uint32_t vdev_id,
+		uint32_t tx_streams, uint32_t rx_streams,
+		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
+		uint32_t channelid, uint32_t mac_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+static inline QDF_STATUS policy_mgr_update_connection_info_utfw(
+		struct wlan_objmgr_psoc *psoc, uint32_t vdev_id,
+		uint32_t tx_streams, uint32_t rx_streams,
+		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
+		uint32_t channelid, uint32_t mac_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+static inline QDF_STATUS policy_mgr_decr_connection_count_utfw(
+		struct wlan_objmgr_psoc *psoc, uint32_t del_all,
+		uint32_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * policy_mgr_convert_device_mode_to_qdf_type() - provides the
+ * type translation from HDD to policy manager type
+ * @device_mode: Generic connection mode type
+ *
+ *
+ * This function provides the type translation
+ *
+ * Return: policy_mgr_con_mode enum
+ */
+enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type(
+		enum QDF_OPMODE device_mode);
+
+/**
+ * policy_mgr_get_qdf_mode_from_pm - provides the
+ * type translation from policy manager type
+ * to generic connection mode type
+ * @device_mode: policy manager mode type
+ *
+ *
+ * This function provides the type translation
+ *
+ * Return: QDF_OPMODE enum
+ */
+enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm(
+			enum policy_mgr_con_mode device_mode);
+
+/**
+ * policy_mgr_check_n_start_opportunistic_timer - check single mac upgrade
+ * needed or not, if needed start the oppurtunistic timer.
+ * @psoc: pointer to SOC
+ *
+ * This function starts the oppurtunistic timer if hw_mode change is needed
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_check_n_start_opportunistic_timer(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_pdev_set_hw_mode() - Set HW mode command to FW
+ * @psoc: PSOC object information
+ * @session_id: Session ID
+ * @mac0_ss: MAC0 spatial stream configuration
+ * @mac0_bw: MAC0 bandwidth configuration
+ * @mac1_ss: MAC1 spatial stream configuration
+ * @mac1_bw: MAC1 bandwidth configuration
+ * @mac0_band_cap: mac0 band capability requirement
+ *     (0: Don't care, 1: 2.4G, 2: 5G)
+ * @dbs: HW DBS capability
+ * @dfs: HW Agile DFS capability
+ * @sbs: HW SBS capability
+ * @reason: Reason for connection update
+ * @next_action: next action to happen at policy mgr after
+ *		HW mode change
+ *
+ * Sends the set hw mode request to FW
+ *
+ * e.g.: To configure 2x2_80
+ *       mac0_ss = HW_MODE_SS_2x2, mac0_bw = HW_MODE_80_MHZ
+ *       mac1_ss = HW_MODE_SS_0x0, mac1_bw = HW_MODE_BW_NONE
+ *       mac0_band_cap = HW_MODE_MAC_BAND_NONE,
+ *       dbs = HW_MODE_DBS_NONE, dfs = HW_MODE_AGILE_DFS_NONE,
+ *       sbs = HW_MODE_SBS_NONE
+ * e.g.: To configure 1x1_80_1x1_40 (DBS)
+ *       mac0_ss = HW_MODE_SS_1x1, mac0_bw = HW_MODE_80_MHZ
+ *       mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ
+ *       mac0_band_cap = HW_MODE_MAC_BAND_NONE,
+ *       dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS_NONE,
+ *       sbs = HW_MODE_SBS_NONE
+ * e.g.: To configure 1x1_80_1x1_40 (Agile DFS)
+ *       mac0_ss = HW_MODE_SS_1x1, mac0_bw = HW_MODE_80_MHZ
+ *       mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ
+ *       mac0_band_cap = HW_MODE_MAC_BAND_NONE,
+ *       dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS,
+ *       sbs = HW_MODE_SBS_NONE
+ * e.g.: To configure 2x2_5g_80+1x1_2g_40
+ *       mac0_ss = HW_MODE_SS_2x2, mac0_bw = HW_MODE_80_MHZ
+ *       mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ
+ *       mac0_band_cap = HW_MODE_MAC_BAND_5G
+ *       dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS_NONE,
+ *       sbs = HW_MODE_SBS_NONE
+ * e.g.: To configure 2x2_2g_40+1x1_5g_40
+ *       mac0_ss = HW_MODE_SS_2x2, mac0_bw = HW_MODE_40_MHZ
+ *       mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ
+ *       mac0_band_cap = HW_MODE_MAC_BAND_2G
+ *       dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS_NONE,
+ *       sbs = HW_MODE_SBS_NONE
+ *
+ * Return: Success if the message made it down to the next layer
+ */
+QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
+		uint32_t session_id,
+		enum hw_mode_ss_config mac0_ss,
+		enum hw_mode_bandwidth mac0_bw,
+		enum hw_mode_ss_config mac1_ss,
+		enum hw_mode_bandwidth mac1_bw,
+		enum hw_mode_mac_band_cap mac0_band_cap,
+		enum hw_mode_dbs_capab dbs,
+		enum hw_mode_agile_dfs_capab dfs,
+		enum hw_mode_sbs_capab sbs,
+		enum policy_mgr_conn_update_reason reason,
+		uint8_t next_action);
+
+/**
+ * policy_mgr_pdev_set_hw_mode_cback() - callback invoked by
+ * other component to provide set HW mode request status
+ * @status: status of the request
+ * @cfgd_hw_mode_index: new HW mode index
+ * @num_vdev_mac_entries: Number of mac entries
+ * @vdev_mac_map: The table of vdev to mac mapping
+ * @next_action: next action to happen at policy mgr after
+ *		beacon update
+ * @reason: Reason for set HW mode
+ * @session_id: vdev id on which the request was made
+ * @context: PSOC object information
+ *
+ * This function is the callback registered with SME at set HW
+ * mode request time
+ *
+ * Return: None
+ */
+typedef void (*policy_mgr_pdev_set_hw_mode_cback)(uint32_t status,
+				uint32_t cfgd_hw_mode_index,
+				uint32_t num_vdev_mac_entries,
+				struct policy_mgr_vdev_mac_map *vdev_mac_map,
+				uint8_t next_action,
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t session_id, void *context);
+
+/**
+ * policy_mgr_nss_update_cback() - callback invoked by other
+ * component to provide nss update request status
+ * @psoc: PSOC object information
+ * @tx_status: tx completion status for updated beacon with new
+ *		nss value
+ * @vdev_id: vdev id for the specific connection
+ * @next_action: next action to happen at policy mgr after
+ *		beacon update
+ * @reason: Reason for nss update
+ * @original_vdev_id: original request hwmode change vdev id
+ *
+ * This function is the callback registered with SME at nss
+ * update request time
+ *
+ * Return: None
+ */
+typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc,
+		uint8_t tx_status,
+		uint8_t vdev_id,
+		uint8_t next_action,
+		enum policy_mgr_conn_update_reason reason,
+		uint32_t original_vdev_id);
+
+/**
+ * struct policy_mgr_sme_cbacks - SME Callbacks to be invoked
+ * from policy manager
+ * @sme_get_valid_channels: Get valid channel list
+ * @sme_get_nss_for_vdev: Get the allowed nss value for the vdev
+ * @sme_soc_set_dual_mac_config: Set the dual MAC scan & FW
+ *                             config
+ * @sme_pdev_set_hw_mode: Set the new HW mode to FW
+ * @sme_pdev_set_pcl: Set new PCL to FW
+ * @sme_nss_update_request: Update NSS value to FW
+ * @sme_change_mcc_beacon_interval: Set MCC beacon interval to FW
+ */
+struct policy_mgr_sme_cbacks {
+	QDF_STATUS (*sme_get_valid_channels)(uint8_t *chan_list,
+					     uint32_t *list_len);
+	void (*sme_get_nss_for_vdev)(enum QDF_OPMODE,
+				     uint8_t *nss_2g, uint8_t *nss_5g);
+	QDF_STATUS (*sme_soc_set_dual_mac_config)(
+		struct policy_mgr_dual_mac_config msg);
+	QDF_STATUS (*sme_pdev_set_hw_mode)(struct policy_mgr_hw_mode msg);
+	QDF_STATUS (*sme_pdev_set_pcl)(struct policy_mgr_pcl_list *msg);
+	QDF_STATUS (*sme_nss_update_request)(uint32_t vdev_id,
+		uint8_t new_nss, policy_mgr_nss_update_cback cback,
+		uint8_t next_action, struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_conn_update_reason reason,
+		uint32_t original_vdev_id);
+	QDF_STATUS (*sme_change_mcc_beacon_interval)(uint8_t session_id);
+	QDF_STATUS (*sme_get_ap_channel_from_scan)(
+		void *roam_profile,
+		void **scan_cache,
+		uint8_t *channel);
+	QDF_STATUS (*sme_scan_result_purge)(
+				void *scan_result);
+};
+
+/**
+ * struct policy_mgr_hdd_cbacks - HDD Callbacks to be invoked
+ * from policy manager
+ * @sap_restart_chan_switch_cb: Restart SAP
+ * @wlan_hdd_get_channel_for_sap_restart: Get channel to restart
+ *                      SAP
+ * @get_mode_for_non_connected_vdev: Get the mode for a non
+ *                                 connected vdev
+ * @hdd_get_device_mode: Get QDF_OPMODE type for session id (vdev id)
+ * @hdd_wapi_security_sta_exist: Get whether wapi encription station existing
+ * or not. Some hw doesn't support WAPI encryption concurrency with other
+ * encryption type.
+ */
+struct policy_mgr_hdd_cbacks {
+	void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id, uint32_t channel,
+				uint32_t channel_bw,
+				bool forced);
+	QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id, uint8_t *channel,
+				uint8_t *sec_ch);
+	enum policy_mgr_con_mode (*get_mode_for_non_connected_vdev)(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id);
+	enum QDF_OPMODE (*hdd_get_device_mode)(uint32_t session_id);
+	bool (*hdd_wapi_security_sta_exist)(void);
+};
+
+
+/**
+ * struct policy_mgr_tdls_cbacks - TDLS Callbacks to be invoked
+ * from policy manager
+ * @set_tdls_ct_mode: Set the tdls connection tracker mode
+ * @check_is_tdls_allowed: check if tdls allowed or not
+ */
+struct policy_mgr_tdls_cbacks {
+	void (*tdls_notify_increment_session)(struct wlan_objmgr_psoc *psoc);
+	void (*tdls_notify_decrement_session)(struct wlan_objmgr_psoc *psoc);
+};
+
+/**
+ * struct policy_mgr_cdp_cbacks - CDP Callbacks to be invoked
+ * from policy manager
+ * @cdp_update_mac_id: update mac_id for vdev
+ */
+struct policy_mgr_cdp_cbacks {
+	void (*cdp_update_mac_id)(struct wlan_objmgr_psoc *soc,
+		uint8_t vdev_id, uint8_t mac_id);
+};
+
+/**
+ * struct policy_mgr_dp_cbacks - CDP Callbacks to be invoked
+ * from policy manager
+ * @hdd_disable_rx_ol_in_concurrency: Callback to disable LRO/GRO offloads
+ * @hdd_set_rx_mode_rps_cb: Callback to set RPS
+ * @hdd_ipa_set_mcc_mode_cb: Callback to set mcc mode for ipa module
+ * @hdd_v2_flow_pool_map: Callback to create vdev flow pool
+ * @hdd_v2_flow_pool_unmap: Callback to delete vdev flow pool
+ */
+struct policy_mgr_dp_cbacks {
+	void (*hdd_disable_rx_ol_in_concurrency)(bool);
+	void (*hdd_set_rx_mode_rps_cb)(bool);
+	void (*hdd_ipa_set_mcc_mode_cb)(bool);
+	void (*hdd_v2_flow_pool_map)(int);
+	void (*hdd_v2_flow_pool_unmap)(int);
+};
+
+/**
+ * struct policy_mgr_wma_cbacks - WMA Callbacks to be invoked
+ * from policy manager
+ * @wma_get_connection_info: Get the connection related info
+ *                         from wma table
+ */
+struct policy_mgr_wma_cbacks {
+	QDF_STATUS (*wma_get_connection_info)(uint8_t vdev_id,
+		struct policy_mgr_vdev_entry_info *conn_table_entry);
+};
+
+/**
+* policy_mgr_need_opportunistic_upgrade - check whether needs to change current
+* HW mode to single mac 2x2 or the other DBS mode(for Dual DBS HW only).
+* @psoc: PSOC object information
+* @reason: enum policy_mgr_conn_update_reason
+*
+*  This function is to check whether needs to change to single Mac mode.
+*  when opportunistic timer fired.  But a special case for Dual DBS HW, this
+*  function will check DBS to DBS change is required or not:
+*  1. For Dual DBS HW, if user set vdev priority list, we may need to do
+*	 DBS to DBS switching.
+*	 eg. P2P GO (2g) < SAP (5G) < STA (2g) in DBS2.
+*	 If STA down, we need to switch to DBS1: P2P GO (2g) < SAP (5g).
+*	 So, for opportunistic checking, we need to add DBS ->DBS checking
+*            as well.
+*  2. Reason code :
+*	   DBS -> Single MAC : POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC
+*	   DBS -> DBS : POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE
+*
+*  return: PM_NOP, upgrade is not needed, otherwise new action type
+*             and reason code be returned.
+*/
+enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
+		struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_conn_update_reason *reason);
+
+/**
+ * policy_mgr_next_actions() - initiates actions needed on current
+ * connections once channel has been decided for the new
+ * connection
+ * @psoc: PSOC object information
+ * @session_id: Session id
+ * @action: action to be executed
+ * @reason: Reason for connection update
+ *
+ * This function initiates initiates actions
+ * needed on current connections once channel has been decided
+ * for the new connection. Notifies UMAC & FW as well
+ *
+ * Return: QDF_STATUS enum
+ */
+QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc,
+		uint32_t session_id,
+		enum policy_mgr_conc_next_action action,
+		enum policy_mgr_conn_update_reason reason);
+
+/**
+ * policy_mgr_set_dual_mac_scan_config() - Set the dual MAC scan config
+ * @psoc: PSOC object information
+ * @dbs_val: Value of DBS bit
+ * @dbs_plus_agile_scan_val: Value of DBS plus agile scan bit
+ * @single_mac_scan_with_dbs_val: Value of Single MAC scan with DBS
+ *
+ * Set the values of scan config. For FW mode config, the existing values
+ * will be retained
+ *
+ * Return: None
+ */
+void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc,
+		uint8_t dbs_val,
+		uint8_t dbs_plus_agile_scan_val,
+		uint8_t single_mac_scan_with_dbs_val);
+
+/**
+ * policy_mgr_set_dual_mac_fw_mode_config() - Set the dual mac FW mode config
+ * @psoc: PSOC object information
+ * @dbs: DBS bit
+ * @dfs: Agile DFS bit
+ *
+ * Set the values of fw mode config. For scan config, the existing values
+ * will be retain.
+ *
+ * Return: None
+ */
+void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc,
+		uint8_t dbs, uint8_t dfs);
+
+/**
+ * policy_mgr_soc_set_dual_mac_cfg_cb() - Callback for set dual mac config
+ * @status: Status of set dual mac config
+ * @scan_config: Current scan config whose status is the first param
+ * @fw_mode_config: Current FW mode config whose status is the first param
+ *
+ * Callback on setting the dual mac configuration
+ *
+ * Return: None
+ */
+void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status,
+		uint32_t scan_config, uint32_t fw_mode_config);
+
+/**
+ * policy_mgr_map_concurrency_mode() - to map concurrency mode
+ * between sme and hdd
+ * @old_mode: sme provided adapter mode
+ * @new_mode: hdd provided concurrency mode
+ *
+ * This routine will map concurrency mode between sme and hdd
+ *
+ * Return: true or false
+ */
+bool policy_mgr_map_concurrency_mode(enum QDF_OPMODE *old_mode,
+				     enum policy_mgr_con_mode *new_mode);
+
+/**
+ * policy_mgr_get_channel_from_scan_result() - to get channel from scan result
+ * @psoc: PSOC object information
+ * @roam_profile: pointer to roam profile
+ * @channel: channel to be filled
+ *
+ * This routine gets channel which most likely a candidate to which STA
+ * will make connection.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_channel_from_scan_result(
+		struct wlan_objmgr_psoc *psoc,
+		void *roam_profile, uint8_t *channel);
+
+/**
+ * policy_mgr_mode_specific_num_open_sessions() - to get number of open sessions
+ *                                                for a specific mode
+ * @psoc: PSOC object information
+ * @mode: device mode
+ * @num_sessions: to store num open sessions
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_mode_specific_num_open_sessions(
+		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode,
+		uint8_t *num_sessions);
+
+/**
+ * policy_mgr_mode_specific_num_active_sessions() - to get number of active
+ *               sessions for a specific mode
+ * @psoc: PSOC object information
+ * @mode: device mode
+ * @num_sessions: to store num active sessions
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_mode_specific_num_active_sessions(
+		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode,
+		uint8_t *num_sessions);
+
+/**
+ * policy_mgr_concurrent_open_sessions_running() - Checks for
+ * concurrent open session
+ * @psoc: PSOC object information
+ *
+ * Checks if more than one open session is running for all the allowed modes
+ * in the driver
+ *
+ * Return: True if more than one open session exists, False otherwise
+ */
+bool policy_mgr_concurrent_open_sessions_running(
+	struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_max_concurrent_connections_reached() - Check if
+ * max conccurrency is reached
+ * @psoc: PSOC object information
+ * Checks for presence of concurrency where more than one connection exists
+ *
+ * Return: True if the max concurrency is reached, False otherwise
+ *
+ * Example:
+ *    STA + STA (wlan0 and wlan1 are connected) - returns true
+ *    STA + STA (wlan0 connected and wlan1 disconnected) - returns false
+ *    DUT with P2P-GO + P2P-CLIENT connection) - returns true
+ *
+ */
+bool policy_mgr_max_concurrent_connections_reached(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_clear_concurrent_session_count() - Clear active session count
+ * @psoc: PSOC object information
+ * Clears the active session count for all modes
+ *
+ * Return: None
+ */
+void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_multiple_active_sta_sessions() - Check for
+ * multiple STA connections
+ * @psoc: PSOC object information
+ *
+ * Checks if multiple active STA connection are in the driver
+ *
+ * Return: True if multiple STA sessions are present, False otherwise
+ *
+ */
+bool policy_mgr_is_multiple_active_sta_sessions(
+	struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_sta_active_connection_exists() - Check if a STA
+ * connection is active
+ * @psoc: PSOC object information
+ *
+ * Checks if there is atleast one active STA connection in the driver
+ *
+ * Return: True if an active STA session is present, False otherwise
+ */
+bool policy_mgr_is_sta_active_connection_exists(
+	struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_concurrent_beaconing_sessions_running() - Checks
+ * for concurrent beaconing entities
+ * @psoc: PSOC object information
+ *
+ * Checks if multiple beaconing sessions are running i.e., if SAP or GO or IBSS
+ * are beaconing together
+ *
+ * Return: True if multiple entities are beaconing together, False otherwise
+ */
+bool policy_mgr_concurrent_beaconing_sessions_running(
+	struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_wait_for_connection_update() - Wait for hw mode
+ * command to get processed
+ * @psoc: PSOC object information
+ * Waits for CONNECTION_UPDATE_TIMEOUT duration until the set hw mode
+ * response sets the event connection_update_done_evt
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_wait_for_connection_update(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_reset_connection_update() - Reset connection
+ * update event
+ * @psoc: PSOC object information
+ * Resets the concurrent connection update event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_set_connection_update() - Set connection update
+ * event
+ * @psoc: PSOC object information
+ * Sets the concurrent connection update event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_set_chan_switch_complete_evt() - set channel
+ * switch completion event
+ * @psoc: PSOC object information
+ * Sets the channel switch completion event.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_reset_chan_switch_complete_evt() - reset channel
+ * switch completion event
+ * @psoc: PSOC object information
+ * Resets the channel switch completion event.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_set_opportunistic_update() - Set opportunistic
+ * update event
+ * @psoc: PSOC object information
+ * Sets the opportunistic update event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_stop_opportunistic_timer() - Stops opportunistic timer
+ * @psoc: PSOC object information
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_restart_opportunistic_timer() - Restarts opportunistic timer
+ * @psoc: PSOC object information
+ * @check_state: check timer state if this flag is set, else restart
+ *               irrespective of state
+ *
+ * Restarts opportunistic timer for DBS_OPPORTUNISTIC_TIME seconds.
+ * Check if current state is RUNNING if check_state is set, else
+ * restart the timer irrespective of state.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_restart_opportunistic_timer(
+		struct wlan_objmgr_psoc *psoc, bool check_state);
+
+/**
+ * policy_mgr_modify_sap_pcl_based_on_mandatory_channel() -
+ * Modify SAPs PCL based on mandatory channel list
+ * @psoc: PSOC object information
+ * @pcl_list_org: Pointer to the preferred channel list to be trimmed
+ * @weight_list_org: Pointer to the weights of the preferred channel list
+ * @pcl_len_org: Pointer to the length of the preferred chanel list
+ *
+ * Modifies the preferred channel list of SAP based on the mandatory channel
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel(
+		struct wlan_objmgr_psoc *psoc, uint8_t *pcl_list_org,
+		uint8_t *weight_list_org, uint32_t *pcl_len_org);
+
+/**
+ * policy_mgr_update_and_wait_for_connection_update() - Update and wait for
+ * connection update
+ * @psoc: PSOC object information
+ * @session_id: Session id
+ * @channel: Channel number
+ * @reason: Reason for connection update
+ *
+ * Update the connection to either single MAC or dual MAC and wait for the
+ * update to complete
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
+		struct wlan_objmgr_psoc *psoc, uint8_t session_id,
+		uint8_t channel, enum policy_mgr_conn_update_reason reason);
+
+/**
+ * policy_mgr_is_sap_mandatory_channel_set() - Checks if SAP
+ * mandatory channel is set
+ * @psoc: PSOC object information
+ * Checks if any mandatory channel is set for SAP operation
+ *
+ * Return: True if mandatory channel is set, false otherwise
+ */
+bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_list_has_24GHz_channel() - Check if list contains 2.4GHz channels
+ * @channel_list: Channel list
+ * @list_len: Length of the channel list
+ *
+ * Checks if the channel list contains atleast one 2.4GHz channel
+ *
+ * Return: True if 2.4GHz channel is present, false otherwise
+ */
+bool policy_mgr_list_has_24GHz_channel(uint8_t *channel_list,
+		uint32_t list_len);
+
+/**
+ * policy_mgr_get_valid_chans() - Get the valid channel list
+ * @psoc: PSOC object information
+ * @chan_list: Pointer to the valid channel list
+ * @list_len: Pointer to the length of the valid channel list
+ *
+ * Gets the valid channel list filtered by band
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc,
+		uint8_t *chan_list, uint32_t *list_len);
+
+/**
+ * policy_mgr_get_nss_for_vdev() - Get the allowed nss value for the
+ * vdev
+ * @psoc: PSOC object information
+ * @dev_mode: connection type.
+ * @nss2g: Pointer to the 2G Nss parameter.
+ * @nss5g: Pointer to the 5G Nss parameter.
+ *
+ * Fills the 2G and 5G Nss values based on connection type.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode,
+		uint8_t *nss_2g, uint8_t *nss_5g);
+
+/**
+ * policy_mgr_get_sap_mandatory_channel() - Get the mandatory channel for SAP
+ * @psoc: PSOC object information
+ * @chan: Pointer to the SAP mandatory channel
+ *
+ * Gets the mandatory channel for SAP operation
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
+		uint32_t *chan);
+
+/**
+ * policy_mgr_set_sap_mandatory_channels() - Set the mandatory channel for SAP
+ * @psoc: PSOC object information
+ * @channels: Channel list to be set
+ * @len: Length of the channel list
+ *
+ * Sets the channels for the mandatory channel list along with the length of
+ * of the channel list.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc,
+		uint8_t *channels, uint32_t len);
+
+/**
+ * policy_mgr_is_any_mode_active_on_band_along_with_session() -
+ * Check if any connection mode is active on a band along with
+ * the given session
+ * @psoc: PSOC object information
+ * @session_id: Session along which active sessions are looked for
+ * @band: Operating frequency band of the connection
+ * POLICY_MGR_BAND_24: Looks for active connection on 2.4 GHz only
+ * POLICY_MGR_BAND_5: Looks for active connection on 5 GHz only
+ *
+ * Checks if any of the connection mode is active on a given frequency band
+ *
+ * Return: True if any connection is active on a given band, false otherwise
+ */
+bool policy_mgr_is_any_mode_active_on_band_along_with_session(
+		struct wlan_objmgr_psoc *psoc, uint8_t session_id,
+		enum policy_mgr_band band);
+
+/**
+ * policy_mgr_get_chan_by_session_id() - Get channel for a given session ID
+ * @psoc: PSOC object information
+ * @session_id: Session ID
+ * @chan: Pointer to the channel
+ *
+ * Gets the channel for a given session ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc,
+		uint8_t session_id, uint8_t *chan);
+
+/**
+ * policy_mgr_get_mac_id_by_session_id() - Get MAC ID for a given session ID
+ * @psoc: PSOC object information
+ * @session_id: Session ID
+ * @mac_id: Pointer to the MAC ID
+ *
+ * Gets the MAC ID for a given session ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc,
+		uint8_t session_id, uint8_t *mac_id);
+
+/**
+ * policy_mgr_get_mcc_session_id_on_mac() - Get MCC session's ID
+ * @psoc: PSOC object information
+ * @mac_id: MAC ID on which MCC session needs to be found
+ * @session_id: Session with which MCC combination needs to be found
+ * @mcc_session_id: Pointer to the MCC session ID
+ *
+ * Get the session ID of the MCC interface
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc,
+		uint8_t mac_id, uint8_t session_id,
+		uint8_t *mcc_session_id);
+
+/**
+ * policy_mgr_get_mcc_operating_channel() - Get the MCC channel
+ * @psoc: PSOC object information
+ * @session_id: Session ID with which MCC is being done
+ *
+ * Gets the MCC channel for a given session ID.
+ *
+ * Return: '0' (INVALID_CHANNEL_ID) or valid channel number
+ */
+uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc,
+		uint8_t session_id);
+
+/**
+ * policy_mgr_get_pcl_for_existing_conn() - Get PCL for existing connection
+ * @psoc: PSOC object information
+ * @mode: Connection mode of type 'policy_mgr_con_mode'
+ * @pcl_ch: Pointer to the PCL
+ * @len: Pointer to the length of the PCL
+ * @pcl_weight: Pointer to the weights of the PCL
+ * @weight_len: Max length of the weights list
+ * @all_matching_cxn_to_del: Need remove all entries before getting pcl
+ *
+ * Get the PCL for an existing connection
+ *
+ * Return: None
+ */
+QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode,
+		uint8_t *pcl_ch, uint32_t *len,
+		uint8_t *weight_list, uint32_t weight_len,
+		bool all_matching_cxn_to_del);
+
+/**
+ * policy_mgr_get_valid_chan_weights() - Get the weightage for
+ * all valid channels
+ * @psoc: PSOC object information
+ * @weight: Pointer to the structure containing pcl, saved channel list and
+ * weighed channel list
+ *
+ * Provides the weightage for all valid channels. This compares the PCL list
+ * with the valid channel list. The channels present in the PCL get their
+ * corresponding weightage and the non-PCL channels get the default weightage
+ * of WEIGHT_OF_NON_PCL_CHANNELS.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_pcl_chan_weights *weight);
+
+/**
+ * policy_mgr_set_hw_mode_on_channel_switch() - Set hw mode
+ * after channel switch
+ * @session_id: Session ID
+ *
+ * Sets hw mode after doing a channel switch
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
+		struct wlan_objmgr_psoc *psoc, uint8_t session_id);
+
+/**
+ * policy_mgr_set_do_hw_mode_change_flag() - Set flag to indicate hw mode change
+ * @psoc: PSOC object information
+ * @flag: Indicate if hw mode change is required or not
+ *
+ * Set the flag to indicate whether a hw mode change is required after a
+ * vdev up or not. Flag value of true indicates that a hw mode change is
+ * required after vdev up.
+ *
+ * Return: None
+ */
+void policy_mgr_set_do_hw_mode_change_flag(struct wlan_objmgr_psoc *psoc,
+		bool flag);
+
+/**
+ * policy_mgr_is_hw_mode_change_after_vdev_up() - Check if hw
+ * mode change is needed
+ * @psoc: PSOC object information
+ * Returns the flag which indicates if a hw mode change is required after
+ * vdev up.
+ *
+ * Return: True if hw mode change is required, false otherwise
+ */
+bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_checkn_update_hw_mode_single_mac_mode() - Set hw_mode to SMM
+ * if required
+ * @psoc: PSOC object information
+ * @channel: channel number for the new STA connection
+ *
+ * After the STA disconnection, if the hw_mode is in DBS and the new STA
+ * connection is coming in the band in which existing connections are
+ * present, then this function stops the dbs opportunistic timer and sets
+ * the hw_mode to Single MAC mode (SMM).
+ *
+ * Return: None
+ */
+void policy_mgr_checkn_update_hw_mode_single_mac_mode(
+		struct wlan_objmgr_psoc *psoc, uint8_t channel);
+
+/**
+ * policy_mgr_dump_connection_status_info() - Dump the concurrency information
+ * @psoc: PSOC object information
+ * Prints the concurrency information such as tx/rx spatial stream, chainmask,
+ * etc.
+ *
+ * Return: None
+ */
+void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_mode_specific_vdev_id() - provides the
+ * vdev id of the pecific mode
+ * @psoc: PSOC object information
+ * @mode: type of connection
+ *
+ * This function provides vdev id for the given mode
+ *
+ * Return: vdev id
+ */
+uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc,
+					  enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_mode_specific_connection_count() - provides the
+ * count of connections of specific mode
+ * @psoc: PSOC object information
+ * @mode: type of connection
+ * @list: To provide the indices on pm_conc_connection_list
+ *	(optional)
+ *
+ * This function provides the count of current connections
+ *
+ * Return: connection count of specific type
+ */
+uint32_t policy_mgr_mode_specific_connection_count(
+		struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode,
+		uint32_t *list);
+
+/**
+ * policy_mgr_check_conn_with_mode_and_vdev_id() - checks if any active
+ * session with specific mode and vdev_id
+ * @psoc: PSOC object information
+ * @mode: type of connection
+ * @vdev_id: vdev_id of the connection
+ *
+ * This function checks if any active session with specific mode and vdev_id
+ * is present
+ *
+ * Return: QDF STATUS with success if active session is found, else failure
+ */
+QDF_STATUS policy_mgr_check_conn_with_mode_and_vdev_id(
+		struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode,
+		uint32_t vdev_id);
+
+/**
+ * policy_mgr_hw_mode_transition_cb() - Callback for HW mode
+ * transition from FW
+ * @old_hw_mode_index: Old HW mode index
+ * @new_hw_mode_index: New HW mode index
+ * @num_vdev_mac_entries: Number of vdev-mac id mapping that follows
+ * @vdev_mac_map: vdev-mac id map. This memory will be freed by the caller.
+ * So, make local copy if needed.
+ *
+ * Provides the old and new HW mode index set by the FW
+ *
+ * Return: None
+ */
+void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index,
+		uint32_t new_hw_mode_index,
+		uint32_t num_vdev_mac_entries,
+		struct policy_mgr_vdev_mac_map *vdev_mac_map,
+		struct wlan_objmgr_psoc *context);
+
+/**
+ * policy_mgr_current_concurrency_is_mcc() - To check the current
+ * concurrency combination if it is doing MCC
+ * @psoc: PSOC object information
+ * This routine is called to check if it is doing MCC
+ *
+ * Return: True - MCC, False - Otherwise
+ */
+bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_register_sme_cb() - register SME callbacks
+ * @psoc: PSOC object information
+ * @sme_cbacks: function pointers from SME
+ *
+ * API, allows SME to register callbacks to be invoked by policy
+ * mgr
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails)
+ */
+QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_sme_cbacks *sme_cbacks);
+
+/**
+ * policy_mgr_register_hdd_cb() - register HDD callbacks
+ * @psoc: PSOC object information
+ * @hdd_cbacks: function pointers from HDD
+ *
+ * API, allows HDD to register callbacks to be invoked by policy
+ * mgr
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails)
+ */
+QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_hdd_cbacks *hdd_cbacks);
+
+/**
+ * policy_mgr_deregister_hdd_cb() - Deregister HDD callbacks
+ * @psoc: PSOC object information
+ *
+ * API, allows HDD to deregister callbacks
+ *
+ * Return: SUCCESS,
+ *         Failure (if de-registration fails)
+ */
+QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_register_tdls_cb() - register TDLS callbacks
+ * @psoc: PSOC object information
+ * @tdls_cbacks: function pointers from TDLS
+ *
+ * API, allows TDLS to register callbacks to be invoked by
+ * policy mgr
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails)
+ */
+QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_tdls_cbacks *tdls_cbacks);
+
+/**
+ * policy_mgr_register_cdp_cb() - register CDP callbacks
+ * @psoc: PSOC object information
+ * @cdp_cbacks: function pointers from CDP
+ *
+ * API, allows CDP to register callbacks to be invoked by
+ * policy mgr
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails)
+ */
+QDF_STATUS policy_mgr_register_cdp_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_cdp_cbacks *cdp_cbacks);
+
+/**
+ * policy_mgr_register_dp_cb() - register CDP callbacks
+ * @psoc: PSOC object information
+ * @cdp_cbacks: function pointers from CDP
+ *
+ * API, allows CDP to register callbacks to be invoked by
+ * policy mgr
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails)
+ */
+QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_dp_cbacks *dp_cbacks);
+
+/**
+ * policy_mgr_register_wma_cb() - register WMA callbacks
+ * @psoc: PSOC object information
+ * @wma_cbacks: function pointers from WMA
+ *
+ * API, allows WMA to register callbacks to be invoked by policy
+ * mgr
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails)
+ */
+QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_wma_cbacks *wma_cbacks);
+
+/**
+ * policy_mgr_is_dbs_enable() - Check if master DBS control is enabled
+ * @psoc: PSOC object information
+ * Checks if the master DBS control is enabled. This will be used
+ * to override any other DBS capability
+ *
+ * Return: True if master DBS control is enabled
+ */
+bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_hw_dbs_capable() - Check if HW is DBS capable
+ * @psoc: PSOC object information
+ * Checks if the HW is DBS capable
+ *
+ * Return: true if the HW is DBS capable
+ */
+bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_hw_sbs_capable() - Check if HW is SBS capable
+ * @psoc: PSOC object information
+ * Checks if the HW is SBS capable
+ *
+ * Return: true if the HW is SBS capable
+ */
+bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_current_hwmode_dbs() - Check if current hw mode is DBS
+ * @psoc: PSOC object information
+ * Checks if current hardware mode of the system is DBS or no
+ *
+ * Return: true or false
+ */
+bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_hw_dbs_2x2_capable() - if hardware is capable of dbs 2x2
+ * @psoc: PSOC object information
+ * This function checks if hw_modes supported are always capable of
+ * DBS and there is no need for downgrading while entering DBS.
+ *    true: DBS 2x2 can always be supported
+ *    false: hw_modes support DBS 1x1 as well
+ * Genoa DBS 2x2 + 1x1 will not be included.
+ *
+ * Return: true - DBS2x2, false - DBS1x1
+ */
+bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * policy_mgr_is_2x2_1x1_dbs_capable() - check 2x2+1x1 DBS supported or not
+ * @psoc: PSOC object data
+ *
+ * This routine is called to check 2x2 5G + 1x1 2G (DBS1) or
+ * 2x2 2G + 1x1 5G (DBS2) support or not.
+ * Either DBS1 or DBS2 supported
+ *
+ * Return: true/false
+ */
+bool policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * policy_mgr_is_2x2_5G_1x1_2G_dbs_capable() - check Genoa DBS1 enabled or not
+ * @psoc: PSOC object data
+ *
+ * This routine is called to check support DBS1 or not.
+ * Notes: DBS1: 2x2 5G + 1x1 2G.
+ * This function will call policy_mgr_get_hw_mode_idx_from_dbs_hw_list to match
+ * the HW mode from hw mode list. The parameters will also be matched to
+ * 2x2 5G +2x2 2G HW mode. But firmware will not report 2x2 5G + 2x2 2G alone
+ * with 2x2 5G + 1x1 2G at same time. So, it is safe to find DBS1 with
+ * policy_mgr_get_hw_mode_idx_from_dbs_hw_list.
+ *
+ * Return: true/false
+ */
+bool policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * policy_mgr_is_2x2_2G_1x1_5G_dbs_capable() - check Genoa DBS2 enabled or not
+ * @psoc: PSOC object data
+ *
+ * This routine is called to check support DBS2 or not.
+ * Notes: DBS2: 2x2 2G + 1x1 5G
+ *
+ * Return: true/false
+ */
+bool policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_init() - Policy Manager component initialization
+ *                 routine
+ *
+ * Return - QDF Status
+ */
+QDF_STATUS policy_mgr_init(void);
+
+/**
+ * policy_mgr_deinit() - Policy Manager component
+ *                 de-initialization routine
+ *
+ * Return - QDF Status
+ */
+QDF_STATUS policy_mgr_deinit(void);
+
+/**
+ * policy_mgr_psoc_enable() - Policy Manager component
+ *                 enable routine
+ * @psoc: PSOC object information
+ *
+ * Return - QDF Status
+ */
+QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_psoc_disable() - Policy Manager component
+ *                 disable routine
+ * @psoc: PSOC object information
+ *
+ * Return - QDF Status
+ */
+QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_psoc_open() - Policy Manager component
+ *                 open routine
+ * @psoc: PSOC object information
+ *
+ * Return - QDF Status
+ */
+QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_psoc_close() - Policy Manager component
+ *                 close routine
+ * @psoc: PSOC object information
+ *
+ * Return - QDF Status
+ */
+QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_num_dbs_hw_modes() - Get number of HW mode
+ * @psoc: PSOC object information
+ * Fetches the number of DBS HW modes returned by the FW
+ *
+ * Return: Negative value on error or returns the number of DBS HW modes
+ */
+int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_dbs_hw_modes() - Get the DBS HW modes for userspace
+ * @psoc: PSOC object information
+ * @one_by_one_dbs: 1x1 DBS capability of HW
+ * @two_by_two_dbs: 2x2 DBS capability of HW
+ *
+ * Provides the DBS HW mode capability such as whether
+ * 1x1 DBS, 2x2 DBS is supported by the HW or not.
+ *
+ * Return: Failure in case of error and 0 on success
+ *         one_by_one_dbs/two_by_two_dbs will be false,
+ *         if they are not supported.
+ *         one_by_one_dbs/two_by_two_dbs will be true,
+ *         if they are supported.
+ *         false values of one_by_one_dbs/two_by_two_dbs,
+ *         indicate DBS is disabled
+ */
+QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc,
+		bool *one_by_one_dbs, bool *two_by_two_dbs);
+
+/**
+ * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case
+ * @data: Pointer to STA adapter
+ *
+ * Restarts the SAP interface in STA-AP concurrency scenario
+ *
+ * Restart: None
+ */
+void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data);
+
+/**
+ * policy_mgr_get_current_hw_mode() - Get current HW mode params
+ * @psoc: PSOC object information
+ * @hw_mode: HW mode parameters
+ *
+ * Provides the current HW mode parameters if the HW mode is initialized
+ * in the driver
+ *
+ * Return: Success if the current HW mode params are successfully populated
+ */
+QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_hw_mode_params *hw_mode);
+
+/**
+ * policy_mgr_get_dbs_plus_agile_scan_config() - Get DBS plus agile scan bit
+ * @psoc: PSOC object information
+ * Gets the DBS plus agile scan bit of concurrent_scan_config_bits
+ *
+ * Return: 0 or 1 to indicate the DBS plus agile scan bit
+ */
+bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_single_mac_scan_with_dfs_config() - Get Single
+ * MAC scan with DFS bit
+ * @psoc: PSOC object information
+ * Gets the Single MAC scan with DFS bit of concurrent_scan_config_bits
+ *
+ * Return: 0 or 1 to indicate the Single MAC scan with DFS bit
+ */
+bool policy_mgr_get_single_mac_scan_with_dfs_config(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_set_hw_mode_change_in_progress() - Set value
+ * corresponding to policy_mgr_hw_mode_change that indicate if
+ * HW mode change is in progress
+ * @psoc: PSOC object information
+ * @value: Indicate if hw mode change is in progress
+ *
+ * Set the value corresponding to policy_mgr_hw_mode_change that
+ * indicated if hw mode change is in progress.
+ *
+ * Return: None
+ */
+void policy_mgr_set_hw_mode_change_in_progress(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value);
+
+/**
+ * policy_mgr_is_hw_mode_change_in_progress() - Check if HW mode
+ * change is in progress.
+ * @psoc: PSOC object information
+ *
+ * Returns the corresponding policy_mgr_hw_mode_change value.
+ *
+ * Return: policy_mgr_hw_mode_change value.
+ */
+enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
+	struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_hw_mode_change_from_hw_mode_index() - Get
+ * matching HW mode from index
+ * @psoc: PSOC object information
+ * @hw_mode_index: HW mode index
+ * Returns the corresponding policy_mgr_hw_mode_change HW mode.
+ *
+ * Return: policy_mgr_hw_mode_change value.
+ */
+enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
+	struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index);
+
+/**
+ * policy_mgr_is_scan_simultaneous_capable() - Check if scan
+ * parallelization is supported or not
+ * @psoc: PSOC object information
+ * currently scan parallelization feature support is dependent on DBS but
+ * it can be independent in future.
+ *
+ * Return: True if master DBS control is enabled
+ */
+bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_set_user_cfg() - Function to set user cfg variables
+ * required by policy manager component
+ * @psoc: PSOC object information
+ * @user_cfg: User config valiables structure pointer
+ *
+ * This function sets the user cfg variables required by policy
+ * manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc,
+				struct policy_mgr_user_cfg *user_cfg);
+
+/**
+ * policy_mgr_init_dbs_config() - Function to initialize DBS
+ * config in policy manager component
+ * @psoc: PSOC object information
+ * @scan_config: DBS scan config
+ * @fw_config: DBS FW config
+ *
+ * This function sets the DBS configurations required by policy
+ * manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc,
+		uint32_t scan_config, uint32_t fw_config);
+
+/**
+ * policy_mgr_update_dbs_scan_config() - Function to update
+ * DBS scan config in policy manager component
+ * @psoc: PSOC object information
+ *
+ * This function updates the DBS scan configurations required by
+ * policy manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_update_dbs_scan_config(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_update_dbs_fw_config() - Function to update DBS FW
+ * config in policy manager component
+ * @psoc: PSOC object information
+ *
+ * This function updates the DBS FW configurations required by
+ * policy manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_update_dbs_fw_config(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_update_dbs_req_config() - Function to update DBS
+ * request config in policy manager component
+ * @psoc: PSOC object information
+ * @scan_config: DBS scan config
+ * @fw_config: DBS FW config
+ *
+ * This function updates DBS request configurations required by
+ * policy manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_update_dbs_req_config(struct wlan_objmgr_psoc *psoc,
+		uint32_t scan_config, uint32_t fw_mode_config);
+
+/**
+ * policy_mgr_dump_dbs_hw_mode() - Function to dump DBS config
+ * @psoc: PSOC object information
+ *
+ * This function dumps the DBS configurations
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_init_dbs_hw_mode() - Function to initialize DBS HW
+ * modes in policy manager component
+ * @psoc: PSOC object information
+ * @num_dbs_hw_modes: Number of HW modes
+ * @ev_wlan_dbs_hw_mode_list: HW list
+ *
+ * This function to initialize the DBS HW modes in policy
+ * manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc,
+				uint32_t num_dbs_hw_modes,
+				uint32_t *ev_wlan_dbs_hw_mode_list);
+
+/**
+ * policy_mgr_update_hw_mode_list() - Function to initialize DBS
+ * HW modes in policy manager component
+ * @psoc: PSOC object information
+ * @tgt_hdl: Target psoc information
+ *
+ * This function to initialize the DBS HW modes in policy
+ * manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc,
+					  struct target_psoc_info *tgt_hdl);
+
+/**
+ * policy_mgr_update_hw_mode_index() - Function to update
+ * current HW mode in policy manager component
+ * @psoc: PSOC object information
+ * @new_hw_mode_index: index to new HW mode
+ *
+ * This function to update the current HW mode in policy manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_update_hw_mode_index(struct wlan_objmgr_psoc *psoc,
+		uint32_t new_hw_mode_index);
+
+/**
+ * policy_mgr_update_old_hw_mode_index() - Function to update
+ * old HW mode in policy manager component
+ * @psoc: PSOC object information
+ * @new_hw_mode_index: index to old HW mode
+ *
+ * This function to update the old HW mode in policy manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc *psoc,
+		uint32_t old_hw_mode_index);
+
+/**
+ * policy_mgr_update_new_hw_mode_index() - Function to update
+ * new HW mode in policy manager component
+ * @psoc: PSOC object information
+ * @new_hw_mode_index: index to new HW mode
+ *
+ * This function to update the new HW mode in policy manager
+ *
+ * Return: SUCCESS or FAILURE
+ *
+ */
+void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc,
+		uint32_t new_hw_mode_index);
+
+/**
+ * policy_mgr_is_chan_ok_for_dnbs() - Function to check if a channel
+ * is OK for "Do Not Break Stream"
+ * @psoc: PSOC object information
+ * @channel: Channel to check.
+ * @ok: Pointer to flag in which status will be stored
+ * This function checks if a channel is OK for
+ * "Do Not Break Stream"
+ * Return: SUCCESS or FAILURE
+ */
+QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc,
+			uint8_t channel, bool *ok);
+
+/**
+ * policy_mgr_get_hw_dbs_nss() - Computes DBS NSS
+ * @psoc: PSOC object information
+ * @nss_dbs: NSS info of both MAC0 and MAC1
+ * This function computes NSS info of both MAC0 and MAC1
+ *
+ * Return: uint32_t value signifies supported RF chains
+ */
+uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc,
+				   struct dbs_nss *nss_dbs);
+
+/**
+ * policy_mgr_is_dnsc_set - Check if user has set
+ * "Do_Not_Switch_Channel" for the vdev passed
+ * @vdev: vdev pointer
+ *
+ * Get "Do_Not_Switch_Channel" setting for the vdev passed.
+ *
+ * Return: true for success, else false
+ */
+bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * policy_mgr_get_updated_scan_and_fw_mode_config() - Function
+ * to get latest scan & fw config for DBS
+ * @psoc: PSOC object information
+ * @scan_config: DBS related scan config
+ * @fw_mode_config: DBS related FW config
+ * @dual_mac_disable_ini: DBS related ini config
+ * This function returns the latest DBS configuration for
+ * connection & scan, sent to FW
+ * Return: SUCCESS or FAILURE
+ */
+QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config(
+		struct wlan_objmgr_psoc *psoc, uint32_t *scan_config,
+		uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini,
+		uint32_t channel_select_logic_conc);
+
+/**
+ * policy_mgr_is_safe_channel - Check if the channel is in LTE
+ * coex channel avoidance list
+ * @psoc: PSOC object information
+ * @channel: channel to be checked
+ *
+ * Check if the channel is in LTE coex channel avoidance list.
+ *
+ * Return: true for success, else false
+ */
+bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
+		uint8_t channel);
+
+/**
+ * policy_mgr_is_force_scc() - checks if SCC needs to be
+ * mandated
+ * @psoc: PSOC object information
+ *
+ * This function checks if SCC needs to be mandated or not
+ *
+ * Return: True if SCC to be mandated, false otherwise
+ */
+bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_valid_sap_conc_channel_check() - checks & updates
+ * the channel SAP to come up on in case of STA+SAP concurrency
+ * @psoc: PSOC object information
+ * @con_ch: pointer to the channel on which sap will come up
+ * @sap_ch: initial channel for SAP
+ *
+ * This function checks & updates the channel SAP to come up on in
+ * case of STA+SAP concurrency
+ * Return: Success if SAP can come up on a channel
+ */
+QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
+	struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch);
+
+/**
+ * policy_mgr_get_alternate_channel_for_sap() - Get an alternate
+ * channel to move the SAP to
+ * @psoc: PSOC object information
+ *
+ * This function returns an alternate channel for SAP to move to
+ * Return: The new channel for SAP
+ */
+uint8_t policy_mgr_get_alternate_channel_for_sap(
+	struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_disallow_mcc() - Check for mcc
+ *
+ * @psoc: PSOC object information
+ * @channel: channel on which new connection is coming up
+ *
+ * When a new connection is about to come up check if current
+ * concurrency combination including the new connection is
+ * causing MCC
+ *
+ * Return: True if it is causing MCC
+ */
+bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc,
+		uint8_t channel);
+
+/**
+ * policy_mgr_mode_specific_get_channel() - Get channel for a
+ * connection type
+ * @psoc: PSOC object information
+ * @chan_list: Connection type
+ *
+ * Get channel for a connection type
+ *
+ * Return: channel number
+ */
+uint8_t policy_mgr_mode_specific_get_channel(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_enable_disable_sap_mandatory_chan_list() - Update the value of
+ * enable_sap_mandatory_chan_list
+ * @psoc: Pointer to soc
+ * @val: value of enable_sap_mandatory_chan_list
+ *
+ * Update the value of enable_sap_mandatory_chan_list
+ *
+ * Return: void
+ */
+void policy_mgr_enable_disable_sap_mandatory_chan_list(
+		struct wlan_objmgr_psoc *psoc, bool val);
+
+/**
+ * policy_mgr_add_sap_mandatory_chan() - Add chan to SAP mandatory channel
+ * list
+ * @psoc: Pointer to soc
+ * @chan: Channel to be added
+ *
+ * Add chan to SAP mandatory channel list
+ *
+ * Return: None
+ */
+void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+		uint8_t chan);
+
+/**
+ * policy_mgr_is_sap_mandatory_chan_list_enabled() - Return the SAP mandatory
+ * channel list enabled status
+ * @psoc: Pointer to soc
+ *
+ * Get the SAP mandatory channel list enabled status
+ *
+ * Return: Enable or Disable
+ */
+bool policy_mgr_is_sap_mandatory_chan_list_enabled(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_sap_mandatory_chan_list_len() - Return the SAP mandatory
+ * channel list len
+ * @psoc: Pointer to soc
+ *
+ * Get the SAP mandatory channel list len
+ *
+ * Return: Channel list length
+ */
+uint32_t policy_mgr_get_sap_mandatory_chan_list_len(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_init_sap_mandatory_2g_chan() - Init 2.4G SAP mandatory channel
+ * list
+ * @psoc: Pointer to soc
+ *
+ * Initialize the 2.4G SAP mandatory channels
+ *
+ * Return: None
+ */
+void  policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_remove_sap_mandatory_chan() - Remove channel from SAP mandatory
+ * channel list
+ * @psoc: Pointer to soc
+ * @chan: channel to be removed from mandatory channel list
+ *
+ * Remove channel from SAP mandatory channel list
+ *
+ * Return: None
+ */
+void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+		uint8_t chan);
+/*
+ * policy_set_cur_conc_system_pref - set current conc_system_pref
+ * @psoc: soc pointer
+ *
+ * Set the current concurrency system preference.
+ *
+ * Return: None
+ */
+void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc,
+		uint8_t conc_system_pref);
+/**
+ * policy_mgr_get_cur_conc_system_pref - Get current conc_system_pref
+ * @psoc: soc pointer
+ *
+ * Get the current concurrent system preference.
+ *
+ * Return: conc_system_pref
+ */
+uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc);
+/**
+ * policy_mgr_check_and_stop_opportunistic_timer - Get current
+ * state of opportunistic timer, if running, stop it and take
+ * action
+ * @psoc: soc pointer
+ * @id: Session/vdev id
+ *
+ * Get the current state of opportunistic timer, if it is
+ * running, stop it and take action.
+ *
+ * Return: None
+ */
+void policy_mgr_check_and_stop_opportunistic_timer(
+	struct wlan_objmgr_psoc *psoc, uint8_t id);
+
+/**
+ * policy_mgr_set_weight_of_dfs_passive_channels_to_zero() - set weight of dfs
+ * and passive channels to 0
+ * @psoc: pointer to soc
+ * @pcl_channels: preferred channel list
+ * @len: length of preferred channel list
+ * @weight_list: preferred channel weight list
+ * @weight_len: length of weight list
+ * This function set the weight of dfs and passive channels to 0
+ *
+ * Return: None
+ */
+void policy_mgr_set_weight_of_dfs_passive_channels_to_zero(
+		struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels,
+		uint32_t *len, uint8_t *weight_list, uint32_t weight_len);
+
+/**
+ * policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc
+ * allowed on dfs chan
+ * @psoc: pointer to soc
+ * This function is used to check if sta+sap scc allowed on dfs channel
+ *
+ * Return: true if sta+sap scc is allowed on dfs channel, otherwise false
+ */
+bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
+		struct wlan_objmgr_psoc *psoc);
+/**
+ * policy_mgr_is_sta_connected_2g() - check if sta connected in 2g
+ * @psoc: pointer to soc
+ *
+ * Return: true if sta is connected in 2g else false
+ */
+bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_trim_acs_channel_list() - Trim the ACS channel list based
+ * on the number of active station connections
+ * @org_ch_list: ACS channel list from user space
+ * @org_ch_list_count: ACS channel count from user space
+ *
+ * Return: None
+ */
+void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc,
+		uint8_t *org_ch_list, uint8_t *org_ch_list_count);
+
+/**
+ * policy_mgr_is_hwmode_set_for_given_chnl() - to check for given channel
+ * if the hw mode is properly set.
+ * @psoc: pointer to psoc
+ * @channel: given channel
+ *
+ * If HW mode is properly set for given channel then it returns true else
+ * it returns false.
+ * For example, when 2x2 DBS is supported and if the first connection is
+ * coming up on 2G band then driver expects DBS HW mode to be set first
+ * before the connection can be established. Driver can call this API to
+ * find-out if HW mode is set properly.
+ *
+ * Return: true if HW mode is set properly else false
+ */
+bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
+					     uint8_t channel);
+/*
+ * policy_mgr_get_connection_info() - Get info of all active connections
+ * @info: Pointer to connection info
+ *
+ * Return: Connection count
+ */
+uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc,
+					struct connection_info *info);
+/**
+ * policy_mgr_register_mode_change_cb() - Register mode change callback with
+ * policy manager
+ * @callback: HDD callback to be registered
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc,
+			send_mode_change_event_cb mode_change_cb);
+/**
+ * policy_mgr_deregister_mode_change_cb() - Deregister mode change callback with
+ * policy manager
+ * @callback: HDD callback to be registered
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_allow_sap_go_concurrency() - check whether SAP/GO concurrency is
+ * allowed.
+ * @psoc: pointer to soc
+ * @policy_mgr_con_mode: operating mode of interface to be checked
+ * @channel: new operating channel of the interface to be checked
+ * @vdev_id: vdev id of the connection to be checked, 0xff for new connection
+ *
+ * Checks whether new channel SAP/GO can co-exist with the channel of existing
+ * SAP/GO connection. This API mainly used for two purposes:
+ *
+ * 1) When new GO/SAP session is coming up and needs to check if this session's
+ * channel can co-exist with existing existing GO/SAP sessions. For example,
+ * when single radio platform comes, MCC for SAP/GO+SAP/GO is not supported, in
+ * such case this API should prevent bringing the second connection.
+ *
+ * 2) There is already existing SAP+GO combination but due to upper layer
+ * notifying LTE-COEX event or sending command to move one of the connections
+ * to different channel. In such cases before moving existing connection to new
+ * channel, check if new channel can co-exist with the other existing
+ * connection. For example, one SAP1 is on channel-6 and second SAP2 is on
+ * channel-36 and lets say they are doing DBS, and lets say upper layer sends
+ * LTE-COEX to move SAP1 from channel-6 to channel-149. In this case, SAP1 and
+ * SAP2 will end up doing MCC which may not be desirable result. such cases
+ * will be prevented with this API.
+ *
+ * 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,
+					 uint32_t vdev_id);
+
+/**
+ * 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);
+
+/**
+ * policy_mgr_sta_sap_scc_on_lte_coex_chan() - get capability that
+ * whether support sta sap scc on lte coex chan
+ * @psoc: pointer to soc
+ *
+ *  Return: bool: capable
+ */
+bool policy_mgr_sta_sap_scc_on_lte_coex_chan(
+	struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_valid_channel_for_channel_switch() - check for valid channel for
+ * channel switch.
+ * @psoc: poniter to psoc
+ * @channel: channel to be validated.
+ * This function validates whether the given channel is valid for channel
+ * switch.
+ *
+ * Return: true or false
+ */
+bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc,
+					    uint8_t channel);
+
+/**
+ * policy_mgr_update_user_config_sap_chan() - Update user configured channel
+ * @psoc: poniter to psoc
+ * @channel: channel to be upated
+ *
+ * Return: void
+ **/
+void policy_mgr_update_user_config_sap_chan(
+			struct wlan_objmgr_psoc *psoc, uint32_t channel);
+
+/**
+ * policy_mgr_is_sap_restart_required_after_sta_disconnect() - is sap restart
+ * required
+ * after sta disconnection
+ * @psoc: psoc object data
+ * @intf_ch: sap channel
+ *
+ * Check if SAP should be moved to a non dfs channel after STA disconnection.
+ * This API applicable only for STA+SAP SCC and ini 'sta_sap_scc_on_dfs_chan'
+ * or 'sta_sap_scc_on_lte_coex_chan' is enabled.
+ *
+ * Return: true if sap restart is required, otherwise false
+ */
+bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
+			struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch);
+
+/**
+ * policy_mgr_is_sta_sap_scc() - check whether SAP is doing SCC with
+ * STA
+ * @psoc: poniter to psoc
+ * @sap_ch: operating channel of SAP interface
+ * This function checks whether SAP is doing SCC with STA
+ *
+ * Return: true or false
+ */
+bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch);
+
+/**
+ * policy_mgr_get_hw_mode_from_idx() - Get HW mode based on index
+ * @psoc: psoc object
+ * @idx: HW mode id
+ * @hw_mode: HW mode params
+ *
+ * Fetches the HW mode parameters
+ *
+ * Return: Success if hw mode is obtained and the hw mode params
+ */
+QDF_STATUS policy_mgr_get_hw_mode_from_idx(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t idx,
+		struct policy_mgr_hw_mode_params *hw_mode);
+#endif /* __WLAN_POLICY_MGR_API_H */

+ 302 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h

@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __CFG_POLICY_MGR
+#define __CFG_POLICY_MGR
+#include "qdf_types.h"
+
+/*
+ * <ini>
+ * gWlanMccToSccSwitchMode - Control SAP channel.
+ * @Min: 0
+ * @Max: 5
+ * @Default: 0
+ *
+ * This ini is used to override SAP channel.
+ * If gWlanMccToSccSwitchMode = 0: disabled.
+ * If gWlanMccToSccSwitchMode = 1: Enable switch.
+ * If gWlainMccToSccSwitchMode = 2: Force switch with SAP restart.
+ * If gWlainMccToSccSwitchMode = 3: Force switch without SAP restart.
+ * If gWlainMccToSccSwitchMode = 4: Switch using
+ * 					fav channel(s)without SAP restart.
+ * If gWlainMccToSccSwitchMode = 5: Force switch without SAP restart.MCC allowed
+ *					in exceptional cases.
+ * If gWlainMccToSccSwitchMode = 6: Force Switch without SAP restart only in
+					user preffered band.
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_MCC_TO_SCC_SWITCH CFG_INI_UINT(\
+					"gWlanMccToSccSwitchMode", \
+					QDF_MCC_TO_SCC_SWITCH_DISABLE, \
+					QDF_MCC_TO_SCC_SWITCH_MAX - 1, \
+					QDF_MCC_TO_SCC_SWITCH_DISABLE, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Provides MCC to SCC switch mode")
+/*
+ * <ini>
+ * gSystemPref - Configure wlan system preference for PCL.
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is used to configure wlan system preference option to help
+ * policy manager decide on Preferred Channel List for a new connection.
+ * For possible values refer to enum hdd_conc_priority_mode
+ *
+ * Related: None.
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_CONC_SYS_PREF CFG_INI_UINT(\
+					"gSystemPref", 0, 2, 0, \
+					CFG_VALUE_OR_DEFAULT, \
+					"System preference to predict PCL")
+/*
+ * <ini>
+ * gMaxConcurrentActiveSessions - Maximum number of concurrent connections.
+ * @Min: 1
+ * @Max: 4
+ * @Default: 3
+ *
+ * This ini is used to configure the maximum number of concurrent connections.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_MAX_CONC_CXNS CFG_INI_UINT(\
+					"gMaxConcurrentActiveSessions", \
+					1, 4, 3, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Config max num allowed connections")
+/*
+ * <ini>
+ * channel_select_logic_conc - Set channel selection logic
+ * for different concurrency combinations to DBS or inter band
+ * MCC. Default is DBS for STA+STA and STA+P2P.
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * 0 - inter-band MCC
+ * 1 - DBS
+ *
+ * BIT 0: STA+STA
+ * BIT 1: STA+P2P
+ * BIT 2-31: Reserved
+ *
+ * Supported Feature: STA+STA, STA+P2P
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_CHNL_SELECT_LOGIC_CONC CFG_INI_UINT(\
+						"channel_select_logic_conc",\
+						0x00000000, \
+						0xFFFFFFFF, \
+						0x00000003, \
+						CFG_VALUE_OR_DEFAULT, \
+						"Set channel selection policy for various concurrency")
+/*
+ * <ini>
+ * dbs_selection_policy - Configure dbs selection policy.
+ * @Min: 0
+ * @Max: 3
+ * @Default: 0
+ *
+ *  set 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. The INI "vdev_priority_list" will
+ * specify the vdev priority.
+ *      bit[1] = 0: vdev priority disabled.
+ * This INI only take effect for Genoa dual DBS hw.
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_DBS_SELECTION_PLCY CFG_INI_UINT(\
+					    "dbs_selection_policy", \
+					    0, 3, 0, \
+					    CFG_VALUE_OR_DEFAULT, \
+					    "Configure dbs selection policy")
+/*
+ * <ini>
+ * vdev_priority_list - Configure vdev priority list.
+ * @Min: 0
+ * @Max: 0x4444
+ * @Default: 0x4321
+ *
+ * @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
+ *      vdev priority id mapping:
+ *        PM_STA_PRI_ID = 1,
+ *        PM_SAP_PRI_ID = 2,
+ *        PM_P2P_GO_PRI_ID = 3,
+ *        PM_P2P_CLI_PRI_ID = 4,
+ * When the previous INI "dbs_selection_policy" bit[1]=1, which means
+ * the vdev 2x2 prioritization enabled. Then this INI will be used to
+ * specify the vdev type priority list. For example :
+ * dbs_selection_policy=0x2
+ * vdev_priority_list=0x4312
+ * means: default preference 2x2 band is 5G, vdev 2x2 prioritization enabled.
+ * And the priority list is CLI < GO < STA < SAP
+ *
+ * This INI only take effect for Genoa dual DBS hw.
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_VDEV_CUSTOM_PRIORITY_LIST CFG_INI_UINT(\
+					"vdev_priority_list", \
+					0, 0x4444, 0x4321, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Configure vdev priority list")
+/*
+ * <ini>
+ * gEnableCustomConcRule1 - Enable custom concurrency rule1.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable custom concurrency rule1.
+ * If SAP comes up first and STA comes up later then SAP needs to follow STA's
+ * channel.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_CONC_RULE1 CFG_INI_UINT(\
+					"gEnableCustomConcRule1", \
+					0, 1, 0, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Enable custom concurrency rule 1")
+/*
+ * <ini>
+ * gEnableCustomConcRule2 - Enable custom concurrency rule2.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable custom concurrency rule2.
+ * If P2PGO comes up first and STA comes up later then P2PGO need to follow
+ * STA's channel in 5Ghz. In following if condition we are just adding sanity
+ * check to make sure that by this time P2PGO's channel is same as STA's
+ * channel.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_CONC_RULE2 CFG_INI_UINT(\
+					"gEnableCustomConcRule2", \
+					0, 1, 0, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Enable custom concurrency rule 2")
+/*
+ * <ini>
+ * gEnableMCCAdaptiveScheduler - MCC Adaptive Scheduler feature.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable MCC Adaptive Scheduler feature.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME CFG_INI_UINT(\
+					"gEnableMCCAdaptiveScheduler", \
+					0, 1, 1, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Enable/Disable MCC Adaptive Scheduler")
+
+/*
+ * <ini>
+ * gEnableStaConnectionIn5Ghz - To enable/disable STA connection in 5G
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable STA connection in 5G band
+ *
+ * Related: STA
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_STA_CONNECTION_IN_5GHZ CFG_INI_UINT(\
+					"gEnableStaConnectionIn5Ghz", \
+					0, 1, 1, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Enable/Disable STA connection in 5G")
+
+#define CFG_POLICY_MGR_ALL \
+		CFG(CFG_MCC_TO_SCC_SWITCH) \
+		CFG(CFG_CONC_SYS_PREF) \
+		CFG(CFG_MAX_CONC_CXNS) \
+		CFG(CFG_DBS_SELECTION_PLCY) \
+		CFG(CFG_VDEV_CUSTOM_PRIORITY_LIST) \
+		CFG(CFG_CHNL_SELECT_LOGIC_CONC) \
+		CFG(CFG_ENABLE_CONC_RULE1) \
+		CFG(CFG_ENABLE_CONC_RULE2) \
+		CFG(CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME)\
+		CFG(CFG_ENABLE_STA_CONNECTION_IN_5GHZ)
+#endif

+ 1091 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h

@@ -0,0 +1,1091 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WLAN_POLICY_MGR_PUBLIC_STRUCT_H
+#define __WLAN_POLICY_MGR_PUBLIC_STRUCT_H
+
+/**
+ * DOC: wlan_policy_mgr_public_struct.h
+ *
+ * Concurrenct Connection Management entity
+ */
+
+/* Include files */
+#include <wmi_unified_api.h>
+
+#define POLICY_MGR_MAX_CHANNEL_LIST 128
+
+/**
+ *  Some max value greater than the max length of the channel list
+ */
+#define MAX_WEIGHT_OF_PCL_CHANNELS 255
+/**
+ *  Some fixed weight difference between the groups
+ */
+#define PCL_GROUPS_WEIGHT_DIFFERENCE 20
+
+/**
+ * Currently max, only 3 groups are possible as per 'enum policy_mgr_pcl_type'.
+ * i.e., in a PCL only 3 groups of channels can be present
+ * e.g., SCC channel on 2.4 Ghz, SCC channel on 5 Ghz & 5 Ghz channels.
+ * Group 1 has highest priority, group 2 has the next higher priority
+ * and so on.
+ */
+#define WEIGHT_OF_GROUP1_PCL_CHANNELS MAX_WEIGHT_OF_PCL_CHANNELS
+#define WEIGHT_OF_GROUP2_PCL_CHANNELS \
+	(WEIGHT_OF_GROUP1_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE)
+#define WEIGHT_OF_GROUP3_PCL_CHANNELS \
+	(WEIGHT_OF_GROUP2_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE)
+#define WEIGHT_OF_GROUP4_PCL_CHANNELS \
+	(WEIGHT_OF_GROUP3_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE)
+
+#define WEIGHT_OF_NON_PCL_CHANNELS 1
+#define WEIGHT_OF_DISALLOWED_CHANNELS 0
+
+#define MAX_MAC 2
+
+#define MAX_NUMBER_OF_CONC_CONNECTIONS 3
+
+typedef int (*send_mode_change_event_cb)(void);
+
+/**
+ * enum hw_mode_ss_config - Possible spatial stream configuration
+ * @HW_MODE_SS_0x0: Unused Tx and Rx of MAC
+ * @HW_MODE_SS_1x1: 1 Tx SS and 1 Rx SS
+ * @HW_MODE_SS_2x2: 2 Tx SS and 2 Rx SS
+ * @HW_MODE_SS_3x3: 3 Tx SS and 3 Rx SS
+ * @HW_MODE_SS_4x4: 4 Tx SS and 4 Rx SS
+ *
+ * Note: Right now only 1x1 and 2x2 are being supported. Other modes should
+ * be added when supported. Asymmetric configuration like 1x2, 2x1 are also
+ * not supported now. But, they are still valid. Right now, Tx/Rx SS support is
+ * 4 bits long. So, we can go upto 15x15
+ */
+enum hw_mode_ss_config {
+	HW_MODE_SS_0x0,
+	HW_MODE_SS_1x1,
+	HW_MODE_SS_2x2,
+	HW_MODE_SS_3x3,
+	HW_MODE_SS_4x4,
+};
+
+/**
+ * enum hw_mode_dbs_capab - DBS HW mode capability
+ * @HW_MODE_DBS_NONE: Non DBS capable
+ * @HW_MODE_DBS: DBS capable
+ */
+enum hw_mode_dbs_capab {
+	HW_MODE_DBS_NONE,
+	HW_MODE_DBS,
+};
+
+/**
+ * enum hw_mode_agile_dfs_capab - Agile DFS HW mode capability
+ * @HW_MODE_AGILE_DFS_NONE: Non Agile DFS capable
+ * @HW_MODE_AGILE_DFS: Agile DFS capable
+ */
+enum hw_mode_agile_dfs_capab {
+	HW_MODE_AGILE_DFS_NONE,
+	HW_MODE_AGILE_DFS,
+};
+
+/**
+ * enum hw_mode_sbs_capab - SBS HW mode capability
+ * @HW_MODE_SBS_NONE: Non SBS capable
+ * @HW_MODE_SBS: SBS capable
+ */
+enum hw_mode_sbs_capab {
+	HW_MODE_SBS_NONE,
+	HW_MODE_SBS,
+};
+
+/**
+ * enum hw_mode_mac_band_cap - mac band capability
+ * @HW_MODE_MAC_BAND_NONE: No band requirement.
+ * @HW_MODE_MAC_BAND_2G: 2G band supported.
+ * @HW_MODE_MAC_BAND_5G: 5G band supported.
+ *
+ * To add HW_MODE_MAC_BAND_NONE value to help to
+ * match the HW DBS mode in hw mode list.
+ * Other enum values should match with WMI header:
+ * typedef enum {
+ *   WLAN_2G_CAPABILITY = 0x1,
+ *   WLAN_5G_CAPABILITY = 0x2,
+ * } WLAN_BAND_CAPABILITY;
+ */
+enum hw_mode_mac_band_cap {
+	HW_MODE_MAC_BAND_NONE = 0,
+	HW_MODE_MAC_BAND_2G = WLAN_2G_CAPABILITY,
+	HW_MODE_MAC_BAND_5G = WLAN_5G_CAPABILITY,
+};
+
+/**
+ * enum policy_mgr_pcl_group_id - Identifies the pcl groups to be used
+ * @POLICY_MGR_PCL_GROUP_ID1_ID2: Use weights of group1 and group2
+ * @POLICY_MGR_PCL_GROUP_ID2_ID3: Use weights of group2 and group3
+ * @POLICY_MGR_PCL_GROUP_ID3_ID4: Use weights of group3 and group4
+ *
+ * Since maximum of three groups are possible, this will indicate which
+ * PCL group needs to be used.
+ */
+enum policy_mgr_pcl_group_id {
+	POLICY_MGR_PCL_GROUP_ID1_ID2,
+	POLICY_MGR_PCL_GROUP_ID2_ID3,
+	POLICY_MGR_PCL_GROUP_ID3_ID4,
+};
+
+/**
+ * policy_mgr_pcl_channel_order - Order in which the PCL is requested
+ * @POLICY_MGR_PCL_ORDER_NONE: no order
+ * @POLICY_MGR_PCL_ORDER_24G_THEN_5G: 2.4 Ghz channel followed by 5 Ghz channel
+ * @POLICY_MGR_PCL_ORDER_5G_THEN_2G: 5 Ghz channel followed by 2.4 Ghz channel
+ *
+ * Order in which the PCL is requested
+ */
+enum policy_mgr_pcl_channel_order {
+	POLICY_MGR_PCL_ORDER_NONE,
+	POLICY_MGR_PCL_ORDER_24G_THEN_5G,
+	POLICY_MGR_PCL_ORDER_5G_THEN_2G,
+};
+
+/**
+ * enum policy_mgr_max_rx_ss - Maximum number of receive spatial streams
+ * @POLICY_MGR_RX_NSS_1: Receive Nss = 1
+ * @POLICY_MGR_RX_NSS_2: Receive Nss = 2
+ * @POLICY_MGR_RX_NSS_3: Receive Nss = 3
+ * @POLICY_MGR_RX_NSS_4: Receive Nss = 4
+ * @POLICY_MGR_RX_NSS_5: Receive Nss = 5
+ * @POLICY_MGR_RX_NSS_6: Receive Nss = 6
+ * @POLICY_MGR_RX_NSS_7: Receive Nss = 7
+ * @POLICY_MGR_RX_NSS_8: Receive Nss = 8
+ *
+ * Indicates the maximum number of spatial streams that the STA can receive
+ */
+enum policy_mgr_max_rx_ss {
+	POLICY_MGR_RX_NSS_1 = 0,
+	POLICY_MGR_RX_NSS_2 = 1,
+	POLICY_MGR_RX_NSS_3 = 2,
+	POLICY_MGR_RX_NSS_4 = 3,
+	POLICY_MGR_RX_NSS_5 = 4,
+	POLICY_MGR_RX_NSS_6 = 5,
+	POLICY_MGR_RX_NSS_7 = 6,
+	POLICY_MGR_RX_NSS_8 = 7,
+	POLICY_MGR_RX_NSS_MAX,
+};
+
+/**
+ * enum policy_mgr_chain_mode - Chain Mask tx & rx combination.
+ *
+ * @POLICY_MGR_ONE_ONE: One for Tx, One for Rx
+ * @POLICY_MGR_TWO_TWO: Two for Tx, Two for Rx
+ * @POLICY_MGR_MAX_NO_OF_CHAIN_MODE: Max place holder
+ *
+ * These are generic IDs that identify the various roles
+ * in the software system
+ */
+enum policy_mgr_chain_mode {
+	POLICY_MGR_ONE_ONE = 0,
+	POLICY_MGR_TWO_TWO,
+	POLICY_MGR_MAX_NO_OF_CHAIN_MODE
+};
+
+/**
+ * enum policy_mgr_conc_priority_mode - t/p, powersave, latency.
+ *
+ * @PM_THROUGHPUT: t/p is the priority
+ * @PM_POWERSAVE: powersave is the priority
+ * @PM_LATENCY: latency is the priority
+ * @PM_MAX_CONC_PRIORITY_MODE: Max place holder
+ *
+ * These are generic IDs that identify the various roles
+ * in the software system
+ */
+enum policy_mgr_conc_priority_mode {
+	PM_THROUGHPUT = 0,
+	PM_POWERSAVE,
+	PM_LATENCY,
+	PM_MAX_CONC_PRIORITY_MODE
+};
+
+/**
+ * enum policy_mgr_con_mode - concurrency mode for PCL table
+ *
+ * @PM_STA_MODE: station mode
+ * @PM_SAP_MODE: SAP mode
+ * @PM_P2P_CLIENT_MODE: P2P client mode
+ * @PM_P2P_GO_MODE: P2P Go mode
+ * @PM_IBSS_MODE: IBSS mode
+ * @PM_NDI_MODE: NDI mode
+ * @PM_MAX_NUM_OF_MODE: max value place holder
+ */
+enum policy_mgr_con_mode {
+	PM_STA_MODE = 0,
+	PM_SAP_MODE,
+	PM_P2P_CLIENT_MODE,
+	PM_P2P_GO_MODE,
+	PM_IBSS_MODE,
+	PM_NDI_MODE,
+	PM_MAX_NUM_OF_MODE
+};
+
+/**
+ * enum policy_mgr_mac_use - MACs that are used
+ * @POLICY_MGR_MAC0: Only MAC0 is used
+ * @POLICY_MGR_MAC1: Only MAC1 is used
+ * @POLICY_MGR_MAC0_AND_MAC1: Both MAC0 and MAC1 are used
+ */
+enum policy_mgr_mac_use {
+	POLICY_MGR_MAC0 = 1,
+	POLICY_MGR_MAC1 = 2,
+	POLICY_MGR_MAC0_AND_MAC1 = 3
+};
+
+/**
+ * enum policy_mgr_pcl_type - Various types of Preferred channel list (PCL).
+ *
+ * @PM_NONE: No channel preference
+ * @PM_24G: 2.4 Ghz channels only
+ * @PM_5G: 5 Ghz channels only
+ * @PM_SCC_CH: SCC channel only
+ * @PM_MCC_CH: MCC channels only
+ * @PM_SBS_CH: SBS channels only
+ * @PM_SCC_CH_24G: SCC channel & 2.4 Ghz channels
+ * @PM_SCC_CH_5G: SCC channel & 5 Ghz channels
+ * @PM_24G_SCC_CH: 2.4 Ghz channels & SCC channel
+ * @PM_5G_SCC_CH: 5 Ghz channels & SCC channel
+ * @PM_SCC_ON_5_SCC_ON_24_24G: SCC channel on 5 Ghz, SCC
+ *	channel on 2.4 Ghz & 2.4 Ghz channels
+ * @PM_SCC_ON_5_SCC_ON_24_5G: SCC channel on 5 Ghz, SCC channel
+ *	on 2.4 Ghz & 5 Ghz channels
+ * @PM_SCC_ON_24_SCC_ON_5_24G: SCC channel on 2.4 Ghz, SCC
+ *	channel on 5 Ghz & 2.4 Ghz channels
+ * @PM_SCC_ON_24_SCC_ON_5_5G: SCC channel on 2.4 Ghz, SCC
+ *	channel on 5 Ghz & 5 Ghz channels
+ * @PM_SCC_ON_5_SCC_ON_24: SCC channel on 5 Ghz, SCC channel on
+ *	2.4 Ghz
+ * @PM_SCC_ON_24_SCC_ON_5: SCC channel on 2.4 Ghz, SCC channel
+ *	on 5 Ghz
+ * @PM_MCC_CH_24G: MCC channels & 2.4 Ghz channels
+ * @PM_MCC_CH_5G:  MCC channels & 5 Ghz channels
+ * @PM_24G_MCC_CH: 2.4 Ghz channels & MCC channels
+ * @PM_5G_MCC_CH: 5 Ghz channels & MCC channels
+ * @PM_SBS_CH_5G: SBS channels & rest of 5 Ghz channels
+ * @PM_24G_SCC_CH_SBS_CH: 2.4 Ghz channels, SCC channel & SBS channels
+ * @PM_24G_SCC_CH_SBS_CH_5G: 2.4 Ghz channels, SCC channel,
+ *      SBS channels & rest of the 5G channels
+ * @PM_24G_SBS_CH_MCC_CH: 2.4 Ghz channels, SBS channels & MCC channels
+ * @PM_MAX_PCL_TYPE: Max place holder
+ *
+ * These are generic IDs that identify the various roles
+ * in the software system
+ */
+enum policy_mgr_pcl_type {
+	PM_NONE = 0,
+	PM_24G,
+	PM_5G,
+	PM_SCC_CH,
+	PM_MCC_CH,
+	PM_SBS_CH,
+	PM_SCC_CH_24G,
+	PM_SCC_CH_5G,
+	PM_24G_SCC_CH,
+	PM_5G_SCC_CH,
+	PM_SCC_ON_5_SCC_ON_24_24G,
+	PM_SCC_ON_5_SCC_ON_24_5G,
+	PM_SCC_ON_24_SCC_ON_5_24G,
+	PM_SCC_ON_24_SCC_ON_5_5G,
+	PM_SCC_ON_5_SCC_ON_24,
+	PM_SCC_ON_24_SCC_ON_5,
+	PM_MCC_CH_24G,
+	PM_MCC_CH_5G,
+	PM_24G_MCC_CH,
+	PM_5G_MCC_CH,
+	PM_SBS_CH_5G,
+	PM_24G_SCC_CH_SBS_CH,
+	PM_24G_SCC_CH_SBS_CH_5G,
+	PM_24G_SBS_CH_MCC_CH,
+
+	PM_MAX_PCL_TYPE
+};
+
+/**
+ * enum policy_mgr_one_connection_mode - Combination of first connection
+ * type, band & spatial stream used.
+ *
+ * @PM_STA_24_1x1: STA connection using [email protected] Ghz
+ * @PM_STA_24_2x2: STA connection using [email protected] Ghz
+ * @PM_STA_5_1x1: STA connection using 1x1@5 Ghz
+ * @PM_STA_5_2x2: STA connection using 2x2@5 Ghz
+ * @PM_P2P_CLI_24_1x1: P2P Client connection using [email protected] Ghz
+ * @PM_P2P_CLI_24_2x2: P2P Client connection using [email protected] Ghz
+ * @PM_P2P_CLI_5_1x1: P2P Client connection using 1x1@5 Ghz
+ * @PM_P2P_CLI_5_2x2: P2P Client connection using 2x2@5 Ghz
+ * @PM_P2P_GO_24_1x1: P2P GO connection using [email protected] Ghz
+ * @PM_P2P_GO_24_2x2: P2P GO connection using [email protected] Ghz
+ * @PM_P2P_GO_5_1x1: P2P GO connection using 1x1@5 Ghz
+ * @PM_P2P_GO_5_2x2: P2P GO connection using 2x2@5 Ghz
+ * @PM_SAP_24_1x1: SAP connection using [email protected] Ghz
+ * @PM_SAP_24_2x2: SAP connection using [email protected] Ghz
+ * @PM_SAP_5_1x1: SAP connection using 1x1@5 Ghz
+ * @PM_SAP_5_1x1: SAP connection using 2x2@5 Ghz
+ * @PM_IBSS_24_1x1:  IBSS connection using [email protected] Ghz
+ * @PM_IBSS_24_2x2:  IBSS connection using [email protected] Ghz
+ * @PM_IBSS_5_1x1:  IBSS connection using 1x1@5 Ghz
+ * @PM_IBSS_5_2x2:  IBSS connection using 2x2@5 Ghz
+ * @PM_MAX_ONE_CONNECTION_MODE: Max place holder
+ *
+ * These are generic IDs that identify the various roles
+ * in the software system
+ */
+enum policy_mgr_one_connection_mode {
+	PM_STA_24_1x1 = 0,
+	PM_STA_24_2x2,
+	PM_STA_5_1x1,
+	PM_STA_5_2x2,
+	PM_P2P_CLI_24_1x1,
+	PM_P2P_CLI_24_2x2,
+	PM_P2P_CLI_5_1x1,
+	PM_P2P_CLI_5_2x2,
+	PM_P2P_GO_24_1x1,
+	PM_P2P_GO_24_2x2,
+	PM_P2P_GO_5_1x1,
+	PM_P2P_GO_5_2x2,
+	PM_SAP_24_1x1,
+	PM_SAP_24_2x2,
+	PM_SAP_5_1x1,
+	PM_SAP_5_2x2,
+	PM_IBSS_24_1x1,
+	PM_IBSS_24_2x2,
+	PM_IBSS_5_1x1,
+	PM_IBSS_5_2x2,
+
+	PM_MAX_ONE_CONNECTION_MODE
+};
+
+/**
+ * enum policy_mgr_two_connection_mode - Combination of first two
+ * connections type, concurrency state, band & spatial stream
+ * used.
+ *
+ * @PM_STA_SAP_SCC_24_1x1: STA & SAP connection on SCC using
+ *			[email protected] Ghz
+ * @PM_STA_SAP_SCC_24_2x2: STA & SAP connection on SCC using
+ *			[email protected] Ghz
+ * @PM_STA_SAP_MCC_24_1x1: STA & SAP connection on MCC using
+ *			[email protected] Ghz
+ * @PM_STA_SAP_MCC_24_2x2: STA & SAP connection on MCC using
+ *			[email protected] Ghz
+ * @PM_STA_SAP_SCC_5_1x1: STA & SAP connection on SCC using
+ *			1x1@5 Ghz
+ * @PM_STA_SAP_SCC_5_2x2: STA & SAP connection on SCC using
+ *			2x2@5 Ghz
+ * @PM_STA_SAP_MCC_5_1x1: STA & SAP connection on MCC using
+ *			1x1@5 Ghz
+ * @PM_STA_SAP_MCC_5_2x2: STA & SAP connection on MCC using
+ *			2x2@5 Ghz
+ * @PM_STA_SAP_DBS_1x1: STA & SAP connection on DBS using 1x1
+ * @PM_STA_SAP_DBS_2x2: STA & SAP connection on DBS using 2x2
+ * @PM_STA_SAP_SBS_5_1x1: STA & SAP connection on 5G SBS using 1x1
+ * @PM_STA_P2P_GO_SCC_24_1x1: STA & P2P GO connection on SCC
+ *			using [email protected] Ghz
+ * @PM_STA_P2P_GO_SCC_24_2x2: STA & P2P GO connection on SCC
+ *			using [email protected] Ghz
+ * @PM_STA_P2P_GO_MCC_24_1x1: STA & P2P GO connection on MCC
+ *			using [email protected] Ghz
+ * @PM_STA_P2P_GO_MCC_24_2x2: STA & P2P GO connection on MCC
+ *			using [email protected] Ghz
+ * @PM_STA_P2P_GO_SCC_5_1x1: STA & P2P GO connection on SCC
+ *			using 1x1@5 Ghz
+ * @PM_STA_P2P_GO_SCC_5_2x2: STA & P2P GO connection on SCC
+ *			using 2x2@5 Ghz
+ * @PM_STA_P2P_GO_MCC_5_1x1: STA & P2P GO connection on MCC
+ *			using 1x1@5 Ghz
+ * @PM_STA_P2P_GO_MCC_5_2x2: STA & P2P GO connection on MCC
+ *			using 2x2@5 Ghz
+ * @PM_STA_P2P_GO_DBS_1x1: STA & P2P GO connection on DBS using
+ *			1x1
+ * @PM_STA_P2P_GO_DBS_2x2: STA & P2P GO connection on DBS using
+ *			2x2
+ * @PM_STA_P2P_GO_SBS_5_1x1: STA & P2P GO connection on 5G SBS
+ *			using 1x1
+ * @PM_STA_P2P_CLI_SCC_24_1x1: STA & P2P CLI connection on SCC
+ *			using [email protected] Ghz
+ * @PM_STA_P2P_CLI_SCC_24_2x2: STA & P2P CLI connection on SCC
+ *			using [email protected] Ghz
+ * @PM_STA_P2P_CLI_MCC_24_1x1: STA & P2P CLI connection on MCC
+ *			using [email protected] Ghz
+ * @PM_STA_P2P_CLI_MCC_24_2x2: STA & P2P CLI connection on MCC
+ *			using [email protected] Ghz
+ * @PM_STA_P2P_CLI_SCC_5_1x1: STA & P2P CLI connection on SCC
+ *			using 1x1@5 Ghz
+ * @PM_STA_P2P_CLI_SCC_5_2x2: STA & P2P CLI connection on SCC
+ *			using 2x2@5 Ghz
+ * @PM_STA_P2P_CLI_MCC_5_1x1: STA & P2P CLI connection on MCC
+ *			using 1x1@5 Ghz
+ * @PM_STA_P2P_CLI_MCC_5_2x2: STA & P2P CLI connection on MCC
+ *			using 2x2@5 Ghz
+ * @PM_STA_P2P_CLI_DBS_1x1: STA & P2P CLI connection on DBS
+ *			using 1x1
+ * @PM_STA_P2P_CLI_DBS_2x2: STA & P2P CLI connection on DBS
+ *			using 2x2
+ * @PM_STA_P2P_CLI_SBS_5_1x1: STA & P2P CLI connection on 5G
+ *			SBS using 1x1
+ * @PM_P2P_GO_P2P_CLI_SCC_24_1x1: P2P GO & CLI connection on
+ *			SCC using [email protected] Ghz
+ * @PM_P2P_GO_P2P_CLI_SCC_24_2x2: P2P GO & CLI connection on
+ *			SCC using [email protected] Ghz
+ * @PM_P2P_GO_P2P_CLI_MCC_24_1x1: P2P GO & CLI connection on
+ *			MCC using [email protected] Ghz
+ * @PM_P2P_GO_P2P_CLI_MCC_24_2x2: P2P GO & CLI connection on
+ *			MCC using [email protected] Ghz
+ * @PM_P2P_GO_P2P_CLI_SCC_5_1x1: P2P GO & CLI connection on
+ *			SCC using 1x1@5 Ghz
+ * @PM_P2P_GO_P2P_CLI_SCC_5_2x2: P2P GO & CLI connection on
+ *			SCC using 2x2@5 Ghz
+ * @PM_P2P_GO_P2P_CLI_MCC_5_1x1: P2P GO & CLI connection on
+ *			MCC using 1x1@5 Ghz
+ * @PM_P2P_GO_P2P_CLI_MCC_5_2x2: P2P GO & CLI connection on
+ *			MCC using 2x2@5 Ghz
+ * @PM_P2P_GO_P2P_CLI_DBS_1x1: P2P GO & CLI connection on DBS
+ *			using 1x1
+ * @PM_P2P_GO_P2P_CLI_DBS_2x2: P2P GO & P2P CLI connection
+ *			on DBS using 2x2
+ * @PM_P2P_GO_P2P_CLI_SBS_5_1x1: P2P GO & P2P CLI connection
+ *			on 5G SBS using 1x1
+ * @PM_P2P_GO_SAP_SCC_24_1x1: P2P GO & SAP connection on
+ *			SCC using [email protected] Ghz
+ * @PM_P2P_GO_SAP_SCC_24_2x2: P2P GO & SAP connection on
+ *			SCC using [email protected] Ghz
+ * @PM_P2P_GO_SAP_MCC_24_1x1: P2P GO & SAP connection on
+ *			MCC using [email protected] Ghz
+ * @PM_P2P_GO_SAP_MCC_24_2x2: P2P GO & SAP connection on
+ *			MCC using [email protected] Ghz
+ * @PM_P2P_GO_SAP_SCC_5_1x1: P2P GO & SAP connection on
+ *			SCC using 1x1@5 Ghz
+ * @PM_P2P_GO_SAP_SCC_5_2x2: P2P GO & SAP connection on
+ *			SCC using 2x2@5 Ghz
+ * @PM_P2P_GO_SAP_MCC_5_1x1: P2P GO & SAP connection on
+ *			MCC using 1x1@5 Ghz
+ * @PM_P2P_GO_SAP_MCC_5_2x2: P2P GO & SAP connection on
+ *			MCC using 2x2@5 Ghz
+ * @PM_P2P_GO_SAP_DBS_1x1: P2P GO & SAP connection on DBS using
+ *			1x1
+ * @PM_P2P_GO_SAP_DBS_2x2: P2P GO & SAP connection on DBS using
+ *			2x2
+ * @PM_P2P_GO_SAP_SBS_5_1x1: P2P GO & SAP connection on 5G SBS
+ *			using 1x1
+ * @PM_P2P_CLI_SAP_SCC_24_1x1: CLI & SAP connection on SCC using
+ *			[email protected] Ghz
+ * @PM_P2P_CLI_SAP_SCC_24_2x2: CLI & SAP connection on SCC using
+ *			[email protected] Ghz
+ * @PM_P2P_CLI_SAP_MCC_24_1x1: CLI & SAP connection on MCC using
+ *			[email protected] Ghz
+ * @PM_P2P_CLI_SAP_MCC_24_2x2: CLI & SAP connection on MCC using
+ *			[email protected] Ghz
+ * @PM_P2P_CLI_SAP_SCC_5_1x1: CLI & SAP connection on SCC using
+ *			1x1@5 Ghz
+ * @PM_P2P_CLI_SAP_SCC_5_2x2: CLI & SAP connection on SCC using
+ *			2x2@5 Ghz
+ * @PM_P2P_CLI_SAP_MCC_5_1x1: CLI & SAP connection on MCC using
+ *			1x1@5 Ghz
+ * @PM_P2P_CLI_SAP_MCC_5_2x2: CLI & SAP connection on MCC using
+ *			2x2@5 Ghz
+ * @POLICY_MGR_P2P_STA_SAP_MCC_24_5_1x1: CLI and SAP connecting on MCC
+ *			in 2.4 and 5GHz 1x1
+ * @POLICY_MGR_P2P_STA_SAP_MCC_24_5_2x2: CLI and SAP connecting on MCC
+ *			in 2.4 and 5GHz 2x2
+ * @PM_P2P_CLI_SAP_DBS_1x1,: CLI & SAP connection on DBS using 1x1
+ * @PM_P2P_CLI_SAP_DBS_2x2: P2P CLI & SAP connection on DBS using
+ *			2x2
+ * @PM_P2P_CLI_SAP_SBS_5_1x1: P2P CLI & SAP connection on 5G SBS
+ *			using 1x1
+ * @PM_SAP_SAP_SCC_24_1x1: SAP & SAP connection on
+ *			SCC using [email protected] Ghz
+ * @PM_SAP_SAP_SCC_24_2x2: SAP & SAP connection on
+ *			SCC using [email protected] Ghz
+ * @PM_SAP_SAP_MCC_24_1x1: SAP & SAP connection on
+ *			MCC using [email protected] Ghz
+ * @PM_SAP_SAP_MCC_24_2x2: SAP & SAP connection on
+ *			MCC using [email protected] Ghz
+ * @PM_SAP_SAP_SCC_5_1x1: SAP & SAP connection on
+ *			SCC using 1x1@5 Ghz
+ * @PM_SAP_SAP_SCC_5_2x2: SAP & SAP connection on
+ *			SCC using 2x2@5 Ghz
+ * @PM_SAP_SAP_MCC_5_1x1: SAP & SAP connection on
+ *			MCC using 1x1@5 Ghz
+ * @PM_SAP_SAP_MCC_5_2x2: SAP & SAP connection on
+ *          MCC using 2x2@5 Ghz
+ * @PM_SAP_SAP_MCC_24_5_1x1: SAP & SAP connection on
+ *			MCC in 2.4 and 5GHz 1x1
+ * @PM_SAP_SAP_MCC_24_5_2x2: SAP & SAP connection on
+ *			MCC in 2.4 and 5GHz 2x2
+ * @PM_SAP_SAP_DBS_1x1: SAP & SAP connection on DBS using
+ *			1x1
+ * @PM_SAP_SAP_DBS_2x2: SAP & SAP connection on DBS using 2x2
+ * @PM_SAP_SAP_SBS_5_1x1: SAP & SAP connection on 5G SBS using 1x1
+ * @PM_STA_STA_SCC_24_1x1: STA & STA connection on
+ *			SCC using [email protected] Ghz
+ * @PM_STA_STA_SCC_24_2x2: STA & STA connection on
+ *			SCC using [email protected] Ghz
+ * @PM_STA_STA_MCC_24_1x1: STA & STA connection on
+ *			MCC using [email protected] Ghz
+ * @PM_STA_STA_MCC_24_2x2: STA & STA connection on
+ *			MCC using [email protected] Ghz
+ * @PM_STA_STA_SCC_5_1x1: STA & STA connection on
+ *			SCC using 1x1@5 Ghz
+ * @PM_STA_STA_SCC_5_2x2: STA & STA connection on
+ *			SCC using 2x2@5 Ghz
+ * @PM_STA_STA_MCC_5_1x1: STA & STA connection on
+ *			MCC using 1x1@5 Ghz
+ * @PM_STA_STA_MCC_5_2x2: STA & STA connection on
+ *          MCC using 2x2@5 Ghz
+ * @PM_STA_STA_MCC_24_5_1x1: STA & STA connection on
+ *			MCC in 2.4 and 5GHz 1x1
+ * @PM_STA_STA_MCC_24_5_2x2: STA & STA connection on
+ *			MCC in 2.4 and 5GHz 2x2
+ * @PM_STA_STA_DBS_1x1: STA & STA connection on DBS using
+ *			1x1
+ * @PM_STA_STA_DBS_2x2: STA & STA connection on DBS using 2x2
+ * @PM_STA_STA_SBS_5_1x1: STA & STA connection on 5G SBS using 1x1
+ *
+ * These are generic IDs that identify the various roles in the
+ * software system
+ */
+enum policy_mgr_two_connection_mode {
+	PM_STA_SAP_SCC_24_1x1 = 0,
+	PM_STA_SAP_SCC_24_2x2,
+	PM_STA_SAP_MCC_24_1x1,
+	PM_STA_SAP_MCC_24_2x2,
+	PM_STA_SAP_SCC_5_1x1,
+	PM_STA_SAP_SCC_5_2x2,
+	PM_STA_SAP_MCC_5_1x1,
+	PM_STA_SAP_MCC_5_2x2,
+	PM_STA_SAP_MCC_24_5_1x1,
+	PM_STA_SAP_MCC_24_5_2x2,
+	PM_STA_SAP_DBS_1x1,
+	PM_STA_SAP_DBS_2x2,
+	PM_STA_SAP_SBS_5_1x1,
+	PM_STA_P2P_GO_SCC_24_1x1,
+	PM_STA_P2P_GO_SCC_24_2x2,
+	PM_STA_P2P_GO_MCC_24_1x1,
+	PM_STA_P2P_GO_MCC_24_2x2,
+	PM_STA_P2P_GO_SCC_5_1x1,
+	PM_STA_P2P_GO_SCC_5_2x2,
+	PM_STA_P2P_GO_MCC_5_1x1,
+	PM_STA_P2P_GO_MCC_5_2x2,
+	PM_STA_P2P_GO_MCC_24_5_1x1,
+	PM_STA_P2P_GO_MCC_24_5_2x2,
+	PM_STA_P2P_GO_DBS_1x1,
+	PM_STA_P2P_GO_DBS_2x2,
+	PM_STA_P2P_GO_SBS_5_1x1,
+	PM_STA_P2P_CLI_SCC_24_1x1,
+	PM_STA_P2P_CLI_SCC_24_2x2,
+	PM_STA_P2P_CLI_MCC_24_1x1,
+	PM_STA_P2P_CLI_MCC_24_2x2,
+	PM_STA_P2P_CLI_SCC_5_1x1,
+	PM_STA_P2P_CLI_SCC_5_2x2,
+	PM_STA_P2P_CLI_MCC_5_1x1,
+	PM_STA_P2P_CLI_MCC_5_2x2,
+	PM_STA_P2P_CLI_MCC_24_5_1x1,
+	PM_STA_P2P_CLI_MCC_24_5_2x2,
+	PM_STA_P2P_CLI_DBS_1x1,
+	PM_STA_P2P_CLI_DBS_2x2,
+	PM_STA_P2P_CLI_SBS_5_1x1,
+	PM_P2P_GO_P2P_CLI_SCC_24_1x1,
+	PM_P2P_GO_P2P_CLI_SCC_24_2x2,
+	PM_P2P_GO_P2P_CLI_MCC_24_1x1,
+	PM_P2P_GO_P2P_CLI_MCC_24_2x2,
+	PM_P2P_GO_P2P_CLI_SCC_5_1x1,
+	PM_P2P_GO_P2P_CLI_SCC_5_2x2,
+	PM_P2P_GO_P2P_CLI_MCC_5_1x1,
+	PM_P2P_GO_P2P_CLI_MCC_5_2x2,
+	PM_P2P_GO_P2P_CLI_MCC_24_5_1x1,
+	PM_P2P_GO_P2P_CLI_MCC_24_5_2x2,
+	PM_P2P_GO_P2P_CLI_DBS_1x1,
+	PM_P2P_GO_P2P_CLI_DBS_2x2,
+	PM_P2P_GO_P2P_CLI_SBS_5_1x1,
+	PM_P2P_GO_SAP_SCC_24_1x1,
+	PM_P2P_GO_SAP_SCC_24_2x2,
+	PM_P2P_GO_SAP_MCC_24_1x1,
+	PM_P2P_GO_SAP_MCC_24_2x2,
+	PM_P2P_GO_SAP_SCC_5_1x1,
+	PM_P2P_GO_SAP_SCC_5_2x2,
+	PM_P2P_GO_SAP_MCC_5_1x1,
+	PM_P2P_GO_SAP_MCC_5_2x2,
+	PM_P2P_GO_SAP_MCC_24_5_1x1,
+	PM_P2P_GO_SAP_MCC_24_5_2x2,
+	PM_P2P_GO_SAP_DBS_1x1,
+	PM_P2P_GO_SAP_DBS_2x2,
+	PM_P2P_GO_SAP_SBS_5_1x1,
+	PM_P2P_CLI_SAP_SCC_24_1x1,
+	PM_P2P_CLI_SAP_SCC_24_2x2,
+	PM_P2P_CLI_SAP_MCC_24_1x1,
+	PM_P2P_CLI_SAP_MCC_24_2x2,
+	PM_P2P_CLI_SAP_SCC_5_1x1,
+	PM_P2P_CLI_SAP_SCC_5_2x2,
+	PM_P2P_CLI_SAP_MCC_5_1x1,
+	PM_P2P_CLI_SAP_MCC_5_2x2,
+	PM_P2P_CLI_SAP_MCC_24_5_1x1,
+	PM_P2P_CLI_SAP_MCC_24_5_2x2,
+	PM_P2P_CLI_SAP_DBS_1x1,
+	PM_P2P_CLI_SAP_DBS_2x2,
+	PM_P2P_CLI_SAP_SBS_5_1x1,
+	PM_SAP_SAP_SCC_24_1x1,
+	PM_SAP_SAP_SCC_24_2x2,
+	PM_SAP_SAP_MCC_24_1x1,
+	PM_SAP_SAP_MCC_24_2x2,
+	PM_SAP_SAP_SCC_5_1x1,
+	PM_SAP_SAP_SCC_5_2x2,
+	PM_SAP_SAP_MCC_5_1x1,
+	PM_SAP_SAP_MCC_5_2x2,
+	PM_SAP_SAP_MCC_24_5_1x1,
+	PM_SAP_SAP_MCC_24_5_2x2,
+	PM_SAP_SAP_DBS_1x1,
+	PM_SAP_SAP_DBS_2x2,
+	PM_SAP_SAP_SBS_5_1x1,
+	PM_STA_STA_SCC_24_1x1,
+	PM_STA_STA_SCC_24_2x2,
+	PM_STA_STA_MCC_24_1x1,
+	PM_STA_STA_MCC_24_2x2,
+	PM_STA_STA_SCC_5_1x1,
+	PM_STA_STA_SCC_5_2x2,
+	PM_STA_STA_MCC_5_1x1,
+	PM_STA_STA_MCC_5_2x2,
+	PM_STA_STA_MCC_24_5_1x1,
+	PM_STA_STA_MCC_24_5_2x2,
+	PM_STA_STA_DBS_1x1,
+	PM_STA_STA_DBS_2x2,
+	PM_STA_STA_SBS_5_1x1,
+
+	PM_MAX_TWO_CONNECTION_MODE
+};
+
+/**
+ * enum policy_mgr_conc_next_action - actions to be taken on old
+ * connections.
+ *
+ * @PM_NOP: No action
+ * @PM_DBS: switch to DBS mode
+ * @PM_DBS_DOWNGRADE: switch to DBS mode & downgrade to 1x1
+ * @PM_DBS_UPGRADE: switch to DBS mode & upgrade to 2x2
+ * @PM_SINGLE_MAC: switch to MCC/SCC mode
+ * @PM_SINGLE_MAC_UPGRADE: switch to MCC/SCC mode & upgrade to 2x2
+ * @PM_SBS: switch to SBS mode
+ * @PM_SBS_DOWNGRADE: switch to SBS mode & downgrade to 1x1
+ * @PM_DOWNGRADE: downgrade to 1x1
+ * @PM_UPGRADE: upgrade to 2x2
+ * @PM_DBS1: switch to DBS 1
+ * @PM_DBS1_DOWNGRADE: downgrade 2G beaconing entity to 1x1 and switch to DBS1.
+ * @PM_DBS2: switch to DBS 2
+ * @PM_DBS2_DOWNGRADE: downgrade 5G beaconing entity to 1x1 and switch to DBS2.
+ * @PM_UPGRADE_5G: upgrade 5g beaconing entity to 2x2.
+ * @PM_UPGRADE_2G: upgrade 2g beaconing entity to 2x2.
+ * @PM_MAX_CONC_PRIORITY_MODE: Max place holder
+ *
+ * These are generic IDs that identify the various roles
+ * in the software system
+ */
+enum policy_mgr_conc_next_action {
+	PM_NOP = 0,
+	PM_DBS,
+	PM_DBS_DOWNGRADE,
+	PM_DBS_UPGRADE,
+	PM_SINGLE_MAC,
+	PM_SINGLE_MAC_UPGRADE,
+	PM_SBS,
+	PM_SBS_DOWNGRADE,
+	PM_DOWNGRADE,
+	PM_UPGRADE,
+	PM_DBS1,
+	PM_DBS1_DOWNGRADE,
+	PM_DBS2,
+	PM_DBS2_DOWNGRADE,
+	PM_UPGRADE_5G,
+	PM_UPGRADE_2G,
+
+	PM_MAX_CONC_NEXT_ACTION
+};
+
+/**
+ * enum policy_mgr_band - wifi band.
+ *
+ * @POLICY_MGR_BAND_24: 2.4 Ghz band
+ * @POLICY_MGR_BAND_5: 5 Ghz band
+ * @POLICY_MGR_ANY: to specify all band
+ * @POLICY_MGR_MAX_BAND: Max place holder
+ *
+ * These are generic IDs that identify the various roles
+ * in the software system
+ */
+enum policy_mgr_band {
+	POLICY_MGR_BAND_24 = 0,
+	POLICY_MGR_BAND_5,
+	POLICY_MGR_ANY,
+	POLICY_MGR_MAX_BAND = POLICY_MGR_ANY,
+};
+
+/**
+ * enum policy_mgr_conn_update_reason: Reason for conc connection update
+ * @POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN: Set probable operating channel
+ * @POLICY_MGR_UPDATE_REASON_JOIN_IBSS: Join IBSS
+ * @POLICY_MGR_UPDATE_REASON_UT: Unit test related
+ * @POLICY_MGR_UPDATE_REASON_START_AP: Start AP
+ * @POLICY_MGR_UPDATE_REASON_NORMAL_STA: Connection to Normal STA
+ * @POLICY_MGR_UPDATE_REASON_HIDDEN_STA: Connection to Hidden STA
+ * @POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC: Opportunistic HW mode update
+ * @POLICY_MGR_UPDATE_REASON_NSS_UPDATE: NSS update
+ * @POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH: Channel switch
+ * @POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA: Channel switch for STA
+ * @POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE: In Dual DBS HW, if the vdev based
+ *        2x2 preference enabled, the vdev down may cause prioritized active
+ *        vdev change, then DBS hw mode may needs to change from one DBS mode
+ *        to the other DBS mode. This reason code indicates such condition.
+ */
+enum policy_mgr_conn_update_reason {
+	POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN,
+	POLICY_MGR_UPDATE_REASON_JOIN_IBSS,
+	POLICY_MGR_UPDATE_REASON_UT,
+	POLICY_MGR_UPDATE_REASON_START_AP,
+	POLICY_MGR_UPDATE_REASON_NORMAL_STA,
+	POLICY_MGR_UPDATE_REASON_HIDDEN_STA,
+	POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC,
+	POLICY_MGR_UPDATE_REASON_NSS_UPDATE,
+	POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH,
+	POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA,
+	POLICY_MGR_UPDATE_REASON_PRE_CAC,
+	POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE,
+};
+
+/**
+ * enum hw_mode_bandwidth - bandwidth of wifi channel.
+ *
+ * @HW_MODE_5_MHZ: 5 Mhz bandwidth
+ * @HW_MODE_10_MHZ: 10 Mhz bandwidth
+ * @HW_MODE_20_MHZ: 20 Mhz bandwidth
+ * @HW_MODE_40_MHZ: 40 Mhz bandwidth
+ * @HW_MODE_80_MHZ: 80 Mhz bandwidth
+ * @HW_MODE_80_PLUS_80_MHZ: 80 Mhz plus 80 Mhz bandwidth
+ * @HW_MODE_160_MHZ: 160 Mhz bandwidth
+ * @HW_MODE_MAX_BANDWIDTH: Max place holder
+ *
+ * These are generic IDs that identify the various roles
+ * in the software system
+ */
+enum hw_mode_bandwidth {
+	HW_MODE_BW_NONE,
+	HW_MODE_5_MHZ,
+	HW_MODE_10_MHZ,
+	HW_MODE_20_MHZ,
+	HW_MODE_40_MHZ,
+	HW_MODE_80_MHZ,
+	HW_MODE_80_PLUS_80_MHZ,
+	HW_MODE_160_MHZ,
+	HW_MODE_MAX_BANDWIDTH
+};
+
+/**
+ * enum set_hw_mode_status - Status of set HW mode command
+ * @SET_HW_MODE_STATUS_OK: command successful
+ * @SET_HW_MODE_STATUS_EINVAL: Requested invalid hw_mode
+ * @SET_HW_MODE_STATUS_ECANCELED: HW mode change cancelled
+ * @SET_HW_MODE_STATUS_ENOTSUP: HW mode not supported
+ * @SET_HW_MODE_STATUS_EHARDWARE: HW mode change prevented by hardware
+ * @SET_HW_MODE_STATUS_EPENDING: HW mode change is pending
+ * @SET_HW_MODE_STATUS_ECOEX: HW mode change conflict with Coex
+ */
+enum set_hw_mode_status {
+	SET_HW_MODE_STATUS_OK,
+	SET_HW_MODE_STATUS_EINVAL,
+	SET_HW_MODE_STATUS_ECANCELED,
+	SET_HW_MODE_STATUS_ENOTSUP,
+	SET_HW_MODE_STATUS_EHARDWARE,
+	SET_HW_MODE_STATUS_EPENDING,
+	SET_HW_MODE_STATUS_ECOEX,
+};
+
+typedef void (*dual_mac_cb)(enum set_hw_mode_status status,
+		uint32_t scan_config,
+		uint32_t fw_mode_config);
+/**
+ * enum policy_mgr_hw_mode_change - identify the HW mode switching to.
+ *
+ * @POLICY_MGR_HW_MODE_NOT_IN_PROGRESS: HW mode change not in progress
+ * @POLICY_MGR_SMM_IN_PROGRESS: switching to SMM mode
+ * @POLICY_MGR_DBS_IN_PROGRESS: switching to DBS mode
+ * @POLICY_MGR_SBS_IN_PROGRESS: switching to SBS mode
+ *
+ * These are generic IDs that identify the various roles
+ * in the software system
+ */
+enum policy_mgr_hw_mode_change {
+	POLICY_MGR_HW_MODE_NOT_IN_PROGRESS = 0,
+	POLICY_MGR_SMM_IN_PROGRESS,
+	POLICY_MGR_DBS_IN_PROGRESS,
+	POLICY_MGR_SBS_IN_PROGRESS
+};
+
+/**
+ * enum dbs_support - structure to define INI values and their meaning
+ *
+ * @ENABLE_DBS_CXN_AND_SCAN: Enable DBS support for connection and scan
+ * @DISABLE_DBS_CXN_AND_SCAN: Disable DBS support for connection and scan
+ * @DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN: disable dbs support for
+ * connection but keep dbs support for scan
+ * @DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF: disable dbs support
+ * for connection but keep dbs for scan but switch off the async scan
+ * @ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF: enable dbs support for
+ * connection and scan but switch off the async scan
+ * @ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN: Enable DBS support for connection and
+ * disable DBS support for scan
+ * @ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN: Enable DBS
+ * support for connection and disable simultaneous scan from
+ * upper layer (DBS scan remains enabled in FW)
+ */
+enum dbs_support {
+	ENABLE_DBS_CXN_AND_SCAN,
+	DISABLE_DBS_CXN_AND_SCAN,
+	DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN,
+	DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF,
+	ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF,
+	ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN,
+	ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN,
+};
+
+/**
+ * struct policy_mgr_conc_connection_info - information of all existing
+ * connections in the wlan system
+ *
+ * @mode: connection type
+ * @chan: channel of the connection
+ * @bw: channel bandwidth used for the connection
+ * @mac: The HW mac it is running
+ * @chain_mask: The original capability advertised by HW
+ * @original_nss: nss negotiated at connection time
+ * @vdev_id: vdev id of the connection
+ * @in_use: if the table entry is active
+ */
+struct policy_mgr_conc_connection_info {
+	enum policy_mgr_con_mode mode;
+	uint8_t       chan;
+	enum hw_mode_bandwidth bw;
+	uint8_t       mac;
+	enum policy_mgr_chain_mode chain_mask;
+	uint32_t      original_nss;
+	uint32_t      vdev_id;
+	bool          in_use;
+};
+
+/**
+ * struct policy_mgr_hw_mode_params - HW mode params
+ * @mac0_tx_ss: MAC0 Tx spatial stream
+ * @mac0_rx_ss: MAC0 Rx spatial stream
+ * @mac1_tx_ss: MAC1 Tx spatial stream
+ * @mac1_rx_ss: MAC1 Rx spatial stream
+ * @mac0_bw: MAC0 bandwidth
+ * @mac1_bw: MAC1 bandwidth
+ * @mac0_band_cap: mac0 band (5g/2g) capability
+ * @dbs_cap: DBS capabality
+ * @agile_dfs_cap: Agile DFS capabality
+ * @action_type: for dbs mode, the field indicates the "Action type" to be
+ * used to switch to the mode. To help the hw mode validation.
+ */
+struct policy_mgr_hw_mode_params {
+	uint8_t mac0_tx_ss;
+	uint8_t mac0_rx_ss;
+	uint8_t mac1_tx_ss;
+	uint8_t mac1_rx_ss;
+	uint8_t mac0_bw;
+	uint8_t mac1_bw;
+	uint8_t mac0_band_cap;
+	uint8_t dbs_cap;
+	uint8_t agile_dfs_cap;
+	uint8_t sbs_cap;
+	enum policy_mgr_conc_next_action action_type;
+};
+
+/**
+ * struct policy_mgr_vdev_mac_map - vdev id-mac id map
+ * @vdev_id: VDEV id
+ * @mac_id: MAC id
+ */
+struct policy_mgr_vdev_mac_map {
+	uint32_t vdev_id;
+	uint32_t mac_id;
+};
+
+/**
+ * struct policy_mgr_dual_mac_config - Dual MAC configuration
+ * @scan_config: Scan configuration
+ * @fw_mode_config: FW mode configuration
+ * @set_dual_mac_cb: Callback function to be executed on response to the command
+ */
+struct policy_mgr_dual_mac_config {
+	uint32_t scan_config;
+	uint32_t fw_mode_config;
+	dual_mac_cb set_dual_mac_cb;
+};
+
+/**
+ * struct policy_mgr_hw_mode - Format of set HW mode
+ * @hw_mode_index: Index of HW mode to be set
+ * @set_hw_mode_cb: HDD set HW mode callback
+ * @reason: Reason for HW mode change
+ * @session_id: Session id
+ * @next_action: next action to happen at policy mgr
+ * @context: psoc context
+ */
+struct policy_mgr_hw_mode {
+	uint32_t hw_mode_index;
+	void *set_hw_mode_cb;
+	enum policy_mgr_conn_update_reason reason;
+	uint32_t session_id;
+	uint8_t next_action;
+	struct wlan_objmgr_psoc *context;
+};
+
+/**
+ * struct policy_mgr_pcl_list - Format of PCL
+ * @pcl_list: List of preferred channels
+ * @weight_list: Weights of the PCL
+ * @pcl_len: Number of channels in the PCL
+ */
+struct policy_mgr_pcl_list {
+	uint8_t pcl_list[POLICY_MGR_MAX_CHANNEL_LIST];
+	uint8_t weight_list[POLICY_MGR_MAX_CHANNEL_LIST];
+	uint32_t pcl_len;
+};
+
+/**
+ * struct policy_mgr_pcl_chan_weights - Params to get the valid weighed list
+ * @pcl_list: Preferred channel list already sorted in the order of preference
+ * @pcl_len: Length of the PCL
+ * @saved_chan_list: Valid channel list updated as part of
+ * WMA_UPDATE_CHAN_LIST_REQ
+ * @saved_num_chan: Length of the valid channel list
+ * @weighed_valid_list: Weights of the valid channel list. This will have one
+ * to one mapping with valid_chan_list. FW expects channel order and size to be
+ * as per the list provided in WMI_SCAN_CHAN_LIST_CMDID.
+ * @weight_list: Weights assigned by policy manager
+ */
+struct policy_mgr_pcl_chan_weights {
+	uint8_t pcl_list[POLICY_MGR_MAX_CHANNEL_LIST];
+	uint32_t pcl_len;
+	uint8_t saved_chan_list[POLICY_MGR_MAX_CHANNEL_LIST];
+	uint32_t saved_num_chan;
+	uint8_t weighed_valid_list[POLICY_MGR_MAX_CHANNEL_LIST];
+	uint8_t weight_list[POLICY_MGR_MAX_CHANNEL_LIST];
+};
+
+/**
+ * struct policy_mgr_vdev_entry_info - vdev related param to be
+ * used by policy manager
+ * @type: type
+ * @sub_type: sub type
+ * @mhz: channel frequency in MHz
+ * @chan_width: channel bandwidth
+ * @mac_id: the mac on which vdev is on
+ */
+struct policy_mgr_vdev_entry_info {
+	uint32_t type;
+	uint32_t sub_type;
+	uint32_t mhz;
+	uint32_t chan_width;
+	uint32_t mac_id;
+};
+
+/**
+ * struct dbs_hw_mode_info - WLAN_DBS_HW_MODES_TLV Format
+ * @tlv_header: TLV header, TLV tag and len; tag equals WMITLV_TAG_ARRAY_UINT32
+ * @hw_mode_list: WLAN_DBS_HW_MODE_LIST entries
+ */
+struct dbs_hw_mode_info {
+	uint32_t tlv_header;
+	uint32_t *hw_mode_list;
+};
+
+/**
+ * struct dual_mac_config - Dual MAC configurations
+ * @prev_scan_config: Previous scan configuration
+ * @prev_fw_mode_config: Previous FW mode configuration
+ * @cur_scan_config: Current scan configuration
+ * @cur_fw_mode_config: Current FW mode configuration
+ * @req_scan_config: Requested scan configuration
+ * @req_fw_mode_config: Requested FW mode configuration
+ */
+struct dual_mac_config {
+	uint32_t prev_scan_config;
+	uint32_t prev_fw_mode_config;
+	uint32_t cur_scan_config;
+	uint32_t cur_fw_mode_config;
+	uint32_t req_scan_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
+ * @enable2x2: 2x2 chain mask user config
+ * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled
+ */
+struct policy_mgr_user_cfg {
+	bool enable2x2;
+	bool sub_20_mhz_enabled;
+	bool is_sta_sap_scc_allowed_on_dfs_chan;
+	uint32_t sta_sap_scc_on_lte_coex_chan;
+};
+
+/**
+ * struct dbs_nss - Number of spatial streams in DBS mode
+ * @mac0_ss: Number of spatial streams on MAC0
+ * @mac1_ss: Number of spatial streams on MAC1
+ */
+struct dbs_nss {
+	enum hw_mode_ss_config mac0_ss;
+	enum hw_mode_ss_config mac1_ss;
+};
+
+/**
+ * struct connection_info - connection information
+ * @mac_id: The HW mac it is running
+ * @vdev_id: vdev id
+ * @channel: channel of the connection
+ */
+struct connection_info {
+	uint8_t mac_id;
+	uint8_t vdev_id;
+	uint8_t channel;
+};
+#endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */

+ 181 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h

@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __WLAN_POLICY_MGR_UCFG
+#define __WLAN_POLICY_MGR_UCFG
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_global_obj.h"
+#include "qdf_status.h"
+
+
+/**
+ * ucfg_policy_mgr_psoc_open() - This API sets CFGs to policy manager context
+ *
+ * This API pulls policy manager's context from PSOC and initialize the CFG
+ * structure of policy manager.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc);
+/**
+ * ucfg_policy_mgr_psoc_close() - This API resets CFGs for policy manager ctx
+ *
+ * This API pulls policy manager's context from PSOC and resets the CFG
+ * structure of policy manager.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+void ucfg_policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * ucfg_policy_mgr_get_mcc_scc_switch() - To mcc to scc switch setting from INI
+ * @psoc: pointer to psoc
+ * @mcc_scc_switch: value to be filled
+ *
+ * This API pulls mcc to scc switch setting which is given as part of INI and
+ * stored in policy manager's CFGs.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *mcc_scc_switch);
+#else
+static inline
+QDF_STATUS ucfg_policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *mcc_scc_switch)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif //FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * ucfg_policy_mgr_get_sys_pref() - to get system preference
+ * @psoc: pointer to psoc
+ * @sys_pref: value to be filled
+ *
+ * This API pulls the system preference for policy manager to provide
+ * PCL
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc,
+					uint8_t *sys_pref);
+/**
+ * ucfg_policy_mgr_set_sys_pref() - to set system preference
+ * @psoc: pointer to psoc
+ * @sys_pref: value to be applied as new INI setting
+ *
+ * This API is meant to override original INI setting for system pref
+ * with new value which is used by policy manager to provide PCL
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc,
+					uint8_t sys_pref);
+/**
+ * ucfg_policy_mgr_get_max_conc_cxns() - to get max num of conc connections
+ * @psoc: pointer to psoc
+ * @max_conc_cxns: value to be filled
+ *
+ * This API pulls max number of active connections which can be allowed
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
+						uint8_t *max_conc_cxns);
+/**
+ * ucfg_policy_mgr_get_conc_rule1() - to find out if conc rule1 is enabled
+ * @psoc: pointer to psoc
+ * @conc_rule1: value to be filled
+ *
+ * This API is used to find out if conc rule-1 is enabled by user
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc,
+						uint8_t *conc_rule1);
+/**
+ * ucfg_policy_mgr_get_conc_rule2() - to find out if conc rule2 is enabled
+ * @psoc: pointer to psoc
+ * @conc_rule2: value to be filled
+ *
+ * This API is used to find out if conc rule-2 is enabled by user
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc,
+						uint8_t *conc_rule2);
+/**
+ * ucfg_policy_mgr_get_dbs_selection_plcy() - DBS HW mode selection setting
+ * @psoc: pointer to psoc
+ * @dbs_selection_plcy: value to be filled
+ *
+ * This API is used to find out DBS HW mode preference.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc,
+						uint32_t *dbs_selection_plcy);
+/**
+ * ucfg_policy_mgr_get_vdev_priority_list() - to get vdev priority list
+ * @psoc: pointer to psoc
+ * @vdev_priority_list: value to be filled
+ *
+ * This API is used to find out vdev_priority_list setting
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc,
+						uint32_t *vdev_priority_list);
+/**
+ * policy_mgr_get_chnl_select_plcy() - to get channel selection policy
+ * @psoc: pointer to psoc
+ * @chnl_select_plcy: value to be filled
+ *
+ * This API is used to find out which channel selection policy has been
+ * configured
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc,
+						uint32_t *chnl_select_plcy);
+/**
+ * policy_mgr_get_mcc_adaptive_sch() - to get mcc adaptive scheduler
+ * @psoc: pointer to psoc
+ * @enable_mcc_adaptive_sch: value to be filled
+ *
+ * This API is used to find out if mcc adaptive scheduler enabled or disabled
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+ucfg_policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *enable_mcc_adaptive_sch);
+
+/**
+ * ucfg_policy_mgr_get_sta_cxn_5g_band() - to get STA's connection in 5G config
+ *
+ * @psoc: pointer to psoc
+ * @enable_sta_cxn_5g_band: value to be filled
+ *
+ * This API is used to find out if STA connection in 5G band is allowed or
+ * disallowed.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc,
+					       uint8_t *enable_sta_cxn_5g_band);
+#endif //__WLAN_POLICY_MGR_UCFG

+ 2183 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -0,0 +1,2183 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_policy_mgr_action.c
+ *
+ * WLAN Concurrenct Connection Management APIs
+ *
+ */
+
+/* Include files */
+
+#include "wlan_policy_mgr_api.h"
+#include "wlan_policy_mgr_tables_no_dbs_i.h"
+#include "wlan_policy_mgr_i.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_objmgr_global_obj.h"
+#include "qdf_platform.h"
+
+enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr)
+	(struct wlan_objmgr_psoc *psoc);
+
+void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index,
+			uint32_t new_hw_mode_index,
+			uint32_t num_vdev_mac_entries,
+			struct policy_mgr_vdev_mac_map *vdev_mac_map,
+			struct wlan_objmgr_psoc *context)
+{
+	QDF_STATUS status;
+	struct policy_mgr_hw_mode_params hw_mode;
+	uint32_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(context);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+
+	if (!vdev_mac_map) {
+		policy_mgr_err("vdev_mac_map is NULL");
+		return;
+	}
+
+	policy_mgr_debug("old_hw_mode_index=%d, new_hw_mode_index=%d",
+		old_hw_mode_index, new_hw_mode_index);
+
+	for (i = 0; i < num_vdev_mac_entries; i++)
+		policy_mgr_debug("vdev_id:%d mac_id:%d",
+			vdev_mac_map[i].vdev_id,
+			vdev_mac_map[i].mac_id);
+
+	status = policy_mgr_get_hw_mode_from_idx(context,
+				new_hw_mode_index, &hw_mode);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Get HW mode failed: %d", status);
+		return;
+	}
+
+	policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d band_cap:%d",
+			 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
+			 hw_mode.mac0_bw, hw_mode.mac0_band_cap);
+	policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d",
+			 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
+			 hw_mode.mac1_bw);
+	policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d",
+			 hw_mode.dbs_cap, hw_mode.agile_dfs_cap,
+			 hw_mode.sbs_cap);
+
+	/* update pm_conc_connection_list */
+	policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries,
+					  vdev_mac_map,
+					  hw_mode);
+
+	if (pm_ctx->mode_change_cb)
+		pm_ctx->mode_change_cb();
+
+	return;
+}
+
+QDF_STATUS policy_mgr_check_n_start_opportunistic_timer(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (policy_mgr_need_opportunistic_upgrade(psoc, NULL)) {
+	/* let's start the timer */
+	qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
+	status = qdf_mc_timer_start(
+				&pm_ctx->dbs_opportunistic_timer,
+				DBS_OPPORTUNISTIC_TIME * 1000);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		policy_mgr_err("Failed to start dbs opportunistic timer");
+	}
+	return status;
+}
+
+QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
+		uint32_t session_id,
+		enum hw_mode_ss_config mac0_ss,
+		enum hw_mode_bandwidth mac0_bw,
+		enum hw_mode_ss_config mac1_ss,
+		enum hw_mode_bandwidth mac1_bw,
+		enum hw_mode_mac_band_cap mac0_band_cap,
+		enum hw_mode_dbs_capab dbs,
+		enum hw_mode_agile_dfs_capab dfs,
+		enum hw_mode_sbs_capab sbs,
+		enum policy_mgr_conn_update_reason reason,
+		uint8_t next_action)
+{
+	int8_t hw_mode_index;
+	struct policy_mgr_hw_mode msg;
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't
+	 * allow to request FW for 2x2
+	 */
+	if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) {
+		policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0");
+		mac0_ss = HW_MODE_SS_1x1;
+	}
+	if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) {
+		policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1");
+		mac1_ss = HW_MODE_SS_1x1;
+	}
+
+	hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc,
+			mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap,
+			dbs, dfs, sbs);
+	if (hw_mode_index < 0) {
+		policy_mgr_err("Invalid HW mode index obtained");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	msg.hw_mode_index = hw_mode_index;
+	msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb;
+	msg.reason = reason;
+	msg.session_id = session_id;
+	msg.next_action = next_action;
+	msg.context = psoc;
+
+	policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d",
+		msg.hw_mode_index, msg.session_id, msg.reason);
+
+	status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to set hw mode to SME");
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
+		struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_conn_update_reason *reason)
+{
+	uint32_t conn_index;
+	enum policy_mgr_conc_next_action upgrade = PM_NOP;
+	enum policy_mgr_conc_next_action preferred_dbs_action;
+	uint8_t mac = 0;
+	struct policy_mgr_hw_mode_params hw_mode;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		goto exit;
+	}
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
+		policy_mgr_err("driver isn't dbs capable, no further action needed");
+		goto exit;
+	}
+
+	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
+		goto exit;
+	}
+	if (!hw_mode.dbs_cap) {
+		policy_mgr_debug("current HW mode is non-DBS capable");
+		goto exit;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	/* Are both mac's still in use */
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		conn_index++) {
+		policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
+			conn_index,
+			pm_conc_connection_list[conn_index].mac,
+			pm_conc_connection_list[conn_index].in_use,
+			pm_conc_connection_list[conn_index].chan,
+			pm_conc_connection_list[conn_index].original_nss);
+		if ((pm_conc_connection_list[conn_index].mac == 0) &&
+			pm_conc_connection_list[conn_index].in_use) {
+			mac |= POLICY_MGR_MAC0;
+			if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				goto done;
+			}
+		} else if ((pm_conc_connection_list[conn_index].mac == 1) &&
+			pm_conc_connection_list[conn_index].in_use) {
+			mac |= POLICY_MGR_MAC1;
+			if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
+			    WLAN_REG_IS_24GHZ_CH(
+				    pm_conc_connection_list[conn_index].chan)
+			    ) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection");
+				goto done;
+			}
+			if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				goto done;
+			}
+		}
+	}
+	/* Let's request for single MAC mode */
+	upgrade = PM_SINGLE_MAC;
+	if (reason)
+		*reason = POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC;
+	/* Is there any connection had an initial connection with 2x2 */
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		conn_index++) {
+		if ((pm_conc_connection_list[conn_index].original_nss == 2) &&
+			pm_conc_connection_list[conn_index].in_use) {
+			upgrade = PM_SINGLE_MAC_UPGRADE;
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			goto done;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+done:
+	if (upgrade == PM_NOP && hw_mode.dbs_cap &&
+	    policy_mgr_is_2x2_1x1_dbs_capable(psoc)) {
+		preferred_dbs_action =
+			policy_mgr_get_preferred_dbs_action_table(
+					psoc, INVALID_VDEV_ID, 0, 0);
+		if (hw_mode.action_type == PM_DBS1 &&
+		    preferred_dbs_action == PM_DBS2) {
+			upgrade = PM_DBS2_DOWNGRADE;
+			if (reason)
+				*reason =
+				POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE;
+		} else if (hw_mode.action_type == PM_DBS2 &&
+		    preferred_dbs_action == PM_DBS1) {
+			upgrade = PM_DBS1_DOWNGRADE;
+			if (reason)
+				*reason =
+				POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE;
+		}
+	}
+exit:
+	return upgrade;
+}
+
+QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
+					uint32_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t conn_index = 0;
+	bool found = false;
+	struct policy_mgr_vdev_entry_info conn_table_entry;
+	enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
+	uint8_t nss_2g, nss_5g;
+	enum policy_mgr_con_mode mode;
+	uint8_t chan;
+	uint32_t nss = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
+			/* debug msg */
+			found = true;
+			break;
+		}
+		conn_index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (!found) {
+		/* err msg */
+		policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
+			vdev_id);
+		return status;
+	}
+	if (pm_ctx->wma_cbacks.wma_get_connection_info) {
+		status = pm_ctx->wma_cbacks.wma_get_connection_info(
+				vdev_id, &conn_table_entry);
+		if (QDF_STATUS_SUCCESS != status) {
+			policy_mgr_err("can't find vdev_id %d in connection table",
+			vdev_id);
+			return status;
+		}
+	} else {
+		policy_mgr_err("wma_get_connection_info is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mode = policy_mgr_get_mode(conn_table_entry.type,
+					conn_table_entry.sub_type);
+	chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz);
+	status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) ||
+			(WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1)))
+			chain_mask = POLICY_MGR_TWO_TWO;
+		else
+			chain_mask = POLICY_MGR_ONE_ONE;
+		nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g;
+	} else {
+		policy_mgr_err("Error in getting nss");
+	}
+
+	policy_mgr_debug("update PM connection table for vdev:%d", vdev_id);
+
+	/* add the entry */
+	policy_mgr_update_conc_list(psoc, conn_index,
+			mode,
+			chan,
+			policy_mgr_get_bw(conn_table_entry.chan_width),
+			conn_table_entry.mac_id,
+			chain_mask,
+			nss, vdev_id, true, true);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t session_id,
+		uint8_t channel,
+		enum policy_mgr_conn_update_reason reason)
+{
+	QDF_STATUS status;
+
+	policy_mgr_debug("session:%d channel:%d reason:%d",
+		session_id, channel, reason);
+
+	status = policy_mgr_reset_connection_update(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		policy_mgr_err("clearing event failed");
+
+	status = policy_mgr_current_connections_update(psoc,
+				session_id, channel, reason);
+	if (QDF_STATUS_E_FAILURE == status) {
+		policy_mgr_err("connections update failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Wait only when status is success */
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = policy_mgr_wait_for_connection_update(psoc);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			policy_mgr_err("qdf wait for event failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
+ * concurreny
+ * @new_conn_mode: new connection mode
+ *
+ * When a new connection is about to come up, check if dbs is allowed for
+ * STA+STA or STA+P2P
+ *
+ * Return: true if dbs is allowed for STA+STA or STA+P2P else false
+ */
+bool policy_mgr_is_dbs_allowed_for_concurrency(
+		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p;
+	bool ret = true;
+	uint32_t ch_sel_plcy;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return ret;
+	}
+
+	count = policy_mgr_get_connection_count(psoc);
+
+	if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE)
+		return ret;
+
+	ch_sel_plcy = pm_ctx->cfg.chnl_select_plcy;
+	dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(ch_sel_plcy);
+	dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(ch_sel_plcy);
+
+	switch (pm_conc_connection_list[0].mode) {
+	case PM_STA_MODE:
+		switch (new_conn_mode) {
+		case QDF_STA_MODE:
+			if (!dbs_for_sta_sta)
+				return false;
+			break;
+		case QDF_P2P_DEVICE_MODE:
+		case QDF_P2P_CLIENT_MODE:
+		case QDF_P2P_GO_MODE:
+			if (!dbs_for_sta_p2p)
+				return false;
+			break;
+		default:
+			break;
+		}
+		break;
+	case PM_P2P_CLIENT_MODE:
+	case PM_P2P_GO_MODE:
+		switch (new_conn_mode) {
+		case QDF_STA_MODE:
+			if (!dbs_for_sta_p2p)
+				return false;
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
+					    uint8_t channel)
+{
+	uint8_t i, pm_chnl;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	/*
+	 * check given channel against already existing connections'
+	 * channels. if they differ then channels are in different bands
+	 */
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		pm_chnl = pm_conc_connection_list[i].chan;
+		if (pm_conc_connection_list[i].in_use)
+			if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_chnl)) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				policy_mgr_debug("channel is in diff band");
+				return true;
+			}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return false;
+}
+
+bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
+					     uint8_t channel)
+{
+	enum policy_mgr_band band;
+	bool is_hwmode_dbs, is_2x2_dbs;
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) == false)
+		return true;
+
+	if (WLAN_REG_IS_24GHZ_CH(channel))
+		band = POLICY_MGR_BAND_24;
+	else
+		band = POLICY_MGR_BAND_5;
+
+	is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
+	is_2x2_dbs = policy_mgr_is_hw_dbs_2x2_capable(psoc);
+	/*
+	 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not
+	 * yet set then this is the right time to block the connection.
+	 */
+	if ((band == POLICY_MGR_BAND_24) && is_2x2_dbs && !is_hwmode_dbs) {
+		policy_mgr_err("HW mode is not yet in DBS!!!!!");
+		return false;
+	}
+
+	/*
+	 * If HW supports 1x1 chains DBS HW mode and if first connection is
+	 * 2G or 5G band and if second connection is coming up in diffrent
+	 * band than the first connection and if current HW mode is not yet
+	 * set in DBS then this is the right time to block the connection.
+	 */
+	if (policy_mgr_is_chnl_in_diff_band(psoc, channel) && !is_hwmode_dbs) {
+		policy_mgr_err("Given channel & existing conn is diff band & HW mode is not yet in DBS !!!!");
+		return false;
+	}
+
+	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->cfg.dbs_selection_plcy) == 1)
+		band_pref_5g = false;
+
+	if (PM_GET_VDEV_PRIORITY_ENABLED(
+	    pm_ctx->cfg.dbs_selection_plcy) == 1 &&
+	    pm_ctx->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->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,
+		enum policy_mgr_conn_update_reason reason)
+{
+	enum policy_mgr_conc_next_action next_action = PM_NOP;
+	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;
+	enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
+		policy_mgr_err("driver isn't dbs capable, no further action needed");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+	if (WLAN_REG_IS_24GHZ_CH(channel))
+		band = POLICY_MGR_BAND_24;
+	else
+		band = POLICY_MGR_BAND_5;
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+
+	policy_mgr_debug("num_connections=%d channel=%d",
+		num_connections, channel);
+
+	switch (num_connections) {
+	case 0:
+		if (band == POLICY_MGR_BAND_24)
+			if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
+				next_action = PM_DBS;
+			else
+				next_action = PM_NOP;
+		else
+			next_action = PM_NOP;
+		break;
+	case 1:
+		second_index =
+			policy_mgr_get_second_connection_pcl_table_index(psoc);
+		if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
+			policy_mgr_err(
+			"couldn't find index for 2nd connection next action table");
+			goto done;
+		}
+		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 =
+			policy_mgr_get_third_connection_pcl_table_index(psoc);
+		if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
+			policy_mgr_err(
+			"couldn't find index for 3rd connection next action table");
+			goto done;
+		}
+		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",
+			num_connections);
+		break;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		goto done;
+	}
+
+	if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
+		new_conn_mode = pm_ctx->hdd_cbacks.
+					hdd_get_device_mode(session_id);
+
+	/*
+	 * Based on channel_select_logic_conc ini, hw mode is set
+	 * when second connection is about to come up that results
+	 * in STA+STA and STA+P2P concurrency.
+	 * 1) If MCC is set and if current hw mode is dbs, hw mode
+	 *  should be set to single mac for above concurrency.
+	 * 2) If MCC is set and if current hw mode is not dbs, hw
+	 *  mode change is not required.
+	 */
+	if (policy_mgr_is_current_hwmode_dbs(psoc) &&
+		!policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
+		next_action = PM_SINGLE_MAC;
+	else if (!policy_mgr_is_current_hwmode_dbs(psoc) &&
+		!policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
+		next_action = PM_NOP;
+
+	if (PM_NOP != next_action)
+		status = policy_mgr_next_actions(psoc, session_id,
+						next_action, reason);
+	else
+		status = QDF_STATUS_E_NOSUPPORT;
+
+	policy_mgr_debug(
+		"idx2=%d idx3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d",
+		second_index, third_index, next_action, band, status,
+		reason, session_id);
+
+done:
+	return status;
+}
+
+/**
+ * policy_mgr_validate_dbs_switch() - Check DBS action valid or not
+ * @psoc: Pointer to psoc
+ * @session_id: vdev id
+ * @action: action requested
+ * @reason: reason of hw mode change
+ *
+ * This routine will check the current hw mode with requested action.
+ * If we are already in the mode, the caller will do nothing.
+ * This will be called by policy_mgr_next_actions to check the action needed
+ * or not.
+ *
+ * return : QDF_STATUS_SUCCESS, action is allowed.
+ *          QDF_STATUS_E_ALREADY, action is not needed.
+ *          QDF_STATUS_E_FAILURE, error happens.
+ *          QDF_STATUS_E_NOSUPPORT, the requested mode not supported.
+ */
+static
+QDF_STATUS policy_mgr_validate_dbs_switch(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t session_id,
+		enum policy_mgr_conc_next_action action,
+		enum policy_mgr_conn_update_reason reason)
+{
+	QDF_STATUS status;
+	struct policy_mgr_hw_mode_params hw_mode;
+
+	/* check for the current HW index to see if really need any action */
+	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
+		return status;
+	}
+
+	if (hw_mode.sbs_cap) {
+		if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) {
+			if (!policy_mgr_is_hw_sbs_capable(psoc)) {
+				/* No action */
+				policy_mgr_notice("firmware is not sbs capable");
+				return QDF_STATUS_E_NOSUPPORT;
+			}
+			/* current mode is already SBS nothing to be
+			 * done
+			 */
+			 policy_mgr_notice("current mode is already SBS");
+			return QDF_STATUS_E_ALREADY;
+		} else {
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	if (!hw_mode.dbs_cap) {
+		if (action == PM_SINGLE_MAC ||
+		    action == PM_SINGLE_MAC_UPGRADE) {
+			policy_mgr_notice("current mode is already single MAC");
+			return QDF_STATUS_E_ALREADY;
+		} else {
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	/**
+	 * If already in DBS, no need to request DBS again (HL, Napier).
+	 * For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1
+	 * switching, we need to check the current DBS mode is same as
+	 * requested or not.
+	 */
+	if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
+	    policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
+		policy_mgr_info("curr dbs action %d new action %d",
+				hw_mode.action_type, action);
+		if (hw_mode.action_type == PM_DBS1 &&
+		    ((action == PM_DBS1 ||
+		    action == PM_DBS1_DOWNGRADE))) {
+			policy_mgr_err("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed",
+				       hw_mode.action_type, action);
+			return QDF_STATUS_E_ALREADY;
+		} else if (hw_mode.action_type == PM_DBS2 &&
+			   ((action == PM_DBS2 ||
+			   action == PM_DBS2_DOWNGRADE))) {
+			policy_mgr_err("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed",
+				       hw_mode.action_type, action);
+			return QDF_STATUS_E_ALREADY;
+		}
+	} else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) ||
+		   (action == PM_DBS_UPGRADE)) {
+		policy_mgr_err("driver is already in %s mode, no further action needed",
+			       (hw_mode.dbs_cap) ? "dbs" : "non dbs");
+		return QDF_STATUS_E_ALREADY;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_next_actions(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t session_id,
+		enum policy_mgr_conc_next_action action,
+		enum policy_mgr_conn_update_reason reason)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct dbs_nss nss_dbs = {0};
+	struct policy_mgr_hw_mode_params hw_mode;
+	enum policy_mgr_conc_next_action next_action;
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
+		policy_mgr_err("driver isn't dbs capable, no further action needed");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	/* check for the current HW index to see if really need any action */
+	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
+		return status;
+	}
+
+	/* check for the current HW index to see if really need any action */
+	status = policy_mgr_validate_dbs_switch(psoc, session_id, action,
+						reason);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err(" not take action %d reason %d session %d status %d",
+			       action, reason, session_id, status);
+		return status;
+	}
+
+	switch (action) {
+	case PM_DBS_DOWNGRADE:
+		/*
+		* check if we have a beaconing entity that is using 2x2. If yes,
+		* update the beacon template & notify FW. Once FW confirms
+		*  beacon updated, send down the HW mode change req
+		*/
+		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
+					PM_DBS, reason, session_id);
+		break;
+	case PM_DBS:
+		(void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
+
+		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
+						     nss_dbs.mac0_ss,
+						     HW_MODE_80_MHZ,
+						     nss_dbs.mac1_ss,
+						     HW_MODE_40_MHZ,
+						     HW_MODE_MAC_BAND_NONE,
+						     HW_MODE_DBS,
+						     HW_MODE_AGILE_DFS_NONE,
+						     HW_MODE_SBS_NONE,
+						     reason, PM_NOP);
+		break;
+	case PM_SINGLE_MAC_UPGRADE:
+		/*
+		 * change the HW mode first before the NSS upgrade
+		 */
+		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
+						HW_MODE_SS_2x2,
+						HW_MODE_80_MHZ,
+						HW_MODE_SS_0x0, HW_MODE_BW_NONE,
+						HW_MODE_MAC_BAND_NONE,
+						HW_MODE_DBS_NONE,
+						HW_MODE_AGILE_DFS_NONE,
+						HW_MODE_SBS_NONE,
+						reason, PM_UPGRADE);
+		break;
+	case PM_SINGLE_MAC:
+		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
+						HW_MODE_SS_2x2,
+						HW_MODE_80_MHZ,
+						HW_MODE_SS_0x0, HW_MODE_BW_NONE,
+						HW_MODE_MAC_BAND_NONE,
+						HW_MODE_DBS_NONE,
+						HW_MODE_AGILE_DFS_NONE,
+						HW_MODE_SBS_NONE,
+						reason, PM_NOP);
+		break;
+	case PM_DBS_UPGRADE:
+		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
+						HW_MODE_SS_2x2,
+						HW_MODE_80_MHZ,
+						HW_MODE_SS_2x2, HW_MODE_80_MHZ,
+						HW_MODE_MAC_BAND_NONE,
+						HW_MODE_DBS,
+						HW_MODE_AGILE_DFS_NONE,
+						HW_MODE_SBS_NONE,
+						reason, PM_UPGRADE);
+		break;
+	case PM_SBS_DOWNGRADE:
+		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
+					PM_SBS, reason, session_id);
+		break;
+	case PM_SBS:
+		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
+						HW_MODE_SS_1x1,
+						HW_MODE_80_MHZ,
+						HW_MODE_SS_1x1, HW_MODE_80_MHZ,
+						HW_MODE_MAC_BAND_NONE,
+						HW_MODE_DBS,
+						HW_MODE_AGILE_DFS_NONE,
+						HW_MODE_SBS,
+						reason, PM_NOP);
+		break;
+	case PM_DOWNGRADE:
+		/*
+		 * check if we have a beaconing entity that advertised 2x2
+		 * intially. If yes, update the beacon template & notify FW.
+		 */
+		status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1,
+					PM_NOP, POLICY_MGR_ANY, reason,
+					session_id);
+		break;
+	case PM_UPGRADE:
+		/*
+		 * check if we have a beaconing entity that advertised 2x2
+		 * intially. If yes, update the beacon template & notify FW.
+		 */
+		status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
+					PM_NOP, POLICY_MGR_ANY, reason,
+					session_id);
+		break;
+	case PM_DBS1_DOWNGRADE:
+		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
+						    PM_DBS1, reason,
+						    session_id);
+		break;
+	case PM_DBS2_DOWNGRADE:
+		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
+						    PM_DBS2, reason,
+						    session_id);
+		break;
+	case PM_DBS1:
+		/*
+		 * PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous
+		 * mode is DBS, that should be 2x2 2G + 1x1 5G mode and
+		 * the 5G band was downgraded to 1x1. So, we need to
+		 * upgrade 5G vdevs after hw mode change.
+		 */
+		if (hw_mode.dbs_cap)
+			next_action = PM_UPGRADE_5G;
+		else
+			next_action = PM_NOP;
+		status = policy_mgr_pdev_set_hw_mode(
+					psoc, session_id,
+					HW_MODE_SS_2x2,
+					HW_MODE_80_MHZ,
+					HW_MODE_SS_1x1, HW_MODE_40_MHZ,
+					HW_MODE_MAC_BAND_5G,
+					HW_MODE_DBS,
+					HW_MODE_AGILE_DFS_NONE,
+					HW_MODE_SBS_NONE,
+					reason, next_action);
+		break;
+	case PM_DBS2:
+		/*
+		 * PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous
+		 * mode is DBS, that should be 2x2 5G + 1x1 2G mode and
+		 * the 2G band was downgraded to 1x1. So, we need to
+		 * upgrade 5G vdevs after hw mode change.
+		 */
+		if (hw_mode.dbs_cap)
+			next_action = PM_UPGRADE_2G;
+		else
+			next_action = PM_NOP;
+		status = policy_mgr_pdev_set_hw_mode(
+						psoc, session_id,
+						HW_MODE_SS_2x2,
+						HW_MODE_40_MHZ,
+						HW_MODE_SS_1x1, HW_MODE_40_MHZ,
+						HW_MODE_MAC_BAND_2G,
+						HW_MODE_DBS,
+						HW_MODE_AGILE_DFS_NONE,
+						HW_MODE_SBS_NONE,
+						reason, next_action);
+		break;
+	case PM_UPGRADE_5G:
+		status = policy_mgr_nss_update(
+					psoc, POLICY_MGR_RX_NSS_2,
+					PM_NOP, POLICY_MGR_BAND_5, reason,
+					session_id);
+		break;
+	case PM_UPGRADE_2G:
+		status = policy_mgr_nss_update(
+					psoc, POLICY_MGR_RX_NSS_2,
+					PM_NOP, POLICY_MGR_BAND_24, reason,
+					session_id);
+		break;
+	default:
+		policy_mgr_err("unexpected action value %d", action);
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc,
+		uint8_t session_id, uint8_t channel)
+{
+	QDF_STATUS status;
+
+	if (!policy_mgr_check_for_session_conc(psoc, session_id, channel)) {
+		policy_mgr_err("Conc not allowed for the session %d",
+			session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = policy_mgr_reset_connection_update(psoc);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		policy_mgr_err("clearing event failed");
+
+	status = policy_mgr_current_connections_update(psoc, session_id,
+			channel,
+			POLICY_MGR_UPDATE_REASON_NORMAL_STA);
+	if (QDF_STATUS_E_FAILURE == status) {
+		policy_mgr_err("connections update failed");
+		return status;
+	}
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+void policy_mgr_update_user_config_sap_chan(
+			struct wlan_objmgr_psoc *psoc, uint32_t channel)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context and failed to update the user config sap channel");
+		return;
+	}
+	pm_ctx->user_config_sap_channel = channel;
+}
+
+/**
+ * policy_mgr_is_restart_sap_allowed() - Check if restart SAP
+ * allowed during SCC -> MCC switch
+ * @psoc: PSOC object data
+ * @mcc_to_scc_switch: MCC to SCC switch enabled user config
+ *
+ * Check if restart SAP allowed during SCC->MCC switch
+ *
+ * Restart: true or false
+ */
+static bool policy_mgr_is_restart_sap_allowed(
+	struct wlan_objmgr_psoc *psoc,
+	uint32_t mcc_to_scc_switch)
+{
+	uint32_t sta_ap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK;
+	uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK;
+
+	if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
+		!policy_mgr_concurrent_open_sessions_running(psoc) ||
+		!(((policy_mgr_get_concurrency_mode(psoc) & sta_ap_bit_mask)
+			== sta_ap_bit_mask) ||
+		((mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
+		((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask)
+			== sta_go_bit_mask)))) {
+		policy_mgr_debug("MCC switch disabled or not concurrent STA/SAP, STA/GO");
+		return false;
+	}
+
+	return true;
+}
+
+bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
+		uint8_t channel)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool is_safe = true;
+	uint8_t j;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return is_safe;
+	}
+
+
+	if (pm_ctx->unsafe_channel_count == 0) {
+		policy_mgr_debug("There are no unsafe channels");
+		return is_safe;
+	}
+
+	for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
+		if (channel == pm_ctx->unsafe_channel_list[j]) {
+			is_safe = false;
+			policy_mgr_warn("CH %d is not safe", channel);
+			break;
+		}
+	}
+
+	return is_safe;
+}
+
+bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
+			struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc,
+								PM_SAP_MODE);
+	bool sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+
+	*intf_ch = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return false;
+	}
+
+	policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u",
+			 sta_sap_scc_on_dfs_chan, sap_chan);
+
+	if ((!sta_sap_scc_on_dfs_chan ||
+	     !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) &&
+	       (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) ==
+			CHANNEL_STATE_DFS))) &&
+	    (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
+	      policy_mgr_is_safe_channel(psoc, sap_chan))) {
+		return false;
+	}
+
+	*intf_ch = pm_ctx->user_config_sap_channel;
+	policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u",
+			 *intf_ch);
+
+	return true;
+}
+
+static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
+	struct sta_ap_intf_check_work_ctx *work_info = NULL;
+	uint32_t mcc_to_scc_switch, cc_count = 0, i;
+	QDF_STATUS status;
+	uint8_t channel, sec_ch;
+	uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
+
+	if (qdf_is_module_state_transitioning()) {
+		policy_mgr_err("Module transition in progress");
+		goto end;
+	}
+
+	work_info = (struct sta_ap_intf_check_work_ctx *) data;
+	if (!work_info) {
+		policy_mgr_err("Invalid work_info");
+		goto end;
+	}
+
+	psoc = work_info->psoc;
+	if (!psoc) {
+		policy_mgr_err("Invalid psoc");
+		goto end;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		goto end;
+	}
+	mcc_to_scc_switch =
+		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
+
+	policy_mgr_info("Concurrent open sessions running: %d",
+		policy_mgr_concurrent_open_sessions_running(psoc));
+
+	if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch))
+		goto end;
+
+	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
+					&operating_channel[cc_count],
+					&vdev_id[cc_count],
+					PM_SAP_MODE);
+	policy_mgr_debug("Number of concurrent SAP: %d", cc_count);
+	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
+		cc_count = cc_count +
+				policy_mgr_get_mode_specific_conn_info
+					(psoc,
+					&operating_channel[cc_count],
+					&vdev_id[cc_count],
+					PM_P2P_GO_MODE);
+	policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
+							cc_count);
+	if (!cc_count) {
+		policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
+		goto end;
+	}
+
+	policy_mgr_debug("wait if channel switch is already in progress");
+	status = qdf_wait_single_event(
+				&pm_ctx->channel_switch_complete_evt,
+				CHANNEL_SWITCH_COMPLETE_TIMEOUT);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("wait for event failed, still continue with channel switch");
+	}
+	if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
+		policy_mgr_err("SAP restart get channel callback in NULL");
+		goto end;
+	}
+	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
+		for (i = 0; i < cc_count; i++) {
+			status = pm_ctx->hdd_cbacks.
+				wlan_hdd_get_channel_for_sap_restart
+					(psoc,
+					vdev_id[i], &channel, &sec_ch);
+			if (status == QDF_STATUS_SUCCESS) {
+				policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d"
+					, operating_channel[i], channel);
+				break;
+			}
+		}
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to switch SAP channel");
+end:
+	if (work_info) {
+		qdf_mem_free(work_info);
+		if (pm_ctx)
+			pm_ctx->sta_ap_intf_check_work_info = NULL;
+	}
+}
+
+void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
+{
+	qdf_ssr_protect(__func__);
+	__policy_mgr_check_sta_ap_concurrent_ch_intf(data);
+	qdf_ssr_unprotect(__func__);
+}
+
+static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
+		uint8_t sta_channel)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return false;
+	}
+
+	if ((wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) &&
+		(!policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))) ||
+		wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) ||
+		!policy_mgr_is_safe_channel(psoc, sta_channel)) {
+		if (policy_mgr_is_hw_dbs_capable(psoc))
+			return true;
+		else
+			return false;
+	}
+	else
+		return true;
+}
+
+QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
+	struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch)
+{
+	uint8_t channel = *con_ch;
+	uint8_t temp_channel = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool sta_sap_scc_on_dfs_chan;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * if force SCC is set, Check if conc channel is DFS
+	 * or passive or part of LTE avoided channel list.
+	 * In that case move SAP to other band if DBS is supported,
+	 * return otherwise
+	 */
+	if (!policy_mgr_is_force_scc(psoc))
+		return QDF_STATUS_SUCCESS;
+
+	/*
+	 * if interference is 0, check if it is DBS case. If DBS case
+	 * return from here. If SCC, check further if SAP can move to
+	 * STA's channel.
+	 */
+	if (!channel &&
+		(sap_ch != policy_mgr_mode_specific_get_channel(
+			psoc, PM_STA_MODE)))
+		return QDF_STATUS_SUCCESS;
+	else if (!channel)
+		channel = sap_ch;
+
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+
+	if (policy_mgr_valid_sta_channel_check(psoc, channel)) {
+		if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) ||
+		    wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, channel) ||
+		    !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
+		      policy_mgr_is_safe_channel(psoc, channel)) ||
+		    (!reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx->pdev)
+		    && reg_is_etsi13_srd_chan(pm_ctx->pdev, channel))) {
+			if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) &&
+			    sta_sap_scc_on_dfs_chan) {
+				policy_mgr_debug("STA SAP SCC is allowed on DFS channel");
+				goto update_chan;
+			}
+
+			if (policy_mgr_is_hw_dbs_capable(psoc)) {
+				temp_channel =
+				policy_mgr_get_alternate_channel_for_sap(psoc);
+				policy_mgr_debug("temp_channel is %d",
+					temp_channel);
+				if (temp_channel) {
+					channel = temp_channel;
+				} else {
+					if (WLAN_REG_IS_5GHZ_CH(channel))
+						channel = PM_24_GHZ_CHANNEL_6;
+					else
+						channel = PM_5_GHZ_CHANNEL_36;
+				}
+				if (!policy_mgr_is_safe_channel(
+					psoc, channel)) {
+					policy_mgr_warn(
+						"Can't have concurrency on %d as it is not safe",
+						channel);
+					return QDF_STATUS_E_FAILURE;
+				}
+			} else {
+				policy_mgr_warn("Can't have concurrency on %d",
+					channel);
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
+	}
+
+update_chan:
+	if (channel != sap_ch)
+		*con_ch = channel;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
+ * concurrent change intf
+ * @psoc: PSOC object information
+ * @operation_channel: operation channel
+ * @vdev_id: vdev id of SAP
+ *
+ * Checks the concurrent change interface and restarts SAP
+ *
+ * Return: None
+ */
+void policy_mgr_check_concurrent_intf_and_restart_sap(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t mcc_to_scc_switch;
+	uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint32_t cc_count = 0;
+	bool restart_sap = false;
+	uint8_t sap_ch;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+	if (policy_mgr_get_connection_count(psoc) == 1) {
+		/*
+		 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
+		 * enabled on DFS channel then move the SAP out of DFS channel
+		 * as soon as STA gets disconnect.
+		 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is
+		 * enabled on unsafe channel then move the SAP to safe channel
+		 * as soon as STA disconnected.
+		 */
+		if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
+							psoc, &sap_ch)) {
+			policy_mgr_debug("move the SAP to configured channel %u",
+					 sap_ch);
+			restart_sap = true;
+			goto sap_restart;
+		}
+	}
+
+	/*
+	 * force SCC with STA+STA+SAP will need some additional logic
+	 */
+	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
+					&operating_channel[cc_count],
+					&vdev_id[cc_count], PM_STA_MODE);
+	if (!cc_count) {
+		policy_mgr_debug("Could not get STA operating channel&vdevid");
+		return;
+	}
+
+	mcc_to_scc_switch =
+		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
+	policy_mgr_info("MCC to SCC switch: %d chan: %d",
+			mcc_to_scc_switch, operating_channel[0]);
+
+	if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) {
+		policy_mgr_debug(
+			"No action taken at check_concurrent_intf_and_restart_sap");
+		return;
+	}
+
+sap_restart:
+	/*
+	 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not
+	 * allowed on DFS channel. SAP is allowed on DFS channel only when STA
+	 * is already connected on that channel.
+	 * In following condition restart_sap will be true if
+	 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel.
+	 * This scenario can come if STA+SAP are operating on DFS channel and
+	 * STA gets disconnected.
+	 */
+	if (restart_sap ||
+	    ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
+	    policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) &&
+	    !pm_ctx->sta_ap_intf_check_work_info)) {
+		struct sta_ap_intf_check_work_ctx *work_info;
+		work_info = qdf_mem_malloc(
+			sizeof(struct sta_ap_intf_check_work_ctx));
+		pm_ctx->sta_ap_intf_check_work_info = work_info;
+		if (work_info) {
+			work_info->psoc = psoc;
+			qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work,
+				policy_mgr_check_sta_ap_concurrent_ch_intf,
+				work_info);
+			qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work);
+			policy_mgr_info(
+				"Checking for Concurrent Change interference");
+		}
+	}
+}
+#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ * @channel: Channel to change
+ * @ch_width: channel width to change
+ * @forced: Force to switch channel, ignore SCC/MCC check
+ *
+ * Invoke the callback function to change SAP channel using (E)CSA
+ *
+ * Return: None
+ */
+void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id, uint32_t channel,
+					    uint32_t ch_width,
+					    bool forced)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+
+	if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
+		policy_mgr_info("SAP change change without restart");
+		pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
+				vdev_id, channel, ch_width, forced);
+	}
+}
+#endif
+
+QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
+
+	policy_mgr_context = policy_mgr_get_context(psoc);
+	if (!policy_mgr_context) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = qdf_wait_single_event(
+			&policy_mgr_context->connection_update_done_evt,
+			CONNECTION_UPDATE_TIMEOUT);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("wait for event failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
+
+	policy_mgr_context = policy_mgr_get_context(psoc);
+	if (!policy_mgr_context) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = qdf_event_reset(
+		&policy_mgr_context->connection_update_done_evt);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("clear event failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
+
+	policy_mgr_context = policy_mgr_get_context(psoc);
+	if (!policy_mgr_context) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = qdf_event_set(&policy_mgr_context->connection_update_done_evt);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("set event failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
+		struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
+
+	policy_mgr_context = policy_mgr_get_context(psoc);
+
+	if (!policy_mgr_context) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	status = qdf_event_set(
+			&policy_mgr_context->channel_switch_complete_evt);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("set event failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
+		struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
+
+	policy_mgr_context = policy_mgr_get_context(psoc);
+
+	if (!policy_mgr_context) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	status = qdf_event_reset(
+			&policy_mgr_context->channel_switch_complete_evt);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("reset event failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
+
+	policy_mgr_context = policy_mgr_get_context(psoc);
+	if (!policy_mgr_context) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = qdf_event_set(
+			&policy_mgr_context->opportunistic_update_done_evt);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("set event failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
+
+	policy_mgr_ctx = policy_mgr_get_context(psoc);
+	if (!policy_mgr_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (policy_mgr_ctx->dbs_opportunistic_timer.state !=
+	    QDF_TIMER_STATE_RUNNING)
+		return QDF_STATUS_SUCCESS;
+
+	qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_restart_opportunistic_timer(
+		struct wlan_objmgr_psoc *psoc, bool check_state)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
+
+	policy_mgr_ctx = policy_mgr_get_context(psoc);
+	if (!policy_mgr_ctx) {
+		policy_mgr_err("Invalid context");
+		return status;
+	}
+
+	if (check_state &&
+			QDF_TIMER_STATE_RUNNING !=
+			policy_mgr_ctx->dbs_opportunistic_timer.state)
+		return status;
+
+	qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
+
+	status = qdf_mc_timer_start(
+			&policy_mgr_ctx->dbs_opportunistic_timer,
+			DBS_OPPORTUNISTIC_TIME * 1000);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("failed to start opportunistic timer");
+		return status;
+	}
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
+			struct wlan_objmgr_psoc *psoc, uint8_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
+	enum policy_mgr_conc_next_action action;
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
+		policy_mgr_err("PM/DBS is disabled");
+		return status;
+	}
+
+	action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc);
+	if ((action != PM_DBS_DOWNGRADE) &&
+	    (action != PM_SINGLE_MAC_UPGRADE) &&
+	    (action != PM_DBS1_DOWNGRADE) &&
+	    (action != PM_DBS2_DOWNGRADE)) {
+		policy_mgr_err("Invalid action: %d", action);
+		status = QDF_STATUS_SUCCESS;
+		goto done;
+	}
+
+	policy_mgr_debug("action:%d session id:%d", action, session_id);
+
+	/* Opportunistic timer is started, PM will check if MCC upgrade can be
+	 * done on timer expiry. This avoids any possible ping pong effect
+	 * as well.
+	 */
+	if (action == PM_SINGLE_MAC_UPGRADE) {
+		qdf_status = policy_mgr_restart_opportunistic_timer(
+			psoc, false);
+		if (QDF_IS_STATUS_SUCCESS(qdf_status))
+			policy_mgr_debug("opportunistic timer for MCC upgrade");
+		goto done;
+	}
+
+	/* For DBS, we want to move right away to DBS mode */
+	status = policy_mgr_next_actions(psoc, session_id, action,
+			POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("no set hw mode command was issued");
+		goto done;
+	}
+done:
+	/* success must be returned only when a set hw mode was done */
+	return status;
+}
+
+void policy_mgr_checkn_update_hw_mode_single_mac_mode(
+		struct wlan_objmgr_psoc *psoc, uint8_t channel)
+{
+	uint8_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (QDF_TIMER_STATE_RUNNING ==
+		pm_ctx->dbs_opportunistic_timer.state)
+		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if (pm_conc_connection_list[i].in_use) {
+			if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
+				pm_conc_connection_list[i].chan)) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				policy_mgr_debug("DBS required");
+				return;
+			}
+			if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
+			    (WLAN_REG_IS_24GHZ_CH(channel) ||
+			    WLAN_REG_IS_24GHZ_CH
+				(pm_conc_connection_list[i].chan))) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				policy_mgr_debug("DBS required");
+				return;
+			}
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	pm_dbs_opportunistic_timer_handler((void *)psoc);
+}
+
+void policy_mgr_check_and_stop_opportunistic_timer(
+	struct wlan_objmgr_psoc *psoc, uint8_t id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum policy_mgr_conc_next_action action = PM_NOP;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	enum policy_mgr_conn_update_reason reason;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	if (QDF_TIMER_STATE_RUNNING ==
+		pm_ctx->dbs_opportunistic_timer.state) {
+		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
+		action = policy_mgr_need_opportunistic_upgrade(psoc, &reason);
+		if (action) {
+			qdf_event_reset(&pm_ctx->opportunistic_update_done_evt);
+			status = policy_mgr_next_actions(psoc, id, action,
+							 reason);
+			if (status != QDF_STATUS_SUCCESS) {
+				policy_mgr_err("Failed in policy_mgr_next_actions");
+				return;
+			}
+			status = qdf_wait_single_event(
+					&pm_ctx->opportunistic_update_done_evt,
+					CONNECTION_UPDATE_TIMEOUT);
+
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				policy_mgr_err("wait for event failed");
+				return;
+			}
+		}
+	}
+}
+
+void policy_mgr_set_hw_mode_change_in_progress(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	pm_ctx->hw_mode_change_in_progress = value;
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	policy_mgr_debug("hw_mode_change_in_progress:%d", value);
+}
+
+enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
+	struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_hw_mode_change value;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return value;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	value = pm_ctx->hw_mode_change_in_progress;
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return value;
+}
+
+enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
+	struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_hw_mode_params hw_mode;
+	enum policy_mgr_hw_mode_change value
+		= POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
+	QDF_STATUS status;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return value;
+	}
+
+	status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to get HW mode index");
+		return value;
+	}
+
+	if (hw_mode.dbs_cap) {
+		policy_mgr_info("DBS is requested with HW (%d)",
+		hw_mode_index);
+		value = POLICY_MGR_DBS_IN_PROGRESS;
+		goto ret_value;
+	}
+
+	if (hw_mode.sbs_cap) {
+		policy_mgr_info("SBS is requested with HW (%d)",
+		hw_mode_index);
+		value = POLICY_MGR_SBS_IN_PROGRESS;
+		goto ret_value;
+	}
+
+	value = POLICY_MGR_SMM_IN_PROGRESS;
+	policy_mgr_info("SMM is requested with HW (%d)", hw_mode_index);
+
+ret_value:
+	return value;
+}
+
+#ifdef MPC_UT_FRAMEWORK
+QDF_STATUS policy_mgr_update_connection_info_utfw(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
+		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
+		uint32_t channelid, uint32_t mac_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t conn_index = 0, found = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
+			/* debug msg */
+			found = 1;
+			break;
+		}
+		conn_index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (!found) {
+		/* err msg */
+		policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
+			vdev_id);
+		return status;
+	}
+	policy_mgr_debug("--> updating entry at index[%d]", conn_index);
+
+	policy_mgr_update_conc_list(psoc, conn_index,
+			policy_mgr_get_mode(type, sub_type),
+			channelid, HW_MODE_20_MHZ,
+			mac_id, chain_mask, 0, vdev_id, true, true);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
+		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
+		uint32_t channelid, uint32_t mac_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t conn_index = 0;
+	bool update_conn = true;
+	enum policy_mgr_con_mode mode;
+
+	conn_index = policy_mgr_get_connection_count(psoc);
+	if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
+		/* err msg */
+		policy_mgr_err("exceeded max connection limit %d",
+			MAX_NUMBER_OF_CONC_CONNECTIONS);
+		return status;
+	}
+	policy_mgr_debug("--> filling entry at index[%d]", conn_index);
+
+	mode = policy_mgr_get_mode(type, sub_type);
+	if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)
+		update_conn = false;
+
+	policy_mgr_update_conc_list(psoc, conn_index,
+				mode,
+				channelid, HW_MODE_20_MHZ,
+				mac_id, chain_mask, 0, vdev_id, true,
+				update_conn);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
+		uint32_t del_all, uint32_t vdev_id)
+{
+	QDF_STATUS status;
+
+	if (del_all) {
+		status = policy_mgr_psoc_disable(psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			policy_mgr_err("Policy manager initialization failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+		status = policy_mgr_psoc_enable(psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			policy_mgr_err("Policy manager initialization failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		policy_mgr_decr_connection_count(psoc, vdev_id);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table(
+		enum policy_mgr_con_mode type,
+		enum policy_mgr_conc_priority_mode sys_pref)
+{
+	if ((sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
+		(type >= PM_MAX_NUM_OF_MODE))
+		return PM_MAX_PCL_TYPE;
+	return first_connection_pcl_table[type][sys_pref];
+}
+
+enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table(
+	enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type,
+	enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
+{
+	if ((idx >= PM_MAX_ONE_CONNECTION_MODE) ||
+		(sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
+		(type >= PM_MAX_NUM_OF_MODE))
+		return PM_MAX_PCL_TYPE;
+	if (dbs_capable)
+		return (*second_connection_pcl_dbs_table)[idx][type][sys_pref];
+	else
+		return second_connection_pcl_nodbs_table[idx][type][sys_pref];
+}
+
+enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table(
+	enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type,
+	enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
+{
+	if ((idx >= PM_MAX_TWO_CONNECTION_MODE) ||
+		(sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
+		(type >= PM_MAX_NUM_OF_MODE))
+		return PM_MAX_PCL_TYPE;
+	if (dbs_capable)
+		return (*third_connection_pcl_dbs_table)[idx][type][sys_pref];
+	else
+		return third_connection_pcl_nodbs_table[idx][type][sys_pref];
+}
+#endif

+ 3135 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -0,0 +1,3135 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_policy_mgr_core.c
+ *
+ * WLAN Concurrenct Connection Management functions
+ *
+ */
+
+/* Include files */
+
+#include "wlan_policy_mgr_i.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_objmgr_global_obj.h"
+
+#define POLICY_MGR_MAX_CON_STRING_LEN   100
+
+struct policy_mgr_conc_connection_info
+	pm_conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+
+struct policy_mgr_psoc_priv_obj *policy_mgr_get_context(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	pm_ctx = (struct policy_mgr_psoc_priv_obj *)
+			wlan_objmgr_psoc_get_comp_private_obj(psoc,
+				WLAN_UMAC_COMP_POLICY_MGR);
+	return pm_ctx;
+}
+
+/**
+ * policy_mgr_get_updated_scan_config() - Get the updated scan configuration
+ * @scan_config: Pointer containing the updated scan config
+ * @dbs_scan: 0 or 1 indicating if DBS scan needs to be enabled/disabled
+ * @dbs_plus_agile_scan: 0 or 1 indicating if DBS plus agile scan needs to be
+ * enabled/disabled
+ * @single_mac_scan_with_dfs: 0 or 1 indicating if single MAC scan with DFS
+ * needs to be enabled/disabled
+ *
+ * Takes the current scan configuration and set the necessary scan config
+ * bits to either 0/1 and provides the updated value to the caller who
+ * can use this to pass it on to the FW
+ *
+ * Return: 0 on success
+ */
+QDF_STATUS policy_mgr_get_updated_scan_config(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *scan_config,
+		bool dbs_scan,
+		bool dbs_plus_agile_scan,
+		bool single_mac_scan_with_dfs)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
+
+	WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(*scan_config, dbs_scan);
+	WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET(*scan_config,
+			dbs_plus_agile_scan);
+	WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET(*scan_config,
+			single_mac_scan_with_dfs);
+
+	policy_mgr_debug("scan_config:%x ", *scan_config);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_get_updated_fw_mode_config() - Get the updated fw
+ * mode configuration
+ * @fw_mode_config: Pointer containing the updated fw mode config
+ * @dbs: 0 or 1 indicating if DBS needs to be enabled/disabled
+ * @agile_dfs: 0 or 1 indicating if agile DFS needs to be enabled/disabled
+ *
+ * Takes the current fw mode configuration and set the necessary fw mode config
+ * bits to either 0/1 and provides the updated value to the caller who
+ * can use this to pass it on to the FW
+ *
+ * Return: 0 on success
+ */
+QDF_STATUS policy_mgr_get_updated_fw_mode_config(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *fw_mode_config,
+		bool dbs,
+		bool agile_dfs)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config;
+
+	WMI_DBS_FW_MODE_CFG_DBS_SET(*fw_mode_config, dbs);
+	WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET(*fw_mode_config, agile_dfs);
+
+	policy_mgr_debug("fw_mode_config:%x ", *fw_mode_config);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_is_dual_mac_disabled_in_ini() - Check if dual mac
+ * is disabled in INI
+ *
+ * Checks if the dual mac feature is disabled in INI
+ *
+ * Return: true if the dual mac connection is disabled from INI
+ */
+bool policy_mgr_is_dual_mac_disabled_in_ini(
+		struct wlan_objmgr_psoc *psoc)
+{
+	bool is_disabled = false;
+	enum dbs_support dbs_type = wlan_objmgr_psoc_get_dual_mac_disable(psoc);
+
+	/*
+	 * If DBS support for connection is disabled through INI then assume
+	 * that DBS is not supported, so that policy manager takes
+	 * the decision considering non-dbs cases only.
+	 *
+	 * For DBS scan check the INI value explicitly
+	 */
+	switch (dbs_type) {
+	case DISABLE_DBS_CXN_AND_SCAN:
+	case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN:
+	case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF:
+		is_disabled = true;
+		break;
+	default:
+		break;
+	}
+
+	return is_disabled;
+}
+
+uint32_t policy_mgr_get_mcc_to_scc_switch_mode(
+	struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+
+	return pm_ctx->cfg.mcc_to_scc_switch;
+}
+
+/**
+ * policy_mgr_get_dbs_config() - Get DBS bit
+ *
+ * Gets the DBS bit of fw_mode_config_bits
+ *
+ * Return: 0 or 1 to indicate the DBS bit
+ */
+bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t fw_mode_config;
+
+	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
+		return false;
+
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		/* We take that it is disabled and proceed */
+		return false;
+	}
+	fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config;
+
+	return WMI_DBS_FW_MODE_CFG_DBS_GET(fw_mode_config);
+}
+
+/**
+ * policy_mgr_get_agile_dfs_config() - Get Agile DFS bit
+ *
+ * Gets the Agile DFS bit of fw_mode_config_bits
+ *
+ * Return: 0 or 1 to indicate the Agile DFS bit
+ */
+bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t fw_mode_config;
+
+	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
+		return false;
+
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		/* We take that it is disabled and proceed */
+		return false;
+	}
+	fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config;
+
+	return WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_mode_config);
+}
+
+/**
+ * policy_mgr_get_dbs_scan_config() - Get DBS scan bit
+ *
+ * Gets the DBS scan bit of concurrent_scan_config_bits
+ *
+ * Return: 0 or 1 to indicate the DBS scan bit
+ */
+bool policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t scan_config;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
+		return false;
+
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		/* We take that it is disabled and proceed */
+		return false;
+	}
+	scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
+
+	return WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config);
+}
+
+/**
+ * policy_mgr_get_tx_rx_ss_from_config() - Get Tx/Rx spatial
+ * stream from HW mode config
+ * @mac_ss: Config which indicates the HW mode as per 'hw_mode_ss_config'
+ * @tx_ss: Contains the Tx spatial stream
+ * @rx_ss: Contains the Rx spatial stream
+ *
+ * Returns the number of spatial streams of Tx and Rx
+ *
+ * Return: None
+ */
+void policy_mgr_get_tx_rx_ss_from_config(enum hw_mode_ss_config mac_ss,
+		uint32_t *tx_ss, uint32_t *rx_ss)
+{
+	switch (mac_ss) {
+	case HW_MODE_SS_0x0:
+		*tx_ss = 0;
+		*rx_ss = 0;
+		break;
+	case HW_MODE_SS_1x1:
+		*tx_ss = 1;
+		*rx_ss = 1;
+		break;
+	case HW_MODE_SS_2x2:
+		*tx_ss = 2;
+		*rx_ss = 2;
+		break;
+	case HW_MODE_SS_3x3:
+		*tx_ss = 3;
+		*rx_ss = 3;
+		break;
+	case HW_MODE_SS_4x4:
+		*tx_ss = 4;
+		*rx_ss = 4;
+		break;
+	default:
+		*tx_ss = 0;
+		*rx_ss = 0;
+	}
+}
+
+/**
+ * policy_mgr_get_matching_hw_mode_index() - Get matching HW mode index
+ * @psoc: psoc handle
+ * @mac0_tx_ss: Number of tx spatial streams of MAC0
+ * @mac0_rx_ss: Number of rx spatial streams of MAC0
+ * @mac0_bw: Bandwidth of MAC0 of type 'hw_mode_bandwidth'
+ * @mac1_tx_ss: Number of tx spatial streams of MAC1
+ * @mac1_rx_ss: Number of rx spatial streams of MAC1
+ * @mac1_bw: Bandwidth of MAC1 of type 'hw_mode_bandwidth'
+ * @mac0_band_cap: mac0 band capability requirement
+ *     (0: Don't care, 1: 2.4G, 2: 5G)
+ * @dbs: DBS capability of type 'hw_mode_dbs_capab'
+ * @dfs: Agile DFS capability of type 'hw_mode_agile_dfs_capab'
+ * @sbs: SBS capability of type 'hw_mode_sbs_capab'
+ *
+ * Fetches the HW mode index corresponding to the HW mode provided.
+ * In Genoa two DBS HW modes (2x2 5G + 1x1 2G, 2x2 2G + 1x1 5G),
+ * the "ss" number and "bw" value are not enough to specify the expected
+ * HW mode. But in both HW mode, the mac0 can support either 5G or 2G.
+ * So, the Parameter "mac0_band_cap" will specify the expected band support
+ * requirement on mac 0 to find the expected HW mode.
+ *
+ * Return: Positive hw mode index in case a match is found or a negative
+ * value, otherwise
+ */
+int8_t policy_mgr_get_matching_hw_mode_index(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t mac0_tx_ss, uint32_t mac0_rx_ss,
+		enum hw_mode_bandwidth mac0_bw,
+		uint32_t mac1_tx_ss, uint32_t mac1_rx_ss,
+		enum hw_mode_bandwidth mac1_bw,
+		enum hw_mode_mac_band_cap mac0_band_cap,
+		enum hw_mode_dbs_capab dbs,
+		enum hw_mode_agile_dfs_capab dfs,
+		enum hw_mode_sbs_capab sbs)
+{
+	uint32_t i;
+	uint32_t t_mac0_tx_ss, t_mac0_rx_ss, t_mac0_bw;
+	uint32_t t_mac1_tx_ss, t_mac1_rx_ss, t_mac1_bw;
+	uint32_t dbs_mode, agile_dfs_mode, sbs_mode;
+	uint32_t t_mac0_band_cap;
+	int8_t found = -EINVAL;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return found;
+	}
+
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		t_mac0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (t_mac0_tx_ss < mac0_tx_ss)
+			continue;
+
+		t_mac0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (t_mac0_rx_ss < mac0_rx_ss)
+			continue;
+
+		t_mac0_bw = POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		/*
+		 * Firmware advertises max bw capability as CBW 80+80
+		 * for single MAC. Thus CBW 20/40/80 should also be
+		 * supported, if CBW 80+80 is supported.
+		 */
+		if (t_mac0_bw < mac0_bw)
+			continue;
+
+		t_mac1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (t_mac1_tx_ss < mac1_tx_ss)
+			continue;
+
+		t_mac1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (t_mac1_rx_ss < mac1_rx_ss)
+			continue;
+
+		t_mac1_bw = POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (t_mac1_bw < mac1_bw)
+			continue;
+
+		dbs_mode = POLICY_MGR_HW_MODE_DBS_MODE_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (dbs_mode != dbs)
+			continue;
+
+		agile_dfs_mode = POLICY_MGR_HW_MODE_AGILE_DFS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (agile_dfs_mode != dfs)
+			continue;
+
+		sbs_mode = POLICY_MGR_HW_MODE_SBS_MODE_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (sbs_mode != sbs)
+			continue;
+
+		t_mac0_band_cap = POLICY_MGR_HW_MODE_MAC0_BAND_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		if (mac0_band_cap && t_mac0_band_cap != mac0_band_cap)
+			continue;
+
+		found = POLICY_MGR_HW_MODE_ID_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+
+		policy_mgr_debug("hw_mode id %d found at %d", found, i);
+
+		break;
+	}
+	return found;
+}
+
+/**
+ * policy_mgr_get_hw_mode_from_dbs_hw_list() - Get hw_mode index
+ * @mac0_ss: MAC0 spatial stream configuration
+ * @mac0_bw: MAC0 bandwidth configuration
+ * @mac1_ss: MAC1 spatial stream configuration
+ * @mac1_bw: MAC1 bandwidth configuration
+ * @mac0_band_cap: mac0 band capability requirement
+ *     (0: Don't care, 1: 2.4G, 2: 5G)
+ * @dbs: HW DBS capability
+ * @dfs: HW Agile DFS capability
+ * @sbs: HW SBS capability
+ *
+ * Get the HW mode index corresponding to the HW modes spatial stream,
+ * bandwidth, DBS, Agile DFS and SBS capability
+ *
+ * In Genoa two DBS HW modes (2x2 5G + 1x1 2G, 2x2 2G + 1x1 5G),
+ * the "ss" number and "bw" value are not enough to specify the expected
+ * HW mode. But in both HW mode, the mac0 can support either 5G or 2G.
+ * So, the Parameter "mac0_band_cap" will specify the expected band support
+ * requirement on mac 0 to find the expected HW mode.
+ *
+ * Return: Index number if a match is found or -negative value if not found
+ */
+int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
+		struct wlan_objmgr_psoc *psoc,
+		enum hw_mode_ss_config mac0_ss,
+		enum hw_mode_bandwidth mac0_bw,
+		enum hw_mode_ss_config mac1_ss,
+		enum hw_mode_bandwidth mac1_bw,
+		enum hw_mode_mac_band_cap mac0_band_cap,
+		enum hw_mode_dbs_capab dbs,
+		enum hw_mode_agile_dfs_capab dfs,
+		enum hw_mode_sbs_capab sbs)
+{
+	uint32_t mac0_tx_ss, mac0_rx_ss;
+	uint32_t mac1_tx_ss, mac1_rx_ss;
+
+	policy_mgr_get_tx_rx_ss_from_config(mac0_ss, &mac0_tx_ss, &mac0_rx_ss);
+	policy_mgr_get_tx_rx_ss_from_config(mac1_ss, &mac1_tx_ss, &mac1_rx_ss);
+
+	policy_mgr_debug("MAC0: TxSS=%d, RxSS=%d, BW=%d band=%d",
+			 mac0_tx_ss, mac0_rx_ss, mac0_bw, mac0_band_cap);
+	policy_mgr_debug("MAC1: TxSS=%d, RxSS=%d, BW=%d",
+			 mac1_tx_ss, mac1_rx_ss, mac1_bw);
+	policy_mgr_debug("DBS=%d, Agile DFS=%d, SBS=%d",
+			 dbs, dfs, sbs);
+
+	return policy_mgr_get_matching_hw_mode_index(psoc, mac0_tx_ss,
+						mac0_rx_ss,
+						mac0_bw,
+						mac1_tx_ss, mac1_rx_ss,
+						mac1_bw,
+						mac0_band_cap,
+						dbs, dfs, sbs);
+}
+
+/**
+ * policy_mgr_get_hw_mode_from_idx() - Get HW mode based on index
+ * @psoc: psoc object
+ * @idx: HW mode id
+ * @hw_mode: HW mode params
+ *
+ * Fetches the HW mode parameters
+ *
+ * Return: Success if hw mode is obtained and the hw mode params
+ */
+QDF_STATUS policy_mgr_get_hw_mode_from_idx(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t idx,
+		struct policy_mgr_hw_mode_params *hw_mode)
+{
+	uint32_t param;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t mac0_min_ss;
+	uint8_t mac1_min_ss;
+	uint32_t i, hw_mode_id;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!pm_ctx->num_dbs_hw_modes) {
+		policy_mgr_err("No dbs hw modes available");
+		return QDF_STATUS_E_FAILURE;
+	}
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		hw_mode_id = POLICY_MGR_HW_MODE_ID_GET(param);
+		if (hw_mode_id == idx)
+			break;
+	}
+	if (i >= pm_ctx->num_dbs_hw_modes) {
+		policy_mgr_err("hw mode id %d not found", idx);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	param = pm_ctx->hw_mode.hw_mode_list[i];
+
+	hw_mode->mac0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param);
+	hw_mode->mac0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param);
+	hw_mode->mac0_bw = POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param);
+	hw_mode->mac1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param);
+	hw_mode->mac1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param);
+	hw_mode->mac1_bw = POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param);
+	hw_mode->mac0_band_cap = POLICY_MGR_HW_MODE_MAC0_BAND_GET(param);
+	hw_mode->dbs_cap = POLICY_MGR_HW_MODE_DBS_MODE_GET(param);
+	hw_mode->agile_dfs_cap = POLICY_MGR_HW_MODE_AGILE_DFS_GET(param);
+	hw_mode->sbs_cap = POLICY_MGR_HW_MODE_SBS_MODE_GET(param);
+	if (hw_mode->dbs_cap) {
+		mac0_min_ss = QDF_MIN(hw_mode->mac0_tx_ss, hw_mode->mac0_rx_ss);
+		mac1_min_ss = QDF_MIN(hw_mode->mac1_tx_ss, hw_mode->mac1_rx_ss);
+		if (hw_mode->mac0_band_cap == WLAN_5G_CAPABILITY &&
+		    mac0_min_ss && mac1_min_ss &&
+		    mac0_min_ss > mac1_min_ss)
+			hw_mode->action_type = PM_DBS1;
+		else if (hw_mode->mac0_band_cap == WLAN_2G_CAPABILITY &&
+			 mac0_min_ss && mac1_min_ss &&
+			 mac0_min_ss > mac1_min_ss)
+			hw_mode->action_type = PM_DBS2;
+		else
+			hw_mode->action_type = PM_DBS;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_get_old_and_new_hw_index() - Get the old and new HW index
+ * @old_hw_mode_index: Value at this pointer contains the old HW mode index
+ * Default value when not configured is POLICY_MGR_DEFAULT_HW_MODE_INDEX
+ * @new_hw_mode_index: Value at this pointer contains the new HW mode index
+ * Default value when not configured is POLICY_MGR_DEFAULT_HW_MODE_INDEX
+ *
+ * Get the old and new HW index configured in the driver
+ *
+ * Return: Failure in case the HW mode indices cannot be fetched and Success
+ * otherwise. When no HW mode transition has happened the values of
+ * old_hw_mode_index and new_hw_mode_index will be the same.
+ */
+QDF_STATUS policy_mgr_get_old_and_new_hw_index(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *old_hw_mode_index,
+		uint32_t *new_hw_mode_index)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*old_hw_mode_index = pm_ctx->old_hw_mode_index;
+	*new_hw_mode_index = pm_ctx->new_hw_mode_index;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_update_conc_list() - Update the concurrent connection list
+ * @conn_index: Connection index
+ * @mode: Mode
+ * @chan: Channel
+ * @bw: Bandwidth
+ * @mac: Mac id
+ * @chain_mask: Chain mask
+ * @vdev_id: vdev id
+ * @in_use: Flag to indicate if the index is in use or not
+ * @update_conn: Flag to indicate if mode change event should
+ *  be sent or not
+ *
+ * Updates the index value of the concurrent connection list
+ *
+ * Return: None
+ */
+void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
+		uint32_t conn_index,
+		enum policy_mgr_con_mode mode,
+		uint8_t chan,
+		enum hw_mode_bandwidth bw,
+		uint8_t mac,
+		enum policy_mgr_chain_mode chain_mask,
+		uint32_t original_nss,
+		uint32_t vdev_id,
+		bool in_use,
+		bool update_conn)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool mcc_mode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (conn_index >= MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		policy_mgr_err("Number of connections exceeded conn_index: %d",
+			conn_index);
+		return;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	pm_conc_connection_list[conn_index].mode = mode;
+	pm_conc_connection_list[conn_index].chan = chan;
+	pm_conc_connection_list[conn_index].bw = bw;
+	pm_conc_connection_list[conn_index].mac = mac;
+	pm_conc_connection_list[conn_index].chain_mask = chain_mask;
+	pm_conc_connection_list[conn_index].original_nss = original_nss;
+	pm_conc_connection_list[conn_index].vdev_id = vdev_id;
+	pm_conc_connection_list[conn_index].in_use = in_use;
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	/*
+	 * For STA and P2P client mode, the mode change event sent as part
+	 * of the callback causes delay in processing M1 frame at supplicant
+	 * resulting in cert test case failure. The mode change event is sent
+	 * as part of add key for STA and P2P client mode.
+	 */
+	if (pm_ctx->mode_change_cb && update_conn)
+		pm_ctx->mode_change_cb();
+
+	policy_mgr_dump_connection_status_info(psoc);
+	if (pm_ctx->cdp_cbacks.cdp_update_mac_id)
+		pm_ctx->cdp_cbacks.cdp_update_mac_id(psoc, vdev_id, mac);
+
+	/* IPA only cares about STA or SAP mode */
+	if (mode == PM_STA_MODE || mode == PM_SAP_MODE) {
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc);
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+		if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb)
+			pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode);
+	}
+}
+
+/**
+ * policy_mgr_store_and_del_conn_info() - Store and del a connection info
+ * @mode: Mode whose entry has to be deleted
+ * @all_matching_cxn_to_del: All the specified mode entries should be deleted
+ * @info: Struture array pointer where the connection info will be saved
+ * @num_cxn_del: Number of connection which are going to be deleted
+ *
+ * Saves the connection info corresponding to the provided mode
+ * and deleted that corresponding entry based on vdev from the
+ * connection info structure
+ *
+ * Return: None
+ */
+void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
+	enum policy_mgr_con_mode mode, bool all_matching_cxn_to_del,
+	struct policy_mgr_conc_connection_info *info, uint8_t *num_cxn_del)
+{
+	int32_t conn_index = 0;
+	uint32_t found_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (!num_cxn_del) {
+		policy_mgr_err("num_cxn_del is NULL");
+		return;
+	}
+	*num_cxn_del = 0;
+	if (!info) {
+		policy_mgr_err("Invalid connection info");
+		return;
+	}
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if (mode == pm_conc_connection_list[conn_index].mode) {
+			/*
+			 * Storing the connection entry which will be
+			 * temporarily deleted.
+			 */
+			info[found_index] = pm_conc_connection_list[conn_index];
+			/* Deleting the connection entry */
+			policy_mgr_decr_connection_count(psoc,
+					info[found_index].vdev_id);
+			policy_mgr_debug("Stored %d (%d), deleted STA entry with vdev id %d, index %d",
+					 info[found_index].vdev_id,
+					 info[found_index].mode,
+					 info[found_index].vdev_id, conn_index);
+			found_index++;
+			if (all_matching_cxn_to_del)
+				continue;
+			else
+				break;
+		}
+		conn_index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (!found_index) {
+		*num_cxn_del = 0;
+		policy_mgr_err("Mode:%d not available in the conn info", mode);
+	} else {
+		*num_cxn_del = found_index;
+		policy_mgr_err("Mode:%d number of conn %d temp del",
+				mode, *num_cxn_del);
+	}
+
+	/*
+	 * Caller should set the PCL and restore the connection entry
+	 * in conn info.
+	 */
+}
+
+void policy_mgr_store_and_del_conn_info_by_vdev_id(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t vdev_id,
+			struct policy_mgr_conc_connection_info *info,
+			uint8_t *num_cxn_del)
+{
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (!info || !num_cxn_del) {
+		policy_mgr_err("Invalid parameters");
+		return;
+	}
+	*num_cxn_del = 0;
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) &&
+		    pm_conc_connection_list[conn_index].in_use) {
+			*num_cxn_del = 1;
+			break;
+		}
+	}
+	/*
+	 * Storing the connection entry which will be
+	 * temporarily deleted.
+	 */
+	if (*num_cxn_del == 1) {
+		*info = pm_conc_connection_list[conn_index];
+		/* Deleting the connection entry */
+		policy_mgr_decr_connection_count(
+			psoc,
+			pm_conc_connection_list[conn_index].vdev_id);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+/**
+ * policy_mgr_restore_deleted_conn_info() - Restore connection info
+ * @info: An array saving connection info that is to be restored
+ * @num_cxn_del: Number of connection temporary deleted
+ *
+ * Restores the connection info of STA that was saved before
+ * updating the PCL to the FW
+ *
+ * Return: None
+ */
+void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_conc_connection_info *info,
+		uint8_t num_cxn_del)
+{
+	uint32_t conn_index;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (MAX_NUMBER_OF_CONC_CONNECTIONS <= num_cxn_del || 0 == num_cxn_del) {
+		policy_mgr_err("Failed to restore %d/%d deleted information",
+				num_cxn_del, MAX_NUMBER_OF_CONC_CONNECTIONS);
+		return;
+	}
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	conn_index = policy_mgr_get_connection_count(psoc);
+	if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
+		policy_mgr_err("Failed to restore the deleted information %d/%d",
+			conn_index, MAX_NUMBER_OF_CONC_CONNECTIONS);
+		return;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	qdf_mem_copy(&pm_conc_connection_list[conn_index], info,
+			num_cxn_del * sizeof(*info));
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	policy_mgr_debug("Restored the deleleted conn info, vdev:%d, index:%d",
+		info->vdev_id, conn_index);
+}
+
+/**
+ * policy_mgr_update_hw_mode_conn_info() - Update connection
+ * info based on HW mode
+ * @num_vdev_mac_entries: Number of vdev-mac id entries that follow
+ * @vdev_mac_map: Mapping of vdev-mac id
+ * @hw_mode: HW mode
+ *
+ * Updates the connection info parameters based on the new HW mode
+ *
+ * Return: None
+ */
+void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc,
+				uint32_t num_vdev_mac_entries,
+				struct policy_mgr_vdev_mac_map *vdev_mac_map,
+				struct policy_mgr_hw_mode_params hw_mode)
+{
+	uint32_t i, conn_index, found;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < num_vdev_mac_entries; i++) {
+		conn_index = 0;
+		found = 0;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (vdev_mac_map[i].vdev_id ==
+				pm_conc_connection_list[conn_index].vdev_id) {
+				found = 1;
+				break;
+			}
+			conn_index++;
+		}
+		if (found) {
+			pm_conc_connection_list[conn_index].mac =
+				vdev_mac_map[i].mac_id;
+			policy_mgr_debug("vdev:%d, mac:%d",
+			  pm_conc_connection_list[conn_index].vdev_id,
+			  pm_conc_connection_list[conn_index].mac);
+			if (pm_ctx->cdp_cbacks.cdp_update_mac_id)
+				pm_ctx->cdp_cbacks.cdp_update_mac_id(
+					psoc,
+					vdev_mac_map[i].vdev_id,
+					vdev_mac_map[i].mac_id);
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_dump_connection_status_info(psoc);
+}
+
+void policy_mgr_pdev_set_hw_mode_cb(uint32_t status,
+				uint32_t cfgd_hw_mode_index,
+				uint32_t num_vdev_mac_entries,
+				struct policy_mgr_vdev_mac_map *vdev_mac_map,
+				uint8_t next_action,
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t session_id, void *context)
+{
+	QDF_STATUS ret;
+	struct policy_mgr_hw_mode_params hw_mode;
+	uint32_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(context);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	policy_mgr_set_hw_mode_change_in_progress(context,
+		POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
+
+	if (status != SET_HW_MODE_STATUS_OK) {
+		policy_mgr_err("Set HW mode failed with status %d", status);
+		return;
+	}
+
+	if (!vdev_mac_map) {
+		policy_mgr_err("vdev_mac_map is NULL");
+		return;
+	}
+
+	policy_mgr_debug("cfgd_hw_mode_index=%d", cfgd_hw_mode_index);
+
+	for (i = 0; i < num_vdev_mac_entries; i++)
+		policy_mgr_debug("vdev_id:%d mac_id:%d",
+				vdev_mac_map[i].vdev_id,
+				vdev_mac_map[i].mac_id);
+
+	ret = policy_mgr_get_hw_mode_from_idx(context, cfgd_hw_mode_index,
+			&hw_mode);
+	if (ret != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Get HW mode failed: %d", ret);
+		return;
+	}
+
+	policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d, band_cap %d",
+			 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
+			 hw_mode.mac0_bw, hw_mode.mac0_band_cap);
+	policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d",
+			 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
+			 hw_mode.mac1_bw);
+	policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d",
+			 hw_mode.dbs_cap, hw_mode.agile_dfs_cap,
+			 hw_mode.sbs_cap);
+
+	/* update pm_conc_connection_list */
+	policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries,
+			vdev_mac_map,
+			hw_mode);
+	if (pm_ctx->mode_change_cb)
+		pm_ctx->mode_change_cb();
+
+	ret = policy_mgr_set_connection_update(context);
+	if (!QDF_IS_STATUS_SUCCESS(ret))
+		policy_mgr_err("ERROR: set connection_update_done event failed");
+
+	if (PM_NOP != next_action)
+		policy_mgr_next_actions(context, session_id,
+			next_action, reason);
+	else {
+		policy_mgr_debug("No action needed right now");
+		ret = policy_mgr_set_opportunistic_update(context);
+		if (!QDF_IS_STATUS_SUCCESS(ret))
+			policy_mgr_err("ERROR: set opportunistic_update event failed");
+	}
+
+	return;
+}
+
+/**
+ * policy_mgr_dump_current_concurrency_one_connection() - To dump the
+ * current concurrency info with one connection
+ * @cc_mode: connection string
+ * @length: Maximum size of the string
+ *
+ * This routine is called to dump the concurrency info
+ *
+ * Return: length of the string
+ */
+static uint32_t policy_mgr_dump_current_concurrency_one_connection(
+		char *cc_mode, uint32_t length)
+{
+	uint32_t count = 0;
+	enum policy_mgr_con_mode mode;
+
+	mode = pm_conc_connection_list[0].mode;
+
+	switch (mode) {
+	case PM_STA_MODE:
+		count = strlcat(cc_mode, "STA",
+					length);
+		break;
+	case PM_SAP_MODE:
+		count = strlcat(cc_mode, "SAP",
+					length);
+		break;
+	case PM_P2P_CLIENT_MODE:
+		count = strlcat(cc_mode, "P2P CLI",
+					length);
+		break;
+	case PM_P2P_GO_MODE:
+		count = strlcat(cc_mode, "P2P GO",
+					length);
+		break;
+	case PM_IBSS_MODE:
+		count = strlcat(cc_mode, "IBSS",
+					length);
+		break;
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+
+	return count;
+}
+
+/**
+ * policy_mgr_dump_current_concurrency_two_connection() - To dump the
+ * current concurrency info with two connections
+ * @cc_mode: connection string
+ * @length: Maximum size of the string
+ *
+ * This routine is called to dump the concurrency info
+ *
+ * Return: length of the string
+ */
+static uint32_t policy_mgr_dump_current_concurrency_two_connection(
+		char *cc_mode, uint32_t length)
+{
+	uint32_t count = 0;
+	enum policy_mgr_con_mode mode;
+
+	mode = pm_conc_connection_list[1].mode;
+
+	switch (mode) {
+	case PM_STA_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+STA",
+					length);
+		break;
+	case PM_SAP_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+SAP",
+					length);
+		break;
+	case PM_P2P_CLIENT_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+P2P CLI",
+					length);
+		break;
+	case PM_P2P_GO_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+P2P GO",
+					length);
+		break;
+	case PM_IBSS_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+IBSS",
+					length);
+		break;
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+
+	return count;
+}
+
+/**
+ * policy_mgr_dump_current_concurrency_three_connection() - To dump the
+ * current concurrency info with three connections
+ * @cc_mode: connection string
+ * @length: Maximum size of the string
+ *
+ * This routine is called to dump the concurrency info
+ *
+ * Return: length of the string
+ */
+static uint32_t policy_mgr_dump_current_concurrency_three_connection(
+		char *cc_mode, uint32_t length)
+{
+	uint32_t count = 0;
+	enum policy_mgr_con_mode mode;
+
+	mode = pm_conc_connection_list[2].mode;
+
+	switch (mode) {
+	case PM_STA_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+STA",
+					length);
+		break;
+	case PM_SAP_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+SAP",
+					length);
+		break;
+	case PM_P2P_CLIENT_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+P2P CLI",
+					length);
+		break;
+	case PM_P2P_GO_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+P2P GO",
+					length);
+		break;
+	case PM_IBSS_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				cc_mode, length);
+		count += strlcat(cc_mode, "+IBSS",
+					length);
+		break;
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+
+	return count;
+}
+
+/**
+ * policy_mgr_dump_dbs_concurrency() - To dump the dbs concurrency
+ * combination
+ * @cc_mode: connection string
+ *
+ * This routine is called to dump the concurrency info
+ *
+ * Return: None
+ */
+static void policy_mgr_dump_dbs_concurrency(struct wlan_objmgr_psoc *psoc,
+					char *cc_mode, uint32_t length)
+{
+	char buf[4] = {0};
+	uint8_t mac = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	strlcat(cc_mode, " DBS", length);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if (pm_conc_connection_list[0].chan ==
+			pm_conc_connection_list[1].chan)
+			strlcat(cc_mode,
+				" with SCC for 1st two connections on mac ",
+				length);
+		else
+			strlcat(cc_mode,
+				" with MCC for 1st two connections on mac ",
+				length);
+		mac = pm_conc_connection_list[0].mac;
+	}
+	if (pm_conc_connection_list[0].mac == pm_conc_connection_list[2].mac) {
+		if (pm_conc_connection_list[0].chan ==
+			pm_conc_connection_list[2].chan)
+			strlcat(cc_mode,
+				" with SCC for 1st & 3rd connections on mac ",
+				length);
+		else
+			strlcat(cc_mode,
+				" with MCC for 1st & 3rd connections on mac ",
+				length);
+		mac = pm_conc_connection_list[0].mac;
+	}
+	if (pm_conc_connection_list[1].mac == pm_conc_connection_list[2].mac) {
+		if (pm_conc_connection_list[1].chan ==
+			pm_conc_connection_list[2].chan)
+			strlcat(cc_mode,
+				" with SCC for 2nd & 3rd connections on mac ",
+				length);
+		else
+			strlcat(cc_mode,
+				" with MCC for 2nd & 3rd connections on mac ",
+				length);
+		mac = pm_conc_connection_list[1].mac;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	snprintf(buf, sizeof(buf), "%d ", mac);
+	strlcat(cc_mode, buf, length);
+}
+
+/**
+ * policy_mgr_dump_current_concurrency() - To dump the current
+ * concurrency combination
+ *
+ * This routine is called to dump the concurrency info
+ *
+ * Return: None
+ */
+void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t num_connections = 0;
+	char cc_mode[POLICY_MGR_MAX_CON_STRING_LEN] = {0};
+	uint32_t count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+
+	switch (num_connections) {
+	case 1:
+		policy_mgr_dump_current_concurrency_one_connection(cc_mode,
+					sizeof(cc_mode));
+		policy_mgr_err("%s Standalone", cc_mode);
+		break;
+	case 2:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+			cc_mode, sizeof(cc_mode));
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		if (pm_conc_connection_list[0].chan ==
+			pm_conc_connection_list[1].chan) {
+			strlcat(cc_mode, " SCC", sizeof(cc_mode));
+		} else if (pm_conc_connection_list[0].mac ==
+					pm_conc_connection_list[1].mac) {
+			strlcat(cc_mode, " MCC", sizeof(cc_mode));
+		} else
+			strlcat(cc_mode, " DBS", sizeof(cc_mode));
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		policy_mgr_err("%s", cc_mode);
+		break;
+	case 3:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+			cc_mode, sizeof(cc_mode));
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		if ((pm_conc_connection_list[0].chan ==
+			pm_conc_connection_list[1].chan) &&
+			(pm_conc_connection_list[0].chan ==
+				pm_conc_connection_list[2].chan)){
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				strlcat(cc_mode, " SCC",
+						sizeof(cc_mode));
+		} else if ((pm_conc_connection_list[0].mac ==
+				pm_conc_connection_list[1].mac)
+				&& (pm_conc_connection_list[0].mac ==
+					pm_conc_connection_list[2].mac)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+					strlcat(cc_mode, " MCC on single MAC",
+						sizeof(cc_mode));
+		} else {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			policy_mgr_dump_dbs_concurrency(psoc, cc_mode,
+					sizeof(cc_mode));
+		}
+		policy_mgr_err("%s", cc_mode);
+		break;
+	default:
+		policy_mgr_err("unexpected num_connections value %d",
+			num_connections);
+		break;
+	}
+
+	return;
+}
+
+/**
+ * policy_mgr_pdev_set_pcl() - Sets PCL to FW
+ * @mode: adapter mode
+ *
+ * Fetches the PCL and sends the PCL to SME
+ * module which in turn will send the WMI
+ * command WMI_PDEV_SET_PCL_CMDID to the fw
+ *
+ * Return: None
+ */
+void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc,
+				enum QDF_OPMODE mode)
+{
+	QDF_STATUS status;
+	enum policy_mgr_con_mode con_mode;
+	struct policy_mgr_pcl_list pcl;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	pcl.pcl_len = 0;
+
+	switch (mode) {
+	case QDF_STA_MODE:
+		con_mode = PM_STA_MODE;
+		break;
+	case QDF_P2P_CLIENT_MODE:
+		con_mode = PM_P2P_CLIENT_MODE;
+		break;
+	case QDF_P2P_GO_MODE:
+		con_mode = PM_P2P_GO_MODE;
+		break;
+	case QDF_SAP_MODE:
+		con_mode = PM_SAP_MODE;
+		break;
+	case QDF_IBSS_MODE:
+		con_mode = PM_IBSS_MODE;
+		break;
+	default:
+		policy_mgr_err("Unable to set PCL to FW: %d", mode);
+		return;
+	}
+
+	policy_mgr_debug("get pcl to set it to the FW");
+
+	status = policy_mgr_get_pcl(psoc, con_mode,
+			pcl.pcl_list, &pcl.pcl_len,
+			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Unable to set PCL to FW, Get PCL failed");
+		return;
+	}
+
+	status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(&pcl);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Send soc set PCL to SME failed");
+	else
+		policy_mgr_debug("Set PCL to FW for mode:%d", mode);
+}
+
+/**
+ * policy_mgr_set_pcl_for_existing_combo() - Set PCL for existing connection
+ * @mode: Connection mode of type 'policy_mgr_con_mode'
+ *
+ * Set the PCL for an existing connection
+ *
+ * Return: None
+ */
+void policy_mgr_set_pcl_for_existing_combo(
+		struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
+{
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	enum QDF_OPMODE pcl_mode;
+	uint8_t num_cxn_del = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	pcl_mode = policy_mgr_get_qdf_mode_from_pm(mode);
+	if (pcl_mode == QDF_MAX_NO_OF_MODE)
+		return;
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) {
+		/* Check, store and temp delete the mode's parameter */
+		policy_mgr_store_and_del_conn_info(psoc, mode, false,
+						info, &num_cxn_del);
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		/* Set the PCL to the FW since connection got updated */
+		policy_mgr_pdev_set_pcl(psoc, pcl_mode);
+		policy_mgr_debug("Set PCL to FW for mode:%d", mode);
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		/* Restore the connection info */
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+static uint32_t pm_get_vdev_id_of_first_conn_idx(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t conn_index = 0, vdev_id = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return conn_index;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++)  {
+		if (pm_conc_connection_list[conn_index].in_use) {
+			vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (conn_index == MAX_NUMBER_OF_CONC_CONNECTIONS)
+		policy_mgr_debug("Use default vdev_id:%d for opportunistic upgrade",
+				 vdev_id);
+	else
+		policy_mgr_debug("Use vdev_id:%d for opportunistic upgrade",
+				 vdev_id);
+
+	return vdev_id;
+}
+
+/**
+ * pm_dbs_opportunistic_timer_handler() - handler of
+ * dbs_opportunistic_timer
+ * @data:  context
+ *
+ * handler for dbs_opportunistic_timer
+ *
+ * Return: None
+ */
+void pm_dbs_opportunistic_timer_handler(void *data)
+{
+	enum policy_mgr_conc_next_action action = PM_NOP;
+	uint32_t session_id;
+	struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)data;
+	enum policy_mgr_conn_update_reason reason;
+
+	if (!psoc) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	/* if we still need it */
+	action = policy_mgr_need_opportunistic_upgrade(psoc, &reason);
+	policy_mgr_debug("action:%d", action);
+	if (!action)
+		return;
+	session_id = pm_get_vdev_id_of_first_conn_idx(psoc);
+	policy_mgr_next_actions(psoc, session_id, action,
+				reason);
+}
+
+/**
+ * policy_mgr_get_connection_for_vdev_id() - provides the
+ * perticular connection with the requested vdev id
+ * @vdev_id: vdev id of the connection
+ *
+ * This function provides the specific connection with the
+ * requested vdev id
+ *
+ * Return: index in the connection table
+ */
+static uint32_t policy_mgr_get_connection_for_vdev_id(
+		struct wlan_objmgr_psoc *psoc, uint32_t vdev_id)
+{
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return conn_index;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		 conn_index++) {
+		if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) &&
+			pm_conc_connection_list[conn_index].in_use) {
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return conn_index;
+}
+
+/**
+ * policy_mgr_get_mode() - Get mode from type and subtype
+ * @type: type
+ * @subtype: subtype
+ *
+ * Get the concurrency mode from the type and subtype
+ * of the interface
+ *
+ * Return: policy_mgr_con_mode
+ */
+enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type,
+		uint8_t subtype)
+{
+	enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
+
+	if (type == WMI_VDEV_TYPE_AP) {
+		switch (subtype) {
+		case 0:
+			mode = PM_SAP_MODE;
+			break;
+		case WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO:
+			mode = PM_P2P_GO_MODE;
+			break;
+		default:
+			policy_mgr_err("Unknown subtype %d for type %d",
+				subtype, type);
+			break;
+		}
+	} else if (type == WMI_VDEV_TYPE_STA) {
+		switch (subtype) {
+		case 0:
+			mode = PM_STA_MODE;
+			break;
+		case WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT:
+			mode = PM_P2P_CLIENT_MODE;
+			break;
+		default:
+			policy_mgr_err("Unknown subtype %d for type %d",
+				subtype, type);
+			break;
+		}
+	} else if (type == WMI_VDEV_TYPE_IBSS) {
+		mode = PM_IBSS_MODE;
+	} else {
+		policy_mgr_err("Unknown type %d", type);
+	}
+
+	return mode;
+}
+
+/**
+ * policy_mgr_get_bw() - Get channel bandwidth type used by WMI
+ * @chan_width: channel bandwidth type defined by host
+ *
+ * Get the channel bandwidth type used by WMI
+ *
+ * Return: hw_mode_bandwidth
+ */
+enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width)
+{
+	enum hw_mode_bandwidth bw = HW_MODE_BW_NONE;
+
+	switch (chan_width) {
+	case CH_WIDTH_20MHZ:
+		bw = HW_MODE_20_MHZ;
+		break;
+	case CH_WIDTH_40MHZ:
+		bw = HW_MODE_40_MHZ;
+		break;
+	case CH_WIDTH_80MHZ:
+		bw = HW_MODE_80_MHZ;
+		break;
+	case CH_WIDTH_160MHZ:
+		bw = HW_MODE_160_MHZ;
+		break;
+	case CH_WIDTH_80P80MHZ:
+		bw = HW_MODE_80_PLUS_80_MHZ;
+		break;
+	case CH_WIDTH_5MHZ:
+		bw = HW_MODE_5_MHZ;
+		break;
+	case CH_WIDTH_10MHZ:
+		bw = HW_MODE_10_MHZ;
+		break;
+	default:
+		policy_mgr_err("Unknown channel BW type %d", chan_width);
+		break;
+	}
+
+	return bw;
+}
+
+/**
+ * policy_mgr_get_sbs_channels() - provides the sbs channel(s)
+ * with respect to current connection(s)
+ * @channels:	the channel(s) on which current connection(s) is
+ * @len:	Number of channels
+ * @pcl_weight: Pointer to the weights of PCL
+ * @weight_len: Max length of the weight list
+ * @index: Index from which the weight list needs to be populated
+ * @group_id: Next available groups for weight assignment
+ * @available_5g_channels: List of available 5g channels
+ * @available_5g_channels_len: Length of the 5g channels list
+ * @add_5g_channels: If this flag is true append 5G channel list as well
+ *
+ * This function provides the channel(s) on which current
+ * connection(s) is/are
+ *
+ * Return: QDF_STATUS
+ */
+
+static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels,
+		uint32_t *len, uint8_t *pcl_weight, uint32_t weight_len,
+		uint32_t *index, enum policy_mgr_pcl_group_id group_id,
+		uint8_t *available_5g_channels,
+		uint32_t available_5g_channels_len,
+		bool add_5g_channels)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t conn_index = 0, num_channels = 0;
+	uint32_t num_5g_channels = 0, cur_5g_channel = 0;
+	uint8_t remaining_5g_Channels[QDF_MAX_NUM_CHAN] = {};
+	uint32_t remaining_channel_index = 0;
+	uint32_t j = 0, i = 0, weight1, weight2;
+
+	if ((NULL == channels) || (NULL == len)) {
+		policy_mgr_err("channels or len is NULL");
+		status = QDF_STATUS_E_FAILURE;
+		return status;
+	}
+
+	if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) {
+		weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+	} else if (group_id == POLICY_MGR_PCL_GROUP_ID2_ID3) {
+		weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+		weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
+	} else {
+		weight1 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
+		weight2 = WEIGHT_OF_GROUP4_PCL_CHANNELS;
+	}
+
+	policy_mgr_debug("weight1=%d weight2=%d index=%d ",
+		weight1, weight2, *index);
+
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[conn_index].chan))
+			&& (pm_conc_connection_list[conn_index].in_use)) {
+			num_5g_channels++;
+			cur_5g_channel =
+				pm_conc_connection_list[conn_index].chan;
+		}
+		conn_index++;
+	}
+
+	conn_index = 0;
+	if (num_5g_channels > 1) {
+		/* This case we are already in SBS so return the channels */
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			channels[num_channels++] =
+				pm_conc_connection_list[conn_index++].chan;
+			if (*index < weight_len)
+				pcl_weight[(*index)++] = weight1;
+		}
+		*len = num_channels;
+		/* fix duplicate issue later */
+		if (add_5g_channels)
+			for (j = 0; j < available_5g_channels_len; j++)
+				remaining_5g_Channels[
+				remaining_channel_index++] =
+				available_5g_channels[j];
+	} else {
+		/* Get list of valid sbs channels for the current
+		 * connected channel
+		 */
+		for (j = 0; j < available_5g_channels_len; j++) {
+			if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS(
+			cur_5g_channel, available_5g_channels[j])) {
+				channels[num_channels++] =
+					available_5g_channels[j];
+			} else {
+				remaining_5g_Channels[
+				remaining_channel_index++] =
+				available_5g_channels[j];
+				continue;
+			}
+			if (*index < weight_len)
+				pcl_weight[(*index)++] = weight1;
+		}
+		*len = num_channels;
+	}
+
+	if (add_5g_channels) {
+		qdf_mem_copy(channels+num_channels, remaining_5g_Channels,
+			remaining_channel_index);
+		*len += remaining_channel_index;
+		for (i = 0; ((i < remaining_channel_index)
+					&& (i < weight_len)); i++)
+			pcl_weight[i] = weight2;
+	}
+
+	return status;
+}
+
+
+/**
+ * policy_mgr_get_connection_channels() - provides the channel(s)
+ * on which current connection(s) is
+ * @channels:	the channel(s) on which current connection(s) is
+ * @len:	Number of channels
+ * @order:	no order OR 2.4 Ghz channel followed by 5 Ghz
+ *	channel OR 5 Ghz channel followed by 2.4 Ghz channel
+ * @skip_dfs_channel: if this flag is true then skip the dfs channel
+ * @pcl_weight: Pointer to the weights of PCL
+ * @weight_len: Max length of the weight list
+ * @index: Index from which the weight list needs to be populated
+ * @group_id: Next available groups for weight assignment
+ *
+ *
+ * This function provides the channel(s) on which current
+ * connection(s) is/are
+ *
+ * Return: QDF_STATUS
+ */
+static
+QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc,
+			uint8_t *channels,
+			uint32_t *len, enum policy_mgr_pcl_channel_order order,
+			bool skip_dfs_channel,
+			uint8_t *pcl_weight, uint32_t weight_len,
+			uint32_t *index, enum policy_mgr_pcl_group_id group_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t conn_index = 0, num_channels = 0;
+	uint32_t weight1, weight2;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	if ((NULL == channels) || (NULL == len)) {
+		policy_mgr_err("channels or len is NULL");
+		status = QDF_STATUS_E_FAILURE;
+		return status;
+	}
+
+	/* POLICY_MGR_PCL_GROUP_ID1_ID2 indicates that all three weights are
+	 * available for assignment. i.e., WEIGHT_OF_GROUP1_PCL_CHANNELS,
+	 * WEIGHT_OF_GROUP2_PCL_CHANNELS and WEIGHT_OF_GROUP3_PCL_CHANNELS
+	 * are all available. Since in this function only two weights are
+	 * assigned at max, only group1 and group2 weights are considered.
+	 *
+	 * The other possible group id POLICY_MGR_PCL_GROUP_ID2_ID3 indicates
+	 * group1 was assigned the weight WEIGHT_OF_GROUP1_PCL_CHANNELS and
+	 * only weights WEIGHT_OF_GROUP2_PCL_CHANNELS and
+	 * WEIGHT_OF_GROUP3_PCL_CHANNELS are available for further weight
+	 * assignments.
+	 *
+	 * e.g., when order is POLICY_MGR_PCL_ORDER_24G_THEN_5G and group id is
+     * POLICY_MGR_PCL_GROUP_ID2_ID3, WEIGHT_OF_GROUP2_PCL_CHANNELS is
+     * assigned to 2.4GHz channels and the weight
+     * WEIGHT_OF_GROUP3_PCL_CHANNELS is assigned to the 5GHz channels.
+	 */
+	if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) {
+		weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+	} else {
+		weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+		weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (POLICY_MGR_PCL_ORDER_NONE == order) {
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev,
+				    pm_conc_connection_list[conn_index].chan)) {
+				conn_index++;
+			} else if (*index < weight_len) {
+				channels[num_channels++] =
+				pm_conc_connection_list[conn_index++].chan;
+				pcl_weight[(*index)++] = weight1;
+			} else {
+				conn_index++;
+			}
+		}
+		*len = num_channels;
+	} else if (POLICY_MGR_PCL_ORDER_24G_THEN_5G == order) {
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (WLAN_REG_IS_24GHZ_CH(
+				    pm_conc_connection_list[conn_index].chan)
+				&& (*index < weight_len)) {
+				channels[num_channels++] =
+				pm_conc_connection_list[conn_index++].chan;
+				pcl_weight[(*index)++] = weight1;
+			} else {
+				conn_index++;
+			}
+		}
+		conn_index = 0;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev,
+				    pm_conc_connection_list[conn_index].chan)) {
+				conn_index++;
+			} else if (WLAN_REG_IS_5GHZ_CH(
+				    pm_conc_connection_list[conn_index].chan)
+				&& (*index < weight_len)) {
+				channels[num_channels++] =
+				pm_conc_connection_list[conn_index++].chan;
+				pcl_weight[(*index)++] = weight2;
+			} else {
+				conn_index++;
+			}
+		}
+		*len = num_channels;
+	} else if (POLICY_MGR_PCL_ORDER_5G_THEN_2G == order) {
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev,
+				pm_conc_connection_list[conn_index].chan)) {
+				conn_index++;
+			} else if (WLAN_REG_IS_5GHZ_CH(
+				    pm_conc_connection_list[conn_index].chan)
+				&& (*index < weight_len)) {
+				channels[num_channels++] =
+				pm_conc_connection_list[conn_index++].chan;
+				pcl_weight[(*index)++] = weight1;
+			} else {
+				conn_index++;
+			}
+		}
+		conn_index = 0;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (WLAN_REG_IS_24GHZ_CH(
+				    pm_conc_connection_list[conn_index].chan)
+				&& (*index < weight_len)) {
+				channels[num_channels++] =
+				pm_conc_connection_list[conn_index++].chan;
+				pcl_weight[(*index)++] = weight2;
+
+			} else {
+				conn_index++;
+			}
+		}
+		*len = num_channels;
+	} else {
+		policy_mgr_err("unknown order %d", order);
+		status = QDF_STATUS_E_FAILURE;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+/**
+ * policy_mgr_set_weight_of_dfs_passive_channels_to_zero() - set weight of dfs
+ * and passive channels to 0
+ * @psoc: pointer to soc
+ * @pcl_channels: preferred channel list
+ * @len: length of preferred channel list
+ * @weight_list: preferred channel weight list
+ * @weight_len: length of weight list
+ * This function set the weight of dfs and passive channels to 0
+ *
+ * Return: None
+ */
+void policy_mgr_set_weight_of_dfs_passive_channels_to_zero(
+		struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels,
+		uint32_t *len, uint8_t *weight_list, uint32_t weight_len)
+{
+	uint8_t i;
+	uint32_t orig_channel_count = 0;
+	bool sta_sap_scc_on_dfs_chan;
+	uint32_t sap_count;
+	enum channel_state channel_state;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+	sap_count = policy_mgr_mode_specific_connection_count(psoc,
+			PM_SAP_MODE, NULL);
+	policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u",
+			 sta_sap_scc_on_dfs_chan, sap_count);
+
+	if (!sta_sap_scc_on_dfs_chan || !sap_count)
+		return;
+
+	if (len)
+		orig_channel_count = QDF_MIN(*len, QDF_MAX_NUM_CHAN);
+	else {
+		policy_mgr_err("invalid number of channel length");
+		return;
+	}
+
+	policy_mgr_debug("Set weight of DFS/passive channels to 0");
+
+	for (i = 0; i < orig_channel_count; i++) {
+		channel_state = reg_get_channel_state(pm_ctx->pdev,
+				pcl_channels[i]);
+		if ((channel_state == CHANNEL_STATE_DISABLE) ||
+				(channel_state == CHANNEL_STATE_INVALID))
+			/* Set weight of inactive channels to 0 */
+			weight_list[i] = 0;
+
+		policy_mgr_debug("chan[%d] - %d, weight[%d] - %d",
+				i, pcl_channels[i], i, weight_list[i]);
+	}
+
+	return;
+}
+
+/**
+ * policy_mgr_get_channel_list() - provides the channel list
+ * suggestion for new connection
+ * @pcl:	The preferred channel list enum
+ * @pcl_channels: PCL channels
+ * @len: length of the PCL
+ * @mode: concurrency mode for which channel list is requested
+ * @pcl_weights: Weights of the PCL
+ * @weight_len: Max length of the weight list
+ *
+ * This function provides the actual channel list based on the
+ * current regulatory domain derived using preferred channel
+ * list enum obtained from one of the pcl_table
+ *
+ * Return: Channel List
+ */
+QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc,
+			enum policy_mgr_pcl_type pcl,
+			uint8_t *pcl_channels, uint32_t *len,
+			enum policy_mgr_con_mode mode,
+			uint8_t *pcl_weights, uint32_t weight_len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t num_channels = 0;
+	uint32_t sbs_num_channels = 0;
+	uint32_t chan_index = 0, chan_index_24 = 0, chan_index_5 = 0;
+	uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0};
+	uint8_t channel_list_24[QDF_MAX_NUM_CHAN] = {0};
+	uint8_t channel_list_5[QDF_MAX_NUM_CHAN] = {0};
+	uint8_t sbs_channel_list[QDF_MAX_NUM_CHAN] = {0};
+	bool skip_dfs_channel = false;
+	bool is_etsi13_srd_chan_allowed_in_mas_mode = true;
+	uint32_t i = 0, j = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool sta_sap_scc_on_dfs_chan;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	if ((NULL == pcl_channels) || (NULL == len)) {
+		policy_mgr_err("pcl_channels or len is NULL");
+		return status;
+	}
+
+	if (PM_MAX_PCL_TYPE == pcl) {
+		/* msg */
+		policy_mgr_err("pcl is invalid");
+		return status;
+	}
+
+	if (PM_NONE == pcl) {
+		/* msg */
+		policy_mgr_debug("pcl is 0");
+		return QDF_STATUS_SUCCESS;
+	}
+	/* get the channel list for current domain */
+	status = policy_mgr_get_valid_chans(psoc, channel_list, &num_channels);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Error in getting valid channels");
+		return status;
+	}
+
+	/*
+	 * if you have atleast one STA connection then don't fill DFS channels
+	 * in the preferred channel list
+	 */
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+	policy_mgr_debug("sta_sap_scc_on_dfs_chan %u", sta_sap_scc_on_dfs_chan);
+	if ((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) {
+		if ((policy_mgr_mode_specific_connection_count(psoc,
+							       PM_STA_MODE,
+							       NULL) > 0) &&
+		    (!sta_sap_scc_on_dfs_chan)) {
+			policy_mgr_debug("skip DFS ch from pcl for SAP/Go");
+			skip_dfs_channel = true;
+		}
+		is_etsi13_srd_chan_allowed_in_mas_mode =
+			wlan_reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx->
+									pdev);
+	}
+
+	/* Let's divide the list in 2.4 & 5 Ghz lists */
+	while ((chan_index < QDF_MAX_NUM_CHAN) &&
+		(channel_list[chan_index] <= 11) &&
+		(chan_index_24 < QDF_MAX_NUM_CHAN))
+		channel_list_24[chan_index_24++] = channel_list[chan_index++];
+	if ((chan_index < QDF_MAX_NUM_CHAN) &&
+		(channel_list[chan_index] == 12) &&
+		(chan_index_24 < QDF_MAX_NUM_CHAN)) {
+		channel_list_24[chan_index_24++] = channel_list[chan_index++];
+		if ((chan_index < QDF_MAX_NUM_CHAN) &&
+			(channel_list[chan_index] == 13) &&
+			(chan_index_24 < QDF_MAX_NUM_CHAN)) {
+			channel_list_24[chan_index_24++] =
+				channel_list[chan_index++];
+			if ((chan_index < QDF_MAX_NUM_CHAN) &&
+				(channel_list[chan_index] == 14) &&
+				(chan_index_24 < QDF_MAX_NUM_CHAN))
+				channel_list_24[chan_index_24++] =
+					channel_list[chan_index++];
+		}
+	}
+
+	while ((chan_index < num_channels) &&
+		(chan_index < QDF_MAX_NUM_CHAN) &&
+		(chan_index_5 < QDF_MAX_NUM_CHAN)) {
+		if ((true == skip_dfs_channel) &&
+		    wlan_reg_is_dfs_ch(pm_ctx->pdev,
+				       channel_list[chan_index])) {
+			chan_index++;
+			continue;
+		}
+		if (!is_etsi13_srd_chan_allowed_in_mas_mode &&
+		    wlan_reg_is_etsi13_srd_chan(pm_ctx->pdev,
+						channel_list[chan_index])) {
+			chan_index++;
+			continue;
+		}
+		channel_list_5[chan_index_5++] = channel_list[chan_index++];
+	}
+
+	num_channels = 0;
+	sbs_num_channels = 0;
+	/* In the below switch case, the channel list is populated based on the
+	 * pcl. e.g., if the pcl is PM_SCC_CH_24G, the SCC channel group is
+	 * populated first followed by the 2.4GHz channel group. Along with
+	 * this, the weights are also populated in the same order for each of
+	 * these groups. There are three weight groups:
+	 * WEIGHT_OF_GROUP1_PCL_CHANNELS, WEIGHT_OF_GROUP2_PCL_CHANNELS and
+	 * WEIGHT_OF_GROUP3_PCL_CHANNELS.
+	 *
+	 * e.g., if pcl is PM_SCC_ON_5_SCC_ON_24_24G: scc on 5GHz (group1)
+	 * channels take the weight WEIGHT_OF_GROUP1_PCL_CHANNELS, scc on 2.4GHz
+	 * (group2) channels take the weight WEIGHT_OF_GROUP2_PCL_CHANNELS and
+	 * 2.4GHz (group3) channels take the weight
+	 * WEIGHT_OF_GROUP3_PCL_CHANNELS.
+	 *
+	 * When the weight to be assigned to the group is known along with the
+	 * number of channels, the weights are directly assigned to the
+	 * pcl_weights list. But, the channel list is populated using
+     * policy_mgr_get_connection_channels(), the order of weights to be used
+     * is passed as an argument to the function
+     * policy_mgr_get_connection_channels() using
+     * 'enum policy_mgr_pcl_group_id' which indicates the next available
+     * weights to be used and policy_mgr_get_connection_channels() will take
+     * care of the weight assignments.
+	 *
+     * e.g., 'enum policy_mgr_pcl_group_id' value of
+     * POLICY_MGR_PCL_GROUP_ID2_ID3 indicates that the next available groups
+     * for weight assignment are WEIGHT_OF_GROUP2_PCL_CHANNELS and
+     * WEIGHT_OF_GROUP3_PCL_CHANNELS and that the
+     * weight WEIGHT_OF_GROUP1_PCL_CHANNELS was already allocated.
+     * So, in the same example, when order is
+     * POLICY_MGR_PCL_ORDER_24G_THEN_5G,
+	 * policy_mgr_get_connection_channels() will assign the weight
+	 * WEIGHT_OF_GROUP2_PCL_CHANNELS to 2.4GHz channels and assign the
+	 * weight WEIGHT_OF_GROUP3_PCL_CHANNELS to 5GHz channels.
+	 */
+	switch (pcl) {
+	case PM_24G:
+		chan_index_24 = QDF_MIN(chan_index_24, weight_len);
+		qdf_mem_copy(pcl_channels, channel_list_24,
+			chan_index_24);
+		*len = chan_index_24;
+		for (i = 0; i < *len; i++)
+			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_5G:
+		chan_index_5 = QDF_MIN(chan_index_5, weight_len);
+		qdf_mem_copy(pcl_channels, channel_list_5,
+			chan_index_5);
+		*len = chan_index_5;
+		for (i = 0; i < *len; i++)
+			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_CH:
+	case PM_MCC_CH:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list, num_channels);
+		*len = num_channels;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_CH_24G:
+	case PM_MCC_CH_24G:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list, num_channels);
+		*len = num_channels;
+		chan_index_24 = QDF_MIN((num_channels + chan_index_24),
+					weight_len) - num_channels;
+		qdf_mem_copy(&pcl_channels[num_channels],
+			channel_list_24, chan_index_24);
+		*len += chan_index_24;
+		for (j = 0; j < chan_index_24; i++, j++)
+			pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_CH_5G:
+	case PM_MCC_CH_5G:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list,
+			num_channels);
+		*len = num_channels;
+		chan_index_5 = QDF_MIN((num_channels + chan_index_5),
+					weight_len) - num_channels;
+		qdf_mem_copy(&pcl_channels[num_channels],
+			channel_list_5, chan_index_5);
+		*len += chan_index_5;
+		for (j = 0; j < chan_index_5; i++, j++)
+			pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_24G_SCC_CH:
+	case PM_24G_MCC_CH:
+		chan_index_24 = QDF_MIN(chan_index_24, weight_len);
+		qdf_mem_copy(pcl_channels, channel_list_24,
+			chan_index_24);
+		*len = chan_index_24;
+		for (i = 0; i < chan_index_24; i++)
+			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID2_ID3);
+		qdf_mem_copy(&pcl_channels[chan_index_24],
+			channel_list, num_channels);
+		*len += num_channels;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_5G_SCC_CH:
+	case PM_5G_MCC_CH:
+		chan_index_5 = QDF_MIN(chan_index_5, weight_len);
+		qdf_mem_copy(pcl_channels, channel_list_5,
+			chan_index_5);
+		*len = chan_index_5;
+		for (i = 0; i < chan_index_5; i++)
+			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID2_ID3);
+		qdf_mem_copy(&pcl_channels[chan_index_5],
+			channel_list, num_channels);
+		*len += num_channels;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_24_SCC_ON_5:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels,
+			POLICY_MGR_PCL_ORDER_24G_THEN_5G,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list,
+			num_channels);
+		*len = num_channels;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_SCC_ON_24:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels,
+			POLICY_MGR_PCL_ORDER_5G_THEN_2G,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list, num_channels);
+		*len = num_channels;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_24_SCC_ON_5_24G:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels,
+			POLICY_MGR_PCL_ORDER_24G_THEN_5G,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list, num_channels);
+		*len = num_channels;
+		chan_index_24 = QDF_MIN((num_channels + chan_index_24),
+					weight_len) - num_channels;
+		qdf_mem_copy(&pcl_channels[num_channels],
+			channel_list_24, chan_index_24);
+		*len += chan_index_24;
+		for (j = 0; j < chan_index_24; i++, j++)
+			pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_24_SCC_ON_5_5G:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels,
+			POLICY_MGR_PCL_ORDER_24G_THEN_5G,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list, num_channels);
+		*len = num_channels;
+		chan_index_5 = QDF_MIN((num_channels + chan_index_5),
+					weight_len) - num_channels;
+		qdf_mem_copy(&pcl_channels[num_channels],
+			channel_list_5, chan_index_5);
+		*len += chan_index_5;
+		for (j = 0; j < chan_index_5; i++, j++)
+			pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_SCC_ON_24_24G:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels,
+			POLICY_MGR_PCL_ORDER_5G_THEN_2G,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list, num_channels);
+		*len = num_channels;
+		chan_index_24 = QDF_MIN((num_channels + chan_index_24),
+					weight_len) - num_channels;
+		qdf_mem_copy(&pcl_channels[num_channels],
+			channel_list_24, chan_index_24);
+		*len += chan_index_24;
+		for (j = 0; j < chan_index_24; i++, j++)
+			pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_SCC_ON_24_5G:
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels,
+			POLICY_MGR_PCL_ORDER_5G_THEN_2G,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID1_ID2);
+		qdf_mem_copy(pcl_channels, channel_list, num_channels);
+		*len = num_channels;
+		chan_index_5 = QDF_MIN((num_channels + chan_index_5),
+					weight_len) - num_channels;
+		qdf_mem_copy(&pcl_channels[num_channels],
+			channel_list_5, chan_index_5);
+		*len += chan_index_5;
+		for (j = 0; j < chan_index_5; i++, j++)
+			pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_24G_SCC_CH_SBS_CH:
+		qdf_mem_copy(pcl_channels, channel_list_24,
+			chan_index_24);
+		*len = chan_index_24;
+		for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++)
+			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID2_ID3);
+		qdf_mem_copy(&pcl_channels[chan_index_24],
+			channel_list, num_channels);
+		*len += num_channels;
+		if (policy_mgr_is_hw_sbs_capable(psoc)) {
+			policy_mgr_get_sbs_channels(
+			sbs_channel_list, &sbs_num_channels, pcl_weights,
+			weight_len, &i, POLICY_MGR_PCL_GROUP_ID3_ID4,
+			channel_list_5, chan_index_5, false);
+			qdf_mem_copy(
+				&pcl_channels[chan_index_24 + num_channels],
+				sbs_channel_list, sbs_num_channels);
+			*len += sbs_num_channels;
+		}
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_24G_SCC_CH_SBS_CH_5G:
+		qdf_mem_copy(pcl_channels, channel_list_24,
+			chan_index_24);
+		*len = chan_index_24;
+		for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++)
+			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID2_ID3);
+		qdf_mem_copy(&pcl_channels[chan_index_24],
+			channel_list, num_channels);
+		*len += num_channels;
+		if (policy_mgr_is_hw_sbs_capable(psoc)) {
+			policy_mgr_get_sbs_channels(
+			sbs_channel_list, &sbs_num_channels, pcl_weights,
+			weight_len, &i, POLICY_MGR_PCL_GROUP_ID3_ID4,
+			channel_list_5, chan_index_5, true);
+			qdf_mem_copy(
+				&pcl_channels[chan_index_24 + num_channels],
+				sbs_channel_list, sbs_num_channels);
+			*len += sbs_num_channels;
+		} else {
+			qdf_mem_copy(
+				&pcl_channels[chan_index_24 + num_channels],
+				channel_list_5, chan_index_5);
+			*len += chan_index_5;
+			for (i = chan_index_24 + num_channels;
+				((i < *len) && (i < weight_len)); i++)
+				pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
+		}
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_24G_SBS_CH_MCC_CH:
+		qdf_mem_copy(pcl_channels, channel_list_24,
+			chan_index_24);
+		*len = chan_index_24;
+		for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++)
+			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		if (policy_mgr_is_hw_sbs_capable(psoc)) {
+			policy_mgr_get_sbs_channels(
+			sbs_channel_list, &sbs_num_channels, pcl_weights,
+			weight_len, &i, POLICY_MGR_PCL_GROUP_ID2_ID3,
+			channel_list_5, chan_index_5, false);
+			qdf_mem_copy(&pcl_channels[num_channels],
+			sbs_channel_list, sbs_num_channels);
+			*len += sbs_num_channels;
+		}
+		policy_mgr_get_connection_channels(psoc,
+			channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE,
+			skip_dfs_channel, pcl_weights, weight_len, &i,
+			POLICY_MGR_PCL_GROUP_ID2_ID3);
+		qdf_mem_copy(&pcl_channels[chan_index_24],
+			channel_list, num_channels);
+		*len += num_channels;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH_5G:
+		if (policy_mgr_is_hw_sbs_capable(psoc)) {
+			policy_mgr_get_sbs_channels(
+			sbs_channel_list, &sbs_num_channels, pcl_weights,
+			weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2,
+			channel_list_5, chan_index_5, true);
+			qdf_mem_copy(&pcl_channels[num_channels],
+			sbs_channel_list, sbs_num_channels);
+			*len += sbs_num_channels;
+		} else {
+			qdf_mem_copy(pcl_channels, channel_list_5,
+			chan_index_5);
+			*len = chan_index_5;
+			for (i = 0; ((i < *len) && (i < weight_len)); i++)
+				pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+		}
+		status = QDF_STATUS_SUCCESS;
+		break;
+	default:
+		policy_mgr_err("unknown pcl value %d", pcl);
+		break;
+	}
+
+	if ((*len != 0) && (*len != i))
+		policy_mgr_debug("pcl len (%d) and weight list len mismatch (%d)",
+			*len, i);
+
+	/* check the channel avoidance list for beaconing entities */
+	if ((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE))
+		policy_mgr_update_with_safe_channel_list(psoc, pcl_channels,
+							 len, pcl_weights,
+							 weight_len);
+
+	policy_mgr_set_weight_of_dfs_passive_channels_to_zero(psoc,
+			pcl_channels, len, pcl_weights, weight_len);
+	return status;
+}
+
+/**
+ * policy_mgr_disallow_mcc() - Check for mcc
+ *
+ * @channel: channel on which new connection is coming up
+ *
+ * When a new connection is about to come up check if current
+ * concurrency combination including the new connection is
+ * causing MCC
+ *
+ * Return: True/False
+ */
+bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc,
+		uint8_t channel)
+{
+	uint32_t index = 0;
+	bool match = false;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return match;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(index)) {
+		if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
+			if (pm_conc_connection_list[index].chan !=
+				channel) {
+				match = true;
+				break;
+			}
+		} else if (WLAN_REG_IS_5GHZ_CH
+			(pm_conc_connection_list[index].chan)) {
+			if (pm_conc_connection_list[index].chan != channel) {
+				match = true;
+				break;
+			}
+		}
+		index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return match;
+}
+
+/**
+ * policy_mgr_allow_new_home_channel() - Check for allowed number of
+ * home channels
+ * @channel: channel on which new connection is coming up
+ * @num_connections: number of current connections
+ *
+ * When a new connection is about to come up check if current
+ * concurrency combination including the new connection is
+ * allowed or not based on the HW capability
+ *
+ * Return: True/False
+ */
+bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc,
+			uint8_t channel, uint32_t num_connections)
+{
+	bool status = true;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t mcc_to_scc_switch;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	mcc_to_scc_switch =
+		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (num_connections == 2) {
+	/* No SCC or MCC combination is allowed with / on DFS channel */
+		if ((mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)
+		&& wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) &&
+		(wlan_reg_is_dfs_ch(pm_ctx->pdev,
+			pm_conc_connection_list[0].chan) ||
+		wlan_reg_is_dfs_ch(pm_ctx->pdev,
+			pm_conc_connection_list[1].chan))) {
+
+			policy_mgr_err("Existing DFS connection, new 3-port DFS connection is not allowed");
+			status = false;
+
+		} else if (((pm_conc_connection_list[0].chan !=
+				pm_conc_connection_list[1].chan)
+		|| (mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)
+		) && (pm_conc_connection_list[0].mac ==
+			pm_conc_connection_list[1].mac)) {
+			if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
+				if ((channel !=
+				     pm_conc_connection_list[0].chan) &&
+				    (channel !=
+				     pm_conc_connection_list[1].chan)) {
+					policy_mgr_err("don't allow 3rd home channel on same MAC");
+					status = false;
+				}
+			} else if (((WLAN_REG_IS_24GHZ_CH(channel)) &&
+				(WLAN_REG_IS_24GHZ_CH
+				(pm_conc_connection_list[0].chan)) &&
+				(WLAN_REG_IS_24GHZ_CH
+				(pm_conc_connection_list[1].chan))) ||
+				   ((WLAN_REG_IS_5GHZ_CH(channel)) &&
+				(WLAN_REG_IS_5GHZ_CH
+				(pm_conc_connection_list[0].chan)) &&
+				(WLAN_REG_IS_5GHZ_CH
+				(pm_conc_connection_list[1].chan)))) {
+					policy_mgr_err("don't allow 3rd home channel on same MAC");
+					status = false;
+			}
+		}
+	} else if ((num_connections == 1)
+		&& (mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)
+		&& wlan_reg_is_dfs_ch(pm_ctx->pdev, channel)
+		&& wlan_reg_is_dfs_ch(pm_ctx->pdev,
+			pm_conc_connection_list[0].chan)) {
+
+		policy_mgr_err("Existing DFS connection, new 2-port DFS connection is not allowed");
+		status = false;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+/**
+ * policy_mgr_is_5g_channel_allowed() - check if 5g channel is allowed
+ * @channel: channel number which needs to be validated
+ * @list: list of existing connections.
+ * @mode: mode against which channel needs to be validated
+ *
+ * This API takes the channel as input and compares with existing
+ * connection channels. If existing connection's channel is DFS channel
+ * and provided channel is 5G channel then don't allow concurrency to
+ * happen as MCC with DFS channel is not yet supported
+ *
+ * Return: true if 5G channel is allowed, false if not allowed
+ *
+ */
+bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc,
+				uint8_t channel, uint32_t *list,
+				enum policy_mgr_con_mode mode)
+{
+	uint32_t index = 0, count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	count = policy_mgr_mode_specific_connection_count(psoc, mode, list);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	while (index < count) {
+		if (wlan_reg_is_dfs_ch(
+			pm_ctx->pdev,
+			pm_conc_connection_list[list[index]].chan) &&
+		    WLAN_REG_IS_5GHZ_CH(channel) &&
+		    (channel != pm_conc_connection_list[list[index]].chan)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			policy_mgr_err("don't allow MCC if SAP/GO on DFS channel");
+			return false;
+		}
+		index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return true;
+}
+
+/**
+ * policy_mgr_nss_update_cb() - callback from SME confirming nss
+ * update
+ * @hdd_ctx:	HDD Context
+ * @tx_status: tx completion status for updated beacon with new
+ *		nss value
+ * @vdev_id: vdev id for the specific connection
+ * @next_action: next action to happen at policy mgr after
+ *		beacon update
+ * @reason: Reason for nss update
+ * @original_vdev_id: original request hwmode change vdev id
+ *
+ * This function is the callback registered with SME at nss
+ * update request time
+ *
+ * Return: None
+ */
+static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc,
+		uint8_t tx_status,
+		uint8_t vdev_id,
+		uint8_t next_action,
+		enum policy_mgr_conn_update_reason reason,
+		uint32_t original_vdev_id)
+{
+	uint32_t conn_index = 0;
+	QDF_STATUS ret;
+
+	if (QDF_STATUS_SUCCESS != tx_status)
+		policy_mgr_err("nss update failed(%d) for vdev %d",
+			tx_status, vdev_id);
+
+	/*
+	 * Check if we are ok to request for HW mode change now
+	 */
+	conn_index = policy_mgr_get_connection_for_vdev_id(psoc, vdev_id);
+	if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
+		policy_mgr_err("connection not found for vdev %d", vdev_id);
+		return;
+	}
+
+	policy_mgr_debug("nss update successful for vdev:%d ori %d reason %d",
+			 vdev_id, original_vdev_id, reason);
+	if (PM_NOP != next_action)
+		policy_mgr_next_actions(psoc, original_vdev_id, next_action,
+					reason);
+	else {
+		policy_mgr_debug("No action needed right now");
+		ret = policy_mgr_set_opportunistic_update(psoc);
+		if (!QDF_IS_STATUS_SUCCESS(ret))
+			policy_mgr_err("ERROR: set opportunistic_update event failed");
+	}
+
+	return;
+}
+
+QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc,
+		uint8_t  new_nss, uint8_t next_action,
+		enum policy_mgr_band band,
+		enum policy_mgr_conn_update_reason reason,
+		uint32_t original_vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t index, count;
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t conn_index = 0;
+	uint32_t vdev_id;
+	uint32_t original_nss;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t chan;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	count = policy_mgr_mode_specific_connection_count(psoc,
+			PM_P2P_GO_MODE, list);
+	for (index = 0; index < count; index++) {
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		vdev_id = pm_conc_connection_list[list[index]].vdev_id;
+		original_nss =
+		pm_conc_connection_list[list[index]].original_nss;
+		chan = pm_conc_connection_list[list[index]].chan;
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		conn_index = policy_mgr_get_connection_for_vdev_id(
+			psoc, vdev_id);
+		if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
+			policy_mgr_err("connection not found for vdev %d",
+				vdev_id);
+			continue;
+		}
+
+		if (original_nss == 2 &&
+		    (band == POLICY_MGR_ANY ||
+		    (band == POLICY_MGR_BAND_24 &&
+		    WLAN_REG_IS_24GHZ_CH(chan)) ||
+		    (band == POLICY_MGR_BAND_5 &&
+		    WLAN_REG_IS_5GHZ_CH(chan)))) {
+			status = pm_ctx->sme_cbacks.sme_nss_update_request(
+					vdev_id, new_nss,
+					policy_mgr_nss_update_cb,
+					next_action, psoc, reason,
+					original_vdev_id);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				policy_mgr_err("sme_nss_update_request() failed for vdev %d",
+				vdev_id);
+			}
+		}
+	}
+
+	count = policy_mgr_mode_specific_connection_count(psoc,
+			PM_SAP_MODE, list);
+	for (index = 0; index < count; index++) {
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		vdev_id = pm_conc_connection_list[list[index]].vdev_id;
+		original_nss =
+		pm_conc_connection_list[list[index]].original_nss;
+		chan = pm_conc_connection_list[list[index]].chan;
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		conn_index = policy_mgr_get_connection_for_vdev_id(
+			psoc, vdev_id);
+		if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
+			policy_mgr_err("connection not found for vdev %d",
+				vdev_id);
+			continue;
+		}
+		if (original_nss == 2 &&
+		    (band == POLICY_MGR_ANY ||
+		    (band == POLICY_MGR_BAND_24 &&
+		    WLAN_REG_IS_24GHZ_CH(chan)) ||
+		    (band == POLICY_MGR_BAND_5 &&
+		    WLAN_REG_IS_5GHZ_CH(chan)))) {
+			status = pm_ctx->sme_cbacks.sme_nss_update_request(
+					vdev_id, new_nss,
+					policy_mgr_nss_update_cb,
+					next_action, psoc, reason,
+					original_vdev_id);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				policy_mgr_err("sme_nss_update_request() failed for vdev %d",
+				vdev_id);
+			}
+		}
+	}
+
+	return status;
+}
+
+/**
+ * policy_mgr_complete_action() - initiates actions needed on
+ * current connections once channel has been decided for the new
+ * connection
+ * @new_nss: the new nss value
+ * @next_action: next action to happen at policy mgr after
+ *		beacon update
+ * @reason: Reason for connection update
+ * @session_id: Session id
+ *
+ * This function initiates initiates actions
+ * needed on current connections once channel has been decided
+ * for the new connection. Notifies UMAC & FW as well
+ *
+ * Return: QDF_STATUS enum
+ */
+QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc,
+				uint8_t  new_nss, uint8_t next_action,
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	enum policy_mgr_band downgrade_band;
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
+		policy_mgr_err("driver isn't dbs capable, no further action needed");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	/* policy_mgr_complete_action() is called by policy_mgr_next_actions().
+	 * All other callers of policy_mgr_next_actions() have taken mutex
+	 * protection. So, not taking any lock inside
+	 * policy_mgr_complete_action() during pm_conc_connection_list access.
+	 */
+	if (next_action == PM_DBS1)
+		downgrade_band = POLICY_MGR_BAND_24;
+	else if (next_action == PM_DBS2)
+		downgrade_band = POLICY_MGR_BAND_5;
+	else
+		downgrade_band = POLICY_MGR_ANY;
+
+	status = policy_mgr_nss_update(psoc, new_nss, next_action,
+				       downgrade_band, reason,
+				       session_id);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		status = policy_mgr_next_actions(psoc, session_id,
+						next_action, reason);
+
+	return status;
+}
+
+enum policy_mgr_con_mode policy_mgr_get_mode_by_vdev_id(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id)
+{
+	enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_index;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return mode;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		conn_index++)
+		if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) &&
+			pm_conc_connection_list[conn_index].in_use){
+				mode = pm_conc_connection_list[conn_index].mode;
+				break;
+		}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return mode;
+}
+
+/**
+ * policy_mgr_init_connection_update() - Initialize connection
+ * update event
+ * @pm_ctx: policy mgr context
+ *
+ * Initializes the concurrent connection update event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_init_connection_update(
+		struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	QDF_STATUS qdf_status;
+
+	qdf_status = qdf_event_create(&pm_ctx->connection_update_done_evt);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		policy_mgr_err("init event failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_get_current_pref_hw_mode_dbs_2x2() - Get the
+ * current preferred hw mode
+ *
+ * Get the preferred hw mode based on the current connection combinations
+ *
+ * Return: No change (PM_NOP), MCC (PM_SINGLE_MAC),
+ *         DBS (PM_DBS), SBS (PM_SBS)
+ */
+enum policy_mgr_conc_next_action
+		policy_mgr_get_current_pref_hw_mode_dbs_2x2(
+		struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t num_connections;
+	uint8_t band1, band2, band3;
+	struct policy_mgr_hw_mode_params hw_mode;
+	QDF_STATUS status;
+
+	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
+		return PM_NOP;
+	}
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+
+	policy_mgr_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d",
+		pm_conc_connection_list[0].chan,
+		pm_conc_connection_list[1].chan,
+		pm_conc_connection_list[2].chan, num_connections,
+		hw_mode.dbs_cap);
+
+	/* If the band of operation of both the MACs is the same,
+	 * single MAC is preferred, otherwise DBS is preferred.
+	 */
+	switch (num_connections) {
+	case 1:
+		band1 = reg_chan_to_band(pm_conc_connection_list[0].chan);
+		if (band1 == BAND_2G)
+			return PM_DBS;
+		else
+			return PM_NOP;
+	case 2:
+		band1 = reg_chan_to_band(pm_conc_connection_list[0].chan);
+		band2 = reg_chan_to_band(pm_conc_connection_list[1].chan);
+		if ((band1 == BAND_2G) ||
+			(band2 == BAND_2G)) {
+			if (!hw_mode.dbs_cap)
+				return PM_DBS;
+			else
+				return PM_NOP;
+		} else if ((band1 == BAND_5G) &&
+				(band2 == BAND_5G)) {
+			if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS(
+				pm_conc_connection_list[0].chan,
+				pm_conc_connection_list[1].chan)) {
+				if (!hw_mode.sbs_cap)
+					return PM_SBS;
+				else
+					return PM_NOP;
+			} else {
+				if (hw_mode.sbs_cap || hw_mode.dbs_cap)
+					return PM_SINGLE_MAC;
+				else
+					return PM_NOP;
+			}
+		} else
+			return PM_NOP;
+	case 3:
+		band1 = reg_chan_to_band(pm_conc_connection_list[0].chan);
+		band2 = reg_chan_to_band(pm_conc_connection_list[1].chan);
+		band3 = reg_chan_to_band(pm_conc_connection_list[2].chan);
+		if ((band1 == BAND_2G) ||
+			(band2 == BAND_2G) ||
+			(band3 == BAND_2G)) {
+			if (!hw_mode.dbs_cap)
+				return PM_DBS;
+			else
+				return PM_NOP;
+		} else if ((band1 == BAND_5G) &&
+				(band2 == BAND_5G) &&
+					(band3 == BAND_5G)) {
+			if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS(
+				pm_conc_connection_list[0].chan,
+				pm_conc_connection_list[2].chan) &&
+				WLAN_REG_IS_CHANNEL_VALID_5G_SBS(
+				pm_conc_connection_list[1].chan,
+				pm_conc_connection_list[2].chan) &&
+				WLAN_REG_IS_CHANNEL_VALID_5G_SBS(
+				pm_conc_connection_list[0].chan,
+				pm_conc_connection_list[1].chan)) {
+				if (!hw_mode.sbs_cap)
+					return PM_SBS;
+				else
+					return PM_NOP;
+			} else {
+				if (hw_mode.sbs_cap || hw_mode.dbs_cap)
+					return PM_SINGLE_MAC;
+				else
+					return PM_NOP;
+			}
+		} else
+			return PM_NOP;
+	default:
+		policy_mgr_err("unexpected num_connections value %d",
+				num_connections);
+		return PM_NOP;
+	}
+}
+
+/**
+ * policy_mgr_get_current_pref_hw_mode_dbs_1x1() - Get the
+ * current preferred hw mode
+ *
+ * Get the preferred hw mode based on the current connection combinations
+ *
+ * Return: No change (PM_NOP), MCC (PM_SINGLE_MAC_UPGRADE),
+ *         DBS (PM_DBS_DOWNGRADE)
+ */
+enum policy_mgr_conc_next_action
+		policy_mgr_get_current_pref_hw_mode_dbs_1x1(
+		struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t num_connections;
+	uint8_t band1, band2, band3;
+	struct policy_mgr_hw_mode_params hw_mode;
+	QDF_STATUS status;
+	enum policy_mgr_conc_next_action next_action;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return PM_NOP;
+	}
+
+	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
+		return PM_NOP;
+	}
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d",
+		pm_conc_connection_list[0].chan,
+		pm_conc_connection_list[1].chan,
+		pm_conc_connection_list[2].chan, num_connections,
+		hw_mode.dbs_cap);
+
+	/* If the band of operation of both the MACs is the same,
+	 * single MAC is preferred, otherwise DBS is preferred.
+	 */
+	switch (num_connections) {
+	case 1:
+		/* The driver would already be in the required hw mode */
+		next_action = PM_NOP;
+		break;
+	case 2:
+		band1 = reg_chan_to_band(pm_conc_connection_list[0].chan);
+		band2 = reg_chan_to_band(pm_conc_connection_list[1].chan);
+		if ((band1 == band2) && (hw_mode.dbs_cap))
+			next_action = PM_SINGLE_MAC_UPGRADE;
+		else if ((band1 != band2) && (!hw_mode.dbs_cap))
+			next_action = PM_DBS_DOWNGRADE;
+		else
+			next_action = PM_NOP;
+
+		break;
+
+	case 3:
+		band1 = reg_chan_to_band(pm_conc_connection_list[0].chan);
+		band2 = reg_chan_to_band(pm_conc_connection_list[1].chan);
+		band3 = reg_chan_to_band(pm_conc_connection_list[2].chan);
+		if (((band1 == band2) && (band2 == band3)) &&
+				(hw_mode.dbs_cap)) {
+			next_action = PM_SINGLE_MAC_UPGRADE;
+		} else if (((band1 != band2) || (band2 != band3) ||
+					(band1 != band3)) &&
+					(!hw_mode.dbs_cap)) {
+			next_action = PM_DBS_DOWNGRADE;
+		} else {
+			next_action = PM_NOP;
+		}
+		break;
+	default:
+		policy_mgr_err("unexpected num_connections value %d",
+				num_connections);
+		next_action = PM_NOP;
+		break;
+	}
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return next_action;
+}
+
+enum policy_mgr_conc_next_action
+policy_mgr_get_current_pref_hw_mode_dual_dbs(
+	struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_conc_next_action next_action;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum policy_mgr_conc_next_action preferred_dbs;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return PM_NOP;
+	}
+
+	next_action = policy_mgr_get_current_pref_hw_mode_dbs_1x1(psoc);
+	policy_mgr_info("next_action %d", next_action);
+	if (next_action != PM_DBS_DOWNGRADE)
+		return next_action;
+
+	preferred_dbs = policy_mgr_get_preferred_dbs_action_table(
+				psoc, INVALID_VDEV_ID, 0, 0);
+	if (preferred_dbs == PM_DBS1) {
+		next_action = PM_DBS1_DOWNGRADE;
+	} else if (preferred_dbs == PM_DBS2) {
+		next_action = PM_DBS2_DOWNGRADE;
+	} else {
+		policy_mgr_err("DBS1 and DBS2 hw mode not supported");
+		return PM_NOP;
+	}
+	policy_mgr_info("preferred_dbs %d", next_action);
+	return next_action;
+}
+
+/**
+ * policy_mgr_reset_sap_mandatory_channels() - Reset the SAP mandatory channels
+ *
+ * Resets the SAP mandatory channel list and the length of the list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_reset_sap_mandatory_channels(
+		struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	pm_ctx->sap_mandatory_channels_len = 0;
+	qdf_mem_zero(pm_ctx->sap_mandatory_channels,
+		QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_enable_disable_sap_mandatory_chan_list(
+		struct wlan_objmgr_psoc *psoc, bool val)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	pm_ctx->enable_sap_mandatory_chan_list = val;
+}
+
+void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+		uint8_t chan)
+{
+	int i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) {
+		if (chan == pm_ctx->sap_mandatory_channels[i])
+			return;
+	}
+
+	policy_mgr_debug("chan %hu", chan);
+	pm_ctx->sap_mandatory_channels[pm_ctx->sap_mandatory_channels_len++]
+		= chan;
+}
+
+bool policy_mgr_is_sap_mandatory_chan_list_enabled(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	return pm_ctx->enable_sap_mandatory_chan_list;
+}
+
+uint32_t policy_mgr_get_sap_mandatory_chan_list_len(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+
+	return pm_ctx->sap_mandatory_channels_len;
+}
+
+void  policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t chan_list[QDF_MAX_NUM_CHAN] = {0};
+	uint32_t len = 0;
+	int i;
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	status = policy_mgr_get_valid_chans(psoc, chan_list, &len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Error in getting valid channels");
+		return;
+	}
+	pm_ctx->sap_mandatory_channels_len = 0;
+
+	for (i = 0; (i < len) && (i < QDF_MAX_NUM_CHAN); i++) {
+		if (WLAN_REG_IS_24GHZ_CH(chan_list[i])) {
+			policy_mgr_debug("Add chan %hu to mandatory list",
+					chan_list[i]);
+			pm_ctx->sap_mandatory_channels[
+				pm_ctx->sap_mandatory_channels_len++] =
+				chan_list[i];
+		}
+	}
+}
+
+void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+		uint8_t chan)
+{
+	uint8_t chan_list[QDF_MAX_NUM_CHAN] = {0};
+	uint32_t num_chan = 0;
+	int i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (pm_ctx->sap_mandatory_channels_len >= QDF_MAX_NUM_CHAN) {
+		policy_mgr_err("Invalid channel len %d ",
+				pm_ctx->sap_mandatory_channels_len);
+		return;
+	}
+
+	for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) {
+		if (chan == pm_ctx->sap_mandatory_channels[i])
+			continue;
+		chan_list[num_chan++] = pm_ctx->sap_mandatory_channels[i];
+	}
+
+	qdf_mem_zero(pm_ctx->sap_mandatory_channels,
+			pm_ctx->sap_mandatory_channels_len);
+	qdf_mem_copy(pm_ctx->sap_mandatory_channels, chan_list, num_chan);
+	pm_ctx->sap_mandatory_channels_len = num_chan;
+}

+ 3463 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -0,0 +1,3463 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_policy_mgr_get_set_utils.c
+ *
+ * WLAN Concurrenct Connection Management APIs
+ *
+ */
+
+/* Include files */
+#include "target_if.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_policy_mgr_i.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+
+/* invalid channel id. */
+#define INVALID_CHANNEL_ID 0
+
+QDF_STATUS policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *mcc_scc_switch)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*mcc_scc_switch = pm_ctx->cfg.mcc_to_scc_switch;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc,
+					uint8_t *sys_pref)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*sys_pref = pm_ctx->cfg.sys_pref;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc,
+				   uint8_t sys_pref)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pm_ctx->cfg.sys_pref = sys_pref;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
+						uint8_t *max_conc_cxns)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*max_conc_cxns = pm_ctx->cfg.max_conc_cxns;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc,
+						uint8_t *conc_rule1)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*conc_rule1 = pm_ctx->cfg.conc_rule1;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc,
+						uint8_t *conc_rule2)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*conc_rule2 = pm_ctx->cfg.conc_rule2;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc,
+						uint32_t *dbs_selection_plcy)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*dbs_selection_plcy = pm_ctx->cfg.dbs_selection_plcy;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc,
+						uint32_t *vdev_priority_list)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*vdev_priority_list = pm_ctx->cfg.vdev_priority_list;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc,
+						uint32_t *chnl_select_plcy)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*chnl_select_plcy = pm_ctx->cfg.chnl_select_plcy;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
+					   uint8_t *enable_mcc_adaptive_sch)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*enable_mcc_adaptive_sch = pm_ctx->cfg.enable_mcc_adaptive_sch;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *enable_sta_cxn_5g_band)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*enable_sta_cxn_5g_band = pm_ctx->cfg.enable_sta_cxn_5g_band;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc,
+		uint32_t new_hw_mode_index)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	pm_ctx->new_hw_mode_index = new_hw_mode_index;
+}
+
+void policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc *psoc,
+		uint32_t old_hw_mode_index)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	pm_ctx->old_hw_mode_index = old_hw_mode_index;
+}
+
+void policy_mgr_update_hw_mode_index(struct wlan_objmgr_psoc *psoc,
+		uint32_t new_hw_mode_index)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	if (POLICY_MGR_DEFAULT_HW_MODE_INDEX == pm_ctx->new_hw_mode_index) {
+		pm_ctx->new_hw_mode_index = new_hw_mode_index;
+	} else {
+		pm_ctx->old_hw_mode_index = pm_ctx->new_hw_mode_index;
+		pm_ctx->new_hw_mode_index = new_hw_mode_index;
+	}
+	policy_mgr_debug("Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
+		pm_ctx->old_hw_mode_index, pm_ctx->new_hw_mode_index);
+}
+
+/**
+ * policy_mgr_get_num_of_setbits_from_bitmask() - to get num of
+ * setbits from bitmask
+ * @mask: given bitmask
+ *
+ * This helper function should return number of setbits from bitmask
+ *
+ * Return: number of setbits from bitmask
+ */
+static uint32_t policy_mgr_get_num_of_setbits_from_bitmask(uint32_t mask)
+{
+	uint32_t num_of_setbits = 0;
+
+	while (mask) {
+		mask &= (mask - 1);
+		num_of_setbits++;
+	}
+	return num_of_setbits;
+}
+
+/**
+ * policy_mgr_map_wmi_channel_width_to_hw_mode_bw() - returns
+ * bandwidth in terms of hw_mode_bandwidth
+ * @width: bandwidth in terms of wmi_channel_width
+ *
+ * This function returns the bandwidth in terms of hw_mode_bandwidth.
+ *
+ * Return: BW in terms of hw_mode_bandwidth.
+ */
+static enum hw_mode_bandwidth policy_mgr_map_wmi_channel_width_to_hw_mode_bw(
+		wmi_channel_width width)
+{
+	switch (width) {
+	case WMI_CHAN_WIDTH_20:
+		return HW_MODE_20_MHZ;
+	case WMI_CHAN_WIDTH_40:
+		return HW_MODE_40_MHZ;
+	case WMI_CHAN_WIDTH_80:
+		return HW_MODE_80_MHZ;
+	case WMI_CHAN_WIDTH_160:
+		return HW_MODE_160_MHZ;
+	case WMI_CHAN_WIDTH_80P80:
+		return HW_MODE_80_PLUS_80_MHZ;
+	case WMI_CHAN_WIDTH_5:
+		return HW_MODE_5_MHZ;
+	case WMI_CHAN_WIDTH_10:
+		return HW_MODE_10_MHZ;
+	default:
+		return HW_MODE_BW_NONE;
+	}
+
+	return HW_MODE_BW_NONE;
+}
+
+static void policy_mgr_get_hw_mode_params(
+		struct wlan_psoc_host_mac_phy_caps *caps,
+		struct policy_mgr_mac_ss_bw_info *info)
+{
+	if (!caps) {
+		policy_mgr_err("Invalid capabilities");
+		return;
+	}
+
+	info->mac_tx_stream = policy_mgr_get_num_of_setbits_from_bitmask(
+		QDF_MAX(caps->tx_chain_mask_2G,
+		caps->tx_chain_mask_5G));
+	info->mac_rx_stream = policy_mgr_get_num_of_setbits_from_bitmask(
+		QDF_MAX(caps->rx_chain_mask_2G,
+		caps->rx_chain_mask_5G));
+	info->mac_bw = policy_mgr_map_wmi_channel_width_to_hw_mode_bw(
+		QDF_MAX(caps->max_bw_supported_2G,
+		caps->max_bw_supported_5G));
+	info->mac_band_cap = caps->supported_bands;
+}
+
+/**
+ * policy_mgr_set_hw_mode_params() - sets TX-RX stream,
+ * bandwidth and DBS in hw_mode_list
+ * @wma_handle: pointer to wma global structure
+ * @mac0_ss_bw_info: TX-RX streams, BW for MAC0
+ * @mac1_ss_bw_info: TX-RX streams, BW for MAC1
+ * @pos: refers to hw_mode_list array index
+ * @hw_mode_id: hw mode id value used by firmware
+ * @dbs_mode: dbs_mode for the dbs_hw_mode
+ * @sbs_mode: sbs_mode for the sbs_hw_mode
+ *
+ * This function sets TX-RX stream, bandwidth and DBS mode in
+ * hw_mode_list.
+ *
+ * Return: none
+ */
+static void policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc *psoc,
+			struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info,
+			struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info,
+			uint32_t pos, uint32_t hw_mode_id, uint32_t dbs_mode,
+			uint32_t sbs_mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		mac0_ss_bw_info.mac_tx_stream);
+	POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		mac0_ss_bw_info.mac_rx_stream);
+	POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		mac0_ss_bw_info.mac_bw);
+	POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		mac1_ss_bw_info.mac_tx_stream);
+	POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		mac1_ss_bw_info.mac_rx_stream);
+	POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		mac1_ss_bw_info.mac_bw);
+	POLICY_MGR_HW_MODE_DBS_MODE_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		dbs_mode);
+	POLICY_MGR_HW_MODE_AGILE_DFS_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		HW_MODE_AGILE_DFS_NONE);
+	POLICY_MGR_HW_MODE_SBS_MODE_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		sbs_mode);
+	POLICY_MGR_HW_MODE_MAC0_BAND_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		mac0_ss_bw_info.mac_band_cap);
+	POLICY_MGR_HW_MODE_ID_SET(
+		pm_ctx->hw_mode.hw_mode_list[pos],
+		hw_mode_id);
+}
+
+QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc,
+					  struct target_psoc_info *tgt_hdl)
+{
+	struct wlan_psoc_host_mac_phy_caps *tmp;
+	uint32_t i, hw_config_type, j = 0;
+	uint32_t dbs_mode, sbs_mode;
+	struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info = {0};
+	struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info = {0};
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct tgt_info *info;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	info = &tgt_hdl->info;
+	if (!info->service_ext_param.num_hw_modes) {
+		policy_mgr_err("Number of HW modes: %d",
+			       info->service_ext_param.num_hw_modes);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * This list was updated as part of service ready event. Re-populate
+	 * HW mode list from the device capabilities.
+	 */
+	if (pm_ctx->hw_mode.hw_mode_list) {
+		qdf_mem_free(pm_ctx->hw_mode.hw_mode_list);
+		pm_ctx->hw_mode.hw_mode_list = NULL;
+		policy_mgr_debug("DBS list is freed");
+	}
+
+	pm_ctx->num_dbs_hw_modes = info->service_ext_param.num_hw_modes;
+	pm_ctx->hw_mode.hw_mode_list =
+		qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) *
+		pm_ctx->num_dbs_hw_modes);
+	if (!pm_ctx->hw_mode.hw_mode_list) {
+		policy_mgr_err("Memory allocation failed for DBS");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_debug("Updated HW mode list: Num modes:%d",
+		pm_ctx->num_dbs_hw_modes);
+
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		/* Update for MAC0 */
+		tmp = &info->mac_phy_cap[j++];
+		policy_mgr_get_hw_mode_params(tmp, &mac0_ss_bw_info);
+		hw_config_type = tmp->hw_mode_config_type;
+		dbs_mode = HW_MODE_DBS_NONE;
+		sbs_mode = HW_MODE_SBS_NONE;
+		mac1_ss_bw_info.mac_tx_stream = 0;
+		mac1_ss_bw_info.mac_rx_stream = 0;
+		mac1_ss_bw_info.mac_bw = 0;
+
+		/* SBS and DBS have dual MAC. Upto 2 MACs are considered. */
+		if ((hw_config_type == WMI_HW_MODE_DBS) ||
+			(hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
+			(hw_config_type == WMI_HW_MODE_SBS)) {
+			/* Update for MAC1 */
+			tmp = &info->mac_phy_cap[j++];
+			policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
+			if (hw_config_type == WMI_HW_MODE_DBS)
+				dbs_mode = HW_MODE_DBS;
+			if ((hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
+				(hw_config_type == WMI_HW_MODE_SBS))
+				sbs_mode = HW_MODE_SBS;
+		}
+
+		/* Updating HW mode list */
+		policy_mgr_set_hw_mode_params(psoc, mac0_ss_bw_info,
+			mac1_ss_bw_info, i, tmp->hw_mode_id, dbs_mode,
+			sbs_mode);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc,
+		uint32_t num_dbs_hw_modes,
+		uint32_t *ev_wlan_dbs_hw_mode_list)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	pm_ctx->num_dbs_hw_modes = num_dbs_hw_modes;
+	pm_ctx->hw_mode.hw_mode_list =
+		qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) *
+		pm_ctx->num_dbs_hw_modes);
+	if (!pm_ctx->hw_mode.hw_mode_list) {
+		policy_mgr_err("Memory allocation failed for DBS");
+		return;
+	}
+	qdf_mem_copy(pm_ctx->hw_mode.hw_mode_list,
+		ev_wlan_dbs_hw_mode_list,
+		(sizeof(*pm_ctx->hw_mode.hw_mode_list) *
+		pm_ctx->num_dbs_hw_modes));
+}
+
+void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t i, param;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		policy_mgr_debug("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d band_cap:%d",
+				 i,
+				 POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param),
+				 POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param),
+				 POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param),
+				 POLICY_MGR_HW_MODE_MAC0_BAND_GET(param));
+		policy_mgr_debug("[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d",
+				 i,
+				 POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param),
+				 POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param),
+				 POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param));
+		policy_mgr_debug("[%d] DBS:%d SBS:%d hw_mode_id:%d", i,
+				 POLICY_MGR_HW_MODE_DBS_MODE_GET(param),
+				 POLICY_MGR_HW_MODE_SBS_MODE_GET(param),
+				 POLICY_MGR_HW_MODE_ID_GET(param));
+	}
+}
+
+void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc,
+		uint32_t scan_config, uint32_t fw_config)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	pm_ctx->dual_mac_cfg.cur_scan_config = 0;
+	pm_ctx->dual_mac_cfg.cur_fw_mode_config = 0;
+
+	/* If dual mac features are disabled in the INI, we
+	 * need not proceed further
+	 */
+	if (DISABLE_DBS_CXN_AND_SCAN ==
+			wlan_objmgr_psoc_get_dual_mac_disable(psoc)) {
+		policy_mgr_err("Disabling dual mac capabilities");
+		/* All capabilities are initialized to 0. We can return */
+		goto done;
+	}
+
+	/* Initialize concurrent_scan_config_bits with default FW value */
+	WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(
+		pm_ctx->dual_mac_cfg.cur_scan_config,
+		WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_GET(scan_config));
+	WMI_DBS_CONC_SCAN_CFG_SYNC_DBS_SCAN_SET(
+		pm_ctx->dual_mac_cfg.cur_scan_config,
+		WMI_DBS_CONC_SCAN_CFG_SYNC_DBS_SCAN_GET(scan_config));
+	WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(
+		pm_ctx->dual_mac_cfg.cur_scan_config,
+		WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config));
+	WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET(
+		pm_ctx->dual_mac_cfg.cur_scan_config,
+		WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config));
+	WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET(
+		pm_ctx->dual_mac_cfg.cur_scan_config,
+		WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config));
+
+	/* Initialize fw_mode_config_bits with default FW value */
+	WMI_DBS_FW_MODE_CFG_DBS_SET(
+		pm_ctx->dual_mac_cfg.cur_fw_mode_config,
+		WMI_DBS_FW_MODE_CFG_DBS_GET(fw_config));
+	WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET(
+		pm_ctx->dual_mac_cfg.cur_fw_mode_config,
+		WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_config));
+	WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(
+		pm_ctx->dual_mac_cfg.cur_fw_mode_config,
+		WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_GET(fw_config));
+done:
+	/* Initialize the previous scan/fw mode config */
+	pm_ctx->dual_mac_cfg.prev_scan_config =
+		pm_ctx->dual_mac_cfg.cur_scan_config;
+	pm_ctx->dual_mac_cfg.prev_fw_mode_config =
+		pm_ctx->dual_mac_cfg.cur_fw_mode_config;
+
+	policy_mgr_debug("cur_scan_config:%x cur_fw_mode_config:%x",
+		pm_ctx->dual_mac_cfg.cur_scan_config,
+		pm_ctx->dual_mac_cfg.cur_fw_mode_config);
+}
+
+void policy_mgr_update_dbs_scan_config(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	pm_ctx->dual_mac_cfg.prev_scan_config =
+		pm_ctx->dual_mac_cfg.cur_scan_config;
+	pm_ctx->dual_mac_cfg.cur_scan_config =
+		pm_ctx->dual_mac_cfg.req_scan_config;
+}
+
+void policy_mgr_update_dbs_fw_config(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	pm_ctx->dual_mac_cfg.prev_fw_mode_config =
+		pm_ctx->dual_mac_cfg.cur_fw_mode_config;
+	pm_ctx->dual_mac_cfg.cur_fw_mode_config =
+		pm_ctx->dual_mac_cfg.req_fw_mode_config;
+}
+
+void policy_mgr_update_dbs_req_config(struct wlan_objmgr_psoc *psoc,
+		uint32_t scan_config, uint32_t fw_mode_config)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	pm_ctx->dual_mac_cfg.req_scan_config = scan_config;
+	pm_ctx->dual_mac_cfg.req_fw_mode_config = fw_mode_config;
+}
+
+bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t scan_config;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
+		return false;
+
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		/* We take that it is disabled and proceed */
+		return false;
+	}
+	scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
+
+	return WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config);
+}
+
+bool policy_mgr_get_single_mac_scan_with_dfs_config(
+		struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t scan_config;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
+		return false;
+
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		/* We take that it is disabled and proceed */
+		return false;
+	}
+	scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
+
+	return WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config);
+}
+
+int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return -EINVAL;
+	}
+	return pm_ctx->num_dbs_hw_modes;
+}
+
+bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t param, i, found = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wmi_unified *wmi_handle;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	if (!policy_mgr_is_dbs_enable(psoc)) {
+		policy_mgr_debug("DBS is disabled");
+		return false;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		policy_mgr_debug("Invalid WMI handle");
+		return false;
+	}
+
+	policy_mgr_debug("DBS service bit map: %d",
+		wmi_service_enabled(wmi_handle,
+		wmi_service_dual_band_simultaneous_support));
+
+	/* The agreement with FW is that: To know if the target is DBS
+	 * capable, DBS needs to be supported both in the HW mode list
+	 * and in the service ready event
+	 */
+	if (!(wmi_service_enabled(wmi_handle,
+		wmi_service_dual_band_simultaneous_support)))
+		return false;
+
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		policy_mgr_debug("HW param: %x", param);
+		if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) {
+			policy_mgr_debug("HW (%d) is DBS capable", i);
+			found = 1;
+			break;
+		}
+	}
+
+	if (found)
+		return true;
+
+	return false;
+}
+
+bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t param, i, found = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wmi_unified *wmi_handle;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		policy_mgr_debug("Invalid WMI handle");
+		return false;
+	}
+
+	policy_mgr_debug("DBS service bit map: %d",
+		wmi_service_enabled(wmi_handle,
+		wmi_service_dual_band_simultaneous_support));
+
+	/* The agreement with FW is that: To know if the target is SBS
+	 * capable, SBS needs to be supported both in the HW mode list
+	 * and DBS needs to be supported in the service ready event
+	 */
+	if (!(wmi_service_enabled(wmi_handle,
+		wmi_service_dual_band_simultaneous_support)))
+		return false;
+
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		policy_mgr_debug("HW param: %x", param);
+		if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) {
+			policy_mgr_debug("HW (%d) is SBS capable", i);
+			found = 1;
+			break;
+		}
+	}
+
+	if (found)
+		return true;
+
+	return false;
+}
+
+QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc,
+		bool *one_by_one_dbs, bool *two_by_two_dbs)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i;
+	int8_t found_one_by_one = -EINVAL, found_two_by_two = -EINVAL;
+	uint32_t conf1_tx_ss, conf1_rx_ss;
+	uint32_t conf2_tx_ss, conf2_rx_ss;
+
+	*one_by_one_dbs = false;
+	*two_by_two_dbs = false;
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
+		policy_mgr_err("HW is not DBS capable");
+		/* Caller will understand that DBS is disabled */
+		return QDF_STATUS_SUCCESS;
+
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* To check 1x1 capability */
+	policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_1x1,
+			&conf1_tx_ss, &conf1_rx_ss);
+	/* To check 2x2 capability */
+	policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_2x2,
+			&conf2_tx_ss, &conf2_rx_ss);
+
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		uint32_t t_conf0_tx_ss, t_conf0_rx_ss;
+		uint32_t t_conf1_tx_ss, t_conf1_rx_ss;
+		uint32_t dbs_mode;
+
+		t_conf0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		t_conf0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		t_conf1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		t_conf1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+		dbs_mode = POLICY_MGR_HW_MODE_DBS_MODE_GET(
+				pm_ctx->hw_mode.hw_mode_list[i]);
+
+		if (((((t_conf0_tx_ss == conf1_tx_ss) &&
+		    (t_conf0_rx_ss == conf1_rx_ss)) ||
+		    ((t_conf1_tx_ss == conf1_tx_ss) &&
+		    (t_conf1_rx_ss == conf1_rx_ss))) &&
+		    (dbs_mode == HW_MODE_DBS)) &&
+		    (found_one_by_one < 0)) {
+			found_one_by_one = i;
+			policy_mgr_debug("1x1 hw_mode index %d found", i);
+			/* Once an entry is found, need not check for 1x1
+			 * again
+			 */
+			continue;
+		}
+
+		if (((((t_conf0_tx_ss == conf2_tx_ss) &&
+		    (t_conf0_rx_ss == conf2_rx_ss)) ||
+		    ((t_conf1_tx_ss == conf2_tx_ss) &&
+		    (t_conf1_rx_ss == conf2_rx_ss))) &&
+		    (dbs_mode == HW_MODE_DBS)) &&
+		    (found_two_by_two < 0)) {
+			found_two_by_two = i;
+			policy_mgr_debug("2x2 hw_mode index %d found", i);
+			/* Once an entry is found, need not check for 2x2
+			 * again
+			 */
+			continue;
+		}
+	}
+
+	if (found_one_by_one >= 0)
+		*one_by_one_dbs = true;
+	if (found_two_by_two >= 0)
+		*two_by_two_dbs = true;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_hw_mode_params *hw_mode)
+{
+	QDF_STATUS status;
+	uint32_t old_hw_index = 0, new_hw_index = 0;
+
+	policy_mgr_debug("Get the current hw mode");
+
+	status = policy_mgr_get_old_and_new_hw_index(psoc, &old_hw_index,
+			&new_hw_index);
+	if (QDF_STATUS_SUCCESS != status) {
+		policy_mgr_err("Failed to get HW mode index");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (new_hw_index == POLICY_MGR_DEFAULT_HW_MODE_INDEX) {
+		policy_mgr_err("HW mode is not yet initialized");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = policy_mgr_get_hw_mode_from_idx(psoc, new_hw_index, hw_mode);
+	if (QDF_STATUS_SUCCESS != status) {
+		policy_mgr_err("Failed to get HW mode index");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_hw_mode_params hw_mode;
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return false;
+	if (QDF_STATUS_SUCCESS !=
+		policy_mgr_get_current_hw_mode(psoc, &hw_mode))
+		return false;
+	if (hw_mode.dbs_cap)
+		return true;
+	return false;
+}
+
+bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) {
+		policy_mgr_debug("DBS is disabled from ini");
+		return false;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	policy_mgr_debug("DBS=%d",
+		WMI_DBS_FW_MODE_CFG_DBS_GET(
+			pm_ctx->dual_mac_cfg.cur_fw_mode_config));
+
+	if (WMI_DBS_FW_MODE_CFG_DBS_GET(
+			pm_ctx->dual_mac_cfg.cur_fw_mode_config))
+		return true;
+
+	return false;
+}
+
+bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc)
+{
+	struct dbs_nss nss_dbs;
+	uint32_t nss;
+
+	nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
+	if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss == nss_dbs.mac1_ss))
+		return true;
+	else
+		return false;
+}
+
+/*
+ * policy_mgr_is_2x2_1x1_dbs_capable() - check 2x2+1x1 DBS supported or not
+ * @psoc: PSOC object data
+ *
+ * This routine is called to check 2x2 5G + 1x1 2G (DBS1) or
+ * 2x2 2G + 1x1 5G (DBS2) support or not.
+ * Either DBS1 or DBS2 supported
+ *
+ * Return: true/false
+ */
+bool policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	struct dbs_nss nss_dbs;
+	uint32_t nss;
+
+	nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
+	if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss > nss_dbs.mac1_ss))
+		return true;
+	else
+		return false;
+}
+
+/*
+ * policy_mgr_is_2x2_5G_1x1_2G_dbs_capable() - check Genoa DBS1 enabled or not
+ * @psoc: PSOC object data
+ *
+ * This routine is called to check support DBS1 or not.
+ * Notes: DBS1: 2x2 5G + 1x1 2G.
+ * This function will call policy_mgr_get_hw_mode_idx_from_dbs_hw_list to match
+ * the HW mode from hw mode list. The parameters will also be matched to
+ * 2x2 5G +2x2 2G HW mode. But firmware will not report 2x2 5G + 2x2 2G alone
+ * with 2x2 5G + 1x1 2G at same time. So, it is safe to find DBS1 with
+ * policy_mgr_get_hw_mode_idx_from_dbs_hw_list.
+ *
+ * Return: true/false
+ */
+bool policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_is_2x2_1x1_dbs_capable(psoc) &&
+		(policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
+					psoc,
+					HW_MODE_SS_2x2,
+					HW_MODE_80_MHZ,
+					HW_MODE_SS_1x1, HW_MODE_40_MHZ,
+					HW_MODE_MAC_BAND_5G,
+					HW_MODE_DBS,
+					HW_MODE_AGILE_DFS_NONE,
+					HW_MODE_SBS_NONE) >= 0);
+}
+
+/*
+ * policy_mgr_is_2x2_2G_1x1_5G_dbs_capable() - check Genoa DBS2 enabled or not
+ * @psoc: PSOC object data
+ *
+ * This routine is called to check support DBS2 or not.
+ * Notes: DBS2: 2x2 2G + 1x1 5G
+ *
+ * Return: true/false
+ */
+bool policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_is_2x2_1x1_dbs_capable(psoc) &&
+		(policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
+					psoc,
+					HW_MODE_SS_2x2,
+					HW_MODE_40_MHZ,
+					HW_MODE_SS_1x1, HW_MODE_40_MHZ,
+					HW_MODE_MAC_BAND_2G,
+					HW_MODE_DBS,
+					HW_MODE_AGILE_DFS_NONE,
+					HW_MODE_SBS_NONE) >= 0);
+}
+
+uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t conn_index, count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return count;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		conn_index++) {
+		if (pm_conc_connection_list[conn_index].in_use)
+			count++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc,
+					  enum policy_mgr_con_mode mode)
+{
+	uint32_t conn_index = 0;
+	uint32_t vdev_id = WLAN_INVALID_VDEV_ID;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return vdev_id;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	/*
+	 * Note: This gives you the first vdev id of the mode type in a
+	 * sta+sta or sap+sap or p2p + p2p case
+	 */
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		conn_index++) {
+		if ((pm_conc_connection_list[conn_index].mode == mode) &&
+			pm_conc_connection_list[conn_index].in_use) {
+			vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return vdev_id;
+}
+
+uint32_t policy_mgr_mode_specific_connection_count(
+		struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode,
+		uint32_t *list)
+{
+	uint32_t conn_index = 0, count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return count;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		conn_index++) {
+		if ((pm_conc_connection_list[conn_index].mode == mode) &&
+			pm_conc_connection_list[conn_index].in_use) {
+			if (list != NULL)
+				list[count] = conn_index;
+			 count++;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+QDF_STATUS policy_mgr_check_conn_with_mode_and_vdev_id(
+		struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode,
+		uint32_t vdev_id)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return qdf_status;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if ((pm_conc_connection_list[conn_index].mode == mode) &&
+		    (pm_conc_connection_list[conn_index].vdev_id == vdev_id)) {
+			qdf_status = QDF_STATUS_SUCCESS;
+			break;
+		}
+		conn_index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	return qdf_status;
+}
+
+void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status,
+		uint32_t scan_config,
+		uint32_t fw_mode_config)
+{
+	policy_mgr_debug("Status:%d for scan_config:%x fw_mode_config:%x",
+			 status, scan_config, fw_mode_config);
+}
+
+void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc,
+		uint8_t dbs_val,
+		uint8_t dbs_plus_agile_scan_val,
+		uint8_t single_mac_scan_with_dbs_val)
+{
+	struct policy_mgr_dual_mac_config cfg;
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	/* Any non-zero positive value is treated as 1 */
+	if (dbs_val != 0)
+		dbs_val = 1;
+	if (dbs_plus_agile_scan_val != 0)
+		dbs_plus_agile_scan_val = 1;
+	if (single_mac_scan_with_dbs_val != 0)
+		single_mac_scan_with_dbs_val = 1;
+
+	status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config,
+			dbs_val,
+			dbs_plus_agile_scan_val,
+			single_mac_scan_with_dbs_val);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("policy_mgr_get_updated_scan_config failed %d",
+			status);
+		return;
+	}
+
+	status = policy_mgr_get_updated_fw_mode_config(psoc,
+			&cfg.fw_mode_config,
+			policy_mgr_get_dbs_config(psoc),
+			policy_mgr_get_agile_dfs_config(psoc));
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d",
+			status);
+		return;
+	}
+
+	cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
+
+	policy_mgr_debug("scan_config:%x fw_mode_config:%x",
+			cfg.scan_config, cfg.fw_mode_config);
+
+	status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status);
+}
+
+void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc,
+			uint8_t dbs, uint8_t dfs)
+{
+	struct policy_mgr_dual_mac_config cfg;
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	/* Any non-zero positive value is treated as 1 */
+	if (dbs != 0)
+		dbs = 1;
+	if (dfs != 0)
+		dfs = 1;
+
+	status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config,
+			policy_mgr_get_dbs_scan_config(psoc),
+			policy_mgr_get_dbs_plus_agile_scan_config(psoc),
+			policy_mgr_get_single_mac_scan_with_dfs_config(psoc));
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("policy_mgr_get_updated_scan_config failed %d",
+			status);
+		return;
+	}
+
+	status = policy_mgr_get_updated_fw_mode_config(psoc,
+				&cfg.fw_mode_config, dbs, dfs);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d",
+			status);
+		return;
+	}
+
+	cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
+
+	policy_mgr_debug("scan_config:%x fw_mode_config:%x",
+			cfg.scan_config, cfg.fw_mode_config);
+
+	status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status);
+}
+
+bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t num_connections = 0;
+	bool is_mcc = false;
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+
+	switch (num_connections) {
+	case 1:
+		break;
+	case 2:
+		if ((pm_conc_connection_list[0].chan !=
+			pm_conc_connection_list[1].chan) &&
+		    (pm_conc_connection_list[0].mac ==
+			pm_conc_connection_list[1].mac)) {
+			is_mcc = true;
+		}
+		break;
+	case 3:
+		if ((pm_conc_connection_list[0].chan !=
+			pm_conc_connection_list[1].chan) ||
+		    (pm_conc_connection_list[0].chan !=
+			pm_conc_connection_list[2].chan) ||
+		    (pm_conc_connection_list[1].chan !=
+			pm_conc_connection_list[2].chan)){
+				is_mcc = true;
+		}
+		break;
+	default:
+		policy_mgr_err("unexpected num_connections value %d",
+			num_connections);
+		break;
+	}
+
+	return is_mcc;
+}
+
+/**
+ * policy_mgr_set_concurrency_mode() - To set concurrency mode
+ * @psoc: PSOC object data
+ * @mode: device mode
+ *
+ * This routine is called to set the concurrency mode
+ *
+ * Return: NONE
+ */
+void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc,
+				     enum QDF_OPMODE mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+
+	switch (mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_GO_MODE:
+	case QDF_SAP_MODE:
+	case QDF_IBSS_MODE:
+	case QDF_MONITOR_MODE:
+		pm_ctx->concurrency_mode |= (1 << mode);
+		pm_ctx->no_of_open_sessions[mode]++;
+		break;
+	default:
+		break;
+	}
+
+	policy_mgr_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
+		pm_ctx->concurrency_mode, mode,
+		pm_ctx->no_of_open_sessions[mode]);
+}
+
+/**
+ * policy_mgr_clear_concurrency_mode() - To clear concurrency mode
+ * @psoc: PSOC object data
+ * @mode: device mode
+ *
+ * This routine is called to clear the concurrency mode
+ *
+ * Return: NONE
+ */
+void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc,
+				       enum QDF_OPMODE mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+
+	switch (mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_GO_MODE:
+	case QDF_SAP_MODE:
+	case QDF_MONITOR_MODE:
+		pm_ctx->no_of_open_sessions[mode]--;
+		if (!(pm_ctx->no_of_open_sessions[mode]))
+			pm_ctx->concurrency_mode &= (~(1 << mode));
+		break;
+	default:
+		break;
+	}
+
+	policy_mgr_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
+		pm_ctx->concurrency_mode, mode,
+		pm_ctx->no_of_open_sessions[mode]);
+}
+
+void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc,
+				enum QDF_OPMODE mode,
+				uint8_t session_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	/*
+	 * Need to aquire mutex as entire functionality in this function
+	 * is in critical section
+	 */
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	switch (mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_GO_MODE:
+	case QDF_SAP_MODE:
+	case QDF_IBSS_MODE:
+		pm_ctx->no_of_active_sessions[mode]++;
+		break;
+	default:
+		break;
+	}
+
+	if (pm_ctx->dp_cbacks.hdd_v2_flow_pool_map)
+		pm_ctx->dp_cbacks.hdd_v2_flow_pool_map(session_id);
+
+	policy_mgr_debug("No.# of active sessions for mode %d = %d",
+		mode, pm_ctx->no_of_active_sessions[mode]);
+	policy_mgr_incr_connection_count(psoc, session_id);
+	if ((policy_mgr_mode_specific_connection_count(
+		psoc, PM_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) {
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE);
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	}
+
+	/* Notify tdls */
+	if (pm_ctx->tdls_cbacks.tdls_notify_increment_session)
+		pm_ctx->tdls_cbacks.tdls_notify_increment_session(psoc);
+
+	/*
+	 * Disable LRO/GRO if P2P or IBSS or SAP connection has come up or
+	 * there are more than one STA connections
+	 */
+	if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL) > 1) ||
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL) > 0) ||
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_CLIENT_MODE, NULL) >
+									0) ||
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_GO_MODE, NULL) > 0) ||
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_IBSS_MODE, NULL) > 0)) {
+		if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency != NULL)
+			pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(true);
+	};
+
+	/* Enable RPS if SAP interface has come up */
+	if (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL)
+		== 1) {
+		if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb != NULL)
+			pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(true);
+	}
+
+	policy_mgr_dump_current_concurrency(psoc);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc,
+				enum QDF_OPMODE mode,
+				uint8_t session_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS qdf_status;
+	bool mcc_mode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("context is NULL");
+		return QDF_STATUS_E_EMPTY;
+	}
+
+	qdf_status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc,
+			policy_mgr_convert_device_mode_to_qdf_type(mode),
+			session_id);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		policy_mgr_debug("No connection with mode:%d vdev_id:%d",
+			policy_mgr_convert_device_mode_to_qdf_type(mode),
+			session_id);
+		return qdf_status;
+	}
+
+	switch (mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_GO_MODE:
+	case QDF_SAP_MODE:
+	case QDF_IBSS_MODE:
+		if (pm_ctx->no_of_active_sessions[mode])
+			pm_ctx->no_of_active_sessions[mode]--;
+		break;
+	default:
+		break;
+	}
+
+	if (pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap)
+		pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap(session_id);
+
+	policy_mgr_debug("No.# of active sessions for mode %d = %d",
+		mode, pm_ctx->no_of_active_sessions[mode]);
+
+	policy_mgr_decr_connection_count(psoc, session_id);
+
+	/* Notify tdls */
+	if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session)
+		pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc);
+	/* Enable LRO/GRO if there no concurrency */
+	if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL) == 1) &&
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL) == 0) &&
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_CLIENT_MODE, NULL) ==
+									0) &&
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_GO_MODE, NULL) == 0) &&
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_IBSS_MODE, NULL) == 0)) {
+		if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency != NULL)
+			pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(false);
+	};
+
+	/* Disable RPS if SAP interface has come up */
+	if (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL)
+		== 0) {
+		if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb != NULL)
+			pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(false);
+	}
+
+	policy_mgr_dump_current_concurrency(psoc);
+
+	/*
+	 * Check mode of entry being removed. Update mcc_mode only when STA
+	 * or SAP since IPA only cares about these two
+	 */
+	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) {
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc);
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+		if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb)
+			pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode);
+	}
+
+	return qdf_status;
+}
+
+QDF_STATUS policy_mgr_incr_connection_count(
+		struct wlan_objmgr_psoc *psoc, uint32_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t conn_index;
+	struct policy_mgr_vdev_entry_info conn_table_entry;
+	enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
+	uint8_t nss_2g = 0, nss_5g = 0;
+	enum policy_mgr_con_mode mode;
+	uint8_t chan;
+	uint32_t nss = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool update_conn = true;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("context is NULL");
+		return status;
+	}
+
+	conn_index = policy_mgr_get_connection_count(psoc);
+	if (pm_ctx->cfg.max_conc_cxns < conn_index) {
+		policy_mgr_err("exceeded max connection limit %d",
+			pm_ctx->cfg.max_conc_cxns);
+		return status;
+	}
+	if (pm_ctx->wma_cbacks.wma_get_connection_info) {
+		status = pm_ctx->wma_cbacks.wma_get_connection_info(
+				vdev_id, &conn_table_entry);
+		if (QDF_STATUS_SUCCESS != status) {
+			policy_mgr_err("can't find vdev_id %d in connection table",
+			vdev_id);
+			return status;
+		}
+	} else {
+		policy_mgr_err("wma_get_connection_info is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mode = policy_mgr_get_mode(conn_table_entry.type,
+					conn_table_entry.sub_type);
+	chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz);
+	status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) ||
+			(WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1)))
+			chain_mask = POLICY_MGR_TWO_TWO;
+		else
+			chain_mask = POLICY_MGR_ONE_ONE;
+		nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g;
+	} else {
+		policy_mgr_err("Error in getting nss");
+	}
+
+	if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)
+		update_conn = false;
+
+	/* add the entry */
+	policy_mgr_update_conc_list(psoc, conn_index,
+			mode,
+			chan,
+			policy_mgr_get_bw(conn_table_entry.chan_width),
+			conn_table_entry.mac_id,
+			chain_mask,
+			nss, vdev_id, true, update_conn);
+	policy_mgr_debug("Add at idx:%d vdev %d mac=%d",
+		conn_index, vdev_id,
+		conn_table_entry.mac_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc,
+					uint32_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t conn_index = 0, next_conn_index = 0;
+	bool found = false;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
+			/* debug msg */
+			found = true;
+			break;
+		}
+		conn_index++;
+	}
+	if (!found) {
+		policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
+			vdev_id);
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		return status;
+	}
+	next_conn_index = conn_index + 1;
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(next_conn_index)) {
+		pm_conc_connection_list[conn_index].vdev_id =
+			pm_conc_connection_list[next_conn_index].vdev_id;
+		pm_conc_connection_list[conn_index].mode =
+			pm_conc_connection_list[next_conn_index].mode;
+		pm_conc_connection_list[conn_index].mac =
+			pm_conc_connection_list[next_conn_index].mac;
+		pm_conc_connection_list[conn_index].chan =
+			pm_conc_connection_list[next_conn_index].chan;
+		pm_conc_connection_list[conn_index].bw =
+			pm_conc_connection_list[next_conn_index].bw;
+		pm_conc_connection_list[conn_index].chain_mask =
+			pm_conc_connection_list[next_conn_index].chain_mask;
+		pm_conc_connection_list[conn_index].original_nss =
+			pm_conc_connection_list[next_conn_index].original_nss;
+		pm_conc_connection_list[conn_index].in_use =
+			pm_conc_connection_list[next_conn_index].in_use;
+		conn_index++;
+		next_conn_index++;
+	}
+
+	/* clean up the entry */
+	qdf_mem_zero(&pm_conc_connection_list[next_conn_index - 1],
+		sizeof(*pm_conc_connection_list));
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_map_concurrency_mode(enum QDF_OPMODE *old_mode,
+				     enum policy_mgr_con_mode *new_mode)
+{
+	bool status = true;
+
+	switch (*old_mode) {
+
+	case QDF_STA_MODE:
+		*new_mode = PM_STA_MODE;
+		break;
+	case QDF_SAP_MODE:
+		*new_mode = PM_SAP_MODE;
+		break;
+	case QDF_P2P_CLIENT_MODE:
+		*new_mode = PM_P2P_CLIENT_MODE;
+		break;
+	case QDF_P2P_GO_MODE:
+		*new_mode = PM_P2P_GO_MODE;
+		break;
+	case QDF_IBSS_MODE:
+		*new_mode = PM_IBSS_MODE;
+		break;
+	default:
+		*new_mode = PM_MAX_NUM_OF_MODE;
+		status = false;
+		break;
+	}
+
+	return status;
+}
+
+bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc,
+				uint8_t *ibss_channel)
+{
+	uint32_t count = 0, index = 0;
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	bool status = false;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+	if (NULL == ibss_channel) {
+		policy_mgr_err("Null pointer error");
+		return false;
+	}
+	count = policy_mgr_mode_specific_connection_count(
+				psoc, PM_IBSS_MODE, list);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (count == 0) {
+		/* No IBSS connection */
+		status = false;
+	} else if (count == 1) {
+		*ibss_channel = pm_conc_connection_list[list[index]].chan;
+		status = true;
+	} else {
+		*ibss_channel = pm_conc_connection_list[list[index]].chan;
+		policy_mgr_debug("Multiple IBSS connections, picking first one");
+		status = true;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+uint32_t policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc,
+				  uint8_t *channel, uint8_t *vdev_id,
+				  enum policy_mgr_con_mode mode)
+{
+
+	uint32_t count = 0, index = 0;
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return count;
+	}
+	if (NULL == channel || NULL == vdev_id) {
+		policy_mgr_err("Null pointer error");
+		return count;
+	}
+
+	count = policy_mgr_mode_specific_connection_count(
+				psoc, mode, list);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (count == 0) {
+		policy_mgr_debug("No mode:[%d] connection", mode);
+	} else if (count == 1) {
+		*channel = pm_conc_connection_list[list[index]].chan;
+		*vdev_id =
+			pm_conc_connection_list[list[index]].vdev_id;
+	} else {
+		for (index = 0; index < count; index++) {
+			channel[index] =
+			pm_conc_connection_list[list[index]].chan;
+
+			vdev_id[index] =
+			pm_conc_connection_list[list[index]].vdev_id;
+		}
+		policy_mgr_debug("Multiple mode:[%d] connections", mode);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+bool policy_mgr_max_concurrent_connections_reached(
+		struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t i = 0, j = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (NULL != pm_ctx) {
+		for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
+			j += pm_ctx->no_of_active_sessions[i];
+		return j >
+			(pm_ctx->cfg.max_conc_cxns - 1);
+	}
+
+	return false;
+}
+
+static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	return pm_ctx->user_cfg.sub_20_mhz_enabled;
+}
+
+/**
+ * policy_mgr_check_privacy_for_new_conn() - Check privacy mode concurrency
+ * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context
+ *
+ * This routine is called to check vdev security mode allowed in concurrency.
+ * At present, WAPI security mode is not allowed to run concurrency with any
+ * other vdev.
+ *
+ * Return: true - allow
+ */
+static bool policy_mgr_check_privacy_for_new_conn(
+	struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	if (!pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist)
+		return true;
+
+	if (pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist() &&
+	    (policy_mgr_get_connection_count(pm_ctx->psoc) > 0))
+		return false;
+
+	return true;
+}
+
+bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
+				       enum policy_mgr_con_mode mode,
+				       uint8_t channel,
+				       enum hw_mode_bandwidth bw)
+{
+	uint32_t num_connections = 0, count = 0, index = 0;
+	bool status = false, match = false;
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool sta_sap_scc_on_dfs_chan;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+	/* find the current connection state from pm_conc_connection_list*/
+	num_connections = policy_mgr_get_connection_count(psoc);
+
+	if (num_connections && policy_mgr_is_sub_20_mhz_enabled(psoc)) {
+		policy_mgr_err("dont allow concurrency if Sub 20 MHz is enabled");
+		status = false;
+		goto done;
+	}
+
+	if (policy_mgr_max_concurrent_connections_reached(psoc)) {
+		policy_mgr_err("Reached max concurrent connections: %d",
+			       pm_ctx->cfg.max_conc_cxns);
+		goto done;
+	}
+
+	if (channel) {
+		/* don't allow 3rd home channel on same MAC */
+		if (!policy_mgr_allow_new_home_channel(psoc,
+			channel, num_connections))
+			goto done;
+
+		/*
+		 * 1) DFS MCC is not yet supported
+		 * 2) If you already have STA connection on 5G channel then
+		 *    don't allow any other persona to make connection on DFS
+		 *    channel because STA 5G + DFS MCC is not allowed.
+		 * 3) If STA is on 2G channel and SAP is coming up on
+		 *    DFS channel then allow concurrency but make sure it is
+		 *    going to DBS and send PCL to firmware indicating that
+		 *    don't allow STA to roam to 5G channels.
+		 */
+		if (!policy_mgr_is_5g_channel_allowed(psoc,
+			channel, list, PM_P2P_GO_MODE))
+			goto done;
+		if (!policy_mgr_is_5g_channel_allowed(psoc,
+			channel, list, PM_SAP_MODE))
+			goto done;
+
+		sta_sap_scc_on_dfs_chan =
+			policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+		policy_mgr_debug("sta_sap_scc_on_dfs_chan %u",
+				 sta_sap_scc_on_dfs_chan);
+
+		if (!sta_sap_scc_on_dfs_chan && ((mode == PM_P2P_GO_MODE) ||
+		    (mode == PM_SAP_MODE))) {
+			if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel))
+				match = policy_mgr_disallow_mcc(psoc, channel);
+		}
+		if (true == match) {
+			policy_mgr_err("No MCC, SAP/GO about to come up on DFS channel");
+			goto done;
+		}
+	}
+
+	/*
+	 * Check all IBSS+STA concurrencies
+	 *
+	 * don't allow IBSS + STA MCC
+	 * don't allow IBSS + STA SCC if IBSS is on DFS channel
+	 */
+	count = policy_mgr_mode_specific_connection_count(psoc,
+				PM_STA_MODE, list);
+	if ((PM_IBSS_MODE == mode) &&
+		(policy_mgr_mode_specific_connection_count(psoc,
+		PM_IBSS_MODE, list)) && count) {
+		policy_mgr_err("No 2nd IBSS, we already have STA + IBSS");
+		goto done;
+	}
+	if ((PM_IBSS_MODE == mode) &&
+		(wlan_reg_is_dfs_ch(pm_ctx->pdev, channel)) && count) {
+		policy_mgr_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel");
+		goto done;
+	}
+	if (PM_IBSS_MODE == mode) {
+		if (policy_mgr_is_hw_dbs_capable(psoc) == true) {
+			if (num_connections > 1) {
+				policy_mgr_err("No IBSS, we have concurrent connections already");
+				goto done;
+			}
+			qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+			if (PM_STA_MODE != pm_conc_connection_list[0].mode) {
+				policy_mgr_err("No IBSS, we've a non-STA connection");
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				goto done;
+			}
+			/*
+			 * This logic protects STA and IBSS to come up on same
+			 * band. If requirement changes then this condition
+			 * needs to be removed
+			 */
+			if (channel &&
+				(pm_conc_connection_list[0].chan != channel) &&
+				WLAN_REG_IS_SAME_BAND_CHANNELS(
+				pm_conc_connection_list[0].chan, channel)) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				policy_mgr_err("No IBSS + STA MCC");
+				goto done;
+			}
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		} else if (num_connections) {
+			policy_mgr_err("No IBSS, we have one connection already");
+			goto done;
+		}
+	}
+
+	if ((PM_STA_MODE == mode) &&
+		(policy_mgr_mode_specific_connection_count(psoc,
+		PM_IBSS_MODE, list)) && count) {
+		policy_mgr_err("No 2nd STA, we already have STA + IBSS");
+		goto done;
+	}
+
+	if ((PM_STA_MODE == mode) &&
+		(policy_mgr_mode_specific_connection_count(psoc,
+		PM_IBSS_MODE, list))) {
+		if (policy_mgr_is_hw_dbs_capable(psoc) == true) {
+			if (num_connections > 1) {
+				policy_mgr_err("No 2nd STA, we already have IBSS concurrency");
+				goto done;
+			}
+			qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+			if (channel &&
+				(wlan_reg_is_dfs_ch(pm_ctx->pdev,
+				pm_conc_connection_list[0].chan))
+				&& (WLAN_REG_IS_5GHZ_CH(channel))) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				policy_mgr_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel");
+				goto done;
+			}
+			/*
+			 * This logic protects STA and IBSS to come up on same
+			 * band. If requirement changes then this condition
+			 * needs to be removed
+			 */
+			if ((pm_conc_connection_list[0].chan != channel) &&
+				WLAN_REG_IS_SAME_BAND_CHANNELS(
+				pm_conc_connection_list[0].chan, channel)) {
+				policy_mgr_err("No IBSS + STA MCC");
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				goto done;
+			}
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		} else {
+			policy_mgr_err("No STA, we have IBSS connection already");
+			goto done;
+		}
+	}
+
+	if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, channel,
+						 WLAN_INVALID_VDEV_ID)) {
+		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;
+		count = policy_mgr_mode_specific_connection_count(psoc,
+						PM_P2P_GO_MODE, list);
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		while (index < count) {
+			if (WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
+				pm_conc_connection_list[list[index]].chan)) {
+				policy_mgr_err("Don't allow P2P GO on same band");
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				goto done;
+			}
+			index++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	}
+
+	if (!policy_mgr_check_privacy_for_new_conn(pm_ctx)) {
+		policy_mgr_err("Don't allow new conn when wapi security conn existing");
+		goto done;
+	}
+
+	status = true;
+
+done:
+	return status;
+}
+
+bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
+				  enum policy_mgr_con_mode mode,
+				  uint8_t channel, enum hw_mode_bandwidth bw)
+{
+	QDF_STATUS status;
+	struct policy_mgr_pcl_list pcl;
+
+	qdf_mem_zero(&pcl, sizeof(pcl));
+	status = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len,
+				    pcl.weight_list,
+				    QDF_ARRAY_SIZE(pcl.weight_list));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("disallow connection:%d", status);
+		return false;
+	}
+
+	return policy_mgr_is_concurrency_allowed(psoc, mode, channel, bw);
+}
+
+bool  policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
+				       enum policy_mgr_con_mode mode,
+				       uint8_t channel,
+				       uint32_t vdev_id)
+{
+	bool allow = false;
+	struct policy_mgr_conc_connection_info info;
+	uint8_t num_cxn_del = 0;
+
+	/*
+	 * Store the connection's parameter and temporarily delete it
+	 * from the concurrency table. This way the allow concurrency
+	 * check can be used as though a new connection is coming up,
+	 * after check, restore the connection to concurrency table.
+	 */
+	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
+						      &info, &num_cxn_del);
+	allow = policy_mgr_allow_concurrency(
+				psoc,
+				mode,
+				channel,
+				HW_MODE_20_MHZ);
+	if (!allow)
+		policy_mgr_err("CSA concurrency check failed");
+	/* Restore the connection entry */
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
+
+	return allow;
+}
+
+/**
+ * policy_mgr_get_concurrency_mode() - return concurrency mode
+ * @psoc: PSOC object information
+ *
+ * This routine is used to retrieve concurrency mode
+ *
+ * Return: uint32_t value of concurrency mask
+ */
+uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STA_MASK;
+	}
+
+	policy_mgr_info("concurrency_mode: 0x%x",
+			pm_ctx->concurrency_mode);
+
+	return pm_ctx->concurrency_mode;
+}
+
+/**
+ * policy_mgr_get_channel_from_scan_result() - to get channel from scan result
+ * @psoc: PSOC object information
+ * @roam_profile: pointer to roam profile
+ * @channel: channel to be filled
+ *
+ * This routine gets channel which most likely a candidate to which STA
+ * will make connection.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_channel_from_scan_result(
+		struct wlan_objmgr_psoc *psoc,
+		void *roam_profile, uint8_t *channel)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	void *scan_cache = NULL;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!roam_profile || !channel) {
+		policy_mgr_err("Invalid input parameters");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan) {
+		status = pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan
+			(roam_profile, &scan_cache, channel);
+		if (status != QDF_STATUS_SUCCESS) {
+			policy_mgr_err("Get AP channel failed");
+			return status;
+		}
+	} else {
+		policy_mgr_err("sme_get_ap_channel_from_scan_cache NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pm_ctx->sme_cbacks.sme_scan_result_purge)
+		status = pm_ctx->sme_cbacks.sme_scan_result_purge(scan_cache);
+	else
+		policy_mgr_err("sme_scan_result_purge NULL");
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc,
+				struct policy_mgr_user_cfg *user_cfg)
+{
+
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (NULL == user_cfg) {
+		policy_mgr_err("Invalid User Config");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->user_cfg = *user_cfg;
+	policy_mgr_debug("dbs_selection_plcy 0x%x",
+			 pm_ctx->cfg.dbs_selection_plcy);
+	policy_mgr_debug("vdev_priority_list 0x%x",
+			 pm_ctx->cfg.vdev_priority_list);
+	pm_ctx->cur_conc_system_pref = pm_ctx->cfg.sys_pref;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint8_t policy_mgr_search_and_check_for_session_conc(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t session_id,
+		void *roam_profile)
+{
+	uint8_t channel = 0;
+	QDF_STATUS status;
+	enum policy_mgr_con_mode mode;
+	bool ret;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return channel;
+	}
+
+	if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) {
+		mode = pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev(
+			psoc, session_id);
+		if (PM_MAX_NUM_OF_MODE == mode) {
+			policy_mgr_err("Invalid mode");
+			return channel;
+		}
+	} else
+		return channel;
+
+	status = policy_mgr_get_channel_from_scan_result(psoc,
+			roam_profile, &channel);
+	if ((QDF_STATUS_SUCCESS != status) || (channel == 0)) {
+		policy_mgr_err("%s error %d %d",
+			__func__, status, channel);
+		return 0;
+	}
+
+	/* Take care of 160MHz and 80+80Mhz later */
+	ret = policy_mgr_allow_concurrency(psoc, mode, channel, HW_MODE_20_MHZ);
+	if (false == ret) {
+		policy_mgr_err("Connection failed due to conc check fail");
+		return 0;
+	}
+
+	return channel;
+}
+
+/**
+ * policy_mgr_is_two_connection_mcc() - Check if MCC scenario
+ * when there are two connections
+ *
+ * If if MCC scenario when there are two connections
+ *
+ * Return: true or false
+ */
+static bool policy_mgr_is_two_connection_mcc(void)
+{
+	return ((pm_conc_connection_list[0].chan !=
+		 pm_conc_connection_list[1].chan) &&
+		(pm_conc_connection_list[0].mac ==
+		 pm_conc_connection_list[1].mac) &&
+		(pm_conc_connection_list[0].chan <=
+		 WLAN_REG_MAX_24GHZ_CH_NUM) &&
+		(pm_conc_connection_list[1].chan <=
+		 WLAN_REG_MAX_24GHZ_CH_NUM)) ? true : false;
+}
+
+/**
+ * policy_mgr_is_three_connection_mcc() - Check if MCC scenario
+ * when there are three connections
+ *
+ * If if MCC scenario when there are three connections
+ *
+ * Return: true or false
+ */
+static bool policy_mgr_is_three_connection_mcc(void)
+{
+	return (((pm_conc_connection_list[0].chan !=
+		  pm_conc_connection_list[1].chan) ||
+		 (pm_conc_connection_list[0].chan !=
+		  pm_conc_connection_list[2].chan) ||
+		 (pm_conc_connection_list[1].chan !=
+		  pm_conc_connection_list[2].chan)) &&
+		(pm_conc_connection_list[0].chan <=
+		 WLAN_REG_MAX_24GHZ_CH_NUM) &&
+		(pm_conc_connection_list[1].chan <=
+		 WLAN_REG_MAX_24GHZ_CH_NUM) &&
+		(pm_conc_connection_list[2].chan <=
+		 WLAN_REG_MAX_24GHZ_CH_NUM)) ? true : false;
+}
+
+bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t num_connections = 0;
+	bool is_24G_mcc = false;
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+
+	switch (num_connections) {
+	case 1:
+		break;
+	case 2:
+		if (policy_mgr_is_two_connection_mcc())
+			is_24G_mcc = true;
+		break;
+	case 3:
+		if (policy_mgr_is_three_connection_mcc())
+			is_24G_mcc = true;
+		break;
+	default:
+		policy_mgr_err("unexpected num_connections value %d",
+			num_connections);
+		break;
+	}
+
+	return is_24G_mcc;
+}
+
+bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc,
+				uint8_t session_id, uint8_t channel)
+{
+	enum policy_mgr_con_mode mode;
+	bool ret;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) {
+		mode = pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev(
+			psoc, session_id);
+		if (PM_MAX_NUM_OF_MODE == mode) {
+			policy_mgr_err("Invalid mode");
+			return false;
+		}
+	} else
+		return false;
+
+	if (channel == 0) {
+		policy_mgr_err("Invalid channel number 0");
+		return false;
+	}
+
+	/* Take care of 160MHz and 80+80Mhz later */
+	ret = policy_mgr_allow_concurrency(psoc, mode, channel, HW_MODE_20_MHZ);
+	if (false == ret) {
+		policy_mgr_err("Connection failed due to conc check fail");
+		return 0;
+	}
+
+	return true;
+}
+
+/**
+ * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @dev_mode: device mode
+ *
+ * Updates the beacon parameters of the GO in MCC scenario
+ *
+ * Return: Success or Failure depending on the overall function behavior
+ */
+QDF_STATUS policy_mgr_change_mcc_go_beacon_interval(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id, enum QDF_OPMODE dev_mode)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_info("UPDATE Beacon Params");
+
+	if (QDF_SAP_MODE == dev_mode) {
+		if (pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval
+		    ) {
+			status = pm_ctx->sme_cbacks.
+				sme_change_mcc_beacon_interval(vdev_id);
+			if (status == QDF_STATUS_E_FAILURE) {
+				policy_mgr_err("Failed to update Beacon Params");
+				return QDF_STATUS_E_FAILURE;
+			}
+		} else {
+			policy_mgr_err("sme_change_mcc_beacon_interval callback is NULL");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(uint32_t *len)
+{
+	struct policy_mgr_conc_connection_info *conn_ptr =
+		&pm_conc_connection_list[0];
+	*len = MAX_NUMBER_OF_CONC_CONNECTIONS;
+
+	return conn_ptr;
+}
+
+enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type(
+			enum QDF_OPMODE device_mode)
+{
+	enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
+	switch (device_mode) {
+	case QDF_STA_MODE:
+		mode = PM_STA_MODE;
+		break;
+	case QDF_P2P_CLIENT_MODE:
+		mode = PM_P2P_CLIENT_MODE;
+		break;
+	case QDF_P2P_GO_MODE:
+		mode = PM_P2P_GO_MODE;
+		break;
+	case QDF_SAP_MODE:
+		mode = PM_SAP_MODE;
+		break;
+	case QDF_IBSS_MODE:
+		mode = PM_IBSS_MODE;
+		break;
+	default:
+		policy_mgr_debug("Unsupported mode (%d)",
+				 device_mode);
+	}
+
+	return mode;
+}
+
+enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm(
+			enum policy_mgr_con_mode device_mode)
+{
+	enum QDF_OPMODE mode = QDF_MAX_NO_OF_MODE;
+
+	switch (device_mode) {
+	case PM_STA_MODE:
+		mode = QDF_STA_MODE;
+		break;
+	case PM_SAP_MODE:
+		mode = QDF_SAP_MODE;
+		break;
+	case PM_P2P_CLIENT_MODE:
+		mode = QDF_P2P_CLIENT_MODE;
+		break;
+	case PM_P2P_GO_MODE:
+		mode = QDF_P2P_GO_MODE;
+		break;
+	case PM_IBSS_MODE:
+		mode = QDF_IBSS_MODE;
+		break;
+	default:
+		policy_mgr_debug("Unsupported policy mgr mode (%d)",
+				 device_mode);
+	}
+	return mode;
+}
+
+QDF_STATUS policy_mgr_mode_specific_num_open_sessions(
+		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode,
+		uint8_t *num_sessions)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*num_sessions = pm_ctx->no_of_open_sessions[mode];
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_mode_specific_num_active_sessions(
+		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode,
+		uint8_t *num_sessions)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*num_sessions = pm_ctx->no_of_active_sessions[mode];
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_concurrent_open_sessions_running() - Checks for
+ * concurrent open session
+ * @psoc: PSOC object information
+ *
+ * Checks if more than one open session is running for all the allowed modes
+ * in the driver
+ *
+ * Return: True if more than one open session exists, False otherwise
+ */
+bool policy_mgr_concurrent_open_sessions_running(
+	struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t i = 0;
+	uint8_t j = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return false;
+	}
+
+	for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
+		j += pm_ctx->no_of_open_sessions[i];
+
+	return j > 1;
+}
+
+/**
+ * policy_mgr_concurrent_beaconing_sessions_running() - Checks
+ * for concurrent beaconing entities
+ * @psoc: PSOC object information
+ *
+ * Checks if multiple beaconing sessions are running i.e., if SAP or GO or IBSS
+ * are beaconing together
+ *
+ * Return: True if multiple entities are beaconing together, False otherwise
+ */
+bool policy_mgr_concurrent_beaconing_sessions_running(
+	struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return false;
+	}
+
+	return (pm_ctx->no_of_open_sessions[QDF_SAP_MODE] +
+		pm_ctx->no_of_open_sessions[QDF_P2P_GO_MODE] +
+		pm_ctx->no_of_open_sessions[QDF_IBSS_MODE] > 1) ? true : false;
+}
+
+
+void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t i = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (NULL != pm_ctx) {
+		for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
+			pm_ctx->no_of_active_sessions[i] = 0;
+	}
+}
+
+bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_mode_specific_connection_count(
+		psoc, PM_STA_MODE, NULL) > 1;
+}
+
+/**
+ * policy_mgr_is_sta_active_connection_exists() - Check if a STA
+ * connection is active
+ * @psoc: PSOC object information
+ *
+ * Checks if there is atleast one active STA connection in the driver
+ *
+ * Return: True if an active STA session is present, False otherwise
+ */
+bool policy_mgr_is_sta_active_connection_exists(
+	struct wlan_objmgr_psoc *psoc)
+{
+	return (!policy_mgr_mode_specific_connection_count(
+		psoc, PM_STA_MODE, NULL)) ? false : true;
+}
+
+bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc,
+				uint8_t *channel)
+{
+	bool status = false;
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+			conn_index++) {
+		if (pm_conc_connection_list[conn_index].in_use &&
+		    !wlan_reg_is_dfs_ch(pm_ctx->pdev,
+			pm_conc_connection_list[conn_index].chan)) {
+			*channel = pm_conc_connection_list[conn_index].chan;
+			status = true;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+bool policy_mgr_is_any_dfs_beaconing_session_present(
+		struct wlan_objmgr_psoc *psoc, uint8_t *channel)
+{
+	struct policy_mgr_conc_connection_info *conn_info;
+	bool status = false;
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+			conn_index++) {
+		conn_info = &pm_conc_connection_list[conn_index];
+		if (conn_info->in_use &&
+			wlan_reg_is_dfs_ch(pm_ctx->pdev, conn_info->chan) &&
+		    (PM_SAP_MODE == conn_info->mode ||
+		     PM_P2P_GO_MODE == conn_info->mode)) {
+			*channel = pm_conc_connection_list[conn_index].chan;
+			status = true;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc,
+				enum policy_mgr_con_mode mode,
+				uint8_t *nss_2g, uint8_t *nss_5g)
+{
+	enum QDF_OPMODE dev_mode;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	dev_mode = policy_mgr_get_qdf_mode_from_pm(mode);
+	if (dev_mode == QDF_MAX_NO_OF_MODE)
+		return  QDF_STATUS_E_FAILURE;
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pm_ctx->sme_cbacks.sme_get_nss_for_vdev) {
+		pm_ctx->sme_cbacks.sme_get_nss_for_vdev(
+			dev_mode, nss_2g, nss_5g);
+
+	} else {
+		policy_mgr_err("sme_get_nss_for_vdev callback is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		policy_mgr_debug("%d: use:%d vdev:%d mode:%d mac:%d chan:%d orig chainmask:%d orig nss:%d bw:%d",
+				i, pm_conc_connection_list[i].in_use,
+				pm_conc_connection_list[i].vdev_id,
+				pm_conc_connection_list[i].mode,
+				pm_conc_connection_list[i].mac,
+				pm_conc_connection_list[i].chan,
+				pm_conc_connection_list[i].chain_mask,
+				pm_conc_connection_list[i].original_nss,
+				pm_conc_connection_list[i].bw);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+bool policy_mgr_is_any_mode_active_on_band_along_with_session(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t session_id,
+						enum policy_mgr_band band)
+{
+	uint32_t i;
+	bool status = false;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		status = false;
+		goto send_status;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		switch (band) {
+		case POLICY_MGR_BAND_24:
+			if ((pm_conc_connection_list[i].vdev_id != session_id)
+			&& (pm_conc_connection_list[i].in_use) &&
+			(WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[i].chan))) {
+				status = true;
+				goto release_mutex_and_send_status;
+			}
+			break;
+		case POLICY_MGR_BAND_5:
+			if ((pm_conc_connection_list[i].vdev_id != session_id)
+			&& (pm_conc_connection_list[i].in_use) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[i].chan))) {
+				status = true;
+				goto release_mutex_and_send_status;
+			}
+			break;
+		default:
+			policy_mgr_err("Invalidband option:%d", band);
+			status = false;
+			goto release_mutex_and_send_status;
+		}
+	}
+release_mutex_and_send_status:
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+send_status:
+	return status;
+}
+
+QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc,
+					uint8_t session_id, uint8_t *chan)
+{
+	uint32_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if ((pm_conc_connection_list[i].vdev_id == session_id) &&
+		    (pm_conc_connection_list[i].in_use)) {
+			*chan = pm_conc_connection_list[i].chan;
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc,
+					uint8_t session_id, uint8_t *mac_id)
+{
+	uint32_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if ((pm_conc_connection_list[i].vdev_id == session_id) &&
+		    (pm_conc_connection_list[i].in_use)) {
+			*mac_id = pm_conc_connection_list[i].mac;
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc,
+					uint8_t mac_id, uint8_t session_id,
+					uint8_t *mcc_session_id)
+{
+	uint32_t i;
+	QDF_STATUS status;
+	uint8_t chan;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = policy_mgr_get_chan_by_session_id(psoc, session_id, &chan);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Failed to get channel for session id:%d",
+			       session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if (pm_conc_connection_list[i].mac != mac_id)
+			continue;
+		if (pm_conc_connection_list[i].vdev_id == session_id)
+			continue;
+		/* Inter band or intra band MCC */
+		if ((pm_conc_connection_list[i].chan != chan) &&
+		    (pm_conc_connection_list[i].in_use)) {
+			*mcc_session_id = pm_conc_connection_list[i].vdev_id;
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc,
+					uint8_t session_id)
+{
+	uint8_t mac_id, mcc_session_id;
+	QDF_STATUS status;
+	uint8_t chan;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return INVALID_CHANNEL_ID;
+	}
+
+	status = policy_mgr_get_mac_id_by_session_id(psoc, session_id, &mac_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get MAC ID");
+		return INVALID_CHANNEL_ID;
+	}
+
+	status = policy_mgr_get_mcc_session_id_on_mac(psoc, mac_id, session_id,
+			&mcc_session_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get MCC session ID");
+		return INVALID_CHANNEL_ID;
+	}
+
+	status = policy_mgr_get_chan_by_session_id(psoc, mcc_session_id,
+						   &chan);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Failed to get channel for MCC session ID:%d",
+			       mcc_session_id);
+		return INVALID_CHANNEL_ID;
+	}
+
+	return chan;
+}
+
+void policy_mgr_set_do_hw_mode_change_flag(struct wlan_objmgr_psoc *psoc,
+		bool flag)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	pm_ctx->do_hw_mode_change = flag;
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	policy_mgr_debug("hw_mode_change_channel:%d", flag);
+}
+
+bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc)
+{
+	bool flag;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return INVALID_CHANNEL_ID;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	flag = pm_ctx->do_hw_mode_change;
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return flag;
+}
+
+bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev)
+{
+	bool roffchan;
+
+	if (!vdev) {
+		policy_mgr_err("Invalid parameter");
+		return false;
+	}
+
+	roffchan = wlan_vdev_mlme_cap_get(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN);
+
+	policy_mgr_debug("Restrict offchannel:%s",
+			 roffchan  ? "set" : "clear");
+
+	return roffchan;
+}
+
+QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc,
+			uint8_t channel, bool *ok)
+{
+	uint32_t cc_count = 0, i;
+	uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!channel || !ok) {
+		policy_mgr_err("Invalid parameter");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
+					&operating_channel[cc_count],
+					&vdev_id[cc_count],
+					PM_SAP_MODE);
+	policy_mgr_debug("Number of SAP modes: %d", cc_count);
+	cc_count = cc_count + policy_mgr_get_mode_specific_conn_info(psoc,
+					&operating_channel[cc_count],
+					&vdev_id[cc_count],
+					PM_P2P_GO_MODE);
+	policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
+							cc_count);
+	if (!cc_count) {
+		*ok = true;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	for (i = 0; i < cc_count; i++) {
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+							vdev_id[i],
+						WLAN_POLICY_MGR_ID);
+		if (!vdev) {
+			policy_mgr_err("vdev for vdev_id:%d is NULL",
+							vdev_id[i]);
+			return QDF_STATUS_E_INVAL;
+		}
+
+	/**
+	 * If channel passed is same as AP/GO operating channel, then
+	 *   return true.
+	 * If channel is different from operating channel but in same band.
+	 *   return false.
+	 * If operating channel in different band (DBS capable).
+	 *   return true.
+	 * If operating channel in different band (not DBS capable).
+	 *   return false.
+	 */
+	/* TODO: To be enhanced for SBS */
+		if (policy_mgr_is_dnsc_set(vdev)) {
+			if (operating_channel[i] == channel) {
+				*ok = true;
+				wlan_objmgr_vdev_release_ref(vdev,
+						WLAN_POLICY_MGR_ID);
+				break;
+			} else if (WLAN_REG_IS_SAME_BAND_CHANNELS(
+				operating_channel[i], channel)) {
+				*ok = false;
+				wlan_objmgr_vdev_release_ref(vdev,
+						WLAN_POLICY_MGR_ID);
+				break;
+			} else if (policy_mgr_is_hw_dbs_capable(psoc)) {
+				*ok = true;
+				wlan_objmgr_vdev_release_ref(vdev,
+						WLAN_POLICY_MGR_ID);
+				break;
+			} else {
+				*ok = false;
+				wlan_objmgr_vdev_release_ref(vdev,
+						WLAN_POLICY_MGR_ID);
+				break;
+			}
+		} else {
+			*ok = true;
+		}
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+	policy_mgr_debug("chan: %d ok %d", channel, *ok);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc,
+				   struct dbs_nss *nss_dbs)
+{
+	int i, param;
+	uint32_t dbs, tx_chain0, rx_chain0, tx_chain1, rx_chain1;
+	uint32_t min_mac0_rf_chains, min_mac1_rf_chains;
+	uint32_t max_rf_chains, final_max_rf_chains = HW_MODE_SS_0x0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return final_max_rf_chains;
+	}
+
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param);
+
+		if (dbs) {
+			tx_chain0
+				= POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param);
+			rx_chain0
+				= POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param);
+
+			tx_chain1
+				= POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param);
+			rx_chain1
+				= POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param);
+
+			min_mac0_rf_chains = QDF_MIN(tx_chain0, rx_chain0);
+			min_mac1_rf_chains = QDF_MIN(tx_chain1, rx_chain1);
+
+			max_rf_chains
+			= QDF_MAX(min_mac0_rf_chains, min_mac1_rf_chains);
+
+			if (final_max_rf_chains < max_rf_chains) {
+				final_max_rf_chains
+					= (max_rf_chains == 2)
+					? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
+
+				nss_dbs->mac0_ss
+					= (min_mac0_rf_chains == 2)
+					? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
+
+				nss_dbs->mac1_ss
+					= (min_mac1_rf_chains == 2)
+					? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
+			}
+		} else {
+			continue;
+		}
+	}
+
+	return final_max_rf_chains;
+}
+
+bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc)
+{
+	if ((DISABLE_DBS_CXN_AND_SCAN ==
+	     wlan_objmgr_psoc_get_dual_mac_disable(psoc)) ||
+	    (ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN ==
+	     wlan_objmgr_psoc_get_dual_mac_disable(psoc)) ||
+	    (ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN ==
+	     wlan_objmgr_psoc_get_dual_mac_disable(psoc)) ||
+	     !policy_mgr_is_hw_dbs_capable(psoc))
+		return false;
+
+	return true;
+}
+
+void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc,
+		uint8_t conc_system_pref)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	policy_mgr_debug("conc_system_pref %hu", conc_system_pref);
+	pm_ctx->cur_conc_system_pref = conc_system_pref;
+}
+
+uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return PM_THROUGHPUT;
+	}
+
+	policy_mgr_debug("conc_system_pref %hu", pm_ctx->cur_conc_system_pref);
+	return pm_ctx->cur_conc_system_pref;
+}
+
+QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config(
+		struct wlan_objmgr_psoc *psoc, uint32_t *scan_config,
+		uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini,
+		uint32_t channel_select_logic_conc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
+	*fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config;
+	switch (dual_mac_disable_ini) {
+	case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF:
+		policy_mgr_debug("dual_mac_disable_ini:%d async/dbs off",
+			dual_mac_disable_ini);
+		WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0);
+		WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(*fw_mode_config, 0);
+		break;
+	case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN:
+		policy_mgr_debug("dual_mac_disable_ini:%d dbs_cxn off",
+			dual_mac_disable_ini);
+		WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(*fw_mode_config, 0);
+		break;
+	case ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF:
+		policy_mgr_debug("dual_mac_disable_ini:%d async off",
+			dual_mac_disable_ini);
+		WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0);
+		break;
+	case ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN:
+		policy_mgr_debug("%s: dual_mac_disable_ini:%d ", __func__,
+				dual_mac_disable_ini);
+		WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(*scan_config, 0);
+		break;
+	default:
+		break;
+	}
+
+	WMI_DBS_FW_MODE_CFG_DBS_FOR_STA_PLUS_STA_SET(*fw_mode_config,
+		PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(channel_select_logic_conc));
+	WMI_DBS_FW_MODE_CFG_DBS_FOR_STA_PLUS_P2P_SET(*fw_mode_config,
+		PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(channel_select_logic_conc));
+
+	policy_mgr_debug("*scan_config:%x ", *scan_config);
+	policy_mgr_debug("*fw_mode_config:%x ", *fw_mode_config);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+
+	return ((pm_ctx->cfg.mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) ||
+		(pm_ctx->cfg.mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) ||
+		(pm_ctx->cfg.mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) ||
+		(pm_ctx->cfg.mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_WITH_PREFERRED_BAND));
+}
+
+bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool status = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	if (policy_mgr_is_force_scc(psoc) &&
+		pm_ctx->user_cfg.is_sta_sap_scc_allowed_on_dfs_chan)
+		status = true;
+
+	return status;
+}
+
+bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_index;
+	bool ret = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return ret;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE &&
+		    pm_conc_connection_list[conn_index].chan <= 14 &&
+		    pm_conc_connection_list[conn_index].in_use)
+			ret = true;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return ret;
+}
+
+void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc,
+		uint8_t *org_ch_list, uint8_t *org_ch_list_count)
+{
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t index = 0, count, i, ch_list_count;
+	uint8_t band_mask = 0, ch_5g = 0, ch_24g = 0;
+	uint8_t ch_list[QDF_MAX_NUM_CHAN];
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (*org_ch_list_count >= QDF_MAX_NUM_CHAN) {
+		policy_mgr_err("org_ch_list_count too big %d",
+			*org_ch_list_count);
+		return;
+	}
+	/*
+	 * if force SCC is enabled and there is a STA connection, trim the
+	 * ACS channel list on the band on which STA connection is present
+	 */
+	count = policy_mgr_mode_specific_connection_count(
+				psoc, PM_STA_MODE, list);
+	if (!(policy_mgr_is_force_scc(psoc) && count))
+		return;
+	while (index < count) {
+		if (WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[list[index]].chan) &&
+			policy_mgr_is_safe_channel(psoc,
+			pm_conc_connection_list[list[index]].chan)) {
+			band_mask |= 1;
+			ch_24g = pm_conc_connection_list[list[index]].chan;
+		}
+		if (WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[list[index]].chan) &&
+			policy_mgr_is_safe_channel(psoc,
+			pm_conc_connection_list[list[index]].chan) &&
+			!wlan_reg_is_dfs_ch(pm_ctx->pdev,
+			pm_conc_connection_list[list[index]].chan) &&
+			!wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev,
+			pm_conc_connection_list[list[index]].chan)) {
+			band_mask |= 2;
+			ch_5g = pm_conc_connection_list[list[index]].chan;
+		}
+		index++;
+	}
+	ch_list_count = 0;
+	if (band_mask == 1) {
+		ch_list[ch_list_count++] = ch_24g;
+		for (i = 0; i < *org_ch_list_count; i++) {
+			if (WLAN_REG_IS_24GHZ_CH(
+				org_ch_list[i]))
+				continue;
+			ch_list[ch_list_count++] =
+				org_ch_list[i];
+		}
+	} else if (band_mask == 2) {
+		if ((reg_get_channel_state(pm_ctx->pdev, ch_5g) ==
+			CHANNEL_STATE_DFS) &&
+		      policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))
+			ch_list[ch_list_count++] = ch_5g;
+		else if (!(reg_get_channel_state(pm_ctx->pdev, ch_5g) ==
+			CHANNEL_STATE_DFS))
+			ch_list[ch_list_count++] = ch_5g;
+		for (i = 0; i < *org_ch_list_count; i++) {
+			if (WLAN_REG_IS_5GHZ_CH(
+				org_ch_list[i]))
+				continue;
+			ch_list[ch_list_count++] =
+				org_ch_list[i];
+		}
+	} else if (band_mask == 3) {
+		ch_list[ch_list_count++] = ch_24g;
+		ch_list[ch_list_count++] = ch_5g;
+	} else {
+		policy_mgr_debug("unexpected band_mask value %d",
+			band_mask);
+		return;
+	}
+
+	*org_ch_list_count = ch_list_count;
+	for (i = 0; i < *org_ch_list_count; i++)
+		org_ch_list[i] = ch_list[i];
+
+}
+
+uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc,
+					struct connection_info *info)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_index, count = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return count;
+	}
+
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			info[count].vdev_id =
+				pm_conc_connection_list[conn_index].vdev_id;
+			info[count].mac_id =
+				pm_conc_connection_list[conn_index].mac;
+			info[count].channel =
+				pm_conc_connection_list[conn_index].chan;
+			count++;
+		}
+	}
+
+	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 vdev_id)
+{
+	enum policy_mgr_con_mode con_mode;
+	uint8_t con_chan;
+	int id;
+	uint32_t vdev;
+	bool dbs;
+
+	if (mode != PM_SAP_MODE && mode != PM_P2P_GO_MODE)
+		return true;
+	if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc))
+		return true;
+	dbs = policy_mgr_is_hw_dbs_capable(psoc);
+	for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) {
+		if (!pm_conc_connection_list[id].in_use)
+			continue;
+		vdev = pm_conc_connection_list[id].vdev_id;
+		if (vdev_id == vdev)
+			continue;
+		con_mode = pm_conc_connection_list[id].mode;
+		if (con_mode != PM_SAP_MODE && con_mode != PM_P2P_GO_MODE)
+			continue;
+		con_chan = pm_conc_connection_list[id].chan;
+		if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc) &&
+		    (channel == con_chan)) {
+			policy_mgr_debug("SCC enabled, 2 AP on same channel, allow 2nd AP");
+			return true;
+		}
+		if (!dbs) {
+			policy_mgr_debug("DBS unsupported, mcc and scc unsupported too, don't allow 2nd AP");
+			return false;
+		}
+		if (WLAN_REG_IS_SAME_BAND_CHANNELS(channel, con_chan)) {
+			policy_mgr_debug("DBS supported, 2 SAP on same band, reject 2nd AP");
+			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)
+{
+	struct wmi_unified *wmi_handle;
+
+	wmi_handle = get_wmi_unified_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("Dual beaconing on same channel on single MAC supported");
+		return true;
+	}
+	policy_mgr_debug("Dual beaconing on same channel on single MAC is not supported");
+	return false;
+}
+
+bool policy_mgr_dual_beacon_on_single_mac_mcc_capable(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct wmi_unified *wmi_handle;
+
+	wmi_handle = get_wmi_unified_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("Dual beaconing on different channel on single MAC supported");
+		return true;
+	}
+	policy_mgr_debug("Dual beaconing on different channel on single MAC is not supported");
+	return false;
+}
+
+bool policy_mgr_sta_sap_scc_on_lte_coex_chan(
+	struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	return pm_ctx->user_cfg.sta_sap_scc_on_lte_coex_chan;
+}
+
+bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc,
+					    uint8_t channel)
+{
+	uint32_t sta_sap_scc_on_dfs_chan;
+	uint32_t sap_count;
+	enum channel_state state;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	sta_sap_scc_on_dfs_chan =
+			policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+	sap_count = policy_mgr_mode_specific_connection_count(psoc,
+							      PM_SAP_MODE,
+							      NULL);
+	state = reg_get_channel_state(pm_ctx->pdev, channel);
+
+	policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u, channel %u, state %u",
+			 sta_sap_scc_on_dfs_chan, sap_count, channel, state);
+
+	if ((state == CHANNEL_STATE_ENABLE) || (sap_count == 0) ||
+	    ((state == CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan)) {
+		policy_mgr_debug("Valid channel for channel switch");
+		return true;
+	}
+
+	policy_mgr_debug("Invalid channel for channel switch");
+	return false;
+}
+
+bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch)
+{
+	uint32_t conn_index;
+	bool is_scc = false;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return is_scc;
+	}
+
+	if (!policy_mgr_mode_specific_connection_count(
+		psoc, PM_STA_MODE, NULL)) {
+		policy_mgr_debug("There is no STA+SAP conc");
+		return is_scc;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		conn_index++) {
+		if (pm_conc_connection_list[conn_index].in_use &&
+			(pm_conc_connection_list[conn_index].mode ==
+			PM_STA_MODE) &&
+			(sap_ch == pm_conc_connection_list[conn_index].chan)) {
+			is_scc = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return is_scc;
+}

+ 583 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef WLAN_POLICY_MGR_I_H
+#define WLAN_POLICY_MGR_I_H
+
+#include "wlan_policy_mgr_api.h"
+#include "qdf_event.h"
+#include "qdf_mc_timer.h"
+#include "qdf_lock.h"
+#include "qdf_defer.h"
+#include "wlan_reg_services_api.h"
+
+#define DBS_OPPORTUNISTIC_TIME   5
+#ifdef QCA_WIFI_3_0_EMU
+#define CONNECTION_UPDATE_TIMEOUT 3000
+#else
+#define CONNECTION_UPDATE_TIMEOUT 1000
+#endif
+
+#define PM_24_GHZ_CHANNEL_6   (6)
+#define PM_5_GHZ_CHANNEL_36   (36)
+#define CHANNEL_SWITCH_COMPLETE_TIMEOUT   (2000)
+
+/**
+ * Policy Mgr hardware mode list bit-mask definitions.
+ * Bits 4:0, 31:29 are unused.
+ *
+ * The below definitions are added corresponding to WMI DBS HW mode
+ * list to make it independent of firmware changes for WMI definitions.
+ * Currently these definitions have dependency with BIT positions of
+ * the existing WMI macros. Thus, if the BIT positions are changed for
+ * WMI macros, then these macros' BIT definitions are also need to be
+ * changed.
+ */
+#define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS  (28)
+#define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS  (24)
+#define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS  (20)
+#define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS  (16)
+#define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS   (12)
+#define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS   (8)
+#define POLICY_MGR_HW_MODE_DBS_MODE_BITPOS         (7)
+#define POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS   (6)
+#define POLICY_MGR_HW_MODE_SBS_MODE_BITPOS         (5)
+#define POLICY_MGR_HW_MODE_MAC0_BAND_BITPOS        (3)
+#define POLICY_MGR_HW_MODE_ID_BITPOS               (0)
+
+#define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_MASK    \
+	(0xf << POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_MASK    \
+	(0xf << POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_MASK    \
+	(0xf << POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_MASK    \
+	(0xf << POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_MASK     \
+	(0xf << POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_MASK     \
+	(0xf << POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS)
+#define POLICY_MGR_HW_MODE_DBS_MODE_MASK           \
+	(0x1 << POLICY_MGR_HW_MODE_DBS_MODE_BITPOS)
+#define POLICY_MGR_HW_MODE_AGILE_DFS_MODE_MASK     \
+	(0x1 << POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS)
+#define POLICY_MGR_HW_MODE_SBS_MODE_MASK           \
+	(0x1 << POLICY_MGR_HW_MODE_SBS_MODE_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC0_BAND_MASK           \
+			(0x3 << POLICY_MGR_HW_MODE_MAC0_BAND_BITPOS)
+#define POLICY_MGR_HW_MODE_ID_MASK           \
+			(0x7 << POLICY_MGR_HW_MODE_ID_BITPOS)
+
+#define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_SET(hw_mode, value) \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS,\
+	4, value)
+#define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_SET(hw_mode, value) \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS,\
+	4, value)
+#define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_SET(hw_mode, value) \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS,\
+	4, value)
+#define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_SET(hw_mode, value) \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS,\
+	4, value)
+#define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_SET(hw_mode, value)  \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS,\
+	4, value)
+#define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_SET(hw_mode, value)  \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS,\
+	4, value)
+#define POLICY_MGR_HW_MODE_DBS_MODE_SET(hw_mode, value)        \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_DBS_MODE_BITPOS,\
+	1, value)
+#define POLICY_MGR_HW_MODE_AGILE_DFS_SET(hw_mode, value)       \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS,\
+	1, value)
+#define POLICY_MGR_HW_MODE_SBS_MODE_SET(hw_mode, value)        \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_SBS_MODE_BITPOS,\
+	1, value)
+#define POLICY_MGR_HW_MODE_MAC0_BAND_SET(hw_mode, value)        \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_BAND_BITPOS,\
+	2, value)
+#define POLICY_MGR_HW_MODE_ID_SET(hw_mode, value)        \
+	WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_ID_BITPOS,\
+	3, value)
+
+#define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(hw_mode)                \
+		(((hw_mode) & POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_MASK) >>    \
+		POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(hw_mode)                \
+		(((hw_mode) & POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_MASK) >>    \
+		POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(hw_mode)                \
+		(((hw_mode) & POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_MASK) >>    \
+		POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(hw_mode)                \
+		(((hw_mode) & POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_MASK) >>    \
+		POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(hw_mode)                 \
+		(((hw_mode) & POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_MASK) >>     \
+		POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(hw_mode)                 \
+		(((hw_mode) & POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_MASK) >>     \
+		POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS)
+#define POLICY_MGR_HW_MODE_DBS_MODE_GET(hw_mode)                       \
+		(((hw_mode) & POLICY_MGR_HW_MODE_DBS_MODE_MASK) >>           \
+		POLICY_MGR_HW_MODE_DBS_MODE_BITPOS)
+#define POLICY_MGR_HW_MODE_AGILE_DFS_GET(hw_mode)                      \
+		(((hw_mode) & POLICY_MGR_HW_MODE_AGILE_DFS_MODE_MASK) >>     \
+		POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS)
+#define POLICY_MGR_HW_MODE_SBS_MODE_GET(hw_mode)                       \
+		(((hw_mode) & POLICY_MGR_HW_MODE_SBS_MODE_MASK) >>           \
+		POLICY_MGR_HW_MODE_SBS_MODE_BITPOS)
+#define POLICY_MGR_HW_MODE_MAC0_BAND_GET(hw_mode)                       \
+		(((hw_mode) & POLICY_MGR_HW_MODE_MAC0_BAND_MASK) >> \
+		POLICY_MGR_HW_MODE_MAC0_BAND_BITPOS)
+#define POLICY_MGR_HW_MODE_ID_GET(hw_mode)                       \
+		(((hw_mode) & POLICY_MGR_HW_MODE_ID_MASK) >> \
+		POLICY_MGR_HW_MODE_ID_BITPOS)
+
+#define POLICY_MGR_DEFAULT_HW_MODE_INDEX 0xFFFF
+
+#define policy_mgr_alert(params...) \
+	QDF_TRACE_FATAL(QDF_MODULE_ID_POLICY_MGR, params)
+#define policy_mgr_err(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_POLICY_MGR, params)
+#define policy_mgr_warn(params...) \
+	QDF_TRACE_WARN(QDF_MODULE_ID_POLICY_MGR, params)
+#define policy_mgr_notice(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_POLICY_MGR, params)
+#define policy_mgr_info(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_POLICY_MGR, params)
+#define policy_mgr_debug(params...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_POLICY_MGR, params)
+
+#define policymgr_nofl_alert(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_POLICY_MGR, params)
+#define policymgr_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_POLICY_MGR, params)
+#define policymgr_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_POLICY_MGR, params)
+#define policymgr_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_POLICY_MGR, params)
+#define policymgr_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_POLICY_MGR, params)
+
+#define PM_CONC_CONNECTION_LIST_VALID_INDEX(index) \
+		((MAX_NUMBER_OF_CONC_CONNECTIONS > index) && \
+			(pm_conc_connection_list[index].in_use))
+
+extern struct policy_mgr_conc_connection_info
+	pm_conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+
+extern const enum policy_mgr_pcl_type
+	first_connection_pcl_table[PM_MAX_NUM_OF_MODE]
+			[PM_MAX_CONC_PRIORITY_MODE];
+extern pm_dbs_pcl_second_connection_table_type
+		*second_connection_pcl_dbs_table;
+extern pm_dbs_pcl_third_connection_table_type
+		*third_connection_pcl_dbs_table;
+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);
+
+/**
+ * struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work
+ * related info
+ * @psoc: pointer to PSOC object information
+ */
+struct sta_ap_intf_check_work_ctx {
+	struct wlan_objmgr_psoc *psoc;
+};
+
+/**
+ * struct policy_mgr_cfg - all the policy manager owned configs
+ * @mcc_to_scc_switch: switch to indicate MCC to SCC config
+ * @sys_pref: system's preference while selecting PCLs
+ * @max_conc_cxns: Max allowed concurrenct active connections
+ * @conc_rule1: concurrency rule1
+ * @conc_rule2: concurrency rule2
+ * @dbs_selection_plcy: DBS selection policy for concurrency
+ * @vdev_priority_list: Priority list for various vdevs
+ * @chnl_select_plcy: Channel selection policy
+ * @enable_mcc_adaptive_sch: Enable/Disable MCC adaptive scheduler
+ * @enable_sta_cxn_5g_band: Enable/Disable STA connection in 5G band
+ */
+struct policy_mgr_cfg {
+	uint8_t mcc_to_scc_switch;
+	uint8_t sys_pref;
+	uint8_t max_conc_cxns;
+	uint8_t conc_rule1;
+	uint8_t conc_rule2;
+	uint8_t enable_mcc_adaptive_sch;
+	uint8_t enable_sta_cxn_5g_band;
+	uint32_t dbs_selection_plcy;
+	uint32_t vdev_priority_list;
+	uint32_t chnl_select_plcy;
+};
+
+/**
+ * struct policy_mgr_psoc_priv_obj - Policy manager private data
+ * @psoc: pointer to PSOC object information
+ * @pdev: pointer to PDEV object information
+ * @connection_update_done_evt: qdf event to synchronize
+ *                            connection activities
+ * @qdf_conc_list_lock: To protect connection table
+ * @dbs_opportunistic_timer: Timer to drop down to Single Mac
+ *                         Mode opportunistically
+ * @sap_restart_chan_switch_cb: Callback for channel switch
+ *                            notification for SAP
+ * @sme_cbacks: callbacks to be registered by SME for
+ *            interaction with Policy Manager
+ * @wma_cbacks: callbacks to be registered by SME for
+ * interaction with Policy Manager
+ * @tdls_cbacks: callbacks to be registered by SME for
+ * interaction with Policy Manager
+ * @cdp_cbacks: callbacks to be registered by SME for
+ * interaction with Policy Manager
+ * @sap_mandatory_channels: The user preferred master list on
+ *                        which SAP can be brought up. This
+ *                        mandatory channel list would be as per
+ *                        OEMs preference & conforming to the
+ *                        regulatory/other considerations
+ * @sap_mandatory_channels_len: Length of the SAP mandatory
+ *                            channel list
+ * @do_hw_mode_change: Flag to check if HW mode change is needed
+ *                   after vdev is up. Especially used after
+ *                   channel switch related vdev restart
+ * @concurrency_mode: active concurrency combination
+ * @no_of_open_sessions: Number of active vdevs
+ * @no_of_active_sessions: Number of active connections
+ * @sta_ap_intf_check_work: delayed sap restart work
+ * @num_dbs_hw_modes: Number of different HW modes supported
+ * @hw_mode: List of HW modes supported
+ * @old_hw_mode_index: Old HW mode from hw_mode table
+ * @new_hw_mode_index: New HW mode from hw_mode table
+ * @dual_mac_cfg: DBS configuration currenctly used by FW for
+ *              scan & connections
+ * @hw_mode_change_in_progress: This is to track if HW mode
+ *                            change is in progress
+ * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler
+ *      value from INI
+ * @unsafe_channel_list: LTE coex channel avoidance list
+ * @unsafe_channel_count: LTE coex channel avoidance list count
+ * @sta_ap_intf_check_work_info: Info related to sta_ap_intf_check_work
+ * @opportunistic_update_done_evt: qdf event to synchronize host
+ *                               & FW HW mode
+ */
+struct policy_mgr_psoc_priv_obj {
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	qdf_event_t connection_update_done_evt;
+	qdf_mutex_t qdf_conc_list_lock;
+	qdf_mc_timer_t dbs_opportunistic_timer;
+	struct policy_mgr_hdd_cbacks hdd_cbacks;
+	struct policy_mgr_sme_cbacks sme_cbacks;
+	struct policy_mgr_wma_cbacks wma_cbacks;
+	struct policy_mgr_tdls_cbacks tdls_cbacks;
+	struct policy_mgr_cdp_cbacks cdp_cbacks;
+	struct policy_mgr_dp_cbacks dp_cbacks;
+	bool enable_sap_mandatory_chan_list;
+	uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN];
+	uint32_t sap_mandatory_channels_len;
+	bool do_hw_mode_change;
+	uint32_t concurrency_mode;
+	uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE];
+	uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE];
+	qdf_work_t sta_ap_intf_check_work;
+	uint32_t num_dbs_hw_modes;
+	struct dbs_hw_mode_info hw_mode;
+	uint32_t old_hw_mode_index;
+	uint32_t new_hw_mode_index;
+	struct dual_mac_config dual_mac_cfg;
+	uint32_t hw_mode_change_in_progress;
+	struct policy_mgr_user_cfg user_cfg;
+	uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN];
+	uint16_t unsafe_channel_count;
+	struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info;
+	uint8_t cur_conc_system_pref;
+	uint8_t sta_sap_scc_on_dfs_chan_allowed;
+	qdf_event_t opportunistic_update_done_evt;
+	qdf_event_t channel_switch_complete_evt;
+	send_mode_change_event_cb mode_change_cb;
+	uint32_t user_config_sap_channel;
+	struct policy_mgr_cfg cfg;
+};
+
+/**
+ * struct policy_mgr_mac_ss_bw_info - hw_mode_list PHY/MAC params for each MAC
+ * @mac_tx_stream: Max TX stream number supported on MAC
+ * @mac_rx_stream: Max RX stream number supported on MAC
+ * @mac_bw: Max bandwidth(wmi_channel_width enum type)
+ * @mac_band_cap: supported Band bit map(WLAN_2G_CAPABILITY = 0x1,
+ *                            WLAN_5G_CAPABILITY = 0x2)
+ */
+struct policy_mgr_mac_ss_bw_info {
+	uint32_t mac_tx_stream;
+	uint32_t mac_rx_stream;
+	uint32_t mac_bw;
+	uint32_t mac_band_cap;
+};
+
+struct policy_mgr_psoc_priv_obj *policy_mgr_get_context(
+		struct wlan_objmgr_psoc *psoc);
+QDF_STATUS policy_mgr_get_updated_scan_config(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *scan_config,
+		bool dbs_scan,
+		bool dbs_plus_agile_scan,
+		bool single_mac_scan_with_dfs);
+QDF_STATUS policy_mgr_get_updated_fw_mode_config(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *fw_mode_config,
+		bool dbs,
+		bool agile_dfs);
+bool policy_mgr_is_dual_mac_disabled_in_ini(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_mcc_to_scc_switch_mode() - MCC to SCC
+ * switch mode value in the user config
+ * @psoc: PSOC object information
+ *
+ * MCC to SCC switch mode value in user config
+ *
+ * Return: MCC to SCC switch mode value
+ */
+uint32_t policy_mgr_get_mcc_to_scc_switch_mode(
+	struct wlan_objmgr_psoc *psoc);
+bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc);
+bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc);
+bool policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc *psoc);
+void policy_mgr_get_tx_rx_ss_from_config(enum hw_mode_ss_config mac_ss,
+		uint32_t *tx_ss, uint32_t *rx_ss);
+int8_t policy_mgr_get_matching_hw_mode_index(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t mac0_tx_ss, uint32_t mac0_rx_ss,
+		enum hw_mode_bandwidth mac0_bw,
+		uint32_t mac1_tx_ss, uint32_t mac1_rx_ss,
+		enum hw_mode_bandwidth mac1_bw,
+		enum hw_mode_mac_band_cap mac0_band_cap,
+		enum hw_mode_dbs_capab dbs,
+		enum hw_mode_agile_dfs_capab dfs,
+		enum hw_mode_sbs_capab sbs);
+int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
+		struct wlan_objmgr_psoc *psoc,
+		enum hw_mode_ss_config mac0_ss,
+		enum hw_mode_bandwidth mac0_bw,
+		enum hw_mode_ss_config mac1_ss,
+		enum hw_mode_bandwidth mac1_bw,
+		enum hw_mode_mac_band_cap mac0_band_cap,
+		enum hw_mode_dbs_capab dbs,
+		enum hw_mode_agile_dfs_capab dfs,
+		enum hw_mode_sbs_capab sbs);
+QDF_STATUS policy_mgr_get_old_and_new_hw_index(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *old_hw_mode_index,
+		uint32_t *new_hw_mode_index);
+void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
+		uint32_t conn_index,
+		enum policy_mgr_con_mode mode,
+		uint8_t chan,
+		enum hw_mode_bandwidth bw,
+		uint8_t mac,
+		enum policy_mgr_chain_mode chain_mask,
+		uint32_t original_nss,
+		uint32_t vdev_id,
+		bool in_use,
+		bool update_conn);
+void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
+				enum policy_mgr_con_mode mode,
+				bool all_matching_cxn_to_del,
+				struct policy_mgr_conc_connection_info *info,
+				uint8_t *num_cxn_del);
+
+/**
+ * policy_mgr_store_and_del_conn_info_by_vdev_id() - Store and del a
+ * connection info by vdev id
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id whose entry has to be deleted
+ * @info: struture array pointer where the connection info will be saved
+ * @num_cxn_del: number of connection which are going to be deleted
+ *
+ * Saves the connection info corresponding to the provided mode
+ * and deleted that corresponding entry based on vdev from the
+ * connection info structure
+ *
+ * Return: None
+ */
+void policy_mgr_store_and_del_conn_info_by_vdev_id(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t vdev_id,
+			struct policy_mgr_conc_connection_info *info,
+			uint8_t *num_cxn_del);
+
+void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc,
+				struct policy_mgr_conc_connection_info *info,
+				uint8_t num_cxn_del);
+void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc,
+				uint32_t num_vdev_mac_entries,
+				struct policy_mgr_vdev_mac_map *vdev_mac_map,
+				struct policy_mgr_hw_mode_params hw_mode);
+void policy_mgr_pdev_set_hw_mode_cb(uint32_t status,
+				uint32_t cfgd_hw_mode_index,
+				uint32_t num_vdev_mac_entries,
+				struct policy_mgr_vdev_mac_map *vdev_mac_map,
+				uint8_t next_action,
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t session_id, void *context);
+void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_pdev_set_pcl() - SET PCL channel list and send to firmware
+ * @psoc: PSOC object information
+ * @mode: Adapter mode
+ *
+ * Return: None
+ */
+void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc,
+			     enum QDF_OPMODE mode);
+void pm_dbs_opportunistic_timer_handler(void *data);
+enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type,
+		uint8_t subtype);
+enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width);
+QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc,
+			enum policy_mgr_pcl_type pcl,
+			uint8_t *pcl_channels, uint32_t *len,
+			enum policy_mgr_con_mode mode,
+			uint8_t *pcl_weights, uint32_t weight_len);
+bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc,
+			uint8_t channel, uint32_t num_connections);
+bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc,
+				uint8_t channel, uint32_t *list,
+				enum policy_mgr_con_mode mode);
+QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc,
+				uint8_t  new_nss, uint8_t next_action,
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t session_id);
+enum policy_mgr_con_mode policy_mgr_get_mode_by_vdev_id(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id);
+QDF_STATUS policy_mgr_init_connection_update(
+		struct policy_mgr_psoc_priv_obj *pm_ctx);
+enum policy_mgr_conc_next_action
+		policy_mgr_get_current_pref_hw_mode_dbs_2x2(
+		struct wlan_objmgr_psoc *psoc);
+enum policy_mgr_conc_next_action
+		policy_mgr_get_current_pref_hw_mode_dbs_1x1(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_current_pref_hw_mode_dual_dbs() - Get the
+ * current preferred hw mode
+ *
+ * Get the preferred hw mode based on the current connection combinations
+ *
+ * Return: No change (PM_NOP), (PM_SINGLE_MAC_UPGRADE),
+ *         DBS (PM_DBS1_DOWNGRADE or PM_DBS2_DOWNGRADE)
+ */
+enum policy_mgr_conc_next_action
+		policy_mgr_get_current_pref_hw_mode_dual_dbs(
+		struct wlan_objmgr_psoc *psoc);
+
+QDF_STATUS policy_mgr_reset_sap_mandatory_channels(
+		struct policy_mgr_psoc_priv_obj *pm_ctx);
+
+/**
+ * policy_mgr_get_mode_specific_conn_info() - Get active mode specific
+ * channel and vdev id
+ * @psoc: PSOC object information
+ * @channel: Mode specific channel (list)
+ * @vdev_id: Mode specific vdev id (list)
+ * @mode: Connection Mode
+ *
+ * Get active mode specific channel and vdev id
+ *
+ * Return: number of connection found as per given mode
+ */
+uint32_t policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc,
+				  uint8_t *channel, uint8_t *vdev_id,
+				  enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_reg_chan_change_callback() - Callback to be
+ * invoked by regulatory module when valid channel list changes
+ * @psoc: PSOC object information
+ * @pdev: PDEV object information
+ * @chan_list: New channel list
+ * @avoid_freq_ind: LTE coex avoid channel list
+ * @arg: Information passed at registration
+ *
+ * Get updated channel list from regulatory module
+ *
+ * Return: None
+ */
+void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc,
+		struct wlan_objmgr_pdev *pdev,
+		struct regulatory_channel *chan_list,
+		struct avoid_freq_ind_data *avoid_freq_ind,
+		void *arg);
+
+/**
+ * policy_mgr_nss_update() - update nss for AP vdev
+ * @psoc: PSOC object information
+ * @new_nss: new NSS value
+ * @next_action: Next action after nss update
+ * @band: update AP vdev on the Band.
+ * @reason: action reason
+ * @original_vdev_id: original request hwmode change vdev id
+ *
+ * The function will update AP vdevs on specific band.
+ *  eg. band = POLICY_MGR_ANY will request to update all band (2g and 5g)
+ *
+ * Return: QDF_STATUS_SUCCESS, update requested successfully.
+ */
+QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc,
+		uint8_t  new_nss, uint8_t next_action,
+		enum policy_mgr_band band,
+		enum policy_mgr_conn_update_reason reason,
+		uint32_t original_vdev_id);
+
+/**
+ * policy_mgr_is_concurrency_allowed() - Check for allowed
+ * concurrency combination
+ * @psoc: PSOC object information
+ * @mode: new connection mode
+ * @channel: channel on which new connection is coming up
+ * @bw: Bandwidth requested by the connection (optional)
+ *
+ * When a new connection is about to come up check if current
+ * concurrency combination including the new connection is
+ * allowed or not based on the HW capability, but no need to
+ * invoke get_pcl
+ *
+ * Return: True/False
+ */
+bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
+				       enum policy_mgr_con_mode mode,
+				       uint8_t channel,
+				       enum hw_mode_bandwidth bw);
+#endif

+ 742 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_policy_mgr_init_deinit.c
+ *
+ * WLAN Concurrenct Connection Management APIs
+ *
+ */
+
+/* Include files */
+
+#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"
+#include "wlan_objmgr_global_obj.h"
+
+static QDF_STATUS policy_mgr_psoc_obj_create_cb(struct wlan_objmgr_psoc *psoc,
+		void *data)
+{
+	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
+
+	policy_mgr_ctx = qdf_mem_malloc(
+		sizeof(struct policy_mgr_psoc_priv_obj));
+	if (!policy_mgr_ctx) {
+		policy_mgr_err("memory allocation failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_ctx->psoc = psoc;
+	policy_mgr_ctx->old_hw_mode_index = POLICY_MGR_DEFAULT_HW_MODE_INDEX;
+	policy_mgr_ctx->new_hw_mode_index = POLICY_MGR_DEFAULT_HW_MODE_INDEX;
+
+	wlan_objmgr_psoc_component_obj_attach(psoc,
+			WLAN_UMAC_COMP_POLICY_MGR,
+			policy_mgr_ctx,
+			QDF_STATUS_SUCCESS);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_psoc_obj_destroy_cb(struct wlan_objmgr_psoc *psoc,
+		void *data)
+{
+	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
+
+	policy_mgr_ctx = policy_mgr_get_context(psoc);
+	wlan_objmgr_psoc_component_obj_detach(psoc,
+					WLAN_UMAC_COMP_POLICY_MGR,
+					policy_mgr_ctx);
+	qdf_mem_free(policy_mgr_ctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void policy_mgr_psoc_obj_status_cb(struct wlan_objmgr_psoc *psoc,
+		void *data, QDF_STATUS status)
+{
+	return;
+}
+
+static QDF_STATUS policy_mgr_pdev_obj_create_cb(struct wlan_objmgr_pdev *pdev,
+		void *data)
+{
+	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	policy_mgr_ctx = policy_mgr_get_context(psoc);
+	if (!policy_mgr_ctx) {
+		policy_mgr_err("invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_ctx->pdev = pdev;
+
+	wlan_reg_register_chan_change_callback(psoc,
+		policy_mgr_reg_chan_change_callback, NULL);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_pdev_obj_destroy_cb(struct wlan_objmgr_pdev *pdev,
+		void *data)
+{
+	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	policy_mgr_ctx = policy_mgr_get_context(psoc);
+	if (!policy_mgr_ctx) {
+		policy_mgr_err("invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_ctx->pdev = NULL;
+	wlan_reg_unregister_chan_change_callback(psoc,
+		policy_mgr_reg_chan_change_callback);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_vdev_obj_create_cb(struct wlan_objmgr_vdev *vdev,
+		void *data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_vdev_obj_destroy_cb(struct wlan_objmgr_vdev *vdev,
+		void *data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static void policy_mgr_vdev_obj_status_cb(struct wlan_objmgr_vdev *vdev,
+		void *data, QDF_STATUS status)
+{
+	return;
+}
+
+QDF_STATUS policy_mgr_init(void)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	status = wlan_objmgr_register_psoc_create_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_psoc_obj_create_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register psoc obj create cback");
+		goto err_psoc_create;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_psoc_obj_destroy_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register psoc obj delete cback");
+		goto err_psoc_delete;
+	}
+
+	status = wlan_objmgr_register_psoc_status_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_psoc_obj_status_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register psoc obj status cback");
+		goto err_psoc_status;
+	}
+
+	status = wlan_objmgr_register_pdev_create_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_pdev_obj_create_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register pdev obj create cback");
+		goto err_pdev_create;
+	}
+
+	status = wlan_objmgr_register_pdev_destroy_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_pdev_obj_destroy_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register pdev obj delete cback");
+		goto err_pdev_delete;
+	}
+
+	status = wlan_objmgr_register_vdev_create_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_vdev_obj_create_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register vdev obj create cback");
+		goto err_vdev_create;
+	}
+
+	status = wlan_objmgr_register_vdev_destroy_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_vdev_obj_destroy_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register vdev obj delete cback");
+		goto err_vdev_delete;
+	}
+
+	status = wlan_objmgr_register_vdev_status_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_vdev_obj_status_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register vdev obj status cback");
+		goto err_vdev_status;
+	}
+
+	policy_mgr_notice("Callbacks registered with obj mgr");
+
+	return QDF_STATUS_SUCCESS;
+
+err_vdev_status:
+	wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR,
+						policy_mgr_vdev_obj_destroy_cb,
+						NULL);
+err_vdev_delete:
+	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR,
+						policy_mgr_vdev_obj_create_cb,
+						NULL);
+err_vdev_create:
+	wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR,
+						policy_mgr_pdev_obj_destroy_cb,
+						NULL);
+err_pdev_delete:
+	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR,
+						policy_mgr_pdev_obj_create_cb,
+						NULL);
+err_pdev_create:
+	wlan_objmgr_unregister_psoc_status_handler(WLAN_UMAC_COMP_POLICY_MGR,
+						policy_mgr_psoc_obj_status_cb,
+						NULL);
+err_psoc_status:
+	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR,
+						policy_mgr_psoc_obj_destroy_cb,
+						NULL);
+err_psoc_delete:
+	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_POLICY_MGR,
+						policy_mgr_psoc_obj_create_cb,
+						NULL);
+err_psoc_create:
+	return status;
+}
+
+QDF_STATUS policy_mgr_deinit(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_unregister_psoc_status_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_psoc_obj_status_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister psoc obj status cback");
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_psoc_obj_destroy_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister psoc obj delete cback");
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_psoc_obj_create_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister psoc obj create cback");
+
+	status = wlan_objmgr_unregister_pdev_destroy_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_pdev_obj_destroy_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister pdev obj delete cback");
+
+	status = wlan_objmgr_unregister_pdev_create_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_pdev_obj_create_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister pdev obj create cback");
+
+	status = wlan_objmgr_unregister_vdev_status_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_vdev_obj_status_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister vdev obj status cback");
+
+	status = wlan_objmgr_unregister_vdev_destroy_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_vdev_obj_destroy_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister vdev obj delete cback");
+
+	status = wlan_objmgr_unregister_vdev_create_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_vdev_obj_create_cb,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister vdev obj create cback");
+
+	policy_mgr_info("deregistered callbacks with obj mgr successfully");
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(
+		&pm_ctx->qdf_conc_list_lock))) {
+		policy_mgr_err("Failed to init qdf_conc_list_lock");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy(
+		&pm_ctx->qdf_conc_list_lock))) {
+		policy_mgr_err("Failed to destroy qdf_conc_list_lock");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pm_ctx->hw_mode.hw_mode_list) {
+		qdf_mem_free(pm_ctx->hw_mode.hw_mode_list);
+		pm_ctx->hw_mode.hw_mode_list = NULL;
+		policy_mgr_info("HW list is freed");
+	}
+
+	if (pm_ctx->sta_ap_intf_check_work_info) {
+		qdf_cancel_work(&pm_ctx->sta_ap_intf_check_work);
+		qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info);
+		pm_ctx->sta_ap_intf_check_work_info = NULL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_debug("Initializing the policy manager");
+
+	/* init pm_conc_connection_list */
+	qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list));
+
+	/* init dbs_opportunistic_timer */
+	status = qdf_mc_timer_init(&pm_ctx->dbs_opportunistic_timer,
+				QDF_TIMER_TYPE_SW,
+				pm_dbs_opportunistic_timer_handler,
+				(void *)psoc);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("Failed to init DBS opportunistic timer");
+		return status;
+	}
+
+	/* init connection_update_done_evt */
+	status = policy_mgr_init_connection_update(pm_ctx);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("connection_update_done_evt init failed");
+		return status;
+	}
+
+	status = qdf_event_create(&pm_ctx->opportunistic_update_done_evt);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("opportunistic_update_done_evt init failed");
+		return status;
+	}
+
+	status = qdf_event_create(&pm_ctx->channel_switch_complete_evt);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("channel_switch_complete_evt init failed");
+		return status;
+	}
+	pm_ctx->do_hw_mode_change = false;
+	pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
+	/* reset sap mandatory channels */
+	status = policy_mgr_reset_sap_mandatory_channels(pm_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to reset mandatory channels");
+		return status;
+	}
+
+	/* init PCL table & function pointers based on HW capability */
+	if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
+		policy_mgr_get_current_pref_hw_mode_ptr =
+		policy_mgr_get_current_pref_hw_mode_dbs_2x2;
+	else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc))
+		policy_mgr_get_current_pref_hw_mode_ptr =
+		policy_mgr_get_current_pref_hw_mode_dual_dbs;
+	else
+		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) ||
+	    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) ||
+	    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)) {
+		next_action_two_connection_table =
+		&pm_next_action_two_connection_dbs_2x2_table;
+	} 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)) {
+		next_action_three_connection_table =
+		&pm_next_action_three_connection_dbs_2x2_table;
+	} 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;
+}
+
+QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* destroy connection_update_done_evt */
+	if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy
+		(&pm_ctx->connection_update_done_evt))) {
+		policy_mgr_err("Failed to destroy connection_update_done_evt");
+		status = QDF_STATUS_E_FAILURE;
+		QDF_ASSERT(0);
+	}
+
+	/* destroy opportunistic_update_done_evt */
+	if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy
+		(&pm_ctx->opportunistic_update_done_evt))) {
+		policy_mgr_err("Failed to destroy opportunistic_update_done_evt");
+		status = QDF_STATUS_E_FAILURE;
+		QDF_ASSERT(0);
+	}
+	/* destroy channel_switch_complete_evt */
+	if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy
+		(&pm_ctx->channel_switch_complete_evt))) {
+		policy_mgr_err("Failed to destroy channel_switch_complete evt");
+		status = QDF_STATUS_E_FAILURE;
+		QDF_ASSERT(0);
+	}
+
+	/* deallocate dbs_opportunistic_timer */
+	if (QDF_TIMER_STATE_RUNNING ==
+			qdf_mc_timer_get_current_state(
+				&pm_ctx->dbs_opportunistic_timer)) {
+		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_destroy(
+			&pm_ctx->dbs_opportunistic_timer))) {
+		policy_mgr_err("Cannot deallocate dbs opportunistic timer");
+		status = QDF_STATUS_E_FAILURE;
+		QDF_ASSERT(0);
+	}
+
+	/* reset sap mandatory channels */
+	if (QDF_IS_STATUS_ERROR(
+		policy_mgr_reset_sap_mandatory_channels(pm_ctx))) {
+		policy_mgr_err("failed to reset sap mandatory channels");
+		status = QDF_STATUS_E_FAILURE;
+		QDF_ASSERT(0);
+	}
+
+	/* deinit pm_conc_connection_list */
+	qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list));
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_sme_cbacks *sme_cbacks)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->sme_cbacks.sme_get_nss_for_vdev =
+		sme_cbacks->sme_get_nss_for_vdev;
+	pm_ctx->sme_cbacks.sme_get_valid_channels =
+		sme_cbacks->sme_get_valid_channels;
+	pm_ctx->sme_cbacks.sme_nss_update_request =
+		sme_cbacks->sme_nss_update_request;
+	pm_ctx->sme_cbacks.sme_pdev_set_hw_mode =
+		sme_cbacks->sme_pdev_set_hw_mode;
+	pm_ctx->sme_cbacks.sme_pdev_set_pcl =
+		sme_cbacks->sme_pdev_set_pcl;
+	pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config =
+		sme_cbacks->sme_soc_set_dual_mac_config;
+	pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval =
+		sme_cbacks->sme_change_mcc_beacon_interval;
+	pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan =
+		sme_cbacks->sme_get_ap_channel_from_scan;
+	pm_ctx->sme_cbacks.sme_scan_result_purge =
+		sme_cbacks->sme_scan_result_purge;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_register_hdd_cb() - register HDD callbacks
+ * @psoc: PSOC object information
+ * @hdd_cbacks: function pointers from HDD
+ *
+ * API, allows HDD to register callbacks to be invoked by policy
+ * mgr
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails)
+ */
+QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_hdd_cbacks *hdd_cbacks)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb =
+		hdd_cbacks->sap_restart_chan_switch_cb;
+	pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
+		hdd_cbacks->wlan_hdd_get_channel_for_sap_restart;
+	pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev =
+		hdd_cbacks->get_mode_for_non_connected_vdev;
+	pm_ctx->hdd_cbacks.hdd_get_device_mode =
+		hdd_cbacks->hdd_get_device_mode;
+	pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist =
+		hdd_cbacks->hdd_wapi_security_sta_exist;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb = NULL;
+	pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = NULL;
+	pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = NULL;
+	pm_ctx->hdd_cbacks.hdd_get_device_mode = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_wma_cbacks *wma_cbacks)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->wma_cbacks.wma_get_connection_info =
+		wma_cbacks->wma_get_connection_info;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_register_cdp_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_cdp_cbacks *cdp_cbacks)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->cdp_cbacks.cdp_update_mac_id =
+		cdp_cbacks->cdp_update_mac_id;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_dp_cbacks *dp_cbacks)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency =
+		dp_cbacks->hdd_disable_rx_ol_in_concurrency;
+	pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb =
+		dp_cbacks->hdd_set_rx_mode_rps_cb;
+	pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb =
+		dp_cbacks->hdd_ipa_set_mcc_mode_cb;
+	pm_ctx->dp_cbacks.hdd_v2_flow_pool_map =
+		dp_cbacks->hdd_v2_flow_pool_map;
+	pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap =
+		dp_cbacks->hdd_v2_flow_pool_unmap;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_tdls_cbacks *tdls_cbacks)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->tdls_cbacks.tdls_notify_increment_session =
+		tdls_cbacks->tdls_notify_increment_session;
+	pm_ctx->tdls_cbacks.tdls_notify_decrement_session =
+		tdls_cbacks->tdls_notify_decrement_session;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc,
+	send_mode_change_event_cb mode_change_cb)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->mode_change_cb = mode_change_cb;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->mode_change_cb = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}

+ 1763 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -0,0 +1,1763 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_policy_mgr_pcl.c
+ *
+ * WLAN Concurrenct Connection Management APIs
+ *
+ */
+
+/* Include files */
+
+#include "wlan_policy_mgr_api.h"
+#include "wlan_policy_mgr_tables_no_dbs_i.h"
+#include "wlan_policy_mgr_i.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_utility.h"
+
+/**
+ * first_connection_pcl_table - table which provides PCL for the
+ * very first connection in the system
+ */
+const enum policy_mgr_pcl_type
+first_connection_pcl_table[PM_MAX_NUM_OF_MODE]
+			[PM_MAX_CONC_PRIORITY_MODE] = {
+	[PM_STA_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_SAP_MODE] = {PM_5G,   PM_5G,   PM_5G  },
+	[PM_P2P_CLIENT_MODE] = {PM_5G,   PM_5G,   PM_5G  },
+	[PM_P2P_GO_MODE] = {PM_5G,   PM_5G,   PM_5G  },
+	[PM_IBSS_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+};
+
+pm_dbs_pcl_second_connection_table_type
+		*second_connection_pcl_dbs_table;
+pm_dbs_pcl_third_connection_table_type
+		*third_connection_pcl_dbs_table;
+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,
+		uint8_t *pcl_ch, uint32_t *len,
+		uint8_t *pcl_weight, uint32_t weight_len,
+		bool all_matching_cxn_to_del)
+{
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	uint8_t num_cxn_del = 0;
+
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	policy_mgr_debug("get pcl for existing conn:%d", mode);
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) {
+		/* Check, store and temp delete the mode's parameter */
+		policy_mgr_store_and_del_conn_info(psoc, mode,
+				all_matching_cxn_to_del, info, &num_cxn_del);
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		/* Get the PCL */
+		status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
+					pcl_weight, weight_len);
+		policy_mgr_debug("Get PCL to FW for mode:%d", mode);
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		/* Restore the connection info */
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc,
+						enum QDF_OPMODE mode,
+						uint8_t session_id)
+{
+	QDF_STATUS qdf_status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	qdf_status = policy_mgr_decr_active_session(psoc, mode, session_id);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		policy_mgr_debug("Invalid active session");
+		return;
+	}
+
+	/*
+	 * After the removal of this connection, we need to check if
+	 * a STA connection still exists. The reason for this is that
+	 * if one or more STA exists, we need to provide the updated
+	 * PCL to the FW for cases like LFR.
+	 *
+	 * Since policy_mgr_get_pcl provides PCL list based on the new
+	 * connection that is going to come up, we will find the
+	 * existing STA entry, save it and delete it temporarily.
+	 * After this we will get PCL as though as new STA connection
+	 * is coming up. This will give the exact PCL that needs to be
+	 * given to the FW. After setting the PCL, we need to restore
+	 * the entry that we have saved before.
+	 */
+	policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE);
+	/* do we need to change the HW mode */
+	policy_mgr_check_n_start_opportunistic_timer(psoc);
+	return;
+}
+
+void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc,
+		struct wlan_objmgr_pdev *pdev,
+		struct regulatory_channel *chan_list,
+		struct avoid_freq_ind_data *avoid_freq_ind,
+		void *arg)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (!avoid_freq_ind) {
+		policy_mgr_debug("avoid_freq_ind NULL");
+		return;
+	}
+
+	/*
+	 * The ch_list buffer can accomadate a maximum of
+	 * NUM_CHANNELS and hence the ch_cnt should also not
+	 * exceed NUM_CHANNELS.
+	 */
+	pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.ch_cnt >=
+			NUM_CHANNELS ?
+			NUM_CHANNELS : avoid_freq_ind->chan_list.ch_cnt;
+	if (pm_ctx->unsafe_channel_count)
+		qdf_mem_copy(pm_ctx->unsafe_channel_list,
+			avoid_freq_ind->chan_list.ch_list,
+			pm_ctx->unsafe_channel_count *
+			sizeof(pm_ctx->unsafe_channel_list[0]));
+	policy_mgr_debug("Channel list update, received %d avoided channels",
+		pm_ctx->unsafe_channel_count);
+}
+
+void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc,
+		uint8_t *pcl_channels, uint32_t *len,
+		uint8_t *weight_list, uint32_t weight_len)
+{
+	uint8_t current_channel_list[QDF_MAX_NUM_CHAN];
+	uint8_t org_weight_list[QDF_MAX_NUM_CHAN];
+	uint8_t is_unsafe = 1;
+	uint8_t i, j;
+	uint32_t safe_channel_count = 0, current_channel_count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (len) {
+		current_channel_count = QDF_MIN(*len, QDF_MAX_NUM_CHAN);
+	} else {
+		policy_mgr_err("invalid number of channel length");
+		return;
+	}
+
+	if (pm_ctx->unsafe_channel_count == 0) {
+		policy_mgr_debug("There are no unsafe channels");
+		return;
+	}
+
+	qdf_mem_copy(current_channel_list, pcl_channels,
+		current_channel_count);
+	qdf_mem_zero(pcl_channels, current_channel_count);
+
+	qdf_mem_copy(org_weight_list, weight_list, QDF_MAX_NUM_CHAN);
+	qdf_mem_zero(weight_list, weight_len);
+
+	for (i = 0; i < current_channel_count; i++) {
+		is_unsafe = 0;
+		for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
+			if (current_channel_list[i] ==
+				pm_ctx->unsafe_channel_list[j]) {
+				/* Found unsafe channel, update it */
+				is_unsafe = 1;
+				policy_mgr_debug("CH %d is not safe",
+					current_channel_list[i]);
+				break;
+			}
+		}
+		if (!is_unsafe) {
+			pcl_channels[safe_channel_count] =
+				current_channel_list[i];
+			if (safe_channel_count < weight_len)
+				weight_list[safe_channel_count] =
+					org_weight_list[i];
+			safe_channel_count++;
+		}
+	}
+	*len = safe_channel_count;
+
+	return;
+}
+
+static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels(
+					struct policy_mgr_psoc_priv_obj *pm_ctx,
+					uint8_t *pcl_list_org,
+					uint8_t *weight_list_org,
+					uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (!wlan_reg_is_passive_or_disable_ch(
+			pm_ctx->pdev, pcl_list_org[i])) {
+			pcl_list_org[pcl_len] = pcl_list_org[i];
+			weight_list_org[pcl_len++] = weight_list_org[i];
+		}
+	}
+	*pcl_len_org = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_modify_pcl_based_on_dnbs(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t *pcl_list_org,
+						uint8_t *weight_list_org,
+						uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+	uint8_t pcl_list[QDF_MAX_NUM_CHAN];
+	uint8_t weight_list[QDF_MAX_NUM_CHAN];
+	bool ok;
+	int ret;
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		ret = policy_mgr_is_chan_ok_for_dnbs(psoc, pcl_list_org[i],
+						&ok);
+
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			policy_mgr_err("Not able to check DNBS eligibility");
+			return ret;
+		}
+		if (ok) {
+			pcl_list[pcl_len] = pcl_list_org[i];
+			weight_list[pcl_len++] = weight_list_org[i];
+		}
+	}
+
+	qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org));
+	qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org));
+	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len);
+	qdf_mem_copy(weight_list_org, weight_list, pcl_len);
+	*pcl_len_org = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc,
+			enum policy_mgr_con_mode mode, uint32_t *vdev_id)
+{
+	uint32_t idx = 0;
+	uint8_t chan;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+
+	if (mode >= PM_MAX_NUM_OF_MODE) {
+		policy_mgr_err("incorrect mode");
+		return 0;
+	}
+
+	for (idx = 0; idx < MAX_NUMBER_OF_CONC_CONNECTIONS; idx++) {
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		if ((pm_conc_connection_list[idx].mode == mode) &&
+				(!vdev_id || (*vdev_id ==
+					pm_conc_connection_list[idx].vdev_id))
+				&& pm_conc_connection_list[idx].in_use) {
+			chan =  pm_conc_connection_list[idx].chan;
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return chan;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	}
+
+	return 0;
+}
+
+static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_nol(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t *pcl_list_org,
+		uint8_t *weight_list_org,
+		uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+	uint8_t pcl_list[QDF_MAX_NUM_CHAN];
+	uint8_t weight_list[QDF_MAX_NUM_CHAN];
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (!wlan_reg_is_disable_ch(pm_ctx->pdev, pcl_list_org[i])) {
+			pcl_list[pcl_len] = pcl_list_org[i];
+			weight_list[pcl_len++] = weight_list_org[i];
+		}
+	}
+
+	qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org));
+	qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org));
+	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len);
+	qdf_mem_copy(weight_list_org, weight_list, pcl_len);
+	*pcl_len_org = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+policy_mgr_modify_sap_pcl_based_on_srd(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *pcl_list_org,
+				       uint8_t *weight_list_org,
+				       uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+	uint8_t pcl_list[QDF_MAX_NUM_CHAN];
+	uint8_t weight_list[QDF_MAX_NUM_CHAN];
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool is_etsi13_srd_chan_allowed_in_mas_mode = true;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	is_etsi13_srd_chan_allowed_in_mas_mode =
+		wlan_reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx->pdev);
+
+	if (is_etsi13_srd_chan_allowed_in_mas_mode)
+		return QDF_STATUS_SUCCESS;
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (wlan_reg_is_etsi13_srd_chan(pm_ctx->pdev,
+						pcl_list_org[i]))
+			continue;
+		pcl_list[pcl_len] = pcl_list_org[i];
+		weight_list[pcl_len++] = weight_list_org[i];
+	}
+
+	qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org));
+	qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org));
+	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len);
+	qdf_mem_copy(weight_list_org, weight_list, pcl_len);
+	*pcl_len_org = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_pcl_modification_for_sap(
+			struct wlan_objmgr_psoc *psoc,
+			uint8_t *pcl_channels, uint8_t *pcl_weight,
+			uint32_t *len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t i;
+
+	if (policy_mgr_is_sap_mandatory_channel_set(psoc)) {
+		status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel(
+				psoc, pcl_channels, pcl_weight, len);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			policy_mgr_err("failed to get modified pcl for SAP");
+			return status;
+		}
+		policy_mgr_debug("modified pcl len:%d", *len);
+		for (i = 0; i < *len; i++)
+			policy_mgr_debug("chan:%d weight:%d",
+				pcl_channels[i], pcl_weight[i]);
+	}
+
+	status = policy_mgr_modify_sap_pcl_based_on_nol(
+			psoc, pcl_channels, pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get modified pcl for SAP");
+		return status;
+	}
+	policy_mgr_debug("modified pcl len:%d", *len);
+	for (i = 0; i < *len; i++)
+		policy_mgr_debug("chan:%d weight:%d",
+			pcl_channels[i], pcl_weight[i]);
+
+	status = policy_mgr_modify_sap_pcl_based_on_srd
+			(psoc, pcl_channels, pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get modified pcl for SAP");
+		return status;
+	}
+	policy_mgr_debug("modified final pcl len:%d", *len);
+	for (i = 0; i < *len; i++)
+		policy_mgr_debug("chan:%d weight:%d",
+				 pcl_channels[i], pcl_weight[i]);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_pcl_modification_for_p2p_go(
+			struct wlan_objmgr_psoc *psoc,
+			uint8_t *pcl_channels, uint8_t *pcl_weight,
+			uint32_t *len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("context is NULL");
+		return status;
+	}
+
+	status = policy_mgr_modify_pcl_based_on_enabled_channels(
+			pm_ctx, pcl_channels, pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get modified pcl for GO");
+		return status;
+	}
+	policy_mgr_debug("modified pcl len:%d", *len);
+	for (i = 0; i < *len; i++)
+		policy_mgr_debug("chan:%d weight:%d",
+			pcl_channels[i], pcl_weight[i]);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl(
+			struct wlan_objmgr_psoc *psoc,
+			uint8_t *pcl_channels, uint8_t *pcl_weight,
+			uint32_t *len, enum policy_mgr_con_mode mode)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	switch (mode) {
+	case PM_SAP_MODE:
+		status = policy_mgr_pcl_modification_for_sap(
+			psoc, pcl_channels, pcl_weight, len);
+		break;
+	case PM_P2P_GO_MODE:
+		status = policy_mgr_pcl_modification_for_p2p_go(
+			psoc, pcl_channels, pcl_weight, len);
+		break;
+	case PM_STA_MODE:
+	case PM_P2P_CLIENT_MODE:
+	case PM_IBSS_MODE:
+		status = QDF_STATUS_SUCCESS;
+		break;
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
+			enum policy_mgr_con_mode mode,
+			uint8_t *pcl_channels, uint32_t *len,
+			uint8_t *pcl_weight, uint32_t weight_len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t num_connections = 0, i;
+	enum policy_mgr_conc_priority_mode first_index = 0;
+	enum policy_mgr_one_connection_mode second_index = 0;
+	enum policy_mgr_two_connection_mode third_index = 0;
+	enum policy_mgr_pcl_type pcl = PM_NONE;
+	enum policy_mgr_conc_priority_mode conc_system_pref = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum QDF_OPMODE qdf_mode;
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("context is NULL");
+		return status;
+	}
+
+	if ((mode < 0) || (mode >= PM_MAX_NUM_OF_MODE)) {
+		policy_mgr_err("Invalid connection mode %d received", mode);
+		return status;
+	}
+
+	/* find the current connection state from pm_conc_connection_list*/
+	num_connections = policy_mgr_get_connection_count(psoc);
+	policy_mgr_debug("connections:%d pref:%d requested mode:%d",
+		num_connections, pm_ctx->cur_conc_system_pref, mode);
+
+	switch (pm_ctx->cur_conc_system_pref) {
+	case 0:
+		conc_system_pref = PM_THROUGHPUT;
+		break;
+	case 1:
+		conc_system_pref = PM_POWERSAVE;
+		break;
+	case 2:
+		conc_system_pref = PM_LATENCY;
+		break;
+	default:
+		policy_mgr_err("unknown cur_conc_system_pref value %d",
+			pm_ctx->cur_conc_system_pref);
+		break;
+	}
+
+	switch (num_connections) {
+	case 0:
+		first_index =
+			policy_mgr_get_first_connection_pcl_table_index(psoc);
+		pcl = first_connection_pcl_table[mode][first_index];
+		break;
+	case 1:
+		second_index =
+			policy_mgr_get_second_connection_pcl_table_index(psoc);
+		if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
+			policy_mgr_err("couldn't find index for 2nd connection pcl table");
+			return status;
+		}
+		qdf_mode = policy_mgr_get_qdf_mode_from_pm(mode);
+		if (qdf_mode == QDF_MAX_NO_OF_MODE)
+			return status;
+
+		if (policy_mgr_is_hw_dbs_capable(psoc) == true &&
+		    policy_mgr_is_dbs_allowed_for_concurrency(
+							psoc, qdf_mode)) {
+			pcl = (*second_connection_pcl_dbs_table)
+				[second_index][mode][conc_system_pref];
+		} else {
+			pcl = second_connection_pcl_nodbs_table
+				[second_index][mode][conc_system_pref];
+		}
+
+		break;
+	case 2:
+		third_index =
+			policy_mgr_get_third_connection_pcl_table_index(psoc);
+		if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
+			policy_mgr_err(
+				"couldn't find index for 3rd connection pcl table");
+			return status;
+		}
+		if (policy_mgr_is_hw_dbs_capable(psoc) == true) {
+			pcl = (*third_connection_pcl_dbs_table)
+				[third_index][mode][conc_system_pref];
+		} else {
+			pcl = third_connection_pcl_nodbs_table
+				[third_index][mode][conc_system_pref];
+		}
+		break;
+	default:
+		policy_mgr_err("unexpected num_connections value %d",
+			num_connections);
+		break;
+	}
+
+	policy_mgr_debug("index1:%d index2:%d index3:%d pcl:%d dbs:%d",
+		first_index, second_index, third_index,
+		pcl, policy_mgr_is_hw_dbs_capable(psoc));
+
+	/* once the PCL enum is obtained find out the exact channel list with
+	 * help from sme_get_cfg_valid_channels
+	 */
+	status = policy_mgr_get_channel_list(psoc, pcl, pcl_channels, len, mode,
+					pcl_weight, weight_len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get channel list:%d", status);
+		return status;
+	}
+
+	policy_mgr_debug("pcl len:%d", *len);
+	for (i = 0; i < *len; i++) {
+		policy_mgr_debug("chan:%d weight:%d",
+				pcl_channels[i], pcl_weight[i]);
+	}
+
+	policy_mgr_mode_specific_modification_on_pcl(
+		psoc, pcl_channels, pcl_weight, len, mode);
+
+	status = policy_mgr_modify_pcl_based_on_dnbs(psoc, pcl_channels,
+						pcl_weight, len);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get modified pcl based on DNBS");
+		return status;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+enum policy_mgr_conc_priority_mode
+		policy_mgr_get_first_connection_pcl_table_index(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("context is NULL");
+		return PM_THROUGHPUT;
+	}
+
+	if (pm_ctx->cur_conc_system_pref >= PM_MAX_CONC_PRIORITY_MODE)
+		return PM_THROUGHPUT;
+
+	return pm_ctx->cur_conc_system_pref;
+}
+
+enum policy_mgr_one_connection_mode
+		policy_mgr_get_second_connection_pcl_table_index(
+		struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_one_connection_mode index = PM_MAX_ONE_CONNECTION_MODE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return index;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (PM_STA_MODE == pm_conc_connection_list[0].mode) {
+		if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_24_1x1;
+			else
+				index = PM_STA_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_5_1x1;
+			else
+				index = PM_STA_5_2x2;
+		}
+	} else if (PM_SAP_MODE == pm_conc_connection_list[0].mode) {
+		if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_24_1x1;
+			else
+				index = PM_SAP_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_5_1x1;
+			else
+				index = PM_SAP_5_2x2;
+		}
+	} else if (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) {
+		if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_24_1x1;
+			else
+				index = PM_P2P_CLI_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_5_1x1;
+			else
+				index = PM_P2P_CLI_5_2x2;
+		}
+	} else if (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) {
+		if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_24_1x1;
+			else
+				index = PM_P2P_GO_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_5_1x1;
+			else
+				index = PM_P2P_GO_5_2x2;
+		}
+	} else if (PM_IBSS_MODE == pm_conc_connection_list[0].mode) {
+		if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_IBSS_24_1x1;
+			else
+				index = PM_IBSS_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_IBSS_5_1x1;
+			else
+				index = PM_IBSS_5_2x2;
+		}
+	}
+
+	policy_mgr_debug("mode:%d chan:%d chain:%d index:%d",
+		pm_conc_connection_list[0].mode,
+		pm_conc_connection_list[0].chan,
+		pm_conc_connection_list[0].chain_mask, index);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index_cli_sap(void)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].chan ==
+		pm_conc_connection_list[1].chan) {
+		if (WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_SAP_SCC_24_1x1;
+			else
+				index = PM_P2P_CLI_SAP_SCC_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_SAP_SCC_5_1x1;
+			else
+				index = PM_P2P_CLI_SAP_SCC_5_2x2;
+		}
+	/* MCC */
+	} else if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if ((WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_SAP_MCC_24_1x1;
+			else
+				index = PM_P2P_CLI_SAP_MCC_24_2x2;
+		} else if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_SAP_MCC_5_1x1;
+			else
+				index = PM_P2P_CLI_SAP_MCC_5_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_SAP_MCC_24_5_1x1;
+			else
+				index = PM_P2P_CLI_SAP_MCC_24_5_2x2;
+		}
+	/* SBS or DBS */
+	} else if (pm_conc_connection_list[0].mac !=
+			pm_conc_connection_list[1].mac) {
+		/* SBS */
+		if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) &&
+		    (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_SAP_SBS_5_1x1;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_SAP_DBS_1x1;
+			else
+				index = PM_P2P_CLI_SAP_DBS_2x2;
+		}
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index_sta_sap(void)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].chan ==
+		pm_conc_connection_list[1].chan) {
+		if (WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_SAP_SCC_24_1x1;
+			else
+				index = PM_STA_SAP_SCC_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_SAP_SCC_5_1x1;
+			else
+				index = PM_STA_SAP_SCC_5_2x2;
+		}
+	/* MCC */
+	} else if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if ((WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_SAP_MCC_24_1x1;
+			else
+				index = PM_STA_SAP_MCC_24_2x2;
+		} else if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_SAP_MCC_5_1x1;
+			else
+				index = PM_STA_SAP_MCC_5_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_SAP_MCC_24_5_1x1;
+			else
+				index = PM_STA_SAP_MCC_24_5_2x2;
+		}
+	/* SBS or DBS */
+	} else if (pm_conc_connection_list[0].mac !=
+			pm_conc_connection_list[1].mac) {
+		/* SBS */
+		if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) &&
+		    (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_SAP_SBS_5_1x1;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_SAP_DBS_1x1;
+			else
+				index = PM_STA_SAP_DBS_2x2;
+		}
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index_sap_sap(void)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].chan ==
+		pm_conc_connection_list[1].chan) {
+		if (WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_SAP_SCC_24_1x1;
+			else
+				index = PM_SAP_SAP_SCC_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_SAP_SCC_5_1x1;
+			else
+				index = PM_SAP_SAP_SCC_5_2x2;
+		}
+	/* MCC */
+	} else if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if ((WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_SAP_MCC_24_1x1;
+			else
+				index = PM_SAP_SAP_MCC_24_2x2;
+		} else if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_SAP_MCC_5_1x1;
+			else
+				index = PM_SAP_SAP_MCC_5_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_SAP_MCC_24_5_1x1;
+			else
+				index = PM_SAP_SAP_MCC_24_5_2x2;
+		}
+	/* SBS or DBS */
+	} else if (pm_conc_connection_list[0].mac !=
+			pm_conc_connection_list[1].mac) {
+		/* SBS */
+		if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) &&
+		    (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_SAP_SBS_5_1x1;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_SAP_SAP_DBS_1x1;
+			else
+				index = PM_SAP_SAP_DBS_2x2;
+		}
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index_sta_go(void)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].chan ==
+		pm_conc_connection_list[1].chan) {
+		if (WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_GO_SCC_24_1x1;
+			else
+				index = PM_STA_P2P_GO_SCC_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_GO_SCC_5_1x1;
+			else
+				index = PM_STA_P2P_GO_SCC_5_2x2;
+		}
+	/* MCC */
+	} else if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if ((WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_GO_MCC_24_1x1;
+			else
+				index = PM_STA_P2P_GO_MCC_24_2x2;
+		} else if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_GO_MCC_5_1x1;
+			else
+				index = PM_STA_P2P_GO_MCC_5_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_GO_MCC_24_5_1x1;
+			else
+				index = PM_STA_P2P_GO_MCC_24_5_2x2;
+		}
+	/* SBS or DBS */
+	} else if (pm_conc_connection_list[0].mac !=
+			pm_conc_connection_list[1].mac) {
+		/* SBS */
+		if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) &&
+		    (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_GO_SBS_5_1x1;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_GO_DBS_1x1;
+			else
+				index = PM_STA_P2P_GO_DBS_2x2;
+		}
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index_sta_cli(void)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].chan ==
+		pm_conc_connection_list[1].chan) {
+		if (WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_CLI_SCC_24_1x1;
+			else
+				index = PM_STA_P2P_CLI_SCC_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_CLI_SCC_5_1x1;
+			else
+				index = PM_STA_P2P_CLI_SCC_5_2x2;
+		}
+	/* MCC */
+	} else if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if ((WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_CLI_MCC_24_1x1;
+			else
+				index = PM_STA_P2P_CLI_MCC_24_2x2;
+		} else if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_CLI_MCC_5_1x1;
+			else
+				index = PM_STA_P2P_CLI_MCC_5_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_CLI_MCC_24_5_1x1;
+			else
+				index = PM_STA_P2P_CLI_MCC_24_5_2x2;
+		}
+	/* SBS or DBS */
+	} else if (pm_conc_connection_list[0].mac !=
+			pm_conc_connection_list[1].mac) {
+		/* SBS */
+		if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) &&
+		    (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_CLI_SBS_5_1x1;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_P2P_CLI_DBS_1x1;
+			else
+				index = PM_STA_P2P_CLI_DBS_2x2;
+		}
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index_go_cli(void)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].chan ==
+		pm_conc_connection_list[1].chan) {
+		if (WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_P2P_CLI_SCC_24_1x1;
+			else
+				index = PM_P2P_GO_P2P_CLI_SCC_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_P2P_CLI_SCC_5_1x1;
+			else
+				index = PM_P2P_GO_P2P_CLI_SCC_5_2x2;
+		}
+	/* MCC */
+	} else if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if ((WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_P2P_CLI_MCC_24_1x1;
+			else
+				index = PM_P2P_GO_P2P_CLI_MCC_24_2x2;
+		} else if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_P2P_CLI_MCC_5_1x1;
+			else
+				index = PM_P2P_GO_P2P_CLI_MCC_5_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_P2P_CLI_MCC_24_5_1x1;
+			else
+				index = PM_P2P_GO_P2P_CLI_MCC_24_5_2x2;
+		}
+	/* SBS or DBS */
+	} else if (pm_conc_connection_list[0].mac !=
+			pm_conc_connection_list[1].mac) {
+		/* SBS */
+		if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) &&
+		    (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_P2P_CLI_SBS_5_1x1;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_P2P_CLI_DBS_1x1;
+			else
+				index = PM_P2P_GO_P2P_CLI_DBS_2x2;
+		}
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index_go_sap(void)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].chan ==
+		pm_conc_connection_list[1].chan) {
+		if (WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_SAP_SCC_24_1x1;
+			else
+				index = PM_P2P_GO_SAP_SCC_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_SAP_SCC_5_1x1;
+			else
+				index = PM_P2P_GO_SAP_SCC_5_2x2;
+		}
+	/* MCC */
+	} else if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if ((WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_SAP_MCC_24_1x1;
+			else
+				index = PM_P2P_GO_SAP_MCC_24_2x2;
+		} else if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_SAP_MCC_5_1x1;
+			else
+				index = PM_P2P_GO_SAP_MCC_5_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_SAP_MCC_24_5_1x1;
+			else
+				index = PM_P2P_GO_SAP_MCC_24_5_2x2;
+		}
+	/* SBS or DBS */
+	} else if (pm_conc_connection_list[0].mac !=
+			pm_conc_connection_list[1].mac) {
+		/* SBS */
+		if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) &&
+		    (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_SAP_SBS_5_1x1;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_SAP_DBS_1x1;
+			else
+				index = PM_P2P_GO_SAP_DBS_2x2;
+		}
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index_sta_sta(void)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].chan ==
+		pm_conc_connection_list[1].chan) {
+		if (WLAN_REG_IS_24GHZ_CH
+			(pm_conc_connection_list[0].chan)) {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_STA_SCC_24_1x1;
+			else
+				index = PM_STA_STA_SCC_24_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+			pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_STA_SCC_5_1x1;
+			else
+				index = PM_STA_STA_SCC_5_2x2;
+		}
+	/* MCC */
+	} else if (pm_conc_connection_list[0].mac ==
+		pm_conc_connection_list[1].mac) {
+		if ((WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_24GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_STA_MCC_24_1x1;
+			else
+				index = PM_STA_STA_MCC_24_2x2;
+		} else if ((WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[0].chan)) &&
+			(WLAN_REG_IS_5GHZ_CH(
+			pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_STA_MCC_5_1x1;
+			else
+				index = PM_STA_STA_MCC_5_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_STA_MCC_24_5_1x1;
+			else
+				index = PM_STA_STA_MCC_24_5_2x2;
+		}
+	/* SBS or DBS */
+	} else if (pm_conc_connection_list[0].mac !=
+			pm_conc_connection_list[1].mac) {
+		/* SBS */
+		if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) &&
+		    (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_STA_SBS_5_1x1;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_STA_DBS_1x1;
+			else
+				index = PM_STA_STA_DBS_2x2;
+		}
+	}
+	return index;
+}
+
+enum policy_mgr_two_connection_mode
+		policy_mgr_get_third_connection_pcl_table_index(
+		struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return index;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_SAP_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_cli_sap();
+	else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_SAP_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_STA_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_sta_sap();
+	else if ((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_SAP_MODE == pm_conc_connection_list[1].mode))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_sap_sap();
+	else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_STA_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_sta_go();
+	else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_STA_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_sta_cli();
+	else if (((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_go_cli();
+	else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_SAP_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_go_sap();
+	else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_STA_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_STA_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_sta_sta();
+
+	policy_mgr_debug("mode0:%d mode1:%d chan0:%d chan1:%d chain:%d index:%d",
+		pm_conc_connection_list[0].mode,
+		pm_conc_connection_list[1].mode,
+		pm_conc_connection_list[0].chan,
+		pm_conc_connection_list[1].chan,
+		pm_conc_connection_list[0].chain_mask, index);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return index;
+}
+
+uint8_t
+policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode,
+		bool for_existing_conn)
+{
+	uint8_t pcl_channels[QDF_MAX_NUM_CHAN];
+	uint8_t pcl_weight[QDF_MAX_NUM_CHAN];
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	/*
+	 * in worst case if we can't find any channel at all
+	 * then return 2.4G channel, so atleast we won't fall
+	 * under 5G MCC scenario
+	 */
+	uint8_t channel = PM_24_GHZ_CHANNEL_6;
+	uint32_t i, pcl_len = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return channel;
+	}
+
+	if (true == for_existing_conn) {
+		/*
+		 * First try to see if there is any non-dfs channel already
+		 * present in current connection table. If yes then return
+		 * that channel
+		 */
+		if (true == policy_mgr_is_any_nondfs_chnl_present(
+			psoc, &channel))
+			return channel;
+
+		if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl_for_existing_conn(
+					psoc, mode,
+					&pcl_channels[0], &pcl_len,
+					pcl_weight, QDF_ARRAY_SIZE(pcl_weight),
+					false))
+			return channel;
+	} else {
+		if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl(psoc, mode,
+					&pcl_channels[0], &pcl_len,
+					pcl_weight, QDF_ARRAY_SIZE(pcl_weight)))
+			return channel;
+	}
+
+	for (i = 0; i < pcl_len; i++) {
+		if (wlan_reg_is_dfs_ch(pm_ctx->pdev, pcl_channels[i])) {
+			continue;
+		} else {
+			channel = pcl_channels[i];
+			break;
+		}
+	}
+
+	return channel;
+}
+
+static void policy_mgr_remove_dsrc_channels(uint8_t *chan_list,
+					    uint32_t *num_channels,
+					    struct wlan_objmgr_pdev *pdev)
+{
+	uint32_t num_chan_temp = 0;
+	int i;
+
+	for (i = 0; i < *num_channels; i++) {
+		if (!wlan_reg_is_dsrc_chan(pdev, chan_list[i])) {
+			chan_list[num_chan_temp] = chan_list[i];
+			num_chan_temp++;
+		}
+	}
+
+	*num_channels = num_chan_temp;
+}
+
+QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc,
+				uint8_t *chan_list, uint32_t *list_len)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	*list_len = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!pm_ctx->sme_cbacks.sme_get_valid_channels) {
+		policy_mgr_err("sme_get_valid_chans callback is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*list_len = QDF_MAX_NUM_CHAN;
+	status = pm_ctx->sme_cbacks.sme_get_valid_channels(
+					chan_list, list_len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Error in getting valid channels");
+		*list_len = 0;
+		return status;
+	}
+
+	policy_mgr_remove_dsrc_channels(chan_list, list_len, pm_ctx->pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_list_has_24GHz_channel(uint8_t *channel_list,
+					uint32_t list_len)
+{
+	uint32_t i;
+
+	for (i = 0; i < list_len; i++) {
+		if (WLAN_REG_IS_24GHZ_CH(channel_list[i]))
+			return true;
+	}
+
+	return false;
+}
+
+QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc,
+					uint8_t *channels, uint32_t len)
+{
+	uint32_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!len) {
+		policy_mgr_err("No mandatory freq/chan configured");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!policy_mgr_list_has_24GHz_channel(channels, len)) {
+		policy_mgr_err("2.4GHz channels missing, this is not expected");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_debug("mandatory chan length:%d",
+			pm_ctx->sap_mandatory_channels_len);
+
+	for (i = 0; i < len; i++) {
+		pm_ctx->sap_mandatory_channels[i] = channels[i];
+		policy_mgr_debug("chan:%d", pm_ctx->sap_mandatory_channels[i]);
+	}
+
+	pm_ctx->sap_mandatory_channels_len = len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	if (pm_ctx->sap_mandatory_channels_len)
+		return true;
+	else
+		return false;
+}
+
+QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t *pcl_list_org,
+		uint8_t *weight_list_org,
+		uint32_t *pcl_len_org)
+{
+	uint32_t i, j, pcl_len = 0;
+	bool found;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!pm_ctx->sap_mandatory_channels_len)
+		return QDF_STATUS_SUCCESS;
+
+	if (!policy_mgr_list_has_24GHz_channel(pm_ctx->sap_mandatory_channels,
+			pm_ctx->sap_mandatory_channels_len)) {
+		policy_mgr_err("fav channel list is missing 2.4GHz channels");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++)
+		policy_mgr_debug("fav chan:%d",
+			pm_ctx->sap_mandatory_channels[i]);
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		found = false;
+		if (i >= QDF_MAX_NUM_CHAN) {
+			policy_mgr_debug("index is exceeding QDF_MAX_NUM_CHAN");
+			break;
+		}
+		for (j = 0; j < pm_ctx->sap_mandatory_channels_len; j++) {
+			if (pcl_list_org[i] ==
+			    pm_ctx->sap_mandatory_channels[j]) {
+				found = true;
+				break;
+			}
+		}
+		if (found && (pcl_len < QDF_MAX_NUM_CHAN)) {
+			pcl_list_org[pcl_len] = pcl_list_org[i];
+			weight_list_org[pcl_len++] = weight_list_org[i];
+		}
+	}
+	*pcl_len_org = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
+		uint32_t *chan)
+{
+	QDF_STATUS status;
+	struct policy_mgr_pcl_list pcl;
+
+	qdf_mem_zero(&pcl, sizeof(pcl));
+
+	status = policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE,
+			pcl.pcl_list, &pcl.pcl_len,
+			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
+			false);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Unable to get PCL for SAP");
+		return status;
+	}
+
+	/*
+	 * Get inside below loop if no existing SAP connection and hence a new
+	 * SAP connection might be coming up. pcl.pcl_len can be 0 if no common
+	 * channel between PCL & mandatory channel list as well
+	 */
+	if (!pcl.pcl_len && !policy_mgr_mode_specific_connection_count(psoc,
+		PM_SAP_MODE, NULL)) {
+		policy_mgr_debug("policy_mgr_get_pcl_for_existing_conn returned no pcl");
+		status = policy_mgr_get_pcl(psoc, PM_SAP_MODE,
+				pcl.pcl_list, &pcl.pcl_len,
+				pcl.weight_list,
+				QDF_ARRAY_SIZE(pcl.weight_list));
+		if (QDF_IS_STATUS_ERROR(status)) {
+			policy_mgr_err("Unable to get PCL for SAP: policy_mgr_get_pcl");
+			return status;
+		}
+	}
+
+	status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel(
+							psoc, pcl.pcl_list,
+							pcl.weight_list,
+							&pcl.pcl_len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Unable to modify SAP PCL");
+		return status;
+	}
+
+	if (!pcl.pcl_len) {
+		policy_mgr_err("No common channel between mandatory list & PCL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*chan = pcl.pcl_list[0];
+	policy_mgr_debug("mandatory channel:%d", *chan);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_pcl_chan_weights *weight)
+{
+	uint32_t i, j;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	uint8_t num_cxn_del = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_set(weight->weighed_valid_list, QDF_MAX_NUM_CHAN,
+		    WEIGHT_OF_DISALLOWED_CHANNELS);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (policy_mgr_mode_specific_connection_count(
+		psoc, PM_STA_MODE, NULL) > 0) {
+		/*
+		 * Store the STA mode's parameter and temporarily delete it
+		 * from the concurrency table. This way the allow concurrency
+		 * check can be used as though a new connection is coming up,
+		 * allowing to detect the disallowed channels.
+		 */
+		policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, false,
+						info, &num_cxn_del);
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		/*
+		 * There is a small window between releasing the above lock
+		 * and acquiring the same in policy_mgr_allow_concurrency,
+		 * below!
+		 */
+		for (i = 0; i < weight->saved_num_chan; i++) {
+			if (policy_mgr_is_concurrency_allowed
+				(psoc, PM_STA_MODE, weight->saved_chan_list[i],
+				HW_MODE_20_MHZ)) {
+				weight->weighed_valid_list[i] =
+					WEIGHT_OF_NON_PCL_CHANNELS;
+			}
+		}
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		/* Restore the connection info */
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	for (i = 0; i < weight->saved_num_chan; i++) {
+		for (j = 0; j < weight->pcl_len; j++) {
+			if (weight->saved_chan_list[i] == weight->pcl_list[j]) {
+				weight->weighed_valid_list[i] =
+					weight->weight_list[j];
+				break;
+			}
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint8_t policy_mgr_mode_specific_get_channel(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
+{
+	uint32_t conn_index;
+	uint8_t channel = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return channel;
+	}
+	/* provides the channel for the first matching mode type */
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		conn_index++) {
+		if ((pm_conc_connection_list[conn_index].mode == mode) &&
+			pm_conc_connection_list[conn_index].in_use) {
+			channel = pm_conc_connection_list[conn_index].chan;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return channel;
+}
+
+uint8_t policy_mgr_get_alternate_channel_for_sap(
+	struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t pcl_channels[QDF_MAX_NUM_CHAN];
+	uint8_t pcl_weight[QDF_MAX_NUM_CHAN];
+	uint8_t channel = 0;
+	uint32_t pcl_len = 0;
+
+	if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(psoc, PM_SAP_MODE,
+		&pcl_channels[0], &pcl_len,
+		pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) {
+		channel = pcl_channels[0];
+	}
+
+	return channel;
+}

+ 1173 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h

@@ -0,0 +1,1173 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WLAN_POLICY_MGR_TABLES_1X1_DBS_H
+#define __WLAN_POLICY_MGR_TABLES_1X1_DBS_H
+
+#include "wlan_policy_mgr_api.h"
+
+/**
+ * second_connection_pcl_dbs_1x1_table - table which provides PCL
+ * for the 2nd connection, when we have a connection already in
+ * the system (with DBS supported by HW)
+ */
+pm_dbs_pcl_second_connection_table_type
+pm_second_connection_pcl_dbs_1x1_table = {
+	[PM_STA_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {PM_5G,        PM_5G,        PM_5G       } },
+
+	[PM_STA_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {PM_5G,        PM_5G,        PM_5G       } },
+
+	[PM_STA_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_IBSS_MODE] = {PM_24G,        PM_24G,        PM_24G       } },
+
+	[PM_STA_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_IBSS_MODE] = {PM_24G,        PM_24G,        PM_24G       } },
+
+	[PM_P2P_CLI_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH, PM_24G_SCC_CH, PM_24G_SCC_CH},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH, PM_24G_SCC_CH, PM_24G_SCC_CH},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] =	{
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+};
+
+/**
+ * third_connection_pcl_dbs_table - table which provides PCL for
+ * the 3rd connection, when we have two connections already in
+ * the system (with DBS supported by HW)
+ */
+static pm_dbs_pcl_third_connection_table_type
+pm_third_connection_pcl_dbs_1x1_table = {
+	[PM_STA_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G},
+	[PM_SAP_MODE] = {PM_24G,        PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G},
+	[PM_SAP_MODE] = {PM_24G,        PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_24G,        PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_24G,        PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+};
+
+/**
+ * next_action_two_connection_table - table which provides next
+ * action while a new connection is coming up, with one
+ * connection already in the system
+ */
+static policy_mgr_next_action_two_connection_table_type
+	pm_next_action_two_connection_dbs_1x1_table = {
+	[PM_STA_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_STA_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_STA_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_STA_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_P2P_CLI_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_P2P_CLI_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_P2P_CLI_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_P2P_CLI_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_P2P_GO_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_P2P_GO_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_P2P_GO_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_P2P_GO_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_SAP_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_SAP_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_SAP_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_SAP_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_IBSS_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_IBSS_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_IBSS_5_1x1] = {PM_DBS,            PM_NOP},
+	[PM_IBSS_5_2x2] = {PM_DBS_DOWNGRADE,  PM_NOP},
+};
+
+/**
+ * next_action_three_connection_table - table which provides next
+ * action while a new connection is coming up, with two
+ * connections already in the system
+ */
+static policy_mgr_next_action_three_connection_table_type
+	pm_next_action_three_connection_dbs_1x1_table = {
+	[PM_STA_SAP_SCC_24_1x1] = {PM_NOP,		PM_DBS},
+	[PM_STA_SAP_SCC_24_2x2] = {PM_NOP,            PM_DBS_DOWNGRADE},
+	[PM_STA_SAP_MCC_24_1x1] = {PM_NOP,            PM_DBS},
+	[PM_STA_SAP_MCC_24_2x2] = {PM_NOP,            PM_DBS_DOWNGRADE},
+	[PM_STA_SAP_SCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_STA_SAP_SCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_STA_SAP_MCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_STA_SAP_MCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_STA_SAP_MCC_24_5_1x1] = {PM_DBS,          PM_DBS},
+	[PM_STA_SAP_MCC_24_5_2x2] = {PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE},
+	[PM_STA_SAP_DBS_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_GO_SCC_24_1x1] = {PM_NOP,         PM_DBS},
+	[PM_STA_P2P_GO_SCC_24_2x2] = {PM_NOP,         PM_DBS_DOWNGRADE},
+	[PM_STA_P2P_GO_MCC_24_1x1] = {PM_NOP,         PM_DBS},
+	[PM_STA_P2P_GO_MCC_24_2x2] = {PM_NOP,         PM_DBS_DOWNGRADE},
+	[PM_STA_P2P_GO_SCC_5_1x1] = {PM_DBS,          PM_NOP},
+	[PM_STA_P2P_GO_SCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP},
+	[PM_STA_P2P_GO_MCC_5_1x1] = {PM_DBS,          PM_NOP},
+	[PM_STA_P2P_GO_MCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP},
+	[PM_STA_P2P_GO_MCC_24_5_1x1] = {PM_DBS,       PM_DBS},
+	[PM_STA_P2P_GO_MCC_24_5_2x2] = {
+			PM_DBS_DOWNGRADE,   PM_DBS_DOWNGRADE},
+	[PM_STA_P2P_GO_DBS_1x1] = {PM_NOP,             PM_NOP},
+	[PM_STA_P2P_CLI_SCC_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_STA_P2P_CLI_SCC_24_2x2] = {
+			PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_STA_P2P_CLI_MCC_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_STA_P2P_CLI_MCC_24_2x2] = {
+			PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_STA_P2P_CLI_SCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_STA_P2P_CLI_SCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_STA_P2P_CLI_MCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_STA_P2P_CLI_MCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_STA_P2P_CLI_MCC_24_5_1x1] = {PM_DBS,             PM_DBS},
+	[PM_STA_P2P_CLI_MCC_24_5_2x2] = {
+			PM_DBS_DOWNGRADE,   PM_DBS_DOWNGRADE},
+	[PM_STA_P2P_CLI_DBS_1x1] = {PM_NOP,             PM_NOP},
+	[PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {
+			PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {
+			PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {PM_DBS,             PM_DBS},
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {
+			PM_DBS_DOWNGRADE,   PM_DBS_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_DBS_1x1] = {PM_NOP,             PM_NOP},
+	[PM_P2P_GO_SAP_SCC_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_P2P_GO_SAP_SCC_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_P2P_GO_SAP_MCC_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_P2P_GO_SAP_MCC_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_P2P_GO_SAP_SCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_P2P_GO_SAP_SCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_P2P_GO_SAP_MCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_P2P_GO_SAP_MCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_P2P_GO_SAP_MCC_24_5_1x1] = {PM_DBS,             PM_DBS},
+	[PM_P2P_GO_SAP_MCC_24_5_2x2] = {
+			PM_DBS_DOWNGRADE,   PM_DBS_DOWNGRADE},
+	[PM_P2P_GO_SAP_DBS_1x1] = {PM_NOP,             PM_NOP},
+	[PM_P2P_CLI_SAP_SCC_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_P2P_CLI_SAP_SCC_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_P2P_CLI_SAP_MCC_24_1x1] = {PM_NOP,             PM_DBS},
+	[PM_P2P_CLI_SAP_MCC_24_2x2] = {PM_NOP,             PM_DBS_DOWNGRADE},
+	[PM_P2P_CLI_SAP_SCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_P2P_CLI_SAP_SCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_5_1x1] = {PM_DBS,             PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_5_2x2] = {PM_DBS_DOWNGRADE,   PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_24_5_1x1] = {PM_DBS,             PM_DBS},
+	[PM_P2P_CLI_SAP_MCC_24_5_2x2] = {PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE},
+	[PM_P2P_CLI_SAP_DBS_1x1] = {PM_NOP,             PM_NOP},
+
+	[PM_SAP_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS},
+	[PM_SAP_SAP_SCC_5_1x1] = {PM_DBS, PM_NOP},
+
+};
+
+#endif

+ 154 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h

@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WLAN_POLICY_MGR_TABLES_2X2_2G_1X1_5G_DBS_H
+#define __WLAN_POLICY_MGR_TABLES_2X2_2G_1X1_5G_DBS_H
+
+#include "wlan_policy_mgr_api.h"
+
+/**
+ * next_action_two_connection_table - table which provides next
+ * action while a new connection is coming up, with one
+ * connection already in the system
+ */
+static policy_mgr_next_action_two_connection_table_type
+	pm_next_action_two_connection_dbs_2x2_2g_1x1_5g_table = {
+	[PM_STA_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_STA_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_STA_5_2x2] = {PM_DBS2, PM_NOP},
+	[PM_P2P_CLI_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_P2P_CLI_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_P2P_CLI_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_P2P_CLI_5_2x2] = {PM_DBS2, PM_NOP},
+	[PM_P2P_GO_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_P2P_GO_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_SAP_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_SAP_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_SAP_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_SAP_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_IBSS_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_IBSS_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_IBSS_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_IBSS_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+};
+
+/**
+ * next_action_three_connection_table - table which provides next
+ * action while a new connection is coming up, with two
+ * connections already in the system
+ */
+static policy_mgr_next_action_three_connection_table_type
+	pm_next_action_three_connection_dbs_2x2_2g_1x1_5g_table = {
+	[PM_STA_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_STA_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_STA_SAP_SCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_STA_SAP_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_STA_SAP_MCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_STA_SAP_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_STA_SAP_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_STA_SAP_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_STA_SAP_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_STA_SAP_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+
+	[PM_STA_P2P_GO_SCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_GO_SCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_GO_MCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_GO_MCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_GO_SCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_STA_P2P_GO_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_STA_P2P_GO_MCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_STA_P2P_GO_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_STA_P2P_GO_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_STA_P2P_GO_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_STA_P2P_GO_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_STA_P2P_GO_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+
+	[PM_STA_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_CLI_SCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_STA_P2P_CLI_SCC_5_2x2] = {PM_DBS2, PM_NOP},
+	[PM_STA_P2P_CLI_MCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_STA_P2P_CLI_MCC_5_2x2] = {PM_DBS2, PM_NOP},
+	[PM_STA_P2P_CLI_MCC_24_5_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_CLI_MCC_24_5_2x2] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_CLI_DBS_1x1] = {PM_NOP, PM_DBS2},
+	[PM_STA_P2P_CLI_DBS_2x2] = {PM_NOP, PM_DBS2},
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE,
+					    PM_DBS2_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE,
+					    PM_DBS2_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+
+	[PM_P2P_GO_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_P2P_GO_SAP_SCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_P2P_GO_SAP_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_P2P_GO_SAP_MCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_P2P_GO_SAP_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_P2P_GO_SAP_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_P2P_GO_SAP_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_P2P_GO_SAP_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_P2P_GO_SAP_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+
+	[PM_P2P_CLI_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_P2P_CLI_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_P2P_CLI_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_P2P_CLI_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_P2P_CLI_SAP_SCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_P2P_CLI_SAP_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_P2P_CLI_SAP_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_P2P_CLI_SAP_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_P2P_CLI_SAP_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+
+	[PM_SAP_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_SAP_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_SAP_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS2},
+	[PM_SAP_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS2},
+	[PM_SAP_SAP_SCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_SAP_SAP_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_SAP_SAP_MCC_5_1x1] = {PM_DBS2, PM_NOP},
+	[PM_SAP_SAP_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP},
+	[PM_SAP_SAP_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_SAP_SAP_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_SAP_SAP_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+	[PM_SAP_SAP_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE},
+};
+
+#endif

+ 154 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h

@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WLAN_POLICY_MGR_TABLES_2X2_5G_1X1_2G_DBS_H
+#define __WLAN_POLICY_MGR_TABLES_2X2_5G_1X1_2G_DBS_H
+
+#include "wlan_policy_mgr_api.h"
+
+/**
+ * next_action_two_connection_table - table which provides next
+ * action while a new connection is coming up, with one
+ * connection already in the system
+ */
+static policy_mgr_next_action_two_connection_table_type
+	pm_next_action_two_connection_dbs_2x2_5g_1x1_2g_table = {
+	[PM_STA_24_1x1] = {PM_NOP,		PM_DBS1},
+	[PM_STA_24_2x2] = {PM_NOP,		PM_DBS1},
+	[PM_STA_5_1x1] = {PM_DBS1,		PM_NOP},
+	[PM_STA_5_2x2] = {PM_DBS1,		PM_NOP},
+	[PM_P2P_CLI_24_1x1] = {PM_NOP,	        PM_DBS1},
+	[PM_P2P_CLI_24_2x2] = {PM_NOP,	        PM_DBS1},
+	[PM_P2P_CLI_5_1x1] = {PM_DBS1,		PM_NOP},
+	[PM_P2P_CLI_5_2x2] = {PM_DBS1,		PM_NOP},
+	[PM_P2P_GO_24_1x1] = {PM_NOP,		PM_DBS1},
+	[PM_P2P_GO_24_2x2] = {PM_NOP,		PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_5_1x1] = {PM_DBS1,		PM_NOP},
+	[PM_P2P_GO_5_2x2] = {PM_DBS1,		PM_NOP},
+	[PM_SAP_24_1x1] = {PM_NOP,		PM_DBS1},
+	[PM_SAP_24_2x2] = {PM_NOP,		PM_DBS1_DOWNGRADE},
+	[PM_SAP_5_1x1] = {PM_DBS1,		PM_NOP},
+	[PM_SAP_5_2x2] = {PM_DBS1,		PM_NOP},
+	[PM_IBSS_24_1x1] = {PM_NOP,		PM_DBS1},
+	[PM_IBSS_24_2x2] = {PM_NOP,		PM_DBS1_DOWNGRADE},
+	[PM_IBSS_5_1x1] = {PM_DBS1,		PM_NOP},
+	[PM_IBSS_5_2x2] = {PM_DBS1,		PM_NOP},
+};
+
+/**
+ * next_action_three_connection_table - table which provides next
+ * action while a new connection is coming up, with two
+ * connections already in the system
+ */
+static policy_mgr_next_action_three_connection_table_type
+	pm_next_action_three_connection_dbs_2x2_5g_1x1_2g_table = {
+	[PM_STA_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_STA_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_STA_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_STA_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_STA_SAP_SCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_STA_SAP_SCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_STA_SAP_MCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_STA_SAP_MCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_STA_SAP_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_STA_SAP_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_STA_SAP_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_STA_SAP_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+
+	[PM_STA_P2P_GO_SCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_STA_P2P_GO_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_STA_P2P_GO_MCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_STA_P2P_GO_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_STA_P2P_GO_SCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_STA_P2P_GO_SCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_STA_P2P_GO_MCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_STA_P2P_GO_MCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_STA_P2P_GO_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_STA_P2P_GO_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_STA_P2P_GO_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_STA_P2P_GO_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+
+	[PM_STA_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_STA_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_DBS1},
+	[PM_STA_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_STA_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_DBS1},
+	[PM_STA_P2P_CLI_SCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_STA_P2P_CLI_SCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_STA_P2P_CLI_MCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_STA_P2P_CLI_MCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_STA_P2P_CLI_MCC_24_5_1x1] = {PM_DBS1, PM_DBS1},
+	[PM_STA_P2P_CLI_MCC_24_5_2x2] = {PM_DBS1, PM_DBS1},
+	[PM_STA_P2P_CLI_DBS_1x1] = {PM_DBS1, PM_DBS1},
+	[PM_STA_P2P_CLI_DBS_2x2] = {PM_DBS1, PM_DBS1},
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE,
+					    PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE,
+					    PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+
+	[PM_P2P_GO_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_P2P_GO_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_P2P_GO_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_SAP_SCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_P2P_GO_SAP_SCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_P2P_GO_SAP_MCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_P2P_GO_SAP_MCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_P2P_GO_SAP_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_SAP_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_SAP_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_P2P_GO_SAP_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+
+	[PM_P2P_CLI_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_P2P_CLI_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_P2P_CLI_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_P2P_CLI_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_P2P_CLI_SAP_SCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_P2P_CLI_SAP_SCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_P2P_CLI_SAP_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_P2P_CLI_SAP_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_P2P_CLI_SAP_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+
+	[PM_SAP_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_SAP_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_SAP_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS1},
+	[PM_SAP_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE},
+	[PM_SAP_SAP_SCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_SAP_SAP_SCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_SAP_SAP_MCC_5_1x1] = {PM_DBS1, PM_NOP},
+	[PM_SAP_SAP_MCC_5_2x2] = {PM_DBS1, PM_NOP},
+	[PM_SAP_SAP_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_SAP_SAP_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_SAP_SAP_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+	[PM_SAP_SAP_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE},
+};
+
+#endif

+ 1394 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h

@@ -0,0 +1,1394 @@
+/*
+ * Copyright (c) 2012-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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WLAN_POLICY_MGR_TABLES_2X2_DBS_H
+#define __WLAN_POLICY_MGR_TABLES_2X2_DBS_H
+
+#include "wlan_policy_mgr_api.h"
+
+/**
+ * second_connection_pcl_dbs_2x2_table - table which provides PCL
+ * for the 2nd connection, when we have a connection already in
+ * the system (with DBS supported by HW)
+ * This table consolidates selection for P2PCLI, P2PGO, STA, SAP
+ * into the single set of STA entries for 2.4G and 5G.
+ */
+static pm_dbs_pcl_second_connection_table_type
+pm_second_connection_pcl_dbs_2x2_table = {
+	[PM_STA_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_STA_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_STA_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_IBSS_MODE] = {PM_24G, PM_24G, PM_24G} },
+
+	[PM_STA_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_IBSS_MODE] = {PM_24G, PM_24G, PM_24G} },
+
+	[PM_P2P_CLI_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+
+	[PM_IBSS_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] =	{
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] =	{
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] =	{
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] =	{
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+};
+
+/**
+ * third_connection_pcl_dbs_table - table which provides PCL for
+ * the 3rd connection, when we have two connections already in
+ * the system (with DBS supported by HW)
+ */
+static pm_dbs_pcl_third_connection_table_type
+pm_third_connection_pcl_dbs_2x2_table = {
+	[PM_STA_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_DBS_2x2] = {
+	[PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SBS_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_SAP_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_DBS_2x2] = {
+	[PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_SBS_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_SAP_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_24_1x1] = {
+		[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_DBS_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SBS_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = { PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_DBS_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SBS_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, },
+
+	[PM_STA_P2P_CLI_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_DBS_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SBS_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_DBS_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SBS_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, },
+
+	[PM_STA_STA_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_SBS_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_SAP_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+};
+
+/**
+ * next_action_two_connection_table - table which provides next
+ * action while a new connection is coming up, with one
+ * connection already in the system
+ */
+static policy_mgr_next_action_two_connection_table_type
+	pm_next_action_two_connection_dbs_2x2_table = {
+	[PM_STA_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_STA_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_P2P_CLI_24_1x1] = {PM_NOP,	PM_NOP},
+	[PM_P2P_CLI_24_2x2] = {PM_NOP,	PM_NOP},
+	[PM_P2P_CLI_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_P2P_CLI_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_P2P_GO_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_P2P_GO_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_P2P_GO_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_P2P_GO_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_SAP_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_SAP_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_SAP_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_SAP_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_IBSS_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_IBSS_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_IBSS_5_1x1] = {PM_DBS,		PM_NOP},
+	[PM_IBSS_5_2x2] = {PM_DBS,		PM_NOP},
+};
+
+/**
+ * next_action_three_connection_table - table which provides next
+ * action while a new connection is coming up, with two
+ * connections already in the system
+ */
+static policy_mgr_next_action_three_connection_table_type
+	pm_next_action_three_connection_dbs_2x2_table = {
+	[PM_STA_SAP_SCC_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_SAP_SCC_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_SAP_MCC_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_SAP_MCC_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_SAP_SCC_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_STA_SAP_SCC_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_STA_SAP_MCC_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_STA_SAP_MCC_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_STA_SAP_MCC_24_5_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_SAP_MCC_24_5_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_SAP_DBS_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_SAP_DBS_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_SAP_SBS_5_1x1] = {PM_DBS_UPGRADE,	PM_NOP},
+
+	[PM_STA_P2P_GO_SCC_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_GO_SCC_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_GO_MCC_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_GO_MCC_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_GO_SCC_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_STA_P2P_GO_SCC_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_STA_P2P_GO_MCC_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_STA_P2P_GO_MCC_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_STA_P2P_GO_MCC_24_5_1x1] = {PM_NOP,	PM_NOP},
+	[PM_STA_P2P_GO_MCC_24_5_2x2] = {PM_NOP,	PM_NOP},
+	[PM_STA_P2P_GO_DBS_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_GO_DBS_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_GO_SBS_5_1x1] = {PM_DBS_UPGRADE,	PM_NOP},
+
+	[PM_STA_P2P_CLI_SCC_24_1x1] = {PM_NOP,	PM_NOP},
+	[PM_STA_P2P_CLI_SCC_24_2x2] = {PM_NOP,	PM_NOP},
+	[PM_STA_P2P_CLI_MCC_24_1x1] = {PM_NOP,	PM_NOP},
+	[PM_STA_P2P_CLI_MCC_24_2x2] = {PM_NOP,	PM_NOP},
+	[PM_STA_P2P_CLI_SCC_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_STA_P2P_CLI_SCC_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_STA_P2P_CLI_MCC_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_STA_P2P_CLI_MCC_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_STA_P2P_CLI_MCC_24_5_1x1] = {PM_NOP,	PM_NOP},
+	[PM_STA_P2P_CLI_MCC_24_5_2x2] = {PM_NOP,	PM_NOP},
+	[PM_STA_P2P_CLI_DBS_1x1] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_CLI_DBS_2x2] = {PM_NOP,		PM_NOP},
+	[PM_STA_P2P_CLI_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP},
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {PM_NOP,	PM_NOP},
+	[PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {PM_NOP,	PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {PM_NOP,	 PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {PM_NOP,	 PM_NOP},
+	[PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {PM_DBS,	  PM_SBS},
+	[PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {PM_DBS,	PM_SBS_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {PM_DBS,	  PM_SBS},
+	[PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {PM_DBS,	PM_SBS_DOWNGRADE},
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {PM_NOP,	PM_NOP},
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {PM_NOP,	PM_NOP},
+	[PM_P2P_GO_P2P_CLI_DBS_1x1] = {PM_NOP,	PM_NOP},
+	[PM_P2P_GO_P2P_CLI_DBS_2x2] = {PM_NOP,	PM_NOP},
+	[PM_P2P_GO_P2P_CLI_SBS_5_1x1] = {PM_DBS_UPGRADE,	PM_NOP},
+
+	[PM_STA_STA_SCC_24_1x1] = {PM_NOP,	PM_NOP},
+	[PM_STA_STA_SCC_24_2x2] = {PM_NOP,	PM_NOP},
+	[PM_STA_STA_MCC_24_1x1] = {PM_NOP,	PM_NOP},
+	[PM_STA_STA_MCC_24_2x2] = {PM_NOP,	PM_NOP},
+	[PM_STA_STA_SCC_5_1x1] = {PM_DBS,	PM_SBS},
+	[PM_STA_STA_SCC_5_2x2] = {PM_DBS,	PM_SBS_DOWNGRADE},
+	[PM_STA_STA_MCC_5_1x1] = {PM_DBS,	PM_SBS},
+	[PM_STA_STA_MCC_5_2x2] = {PM_DBS,	PM_SBS_DOWNGRADE},
+	[PM_STA_STA_MCC_24_5_1x1] = {PM_NOP,	PM_NOP},
+	[PM_STA_STA_MCC_24_5_2x2] = {PM_NOP,	PM_NOP},
+	[PM_STA_STA_DBS_1x1] = {PM_NOP,	PM_NOP},
+	[PM_STA_STA_DBS_2x2] = {PM_NOP,	PM_NOP},
+	[PM_STA_STA_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP},
+
+	[PM_SAP_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS},
+	[PM_SAP_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS},
+	[PM_SAP_SAP_SCC_5_1x1] = {PM_DBS, PM_NOP},
+	[PM_SAP_SAP_SCC_5_2x2] = {PM_DBS, PM_NOP},
+
+};
+
+#endif

+ 900 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_no_dbs_i.h

@@ -0,0 +1,900 @@
+/*
+ * Copyright (c) 2012-2017 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WLAN_POLICY_MGR_TABLES_NO_DBS_H
+#define __WLAN_POLICY_MGR_TABLES_NO_DBS_H
+
+#include "wlan_policy_mgr_api.h"
+
+/**
+ * second_connection_pcl_nodbs_table - table which provides PCL
+ * for the 2nd connection, when we have a connection already in
+ * the system (with DBS not supported by HW)
+ */
+static const enum policy_mgr_pcl_type
+second_connection_pcl_nodbs_table[PM_MAX_ONE_CONNECTION_MODE]
+			[PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE] = {
+	[PM_STA_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH,    PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH,    PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH,    PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH,    PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH,    PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH,    PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_24_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_24_2x2] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_5_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_IBSS_5_2x2] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+};
+
+/**
+ * third_connection_pcl_nodbs_table - table which provides PCL
+ * for the 3rd connection, when we have two connections already
+ * in the system (with DBS not supported by HW)
+ */
+static const enum policy_mgr_pcl_type
+third_connection_pcl_nodbs_table[PM_MAX_TWO_CONNECTION_MODE]
+			[PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE] = {
+	[PM_STA_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G,        PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_5G,        PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {
+			PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {
+			PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_GO_DBS_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_P2P_CLI_DBS_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {
+			PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {
+			PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_CLI_DBS_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+
+	[PM_P2P_CLI_SAP_SCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_24_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_24_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_24_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_MCC_24_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_CLIENT_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_P2P_GO_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_IBSS_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+};
+
+#endif

+ 146 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c

@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "wlan_policy_mgr_ucfg.h"
+#include "wlan_policy_mgr_i.h"
+#include "cfg_ucfg_api.h"
+#include "wlan_policy_mgr_api.h"
+
+static QDF_STATUS policy_mgr_init_cfg(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_cfg *cfg;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	cfg = &pm_ctx->cfg;
+
+	cfg->mcc_to_scc_switch = cfg_get(psoc, CFG_MCC_TO_SCC_SWITCH);
+	cfg->sys_pref = cfg_get(psoc, CFG_CONC_SYS_PREF);
+	cfg->max_conc_cxns = cfg_get(psoc, CFG_MAX_CONC_CXNS);
+	cfg->conc_rule1 = cfg_get(psoc, CFG_ENABLE_CONC_RULE1);
+	cfg->conc_rule2 = cfg_get(psoc, CFG_ENABLE_CONC_RULE2);
+	cfg->dbs_selection_plcy = cfg_get(psoc, CFG_DBS_SELECTION_PLCY);
+	cfg->vdev_priority_list = cfg_get(psoc, CFG_VDEV_CUSTOM_PRIORITY_LIST);
+	cfg->chnl_select_plcy = cfg_get(psoc, CFG_CHNL_SELECT_LOGIC_CONC);
+	cfg->enable_mcc_adaptive_sch =
+		cfg_get(psoc, CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME);
+	cfg->enable_sta_cxn_5g_band =
+		cfg_get(psoc, CFG_ENABLE_STA_CONNECTION_IN_5GHZ);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void policy_mgr_deinit_cfg(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return;
+	}
+
+	qdf_mem_zero(&pm_ctx->cfg, sizeof(pm_ctx->cfg));
+}
+
+QDF_STATUS ucfg_policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+
+	status = policy_mgr_init_cfg(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("pm_ctx is NULL");
+		return status;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+void ucfg_policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	policy_mgr_deinit_cfg(psoc);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *mcc_scc_switch)
+{
+	return policy_mgr_get_mcc_scc_switch(psoc, mcc_scc_switch);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc,
+					uint8_t *sys_pref)
+{
+	return policy_mgr_get_sys_pref(psoc, sys_pref);
+}
+
+QDF_STATUS ucfg_policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc,
+					uint8_t sys_pref)
+{
+	return policy_mgr_set_sys_pref(psoc, sys_pref);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
+						uint8_t *max_conc_cxns)
+{
+	return policy_mgr_get_max_conc_cxns(psoc, max_conc_cxns);;
+}
+
+QDF_STATUS ucfg_policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc,
+						uint8_t *conc_rule1)
+{
+	return policy_mgr_get_conc_rule1(psoc, conc_rule1);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc,
+						uint8_t *conc_rule2)
+{
+	return policy_mgr_get_conc_rule2(psoc, conc_rule2);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc,
+						uint32_t *dbs_selection_plcy)
+{
+	return policy_mgr_get_dbs_selection_plcy(psoc, dbs_selection_plcy);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc,
+						uint32_t *vdev_priority_list)
+{
+	return policy_mgr_get_vdev_priority_list(psoc, vdev_priority_list);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc,
+						uint32_t *chnl_select_plcy)
+{
+	return policy_mgr_get_chnl_select_plcy(psoc, chnl_select_plcy);
+}
+
+
+QDF_STATUS ucfg_policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
+						uint8_t *mcc_adaptive_sch)
+{
+	return policy_mgr_get_mcc_adaptive_sch(psoc, mcc_adaptive_sch);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc,
+					       uint8_t *enable_sta_cxn_5g_band)
+{
+	return policy_mgr_get_sta_cxn_5g_band(psoc, enable_sta_cxn_5g_band);
+}