瀏覽代碼

Add 'qcom/opensource/wlan/qcacld-3.0/' from commit 'f5a566817a453ad657922a9aa68024db4d1ac3c7'

git-subtree-dir: qcom/opensource/wlan/qcacld-3.0
git-subtree-mainline: 925e49bf4f9ba866bc56ffbdb9fae1473e86b8fc
git-subtree-split: f5a566817a453ad657922a9aa68024db4d1ac3c7
Change-Id:
repo: https://git.codelinaro.org/clo/la/platform/vendor/qcom-opensource/wlan/qcacld-3.0
tag: LA.VENDOR.14.3.0.r1-17300-lanai.QSSI15.0
David Wronek 8 月之前
父節點
當前提交
5add812a59
共有 100 個文件被更改,包括 85560 次插入0 次删除
  1. 390 0
      qcom/opensource/wlan/qcacld-3.0/Android.mk
  2. 10 0
      qcom/opensource/wlan/qcacld-3.0/BUILD.bazel
  3. 5063 0
      qcom/opensource/wlan/qcacld-3.0/Kbuild
  4. 2156 0
      qcom/opensource/wlan/qcacld-3.0/Kconfig
  5. 40 0
      qcom/opensource/wlan/qcacld-3.0/Makefile
  6. 1 0
      qcom/opensource/wlan/qcacld-3.0/README.txt
  7. 1 0
      qcom/opensource/wlan/qcacld-3.0/api
  8. 1 0
      qcom/opensource/wlan/qcacld-3.0/cmn
  9. 173 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/inc/wlan_action_oui_main.h
  10. 79 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/inc/wlan_action_oui_objmgr.h
  11. 185 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/inc/wlan_action_oui_priv.h
  12. 503 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/src/wlan_action_oui_main.c
  13. 1091 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/src/wlan_action_oui_parse.c
  14. 914 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/inc/wlan_action_oui_cfg.h
  15. 260 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h
  16. 51 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/inc/wlan_action_oui_tgt_api.h
  17. 331 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/inc/wlan_action_oui_ucfg_api.h
  18. 43 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/src/wlan_action_oui_tgt_api.c
  19. 233 0
      qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/src/wlan_action_oui_ucfg_api.c
  20. 74 0
      qcom/opensource/wlan/qcacld-3.0/components/cfg/cfg_all.h
  21. 199 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/interface_mgr/inc/wlan_if_mgr_roam.h
  22. 1007 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c
  23. 235 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c
  24. 288 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c
  25. 1713 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/logging/inc/wlan_connectivity_logging.h
  26. 1231 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/logging/src/wlan_connectivity_logging.c
  27. 781 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/cfg_policy_mgr.h
  28. 5771 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h
  29. 133 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ll_sap.h
  30. 1911 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h
  31. 470 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h
  32. 4321 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c
  33. 5327 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c
  34. 13013 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c
  35. 1214 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h
  36. 989 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c
  37. 327 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ll_sap.c
  38. 5135 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c
  39. 2283 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h
  40. 151 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h
  41. 151 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h
  42. 2580 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h
  43. 2208 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_sbs_i.h
  44. 3692 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_no_dbs_i.h
  45. 381 0
      qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c
  46. 152 0
      qcom/opensource/wlan/qcacld-3.0/components/coap/core/inc/wlan_coap_main.h
  47. 163 0
      qcom/opensource/wlan/qcacld-3.0/components/coap/core/src/wlan_coap_main.c
  48. 123 0
      qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/inc/wlan_coap_public_structs.h
  49. 106 0
      qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/inc/wlan_coap_tgt_api.h
  50. 91 0
      qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/inc/wlan_coap_ucfg_api.h
  51. 187 0
      qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/src/wlan_coap_tgt_api.c
  52. 99 0
      qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/src/wlan_coap_ucfg_api.c
  53. 249 0
      qcom/opensource/wlan/qcacld-3.0/components/coex/core/inc/wlan_coex_main.h
  54. 264 0
      qcom/opensource/wlan/qcacld-3.0/components/coex/core/src/wlan_coex_main.c
  55. 78 0
      qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/inc/wlan_coex_tgt_api.h
  56. 198 0
      qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/inc/wlan_coex_ucfg_api.h
  57. 88 0
      qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/inc/wlan_coex_utils_api.h
  58. 151 0
      qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/src/wlan_coex_tgt_api.c
  59. 167 0
      qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/src/wlan_coex_ucfg_api.c
  60. 147 0
      qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/src/wlan_coex_utils_api.c
  61. 63 0
      qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_ext_type.h
  62. 875 0
      qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h
  63. 129 0
      qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_tgt_api.h
  64. 538 0
      qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h
  65. 1564 0
      qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c
  66. 1460 0
      qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c
  67. 333 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/core/inc/wlan_dlm_core.h
  68. 178 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/core/inc/wlan_dlm_main.h
  69. 1486 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/core/src/wlan_dlm_core.c
  70. 190 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/core/src/wlan_dlm_main.c
  71. 176 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/cfg_dlm.h
  72. 173 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/wlan_dlm_api.h
  73. 186 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/wlan_dlm_public_struct.h
  74. 42 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/wlan_dlm_tgt_api.h
  75. 222 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/wlan_dlm_ucfg_api.h
  76. 51 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/src/wlan_dlm_tgt_api.c
  77. 253 0
      qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/src/wlan_dlm_ucfg_api.c
  78. 100 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/core/inc/wlan_disa_main.h
  79. 193 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/core/inc/wlan_disa_objmgr.h
  80. 61 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/core/inc/wlan_disa_priv.h
  81. 105 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/core/src/wlan_disa_main.c
  82. 116 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_api.h
  83. 56 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_public_struct.h
  84. 91 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_public_struct.h
  85. 71 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_tgt_api.h
  86. 46 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_ucfg_api.h
  87. 209 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/src/wlan_disa_obj_mgmt_api.c
  88. 133 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/src/wlan_disa_tgt_api.c
  89. 34 0
      qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/src/wlan_disa_ucfg_api.c
  90. 1030 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_main.h
  91. 158 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_objmgr.h
  92. 122 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_periodic_sta_stats.h
  93. 163 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_prealloc.h
  94. 979 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_priv.h
  95. 763 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_rx_thread.h
  96. 177 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_swlm.h
  97. 674 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_txrx.h
  98. 187 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_wfds.h
  99. 2347 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/src/wlan_dp_bus_bandwidth.c
  100. 453 0
      qcom/opensource/wlan/qcacld-3.0/components/dp/core/src/wlan_dp_bus_bandwidth.h

+ 390 - 0
qcom/opensource/wlan/qcacld-3.0/Android.mk

@@ -0,0 +1,390 @@
+# Android makefile for the WLAN Module
+
+# set WLAN_BUILD_DEBUG=y in your environment to enable debug logging
+define wlog
+$(if $(WLAN_BUILD_DEBUG),$(info $(1)))
+endef
+
+define target_is_dual_wlan
+$(strip \
+  $(if $(TARGET_SUPPORT_DUAL_WLAN), \
+     $(if $(findstring cnss2,$(1)),true,), \
+  ) \
+)
+endef
+
+LOCAL_MODULE_DDK_BUILD := false
+LOCAL_MODULE_DDK_ALLOW_UNSAFE_HEADERS := false
+
+ifeq ($(TARGET_BOARD_PLATFORM), sun)
+LOCAL_MODULE_DDK_BUILD := true
+LOCAL_MODULE_DDK_ALLOW_UNSAFE_HEADERS := true
+endif
+ifeq ($(TARGET_BOARD_PLATFORM), pineapple)
+LOCAL_MODULE_DDK_BUILD := true
+LOCAL_MODULE_DDK_ALLOW_UNSAFE_HEADERS := true
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM), niobe)
+LOCAL_MODULE_DDK_BUILD := true
+LOCAL_MODULE_DDK_ALLOW_UNSAFE_HEADERS := true
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM), volcano)
+LOCAL_MODULE_DDK_BUILD := true
+LOCAL_MODULE_DDK_ALLOW_UNSAFE_HEADERS := true
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM),parrot)
+ifeq ($(TARGET_BOARD_SUFFIX),66)
+LOCAL_MODULE_DDK_BUILD := true
+LOCAL_MODULE_DDK_ALLOW_UNSAFE_HEADERS := true
+endif
+endif
+
+LOCAL_PATH := $(call my-dir)
+$(call wlog,LOCAL_PATH=$(LOCAL_PATH))
+BOARD_OPENSOURCE_DIR ?= vendor/qcom/opensource
+
+ENABLE_QCACLD := true
+ifeq ($(TARGET_USES_QMAA), true)
+ifneq ($(TARGET_USES_QMAA_OVERRIDE_WLAN), true)
+ENABLE_QCACLD := false
+else
+ENABLE_QCACLD := true
+endif
+endif
+
+ifeq ($(BOARD_COMMON_DIR),)
+    BOARD_COMMON_DIR := device/qcom/common
+endif
+
+ifeq  ($(ENABLE_QCACLD), true)
+
+# Assume no targets will be supported
+WLAN_CHIPSET :=
+
+ifeq ($(BOARD_HAS_QCOM_WLAN), true)
+
+# Check if this driver needs be built for current target
+ifneq ($(findstring qca_cld3,$(WIFI_DRIVER_BUILT)),)
+	WLAN_CHIPSET := qca_cld3
+	WLAN_SELECT  := CONFIG_QCA_CLD_WLAN=m
+endif
+
+# Build/Package only in case of supported target
+ifneq ($(WLAN_CHIPSET),)
+
+# This makefile is only for DLKM
+ifneq ($(findstring vendor,$(LOCAL_PATH)),)
+
+ifneq ($(findstring opensource,$(LOCAL_PATH)),)
+	WLAN_BLD_DIR := $(BOARD_OPENSOURCE_DIR)/wlan
+endif # opensource
+
+# Multi-ko check
+LOCAL_DEV_NAME := $(patsubst .%,%,\
+	$(lastword $(strip $(subst /, ,$(LOCAL_PATH)))))
+
+$(call wlog,LOCAL_DEV_NAME=$(LOCAL_DEV_NAME))
+$(call wlog,TARGET_WLAN_CHIP=$(TARGET_WLAN_CHIP))
+
+TARGET_WLAN_CHIP ?= wlan
+LOCAL_MULTI_KO := false
+ifneq ($(TARGET_WLAN_CHIP), wlan)
+ifeq ($(LOCAL_DEV_NAME), qcacld-3.0)
+LOCAL_MULTI_KO := true
+endif
+endif
+
+ifeq ($(LOCAL_MULTI_KO), true)
+LOCAL_ANDROID_ROOT := $(shell pwd)
+LOCAL_WLAN_BLD_DIR := $(LOCAL_ANDROID_ROOT)/$(WLAN_BLD_DIR)
+$(shell `find $(LOCAL_WLAN_BLD_DIR)/qcacld-3.0/ -maxdepth 1 -name '.*' ! -name '.git' -delete`)
+
+ifeq ($(LOCAL_MODULE_DDK_BUILD), true)
+ifeq ($(CHIPSET),)
+$(foreach chip, $(TARGET_WLAN_CHIP),\
+	$(eval CHIPSET := $(chip))\
+	$(eval include $(LOCAL_PATH)/Android.mk))
+else
+# DLKM_DIR was moved for JELLY_BEAN (PLATFORM_SDK 16)
+BAZEL_CHIPSET_NAME := $(subst _,-,$(CHIPSET))
+ifeq ($(call is-platform-sdk-version-at-least,16),true)
+        DLKM_DIR := $(TOP)/$(BOARD_COMMON_DIR)/dlkm
+else
+        DLKM_DIR := build/dlkm
+endif # platform-sdk-version
+
+include $(CLEAR_VARS)
+LOCAL_MOD_NAME := wlan
+LOCAL_MODULE              := qca_cld3_$(CHIPSET).ko
+LOCAL_MODULE_KBUILD_NAME  := qca_cld3_$(CHIPSET).ko
+LOCAL_MODULE_DEBUG_ENABLE := true
+LOCAL_MODULE_DDK_SUBTARGET_REGEX := "all.*"
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+    ifeq ($(WIFI_DRIVER_INSTALL_TO_KERNEL_OUT),true)
+        LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
+    else
+        LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)
+    endif
+else
+    LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/modules/$(WLAN_CHIPSET)
+endif
+
+
+LOCAL_DEV_NAME := $(CHIPSET)
+LOCAL_CHIP_NAME := $(LOCAL_DEV_NAME)
+TARGET_MAC_BIN_PATH := /mnt/vendor/persist/$(LOCAL_CHIP_NAME)
+TARGET_FW_DIR := firmware/wlan/qca_cld/$(LOCAL_CHIP_NAME)
+TARGET_CFG_PATH := /vendor/etc/wifi/$(LOCAL_CHIP_NAME)
+TARGET_MAC_BIN_PATH := /mnt/vendor/persist/$(LOCAL_CHIP_NAME)
+
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+TARGET_FW_PATH := $(TARGET_OUT_VENDOR)/$(TARGET_FW_DIR)
+else
+TARGET_FW_PATH := $(TARGET_OUT_ETC)/$(TARGET_FW_DIR)
+endif
+
+# Create wlan_mac.bin symbolic link as part of the module
+$(call symlink-file,,$(TARGET_MAC_BIN_PATH)/wlan_mac.bin,$(TARGET_FW_PATH)/wlan_mac.bin)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_FW_PATH)/wlan_mac.bin
+
+# Conditionally create module symbolic link
+ifneq ($(findstring $(WLAN_CHIPSET),$(WIFI_DRIVER_DEFAULT)),)
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+ifneq ($(WIFI_DRIVER_INSTALL_TO_KERNEL_OUT),true)
+$(call symlink-file,,$(TARGET_COPY_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)/$(LOCAL_MODULE),$(TARGET_OUT_VENDOR)/lib/modules/$(LOCAL_MODULE))
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_VENDOR)/lib/modules/$(LOCAL_MODULE)
+endif
+else
+$(call symlink-file,,/system/lib/modules/$(WLAN_CHIPSET)/$(LOCAL_MODULE),$(TARGET_OUT)/lib/modules/$(LOCAL_MODULE))
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT)/lib/modules/$(LOCAL_MODULE)
+endif
+endif
+
+# Conditionally create ini symbolic link
+ifeq ($(TARGET_BOARD_AUTO),true)
+$(call symlink-file,,$(TARGET_CFG_PATH)/WCNSS_qcom_cfg.ini,$(TARGET_FW_PATH)/WCNSS_qcom_cfg.ini)
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_FW_PATH)/WCNSS_qcom_cfg.ini
+$(call wlog,"generate soft link because TARGET_BOARD_AUTO true")
+else
+ifneq ($(GENERIC_ODM_IMAGE),true)
+$(call symlink-file,,$(TARGET_CFG_PATH)/WCNSS_qcom_cfg.ini,$(TARGET_FW_PATH)/WCNSS_qcom_cfg.ini)
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_FW_PATH)/WCNSS_qcom_cfg.ini
+$(call wlog,"generate soft link because GENERIC_ODM_IMAGE not true")
+endif
+endif
+
+# Set dependencies so that CNSS family drivers can be compiled ahead.
+ifneq ($(WLAN_PLATFORM_KBUILD_OPTIONS),)
+LOCAL_REQUIRED_MODULES := wlan-platform-module-symvers
+LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,wlan-platform-module-symvers)/Module.symvers
+endif
+
+$(call wlog,TARGET_USES_KERNEL_PLATFORM=$(TARGET_USES_KERNEL_PLATFORM))
+ifeq ($(TARGET_USES_KERNEL_PLATFORM),true)
+    include $(DLKM_DIR)/Build_external_kernelmodule.mk
+else
+    include $(DLKM_DIR)/AndroidKernelModule.mk
+endif
+endif
+else
+$(foreach chip, $(TARGET_WLAN_CHIP), \
+	$(shell ln -sf . $(LOCAL_WLAN_BLD_DIR)/qcacld-3.0/.$(chip)))
+include $(foreach chip, $(TARGET_WLAN_CHIP), $(LOCAL_PATH)/.$(chip)/Android.mk)
+endif
+
+else # Multi-ok check
+
+# When dual wlan enabled, secondary dev name would be $(chip)_cnss2.
+# Use LOCAL_CHIP_NAME instead of LOCAL_DEV_NAME for secondary one.
+LOCAL_CHIP_NAME := $(LOCAL_DEV_NAME)
+TARGET_SECONDARY_WLAN := $(call target_is_dual_wlan,$(LOCAL_DEV_NAME))
+ifeq ($(TARGET_SECONDARY_WLAN), true)
+LOCAL_CHIP_NAME := $(patsubst %_cnss2,%,$(strip $(LOCAL_DEV_NAME)))
+endif
+
+ifeq ($(WLAN_PROFILE),)
+WLAN_PROFILE := default
+endif
+
+ifeq ($(LOCAL_DEV_NAME), qcacld-3.0)
+
+LOCAL_DEV_NAME := wlan
+LOCAL_MOD_NAME := wlan
+LOCAL_SRC_DIR :=
+TARGET_FW_DIR := firmware/wlan/qca_cld
+TARGET_CFG_PATH := /vendor/etc/wifi
+TARGET_MAC_BIN_PATH := /mnt/vendor/persist
+
+else
+
+LOCAL_SRC_DIR := .$(LOCAL_DEV_NAME)
+# Use default profile if WLAN_CFG_USE_DEFAULT defined.
+ifeq ($(WLAN_CFG_USE_DEFAULT),)
+WLAN_PROFILE := $(LOCAL_CHIP_NAME)
+endif
+TARGET_FW_DIR := firmware/wlan/qca_cld/$(LOCAL_CHIP_NAME)
+TARGET_CFG_PATH := /vendor/etc/wifi/$(LOCAL_CHIP_NAME)
+TARGET_MAC_BIN_PATH := /mnt/vendor/persist/$(LOCAL_CHIP_NAME)
+
+ifneq ($(TARGET_MULTI_WLAN), true)
+LOCAL_MOD_NAME := wlan
+DYNAMIC_SINGLE_CHIP := $(LOCAL_DEV_NAME)
+else
+LOCAL_MOD_NAME := $(LOCAL_DEV_NAME)
+endif
+
+ifeq ($(TARGET_SECONDARY_WLAN), true)
+TARGET_SECONDARY_WLAN_NUMBER := 2
+LOCAL_MOD_NAME := $(LOCAL_CHIP_NAME)_$(TARGET_SECONDARY_WLAN_NUMBER)
+DYNAMIC_SINGLE_CHIP := $(LOCAL_CHIP_NAME)
+endif
+
+endif
+
+# DLKM_DIR was moved for JELLY_BEAN (PLATFORM_SDK 16)
+ifeq ($(call is-platform-sdk-version-at-least,16),true)
+	DLKM_DIR := $(TOP)/$(BOARD_COMMON_DIR)/dlkm
+else
+	DLKM_DIR := build/dlkm
+endif # platform-sdk-version
+
+# Build wlan.ko as $(WLAN_CHIPSET)_wlan.ko
+###########################################################
+# This is set once per LOCAL_PATH, not per (kernel) module
+KBUILD_OPTIONS := WLAN_ROOT=$(WLAN_BLD_DIR)/qcacld-3.0/$(LOCAL_SRC_DIR)
+KBUILD_OPTIONS += WLAN_COMMON_ROOT=cmn
+KBUILD_OPTIONS += WLAN_COMMON_INC=$(WLAN_BLD_DIR)/qcacld-3.0/cmn
+KBUILD_OPTIONS += WLAN_FW_API=$(WLAN_BLD_DIR)/fw-api
+KBUILD_OPTIONS += WLAN_PROFILE=$(WLAN_PROFILE)
+KBUILD_OPTIONS += DYNAMIC_SINGLE_CHIP=$(DYNAMIC_SINGLE_CHIP)
+
+# We are actually building wlan.ko here, as per the
+# requirement we are specifying <chipset>_wlan.ko as LOCAL_MODULE.
+# This means we need to rename the module to <chipset>_wlan.ko
+# after wlan.ko is built.
+KBUILD_OPTIONS += MODNAME=$(LOCAL_MOD_NAME)
+KBUILD_OPTIONS += DEVNAME=$(LOCAL_DEV_NAME)
+KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
+KBUILD_OPTIONS += $(WLAN_SELECT)
+
+KBUILD_REQUIRED_KOS := ipam.ko
+
+ifneq ($(WLAN_CFG_OVERRIDE_$(LOCAL_DEV_NAME)),)
+KBUILD_OPTIONS += WLAN_CFG_OVERRIDE="$(WLAN_CFG_OVERRIDE_$(LOCAL_DEV_NAME))"
+endif
+
+# driver expects "/dev/<name>" for wifi driver state ctrl parameter.
+# i.e. WIFI_DRIVER_STATE_CTRL_PARAM="/dev/wlan" is defined for single wlan.
+# WIFI_DRIVER_STATE_CTRL_PARAM_SECONDARY="/dev/wlan2" is defined for 2nd wlan.
+ifeq ($(TARGET_SECONDARY_WLAN), true)
+$(call wlog,STATE_CTRL_PARAM_SECONDARY=$(WIFI_DRIVER_STATE_CTRL_PARAM_SECONDARY))
+PARAM_SECONDARY := $(patsubst "%",%,$(WIFI_DRIVER_STATE_CTRL_PARAM_SECONDARY))
+$(call wlog,PARAM_SECONDARY=$(PARAM_SECONDARY))
+ifeq ($(dir $(PARAM_SECONDARY)),/dev/)
+KBUILD_OPTIONS += WLAN_CTRL_NAME=$(notdir $(PARAM_SECONDARY))
+endif
+else
+$(call wlog,WIFI_DRIVER_STATE_CTRL_PARAM=$(WIFI_DRIVER_STATE_CTRL_PARAM))
+PARAM := $(patsubst "%",%,$(WIFI_DRIVER_STATE_CTRL_PARAM))
+$(call wlog,PARAM=$(PARAM))
+ifeq ($(dir $(PARAM)),/dev/)
+KBUILD_OPTIONS += WLAN_CTRL_NAME=$(notdir $(PARAM))
+endif
+endif
+
+# Pass build options per chip to Kbuild. This will be injected from upper layer
+# makefile.
+#
+# e.g.
+#  WLAN_KBUILD_OPTIONS_qca6390 := CONFIG_CNSS_QCA6390=y
+ifneq ($(WLAN_KBUILD_OPTIONS_$(LOCAL_DEV_NAME)),)
+KBUILD_OPTIONS += "$(WLAN_KBUILD_OPTIONS_$(LOCAL_DEV_NAME))"
+endif
+
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+TARGET_FW_PATH := $(TARGET_OUT_VENDOR)/$(TARGET_FW_DIR)
+else
+TARGET_FW_PATH := $(TARGET_OUT_ETC)/$(TARGET_FW_DIR)
+endif
+
+# WLAN_PLATFORM_KBUILD_OPTIONS should be passed from upper level Makefiles
+# like wlan.mk. It indicates sources of CNSS family drivers (cnss2, cnss_nl,
+# cnss_prealloc and cnss_utils etc.) are built out of kernel tree and it
+# should also include all necessary config flags (e.g. CONFIG_CNSS2) which
+# are originally defined from kernel Kconfig/defconfig. KBUILD_EXTRA_SYMBOLS
+# is also needed to indicate all the symbols from these drivers.
+ifneq ($(WLAN_PLATFORM_KBUILD_OPTIONS),)
+KBUILD_OPTIONS += $(foreach wlan_platform_kbuild_option, \
+		   $(WLAN_PLATFORM_KBUILD_OPTIONS), \
+		   $(wlan_platform_kbuild_option))
+
+KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS+=$(shell pwd)/$(call intermediates-dir-for,DLKM,wlan-platform-module-symvers)/Module.symvers
+endif
+
+include $(CLEAR_VARS)
+
+# Create the module
+LOCAL_MODULE              := $(WLAN_CHIPSET)_$(LOCAL_DEV_NAME).ko
+LOCAL_MODULE_KBUILD_NAME  := $(LOCAL_MOD_NAME).ko
+LOCAL_MODULE_DEBUG_ENABLE := true
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+    ifeq ($(WIFI_DRIVER_INSTALL_TO_KERNEL_OUT),true)
+        LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
+    else
+        LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)
+    endif
+else
+    LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/modules/$(WLAN_CHIPSET)
+endif
+
+# Create wlan_mac.bin symbolic link as part of the module
+$(call symlink-file,,$(TARGET_MAC_BIN_PATH)/wlan_mac.bin,$(TARGET_FW_PATH)/wlan_mac.bin)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_FW_PATH)/wlan_mac.bin
+
+# Conditionally create module symbolic link
+ifneq ($(findstring $(WLAN_CHIPSET),$(WIFI_DRIVER_DEFAULT)),)
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+ifneq ($(WIFI_DRIVER_INSTALL_TO_KERNEL_OUT),true)
+$(call symlink-file,,$(TARGET_COPY_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)/$(LOCAL_MODULE),$(TARGET_OUT_VENDOR)/lib/modules/$(LOCAL_MODULE))
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_VENDOR)/lib/modules/$(LOCAL_MODULE)
+endif
+else
+$(call symlink-file,,/system/lib/modules/$(WLAN_CHIPSET)/$(LOCAL_MODULE),$(TARGET_OUT)/lib/modules/$(LOCAL_MODULE))
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT)/lib/modules/$(LOCAL_MODULE)
+endif
+endif
+
+# Conditionally create ini symbolic link
+ifeq ($(TARGET_BOARD_AUTO),true)
+$(call symlink-file,,$(TARGET_CFG_PATH)/WCNSS_qcom_cfg.ini,$(TARGET_FW_PATH)/WCNSS_qcom_cfg.ini)
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_FW_PATH)/WCNSS_qcom_cfg.ini
+$(call wlog,"generate soft link because TARGET_BOARD_AUTO true")
+else
+ifneq ($(GENERIC_ODM_IMAGE),true)
+$(call symlink-file,,$(TARGET_CFG_PATH)/WCNSS_qcom_cfg.ini,$(TARGET_FW_PATH)/WCNSS_qcom_cfg.ini)
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_FW_PATH)/WCNSS_qcom_cfg.ini
+$(call wlog,"generate soft link because GENERIC_ODM_IMAGE not true")
+endif
+endif
+
+# Set dependencies so that CNSS family drivers can be compiled ahead.
+ifneq ($(WLAN_PLATFORM_KBUILD_OPTIONS),)
+LOCAL_REQUIRED_MODULES := wlan-platform-module-symvers
+LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,wlan-platform-module-symvers)/Module.symvers
+endif
+
+$(call wlog,TARGET_USES_KERNEL_PLATFORM=$(TARGET_USES_KERNEL_PLATFORM))
+ifeq ($(TARGET_USES_KERNEL_PLATFORM),true)
+    include $(DLKM_DIR)/Build_external_kernelmodule.mk
+else
+    include $(DLKM_DIR)/AndroidKernelModule.mk
+endif
+
+endif # Multi-ko check
+endif # DLKM check
+endif # supported target check
+endif # WLAN enabled check
+endif # ENABLE_QCACLD

+ 10 - 0
qcom/opensource/wlan/qcacld-3.0/BUILD.bazel

@@ -0,0 +1,10 @@
+load("//build/kernel/kleaf:kernel.bzl", "ddk_headers")
+load(":wlan_qcacld3_modules.bzl", "define_modules")
+
+package(
+    default_visibility = [
+        "//visibility:public",
+    ],
+)
+
+define_modules()

+ 5063 - 0
qcom/opensource/wlan/qcacld-3.0/Kbuild

@@ -0,0 +1,5063 @@
+# We can build either as part of a standalone Kernel build or as
+# an external module.  Determine which mechanism is being used
+ifeq ($(MODNAME),)
+	KERNEL_BUILD := y
+else
+	KERNEL_BUILD := n
+endif
+
+ifeq ($(KERNEL_BUILD), y)
+	# These are provided in external module based builds
+	# Need to explicitly define for Kernel-based builds
+	MODNAME := wlan
+	WLAN_ROOT := drivers/staging/qcacld-3.0
+	WLAN_COMMON_ROOT := cmn
+	WLAN_COMMON_INC := $(WLAN_ROOT)/$(WLAN_COMMON_ROOT)
+	WLAN_FW_API := $(WLAN_ROOT)/../fw-api/
+	WLAN_PROFILE := default
+endif
+
+WLAN_COMMON_ROOT ?= cmn
+WLAN_COMMON_INC ?= $(WLAN_ROOT)/$(WLAN_COMMON_ROOT)
+WLAN_FW_API ?= $(WLAN_ROOT)/../fw-api/
+WLAN_PROFILE ?= default
+CONFIG_QCA_CLD_WLAN_PROFILE ?= $(WLAN_PROFILE)
+DEVNAME ?= wlan
+WLAN_PLATFORM_INC ?= $(WLAN_ROOT)/../platform/inc
+DATA_IPA_INC ?= $(WLAN_ROOT)/../dataipa/drivers/platform/msm/include
+DATA_IPA_UAPI_INC ?= $(DATA_IPA_INC)/uapi
+
+ifeq ($(KERNEL_BUILD), n)
+ifneq ($(ANDROID_BUILD_TOP),)
+      ANDROID_BUILD_TOP_REL := $(shell python -c "import os.path; print(os.path.relpath('$(ANDROID_BUILD_TOP)'))")
+      override WLAN_ROOT := $(ANDROID_BUILD_TOP_REL)/$(WLAN_ROOT)
+      override WLAN_COMMON_INC := $(ANDROID_BUILD_TOP_REL)/$(WLAN_COMMON_INC)
+      override WLAN_FW_API := $(ANDROID_BUILD_TOP_REL)/$(WLAN_FW_API)
+else ifneq ($(LINUX_BUILD_TOP),)
+      LINUX_BUILD_TOP_REL := $(shell python -c "import os.path; print(os.path.relpath('$(LINUX_BUILD_TOP)'))")
+      $(warning "LINUX_BUILD_TOP_REL=: $(LINUX_BUILD_TOP_REL)")
+      override WLAN_ROOT := $(LINUX_BUILD_TOP_REL)/qcacld-3.0
+      override WLAN_COMMON_ROOT ?= cmn
+      override WLAN_COMMON_INC ?= $(WLAN_ROOT)/$(WLAN_COMMON_ROOT)
+      override WLAN_FW_API := $(WLAN_ROOT)/../fw-api
+endif
+endif
+
+include $(WLAN_ROOT)/configs/$(CONFIG_QCA_CLD_WLAN_PROFILE)_defconfig
+
+# add configurations in WLAN_CFG_OVERRIDE
+$(foreach cfg, $(WLAN_CFG_OVERRIDE), \
+	$(eval $(cfg)) \
+	$(warning "Overriding WLAN config with: $(cfg)"))
+
+# KERNEL_SUPPORTS_NESTED_COMPOSITES := y is used to enable nested
+# composite support. The nested composite support is available in some
+# MSM kernels, and is available in 5.10 GKI kernels beginning with
+# 5.10.20, but unfortunately is not available in any upstream kernel.
+#
+# When the feature is present in an MSM kernel, the flag is explicitly
+# set in the kernel sources.  When a GKI kernel is used, there isn't a
+# flag set in the sources, so set the flag here if we are building
+# with GKI kernel where the feature is present
+KERNEL_VERSION = $(shell echo $$(( ( $1 << 16 ) + ( $2 << 8 ) + $3 )))
+LINUX_CODE := $(call KERNEL_VERSION,$(VERSION),$(PATCHLEVEL),$(SUBLEVEL))
+
+# Comosite feature was added to GKI 5.10.20
+COMPOSITE_CODE_ADDED := 330260 # hardcoded $(call KERNEL_VERSION,5,10,20)
+
+# Comosite feature was not ported beyond 5.10.x
+COMPOSITE_CODE_REMOVED := 330496 # hardcoded $(call KERNEL_VERSION,5,11,0)
+
+ifeq ($(KERNEL_SUPPORTS_NESTED_COMPOSITES),)
+  #flag is not explicitly present
+  ifneq ($(findstring gki,$(CONFIG_LOCALVERSION))$(findstring qki,$(CONFIG_LOCALVERSION)),)
+    # GKI kernel
+    ifeq ($(shell test $(LINUX_CODE) -ge $(COMPOSITE_CODE_ADDED); echo $$?),0)
+      # version >= 5.10.20
+      ifeq ($(shell test $(LINUX_CODE) -lt $(COMPOSITE_CODE_REMOVED); echo $$?),0)
+        # version < 5.11.0
+        KERNEL_SUPPORTS_NESTED_COMPOSITES := y
+      endif
+    endif
+  endif
+endif
+
+OBJS :=
+OBJS_DIRS :=
+
+define add-wlan-objs
+$(eval $(_add-wlan-objs))
+endef
+
+define _add-wlan-objs
+  ifneq ($(2),)
+    ifeq ($(KERNEL_SUPPORTS_NESTED_COMPOSITES),y)
+      OBJS_DIRS += $(dir $(2))
+      OBJS += $(1).o
+      $(1)-y := $(2)
+    else
+      OBJS += $(2)
+    endif
+  endif
+endef
+
+############ UAPI ############
+UAPI_DIR :=	uapi
+UAPI_INC :=	-I$(WLAN_ROOT)/$(UAPI_DIR)/linux
+
+############ COMMON ############
+COMMON_DIR :=	core/common
+COMMON_INC :=	-I$(WLAN_ROOT)/$(COMMON_DIR)
+
+############ HDD ############
+HDD_DIR :=	core/hdd
+HDD_INC_DIR :=	$(HDD_DIR)/inc
+HDD_SRC_DIR :=	$(HDD_DIR)/src
+
+HDD_INC := 	-I$(WLAN_ROOT)/$(HDD_INC_DIR) \
+		-I$(WLAN_ROOT)/$(HDD_SRC_DIR)
+
+HDD_OBJS := 	$(HDD_SRC_DIR)/wlan_hdd_assoc.o \
+		$(HDD_SRC_DIR)/wlan_hdd_cfg.o \
+		$(HDD_SRC_DIR)/wlan_hdd_cfg80211.o \
+		$(HDD_SRC_DIR)/wlan_hdd_data_stall_detection.o \
+		$(HDD_SRC_DIR)/wlan_hdd_driver_ops.o \
+		$(HDD_SRC_DIR)/wlan_hdd_ftm.o \
+		$(HDD_SRC_DIR)/wlan_hdd_hostapd.o \
+		$(HDD_SRC_DIR)/wlan_hdd_ioctl.o \
+		$(HDD_SRC_DIR)/wlan_hdd_main.o \
+		$(HDD_SRC_DIR)/wlan_hdd_object_manager.o \
+		$(HDD_SRC_DIR)/wlan_hdd_oemdata.o \
+		$(HDD_SRC_DIR)/wlan_hdd_p2p.o \
+		$(HDD_SRC_DIR)/wlan_hdd_power.o \
+		$(HDD_SRC_DIR)/wlan_hdd_regulatory.o \
+		$(HDD_SRC_DIR)/wlan_hdd_scan.o \
+		$(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \
+		$(HDD_SRC_DIR)/wlan_hdd_sta_info.o \
+		$(HDD_SRC_DIR)/wlan_hdd_stats.o \
+		$(HDD_SRC_DIR)/wlan_hdd_trace.o \
+		$(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \
+		$(HDD_SRC_DIR)/wlan_hdd_wmm.o \
+		$(HDD_SRC_DIR)/wlan_hdd_wowl.o\
+		$(HDD_SRC_DIR)/wlan_hdd_ll_lt_sap.o\
+
+ifeq ($(CONFIG_UNIT_TEST), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_unit_test.o
+endif
+
+ifeq ($(CONFIG_WLAN_WEXT_SUPPORT_ENABLE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_wext.o \
+	    $(HDD_SRC_DIR)/wlan_hdd_hostapd_wext.o
+endif
+
+ifeq ($(CONFIG_AFC_SUPPORT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_afc.o
+endif
+
+ifeq ($(CONFIG_DCS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_dcs.o
+endif
+
+ifeq ($(CONFIG_FEATURE_WLAN_EXTSCAN), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_ext_scan.o
+endif
+
+ifeq ($(CONFIG_WLAN_DEBUGFS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs.o
+ifeq ($(CONFIG_WLAN_FEATURE_LINK_LAYER_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_llstat.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_MIB_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_mibstat.o
+endif
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_csr.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_offload.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_roam.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_config.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_unit_test.o
+ifeq ($(CONFIG_WLAN_MWS_INFO_DEBUGFS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_coex.o
+endif
+endif
+
+ifeq ($(CONFIG_WLAN_CONV_SPECTRAL_ENABLE),y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_spectralscan.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+HDD_OBJS+=	$(HDD_SRC_DIR)/wlan_hdd_ocb.o
+endif
+
+ifeq ($(CONFIG_FEATURE_MEMDUMP_ENABLE), y)
+HDD_OBJS+=	$(HDD_SRC_DIR)/wlan_hdd_memdump.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_FIPS), y)
+HDD_OBJS+=	$(HDD_SRC_DIR)/wlan_hdd_fips.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_GREEN_AP), y)
+HDD_OBJS+=	$(HDD_SRC_DIR)/wlan_hdd_green_ap.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_APF), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_apf.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_LPSS), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_lpass.o
+endif
+
+ifeq ($(CONFIG_WLAN_NAPI), y)
+HDD_OBJS +=     $(HDD_SRC_DIR)/wlan_hdd_napi.o
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_ipa.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_SON), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_son.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_nan.o
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_nan_datapath.o
+endif
+
+ifeq ($(CONFIG_QCOM_TDLS), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_tdls.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYNC_TSF_PLUS), y)
+CONFIG_WLAN_SYNC_TSF := y
+endif
+
+ifeq ($(CONFIG_WLAN_SYNC_TSF), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_tsf.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DISA), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_disa.o
+endif
+
+ifeq ($(CONFIG_LFR_SUBNET_DETECTION), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_subnet_detect.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_11AX), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_he.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_11BE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_eht.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_twt.o
+endif
+
+ifeq ($(CONFIG_FEATURE_MONITOR_MODE_SUPPORT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_rx_monitor.o
+endif
+
+ifeq ($(CONFIG_WLAN_NUD_TRACKING), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_nud_tracking.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_PACKET_FILTERING), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_packet_filter.o
+endif
+
+ifeq ($(CONFIG_FEATURE_RSSI_MONITOR), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_rssi_monitor.o
+endif
+
+ifeq ($(CONFIG_FEATURE_BSS_TRANSITION), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_bss_transition.o
+endif
+
+ifeq ($(CONFIG_FEATURE_STATION_INFO), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_station_info.o
+endif
+
+ifeq ($(CONFIG_FEATURE_TX_POWER), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tx_power.o
+endif
+
+ifeq ($(CONFIG_FEATURE_OTA_TEST), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_ota_test.o
+endif
+
+ifeq ($(CONFIG_FEATURE_ACTIVE_TOS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_active_tos.o
+endif
+
+ifeq ($(CONFIG_FEATURE_SAR_LIMITS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sar_limits.o
+endif
+
+ifeq ($(CONFIG_FEATURE_CONCURRENCY_MATRIX), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_concurrency_matrix.o
+endif
+
+ifeq ($(CONFIG_FEATURE_SAP_COND_CHAN_SWITCH), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sap_cond_chan_switch.o
+endif
+
+ifeq ($(CONFIG_FEATURE_P2P_LISTEN_OFFLOAD), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_p2p_listen_offload.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYSFS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs.o
+ifeq ($(CONFIG_WLAN_SYSFS_CHANNEL), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_channel.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_FW_MODE_CFG), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_fw_mode_config.o
+endif
+ifeq ($(CONFIG_WLAN_REASSOC), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_reassoc.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_STA_INFO), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_sta_info.o
+endif
+ifeq ($(CONFIG_WLAN_DEBUG_CRASH_INJECT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_crash_inject.o
+endif
+ifeq ($(CONFIG_FEATURE_UNIT_TEST_SUSPEND), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_suspend_resume.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_MEM_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_mem_stats.o
+endif
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_unit_test.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_modify_acl.o
+ifeq ($(CONFIG_WLAN_SYSFS_CONNECT_INFO), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_connect_info.o
+endif
+ifeq ($(CONFIG_WLAN_SCAN_DISABLE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_scan_disable.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_DCM), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dcm.o
+endif
+ifeq ($(CONFIG_WLAN_WOW_ITO), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_wow_ito.o
+endif
+ifeq ($(CONFIG_WLAN_WOWL_ADD_PTRN), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_wowl_add_ptrn.o
+endif
+ifeq ($(CONFIG_WLAN_WOWL_DEL_PTRN), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_wowl_del_ptrn.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_TX_STBC), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_tx_stbc.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_SCAN_CFG), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_scan_config.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_MONITOR_MODE_CHANNEL), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_monitor_mode_channel.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_RANGE_EXT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_range_ext.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_RADAR), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_radar.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_RTS_CTS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_rts_cts.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_HE_BSS_COLOR), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_he_bss_color.o
+endif
+ifeq ($(CONFIG_WLAN_TXRX_FW_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_txrx_fw_stats.o
+endif
+ifeq ($(CONFIG_WLAN_TXRX_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_txrx_stats.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_DP_TRACE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dp_trace.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_stats.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_TDLS_PEERS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_tdls_peers.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_TEMPERATURE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_temperature.o
+endif
+ifeq ($(CONFIG_WLAN_THERMAL_CFG), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_thermal_cfg.o
+endif
+ifeq ($(CONFIG_FEATURE_MOTION_DETECTION), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_motion_detection.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_WLAN_DBG), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_wlan_dbg.o
+endif
+ifeq ($(CONFIG_WLAN_TXRX_FW_ST_RST), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_txrx_fw_st_rst.o
+endif
+ifeq ($(CONFIG_WLAN_GTX_BW_MASK), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_gtx_bw_mask.o
+endif
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_ipa.o
+endif
+ifeq ($(CONFIG_REMOVE_PKT_LOG), n)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_pktlog.o
+endif
+ifeq ($(CONFIG_WLAN_DL_MODES), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dl_modes.o
+endif
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_policy_mgr.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dp_aggregation.o
+ifeq ($(CONFIG_DP_SWLM), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_swlm.o
+endif
+ifeq ($(CONFIG_WLAN_DUMP_IN_PROGRESS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dump_in_progress.o
+endif
+ifeq ($(CONFIG_FEATURE_SET), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_wifi_features.o
+endif
+ifeq ($(CONFIG_WLAN_BMISS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_bmiss.o
+endif
+ifeq ($(CONFIG_WLAN_FREQ_LIST), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_get_freq_for_pwr.o
+endif
+ifeq ($(CONFIG_WLAN_SYSFS_DP_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_txrx_stats_console.o
+endif
+
+ifeq ($(CONFIG_DP_PKT_ADD_TIMESTAMP), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_add_timestamp.o
+endif
+
+ifeq ($(CONFIG_DP_TRAFFIC_END_INDICATION), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dp_traffic_end_indication.o
+endif
+
+ifeq ($(CONFIG_DP_HW_TX_DELAY_STATS_ENABLE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dp_tx_delay_stats.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYSFS_EHT_RATE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_eht_rate.o
+endif
+
+ifeq ($(CONFIG_FEATURE_DIRECT_LINK), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_direct_link_ut_cmd.o
+endif
+
+ifeq ($(CONFIG_BUS_AUTO_SUSPEND), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_runtime_pm.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYSFS_LOG_BUFFER), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_log_buffer.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYSFS_DFSNOL), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_dfsnol.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYSFS_WDS_MODE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_wds_mode.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYSFS_ROAM_TRIGGER_BITMAP), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_roam_trigger_bitmap.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYSFS_RF_TEST_MODE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_rf_test_mode.o
+endif
+
+endif # CONFIG_WLAN_SYSFS
+
+ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_fw_state.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_COEX_CONFIG), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_coex_config.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_MPTA_HELPER), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_mpta_helper.o
+endif
+
+ifeq ($(CONFIG_WLAN_BCN_RECV_FEATURE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_bcn_recv.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_HW_CAPABILITY), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_hw_capability.o
+endif
+
+ifeq ($(CONFIG_FW_THERMAL_THROTTLE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_thermal.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_BTC_CHAIN_MODE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_btc_chain_mode.o
+endif
+
+ifeq ($(CONFIG_FEATURE_WLAN_TIME_SYNC_FTM), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_ftm_time_sync.o
+endif
+
+ifeq ($(CONFIG_WLAN_HANG_EVENT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_hang_event.o
+endif
+
+ifeq ($(CONFIG_WLAN_CFR_ENABLE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_cfr.o
+endif
+
+ifeq ($(CONFIG_FEATURE_GPIO_CFG),y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_gpio.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_MEDIUM_ASSESS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_medium_assess.o
+endif
+
+ifeq ($(CONFIG_WLAN_ENABLE_GPIO_WAKEUP),y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_gpio_wakeup.o
+endif
+
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_cm_connect.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_cm_disconnect.o
+
+
+ifeq ($(CONFIG_WLAN_BOOTUP_MARKER), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_bootup_marker.o
+endif
+
+ifeq ($(CONFIG_FEATURE_WLAN_CH_AVOID_EXT),y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_avoid_freq_ext.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_11BE_MLO), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_mlo.o
+endif
+
+
+ifeq ($(CONFIG_WLAN_FEATURE_MDNS_OFFLOAD),y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_mdns_offload.o
+endif
+
+ifeq ($(CONFIG_QCACLD_WLAN_CONNECTIVITY_DIAG_EVENT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_connectivity_logging.o
+else ifeq ($(CONFIG_QCACLD_WLAN_CONNECTIVITY_LOGGING), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_connectivity_logging.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_MCC_QUOTA), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_mcc_quota.o
+endif
+
+ifeq ($(CONFIG_FEATURE_WDS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_wds.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_PEER_TXQ_FLUSH_CONF), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_peer_txq_flush.o
+endif
+
+ifeq ($(CONFIG_WIFI_POS_CONVERGED), y)
+ifeq ($(CONFIG_WIFI_POS_PASN), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_wifi_pos_pasn.o
+endif
+endif
+
+$(call add-wlan-objs,hdd,$(HDD_OBJS))
+
+###### OSIF_SYNC ########
+SYNC_DIR := os_if/sync
+SYNC_INC_DIR := $(SYNC_DIR)/inc
+SYNC_SRC_DIR := $(SYNC_DIR)/src
+
+SYNC_INC := \
+	-I$(WLAN_ROOT)/$(SYNC_INC_DIR) \
+	-I$(WLAN_ROOT)/$(SYNC_SRC_DIR) \
+
+SYNC_OBJS := \
+	$(SYNC_SRC_DIR)/osif_sync.o \
+	$(SYNC_SRC_DIR)/osif_driver_sync.o \
+	$(SYNC_SRC_DIR)/osif_psoc_sync.o \
+	$(SYNC_SRC_DIR)/osif_vdev_sync.o \
+
+$(call add-wlan-objs,sync,$(SYNC_OBJS))
+
+########### Driver Synchronization Core (DSC) ###########
+DSC_DIR := components/dsc
+DSC_INC_DIR := $(DSC_DIR)/inc
+DSC_SRC_DIR := $(DSC_DIR)/src
+DSC_TEST_DIR := $(DSC_DIR)/test
+
+DSC_INC := \
+	-I$(WLAN_ROOT)/$(DSC_INC_DIR) \
+	-I$(WLAN_ROOT)/$(DSC_SRC_DIR) \
+	-I$(WLAN_ROOT)/$(DSC_TEST_DIR)
+
+DSC_OBJS := \
+	$(DSC_SRC_DIR)/__wlan_dsc.o \
+	$(DSC_SRC_DIR)/wlan_dsc_driver.o \
+	$(DSC_SRC_DIR)/wlan_dsc_psoc.o \
+	$(DSC_SRC_DIR)/wlan_dsc_vdev.o
+
+ifeq ($(CONFIG_DSC_TEST), y)
+	DSC_OBJS += $(DSC_TEST_DIR)/wlan_dsc_test.o
+endif
+
+$(call add-wlan-objs,dsc,$(DSC_OBJS))
+
+########### HOST DIAG LOG ###########
+HOST_DIAG_LOG_DIR :=	$(WLAN_COMMON_ROOT)/utils/host_diag_log
+
+HOST_DIAG_LOG_INC_DIR :=	$(HOST_DIAG_LOG_DIR)/inc
+HOST_DIAG_LOG_SRC_DIR :=	$(HOST_DIAG_LOG_DIR)/src
+
+HOST_DIAG_LOG_INC :=	-I$(WLAN_ROOT)/$(HOST_DIAG_LOG_INC_DIR) \
+			-I$(WLAN_ROOT)/$(HOST_DIAG_LOG_SRC_DIR)
+
+ifeq ($(CONFIG_WLAN_DIAG_VERSION), y)
+HOST_DIAG_LOG_OBJS +=	$(HOST_DIAG_LOG_SRC_DIR)/host_diag_log.o
+endif
+
+$(call add-wlan-objs,host_diag_log,$(HOST_DIAG_LOG_OBJS))
+
+############ EPPING ############
+EPPING_DIR :=	$(WLAN_COMMON_ROOT)/utils/epping
+EPPING_INC_DIR :=	$(EPPING_DIR)/inc
+EPPING_SRC_DIR :=	$(EPPING_DIR)/src
+
+EPPING_INC := 	-I$(WLAN_ROOT)/$(EPPING_INC_DIR)
+
+ifeq ($(CONFIG_FEATURE_EPPING), y)
+EPPING_OBJS := $(EPPING_SRC_DIR)/epping_main.o \
+		$(EPPING_SRC_DIR)/epping_txrx.o \
+		$(EPPING_SRC_DIR)/epping_tx.o \
+		$(EPPING_SRC_DIR)/epping_rx.o \
+		$(EPPING_SRC_DIR)/epping_helper.o
+endif
+
+$(call add-wlan-objs,epping,$(EPPING_OBJS))
+
+############ SYS ############
+CMN_SYS_DIR :=	$(WLAN_COMMON_ROOT)/utils/sys
+CMN_SYS_INC_DIR := 	$(CMN_SYS_DIR)
+CMN_SYS_INC :=	-I$(WLAN_ROOT)/$(CMN_SYS_INC_DIR)
+
+############ MAC ############
+MAC_DIR :=	core/mac
+MAC_INC_DIR :=	$(MAC_DIR)/inc
+MAC_SRC_DIR :=	$(MAC_DIR)/src
+
+MAC_INC := 	-I$(WLAN_ROOT)/$(MAC_INC_DIR) \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/dph \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/include \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/include \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/lim \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/nan
+
+MAC_DPH_OBJS :=	$(MAC_SRC_DIR)/dph/dph_hash_table.o
+
+ifeq ($(KERNEL_SUPPORTS_NESTED_COMPOSITES),y)
+MAC_LIM_OBJS := $(MAC_SRC_DIR)/pe/lim/lim_aid_mgmt.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_admit_control.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_api.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_assoc_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_ft.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_link_monitoring_algo.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_action_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_assoc_req_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_assoc_rsp_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_auth_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_beacon_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_cfg_updates.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_deauth_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_disassoc_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_message_queue.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_mlm_req_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_mlm_rsp_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_probe_req_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_probe_rsp_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_sme_req_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_prop_exts_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_scan_result_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_security_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_send_management_frames.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_send_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_send_sme_rsp_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_session.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_session_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_sme_req_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_timer_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_trace.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_utils.o
+else
+#composite of all of the above is in lim.c
+MAC_LIM_OBJS := $(MAC_SRC_DIR)/pe/lim/lim.o
+endif
+
+ifeq ($(CONFIG_QCOM_TDLS), y)
+MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_process_tdls.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_FILS), y)
+MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_process_fils.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
+MAC_NDP_OBJS += $(MAC_SRC_DIR)/pe/nan/nan_datapath.o
+endif
+
+ifeq ($(CONFIG_QCACLD_WLAN_LFR2), y)
+	MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_process_mlm_host_roam.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_send_frames_host_roam.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_roam_timer_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_ft_preauth.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_reassoc_utils.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_11BE_MLO), y)
+	MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_mlo.o
+endif
+
+MAC_SCH_OBJS := $(MAC_SRC_DIR)/pe/sch/sch_api.o \
+		$(MAC_SRC_DIR)/pe/sch/sch_beacon_gen.o \
+		$(MAC_SRC_DIR)/pe/sch/sch_beacon_process.o \
+		$(MAC_SRC_DIR)/pe/sch/sch_message.o
+
+MAC_RRM_OBJS :=	$(MAC_SRC_DIR)/pe/rrm/rrm_api.o
+
+MAC_OBJS := 	$(MAC_CFG_OBJS) \
+		$(MAC_DPH_OBJS) \
+		$(MAC_LIM_OBJS) \
+		$(MAC_SCH_OBJS) \
+		$(MAC_RRM_OBJS) \
+		$(MAC_NDP_OBJS)
+
+$(call add-wlan-objs,mac,$(MAC_OBJS))
+
+############ SAP ############
+SAP_DIR :=	core/sap
+SAP_INC_DIR :=	$(SAP_DIR)/inc
+SAP_SRC_DIR :=	$(SAP_DIR)/src
+
+SAP_INC := 	-I$(WLAN_ROOT)/$(SAP_INC_DIR) \
+		-I$(WLAN_ROOT)/$(SAP_SRC_DIR)
+
+SAP_OBJS :=	$(SAP_SRC_DIR)/sap_api_link_cntl.o \
+		$(SAP_SRC_DIR)/sap_ch_select.o \
+		$(SAP_SRC_DIR)/sap_fsm.o \
+		$(SAP_SRC_DIR)/sap_module.o
+
+$(call add-wlan-objs,sap,$(SAP_OBJS))
+
+############ CFG ############
+CFG_REL_DIR := $(WLAN_COMMON_ROOT)/cfg
+CFG_DIR := $(WLAN_ROOT)/$(CFG_REL_DIR)
+CFG_INC := \
+	-I$(CFG_DIR)/inc \
+	-I$(CFG_DIR)/dispatcher/inc \
+	-I$(WLAN_ROOT)/components/cfg
+CFG_OBJS := \
+	$(CFG_REL_DIR)/src/cfg.o
+
+$(call add-wlan-objs,cfg,$(CFG_OBJS))
+
+############ DFS ############
+DFS_DIR :=     $(WLAN_COMMON_ROOT)/umac/dfs
+DFS_CORE_INC_DIR := $(DFS_DIR)/core/inc
+DFS_CORE_SRC_DIR := $(DFS_DIR)/core/src
+
+DFS_DISP_INC_DIR := $(DFS_DIR)/dispatcher/inc
+DFS_DISP_SRC_DIR := $(DFS_DIR)/dispatcher/src
+DFS_TARGET_INC_DIR := $(WLAN_COMMON_ROOT)/target_if/dfs/inc
+DFS_CMN_SERVICES_INC_DIR := $(WLAN_COMMON_ROOT)/umac/cmn_services/dfs/inc
+
+DFS_INC :=	-I$(WLAN_ROOT)/$(DFS_DISP_INC_DIR) \
+		-I$(WLAN_ROOT)/$(DFS_TARGET_INC_DIR) \
+		-I$(WLAN_ROOT)/$(DFS_CMN_SERVICES_INC_DIR)
+
+ifeq ($(CONFIG_WLAN_DFS_MASTER_ENABLE), y)
+
+DFS_OBJS :=	$(DFS_CORE_SRC_DIR)/misc/dfs.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_nol.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_random_chan_sel.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_process_radar_found_ind.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_init_deinit_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_lmac_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_mlme_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_tgt_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_ucfg_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_tgt_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_utils_api.o \
+		$(WLAN_COMMON_ROOT)/target_if/dfs/src/target_if_dfs.o
+
+ifeq ($(CONFIG_WLAN_FEATURE_DFS_OFFLOAD), y)
+DFS_OBJS +=	$(WLAN_COMMON_ROOT)/target_if/dfs/src/target_if_dfs_full_offload.o
+else
+DFS_OBJS +=	$(WLAN_COMMON_ROOT)/target_if/dfs/src/target_if_dfs_partial_offload.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_fcc_bin5.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_bindetects.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_debug.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_init.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_misc.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_phyerr_tlv.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_process_phyerr.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_process_radarevent.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_staggered.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_radar.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_partial_offload_radar.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_filter_init.o
+endif
+endif
+
+$(call add-wlan-objs,dfs,$(DFS_OBJS))
+
+############ SME ############
+SME_DIR :=	core/sme
+SME_INC_DIR :=	$(SME_DIR)/inc
+SME_SRC_DIR :=	$(SME_DIR)/src
+
+SME_INC := 	-I$(WLAN_ROOT)/$(SME_INC_DIR) \
+		-I$(WLAN_ROOT)/$(SME_SRC_DIR)/csr \
+		-I$(WLAN_ROOT)/$(SME_SRC_DIR)/qos \
+		-I$(WLAN_ROOT)/$(SME_SRC_DIR)/common \
+		-I$(WLAN_ROOT)/$(SME_SRC_DIR)/rrm \
+		-I$(WLAN_ROOT)/$(SME_SRC_DIR)/nan
+
+ifeq ($(KERNEL_SUPPORTS_NESTED_COMPOSITES),y)
+SME_CSR_OBJS := $(SME_SRC_DIR)/csr/csr_api_roam.o \
+		$(SME_SRC_DIR)/csr/csr_api_scan.o \
+		$(SME_SRC_DIR)/csr/csr_cmd_process.o \
+		$(SME_SRC_DIR)/csr/csr_link_list.o \
+		$(SME_SRC_DIR)/csr/csr_util.o \
+
+SME_QOS_OBJS := $(SME_SRC_DIR)/qos/sme_qos.o
+
+SME_CMN_OBJS := $(SME_SRC_DIR)/common/sme_api.o \
+		$(SME_SRC_DIR)/common/sme_power_save.o \
+		$(SME_SRC_DIR)/common/sme_trace.o
+
+SME_RRM_OBJS := $(SME_SRC_DIR)/rrm/sme_rrm.o
+
+ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
+SME_NDP_OBJS += $(SME_SRC_DIR)/nan/nan_datapath_api.o
+endif
+
+SME_OBJS :=	$(SME_CMN_OBJS) \
+		$(SME_CSR_OBJS) \
+		$(SME_QOS_OBJS) \
+		$(SME_RRM_OBJS) \
+		$(SME_NAN_OBJS) \
+		$(SME_NDP_OBJS)
+else # KERNEL_SUPPORTS_NESTED_COMPOSITES
+SME_OBJS := $(SME_SRC_DIR)/sme.o
+endif
+$(call add-wlan-objs,sme,$(SME_OBJS))
+
+############ NLINK ############
+NLINK_DIR     :=	$(WLAN_COMMON_ROOT)/utils/nlink
+NLINK_INC_DIR :=	$(NLINK_DIR)/inc
+NLINK_SRC_DIR :=	$(NLINK_DIR)/src
+
+NLINK_INC     := 	-I$(WLAN_ROOT)/$(NLINK_INC_DIR)
+NLINK_OBJS    :=	$(NLINK_SRC_DIR)/wlan_nlink_srv.o
+
+$(call add-wlan-objs,nlink,$(NLINK_OBJS))
+
+############ PTT ############
+PTT_DIR     :=	$(WLAN_COMMON_ROOT)/utils/ptt
+PTT_INC_DIR :=	$(PTT_DIR)/inc
+PTT_SRC_DIR :=	$(PTT_DIR)/src
+
+PTT_INC     := 	-I$(WLAN_ROOT)/$(PTT_INC_DIR)
+PTT_OBJS    :=	$(PTT_SRC_DIR)/wlan_ptt_sock_svc.o
+
+$(call add-wlan-objs,ptt,$(PTT_OBJS))
+
+############ WLAN_LOGGING ############
+WLAN_LOGGING_DIR     :=	$(WLAN_COMMON_ROOT)/utils/logging
+WLAN_LOGGING_INC_DIR :=	$(WLAN_LOGGING_DIR)/inc
+WLAN_LOGGING_SRC_DIR :=	$(WLAN_LOGGING_DIR)/src
+
+WLAN_LOGGING_INC     := -I$(WLAN_ROOT)/$(WLAN_LOGGING_INC_DIR)
+WLAN_LOGGING_OBJS    := $(WLAN_LOGGING_SRC_DIR)/wlan_logging_sock_svc.o \
+		$(WLAN_LOGGING_SRC_DIR)/wlan_roam_debug.o
+
+$(call add-wlan-objs,wlan_logging,$(WLAN_LOGGING_OBJS))
+
+############ SYS ############
+SYS_DIR :=	core/mac/src/sys
+
+SYS_INC := 	-I$(WLAN_ROOT)/$(SYS_DIR)/common/inc \
+		-I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/platform/inc \
+		-I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/system/inc \
+		-I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/utils/inc
+
+SYS_COMMON_SRC_DIR := $(SYS_DIR)/common/src
+SYS_LEGACY_SRC_DIR := $(SYS_DIR)/legacy/src
+SYS_OBJS :=	$(SYS_COMMON_SRC_DIR)/wlan_qct_sys.o \
+		$(SYS_LEGACY_SRC_DIR)/platform/src/sys_wrapper.o \
+		$(SYS_LEGACY_SRC_DIR)/system/src/mac_init_api.o \
+		$(SYS_LEGACY_SRC_DIR)/system/src/sys_entry_func.o \
+		$(SYS_LEGACY_SRC_DIR)/utils/src/dot11f.o \
+		$(SYS_LEGACY_SRC_DIR)/utils/src/mac_trace.o \
+		$(SYS_LEGACY_SRC_DIR)/utils/src/parser_api.o \
+		$(SYS_LEGACY_SRC_DIR)/utils/src/utils_parser.o
+
+$(call add-wlan-objs,sys,$(SYS_OBJS))
+
+############ Qcacld WMI ###################
+WMI_DIR := components/wmi
+
+CLD_WMI_INC  :=	-I$(WLAN_ROOT)/$(WMI_DIR)/inc
+
+ifeq ($(CONFIG_WMI_ROAM_SUPPORT), y)
+CLD_WMI_ROAM_OBJS +=	$(WMI_DIR)/src/wmi_unified_roam_tlv.o \
+			$(WMI_DIR)/src/wmi_unified_roam_api.o
+endif
+
+ifeq ($(CONFIG_CP_STATS), y)
+CLD_WMI_MC_CP_STATS_OBJS :=	$(WMI_DIR)/src/wmi_unified_mc_cp_stats_tlv.o \
+				$(WMI_DIR)/src/wmi_unified_mc_cp_stats_api.o
+endif
+
+ifeq ($(CONFIG_QCA_TARGET_IF_MLME), y)
+CLD_WMI_MLME_OBJS += $(WMI_DIR)/src/wmi_unified_mlme_tlv.o \
+		     $(WMI_DIR)/src/wmi_unified_mlme_api.o
+endif
+
+CLD_WMI_OBJS :=	$(CLD_WMI_ROAM_OBJS) \
+		$(CLD_WMI_MC_CP_STATS_OBJS) \
+		$(CLD_WMI_MLME_OBJS)
+
+$(call add-wlan-objs,cld_wmi,$(CLD_WMI_OBJS))
+
+############ Qca-wifi-host-cmn ############
+QDF_OS_DIR :=	qdf
+QDF_OS_INC_DIR := $(QDF_OS_DIR)/inc
+QDF_OS_SRC_DIR := $(QDF_OS_DIR)/src
+QDF_OS_LINUX_SRC_DIR := $(QDF_OS_DIR)/linux/src
+QDF_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(QDF_OS_SRC_DIR)
+QDF_LINUX_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(QDF_OS_LINUX_SRC_DIR)
+QDF_TEST_DIR := $(QDF_OS_DIR)/test
+QDF_TEST_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(QDF_TEST_DIR)
+
+QDF_INC := \
+	-I$(WLAN_COMMON_INC)/$(QDF_OS_INC_DIR) \
+	-I$(WLAN_COMMON_INC)/$(QDF_OS_LINUX_SRC_DIR) \
+	-I$(WLAN_COMMON_INC)/$(QDF_TEST_DIR)
+
+QDF_OBJS := \
+	$(QDF_LINUX_OBJ_DIR)/qdf_crypto.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_defer.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_delayed_work.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_event.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_file.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_func_tracker.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_idr.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_list.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_lock.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_mc_timer.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_mem.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_nbuf.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_periodic_work.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_status.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_threads.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_trace.o \
+	$(QDF_LINUX_OBJ_DIR)/qdf_nbuf_frag.o \
+	$(QDF_OBJ_DIR)/qdf_flex_mem.o \
+	$(QDF_OBJ_DIR)/qdf_parse.o \
+	$(QDF_OBJ_DIR)/qdf_platform.o \
+	$(QDF_OBJ_DIR)/qdf_str.o \
+	$(QDF_OBJ_DIR)/qdf_talloc.o \
+	$(QDF_OBJ_DIR)/qdf_types.o \
+
+ifeq ($(CONFIG_CNSS2_SSR_DRIVER_DUMP), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_ssr_driver_dump.o
+endif
+
+ifeq ($(CONFIG_WLAN_DEBUGFS), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_debugfs.o
+endif
+
+ifeq ($(CONFIG_WLAN_TRACEPOINTS), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_tracepoint.o
+endif
+
+ifeq ($(CONFIG_WLAN_STREAMFS), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_streamfs.o
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_ipa.o
+endif
+
+ifeq ($(CONFIG_DP_PKT_ADD_TIMESTAMP), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_pkt_add_timestamp.o
+endif
+
+# enable CPU hotplug support if SMP is enabled
+ifeq ($(CONFIG_SMP), y)
+	QDF_OBJS += $(QDF_OBJ_DIR)/qdf_cpuhp.o
+	QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_cpuhp.o
+endif
+
+ifeq ($(CONFIG_LEAK_DETECTION), y)
+	QDF_OBJS += $(QDF_OBJ_DIR)/qdf_debug_domain.o
+	QDF_OBJS += $(QDF_OBJ_DIR)/qdf_tracker.o
+endif
+
+ifeq ($(CONFIG_WLAN_HANG_EVENT), y)
+	QDF_OBJS += $(QDF_OBJ_DIR)/qdf_notifier.o
+endif
+
+ifeq ($(CONFIG_QDF_TEST), y)
+	QDF_OBJS += $(QDF_TEST_OBJ_DIR)/qdf_delayed_work_test.o
+	QDF_OBJS += $(QDF_TEST_OBJ_DIR)/qdf_hashtable_test.o
+	QDF_OBJS += $(QDF_TEST_OBJ_DIR)/qdf_periodic_work_test.o
+	QDF_OBJS += $(QDF_TEST_OBJ_DIR)/qdf_ptr_hash_test.o
+	QDF_OBJS += $(QDF_TEST_OBJ_DIR)/qdf_slist_test.o
+	QDF_OBJS += $(QDF_TEST_OBJ_DIR)/qdf_talloc_test.o
+	QDF_OBJS += $(QDF_TEST_OBJ_DIR)/qdf_tracker_test.o
+	QDF_OBJS += $(QDF_TEST_OBJ_DIR)/qdf_types_test.o
+endif
+
+ifeq ($(CONFIG_WLAN_HANG_EVENT), y)
+	QDF_OBJS += $(QDF_OBJ_DIR)/qdf_hang_event_notifier.o
+endif
+
+ifeq ($(CONFIG_WLAN_LRO), y)
+QDF_OBJS +=     $(QDF_LINUX_OBJ_DIR)/qdf_lro.o
+endif
+
+$(call add-wlan-objs,qdf,$(QDF_OBJS))
+
+############ WBUFF ############
+WBUFF_OS_DIR :=	wbuff
+WBUFF_OS_INC_DIR := $(WBUFF_OS_DIR)/inc
+WBUFF_OS_SRC_DIR := $(WBUFF_OS_DIR)/src
+WBUFF_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(WBUFF_OS_SRC_DIR)
+
+WBUFF_INC :=	-I$(WLAN_COMMON_INC)/$(WBUFF_OS_INC_DIR) \
+
+ifeq ($(CONFIG_WLAN_WBUFF), y)
+WBUFF_OBJS += 	$(WBUFF_OBJ_DIR)/wbuff.o
+endif
+
+$(call add-wlan-objs,wbuff,$(WBUFF_OBJS))
+
+##########QAL #######
+QAL_OS_DIR :=	qal
+QAL_OS_INC_DIR := $(QAL_OS_DIR)/inc
+QAL_OS_LINUX_SRC_DIR := $(QAL_OS_DIR)/linux/src
+
+QAL_INC :=	-I$(WLAN_COMMON_INC)/$(QAL_OS_INC_DIR) \
+		-I$(WLAN_COMMON_INC)/$(QAL_OS_LINUX_SRC_DIR)
+
+
+##########OS_IF #######
+OS_IF_DIR := $(WLAN_COMMON_ROOT)/os_if
+
+OS_IF_INC += -I$(WLAN_COMMON_INC)/os_if/linux \
+            -I$(WLAN_COMMON_INC)/os_if/linux/scan/inc \
+            -I$(WLAN_COMMON_INC)/os_if/linux/spectral/inc \
+            -I$(WLAN_COMMON_INC)/os_if/linux/crypto/inc \
+            -I$(WLAN_COMMON_INC)/os_if/linux/mlme/inc \
+            -I$(WLAN_COMMON_INC)/os_if/linux/gpio/inc
+
+OS_IF_OBJ += $(OS_IF_DIR)/linux/wlan_osif_request_manager.o \
+	     $(OS_IF_DIR)/linux/crypto/src/wlan_nl_to_crypto_params.o \
+	     $(OS_IF_DIR)/linux/mlme/src/osif_cm_util.o \
+	     $(OS_IF_DIR)/linux/mlme/src/osif_cm_connect_rsp.o \
+	     $(OS_IF_DIR)/linux/mlme/src/osif_cm_disconnect_rsp.o \
+	     $(OS_IF_DIR)/linux/mlme/src/osif_cm_req.o \
+	     $(OS_IF_DIR)/linux/mlme/src/osif_cm_roam_rsp.o \
+	     $(OS_IF_DIR)/linux/mlme/src/osif_vdev_mgr_util.o
+
+OS_IF_OBJ += $(OS_IF_DIR)/linux/crypto/src/wlan_cfg80211_crypto.o
+
+$(call add-wlan-objs,os_if,$(OS_IF_OBJ))
+
+############ UMAC_DISP ############
+UMAC_DISP_DIR := umac/global_umac_dispatcher/lmac_if
+UMAC_DISP_INC_DIR := $(UMAC_DISP_DIR)/inc
+UMAC_DISP_SRC_DIR := $(UMAC_DISP_DIR)/src
+UMAC_DISP_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_DISP_SRC_DIR)
+
+UMAC_DISP_INC := -I$(WLAN_COMMON_INC)/$(UMAC_DISP_INC_DIR)
+
+UMAC_DISP_OBJS := $(UMAC_DISP_OBJ_DIR)/wlan_lmac_if.o
+
+$(call add-wlan-objs,umac_disp,$(UMAC_DISP_OBJS))
+
+############# UMAC_SCAN ############
+UMAC_SCAN_DIR := umac/scan
+UMAC_SCAN_DISP_INC_DIR := $(UMAC_SCAN_DIR)/dispatcher/inc
+UMAC_SCAN_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SCAN_DIR)/core/src
+UMAC_SCAN_DISP_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SCAN_DIR)/dispatcher/src
+UMAC_TARGET_SCAN_INC := -I$(WLAN_COMMON_INC)/target_if/scan/inc
+
+UMAC_SCAN_INC := -I$(WLAN_COMMON_INC)/$(UMAC_SCAN_DISP_INC_DIR)
+UMAC_SCAN_OBJS := $(UMAC_SCAN_CORE_DIR)/wlan_scan_cache_db.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_11d.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_filter.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_main.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_manager.o \
+		$(UMAC_SCAN_DISP_DIR)/wlan_scan_tgt_api.o \
+		$(UMAC_SCAN_DISP_DIR)/wlan_scan_ucfg_api.o \
+		$(UMAC_SCAN_DISP_DIR)/wlan_scan_api.o \
+		$(UMAC_SCAN_DISP_DIR)/wlan_scan_utils_api.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/scan/src/wlan_cfg80211_scan.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/wlan_cfg80211.o \
+		$(WLAN_COMMON_ROOT)/target_if/scan/src/target_if_scan.o
+
+ifeq ($(CONFIG_FEATURE_WLAN_EXTSCAN), y)
+UMAC_SCAN_OBJS += $(UMAC_SCAN_DISP_DIR)/wlan_extscan_api.o
+endif
+
+ifeq ($(CONFIG_BAND_6GHZ), y)
+UMAC_SCAN_OBJS += $(UMAC_SCAN_CORE_DIR)/wlan_scan_manager_6ghz.o
+endif
+
+$(call add-wlan-objs,umac_scan,$(UMAC_SCAN_OBJS))
+
+############# UMAC_SPECTRAL_SCAN ############
+UMAC_SPECTRAL_DIR := spectral
+UMAC_SPECTRAL_DISP_INC_DIR := $(UMAC_SPECTRAL_DIR)/dispatcher/inc
+UMAC_SPECTRAL_CORE_INC_DIR := $(UMAC_SPECTRAL_DIR)/core
+UMAC_SPECTRAL_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SPECTRAL_DIR)/core
+UMAC_SPECTRAL_DISP_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SPECTRAL_DIR)/dispatcher/src
+UMAC_TARGET_SPECTRAL_INC := -I$(WLAN_COMMON_INC)/target_if/spectral
+
+UMAC_SPECTRAL_INC := -I$(WLAN_COMMON_INC)/$(UMAC_SPECTRAL_DISP_INC_DIR) \
+			-I$(WLAN_COMMON_INC)/$(UMAC_SPECTRAL_CORE_INC_DIR) \
+			-I$(WLAN_COMMON_INC)/target_if/direct_buf_rx/inc
+ifeq ($(CONFIG_WLAN_CONV_SPECTRAL_ENABLE),y)
+UMAC_SPECTRAL_OBJS := $(UMAC_SPECTRAL_CORE_DIR)/spectral_offload.o \
+		$(UMAC_SPECTRAL_CORE_DIR)/spectral_common.o \
+		$(UMAC_SPECTRAL_DISP_DIR)/wlan_spectral_ucfg_api.o \
+		$(UMAC_SPECTRAL_DISP_DIR)/wlan_spectral_utils_api.o \
+		$(UMAC_SPECTRAL_DISP_DIR)/wlan_spectral_tgt_api.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/spectral/src/wlan_cfg80211_spectral.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/spectral/src/os_if_spectral_netlink.o \
+		$(WLAN_COMMON_ROOT)/target_if/spectral/target_if_spectral_netlink.o \
+		$(WLAN_COMMON_ROOT)/target_if/spectral/target_if_spectral_phyerr.o \
+		$(WLAN_COMMON_ROOT)/target_if/spectral/target_if_spectral.o \
+		$(WLAN_COMMON_ROOT)/target_if/spectral/target_if_spectral_sim.o
+endif
+
+$(call add-wlan-objs,umac_spectral,$(UMAC_SPECTRAL_OBJS))
+
+############# WLAN_CFR ############
+WLAN_CFR_DIR := umac/cfr
+WLAN_CFR_DISP_INC_DIR := $(WLAN_CFR_DIR)/dispatcher/inc
+WLAN_CFR_CORE_INC_DIR := $(WLAN_CFR_DIR)/core/inc
+WLAN_CFR_CORE_DIR := $(WLAN_COMMON_ROOT)/$(WLAN_CFR_DIR)/core/src
+WLAN_CFR_DISP_DIR := $(WLAN_COMMON_ROOT)/$(WLAN_CFR_DIR)/dispatcher/src
+WLAN_CFR_TARGET_INC_DIR := target_if/cfr/inc
+
+WLAN_CFR_INC := -I$(WLAN_COMMON_INC)/$(WLAN_CFR_DISP_INC_DIR) \
+			-I$(WLAN_COMMON_INC)/$(WLAN_CFR_CORE_INC_DIR) \
+			-I$(WLAN_COMMON_INC)/$(WLAN_CFR_TARGET_INC_DIR)
+ifeq ($(CONFIG_WLAN_CFR_ENABLE),y)
+WLAN_CFR_OBJS := $(WLAN_CFR_CORE_DIR)/cfr_common.o \
+                $(WLAN_CFR_DISP_DIR)/wlan_cfr_tgt_api.o \
+                $(WLAN_CFR_DISP_DIR)/wlan_cfr_ucfg_api.o \
+                $(WLAN_CFR_DISP_DIR)/wlan_cfr_utils_api.o \
+		$(WLAN_COMMON_ROOT)/target_if/cfr/src/target_if_cfr.o \
+		$(WLAN_COMMON_ROOT)/target_if/cfr/src/target_if_cfr_6490.o
+ifeq ($(CONFIG_WLAN_ENH_CFR_ENABLE),y)
+WLAN_CFR_OBJS += $(WLAN_COMMON_ROOT)/target_if/cfr/src/target_if_cfr_enh.o
+endif
+ifeq ($(CONFIG_WLAN_CFR_ADRASTEA),y)
+WLAN_CFR_OBJS += $(WLAN_COMMON_ROOT)/target_if/cfr/src/target_if_cfr_adrastea.o
+endif
+ifeq ($(CONFIG_WLAN_CFR_DBR),y)
+WLAN_CFR_OBJS += $(WLAN_COMMON_ROOT)/target_if/cfr/src/target_if_cfr_dbr.o
+endif
+endif
+
+$(call add-wlan-objs,wlan_cfr,$(WLAN_CFR_OBJS))
+
+############# GPIO_CFG ############
+UMAC_GPIO_DIR := gpio
+UMAC_GPIO_DISP_INC_DIR := $(UMAC_GPIO_DIR)/dispatcher/inc
+UMAC_GPIO_CORE_INC_DIR := $(UMAC_GPIO_DIR)/core/inc
+UMAC_GPIO_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_GPIO_DIR)/core/src
+UMAC_GPIO_DISP_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_GPIO_DIR)/dispatcher/src
+UMAC_TARGET_GPIO_INC := -I$(WLAN_COMMON_INC)/target_if/gpio
+
+UMAC_GPIO_INC := -I$(WLAN_COMMON_INC)/$(UMAC_GPIO_DISP_INC_DIR) \
+			-I$(WLAN_COMMON_INC)/$(UMAC_GPIO_CORE_INC_DIR)
+
+ifeq ($(CONFIG_FEATURE_GPIO_CFG),y)
+UMAC_GPIO_OBJS := $(UMAC_GPIO_DISP_DIR)/wlan_gpio_tgt_api.o \
+		$(UMAC_GPIO_DISP_DIR)/wlan_gpio_ucfg_api.o \
+		$(UMAC_GPIO_CORE_DIR)/wlan_gpio_api.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/gpio/src/wlan_cfg80211_gpio.o \
+		$(WLAN_COMMON_ROOT)/target_if/gpio/target_if_gpio.o
+endif
+
+$(call add-wlan-objs,umac_gpio,$(UMAC_GPIO_OBJS))
+
+############# UMAC_GREEN_AP ############
+UMAC_GREEN_AP_DIR := umac/green_ap
+UMAC_GREEN_AP_DISP_INC_DIR := $(UMAC_GREEN_AP_DIR)/dispatcher/inc
+UMAC_GREEN_AP_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_GREEN_AP_DIR)/core/src
+UMAC_GREEN_AP_DISP_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_GREEN_AP_DIR)/dispatcher/src
+UMAC_TARGET_GREEN_AP_INC := -I$(WLAN_COMMON_INC)/target_if/green_ap/inc
+
+UMAC_GREEN_AP_INC := -I$(WLAN_COMMON_INC)/$(UMAC_GREEN_AP_DISP_INC_DIR)
+
+ifeq ($(CONFIG_QCACLD_FEATURE_GREEN_AP), y)
+UMAC_GREEN_AP_OBJS := $(UMAC_GREEN_AP_CORE_DIR)/wlan_green_ap_main.o \
+		$(UMAC_GREEN_AP_DISP_DIR)/wlan_green_ap_api.o \
+                $(UMAC_GREEN_AP_DISP_DIR)/wlan_green_ap_ucfg_api.o \
+                $(WLAN_COMMON_ROOT)/target_if/green_ap/src/target_if_green_ap.o
+endif
+
+$(call add-wlan-objs,umac_green_ap,$(UMAC_GREEN_AP_OBJS))
+
+############# WLAN_CONV_CRYPTO_SUPPORTED ############
+UMAC_CRYPTO_DIR := umac/cmn_services/crypto
+UMAC_CRYPTO_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_CRYPTO_DIR)/src
+UMAC_CRYPTO_INC := -I$(WLAN_COMMON_INC)/$(UMAC_CRYPTO_DIR)/inc \
+		-I$(WLAN_COMMON_INC)/$(UMAC_CRYPTO_DIR)/src
+
+UMAC_CRYPTO_OBJS := $(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_global_api.o \
+		$(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_ucfg_api.o \
+		$(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_main.o \
+		$(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_obj_mgr.o \
+		$(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_param_handling.o
+
+$(call add-wlan-objs,umac_crypto,$(UMAC_CRYPTO_OBJS))
+
+############# FTM CORE ############
+FTM_CORE_DIR := ftm
+TARGET_IF_FTM_DIR := target_if/ftm
+OS_IF_LINUX_FTM_DIR := os_if/linux/ftm
+
+FTM_CORE_SRC := $(WLAN_COMMON_ROOT)/$(FTM_CORE_DIR)/core/src
+FTM_DISP_SRC := $(WLAN_COMMON_ROOT)/$(FTM_CORE_DIR)/dispatcher/src
+TARGET_IF_FTM_SRC := $(WLAN_COMMON_ROOT)/$(TARGET_IF_FTM_DIR)/src
+OS_IF_FTM_SRC := $(WLAN_COMMON_ROOT)/$(OS_IF_LINUX_FTM_DIR)/src
+
+FTM_CORE_INC := $(WLAN_COMMON_INC)/$(FTM_CORE_DIR)/core/src
+FTM_DISP_INC := $(WLAN_COMMON_INC)/$(FTM_CORE_DIR)/dispatcher/inc
+TARGET_IF_FTM_INC := $(WLAN_COMMON_INC)/$(TARGET_IF_FTM_DIR)/inc
+OS_IF_FTM_INC := $(WLAN_COMMON_INC)/$(OS_IF_LINUX_FTM_DIR)/inc
+
+FTM_INC := -I$(FTM_DISP_INC)	\
+	   -I$(FTM_CORE_INC)	\
+	   -I$(OS_IF_FTM_INC)	\
+	   -I$(TARGET_IF_FTM_INC)
+
+ifeq ($(CONFIG_QCA_WIFI_FTM), y)
+FTM_OBJS := $(FTM_DISP_SRC)/wlan_ftm_init_deinit.o \
+	    $(FTM_DISP_SRC)/wlan_ftm_ucfg_api.o \
+	    $(FTM_CORE_SRC)/wlan_ftm_svc.o \
+	    $(TARGET_IF_FTM_SRC)/target_if_ftm.o
+
+ifeq ($(QCA_WIFI_FTM_NL80211), y)
+FTM_OBJS += $(OS_IF_FTM_SRC)/wlan_cfg80211_ftm.o
+endif
+
+ifeq ($(CONFIG_LINUX_QCMBR), y)
+FTM_OBJS += $(OS_IF_FTM_SRC)/wlan_ioctl_ftm.o
+endif
+
+endif
+
+$(call add-wlan-objs,ftm,$(FTM_OBJS))
+
+############# UMAC_CMN_SERVICES ############
+UMAC_COMMON_INC := -I$(WLAN_COMMON_INC)/umac/cmn_services/cmn_defs/inc \
+		-I$(WLAN_COMMON_INC)/umac/cmn_services/utils/inc
+UMAC_COMMON_OBJS := $(WLAN_COMMON_ROOT)/umac/cmn_services/utils/src/wlan_utility.o
+
+$(call add-wlan-objs,umac_common,$(UMAC_COMMON_OBJS))
+
+############ CDS (Connectivity driver services) ############
+CDS_DIR :=	core/cds
+CDS_INC_DIR :=	$(CDS_DIR)/inc
+CDS_SRC_DIR :=	$(CDS_DIR)/src
+
+CDS_INC := 	-I$(WLAN_ROOT)/$(CDS_INC_DIR) \
+		-I$(WLAN_ROOT)/$(CDS_SRC_DIR)
+
+CDS_OBJS :=	$(CDS_SRC_DIR)/cds_api.o \
+		$(CDS_SRC_DIR)/cds_reg_service.o \
+		$(CDS_SRC_DIR)/cds_packet.o \
+		$(CDS_SRC_DIR)/cds_regdomain.o \
+		$(CDS_SRC_DIR)/cds_sched.o \
+		$(CDS_SRC_DIR)/cds_utils.o
+
+$(call add-wlan-objs,cds,$(CDS_OBJS))
+
+###### UMAC OBJMGR ########
+UMAC_OBJMGR_DIR := $(WLAN_COMMON_ROOT)/umac/cmn_services/obj_mgr
+
+UMAC_OBJMGR_INC := -I$(WLAN_COMMON_INC)/umac/cmn_services/obj_mgr/inc \
+		-I$(WLAN_COMMON_INC)/umac/cmn_services/obj_mgr/src \
+		-I$(WLAN_COMMON_INC)/umac/cmn_services/inc
+
+UMAC_OBJMGR_OBJS := $(UMAC_OBJMGR_DIR)/src/wlan_objmgr_global_obj.o \
+		$(UMAC_OBJMGR_DIR)/src/wlan_objmgr_pdev_obj.o \
+		$(UMAC_OBJMGR_DIR)/src/wlan_objmgr_peer_obj.o \
+		$(UMAC_OBJMGR_DIR)/src/wlan_objmgr_psoc_obj.o \
+		$(UMAC_OBJMGR_DIR)/src/wlan_objmgr_vdev_obj.o
+
+ifeq ($(CONFIG_WLAN_OBJMGR_DEBUG), y)
+UMAC_OBJMGR_OBJS += $(UMAC_OBJMGR_DIR)/src/wlan_objmgr_debug.o
+endif
+
+$(call add-wlan-objs,umac_objmgr,$(UMAC_OBJMGR_OBJS))
+
+###########  UMAC MGMT TXRX ##########
+UMAC_MGMT_TXRX_DIR := $(WLAN_COMMON_ROOT)/umac/cmn_services/mgmt_txrx
+
+UMAC_MGMT_TXRX_INC := -I$(WLAN_COMMON_INC)/umac/cmn_services/mgmt_txrx/dispatcher/inc \
+
+UMAC_MGMT_TXRX_OBJS := $(UMAC_MGMT_TXRX_DIR)/core/src/wlan_mgmt_txrx_main.o \
+	$(UMAC_MGMT_TXRX_DIR)/dispatcher/src/wlan_mgmt_txrx_utils_api.o \
+	$(UMAC_MGMT_TXRX_DIR)/dispatcher/src/wlan_mgmt_txrx_tgt_api.o
+
+$(call add-wlan-objs,umac_mgmt_txrx,$(UMAC_MGMT_TXRX_OBJS))
+
+###### UMAC INTERFACE_MGR ########
+UMAC_INTERFACE_MGR_COMP_DIR :=	components/cmn_services/interface_mgr
+UMAC_INTERFACE_MGR_CMN_DIR := $(WLAN_COMMON_ROOT)/umac/cmn_services/interface_mgr
+
+UMAC_INTERFACE_MGR_INC := -I$(WLAN_COMMON_INC)/umac/cmn_services/interface_mgr/inc \
+			 -I$(WLAN_ROOT)/components/cmn_services/interface_mgr/inc
+
+UMAC_INTERFACE_MGR_OBJS := $(UMAC_INTERFACE_MGR_CMN_DIR)/src/wlan_if_mgr_main.o \
+			  $(UMAC_INTERFACE_MGR_CMN_DIR)/src/wlan_if_mgr_core.o \
+			  $(UMAC_INTERFACE_MGR_COMP_DIR)/src/wlan_if_mgr_sta.o \
+			  $(UMAC_INTERFACE_MGR_COMP_DIR)/src/wlan_if_mgr_sap.o \
+			  $(UMAC_INTERFACE_MGR_COMP_DIR)/src/wlan_if_mgr_roam.o
+
+$(call add-wlan-objs,umac_ifmgr,$(UMAC_INTERFACE_MGR_OBJS))
+
+###### UMAC MLO_MGR ########
+UMAC_MLO_MGR_CMN_DIR :=	$(WLAN_COMMON_ROOT)/umac/mlo_mgr
+MLO_MGR_TARGET_IF_DIR := $(WLAN_COMMON_ROOT)/target_if/mlo_mgr
+
+UMAC_MLO_MGR_CLD_DIR := components/umac/mlme/mlo_mgr
+UMAC_MLO_MGR_CLD_INC := -I$(WLAN_ROOT)/$(UMAC_MLO_MGR_CLD_DIR)/inc \
+			-I$(WLAN_ROOT)/$(UMAC_MLO_MGR_CLD_DIR)/dispatcher/inc \
+
+UMAC_MLO_MGR_INC := -I$(WLAN_COMMON_INC)/umac/mlo_mgr/inc \
+		    -I$(WLAN_COMMON_INC)/target_if/mlo_mgr/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_11BE_MLO), y)
+UMAC_MLO_MGR_OBJS := $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_main.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_cmn.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_sta.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_op.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/utils_mlo.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_ap.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_peer_list.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_aid.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_peer.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_msgq.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_primary_umac.o \
+			  $(MLO_MGR_TARGET_IF_DIR)/src/target_if_mlo_mgr.o \
+			  $(UMAC_MLO_MGR_CLD_DIR)/src/wlan_mlo_link_force.o \
+			  $(UMAC_MLO_MGR_CLD_DIR)/src/wlan_mlo_mgr_roam.o \
+			  $(UMAC_MLO_MGR_CLD_DIR)/src/wlan_t2lm_api.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_t2lm.o \
+			  $(UMAC_MLO_MGR_CLD_DIR)/src/wlan_epcs_api.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_epcs.o \
+			  $(UMAC_MLO_MGR_CLD_DIR)/dispatcher/src/wlan_mlo_epcs_ucfg_api.o \
+			  $(UMAC_MLO_MGR_CMN_DIR)/src/wlan_mlo_mgr_link_switch.o \
+
+$(call add-wlan-objs,umac_mlomgr,$(UMAC_MLO_MGR_OBJS))
+endif
+########## POWER MANAGEMENT OFFLOADS (PMO) ##########
+PMO_DIR :=	components/pmo
+PMO_INC :=	-I$(WLAN_ROOT)/$(PMO_DIR)/core/inc \
+			-I$(WLAN_ROOT)/$(PMO_DIR)/dispatcher/inc \
+
+ifeq ($(CONFIG_POWER_MANAGEMENT_OFFLOAD), y)
+PMO_OBJS :=     $(PMO_DIR)/core/src/wlan_pmo_main.o \
+		$(PMO_DIR)/core/src/wlan_pmo_apf.o \
+		$(PMO_DIR)/core/src/wlan_pmo_arp.o \
+		$(PMO_DIR)/core/src/wlan_pmo_gtk.o \
+		$(PMO_DIR)/core/src/wlan_pmo_mc_addr_filtering.o \
+		$(PMO_DIR)/core/src/wlan_pmo_static_config.o \
+		$(PMO_DIR)/core/src/wlan_pmo_wow.o \
+		$(PMO_DIR)/core/src/wlan_pmo_lphb.o \
+		$(PMO_DIR)/core/src/wlan_pmo_suspend_resume.o \
+		$(PMO_DIR)/core/src/wlan_pmo_hw_filter.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_obj_mgmt_api.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_ucfg_api.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_arp.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_gtk.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_wow.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_static_config.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_lphb.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_suspend_resume.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_hw_filter.o \
+
+ifeq ($(CONFIG_WLAN_FEATURE_PACKET_FILTERING), y)
+PMO_OBJS +=	$(PMO_DIR)/core/src/wlan_pmo_pkt_filter.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_pkt_filter.o
+endif
+endif
+
+ifeq ($(CONFIG_WLAN_NS_OFFLOAD), y)
+PMO_OBJS +=     $(PMO_DIR)/core/src/wlan_pmo_ns.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_ns.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_ICMP_OFFLOAD), y)
+PMO_OBJS +=     $(PMO_DIR)/core/src/wlan_pmo_icmp.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_icmp.o
+endif
+
+$(call add-wlan-objs,pmo,$(PMO_OBJS))
+
+########## DISA (ENCRYPTION TEST) ##########
+
+DISA_DIR :=	components/disa
+DISA_INC :=	-I$(WLAN_ROOT)/$(DISA_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(DISA_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_DISA), y)
+DISA_OBJS :=	$(DISA_DIR)/core/src/wlan_disa_main.o \
+		$(DISA_DIR)/dispatcher/src/wlan_disa_obj_mgmt_api.o \
+		$(DISA_DIR)/dispatcher/src/wlan_disa_tgt_api.o \
+		$(DISA_DIR)/dispatcher/src/wlan_disa_ucfg_api.o
+endif
+
+$(call add-wlan-objs,disa,$(DISA_OBJS))
+
+######## OCB ##############
+OCB_DIR := components/ocb
+OCB_INC := -I$(WLAN_ROOT)/$(OCB_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(OCB_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+OCB_OBJS :=	$(OCB_DIR)/dispatcher/src/wlan_ocb_ucfg_api.o \
+		$(OCB_DIR)/dispatcher/src/wlan_ocb_tgt_api.o \
+		$(OCB_DIR)/core/src/wlan_ocb_main.o
+endif
+
+$(call add-wlan-objs,ocb,$(OCB_OBJS))
+
+######## IPA ##############
+IPA_DIR := $(WLAN_COMMON_ROOT)/ipa
+IPA_INC := -I$(WLAN_ROOT)/$(IPA_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(IPA_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+IPA_OBJS :=	$(IPA_DIR)/dispatcher/src/wlan_ipa_ucfg_api.o \
+		$(IPA_DIR)/dispatcher/src/wlan_ipa_obj_mgmt_api.o \
+		$(IPA_DIR)/dispatcher/src/wlan_ipa_tgt_api.o \
+		$(IPA_DIR)/core/src/wlan_ipa_main.o \
+		$(IPA_DIR)/core/src/wlan_ipa_core.o \
+		$(IPA_DIR)/core/src/wlan_ipa_stats.o \
+		$(IPA_DIR)/core/src/wlan_ipa_rm.o
+endif
+
+$(call add-wlan-objs,ipa,$(IPA_OBJS))
+
+######## FWOL ##########
+FWOL_CORE_INC := components/fw_offload/core/inc
+FWOL_CORE_SRC := components/fw_offload/core/src
+FWOL_DISPATCHER_INC := components/fw_offload/dispatcher/inc
+FWOL_DISPATCHER_SRC := components/fw_offload/dispatcher/src
+FWOL_TARGET_IF_INC := components/target_if/fw_offload/inc
+FWOL_TARGET_IF_SRC := components/target_if/fw_offload/src
+FWOL_OS_IF_INC := os_if/fw_offload/inc
+FWOL_OS_IF_SRC := os_if/fw_offload/src
+
+FWOL_INC := -I$(WLAN_ROOT)/$(FWOL_CORE_INC) \
+	    -I$(WLAN_ROOT)/$(FWOL_DISPATCHER_INC) \
+	    -I$(WLAN_ROOT)/$(FWOL_TARGET_IF_INC) \
+	    -I$(WLAN_ROOT)/$(FWOL_OS_IF_INC) \
+	    -I$(WLAN_COMMON_INC)/umac/thermal/dispatcher/inc
+
+ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y)
+FWOL_OBJS :=	$(FWOL_CORE_SRC)/wlan_fw_offload_main.o \
+		$(FWOL_DISPATCHER_SRC)/wlan_fwol_ucfg_api.o \
+		$(FWOL_DISPATCHER_SRC)/wlan_fwol_tgt_api.o \
+		$(FWOL_TARGET_IF_SRC)/target_if_fwol.o \
+		$(FWOL_OS_IF_SRC)/os_if_fwol.o
+endif
+
+$(call add-wlan-objs,fwol,$(FWOL_OBJS))
+
+######## SM FRAMEWORK  ##############
+UMAC_SM_DIR := umac/cmn_services/sm_engine
+UMAC_SM_INC := -I$(WLAN_COMMON_INC)/$(UMAC_SM_DIR)/inc
+
+UMAC_SM_OBJS := $(WLAN_COMMON_ROOT)/$(UMAC_SM_DIR)/src/wlan_sm_engine.o
+
+ifeq ($(CONFIG_SM_ENG_HIST), y)
+UMAC_SM_OBJS +=	$(WLAN_COMMON_ROOT)/$(UMAC_SM_DIR)/src/wlan_sm_engine_dbg.o
+endif
+
+$(call add-wlan-objs,umac_sm,$(UMAC_SM_OBJS))
+
+######## COMMON MLME ##############
+UMAC_MLME_INC := -I$(WLAN_COMMON_INC)/umac/mlme \
+		-I$(WLAN_COMMON_INC)/umac/mlme/mlme_objmgr/dispatcher/inc \
+		-I$(WLAN_COMMON_INC)/umac/mlme/vdev_mgr/dispatcher/inc \
+		-I$(WLAN_COMMON_INC)/umac/mlme/pdev_mgr/dispatcher/inc \
+		-I$(WLAN_COMMON_INC)/umac/mlme/psoc_mgr/dispatcher/inc \
+		-I$(WLAN_COMMON_INC)/umac/mlme/connection_mgr/dispatcher/inc \
+		-I$(WLAN_COMMON_INC)/umac/mlme/connection_mgr/utf/inc \
+		-I$(WLAN_COMMON_INC)/umac/mlme/include \
+		-I$(WLAN_COMMON_INC)/umac/mlme/mlme_utils/
+
+UMAC_MLME_OBJS := $(WLAN_COMMON_ROOT)/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_ucfg_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/mlme_objmgr/dispatcher/src/wlan_pdev_mlme_main.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/pdev_mgr/dispatcher/src/wlan_pdev_mlme_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/mlme_objmgr/dispatcher/src/wlan_psoc_mlme_main.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_ucfg_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_bss_scoring.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_main.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_sm.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_connect.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_connect_scan.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_util.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_ucfg_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.o
+ifeq ($(CONFIG_CM_UTF_ENABLE), y)
+UMAC_MLME_OBJS += $(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/utf/src/wlan_cm_utf_main.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/utf/src/wlan_cm_utf_scan.o
+endif
+
+ifeq ($(CONFIG_QCACLD_WLAN_LFR3), y)
+# Add LFR3/FW roam specific connection manager files here
+UMAC_MLME_OBJS += $(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_roam_util.o
+
+endif
+ifeq ($(CONFIG_QCACLD_WLAN_LFR2), y)
+# Add LFR2/host roam specific connection manager files here
+UMAC_MLME_OBJS += $(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_roam_util.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/connection_mgr/core/src/wlan_cm_host_roam.o
+endif
+
+$(call add-wlan-objs,umac_mlme,$(UMAC_MLME_OBJS))
+
+######## MLME ##############
+MLME_DIR := components/mlme
+MLME_INC := -I$(WLAN_ROOT)/$(MLME_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(MLME_DIR)/dispatcher/inc \
+
+MLME_OBJS :=	$(MLME_DIR)/core/src/wlan_mlme_main.o \
+		$(MLME_DIR)/dispatcher/src/wlan_mlme_api.o \
+		$(MLME_DIR)/dispatcher/src/wlan_mlme_ucfg_api.o
+
+MLME_OBJS += $(MLME_DIR)/core/src/wlan_mlme_vdev_mgr_interface.o
+
+ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
+MLME_OBJS += $(MLME_DIR)/core/src/wlan_mlme_twt_api.o
+MLME_OBJS += $(MLME_DIR)/dispatcher/src/wlan_mlme_twt_ucfg_api.o
+endif
+
+CM_DIR := components/umac/mlme/connection_mgr
+CM_TGT_IF_DIR := components/target_if/connection_mgr
+
+CM_INC := -I$(WLAN_ROOT)/$(CM_DIR)/dispatcher/inc \
+		-I$(WLAN_ROOT)/$(CM_DIR)/utf/inc \
+		-I$(WLAN_ROOT)/$(CM_TGT_IF_DIR)/inc
+
+MLME_INC += $(CM_INC)
+
+MLME_OBJS +=    $(CM_DIR)/dispatcher/src/wlan_cm_tgt_if_tx_api.o \
+		$(CM_DIR)/dispatcher/src/wlan_cm_roam_api.o \
+		$(CM_DIR)/dispatcher/src/wlan_cm_roam_ucfg_api.o \
+		$(CM_TGT_IF_DIR)/src/target_if_cm_roam_offload.o \
+		$(CM_TGT_IF_DIR)/src/target_if_cm_roam_event.o \
+		$(CM_DIR)/core/src/wlan_cm_roam_offload.o \
+		$(CM_DIR)/core/src/wlan_cm_vdev_connect.o \
+		$(CM_DIR)/core/src/wlan_cm_vdev_disconnect.o
+
+ifeq ($(CONFIG_CM_UTF_ENABLE), y)
+MLME_OBJS +=    $(CM_DIR)/utf/src/cm_utf.o
+endif
+
+ifeq ($(CONFIG_QCACLD_WLAN_LFR3), y)
+MLME_OBJS +=    $(CM_DIR)/core/src/wlan_cm_roam_fw_sync.o \
+		$(CM_DIR)/core/src/wlan_cm_roam_offload_event.o
+endif
+
+ifeq ($(CONFIG_QCACLD_WLAN_LFR2), y)
+# Add LFR2/host roam specific connection manager files here
+MLME_OBJS +=    $(CM_DIR)/core/src/wlan_cm_host_roam_preauth.o \
+		$(CM_DIR)/core/src/wlan_cm_host_util.o
+endif
+
+####### WFA_CONFIG ########
+
+WFA_DIR := components/umac/mlme/wfa_config
+WFA_TGT_IF_DIR := components/target_if/wfa_config
+
+WFA_INC := -I$(WLAN_ROOT)/$(WFA_DIR)/dispatcher/inc \
+		-I$(WLAN_ROOT)/$(WFA_TGT_IF_DIR)/inc
+
+MLME_INC += $(WFA_INC)
+
+MLME_OBJS += $(WFA_TGT_IF_DIR)/src/target_if_wfa_testcmd.o \
+		$(WFA_DIR)/dispatcher/src/wlan_wfa_tgt_if_tx_api.o
+
+####### LL_SAP #######
+LL_SAP_DIR := components/umac/mlme/sap/ll_sap
+LL_SAP_OS_IF_DIR := os_if/mlme/sap/ll_sap
+LL_SAP_TARGET_IF_DIR := components/target_if/sap/ll_sap
+LL_SAP_WMI_DIR := components/wmi/
+
+LL_SAP_INC := -I$(WLAN_ROOT)/$(LL_SAP_DIR)/dispatcher/inc \
+		-I$(WLAN_ROOT)/$(LL_SAP_OS_IF_DIR)/inc \
+		-I$(WLAN_ROOT)/$(LL_SAP_TARGET_IF_DIR)/inc \
+		-I$(WLAN_ROOT)/$(LL_SAP_WMI_DIR)/inc
+
+MLME_INC += $(LL_SAP_INC)
+
+ifeq ($(CONFIG_WLAN_FEATURE_LL_LT_SAP), y)
+MLME_OBJS += $(LL_SAP_DIR)/dispatcher/src/wlan_ll_sap_ucfg_api.o \
+		$(LL_SAP_DIR)/dispatcher/src/wlan_ll_sap_api.o \
+		$(LL_SAP_DIR)/core/src/wlan_ll_sap_main.o \
+		$(LL_SAP_DIR)/core/src/wlan_ll_lt_sap_main.o \
+		$(LL_SAP_DIR)/core/src/wlan_ll_lt_sap_bearer_switch.o \
+		$(LL_SAP_OS_IF_DIR)/src/os_if_ll_sap.o \
+		$(LL_SAP_TARGET_IF_DIR)/src/target_if_ll_sap.o \
+		$(LL_SAP_WMI_DIR)/src/wmi_unified_ll_sap_api.o \
+		$(LL_SAP_WMI_DIR)/src/wmi_unified_ll_sap_tlv.o
+endif
+
+$(call add-wlan-objs,mlme,$(MLME_OBJS))
+
+####### DENYLIST_MGR ########
+
+DLM_DIR := components/denylist_mgr
+DLM_INC := -I$(WLAN_ROOT)/$(DLM_DIR)/core/inc \
+                -I$(WLAN_ROOT)/$(DLM_DIR)/dispatcher/inc
+ifeq ($(CONFIG_FEATURE_DENYLIST_MGR), y)
+DLM_OBJS :=    $(DLM_DIR)/core/src/wlan_dlm_main.o \
+                $(DLM_DIR)/core/src/wlan_dlm_core.o \
+                $(DLM_DIR)/dispatcher/src/wlan_dlm_ucfg_api.o \
+                $(DLM_DIR)/dispatcher/src/wlan_dlm_tgt_api.o
+endif
+
+$(call add-wlan-objs,dlm,$(DLM_OBJS))
+
+######### CONNECTIVITY_LOGGING #########
+CONN_LOGGING_DIR := components/cmn_services/logging
+CONN_LOGGING_INC := -I$(WLAN_ROOT)/$(CONN_LOGGING_DIR)/inc
+
+ifeq ($(CONFIG_QCACLD_WLAN_CONNECTIVITY_DIAG_EVENT), y)
+CONN_LOGGING_OBJS := $(CONN_LOGGING_DIR)/src/wlan_connectivity_logging.o
+else ifeq ($(CONFIG_QCACLD_WLAN_CONNECTIVITY_LOGGING), y)
+CONN_LOGGING_OBJS := $(CONN_LOGGING_DIR)/src/wlan_connectivity_logging.o
+endif
+
+$(call add-wlan-objs,conn_logging,$(CONN_LOGGING_OBJS))
+
+########## ACTION OUI ##########
+
+ACTION_OUI_DIR := components/action_oui
+ACTION_OUI_INC := -I$(WLAN_ROOT)/$(ACTION_OUI_DIR)/core/inc \
+		  -I$(WLAN_ROOT)/$(ACTION_OUI_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_ACTION_OUI), y)
+ACTION_OUI_OBJS := $(ACTION_OUI_DIR)/core/src/wlan_action_oui_main.o \
+		$(ACTION_OUI_DIR)/core/src/wlan_action_oui_parse.o \
+		$(ACTION_OUI_DIR)/dispatcher/src/wlan_action_oui_tgt_api.o \
+		$(ACTION_OUI_DIR)/dispatcher/src/wlan_action_oui_ucfg_api.o
+endif
+
+$(call add-wlan-objs,action_oui,$(ACTION_OUI_OBJS))
+
+######## PACKET CAPTURE ########
+
+PKT_CAPTURE_DIR := components/pkt_capture
+PKT_CAPTURE_OS_IF_DIR := os_if/pkt_capture
+PKT_CAPTURE_TARGET_IF_DIR := components/target_if/pkt_capture/
+PKT_CAPTURE_INC := -I$(WLAN_ROOT)/$(PKT_CAPTURE_DIR)/core/inc \
+		  -I$(WLAN_ROOT)/$(PKT_CAPTURE_DIR)/dispatcher/inc \
+		  -I$(WLAN_ROOT)/$(PKT_CAPTURE_TARGET_IF_DIR)/inc \
+		  -I$(WLAN_ROOT)/$(PKT_CAPTURE_OS_IF_DIR)/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_PKT_CAPTURE), y)
+PKT_CAPTURE_OBJS := $(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_main.o \
+		$(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_mon_thread.o \
+		$(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_mgmt_txrx.o \
+		$(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_data_txrx.o \
+		$(PKT_CAPTURE_DIR)/dispatcher/src/wlan_pkt_capture_ucfg_api.o \
+		$(PKT_CAPTURE_DIR)/dispatcher/src/wlan_pkt_capture_tgt_api.o \
+		$(PKT_CAPTURE_DIR)/dispatcher/src/wlan_pkt_capture_api.o \
+		$(PKT_CAPTURE_TARGET_IF_DIR)/src/target_if_pkt_capture.o \
+		$(PKT_CAPTURE_OS_IF_DIR)/src/os_if_pkt_capture.o
+endif
+
+$(call add-wlan-objs,pkt_capture,$(PKT_CAPTURE_OBJS))
+
+########## FTM TIME SYNC ##########
+
+FTM_TIME_SYNC_DIR := components/ftm_time_sync
+FTM_TIME_SYNC_INC := -I$(WLAN_ROOT)/$(FTM_TIME_SYNC_DIR)/core/inc \
+		  -I$(WLAN_ROOT)/$(FTM_TIME_SYNC_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_FEATURE_WLAN_TIME_SYNC_FTM), y)
+FTM_TIME_SYNC_OBJS := $(FTM_TIME_SYNC_DIR)/core/src/ftm_time_sync_main.o \
+		$(FTM_TIME_SYNC_DIR)/dispatcher/src/ftm_time_sync_ucfg_api.o \
+		$(FTM_TIME_SYNC_DIR)/dispatcher/src/wlan_ftm_time_sync_tgt_api.o
+endif
+
+$(call add-wlan-objs,ftm_time_sync,$(FTM_TIME_SYNC_OBJS))
+
+########## WLAN PRE_CAC ##########
+
+WLAN_PRE_CAC_DIR := components/pre_cac
+PRE_CAC_OSIF_DIR := os_if/pre_cac
+WLAN_PRE_CAC_INC := -I$(WLAN_ROOT)/$(WLAN_PRE_CAC_DIR)/dispatcher/inc \
+		  -I$(WLAN_ROOT)/$(WLAN_PRE_CAC_DIR)/core/src \
+		  -I$(WLAN_ROOT)/$(PRE_CAC_OSIF_DIR)/inc
+
+ifeq ($(CONFIG_FEATURE_WLAN_PRE_CAC), y)
+WLAN_PRE_CAC_OBJS := $(HDD_SRC_DIR)/wlan_hdd_pre_cac.o \
+		$(WLAN_PRE_CAC_DIR)/core/src/wlan_pre_cac_main.o \
+		$(WLAN_PRE_CAC_DIR)/dispatcher/src/wlan_pre_cac_ucfg_api.o \
+		$(WLAN_PRE_CAC_DIR)/dispatcher/src/wlan_pre_cac_api.o \
+		$(PRE_CAC_OSIF_DIR)/src/osif_pre_cac.o
+endif
+
+$(call add-wlan-objs,wlan_pre_cac,$(WLAN_PRE_CAC_OBJS))
+
+########## CLD TARGET_IF #######
+CLD_TARGET_IF_DIR := components/target_if
+
+CLD_TARGET_IF_INC := -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/pmo/inc \
+		     -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/mlme/inc \
+
+ifeq ($(CONFIG_QCA_TARGET_IF_MLME), y)
+CLD_TARGET_IF_OBJ := $(CLD_TARGET_IF_DIR)/mlme/src/target_if_mlme.o
+endif
+
+ifeq ($(CONFIG_POWER_MANAGEMENT_OFFLOAD), y)
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_arp.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_gtk.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_hw_filter.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_lphb.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_main.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_mc_addr_filtering.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_static_config.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_suspend_resume.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_wow.o
+ifeq ($(CONFIG_WLAN_NS_OFFLOAD), y)
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_ns.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_PACKET_FILTERING), y)
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_pkt_filter.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_ICMP_OFFLOAD), y)
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_icmp.o
+endif
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/ocb/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/ocb/src/target_if_ocb.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DISA), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/disa/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/disa/src/target_if_disa.o
+endif
+
+ifeq ($(CONFIG_FEATURE_DENYLIST_MGR), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/denylist_mgr/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/denylist_mgr/src/target_if_dlm.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_ACTION_OUI), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/action_oui/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/action_oui/src/target_if_action_oui.o
+endif
+
+ifeq ($(CONFIG_FEATURE_WLAN_TIME_SYNC_FTM), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/ftm_time_sync/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/ftm_time_sync/src/target_if_ftm_time_sync.o
+endif
+
+$(call add-wlan-objs,cld_target_if,$(CLD_TARGET_IF_OBJ))
+
+############## UMAC P2P ###########
+P2P_DIR := components/p2p
+P2P_CORE_OBJ_DIR := $(P2P_DIR)/core/src
+P2P_DISPATCHER_DIR := $(P2P_DIR)/dispatcher
+P2P_DISPATCHER_INC_DIR := $(P2P_DISPATCHER_DIR)/inc
+P2P_DISPATCHER_OBJ_DIR := $(P2P_DISPATCHER_DIR)/src
+P2P_OS_IF_INC := os_if/p2p/inc
+P2P_OS_IF_SRC := os_if/p2p/src
+P2P_TARGET_IF_INC := components/target_if/p2p/inc
+P2P_TARGET_IF_SRC := components/target_if/p2p/src
+P2P_INC := -I$(WLAN_ROOT)/$(P2P_DISPATCHER_INC_DIR) \
+	   -I$(WLAN_ROOT)/$(P2P_OS_IF_INC) \
+	   -I$(WLAN_ROOT)/$(P2P_TARGET_IF_INC)
+P2P_OBJS := $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_ucfg_api.o \
+	    $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_tgt_api.o \
+	    $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_cfg.o \
+	    $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_api.o \
+	    $(P2P_CORE_OBJ_DIR)/wlan_p2p_main.o \
+	    $(P2P_CORE_OBJ_DIR)/wlan_p2p_roc.o \
+	    $(P2P_CORE_OBJ_DIR)/wlan_p2p_off_chan_tx.o \
+	    $(P2P_OS_IF_SRC)/wlan_cfg80211_p2p.o \
+	    $(P2P_TARGET_IF_SRC)/target_if_p2p.o
+ifeq ($(CONFIG_WLAN_FEATURE_MCC_QUOTA), y)
+P2P_OBJS += $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_mcc_quota_tgt_api.o \
+	    $(P2P_CORE_OBJ_DIR)/wlan_p2p_mcc_quota.o \
+	    $(P2P_TARGET_IF_SRC)/target_if_p2p_mcc_quota.o
+endif
+$(call add-wlan-objs,p2p,$(P2P_OBJS))
+
+###### UMAC POLICY MGR ########
+POLICY_MGR_DIR := components/cmn_services/policy_mgr
+
+POLICY_MGR_INC := -I$(WLAN_ROOT)/$(POLICY_MGR_DIR)/inc \
+		  -I$(WLAN_ROOT)/$(POLICY_MGR_DIR)/src
+
+POLICY_MGR_OBJS := $(POLICY_MGR_DIR)/src/wlan_policy_mgr_action.o \
+	$(POLICY_MGR_DIR)/src/wlan_policy_mgr_core.o \
+	$(POLICY_MGR_DIR)/src/wlan_policy_mgr_get_set_utils.o \
+	$(POLICY_MGR_DIR)/src/wlan_policy_mgr_init_deinit.o \
+	$(POLICY_MGR_DIR)/src/wlan_policy_mgr_ucfg.o \
+	$(POLICY_MGR_DIR)/src/wlan_policy_mgr_pcl.o
+ifeq ($(CONFIG_WLAN_FEATURE_LL_LT_SAP), y)
+POLICY_MGR_OBJS += $(POLICY_MGR_DIR)/src/wlan_policy_mgr_ll_sap.o
+endif
+
+$(call add-wlan-objs,policy_mgr,$(POLICY_MGR_OBJS))
+
+###### UMAC TDLS ########
+TDLS_DIR := components/tdls
+
+TDLS_OS_IF_INC := os_if/tdls/inc
+TDLS_OS_IF_SRC := os_if/tdls/src
+TDLS_TARGET_IF_INC := components/target_if/tdls/inc
+TDLS_TARGET_IF_SRC := components/target_if/tdls/src
+TDLS_INC := -I$(WLAN_ROOT)/$(TDLS_DIR)/dispatcher/inc \
+	    -I$(WLAN_ROOT)/$(TDLS_DIR)/core/src \
+	    -I$(WLAN_ROOT)/$(TDLS_OS_IF_INC) \
+	    -I$(WLAN_ROOT)/$(TDLS_TARGET_IF_INC)
+
+ifeq ($(CONFIG_QCOM_TDLS), y)
+TDLS_OBJS := $(TDLS_DIR)/core/src/wlan_tdls_main.o \
+       $(TDLS_DIR)/core/src/wlan_tdls_cmds_process.o \
+       $(TDLS_DIR)/core/src/wlan_tdls_peer.o \
+       $(TDLS_DIR)/core/src/wlan_tdls_mgmt.o \
+       $(TDLS_DIR)/core/src/wlan_tdls_ct.o \
+       $(TDLS_DIR)/dispatcher/src/wlan_tdls_tgt_api.o \
+       $(TDLS_DIR)/dispatcher/src/wlan_tdls_ucfg_api.o \
+       $(TDLS_DIR)/dispatcher/src/wlan_tdls_utils_api.o \
+       $(TDLS_DIR)/dispatcher/src/wlan_tdls_cfg.o \
+       $(TDLS_DIR)/dispatcher/src/wlan_tdls_api.o \
+       $(TDLS_OS_IF_SRC)/wlan_cfg80211_tdls.o \
+       $(TDLS_TARGET_IF_SRC)/target_if_tdls.o
+endif
+
+$(call add-wlan-objs,tdls,$(TDLS_OBJS))
+
+########### BMI ###########
+BMI_DIR := core/bmi
+
+BMI_INC := -I$(WLAN_ROOT)/$(BMI_DIR)/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_BMI), y)
+BMI_OBJS := $(BMI_DIR)/src/bmi.o \
+            $(BMI_DIR)/src/bmi_1.o \
+            $(BMI_DIR)/src/ol_fw.o \
+            $(BMI_DIR)/src/ol_fw_common.o
+endif
+
+$(call add-wlan-objs,bmi,$(BMI_OBJS))
+
+##########  TARGET_IF #######
+TARGET_IF_DIR := $(WLAN_COMMON_ROOT)/target_if
+
+TARGET_IF_INC := -I$(WLAN_COMMON_INC)/target_if/core/inc \
+		 -I$(WLAN_COMMON_INC)/target_if/init_deinit/inc \
+		 -I$(WLAN_COMMON_INC)/target_if/crypto/inc \
+		 -I$(WLAN_COMMON_INC)/target_if/regulatory/inc \
+		 -I$(WLAN_COMMON_INC)/target_if/mlme/vdev_mgr/inc \
+		 -I$(WLAN_COMMON_INC)/target_if/dispatcher/inc \
+		 -I$(WLAN_COMMON_INC)/target_if/mlme/psoc/inc \
+		 -I$(WLAN_COMMON_INC)/target_if/ipa/inc
+
+TARGET_IF_OBJ := $(TARGET_IF_DIR)/core/src/target_if_main.o \
+		$(TARGET_IF_DIR)/regulatory/src/target_if_reg.o \
+		$(TARGET_IF_DIR)/regulatory/src/target_if_reg_lte.o \
+		$(TARGET_IF_DIR)/regulatory/src/target_if_reg_11d.o \
+		$(TARGET_IF_DIR)/init_deinit/src/init_cmd_api.o \
+		$(TARGET_IF_DIR)/init_deinit/src/init_deinit_lmac.o \
+		$(TARGET_IF_DIR)/init_deinit/src/init_event_handler.o \
+		$(TARGET_IF_DIR)/init_deinit/src/service_ready_util.o \
+		$(TARGET_IF_DIR)/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.o \
+		$(TARGET_IF_DIR)/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.o \
+		$(TARGET_IF_DIR)/mlme/psoc/src/target_if_psoc_timer_tx_ops.o
+
+ifeq ($(CONFIG_FEATURE_VDEV_OPS_WAKELOCK), y)
+TARGET_IF_OBJ += $(TARGET_IF_DIR)/mlme/psoc/src/target_if_psoc_wake_lock.o
+endif
+
+TARGET_IF_OBJ += $(TARGET_IF_DIR)/crypto/src/target_if_crypto.o
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+TARGET_IF_OBJ += $(TARGET_IF_DIR)/ipa/src/target_if_ipa.o
+endif
+
+$(call add-wlan-objs,target_if,$(TARGET_IF_OBJ))
+
+########### GLOBAL_LMAC_IF ##########
+GLOBAL_LMAC_IF_DIR := $(WLAN_COMMON_ROOT)/global_lmac_if
+
+GLOBAL_LMAC_IF_INC := -I$(WLAN_COMMON_INC)/global_lmac_if/inc \
+
+GLOBAL_LMAC_IF_OBJ := $(GLOBAL_LMAC_IF_DIR)/src/wlan_global_lmac_if.o
+
+$(call add-wlan-objs,global_lmac_if,$(GLOBAL_LMAC_IF_OBJ))
+
+########### WMI ###########
+WMI_ROOT_DIR := wmi
+
+WMI_SRC_DIR := $(WMI_ROOT_DIR)/src
+WMI_INC_DIR := $(WMI_ROOT_DIR)/inc
+WMI_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(WMI_SRC_DIR)
+
+WMI_INC := -I$(WLAN_COMMON_INC)/$(WMI_INC_DIR)
+
+WMI_OBJS := $(WMI_OBJ_DIR)/wmi_unified.o \
+	    $(WMI_OBJ_DIR)/wmi_tlv_helper.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_tlv.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_api.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_reg_api.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_vdev_api.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_vdev_tlv.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_crypto_api.o
+
+ifeq ($(CONFIG_POWER_MANAGEMENT_OFFLOAD), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_pmo_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_pmo_tlv.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_APF), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_apf_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_ACTION_OUI), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_action_oui_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+ifeq ($(CONFIG_OCB_UT_FRAMEWORK), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_ocb_ut.o
+endif
+endif
+
+ifeq ($(CONFIG_WLAN_DFS_MASTER_ENABLE), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_dfs_api.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_twt_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_twt_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_ocb_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_ocb_tlv.o
+endif
+
+ifeq ($(CONFIG_FEATURE_WLAN_EXTSCAN), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_extscan_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_extscan_tlv.o
+endif
+
+ifeq ($(CONFIG_FEATURE_INTEROP_ISSUES_AP), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_interop_issues_ap_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_interop_issues_ap_tlv.o
+endif
+
+ifeq ($(CONFIG_DCS), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_dcs_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_dcs_tlv.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_nan_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_nan_tlv.o
+endif
+
+ifeq ($(CONFIG_CONVERGED_P2P_ENABLE), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_p2p_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_p2p_tlv.o
+endif
+
+ifeq ($(CONFIG_WMI_CONCURRENCY_SUPPORT), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_concurrency_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_concurrency_tlv.o
+endif
+
+ifeq ($(CONFIG_WMI_STA_SUPPORT), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_sta_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_sta_tlv.o
+endif
+
+ifeq ($(CONFIG_WMI_BCN_OFFLOAD), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_bcn_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_bcn_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_fwol_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_fwol_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_HANG_EVENT), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_hang_event.o
+endif
+
+ifeq ($(CONFIG_WLAN_CFR_ENABLE), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_cfr_tlv.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_cfr_api.o
+endif
+
+ifeq ($(CONFIG_CP_STATS), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_cp_stats_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_cp_stats_tlv.o
+endif
+
+ifeq ($(CONFIG_FEATURE_GPIO_CFG), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_gpio_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_gpio_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_11BE_MLO), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_11be_tlv.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_11be_api.o
+endif
+
+ifeq ($(CONFIG_FEATURE_WDS), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_wds_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_wds_tlv.o
+endif
+
+$(call add-wlan-objs,wmi,$(WMI_OBJS))
+
+########### FWLOG ###########
+FWLOG_DIR := $(WLAN_COMMON_ROOT)/utils/fwlog
+
+FWLOG_INC := -I$(WLAN_ROOT)/$(FWLOG_DIR)
+
+ifeq ($(CONFIG_FEATURE_FW_LOG_PARSING), y)
+FWLOG_OBJS := $(FWLOG_DIR)/dbglog_host.o
+endif
+
+$(call add-wlan-objs,fwlog,$(FWLOG_OBJS))
+
+############ TXRX ############
+TXRX_DIR :=     core/dp/txrx
+TXRX_INC :=     -I$(WLAN_ROOT)/$(TXRX_DIR)
+
+TXRX_OBJS :=
+ifeq ($(CONFIG_WDI_EVENT_ENABLE), y)
+TXRX_OBJS += 	$(TXRX_DIR)/ol_txrx_event.o
+endif
+
+ifneq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM) $(CONFIG_RHINE)))
+TXRX_OBJS += $(TXRX_DIR)/ol_txrx.o \
+		$(TXRX_DIR)/ol_cfg.o \
+                $(TXRX_DIR)/ol_rx.o \
+                $(TXRX_DIR)/ol_rx_fwd.o \
+                $(TXRX_DIR)/ol_txrx.o \
+                $(TXRX_DIR)/ol_rx_defrag.o \
+                $(TXRX_DIR)/ol_tx_desc.o \
+                $(TXRX_DIR)/ol_tx.o \
+                $(TXRX_DIR)/ol_rx_reorder_timeout.o \
+                $(TXRX_DIR)/ol_rx_reorder.o \
+                $(TXRX_DIR)/ol_rx_pn.o \
+                $(TXRX_DIR)/ol_txrx_peer_find.o \
+                $(TXRX_DIR)/ol_txrx_encap.o \
+                $(TXRX_DIR)/ol_tx_send.o
+
+ifeq ($(CONFIG_LL_DP_SUPPORT), y)
+
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_ll.o
+
+ifeq ($(CONFIG_WLAN_FASTPATH), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_ll_fastpath.o
+else
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_ll_legacy.o
+endif
+
+ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_flow_control.o
+endif
+
+endif #CONFIG_LL_DP_SUPPORT
+
+ifeq ($(CONFIG_HL_DP_SUPPORT), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_hl.o
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_classify.o
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_sched.o
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_queue.o
+endif #CONFIG_HL_DP_SUPPORT
+
+ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_legacy_flow_control.o
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_ipa.o
+endif
+
+ifeq ($(CONFIG_QCA_SUPPORT_TX_THROTTLE), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_throttle.o
+endif
+endif #LITHIUM/BERYLLIUM/RHINE
+
+$(call add-wlan-objs,txrx,$(TXRX_OBJS))
+
+ifeq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM) $(CONFIG_RHINE)))
+############ DP 3.0 ############
+DP_INC := -I$(WLAN_COMMON_INC)/dp/inc \
+	-I$(WLAN_COMMON_INC)/dp/wifi3.0 \
+	-I$(WLAN_COMMON_INC)/target_if/dp/inc \
+	-I$(WLAN_COMMON_INC)/dp/cmn_dp_api
+
+DP_SRC := $(WLAN_COMMON_ROOT)/dp/wifi3.0
+DP_OBJS := $(DP_SRC)/dp_main.o \
+		$(DP_SRC)/dp_tx.o \
+		$(DP_SRC)/dp_arch_ops.o \
+		$(DP_SRC)/dp_tx_desc.o \
+		$(DP_SRC)/dp_rx.o \
+		$(DP_SRC)/dp_htt.o \
+		$(DP_SRC)/dp_peer.o \
+		$(DP_SRC)/dp_rx_desc.o \
+		$(DP_SRC)/dp_rx_defrag.o \
+		$(DP_SRC)/dp_stats.o \
+		$(WLAN_COMMON_ROOT)/target_if/dp/src/target_if_dp.o
+
+ifneq ($(CONFIG_RHINE), y)
+DP_OBJS += $(DP_SRC)/dp_rings_main.o
+DP_OBJS += $(DP_SRC)/dp_reo.o
+DP_OBJS += $(DP_SRC)/dp_rx_err.o
+DP_OBJS += $(DP_SRC)/dp_rx_tid.o
+endif
+
+ifeq ($(CONFIG_WIFI_MONITOR_SUPPORT), y)
+DP_INC += -I$(WLAN_COMMON_INC)/dp/wifi3.0/monitor \
+	-I$(WLAN_COMMON_INC)/dp/wifi3.0/monitor/1.0 \
+	-I$(WLAN_COMMON_INC)/dp/wifi3.0/monitor/2.0 \
+
+DP_OBJS += $(DP_SRC)/monitor/dp_mon.o \
+		$(DP_SRC)/monitor/dp_mon_filter.o \
+		$(DP_SRC)/monitor/dp_rx_mon.o \
+		$(DP_SRC)/monitor/1.0/dp_rx_mon_dest_1.0.o \
+		$(DP_SRC)/monitor/1.0/dp_rx_mon_status_1.0.o \
+		$(DP_SRC)/monitor/1.0/dp_mon_filter_1.0.o \
+		$(DP_SRC)/monitor/1.0/dp_mon_1.0.o
+endif
+
+DP_OBJS += $(DP_SRC)/../cmn_dp_api/dp_ratetable.o
+
+ifeq ($(CONFIG_BERYLLIUM), y)
+DP_INC += -I$(WLAN_COMMON_INC)/dp/wifi3.0/be
+
+DP_OBJS += $(DP_SRC)/be/dp_be.o
+DP_OBJS += $(DP_SRC)/be/dp_be_tx.o
+DP_OBJS += $(DP_SRC)/be/dp_be_rx.o
+
+ifeq ($(CONFIG_WIFI_MONITOR_SUPPORT), y)
+ifeq ($(CONFIG_WLAN_TX_MON_2_0), y)
+DP_OBJS += $(DP_SRC)/monitor/2.0/dp_mon_2.0.o \
+		$(DP_SRC)/monitor/2.0/dp_mon_filter_2.0.o
+DP_OBJS += $(DP_SRC)/monitor/2.0/dp_tx_mon_2.0.o \
+		$(DP_SRC)/monitor/2.0/dp_tx_mon_status_2.0.o
+ccflags-$(CONFIG_WLAN_TX_MON_2_0) += -DWLAN_PKT_CAPTURE_TX_2_0
+ccflags-y += -DWLAN_TX_PKT_CAPTURE_ENH_BE
+ccflags-y += -DQDF_FRAG_CACHE_SUPPORT
+endif
+endif
+endif
+
+ifeq ($(CONFIG_LITHIUM), y)
+DP_OBJS += $(DP_SRC)/li/dp_li.o
+DP_OBJS += $(DP_SRC)/li/dp_li_tx.o
+DP_OBJS += $(DP_SRC)/li/dp_li_rx.o
+endif
+
+ifeq ($(CONFIG_RHINE), y)
+DP_OBJS += $(DP_SRC)/rh/dp_rh.o
+DP_OBJS += $(DP_SRC)/rh/dp_rh_tx.o
+DP_OBJS += $(DP_SRC)/rh/dp_rh_rx.o
+DP_OBJS += $(DP_SRC)/rh/dp_rh_htt.o
+endif
+
+ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y)
+DP_OBJS += $(DP_SRC)/dp_tx_flow_control.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_RX_BUFFER_POOL), y)
+DP_OBJS += $(DP_SRC)/dp_rx_buffer_pool.o
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+DP_OBJS +=     $(DP_SRC)/dp_ipa.o
+endif
+
+ifeq ($(CONFIG_WDI_EVENT_ENABLE), y)
+DP_OBJS +=     $(DP_SRC)/dp_wdi_event.o
+endif
+
+ifeq ($(CONFIG_FEATURE_MEC), y)
+DP_OBJS += $(DP_SRC)/dp_txrx_wds.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_SON), y)
+DP_OBJS += $(WLAN_COMMON_ROOT)/dp/cmn_dp_api/dp_ratetable.o
+DP_INC += -I$(WLAN_COMMON_INC)/dp/cmn_dp_api
+endif
+
+endif #LITHIUM
+
+$(call add-wlan-objs,dp,$(DP_OBJS))
+
+############ CFG ############
+WCFG_DIR := wlan_cfg
+WCFG_INC := -I$(WLAN_COMMON_INC)/$(WCFG_DIR)
+WCFG_SRC := $(WLAN_COMMON_ROOT)/$(WCFG_DIR)
+
+ifeq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM) $(CONFIG_RHINE)))
+WCFG_OBJS := $(WCFG_SRC)/wlan_cfg.o
+endif
+
+$(call add-wlan-objs,wcfg,$(WCFG_OBJS))
+
+############ OL ############
+OL_DIR :=     core/dp/ol
+OL_INC :=     -I$(WLAN_ROOT)/$(OL_DIR)/inc
+
+############ CDP ############
+CDP_ROOT_DIR := dp
+CDP_INC_DIR := $(CDP_ROOT_DIR)/inc
+CDP_INC := -I$(WLAN_COMMON_INC)/$(CDP_INC_DIR)
+
+############ PKTLOG ############
+PKTLOG_DIR :=      $(WLAN_COMMON_ROOT)/utils/pktlog
+PKTLOG_INC :=      -I$(WLAN_ROOT)/$(PKTLOG_DIR)/include
+
+ifeq ($(CONFIG_REMOVE_PKT_LOG), n)
+PKTLOG_OBJS :=	$(PKTLOG_DIR)/pktlog_ac.o \
+		$(PKTLOG_DIR)/pktlog_internal.o \
+		$(PKTLOG_DIR)/linux_ac.o
+
+ifeq ($(CONFIG_PKTLOG_LEGACY), y)
+	PKTLOG_OBJS  += $(PKTLOG_DIR)/pktlog_wifi2.o
+else
+	PKTLOG_OBJS  += $(PKTLOG_DIR)/pktlog_wifi3.o
+endif
+
+endif
+
+
+$(call add-wlan-objs,pktlog,$(PKTLOG_OBJS))
+
+############ HTT ############
+HTT_DIR :=      core/dp/htt
+HTT_INC :=      -I$(WLAN_ROOT)/$(HTT_DIR)
+
+ifneq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM) $(CONFIG_RHINE)))
+HTT_OBJS := $(HTT_DIR)/htt_tx.o \
+            $(HTT_DIR)/htt.o \
+            $(HTT_DIR)/htt_t2h.o \
+            $(HTT_DIR)/htt_h2t.o \
+            $(HTT_DIR)/htt_fw_stats.o \
+            $(HTT_DIR)/htt_rx.o
+
+ifeq ($(CONFIG_FEATURE_MONITOR_MODE_SUPPORT), y)
+HTT_OBJS += $(HTT_DIR)/htt_monitor_rx.o
+endif
+
+ifeq ($(CONFIG_LL_DP_SUPPORT), y)
+HTT_OBJS += $(HTT_DIR)/htt_rx_ll.o
+endif
+
+ifeq ($(CONFIG_HL_DP_SUPPORT), y)
+HTT_OBJS += $(HTT_DIR)/htt_rx_hl.o
+endif
+endif
+
+$(call add-wlan-objs,htt,$(HTT_OBJS))
+
+############## INIT-DEINIT ###########
+INIT_DEINIT_DIR := init_deinit/dispatcher
+INIT_DEINIT_INC_DIR := $(INIT_DEINIT_DIR)/inc
+INIT_DEINIT_SRC_DIR := $(INIT_DEINIT_DIR)/src
+INIT_DEINIT_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(INIT_DEINIT_SRC_DIR)
+INIT_DEINIT_INC := -I$(WLAN_COMMON_INC)/$(INIT_DEINIT_INC_DIR)
+INIT_DEINIT_OBJS := $(INIT_DEINIT_OBJ_DIR)/dispatcher_init_deinit.o
+
+$(call add-wlan-objs,init_deinit,$(INIT_DEINIT_OBJS))
+
+############## REGULATORY ###########
+REGULATORY_DIR := umac/regulatory
+REGULATORY_CORE_SRC_DIR := $(REGULATORY_DIR)/core/src
+REG_DISPATCHER_INC_DIR := $(REGULATORY_DIR)/dispatcher/inc
+REG_DISPATCHER_SRC_DIR := $(REGULATORY_DIR)/dispatcher/src
+REG_CORE_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(REGULATORY_CORE_SRC_DIR)
+REG_DISPATCHER_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(REG_DISPATCHER_SRC_DIR)
+REGULATORY_INC := -I$(WLAN_COMMON_INC)/$(REGULATORY_CORE_SRC_DIR)
+REGULATORY_INC += -I$(WLAN_COMMON_INC)/$(REG_DISPATCHER_INC_DIR)
+REGULATORY_INC += -I$(WLAN_COMMON_INC)/umac/cmn_services/regulatory/inc
+REGULATORY_OBJS := $(REG_CORE_OBJ_DIR)/reg_build_chan_list.o \
+		    $(REG_CORE_OBJ_DIR)/reg_callbacks.o \
+		    $(REG_CORE_OBJ_DIR)/reg_db.o \
+		    $(REG_CORE_OBJ_DIR)/reg_db_parser.o \
+		    $(REG_CORE_OBJ_DIR)/reg_utils.o \
+		    $(REG_CORE_OBJ_DIR)/reg_lte.o \
+		    $(REG_CORE_OBJ_DIR)/reg_offload_11d_scan.o \
+		    $(REG_CORE_OBJ_DIR)/reg_opclass.o \
+		    $(REG_CORE_OBJ_DIR)/reg_priv_objs.o \
+		    $(REG_DISPATCHER_OBJ_DIR)/wlan_reg_services_api.o \
+		    $(REG_CORE_OBJ_DIR)/reg_services_common.o \
+		    $(REG_DISPATCHER_OBJ_DIR)/wlan_reg_tgt_api.o \
+		    $(REG_DISPATCHER_OBJ_DIR)/wlan_reg_ucfg_api.o
+ifeq ($(CONFIG_HOST_11D_SCAN), y)
+REGULATORY_OBJS += $(REG_CORE_OBJ_DIR)/reg_host_11d.o
+endif
+
+$(call add-wlan-objs,regulatory,$(REGULATORY_OBJS))
+
+############## Control path common scheduler ##########
+SCHEDULER_DIR := scheduler
+SCHEDULER_INC_DIR := $(SCHEDULER_DIR)/inc
+SCHEDULER_SRC_DIR := $(SCHEDULER_DIR)/src
+SCHEDULER_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(SCHEDULER_SRC_DIR)
+SCHEDULER_INC := -I$(WLAN_COMMON_INC)/$(SCHEDULER_INC_DIR)
+SCHEDULER_OBJS := $(SCHEDULER_OBJ_DIR)/scheduler_api.o \
+                  $(SCHEDULER_OBJ_DIR)/scheduler_core.o
+
+$(call add-wlan-objs,scheduler,$(SCHEDULER_OBJS))
+
+###### UMAC SERIALIZATION ########
+UMAC_SER_DIR := umac/cmn_services/serialization
+UMAC_SER_INC_DIR := $(UMAC_SER_DIR)/inc
+UMAC_SER_SRC_DIR := $(UMAC_SER_DIR)/src
+UMAC_SER_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SER_SRC_DIR)
+
+UMAC_SER_INC := -I$(WLAN_COMMON_INC)/$(UMAC_SER_INC_DIR)
+UMAC_SER_OBJS := $(UMAC_SER_OBJ_DIR)/wlan_serialization_main.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_api.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_utils.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_legacy_api.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_rules.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_internal.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_non_scan.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_queue.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_scan.o
+
+$(call add-wlan-objs,umac_ser,$(UMAC_SER_OBJS))
+
+###### WIFI POS ########
+WIFI_POS_OS_IF_DIR := $(WLAN_COMMON_ROOT)/os_if/linux/wifi_pos/src
+WIFI_POS_OS_IF_INC := -I$(WLAN_COMMON_INC)/os_if/linux/wifi_pos/inc
+WIFI_POS_TGT_DIR := $(WLAN_COMMON_ROOT)/target_if/wifi_pos/src
+WIFI_POS_TGT_INC := -I$(WLAN_COMMON_INC)/target_if/wifi_pos/inc
+WIFI_POS_CORE_DIR := $(WLAN_COMMON_ROOT)/umac/wifi_pos/src
+WIFI_POS_API_INC := -I$(WLAN_COMMON_INC)/umac/wifi_pos/inc
+
+
+ifeq ($(CONFIG_WIFI_POS_CONVERGED), y)
+
+WIFI_POS_CLD_DIR := components/wifi_pos
+WIFI_POS_CLD_CORE_DIR := $(WIFI_POS_CLD_DIR)/core
+WIFI_POS_CLD_CORE_SRC := $(WIFI_POS_CLD_CORE_DIR)/src
+WIFI_POS_CLD_DISP_DIR := $(WIFI_POS_CLD_DIR)/dispatcher
+
+WIFI_POS_OBJS := $(WIFI_POS_CORE_DIR)/wifi_pos_api.o \
+		 $(WIFI_POS_CORE_DIR)/wifi_pos_main.o \
+		 $(WIFI_POS_CORE_DIR)/wifi_pos_ucfg.o \
+		 $(WIFI_POS_CORE_DIR)/wifi_pos_utils.o \
+		 $(WIFI_POS_CLD_DISP_DIR)/src/wifi_pos_ucfg_api.o \
+		 $(WIFI_POS_OS_IF_DIR)/os_if_wifi_pos.o \
+		 $(WIFI_POS_OS_IF_DIR)/os_if_wifi_pos_utils.o \
+		 $(WIFI_POS_OS_IF_DIR)/wlan_cfg80211_wifi_pos.o \
+		 $(WIFI_POS_TGT_DIR)/target_if_wifi_pos.o \
+		 $(WIFI_POS_TGT_DIR)/target_if_wifi_pos_rx_ops.o \
+		 $(WIFI_POS_TGT_DIR)/target_if_wifi_pos_tx_ops.o
+
+ifeq ($(CONFIG_WIFI_POS_PASN), y)
+WIFI_POS_OBJS += $(WIFI_POS_CORE_DIR)/wifi_pos_pasn_api.o
+WIFI_POS_OBJS += $(WIFI_POS_CLD_CORE_SRC)/wlan_wifi_pos_interface.o
+endif
+
+WIFI_POS_CLD_INC :=	-I$(WLAN_ROOT)/$(WIFI_POS_CLD_CORE_DIR)/inc \
+			-I$(WLAN_ROOT)/$(WIFI_POS_CLD_DISP_DIR)/inc
+endif
+
+$(call add-wlan-objs,wifi_pos,$(WIFI_POS_OBJS))
+
+###### TWT CONVERGED ########
+TWT_CONV_CMN_OSIF_SRC := $(WLAN_COMMON_ROOT)/os_if/linux/twt/src
+TWT_CONV_CMN_DISPATCHER_SRC := $(WLAN_COMMON_ROOT)/umac/twt/dispatcher/src
+TWT_CONV_CMN_CORE_SRC := $(WLAN_COMMON_ROOT)/umac/twt/core/src
+TWT_CONV_CMN_TGT_SRC := $(WLAN_COMMON_ROOT)/target_if/twt/src
+TWT_CONV_OSIF_SRC := os_if/twt/src
+TWT_CONV_DISPATCHER_SRC := components/umac/twt/dispatcher/src
+TWT_CONV_CORE_SRC := components/umac/twt/core/src
+TWT_CONV_TGT_SRC := components/target_if/twt/src
+
+TWT_CONV_INCS := -I$(WLAN_COMMON_INC)/umac \
+		 -I$(WLAN_ROOT)/components/umac \
+		 -I$(WLAN_COMMON_INC)/os_if/linux/twt/inc \
+		 -I$(WLAN_COMMON_INC)/umac/twt/dispatcher/inc \
+		 -I$(WLAN_COMMON_INC)/target_if/twt/inc \
+		 -I$(WLAN_ROOT)/os_if/twt/inc \
+		 -I$(WLAN_ROOT)/components/umac/twt/dispatcher/inc \
+		 -I$(WLAN_ROOT)/components/target_if/twt/inc
+
+
+ifeq ($(CONFIG_WLAN_TWT_CONVERGED), y)
+TWT_CONV_OBJS := $(TWT_CONV_CMN_OSIF_SRC)/osif_twt_req.o \
+		 $(TWT_CONV_CMN_OSIF_SRC)/osif_twt_rsp.o \
+		 $(TWT_CONV_CMN_DISPATCHER_SRC)/wlan_twt_api.o \
+		 $(TWT_CONV_CMN_DISPATCHER_SRC)/wlan_twt_tgt_if_rx_api.o \
+		 $(TWT_CONV_CMN_DISPATCHER_SRC)/wlan_twt_tgt_if_tx_api.o \
+		 $(TWT_CONV_CMN_DISPATCHER_SRC)/wlan_twt_ucfg_api.o \
+		 $(TWT_CONV_CMN_CORE_SRC)/wlan_twt_common.o \
+		 $(TWT_CONV_CMN_CORE_SRC)/wlan_twt_objmgr.o \
+		 $(TWT_CONV_CMN_TGT_SRC)/target_if_twt_cmd.o \
+		 $(TWT_CONV_CMN_TGT_SRC)/target_if_twt_evt.o \
+		 $(TWT_CONV_CMN_TGT_SRC)/target_if_twt.o \
+		 $(TWT_CONV_OSIF_SRC)/osif_twt_ext_req.o \
+		 $(TWT_CONV_OSIF_SRC)/osif_twt_ext_rsp.o \
+		 $(TWT_CONV_OSIF_SRC)/osif_twt_ext_util.o \
+		 $(TWT_CONV_DISPATCHER_SRC)/wlan_twt_ucfg_ext_api.o \
+		 $(TWT_CONV_DISPATCHER_SRC)/wlan_twt_cfg_ext_api.o \
+		 $(TWT_CONV_DISPATCHER_SRC)/wlan_twt_tgt_if_ext_rx_api.o \
+		 $(TWT_CONV_DISPATCHER_SRC)/wlan_twt_tgt_if_ext_tx_api.o \
+		 $(TWT_CONV_CORE_SRC)/wlan_twt_cfg.o \
+		 $(TWT_CONV_CORE_SRC)/wlan_twt_main.o \
+		 $(TWT_CONV_TGT_SRC)/target_if_ext_twt_cmd.o \
+		 $(TWT_CONV_TGT_SRC)/target_if_ext_twt_evt.o
+endif
+
+$(call add-wlan-objs,twt_conv,$(TWT_CONV_OBJS))
+
+###### CP STATS ########
+CP_MC_STATS_OS_IF_SRC           := os_if/cp_stats/src
+CP_STATS_TGT_SRC                := $(WLAN_COMMON_ROOT)/target_if/cp_stats/src
+CP_STATS_CORE_SRC               := $(WLAN_COMMON_ROOT)/umac/cp_stats/core/src
+CP_STATS_DISPATCHER_SRC         := $(WLAN_COMMON_ROOT)/umac/cp_stats/dispatcher/src
+CP_MC_STATS_COMPONENT_SRC       := components/cp_stats/dispatcher/src
+CP_MC_STATS_COMPONENT_TGT_SRC   := $(CLD_TARGET_IF_DIR)/cp_stats/src
+
+CP_STATS_OS_IF_INC              := -I$(WLAN_COMMON_INC)/os_if/linux/cp_stats/inc
+CP_STATS_TGT_INC                := -I$(WLAN_COMMON_INC)/target_if/cp_stats/inc
+CP_STATS_DISPATCHER_INC         := -I$(WLAN_COMMON_INC)/umac/cp_stats/dispatcher/inc
+CP_MC_STATS_COMPONENT_INC       := -I$(WLAN_ROOT)/components/cp_stats/dispatcher/inc
+CP_STATS_CFG80211_OS_IF_INC     := -I$(WLAN_ROOT)/os_if/cp_stats/inc
+
+ifeq ($(CONFIG_CP_STATS), y)
+CP_STATS_OBJS := $(CP_MC_STATS_COMPONENT_SRC)/wlan_cp_stats_mc_tgt_api.o	\
+		 $(CP_MC_STATS_COMPONENT_SRC)/wlan_cp_stats_mc_ucfg_api.o	\
+		 $(CP_MC_STATS_COMPONENT_TGT_SRC)/target_if_mc_cp_stats.o	\
+		 $(CP_STATS_CORE_SRC)/wlan_cp_stats_comp_handler.o		\
+		 $(CP_STATS_CORE_SRC)/wlan_cp_stats_obj_mgr_handler.o		\
+		 $(CP_STATS_CORE_SRC)/wlan_cp_stats_ol_api.o			\
+		 $(CP_MC_STATS_OS_IF_SRC)/wlan_cfg80211_mc_cp_stats.o		\
+		 $(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_utils_api.o		\
+		 $(WLAN_COMMON_ROOT)/target_if/cp_stats/src/target_if_cp_stats.o	\
+		 $(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_ucfg_api.o
+
+endif
+
+$(call add-wlan-objs,cp_stats,$(CP_STATS_OBJS))
+
+###### DCS ######
+DCS_TGT_IF_SRC := $(WLAN_COMMON_ROOT)/target_if/dcs/src
+DCS_CORE_SRC   := $(WLAN_COMMON_ROOT)/umac/dcs/core/src
+DCS_DISP_SRC   := $(WLAN_COMMON_ROOT)/umac/dcs/dispatcher/src
+
+DCS_TGT_IF_INC := -I$(WLAN_COMMON_INC)/target_if/dcs/inc
+DCS_DISP_INC   := -I$(WLAN_COMMON_INC)/umac/dcs/dispatcher/inc
+
+ifeq ($(CONFIG_DCS), y)
+DCS_OBJS := $(DCS_TGT_IF_SRC)/target_if_dcs.o \
+	$(DCS_CORE_SRC)/wlan_dcs.o \
+	$(DCS_DISP_SRC)/wlan_dcs_init_deinit_api.o \
+	$(DCS_DISP_SRC)/wlan_dcs_ucfg_api.o \
+	$(DCS_DISP_SRC)/wlan_dcs_tgt_api.o
+endif
+
+$(call add-wlan-objs,dcs,$(DCS_OBJS))
+
+####### AFC ######
+AFC_CMN_OSIF_SRC  := $(WLAN_COMMON_ROOT)/os_if/linux/afc/src
+AFC_CMN_CORE_SRC  := $(WLAN_COMMON_ROOT)/umac/afc/core/src
+AFC_CMN_DISP_SRC  := $(WLAN_COMMON_ROOT)/umac/afc/dispatcher/src
+
+AFC_CMN_OSIF_INC  := -I$(WLAN_COMMON_INC)/os_if/linux/afc/inc
+AFC_CMN_DISP_INC  := -I$(WLAN_COMMON_INC)/umac/afc/dispatcher/inc
+AFC_CMN_CORE_INC  := -I$(WLAN_COMMON_INC)/umac/afc/core/inc
+
+ifeq ($(CONFIG_AFC_SUPPORT), y)
+AFC_OBJS := $(AFC_CMN_OSIF_SRC)/wlan_cfg80211_afc.o \
+	    $(AFC_CMN_CORE_SRC)/wlan_afc_main.o \
+	    $(AFC_CMN_DISP_SRC)/wlan_afc_ucfg_api.o
+endif
+
+$(call add-wlan-objs,afc,$(AFC_OBJS))
+
+###### INTEROP ISSUES AP ########
+INTEROP_ISSUES_AP_OS_IF_SRC      := os_if/interop_issues_ap/src
+INTEROP_ISSUES_AP_TGT_SRC        := components/target_if/interop_issues_ap/src
+INTEROP_ISSUES_AP_CORE_SRC       := components/interop_issues_ap/core/src
+INTEROP_ISSUES_AP_DISPATCHER_SRC := components/interop_issues_ap/dispatcher/src
+
+INTEROP_ISSUES_AP_OS_IF_INC      := -I$(WLAN_ROOT)/os_if/interop_issues_ap/inc
+INTEROP_ISSUES_AP_TGT_INC        := -I$(WLAN_ROOT)/components/target_if/interop_issues_ap/inc
+INTEROP_ISSUES_AP_DISPATCHER_INC := -I$(WLAN_ROOT)/components/interop_issues_ap/dispatcher/inc
+INTEROP_ISSUES_AP_CORE_INC       := -I$(WLAN_ROOT)/components/interop_issues_ap/core/inc
+
+ifeq ($(CONFIG_FEATURE_INTEROP_ISSUES_AP), y)
+INTEROP_ISSUES_AP_OBJS := $(INTEROP_ISSUES_AP_TGT_SRC)/target_if_interop_issues_ap.o \
+		$(INTEROP_ISSUES_AP_CORE_SRC)/wlan_interop_issues_ap_api.o \
+		$(INTEROP_ISSUES_AP_OS_IF_SRC)/wlan_cfg80211_interop_issues_ap.o \
+		$(INTEROP_ISSUES_AP_DISPATCHER_SRC)/wlan_interop_issues_ap_tgt_api.o \
+		$(INTEROP_ISSUES_AP_DISPATCHER_SRC)/wlan_interop_issues_ap_ucfg_api.o
+endif
+
+$(call add-wlan-objs,interop_issues_ap,$(INTEROP_ISSUES_AP_OBJS))
+
+######################### NAN #########################
+NAN_CORE_DIR := components/nan/core/src
+NAN_CORE_INC := -I$(WLAN_ROOT)/components/nan/core/inc
+NAN_UCFG_DIR := components/nan/dispatcher/src
+NAN_UCFG_INC := -I$(WLAN_ROOT)/components/nan/dispatcher/inc
+NAN_TGT_DIR  := components/target_if/nan/src
+NAN_TGT_INC  := -I$(WLAN_ROOT)/components/target_if/nan/inc
+
+NAN_OS_IF_DIR  := os_if/nan/src
+NAN_OS_IF_INC  := -I$(WLAN_ROOT)/os_if/nan/inc
+
+ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
+WLAN_NAN_OBJS := $(NAN_CORE_DIR)/nan_main.o \
+		 $(NAN_CORE_DIR)/nan_api.o \
+		 $(NAN_UCFG_DIR)/nan_ucfg_api.o \
+		 $(NAN_UCFG_DIR)/wlan_nan_api.o \
+		 $(NAN_UCFG_DIR)/cfg_nan.o \
+		 $(NAN_TGT_DIR)/target_if_nan.o \
+		 $(NAN_OS_IF_DIR)/os_if_nan.o
+endif
+
+$(call add-wlan-objs,nan,$(WLAN_NAN_OBJS))
+
+#######################################################
+
+######################### DP_COMPONENT #########################
+DP_COMP_CORE_DIR := components/dp/core/src
+DP_COMP_UCFG_DIR := components/dp/dispatcher/src
+DP_COMP_TGT_DIR  := components/target_if/dp/src
+DP_COMP_OS_IF_DIR  := os_if/dp/src
+
+DP_COMP_INC	:= -I$(WLAN_ROOT)/components/dp/core/inc	\
+		-I$(WLAN_ROOT)/components/dp/core/src		\
+		-I$(WLAN_ROOT)/components/dp/dispatcher/inc	\
+		-I$(WLAN_ROOT)/components/target_if/dp/inc	\
+		-I$(WLAN_ROOT)/os_if/dp/inc
+
+WLAN_DP_COMP_OBJS := $(DP_COMP_CORE_DIR)/wlan_dp_main.o \
+		 $(DP_COMP_UCFG_DIR)/wlan_dp_ucfg_api.o \
+		$(DP_COMP_UCFG_DIR)/wlan_dp_api.o \
+		 $(DP_COMP_OS_IF_DIR)/os_if_dp.o \
+		 $(DP_COMP_OS_IF_DIR)/os_if_dp_txrx.o \
+		 $(DP_COMP_CORE_DIR)/wlan_dp_bus_bandwidth.o \
+		 $(DP_COMP_CORE_DIR)/wlan_dp_softap_txrx.o \
+		 $(DP_COMP_CORE_DIR)/wlan_dp_txrx.o \
+		 $(DP_COMP_TGT_DIR)/target_if_dp_comp.o
+
+ifeq ($(CONFIG_WLAN_LRO), y)
+WLAN_DP_COMP_OBJS += $(DP_COMP_OS_IF_DIR)/os_if_dp_lro.o
+endif
+
+ifeq ($(CONFIG_WLAN_NUD_TRACKING), y)
+WLAN_DP_COMP_OBJS += $(DP_COMP_CORE_DIR)/wlan_dp_nud_tracking.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_PERIODIC_STA_STATS), y)
+WLAN_DP_COMP_OBJS += $(DP_COMP_CORE_DIR)/wlan_dp_periodic_sta_stats.o
+endif
+
+ifeq ($(CONFIG_DP_SWLM), y)
+WLAN_DP_COMP_OBJS += $(DP_COMP_CORE_DIR)/wlan_dp_swlm.o
+endif
+
+ifeq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM) $(CONFIG_RHINE)))
+WLAN_DP_COMP_OBJS += $(DP_COMP_CORE_DIR)/wlan_dp_prealloc.o
+
+ifeq ($(CONFIG_WLAN_TX_MON_2_0), y)
+ifeq ($(CONFIG_WLAN_DP_LOCAL_PKT_CAPTURE), y)
+WLAN_DP_COMP_OBJS += $(DP_COMP_OS_IF_DIR)/os_if_dp_local_pkt_capture.o
+endif #CONFIG_WLAN_DP_LOCAL_PKT_CAPTURE
+endif #CONFIG_WLAN_TX_MON_2_0
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DP_RX_THREADS), y)
+WLAN_DP_COMP_OBJS += $(DP_COMP_CORE_DIR)/wlan_dp_rx_thread.o
+endif
+
+ifeq ($(CONFIG_RX_FISA), y)
+WLAN_DP_COMP_OBJS += $(DP_COMP_CORE_DIR)/wlan_dp_fisa_rx.o
+WLAN_DP_COMP_OBJS += $(DP_COMP_CORE_DIR)/wlan_dp_rx_fst.o
+endif
+
+ifeq ($(CONFIG_FEATURE_DIRECT_LINK), y)
+WLAN_DP_COMP_OBJS += $(DP_COMP_CORE_DIR)/wlan_dp_wfds.o
+endif
+
+$(call add-wlan-objs,dp_comp,$(WLAN_DP_COMP_OBJS))
+
+#######################################################
+
+######################### QMI_COMPONENT #########################
+QMI_COMP_CORE_DIR := components/qmi/core/src
+QMI_COMP_UCFG_DIR := components/qmi/dispatcher/src
+QMI_COMP_OS_IF_DIR := os_if/qmi/src
+
+QMI_COMP_INC := -I$(WLAN_ROOT)/components/qmi/core/inc       \
+		-I$(WLAN_ROOT)/components/qmi/core/src       \
+		-I$(WLAN_ROOT)/components/qmi/dispatcher/inc \
+		-I$(WLAN_ROOT)/os_if/qmi/inc
+
+ifeq ($(CONFIG_QMI_COMPONENT_ENABLE), y)
+WLAN_QMI_COMP_OBJS := $(QMI_COMP_CORE_DIR)/wlan_qmi_main.o \
+		 $(QMI_COMP_UCFG_DIR)/wlan_qmi_ucfg_api.o  \
+		 $(QMI_COMP_OS_IF_DIR)/os_if_qmi.o
+
+ifeq ($(CONFIG_QMI_WFDS), y)
+WLAN_QMI_COMP_OBJS += $(QMI_COMP_OS_IF_DIR)/os_if_qmi_wifi_driver_service_v01.o
+WLAN_QMI_COMP_OBJS += $(QMI_COMP_OS_IF_DIR)/os_if_qmi_wfds.o
+WLAN_QMI_COMP_OBJS += $(QMI_COMP_UCFG_DIR)/wlan_qmi_wfds_api.o
+endif
+endif
+
+$(call add-wlan-objs,qmi_comp,$(WLAN_QMI_COMP_OBJS))
+
+#######################################################
+
+######################### SON #########################
+#SON_CORE_DIR := components/son/core/src
+#SON_CORE_INC := -I$(WLAN_ROOT)/components/son/core/inc
+SON_UCFG_DIR := components/son/dispatcher/src
+SON_UCFG_INC := -I$(WLAN_ROOT)/components/son/dispatcher/inc
+SON_TGT_DIR  := $(WLAN_COMMON_ROOT)/target_if/son/src
+SON_TGT_INC  := -I$(WLAN_COMMON_INC)/target_if/son/inc/
+
+SON_OS_IF_DIR  := os_if/son/src
+SON_OS_IF_INC  := -I$(WLAN_ROOT)/os_if/son/inc
+
+ifeq ($(CONFIG_QCACLD_FEATURE_SON), y)
+WLAN_SON_OBJS := $(SON_UCFG_DIR)/son_ucfg_api.o \
+		 $(SON_UCFG_DIR)/son_api.o \
+		 $(SON_OS_IF_DIR)/os_if_son.o \
+		 $(SON_TGT_DIR)/target_if_son.o
+endif
+
+$(call add-wlan-objs,son,$(WLAN_SON_OBJS))
+
+#######################################################
+
+######################### SPATIAL_REUSE #########################
+SR_UCFG_DIR := components/spatial_reuse/dispatcher/src
+SR_UCFG_INC := -I$(WLAN_ROOT)/components/spatial_reuse/dispatcher/inc
+SR_TGT_DIR  := $(WLAN_COMMON_ROOT)/target_if/spatial_reuse/src
+SR_TGT_INC  := -I$(WLAN_COMMON_INC)/target_if/spatial_reuse/inc/
+
+ifeq ($(CONFIG_WLAN_FEATURE_SR), y)
+WLAN_SR_OBJS := $(SR_UCFG_DIR)/spatial_reuse_ucfg_api.o \
+		 $(SR_UCFG_DIR)/spatial_reuse_api.o \
+		 $(SR_TGT_DIR)/target_if_spatial_reuse.o
+endif
+
+$(call add-wlan-objs,spatial_reuse,$(WLAN_SR_OBJS))
+
+#######################################################
+
+###### COEX ########
+COEX_OS_IF_SRC      := os_if/coex/src
+COEX_TGT_SRC        := components/target_if/coex/src
+COEX_CORE_SRC       := components/coex/core/src
+COEX_DISPATCHER_SRC := components/coex/dispatcher/src
+
+COEX_OS_IF_INC      := -I$(WLAN_ROOT)/os_if/coex/inc
+COEX_TGT_INC        := -I$(WLAN_ROOT)/components/target_if/coex/inc
+COEX_DISPATCHER_INC := -I$(WLAN_ROOT)/components/coex/dispatcher/inc
+COEX_CORE_INC       := -I$(WLAN_ROOT)/components/coex/core/inc
+COEX_STRUCT_INC     := -I$(WLAN_COMMON_INC)/coex/dispatcher/inc
+
+ifeq ($(CONFIG_FEATURE_COEX), y)
+COEX_OBJS := $(COEX_TGT_SRC)/target_if_coex.o                 \
+		 $(COEX_CORE_SRC)/wlan_coex_main.o                 \
+		 $(COEX_OS_IF_SRC)/wlan_cfg80211_coex.o           \
+		 $(COEX_DISPATCHER_SRC)/wlan_coex_tgt_api.o       \
+		 $(COEX_DISPATCHER_SRC)/wlan_coex_utils_api.o       \
+		 $(COEX_DISPATCHER_SRC)/wlan_coex_ucfg_api.o
+endif
+
+$(call add-wlan-objs,coex,$(COEX_OBJS))
+
+###### COAP ########
+ifeq ($(CONFIG_WLAN_FEATURE_COAP), y)
+COAP_HDD_SRC := core/hdd/src
+COAP_OS_IF_SRC := os_if/coap/src
+COAP_TGT_SRC := components/target_if/coap/src
+COAP_CORE_SRC  := components/coap/core/src
+COAP_DISPATCHER_SRC := components/coap/dispatcher/src
+COAP_WMI_SRC := components/wmi/src
+
+COAP_OS_IF_INC  := -I$(WLAN_ROOT)/os_if/coap/inc
+COAP_TGT_INC := -I$(WLAN_ROOT)/components/target_if/coap/inc
+COAP_DISPATCHER_INC := -I$(WLAN_ROOT)/components/coap/dispatcher/inc
+COAP_CORE_INC := -I$(WLAN_ROOT)/components/coap/core/inc
+COAP_WMI_INC := -I$(WLAN_ROOT)/components/wmi/inc
+
+COAP_OBJS := \
+	$(COAP_HDD_SRC)/wlan_hdd_coap.o \
+	$(COAP_OS_IF_SRC)/wlan_cfg80211_coap.o \
+	$(COAP_TGT_SRC)/target_if_coap.o  \
+	$(COAP_CORE_SRC)/wlan_coap_main.o  \
+	$(COAP_DISPATCHER_SRC)/wlan_coap_tgt_api.o \
+	$(COAP_DISPATCHER_SRC)/wlan_coap_ucfg_api.o \
+	$(COAP_WMI_SRC)/wmi_unified_coap_tlv.o
+$(call add-wlan-objs,coap,$(COAP_OBJS))
+endif
+
+############## HTC ##########
+HTC_DIR := htc
+HTC_INC := -I$(WLAN_COMMON_INC)/$(HTC_DIR)
+
+HTC_OBJS := $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc.o \
+            $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_send.o \
+            $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_recv.o \
+            $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_services.o
+
+ifeq ($(CONFIG_FEATURE_HTC_CREDIT_HISTORY), y)
+HTC_OBJS += $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_credit_history.o
+endif
+
+ifeq ($(CONFIG_WLAN_HANG_EVENT), y)
+HTC_OBJS += $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_hang_event.o
+endif
+
+$(call add-wlan-objs,htc,$(HTC_OBJS))
+
+########### HIF ###########
+HIF_DIR := hif
+HIF_CE_DIR := $(HIF_DIR)/src/ce
+
+HIF_DISPATCHER_DIR := $(HIF_DIR)/src/dispatcher
+
+HIF_PCIE_DIR := $(HIF_DIR)/src/pcie
+HIF_IPCIE_DIR := $(HIF_DIR)/src/ipcie
+HIF_SNOC_DIR := $(HIF_DIR)/src/snoc
+HIF_USB_DIR := $(HIF_DIR)/src/usb
+HIF_SDIO_DIR := $(HIF_DIR)/src/sdio
+
+HIF_SDIO_NATIVE_DIR := $(HIF_SDIO_DIR)/native_sdio
+HIF_SDIO_NATIVE_INC_DIR := $(HIF_SDIO_NATIVE_DIR)/include
+HIF_SDIO_NATIVE_SRC_DIR := $(HIF_SDIO_NATIVE_DIR)/src
+
+HIF_INC := -I$(WLAN_COMMON_INC)/$(HIF_DIR)/inc \
+	   -I$(WLAN_COMMON_INC)/$(HIF_DIR)/src
+
+ifeq ($(CONFIG_HIF_PCI), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_PCIE_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR)
+endif
+
+ifeq ($(CONFIG_HIF_IPCI), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_IPCIE_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR)
+endif
+
+ifeq ($(CONFIG_HIF_SNOC), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_SNOC_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR)
+endif
+
+ifeq ($(CONFIG_HIF_USB), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_USB_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR)
+endif
+
+ifeq ($(CONFIG_HIF_SDIO), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_SDIO_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_SDIO_NATIVE_INC_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR)
+endif
+
+HIF_COMMON_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/ath_procfs.o \
+		   $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_main.o \
+		   $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_runtime_pm.o \
+		   $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_exec.o
+
+ifneq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM)))
+HIF_COMMON_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_main_legacy.o
+endif
+
+ifeq ($(CONFIG_WLAN_NAPI), y)
+HIF_COMMON_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_irq_affinity.o
+endif
+
+HIF_CE_OBJS :=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_diag.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_main.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_tasklet.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/mp_dev.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/regtable.o
+
+ifeq ($(CONFIG_WLAN_FEATURE_BMI), y)
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_bmi.o
+endif
+
+ifeq ($(CONFIG_LITHIUM), y)
+ifeq ($(CONFIG_CNSS_QCA6290), y)
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/qca6290def.o
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6390), y)
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/qca6390def.o
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6490), y)
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/qca6490def.o
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6750), y)
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/qca6750def.o
+endif
+
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service_srng.o
+else ifeq ($(CONFIG_BERYLLIUM), y)
+ifeq (y,$(findstring y,$(CONFIG_CNSS_KIWI) $(CONFIG_CNSS_KIWI_V2) $CONFIG_CNSS_PEACH))
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/kiwidef.o
+endif
+
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service_srng.o
+else
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service_legacy.o
+endif
+
+HIF_USB_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/usbdrv.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/hif_usb.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/if_usb.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/regtable_usb.o
+
+HIF_SDIO_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_diag_reg_access.o \
+                 $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_sdio_dev.o \
+                 $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_sdio.o \
+                 $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/regtable_sdio.o \
+                 $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/transfer/transfer.o
+
+ifeq ($(CONFIG_WLAN_FEATURE_BMI), y)
+HIF_SDIO_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_bmi_reg_access.o
+endif
+
+ifeq ($(CONFIG_SDIO_TRANSFER), adma)
+HIF_SDIO_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/transfer/adma.o
+else
+HIF_SDIO_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/transfer/mailbox.o
+endif
+
+HIF_SDIO_NATIVE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/hif.o \
+                        $(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/hif_scatter.o \
+                        $(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/dev_quirks.o
+
+ifeq ($(CONFIG_WLAN_NAPI), y)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_napi.o
+endif
+
+ifeq ($(CONFIG_FEATURE_UNIT_TEST_SUSPEND), y)
+	HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_unit_test_suspend.o
+endif
+
+HIF_PCIE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_PCIE_DIR)/if_pci.o
+HIF_IPCIE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_IPCIE_DIR)/if_ipci.o
+HIF_SNOC_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SNOC_DIR)/if_snoc.o
+HIF_SDIO_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/if_sdio.o
+
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus.o
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/dummy.o
+HIF_OBJS += $(HIF_COMMON_OBJS)
+
+ifeq ($(CONFIG_HIF_PCI), y)
+HIF_OBJS += $(HIF_PCIE_OBJS)
+HIF_OBJS += $(HIF_CE_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_pci.o
+endif
+
+ifeq ($(CONFIG_HIF_IPCI), y)
+HIF_OBJS += $(HIF_IPCIE_OBJS)
+HIF_OBJS += $(HIF_CE_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_ipci.o
+endif
+
+ifeq ($(CONFIG_HIF_SNOC), y)
+HIF_OBJS += $(HIF_SNOC_OBJS)
+HIF_OBJS += $(HIF_CE_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_snoc.o
+endif
+
+ifeq ($(CONFIG_HIF_SDIO), y)
+HIF_OBJS += $(HIF_SDIO_OBJS)
+HIF_OBJS += $(HIF_SDIO_NATIVE_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_sdio.o
+endif
+
+ifeq ($(CONFIG_HIF_USB), y)
+HIF_OBJS += $(HIF_USB_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_usb.o
+endif
+
+$(call add-wlan-objs,hif,$(HIF_OBJS))
+
+############ HAL ############
+ifeq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM) $(CONFIG_RHINE)))
+HAL_DIR :=	hal
+HAL_INC :=	-I$(WLAN_COMMON_INC)/$(HAL_DIR)/inc \
+		-I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0
+
+#TODO fix hal_reo for RHINE
+HAL_OBJS :=	$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/hal_srng.o \
+		$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/hal_reo.o
+
+ifeq ($(CONFIG_RX_FISA), y)
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/hal_rx_flow.o
+endif
+endif #### CONFIG LITHIUM/BERYLLIUM/RHINE ####
+
+ifeq ($(CONFIG_LITHIUM), y)
+HAL_INC += 	-I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/li
+
+HAL_OBJS +=	$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/li/hal_li_generic_api.o
+
+HAL_OBJS +=	$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/li/hal_li_reo.o
+
+ifeq ($(CONFIG_CNSS_QCA6290), y)
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/qca6290
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/qca6290/hal_6290.o
+else ifeq ($(CONFIG_CNSS_QCA6390), y)
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/qca6390
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/qca6390/hal_6390.o
+else ifeq ($(CONFIG_CNSS_QCA6490), y)
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/qca6490
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/qca6490/hal_6490.o
+else ifeq ($(CONFIG_CNSS_QCA6750), y)
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/qca6750
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/qca6750/hal_6750.o
+else
+#error "Not 11ax"
+endif
+
+endif #####CONFIG_LITHIUM####
+
+ifeq ($(CONFIG_BERYLLIUM), y)
+HAL_INC += 	-I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/be
+
+HAL_OBJS +=	$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/be/hal_be_generic_api.o
+
+HAL_OBJS +=	$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/be/hal_be_reo.o \
+
+ifeq (y,$(findstring y,$(CONFIG_INCLUDE_HAL_PEACH)))
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/peach
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/peach/hal_peach.o
+ccflags-y += -DINCLUDE_HAL_PEACH
+else ifeq (y,$(findstring y,$(CONFIG_INCLUDE_HAL_KIWI)))
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/kiwi
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/kiwi/hal_kiwi.o
+ccflags-y += -DINCLUDE_HAL_KIWI
+endif
+
+endif #### CONFIG_BERYLLIUM ####
+
+ifeq ($(CONFIG_RHINE), y)
+HAL_INC += 	-I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/rh
+
+HAL_OBJS +=	$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/rh/hal_rh_generic_api.o
+
+ifeq ($(CONFIG_CNSS_WCN6450), y)
+#TODO fix this for RHINE
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/wcn6450
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/wcn6450/hal_wcn6450.o
+else
+#error "Not RHINE"
+endif
+
+endif #####CONFIG_RHINE####
+
+$(call add-wlan-objs,hal,$(HAL_OBJS))
+
+############ WMA ############
+WMA_DIR :=	core/wma
+
+WMA_INC_DIR :=  $(WMA_DIR)/inc
+WMA_SRC_DIR :=  $(WMA_DIR)/src
+
+WMA_INC :=	-I$(WLAN_ROOT)/$(WMA_INC_DIR) \
+		-I$(WLAN_ROOT)/$(WMA_SRC_DIR)
+
+ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
+WMA_NDP_OBJS += $(WMA_SRC_DIR)/wma_nan_datapath.o
+endif
+
+WMA_OBJS :=	$(WMA_SRC_DIR)/wma_main.o \
+		$(WMA_SRC_DIR)/wma_scan_roam.o \
+		$(WMA_SRC_DIR)/wma_dev_if.o \
+		$(WMA_SRC_DIR)/wma_mgmt.o \
+		$(WMA_SRC_DIR)/wma_power.o \
+		$(WMA_SRC_DIR)/wma_data.o \
+		$(WMA_SRC_DIR)/wma_utils.o \
+		$(WMA_SRC_DIR)/wma_features.o \
+		$(WMA_SRC_DIR)/wlan_qct_wma_legacy.o\
+		$(WMA_NDP_OBJS)
+
+ifeq ($(CONFIG_WLAN_FEATURE_11BE), y)
+WMA_OBJS +=	$(WMA_SRC_DIR)/wma_eht.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+WMA_OBJS+=	$(WMA_SRC_DIR)/wma_ocb.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_FIPS), y)
+WMA_OBJS+=	$(WMA_SRC_DIR)/wma_fips_api.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_11AX), y)
+WMA_OBJS+=	$(WMA_SRC_DIR)/wma_he.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
+WMA_OBJS +=	$(WMA_SRC_DIR)/wma_twt.o
+endif
+ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y)
+WMA_OBJS +=	$(WMA_SRC_DIR)/wma_fw_state.o
+endif
+ifeq ($(CONFIG_WLAN_MWS_INFO_DEBUGFS), y)
+WMA_OBJS +=	$(WMA_SRC_DIR)/wma_coex.o
+endif
+ifeq ($(CONFIG_WIFI_POS_CONVERGED), y)
+ifeq ($(CONFIG_WIFI_POS_PASN), y)
+WMA_OBJS +=	$(WMA_SRC_DIR)/wma_pasn_peer_api.o
+endif
+endif
+
+$(call add-wlan-objs,wma,$(WMA_OBJS))
+
+#######DIRECT_BUFFER_RX#########
+ifeq ($(CONFIG_DIRECT_BUF_RX_ENABLE), y)
+DBR_DIR = $(WLAN_COMMON_ROOT)/target_if/direct_buf_rx
+UMAC_DBR_INC := -I$(WLAN_COMMON_INC)/target_if/direct_buf_tx/inc
+UMAC_DBR_OBJS := $(DBR_DIR)/src/target_if_direct_buf_rx_api.o \
+		 $(DBR_DIR)/src/target_if_direct_buf_rx_main.o \
+		 $(WLAN_COMMON_ROOT)/wmi/src/wmi_unified_dbr_api.o \
+		 $(WLAN_COMMON_ROOT)/wmi/src/wmi_unified_dbr_tlv.o
+endif
+
+$(call add-wlan-objs,umac_dbr,$(UMAC_DBR_OBJS))
+
+############## PLD ##########
+PLD_DIR := core/pld
+PLD_INC_DIR := $(PLD_DIR)/inc
+PLD_SRC_DIR := $(PLD_DIR)/src
+
+PLD_INC :=	-I$(WLAN_ROOT)/$(PLD_INC_DIR) \
+		-I$(WLAN_ROOT)/$(PLD_SRC_DIR)
+
+PLD_OBJS :=	$(PLD_SRC_DIR)/pld_common.o
+
+ifeq ($(CONFIG_IPCIE_FW_SIM), y)
+PLD_OBJS +=     $(PLD_SRC_DIR)/pld_pcie_fw_sim.o
+endif
+ifeq ($(CONFIG_PCIE_FW_SIM), y)
+PLD_OBJS +=     $(PLD_SRC_DIR)/pld_pcie_fw_sim.o
+else ifeq ($(CONFIG_HIF_PCI), y)
+PLD_OBJS +=     $(PLD_SRC_DIR)/pld_pcie.o
+endif
+ifeq ($(CONFIG_SNOC_FW_SIM),y)
+PLD_OBJS +=     $(PLD_SRC_DIR)/pld_snoc_fw_sim.o
+else ifeq (y,$(findstring y, $(CONFIG_ICNSS) $(CONFIG_PLD_SNOC_ICNSS_FLAG)))
+PLD_OBJS +=     $(PLD_SRC_DIR)/pld_snoc.o
+else ifeq (y,$(findstring y, $(CONFIG_PLD_IPCI_ICNSS_FLAG)))
+PLD_OBJS +=     $(PLD_SRC_DIR)/pld_ipci.o
+endif
+
+ifeq ($(CONFIG_QCA_WIFI_SDIO), y)
+PLD_OBJS +=	$(PLD_SRC_DIR)/pld_sdio.o
+endif
+ifeq ($(CONFIG_HIF_USB), y)
+PLD_OBJS +=	$(PLD_SRC_DIR)/pld_usb.o
+endif
+
+$(call add-wlan-objs,pld,$(PLD_OBJS))
+
+
+TARGET_INC := 	-I$(WLAN_FW_API)/fw
+
+ifeq ($(CONFIG_CNSS_QCA6290), y)
+ifeq ($(CONFIG_QCA6290_11AX), y)
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/qca6290/11ax/v2
+else
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/qca6290/v2
+endif
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6390), y)
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/qca6390/v1
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6490), y)
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/qca6490/v1
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6750), y)
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/qca6750/v1
+endif
+
+ifeq ($(CONFIG_CNSS_WCN6450), y)
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/wcn6450/v1
+endif
+
+ifeq ($(CONFIG_CNSS_PEACH), y)
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/peach/v1/
+else
+ifeq ($(CONFIG_CNSS_KIWI_V2), y)
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/kiwi/v2/
+else
+ifeq ($(CONFIG_CNSS_KIWI), y)
+TARGET_INC +=	-I$(WLAN_FW_API)/hw/kiwi/v1/
+endif
+endif
+endif
+
+LINUX_INC :=	-Iinclude
+
+INCS :=		$(HDD_INC) \
+		$(SYNC_INC) \
+		$(DSC_INC) \
+		$(EPPING_INC) \
+		$(LINUX_INC) \
+		$(MAC_INC) \
+		$(SAP_INC) \
+		$(SME_INC) \
+		$(SYS_INC) \
+		$(CLD_WMI_INC) \
+		$(QAL_INC) \
+		$(QDF_INC) \
+		$(WBUFF_INC) \
+		$(CDS_INC) \
+		$(CFG_INC) \
+		$(DFS_INC) \
+		$(TARGET_IF_INC) \
+		$(CLD_TARGET_IF_INC) \
+		$(OS_IF_INC) \
+		$(GLOBAL_LMAC_IF_INC) \
+		$(FTM_INC)
+
+INCS +=		$(WMA_INC) \
+		$(UAPI_INC) \
+		$(COMMON_INC) \
+		$(WMI_INC) \
+		$(FWLOG_INC) \
+		$(TXRX_INC) \
+		$(OL_INC) \
+		$(CDP_INC) \
+		$(PKTLOG_INC) \
+		$(HTT_INC) \
+		$(INIT_DEINIT_INC) \
+		$(SCHEDULER_INC) \
+		$(REGULATORY_INC) \
+		$(HTC_INC) \
+		$(WCFG_INC)
+
+INCS +=		$(HIF_INC) \
+		$(BMI_INC) \
+		$(CMN_SYS_INC)
+
+ifeq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM) $(CONFIG_RHINE)))
+INCS += 	$(HAL_INC) \
+		$(DP_INC)
+endif
+
+################ WIFI POS ################
+INCS +=		$(WIFI_POS_CLD_INC)
+INCS +=		$(WIFI_POS_API_INC)
+INCS +=		$(WIFI_POS_TGT_INC)
+INCS +=		$(WIFI_POS_OS_IF_INC)
+################ CP STATS ################
+INCS +=		$(CP_STATS_OS_IF_INC)
+INCS +=		$(CP_STATS_TGT_INC)
+INCS +=		$(CP_STATS_DISPATCHER_INC)
+INCS +=		$(CP_MC_STATS_COMPONENT_INC)
+INCS +=		$(CP_STATS_CFG80211_OS_IF_INC)
+################ TWT CONVERGED ################
+INCS +=		$(TWT_CONV_INCS)
+################ Dynamic ACS ####################
+INCS +=		$(DCS_TGT_IF_INC)
+INCS +=		$(DCS_DISP_INC)
+################ AFC #################
+INCS +=		$(AFC_CMN_OSIF_INC)
+INCS +=		$(AFC_CMN_DISP_INC)
+INCS +=		$(AFC_CMN_CORE_INC)
+################ INTEROP ISSUES AP ################
+INCS +=		$(INTEROP_ISSUES_AP_OS_IF_INC)
+INCS +=		$(INTEROP_ISSUES_AP_TGT_INC)
+INCS +=		$(INTEROP_ISSUES_AP_DISPATCHER_INC)
+INCS +=		$(INTEROP_ISSUES_AP_CORE_INC)
+################ NAN POS ################
+INCS +=		$(NAN_CORE_INC)
+INCS +=		$(NAN_UCFG_INC)
+INCS +=		$(NAN_TGT_INC)
+INCS +=		$(NAN_OS_IF_INC)
+###########DP_COMPONENT ####################
+INCS +=		$(DP_COMP_INC)
+###########QMI_COMPONENT ####################
+INCS +=		$(QMI_COMP_INC)
+################ SON ################
+INCS +=		$(SON_CORE_INC)
+INCS +=		$(SON_UCFG_INC)
+INCS +=		$(SON_TGT_INC)
+INCS +=		$(SON_OS_IF_INC)
+################ SPATIAL_REUSE ################
+INCS +=		$(SR_UCFG_INC)
+INCS +=		$(SR_TGT_INC)
+##########################################
+
+INCS +=		$(UMAC_OBJMGR_INC)
+INCS +=		$(UMAC_MGMT_TXRX_INC)
+INCS +=		$(PMO_INC)
+INCS +=		$(P2P_INC)
+INCS +=		$(POLICY_MGR_INC)
+INCS +=		$(TARGET_INC)
+INCS +=		$(TDLS_INC)
+INCS +=		$(UMAC_SER_INC)
+INCS +=		$(NLINK_INC) \
+		$(PTT_INC) \
+		$(WLAN_LOGGING_INC)
+
+INCS +=		$(PLD_INC)
+INCS +=		$(OCB_INC)
+
+INCS +=		$(IPA_INC)
+INCS +=		$(UMAC_SM_INC)
+INCS +=		$(UMAC_MLME_INC)
+INCS +=		$(MLME_INC)
+INCS +=		$(FWOL_INC)
+INCS +=		$(DLM_INC)
+INCS +=		$(CONN_LOGGING_INC)
+
+ifeq ($(CONFIG_REMOVE_PKT_LOG), n)
+INCS +=		$(PKTLOG_INC)
+endif
+
+INCS +=		$(HOST_DIAG_LOG_INC)
+
+INCS +=		$(DISA_INC)
+INCS +=		$(ACTION_OUI_INC)
+INCS +=		$(PKT_CAPTURE_INC)
+INCS +=		$(FTM_TIME_SYNC_INC)
+INCS +=		$(WLAN_PRE_CAC_INC)
+
+INCS +=		$(UMAC_DISP_INC)
+INCS +=		$(UMAC_SCAN_INC)
+INCS +=		$(UMAC_TARGET_SCAN_INC)
+INCS +=		$(UMAC_GREEN_AP_INC)
+INCS +=		$(UMAC_TARGET_GREEN_AP_INC)
+INCS +=		$(UMAC_COMMON_INC)
+INCS +=		$(UMAC_SPECTRAL_INC)
+INCS +=		$(WLAN_CFR_INC)
+INCS +=		$(UMAC_TARGET_SPECTRAL_INC)
+INCS +=		$(UMAC_GPIO_INC)
+INCS +=		$(UMAC_TARGET_GPIO_INC)
+INCS +=		$(UMAC_DBR_INC)
+INCS +=		$(UMAC_CRYPTO_INC)
+INCS +=		$(UMAC_INTERFACE_MGR_INC)
+INCS +=		$(UMAC_MLO_MGR_INC)
+INCS +=		$(UMAC_MLO_MGR_CLD_INC)
+INCS +=		$(COEX_OS_IF_INC)
+INCS +=		$(COEX_TGT_INC)
+INCS +=		$(COEX_DISPATCHER_INC)
+INCS +=		$(COEX_CORE_INC)
+INCS +=		$(COEX_STRUCT_INC)
+################ COAP ################
+INCS +=		$(COAP_OS_IF_INC)
+INCS +=		$(COAP_TGT_INC)
+INCS +=		$(COAP_DISPATCHER_INC)
+INCS +=		$(COAP_CORE_INC)
+INCS +=		$(COAP_WMI_INC)
+
+ccflags-y += $(INCS)
+
+ccflags-y += -include $(WLAN_ROOT)/configs/default_config.h
+
+# CFG80211_MLO_KEY_OPERATION_SUPPORT
+# Used to indicate the Linux Kernel contains support for ML key operation
+# support.
+#
+# This feature was backported to Android Common Kernel 5.15 via:
+# https://android-review.googlesource.com/c/kernel/common/+/2173923
+found = $(shell if grep -qF "nl80211_validate_key_link_id" $(srctree)/net/wireless/nl80211.c; then echo "yes" ;else echo "no" ;fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DCFG80211_MLO_KEY_OPERATION_SUPPORT
+endif
+
+found = $(shell if grep -qF "struct link_station_parameters" $(srctree)/include/net/cfg80211.h; then echo "yes"; else echo "no"; fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DCFG80211_LINK_STA_PARAMS_PRESENT
+endif
+
+found = $(shell if grep -qF "NL80211_EXT_FEATURE_PUNCT" $(srctree)/include/uapi/linux/nl80211.h; then echo "yes" ;else echo "no" ;fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DNL80211_EXT_FEATURE_PUNCT_SUPPORT
+endif
+
+found = $(shell if grep -qF "unsigned int link_id, u16 punct_bitmap" $(srctree)/include/net/cfg80211.h; then echo "yes" ;else echo "no" ;fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DCFG80211_RU_PUNCT_NOTIFY
+endif
+
+found = $(shell if grep -qF "NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA" $(srctree)/include/uapi/linux/nl80211.h; then echo "yes"; else echo "no"; fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DCFG80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA
+endif
+
+# CFG80211_EXTERNAL_AUTH_MLO_SUPPORT
+# Used to indicate Linux kernel contains support for ML external auth support.
+#
+# This feature was backported to Android Common Kernel 5.15 via:
+# https://android-review.googlesource.com/c/kernel/common/+/2450264
+found = $(shell if grep -qF "MLD address of the peer. Used by the authentication request event" $(srctree)/include/net/cfg80211.h; then echo "yes" ;else echo "no" ;fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DCFG80211_EXTERNAL_AUTH_MLO_SUPPORT
+endif
+
+found = $(shell if grep -qF "NL80211_EXT_FEATURE_SECURE_NAN" $(srctree)/include/uapi/linux/nl80211.h; then echo "yes"; else echo "no"; fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DCFG80211_EXT_FEATURE_SECURE_NAN
+endif
+
+found = $(shell if grep -qF "bool mlo_params_valid;" $(srctree)/include/net/cfg80211.h; then echo "yes" ;else echo "no" ;fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DCFG80211_MLD_AP_STA_CONNECT_UPSTREAM_SUPPORT
+endif
+
+ifeq (qca_cld3, $(WLAN_WEAR_CHIPSET))
+	ccflags-y += -DWLAN_WEAR_CHIPSET
+endif
+
+ccflags-$(CONFIG_ONE_MSI_VECTOR) += -DWLAN_ONE_MSI_VECTOR
+
+ccflags-$(CONFIG_DSC_DEBUG) += -DWLAN_DSC_DEBUG
+ccflags-$(CONFIG_DSC_TEST) += -DWLAN_DSC_TEST
+
+ifeq ($(CONFIG_LITHIUM), y)
+ccflags-y += -DCONFIG_LITHIUM
+endif
+
+ifeq ($(CONFIG_BERYLLIUM), y)
+ccflags-y += -DCONFIG_BERYLLIUM
+ccflags-y += -DDP_OFFLOAD_FRAME_WITH_SW_EXCEPTION
+endif
+
+ifeq ($(CONFIG_RHINE), y)
+ccflags-y += -DCONFIG_RHINE
+ccflags-y += -DDP_OFFLOAD_FRAME_WITH_SW_EXCEPTION
+endif
+
+ccflags-$(CONFIG_TALLOC_DEBUG) += -DWLAN_TALLOC_DEBUG
+ccflags-$(CONFIG_QDF_TEST) += -DWLAN_DELAYED_WORK_TEST
+ccflags-$(CONFIG_QDF_TEST) += -DWLAN_HASHTABLE_TEST
+ccflags-$(CONFIG_QDF_TEST) += -DWLAN_PERIODIC_WORK_TEST
+ccflags-$(CONFIG_QDF_TEST) += -DWLAN_PTR_HASH_TEST
+ccflags-$(CONFIG_QDF_TEST) += -DWLAN_SLIST_TEST
+ccflags-$(CONFIG_QDF_TEST) += -DWLAN_TALLOC_TEST
+ccflags-$(CONFIG_QDF_TEST) += -DWLAN_TRACKER_TEST
+ccflags-$(CONFIG_QDF_TEST) += -DWLAN_TYPES_TEST
+ccflags-$(CONFIG_WLAN_HANG_EVENT) += -DWLAN_HANG_EVENT
+
+#Flag to enable pre_cac
+ccflags-$(CONFIG_FEATURE_WLAN_PRE_CAC)  += -DPRE_CAC_SUPPORT
+
+ccflags-$(CONFIG_WIFI_POS_PASN) += -DWLAN_FEATURE_RTT_11AZ_SUPPORT
+
+ifeq ($(CONFIG_DIRECT_BUF_RX_ENABLE), y)
+ifeq ($(CONFIG_DBR_HOLD_LARGE_MEM), y)
+ccflags-y += -DDBR_HOLD_LARGE_MEM
+endif
+endif
+
+ccflags-$(CONFIG_QCA_DMA_PADDR_CHECK) += -DQCA_DMA_PADDR_CHECK
+ccflags-$(CONFIG_PADDR_CHECK_ON_3RD_PARTY_PLATFORM) += -DQCA_PADDR_CHECK_ON_3RD_PARTY_PLATFORM
+ccflags-$(CONFIG_DP_TRAFFIC_END_INDICATION) += -DDP_TRAFFIC_END_INDICATION
+ccflags-$(CONFIG_THERMAL_STATS_SUPPORT) += -DTHERMAL_STATS_SUPPORT
+ccflags-$(CONFIG_PTT_SOCK_SVC_ENABLE) += -DPTT_SOCK_SVC_ENABLE
+ccflags-$(CONFIG_FEATURE_WLAN_WAPI) += -DFEATURE_WLAN_WAPI
+ccflags-$(CONFIG_FEATURE_WLAN_WAPI) += -DATH_SUPPORT_WAPI
+ccflags-$(CONFIG_SOFTAP_CHANNEL_RANGE) += -DSOFTAP_CHANNEL_RANGE
+ccflags-$(CONFIG_FEATURE_WLAN_SCAN_PNO) += -DFEATURE_WLAN_SCAN_PNO
+ccflags-$(CONFIG_WLAN_FEATURE_PACKET_FILTERING) += -DWLAN_FEATURE_PACKET_FILTERING
+ccflags-$(CONFIG_DHCP_SERVER_OFFLOAD) += -DDHCP_SERVER_OFFLOAD
+ccflags-$(CONFIG_WLAN_NS_OFFLOAD) += -DWLAN_NS_OFFLOAD
+ccflags-$(CONFIG_QCA_TARGET_IF_MLME) += -DQCA_TARGET_IF_MLME
+ccflags-$(CONFIG_WLAN_DYNAMIC_ARP_NS_OFFLOAD) += -DFEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
+ccflags-$(CONFIG_WLAN_FEATURE_ICMP_OFFLOAD) += -DWLAN_FEATURE_ICMP_OFFLOAD
+ccflags-$(CONFIG_FEATURE_WLAN_RA_FILTERING) += -DFEATURE_WLAN_RA_FILTERING
+ccflags-$(CONFIG_FEATURE_WLAN_LPHB) += -DFEATURE_WLAN_LPHB
+ccflags-$(CONFIG_QCA_SUPPORT_TX_THROTTLE) += -DQCA_SUPPORT_TX_THROTTLE
+ccflags-$(CONFIG_WMI_INTERFACE_EVENT_LOGGING) += -DWMI_INTERFACE_EVENT_LOGGING
+ccflags-$(CONFIG_WLAN_FEATURE_LINK_LAYER_STATS) += -DWLAN_FEATURE_LINK_LAYER_STATS
+ccflags-$(CONFIG_FEATURE_CLUB_LL_STATS_AND_GET_STATION) += -DFEATURE_CLUB_LL_STATS_AND_GET_STATION
+ccflags-$(CONFIG_WLAN_FEATURE_MIB_STATS) += -DWLAN_FEATURE_MIB_STATS
+ccflags-$(CONFIG_FEATURE_WLAN_EXTSCAN) += -DFEATURE_WLAN_EXTSCAN
+ccflags-$(CONFIG_160MHZ_SUPPORT) += -DCONFIG_160MHZ_SUPPORT
+ccflags-$(CONFIG_REG_CLIENT) += -DCONFIG_REG_CLIENT
+ccflags-$(CONFIG_WLAN_PMO_ENABLE) += -DWLAN_PMO_ENABLE
+ccflags-$(CONFIG_CONVERGED_P2P_ENABLE) += -DCONVERGED_P2P_ENABLE
+ccflags-$(CONFIG_WLAN_POLICY_MGR_ENABLE) += -DWLAN_POLICY_MGR_ENABLE
+ccflags-$(CONFIG_FEATURE_DENYLIST_MGR) += -DFEATURE_DENYLIST_MGR
+ccflags-$(CONFIG_WAPI_BIG_ENDIAN) += -DFEATURE_WAPI_BIG_ENDIAN
+ccflags-$(CONFIG_SUPPORT_11AX) += -DSUPPORT_11AX
+ccflags-$(CONFIG_HDD_INIT_WITH_RTNL_LOCK) += -DCONFIG_HDD_INIT_WITH_RTNL_LOCK
+ccflags-$(CONFIG_WLAN_CONV_SPECTRAL_ENABLE) += -DWLAN_CONV_SPECTRAL_ENABLE
+ccflags-$(CONFIG_WLAN_CFR_ENABLE) += -DWLAN_CFR_ENABLE
+ccflags-$(CONFIG_WLAN_ENH_CFR_ENABLE) += -DWLAN_ENH_CFR_ENABLE
+ccflags-$(CONFIG_WLAN_ENH_CFR_ENABLE) += -DWLAN_CFR_PM
+ccflags-$(CONFIG_WLAN_CFR_ADRASTEA) += -DWLAN_CFR_ADRASTEA
+ccflags-$(CONFIG_WLAN_CFR_DBR) += -DWLAN_CFR_DBR
+ccflags-$(CONFIG_WLAN_CFR_ENABLE) += -DCFR_USE_FIXED_FOLDER
+ccflags-$(CONFIG_WLAN_FEATURE_MEDIUM_ASSESS) += -DWLAN_FEATURE_MEDIUM_ASSESS
+ccflags-$(CONFIG_FEATURE_RADAR_HISTORY) += -DFEATURE_RADAR_HISTORY
+ccflags-$(CONFIG_DIRECT_BUF_RX_ENABLE) += -DDIRECT_BUF_RX_ENABLE
+ccflags-$(CONFIG_WMI_DBR_SUPPORT) += -DWMI_DBR_SUPPORT
+ifneq ($(CONFIG_CNSS_QCA6750), y)
+ccflags-$(CONFIG_DIRECT_BUF_RX_ENABLE) += -DDBR_MULTI_SRNG_ENABLE
+endif
+ifneq ($(CONFIG_CNSS_WCN6450), y)
+ccflags-$(CONFIG_DIRECT_BUF_RX_ENABLE) += -DDBR_MULTI_SRNG_ENABLE
+endif
+ccflags-$(CONFIG_WMI_CMD_STRINGS) += -DWMI_CMD_STRINGS
+ccflags-$(CONFIG_WLAN_FEATURE_TWT) += -DWLAN_SUPPORT_TWT
+ifeq ($(CONFIG_WLAN_FEATURE_11BE_MLO), y)
+ifeq ($(CONFIG_DP_USE_REDUCED_PEER_ID_FIELD_WIDTH), y)
+ccflags-y += -DDP_USE_REDUCED_PEER_ID_FIELD_WIDTH
+endif
+endif
+ccflags-$(CONFIG_DP_MULTIPASS_SUPPORT) += -DQCA_MULTIPASS_SUPPORT
+ccflags-$(CONFIG_DP_MULTIPASS_SUPPORT) += -DWLAN_REPEATER_NOT_SUPPORTED
+ccflags-$(CONFIG_DP_MULTIPASS_SUPPORT) += -DQCA_SUPPORT_PEER_ISOLATION
+ccflags-$(CONFIG_WLAN_DP_PROFILE_SUPPORT) += -DWLAN_DP_PROFILE_SUPPORT
+
+ifdef CONFIG_WLAN_TWT_SAP_STA_COUNT
+WLAN_TWT_SAP_STA_COUNT ?= 32
+ccflags-y += -DWLAN_TWT_SAP_STA_COUNT=$(WLAN_TWT_SAP_STA_COUNT)
+endif
+
+ccflags-$(CONFIG_ENABLE_LOW_POWER_MODE) += -DCONFIG_ENABLE_LOW_POWER_MODE
+ccflags-$(CONFIG_WLAN_TWT_SAP_PDEV_COUNT) += -DWLAN_TWT_AP_PDEV_COUNT_NUM_PHY
+ccflags-$(CONFIG_WLAN_DISABLE_EXPORT_SYMBOL) += -DWLAN_DISABLE_EXPORT_SYMBOL
+ccflags-$(CONFIG_WIFI_POS_CONVERGED) += -DWIFI_POS_CONVERGED
+ccflags-$(CONFIG_WLAN_TWT_CONVERGED) += -DWLAN_TWT_CONV_SUPPORTED
+ccflags-$(CONFIG_WIFI_POS_LEGACY) += -DFEATURE_OEM_DATA_SUPPORT
+ccflags-$(CONFIG_FEATURE_HTC_CREDIT_HISTORY) += -DFEATURE_HTC_CREDIT_HISTORY
+ccflags-$(CONFIG_WLAN_FEATURE_P2P_DEBUG) += -DWLAN_FEATURE_P2P_DEBUG
+ccflags-$(CONFIG_WLAN_WEXT_SUPPORT_ENABLE) += -DWLAN_WEXT_SUPPORT_ENABLE
+ccflags-$(CONFIG_WLAN_LOGGING_SOCK_SVC) += -DWLAN_LOGGING_SOCK_SVC_ENABLE
+ccflags-$(CONFIG_WLAN_LOGGING_BUFFERS_DYNAMICALLY) += -DWLAN_LOGGING_BUFFERS_DYNAMICALLY
+ccflags-$(CONFIG_WLAN_FEATURE_FILS) += -DWLAN_FEATURE_FILS_SK
+ccflags-$(CONFIG_CP_STATS) += -DWLAN_SUPPORT_INFRA_CTRL_PATH_STATS
+ccflags-$(CONFIG_CP_STATS) += -DQCA_SUPPORT_CP_STATS
+ccflags-$(CONFIG_CP_STATS) += -DQCA_SUPPORT_MC_CP_STATS
+ccflags-$(CONFIG_CP_STATS) += -DWLAN_SUPPORT_LEGACY_CP_STATS_HANDLERS
+ccflags-$(CONFIG_DCS) += -DDCS_INTERFERENCE_DETECTION
+ccflags-$(CONFIG_FEATURE_INTEROP_ISSUES_AP) += -DWLAN_FEATURE_INTEROP_ISSUES_AP
+ccflags-$(CONFIG_FEATURE_MEMDUMP_ENABLE) += -DWLAN_FEATURE_MEMDUMP_ENABLE
+ccflags-$(CONFIG_FEATURE_FW_LOG_PARSING) += -DFEATURE_FW_LOG_PARSING
+ccflags-$(CONFIG_FEATURE_OEM_DATA) += -DFEATURE_OEM_DATA
+ccflags-$(CONFIG_FEATURE_MOTION_DETECTION) += -DWLAN_FEATURE_MOTION_DETECTION
+ccflags-$(CONFIG_WLAN_FW_OFFLOAD) += -DWLAN_FW_OFFLOAD
+ccflags-$(CONFIG_WLAN_FEATURE_ELNA) += -DWLAN_FEATURE_ELNA
+ccflags-$(CONFIG_FEATURE_COEX) += -DFEATURE_COEX
+ccflags-$(CONFIG_HOST_WAKEUP_OVER_QMI) += -DHOST_WAKEUP_OVER_QMI
+ccflags-$(CONFIG_DISABLE_STATUS_RING_TIMER_WAR) += -DWLAN_DISABLE_STATUS_RING_TIMER_WAR
+ccflags-$(CONFIG_CE_DISABLE_SRNG_TIMER_IRQ) += -DWLAN_WAR_CE_DISABLE_SRNG_TIMER_IRQ
+
+ccflags-$(CONFIG_PLD_IPCI_ICNSS_FLAG) += -DCONFIG_PLD_IPCI_ICNSS
+ccflags-$(CONFIG_PLD_SDIO_CNSS_FLAG) += -DCONFIG_PLD_SDIO_CNSS
+ccflags-$(CONFIG_WLAN_RESIDENT_DRIVER) += -DFEATURE_WLAN_RESIDENT_DRIVER
+ccflags-$(CONFIG_FEATURE_GPIO_CFG) += -DWLAN_FEATURE_GPIO_CFG
+ccflags-$(CONFIG_FEATURE_BUS_BANDWIDTH_MGR) += -DFEATURE_BUS_BANDWIDTH_MGR
+ccflags-$(CONFIG_DP_BE_WAR) += -DDP_BE_WAR
+
+ifeq ($(CONFIG_IPCIE_FW_SIM), y)
+ccflags-y += -DCONFIG_PLD_IPCIE_FW_SIM
+endif
+ifeq ($(CONFIG_PLD_PCIE_CNSS_FLAG), y)
+ifeq ($(CONFIG_PCIE_FW_SIM), y)
+ccflags-y += -DCONFIG_PLD_PCIE_FW_SIM
+else
+ccflags-y += -DCONFIG_PLD_PCIE_CNSS
+endif
+endif
+
+ccflags-$(CONFIG_PLD_PCIE_INIT_FLAG) += -DCONFIG_PLD_PCIE_INIT
+ccflags-$(CONFIG_WLAN_FEATURE_DP_RX_THREADS) += -DFEATURE_WLAN_DP_RX_THREADS
+ccflags-$(CONFIG_WLAN_DP_LOCAL_PKT_CAPTURE) += -DWLAN_FEATURE_LOCAL_PKT_CAPTURE
+ccflags-$(CONFIG_WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT) += -DWLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
+ccflags-$(CONFIG_FEATURE_HIF_LATENCY_PROFILE_ENABLE) += -DHIF_LATENCY_PROFILE_ENABLE
+ccflags-$(CONFIG_FEATURE_HAL_DELAYED_REG_WRITE) += -DFEATURE_HAL_DELAYED_REG_WRITE
+ccflags-$(CONFIG_FEATURE_HAL_RECORD_SUSPEND_WRITE) += -DFEATURE_HAL_RECORD_SUSPEND_WRITE
+ccflags-$(CONFIG_QCA_OL_DP_SRNG_LOCK_LESS_ACCESS) += -DQCA_OL_DP_SRNG_LOCK_LESS_ACCESS
+ccflags-$(CONFIG_SHADOW_WRITE_DELAY) += -DSHADOW_WRITE_DELAY
+
+ccflags-$(CONFIG_PLD_USB_CNSS) += -DCONFIG_PLD_USB_CNSS
+ccflags-$(CONFIG_PLD_SDIO_CNSS2) += -DCONFIG_PLD_SDIO_CNSS2
+ccflags-$(CONFIG_WLAN_RECORD_RX_PADDR) += -DHIF_RECORD_RX_PADDR
+ccflags-$(CONFIG_FEATURE_WLAN_TIME_SYNC_FTM) += -DFEATURE_WLAN_TIME_SYNC_FTM
+
+ccflags-$(CONFIG_WLAN_FEATURE_LRO_CTX_IN_CB) += -DWLAN_FEATURE_LRO_CTX_IN_CB
+
+#For both legacy and lithium chip's monitor mode config
+ifeq ($(CONFIG_FEATURE_MONITOR_MODE_SUPPORT), y)
+ccflags-y += -DFEATURE_MONITOR_MODE_SUPPORT
+ccflags-$(CONFIG_DP_CON_MON_MSI_ENABLED) += -DDP_CON_MON_MSI_ENABLED
+ccflags-$(CONFIG_WLAN_RX_MON_PARSE_CMN_USER_INFO) += -DWLAN_RX_MON_PARSE_CMN_USER_INFO
+ccflags-$(CONFIG_DP_CON_MON_MSI_SKIP_SET) += -DDP_CON_MON_MSI_SKIP_SET
+ccflags-$(CONFIG_QCA_WIFI_MONITOR_MODE_NO_MSDU_START_TLV_SUPPORT) += -DQCA_WIFI_MONITOR_MODE_NO_MSDU_START_TLV_SUPPORT
+else
+ccflags-y += -DDISABLE_MON_CONFIG
+endif
+
+ifeq ($(CONFIG_SMP), y)
+ifneq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM) $(CONFIG_RHINE)))
+ccflags-y += -DWLAN_DP_LEGACY_OL_RX_THREAD
+endif
+endif
+
+#Enable NL80211 test mode
+ccflags-$(CONFIG_NL80211_TESTMODE) += -DWLAN_NL80211_TESTMODE
+
+# Flag to enable bus auto suspend
+ifeq ($(CONFIG_BUS_AUTO_SUSPEND), y)
+ccflags-y += -DFEATURE_RUNTIME_PM
+endif
+
+ifeq (y,$(findstring y, $(CONFIG_ICNSS) $(CONFIG_ICNSS_MODULE)))
+ifeq ($(CONFIG_SNOC_FW_SIM), y)
+ccflags-y += -DCONFIG_PLD_SNOC_FW_SIM
+else
+ccflags-y += -DCONFIG_PLD_SNOC_ICNSS
+endif
+endif
+
+ccflags-$(CONFIG_PLD_SNOC_ICNSS_FLAG) += -DCONFIG_PLD_SNOC_ICNSS
+ccflags-$(CONFIG_ICNSS2_HELIUM) += -DCONFIG_PLD_SNOC_ICNSS2
+
+ccflags-$(CONFIG_WIFI_3_0_ADRASTEA) += -DQCA_WIFI_3_0_ADRASTEA
+ccflags-$(CONFIG_WIFI_3_0_ADRASTEA) += -DQCA_WIFI_3_0
+ccflags-$(CONFIG_ADRASTEA_SHADOW_REGISTERS) += -DADRASTEA_SHADOW_REGISTERS
+ccflags-$(CONFIG_ADRASTEA_RRI_ON_DDR) += -DADRASTEA_RRI_ON_DDR
+
+ifeq ($(CONFIG_QMI_SUPPORT), n)
+ccflags-y += -DCONFIG_BYPASS_QMI
+endif
+
+ccflags-$(CONFIG_WLAN_FASTPATH) +=	-DWLAN_FEATURE_FASTPATH
+
+ccflags-$(CONFIG_FEATURE_PKTLOG) +=     -DFEATURE_PKTLOG
+
+ccflags-$(CONFIG_CONNECTIVITY_PKTLOG) += -DCONNECTIVITY_PKTLOG
+
+ifeq ($(CONFIG_WLAN_NAPI), y)
+ccflags-y += -DFEATURE_NAPI
+ccflags-y += -DHIF_IRQ_AFFINITY
+ifeq ($(CONFIG_WLAN_NAPI_DEBUG), y)
+ccflags-y += -DFEATURE_NAPI_DEBUG
+endif
+endif
+
+ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM)))
+ccflags-y += -DMSM_PLATFORM
+endif
+
+ccflags-$(CONFIG_CNSS_OUT_OF_TREE) += -DCONFIG_CNSS_OUT_OF_TREE
+ccflags-$(CONFIG_CNSS_OUT_OF_TREE) += -I$(WLAN_PLATFORM_INC)
+ccflags-$(CONFIG_IPA_OUT_OF_TREE) += -I$(DATA_IPA_INC)
+ccflags-$(CONFIG_IPA_OUT_OF_TREE) += -I$(DATA_IPA_UAPI_INC)
+
+ccflags-$(CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH) += -DWLAN_FEATURE_DP_BUS_BANDWIDTH
+ccflags-$(CONFIG_WLAN_FEATURE_PERIODIC_STA_STATS) += -DWLAN_FEATURE_PERIODIC_STA_STATS
+
+ccflags-$(CONFIG_WLAN_TX_FLOW_CONTROL_V2) += -DQCA_LL_TX_FLOW_CONTROL_V2
+ccflags-$(CONFIG_WLAN_TX_FLOW_CONTROL_V2) += -DQCA_LL_TX_FLOW_GLOBAL_MGMT_POOL
+ccflags-$(CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY) += -DQCA_LL_LEGACY_TX_FLOW_CONTROL
+ccflags-$(CONFIG_WLAN_PDEV_TX_FLOW_CONTROL) += -DQCA_LL_PDEV_TX_FLOW_CONTROL
+
+ifeq ($(CONFIG_WLAN_DEBUG_VERSION), y)
+ccflags-y +=	-DWLAN_DEBUG
+ifeq ($(CONFIG_TRACE_RECORD_FEATURE), y)
+ccflags-y +=	-DTRACE_RECORD \
+		-DLIM_TRACE_RECORD \
+		-DSME_TRACE_RECORD \
+		-DHDD_TRACE_RECORD
+endif
+endif
+ccflags-$(CONFIG_UNIT_TEST) += -DWLAN_UNIT_TEST
+ccflags-$(CONFIG_WLAN_DEBUG_CRASH_INJECT) += -DCONFIG_WLAN_DEBUG_CRASH_INJECT
+ccflags-$(CONFIG_WLAN_SYSFS_FW_MODE_CFG) += -DCONFIG_WLAN_SYSFS_FW_MODE_CFG
+ccflags-$(CONFIG_WLAN_REASSOC) += -DCONFIG_WLAN_REASSOC
+ccflags-$(CONFIG_WLAN_SCAN_DISABLE) += -DCONFIG_WLAN_SCAN_DISABLE
+ccflags-$(CONFIG_WLAN_WOW_ITO) += -DCONFIG_WLAN_WOW_ITO
+ccflags-$(CONFIG_WLAN_WOWL_ADD_PTRN) += -DCONFIG_WLAN_WOWL_ADD_PTRN
+ccflags-$(CONFIG_WLAN_WOWL_DEL_PTRN) += -DCONFIG_WLAN_WOWL_DEL_PTRN
+ccflags-$(CONFIG_WLAN_SYSFS_TX_STBC) += -DCONFIG_WLAN_SYSFS_TX_STBC
+ccflags-$(CONFIG_WLAN_GET_STATS) += -DCONFIG_WLAN_GET_STATS
+ccflags-$(CONFIG_WLAN_SYSFS_WLAN_DBG) += -DCONFIG_WLAN_SYSFS_WLAN_DBG
+ccflags-$(CONFIG_WLAN_TXRX_FW_ST_RST) += -DCONFIG_WLAN_TXRX_FW_ST_RST
+ccflags-$(CONFIG_WLAN_GTX_BW_MASK) += -DCONFIG_WLAN_GTX_BW_MASK
+ccflags-$(CONFIG_WLAN_SYSFS_SCAN_CFG) += -DCONFIG_WLAN_SYSFS_SCAN_CFG
+ccflags-$(CONFIG_WLAN_SYSFS_MONITOR_MODE_CHANNEL) += -DCONFIG_WLAN_SYSFS_MONITOR_MODE_CHANNEL
+ccflags-$(CONFIG_WLAN_SYSFS_RADAR) += -DCONFIG_WLAN_SYSFS_RADAR
+ccflags-$(CONFIG_WLAN_SYSFS_RTS_CTS) += -DWLAN_SYSFS_RTS_CTS
+ccflags-$(CONFIG_WLAN_TXRX_FW_STATS) += -DCONFIG_WLAN_TXRX_FW_STATS
+ccflags-$(CONFIG_WLAN_TXRX_STATS) += -DCONFIG_WLAN_TXRX_STATS
+ccflags-$(CONFIG_WLAN_SYSFS_DP_TRACE) += -DWLAN_SYSFS_DP_TRACE
+ccflags-$(CONFIG_WLAN_SYSFS_STATS) += -DWLAN_SYSFS_STATS
+ccflags-$(CONFIG_WLAN_SYSFS_TEMPERATURE) += -DCONFIG_WLAN_SYSFS_TEMPERATURE
+ccflags-$(CONFIG_WLAN_THERMAL_CFG) += -DCONFIG_WLAN_THERMAL_CFG
+ccflags-$(CONFIG_FEATURE_UNIT_TEST_SUSPEND) += -DWLAN_SUSPEND_RESUME_TEST
+ccflags-$(CONFIG_FEATURE_WLM_STATS) += -DFEATURE_WLM_STATS
+ccflags-$(CONFIG_WLAN_SYSFS_MEM_STATS) += -DCONFIG_WLAN_SYSFS_MEM_STATS
+ccflags-$(CONFIG_WLAN_SYSFS_DCM) += -DWLAN_SYSFS_DCM
+ccflags-$(CONFIG_WLAN_SYSFS_HE_BSS_COLOR) += -DWLAN_SYSFS_HE_BSS_COLOR
+ccflags-$(CONFIG_WLAN_SYSFS_STA_INFO) += -DWLAN_SYSFS_STA_INFO
+ccflags-$(CONFIG_WLAN_DL_MODES) += -DCONFIG_WLAN_DL_MODES
+ccflags-$(CONFIG_WLAN_THERMAL_MULTI_CLIENT_SUPPORT) += -DFEATURE_WPSS_THERMAL_MITIGATION
+ccflags-$(CONFIG_WLAN_DUMP_IN_PROGRESS) += -DCONFIG_WLAN_DUMP_IN_PROGRESS
+ccflags-$(CONFIG_WLAN_BMISS) += -DCONFIG_WLAN_BMISS
+ccflags-$(CONFIG_WLAN_SYSFS_DP_STATS) += -DWLAN_SYSFS_DP_STATS
+ccflags-$(CONFIG_WLAN_FREQ_LIST) += -DCONFIG_WLAN_FREQ_LIST
+
+ccflags-$(CONFIG_WIFI_MONITOR_SUPPORT) += -DWIFI_MONITOR_SUPPORT
+ccflags-$(CONFIG_QCA_MONITOR_PKT_SUPPORT) += -DQCA_MONITOR_PKT_SUPPORT
+ccflags-$(CONFIG_MONITOR_MODULARIZED_ENABLE) += -DMONITOR_MODULARIZED_ENABLE
+ccflags-$(CONFIG_DP_PKT_ADD_TIMESTAMP) += -DCONFIG_DP_PKT_ADD_TIMESTAMP
+ccflags-$(CONFIG_WLAN_PDEV_VDEV_SEND_MULTI_PARAM) += -DWLAN_PDEV_VDEV_SEND_MULTI_PARAM
+ccflags-$(CONFIG_WLAN_SYSFS_LOG_BUFFER) += -DFEATURE_SYSFS_LOG_BUFFER
+ccflags-$(CONFIG_ENABLE_VALLOC_REPLACE_MALLOC) += -DENABLE_VALLOC_REPLACE_MALLOC
+ccflags-$(CONFIG_WLAN_SYSFS_DFSNOL) += -DCONFIG_WLAN_SYSFS_DFSNOL
+ccflags-$(CONFIG_WLAN_SYSFS_WDS_MODE) += -DFEATURE_SYSFS_WDS_MODE
+ccflags-$(CONFIG_WLAN_SYSFS_ROAM_TRIGGER_BITMAP) += -DFEATURE_SYSFS_ROAM_TRIGGER_BITMAP
+cppflags-$(CONFIG_BCN_RATECODE_ENABLE) += -DWLAN_BCN_RATECODE_ENABLE
+ccflags-$(CONFIG_WLAN_SYSFS_RF_TEST_MODE) += -DFEATURE_SYSFS_RF_TEST_MODE
+
+ifeq ($(CONFIG_LEAK_DETECTION), y)
+ccflags-y += \
+	-DCONFIG_HALT_KMEMLEAK \
+	-DCONFIG_LEAK_DETECTION \
+	-DMEMORY_DEBUG \
+	-DNBUF_MEMORY_DEBUG \
+	-DNBUF_MAP_UNMAP_DEBUG \
+	-DTIMER_MANAGER \
+	-DWLAN_DELAYED_WORK_DEBUG \
+	-DWLAN_WAKE_LOCK_DEBUG \
+	-DWLAN_PERIODIC_WORK_DEBUG
+endif
+
+cppflags-$(CONFIG_ALLOC_CONTIGUOUS_MULTI_PAGE) += -DALLOC_CONTIGUOUS_MULTI_PAGE
+
+ifeq ($(CONFIG_QCOM_VOWIFI_11R), y)
+ccflags-y += -DKERNEL_SUPPORT_11R_CFG80211
+ccflags-y += -DUSE_80211_WMMTSPEC_FOR_RIC
+endif
+
+ifeq ($(CONFIG_QCOM_ESE), y)
+ccflags-y += -DFEATURE_WLAN_ESE
+endif
+
+#normally, TDLS negative behavior is not needed
+ccflags-$(CONFIG_QCOM_TDLS) += -DFEATURE_WLAN_TDLS
+ccflags-$(CONFIG_QCOM_TDLS) += -DWLAN_FEATURE_TDLS_CONCURRENCIES
+
+ifeq (y,$(filter y,$(CONFIG_LITHIUM) $(CONFIG_BERYLLIUM)))
+ccflags-$(CONFIG_QCOM_TDLS) += -DTDLS_WOW_ENABLED
+endif
+
+ccflags-$(CONFIG_WLAN_SYSFS_TDLS_PEERS) += -DWLAN_SYSFS_TDLS_PEERS
+ccflags-$(CONFIG_WLAN_SYSFS_RANGE_EXT) += -DWLAN_SYSFS_RANGE_EXT
+
+ccflags-$(CONFIG_QCACLD_WLAN_LFR2) += -DWLAN_FEATURE_PREAUTH_ENABLE
+
+ifeq ($(CONFIG_CM_UTF_ENABLE), y)
+ccflags-y += -DFEATURE_CM_UTF_ENABLE
+endif
+
+ccflags-$(CONFIG_QCACLD_WLAN_LFR3) += -DWLAN_FEATURE_ROAM_OFFLOAD
+ccflags-$(CONFIG_WLAN_FEATURE_ROAM_INFO_STATS) += -DWLAN_FEATURE_ROAM_INFO_STATS
+ccflags-$(CONFIG_QCACLD_WLAN_CONNECTIVITY_LOGGING) += -DWLAN_FEATURE_CONNECTIVITY_LOGGING
+ccflags-$(CONFIG_QCACLD_WLAN_CONNECTIVITY_DIAG_EVENT) += -DCONNECTIVITY_DIAG_EVENT
+ccflags-$(CONFIG_OFDM_SCRAMBLER_SEED) += -DWLAN_FEATURE_OFDM_SCRAMBLER_SEED
+
+ccflags-$(CONFIG_WLAN_FEATURE_MBSSID) += -DWLAN_FEATURE_MBSSID
+ccflags-$(CONFIG_WLAN_FEATURE_P2P_P2P_STA) += -DWLAN_FEATURE_P2P_P2P_STA
+
+ifeq (y,$(findstring y, $(CONFIG_CNSS_GENL) $(CONFIG_CNSS_GENL_MODULE)))
+ccflags-y += -DCNSS_GENL
+endif
+
+ifeq (y,$(findstring y, $(CONFIG_CNSS_UTILS) $(CONFIG_CNSS_UTILS_MODULE)))
+ccflags-y += -DCNSS_UTILS
+endif
+
+ifeq (y,$(findstring y, $(CONFIG_WCNSS_MEM_PRE_ALLOC) $(CONFIG_WCNSS_MEM_PRE_ALLOC_MODULE)))
+ccflags-y += -DCNSS_MEM_PRE_ALLOC
+endif
+
+ccflags-$(CONFIG_QCACLD_WLAN_LFR2) += -DWLAN_FEATURE_HOST_ROAM
+
+ccflags-$(CONFIG_FEATURE_ROAM_DEBUG) += -DFEATURE_ROAM_DEBUG
+
+ccflags-$(CONFIG_WLAN_POWER_DEBUG) += -DWLAN_POWER_DEBUG
+
+ccflags-$(CONFIG_WLAN_MWS_INFO_DEBUGFS) += -DWLAN_MWS_INFO_DEBUGFS
+
+ifeq ($(CONFIG_WLAN_DEBUG_LINK_VOTE), y)
+ccflags-$(CONFIG_WLAN_DEBUG_LINK_VOTE) += -DWLAN_DEBUG_LINK_VOTE
+endif
+# Enable object manager reference count debug infrastructure
+ccflags-$(CONFIG_WLAN_OBJMGR_DEBUG) += -DWLAN_OBJMGR_DEBUG
+ccflags-$(CONFIG_WLAN_OBJMGR_DEBUG) += -DWLAN_OBJMGR_REF_ID_DEBUG
+ccflags-$(CONFIG_WLAN_OBJMGR_REF_ID_TRACE) += -DWLAN_OBJMGR_REF_ID_TRACE
+ccflags-$(CONFIG_FEATURE_DELAYED_PEER_OBJ_DESTROY) += -DFEATURE_DELAYED_PEER_OBJ_DESTROY
+
+ccflags-$(CONFIG_WLAN_FEATURE_SAE) += -DWLAN_FEATURE_SAE
+
+ifeq ($(CONFIG_WLAN_DIAG_VERSION), y)
+ccflags-y += -DFEATURE_WLAN_DIAG_SUPPORT
+ccflags-y += -DFEATURE_WLAN_DIAG_SUPPORT_CSR
+ccflags-y += -DFEATURE_WLAN_DIAG_SUPPORT_LIM
+ifeq ($(CONFIG_HIF_PCI), y)
+ccflags-y += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT
+endif
+ifeq ($(CONFIG_HIF_IPCI), y)
+ccflags-y += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT
+endif
+endif
+
+ifeq ($(CONFIG_HIF_USB), y)
+ccflags-y += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT
+ccflags-y += -DQCA_SUPPORT_OL_RX_REORDER_TIMEOUT
+ccflags-y += -DCONFIG_ATH_PCIE_MAX_PERF=0 -DCONFIG_ATH_PCIE_AWAKE_WHILE_DRIVER_LOAD=0 -DCONFIG_DISABLE_CDC_MAX_PERF_WAR=0
+endif
+
+ccflags-$(CONFIG_QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK) += -DQCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
+
+ccflags-$(CONFIG_QCA_TXDESC_SANITY_CHECKS) += -DQCA_SUPPORT_TXDESC_SANITY_CHECKS
+
+ccflags-$(CONFIG_QCOM_LTE_COEX) += -DFEATURE_WLAN_CH_AVOID
+
+ccflags-$(CONFIG_WLAN_FEATURE_LPSS) += -DWLAN_FEATURE_LPSS
+
+ccflags-$(CONFIG_DESC_DUP_DETECT_DEBUG) += -DDESC_DUP_DETECT_DEBUG
+ccflags-$(CONFIG_DEBUG_RX_RING_BUFFER) += -DDEBUG_RX_RING_BUFFER
+
+ccflags-$(CONFIG_DESC_TIMESTAMP_DEBUG_INFO) += -DDESC_TIMESTAMP_DEBUG_INFO
+
+ccflags-$(PANIC_ON_BUG) += -DPANIC_ON_BUG
+
+ccflags-$(WLAN_WARN_ON_ASSERT) += -DWLAN_WARN_ON_ASSERT
+
+ccflags-$(CONFIG_POWER_MANAGEMENT_OFFLOAD) += -DWLAN_POWER_MANAGEMENT_OFFLOAD
+
+ccflags-$(CONFIG_WLAN_LOG_FATAL) += -DWLAN_LOG_FATAL
+ccflags-$(CONFIG_WLAN_LOG_ERROR) += -DWLAN_LOG_ERROR
+ccflags-$(CONFIG_WLAN_LOG_WARN) += -DWLAN_LOG_WARN
+ccflags-$(CONFIG_WLAN_LOG_INFO) += -DWLAN_LOG_INFO
+ccflags-$(CONFIG_WLAN_LOG_DEBUG) += -DWLAN_LOG_DEBUG
+ccflags-$(CONFIG_WLAN_LOG_ENTER) += -DWLAN_LOG_ENTER
+ccflags-$(CONFIG_WLAN_LOG_EXIT) += -DWLAN_LOG_EXIT
+ccflags-$(WLAN_OPEN_SOURCE) += -DWLAN_OPEN_SOURCE
+ccflags-$(CONFIG_FEATURE_STATS_EXT) += -DWLAN_FEATURE_STATS_EXT
+ccflags-$(CONFIG_QCACLD_FEATURE_NAN) += -DWLAN_FEATURE_NAN
+ccflags-$(CONFIG_QCACLD_FEATURE_SON) += -DWLAN_FEATURE_SON
+ccflags-$(CONFIG_NDP_SAP_CONCURRENCY_ENABLE) += -DNDP_SAP_CONCURRENCY_ENABLE
+ccflags-$(CONFIG_ENFORCE_PLD_REMOVE) += -DENFORCE_PLD_REMOVE
+
+ifeq ($(CONFIG_DFS_FCC_TYPE4_DURATION_CHECK), y)
+ccflags-$(CONFIG_DFS_FCC_TYPE4_DURATION_CHECK) += -DDFS_FCC_TYPE4_DURATION_CHECK
+endif
+
+ccflags-$(CONFIG_WLAN_SYSFS) += -DWLAN_SYSFS
+ccflags-$(CONFIG_WLAN_SYSFS_CHANNEL) += -DWLAN_SYSFS_CHANNEL
+ccflags-$(CONFIG_FEATURE_BECN_STATS) += -DWLAN_FEATURE_BEACON_RECEPTION_STATS
+
+ccflags-$(CONFIG_WLAN_SYSFS_CONNECT_INFO) += -DWLAN_SYSFS_CONNECT_INFO
+ccflags-$(CONFIG_WLAN_SYSFS_EHT_RATE) += -DWLAN_SYSFS_EHT_RATE
+
+#Set RX_PERFORMANCE
+ccflags-$(CONFIG_RX_PERFORMANCE) += -DRX_PERFORMANCE
+
+#Set MULTI_IF_LOG
+ccflags-$(CONFIG_MULTI_IF_LOG) += -DMULTI_IF_LOG
+
+#Set SLUB_MEM_OPTIMIZE
+ccflags-$(CONFIG_SLUB_MEM_OPTIMIZE) += -DSLUB_MEM_OPTIMIZE
+
+ifeq ($(CONFIG_ARCH_SDXBAAGHA), y)
+ccflags-$(CONFIG_WLAN_MEMORY_OPT) += -DWLAN_MEMORY_OPT
+endif
+
+#Set DFS_PRI_MULTIPLIER
+ccflags-$(CONFIG_DFS_PRI_MULTIPLIER) += -DDFS_PRI_MULTIPLIER
+
+#Set DFS_OVERRIDE_RF_THRESHOLD
+ccflags-$(CONFIG_DFS_OVERRIDE_RF_THRESHOLD) += -DDFS_OVERRIDE_RF_THRESHOLD
+
+#Enable OL debug and wmi unified functions
+ccflags-$(CONFIG_ATH_PERF_PWR_OFFLOAD) += -DATH_PERF_PWR_OFFLOAD
+
+#Disable packet log
+ccflags-$(CONFIG_REMOVE_PKT_LOG) += -DREMOVE_PKT_LOG
+
+#Enable 11AC TX
+ccflags-$(CONFIG_ATH_11AC_TXCOMPACT) += -DATH_11AC_TXCOMPACT
+
+#ENABLE HTT HTC tx completion
+ccflags-$(ENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST) += -DENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST
+
+#Enable PCI specific APIS (dma, etc)
+ccflags-$(CONFIG_HIF_PCI) += -DHIF_PCI
+
+ccflags-$(CONFIG_HIF_IPCI) += -DHIF_IPCI
+
+ccflags-$(CONFIG_HIF_SNOC) += -DHIF_SNOC
+
+ccflags-$(CONFIG_HL_DP_SUPPORT) += -DCONFIG_HL_SUPPORT
+ccflags-$(CONFIG_HL_DP_SUPPORT) += -DWLAN_PARTIAL_REORDER_OFFLOAD
+ccflags-$(CONFIG_HL_DP_SUPPORT) += -DQCA_COMPUTE_TX_DELAY
+ccflags-$(CONFIG_HL_DP_SUPPORT) += -DQCA_COMPUTE_TX_DELAY_PER_TID
+ccflags-$(CONFIG_LL_DP_SUPPORT) += -DCONFIG_LL_DP_SUPPORT
+ccflags-$(CONFIG_LL_DP_SUPPORT) += -DWLAN_FULL_REORDER_OFFLOAD
+ccflags-$(CONFIG_WLAN_FEATURE_BIG_DATA_STATS) += -DWLAN_FEATURE_BIG_DATA_STATS
+ifeq ($(CONFIG_WLAN_FEATURE_11AX), y)
+ccflags-$(CONFIG_WLAN_FEATURE_SR) += -DWLAN_FEATURE_SR
+ccflags-$(CONFIG_OBSS_PD) += -DOBSS_PD
+endif
+ccflags-$(CONFIG_WLAN_FEATURE_IGMP_OFFLOAD) += -DWLAN_FEATURE_IGMP_OFFLOAD
+ccflags-$(CONFIG_WLAN_FEATURE_GET_USABLE_CHAN_LIST) += -DWLAN_FEATURE_GET_USABLE_CHAN_LIST
+
+# For PCIe GEN switch
+ccflags-$(CONFIG_PCIE_GEN_SWITCH) += -DPCIE_GEN_SWITCH
+
+# For OOB testing
+ccflags-$(CONFIG_WLAN_FEATURE_WOW_PULSE) += -DWLAN_FEATURE_WOW_PULSE
+
+#Enable High Latency related Flags
+ifeq ($(CONFIG_QCA_WIFI_SDIO), y)
+ccflags-y += -DCONFIG_AR6320_SUPPORT \
+            -DSDIO_3_0 \
+            -DHIF_SDIO \
+            -DCONFIG_DISABLE_CDC_MAX_PERF_WAR=0 \
+            -DCONFIG_ATH_PROCFS_DIAG_SUPPORT \
+            -DHIF_MBOX_SLEEP_WAR \
+            -DDEBUG_HL_LOGGING \
+            -DQCA_BAD_PEER_TX_FLOW_CL \
+            -DCONFIG_SDIO \
+            -DFEATURE_WLAN_FORCE_SAP_SCC
+
+ifeq ($(CONFIG_SDIO_TRANSFER), adma)
+ccflags-y += -DCONFIG_SDIO_TRANSFER_ADMA
+else
+ccflags-y += -DCONFIG_SDIO_TRANSFER_MAILBOX
+endif
+endif
+
+ccflags-$(CONFIG_AR6320_SUPPORT) += -DCONFIG_AR6320_SUPPORT
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+ccflags-y += -DWLAN_FEATURE_DSRC
+ifeq ($(CONFIG_OCB_UT_FRAMEWORK), y)
+ccflags-y += -DWLAN_OCB_UT
+endif
+
+else ifeq ($(CONFIG_WLAN_REG_AUTO), y)
+ccflags-y += -DWLAN_REG_AUTO
+endif
+
+ccflags-$(CONFIG_FEATURE_SKB_PRE_ALLOC) += -DFEATURE_SKB_PRE_ALLOC
+
+#Enable USB specific APIS
+ifeq ($(CONFIG_HIF_USB), y)
+ccflags-y += -DHIF_USB \
+            -DDEBUG_HL_LOGGING
+endif
+
+#Enable Genoa specific features.
+ccflags-$(CONFIG_QCA_HL_NETDEV_FLOW_CONTROL) += -DQCA_HL_NETDEV_FLOW_CONTROL
+ccflags-$(CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL) += -DFEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+ccflags-$(CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING) += -DFEATURE_HL_DBS_GROUP_CREDIT_SHARING
+ccflags-$(CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE) += -DCONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE
+ccflags-$(CONFIG_RX_PN_CHECK_OFFLOAD) += -DCONFIG_RX_PN_CHECK_OFFLOAD
+
+ccflags-$(CONFIG_WLAN_SYNC_TSF_TIMER) += -DWLAN_FEATURE_TSF_TIMER_SYNC
+ccflags-$(CONFIG_WLAN_SYNC_TSF_PTP) += -DWLAN_FEATURE_TSF_PTP
+ccflags-$(CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_IRQ) += -DWLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ
+ccflags-$(CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_SYNC) += -DWLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+ccflags-$(CONFIG_TX_DESC_HI_PRIO_RESERVE) += -DCONFIG_TX_DESC_HI_PRIO_RESERVE
+
+#Enable power management suspend/resume functionality
+ccflags-$(CONFIG_ATH_BUS_PM) += -DATH_BUS_PM
+
+#Enable FLOWMAC module support
+ccflags-$(CONFIG_ATH_SUPPORT_FLOWMAC_MODULE) += -DATH_SUPPORT_FLOWMAC_MODULE
+
+#Enable spectral support
+ccflags-$(CONFIG_ATH_SUPPORT_SPECTRAL) += -DATH_SUPPORT_SPECTRAL
+
+#Enable legacy pktlog
+ccflags-$(CONFIG_PKTLOG_LEGACY) += -DPKTLOG_LEGACY
+
+#Enable WDI Event support
+ccflags-$(CONFIG_WDI_EVENT_ENABLE) += -DWDI_EVENT_ENABLE
+
+#Enable the type_specific_data in the struct ath_pktlog_arg
+ccflags-$(CONFIG_PKTLOG_HAS_SPECIFIC_DATA) += -DPKTLOG_HAS_SPECIFIC_DATA
+
+#Endianness selection
+ifeq ($(CONFIG_LITTLE_ENDIAN), y)
+ccflags-y += -DANI_LITTLE_BYTE_ENDIAN
+ccflags-y += -DANI_LITTLE_BIT_ENDIAN
+ccflags-y += -DDOT11F_LITTLE_ENDIAN_HOST
+else
+ccflags-y += -DANI_BIG_BYTE_ENDIAN
+ccflags-y += -DBIG_ENDIAN_HOST
+endif
+
+#Enable TX reclaim support
+ccflags-$(CONFIG_TX_CREDIT_RECLAIM_SUPPORT) += -DTX_CREDIT_RECLAIM_SUPPORT
+
+#Enable FTM support
+ccflags-$(CONFIG_QCA_WIFI_FTM) += -DQCA_WIFI_FTM
+ccflags-$(CONFIG_NL80211_TESTMODE) += -DQCA_WIFI_FTM_NL80211
+ccflags-$(CONFIG_LINUX_QCMBR) += -DLINUX_QCMBR -DQCA_WIFI_FTM_IOCTL
+
+#Enable Checksum Offload support
+ccflags-$(CONFIG_CHECKSUM_OFFLOAD) += -DCHECKSUM_OFFLOAD
+
+#Enable IPA Offload support
+ccflags-$(CONFIG_IPA_OFFLOAD) += -DIPA_OFFLOAD
+
+#Enable IPA optional Wifi datapath
+ifeq ($(CONFIG_IPA_OPT_WIFI_DP), y)
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+ccflags-$(CONFIG_IPA_OPT_WIFI_DP) += -DIPA_OPT_WIFI_DP
+endif
+endif
+
+ccflags-$(CONFIG_WDI3_IPA_OVER_GSI) += -DIPA_WDI3_GSI
+ccflags-$(CONFIG_WDI2_IPA_OVER_GSI) += -DIPA_WDI2_GSI
+
+#Enable WMI DIAG log over CE7
+ccflags-$(CONFIG_WLAN_FEATURE_WMI_DIAG_OVER_CE7) += -DWLAN_FEATURE_WMI_DIAG_OVER_CE7
+
+ifdef CONFIG_WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY
+ccflags-y += -DWLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY
+endif
+
+ifeq ($(CONFIG_ARCH_SDX20), y)
+ccflags-y += -DSYNC_IPA_READY
+endif
+
+ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y)
+CONFIG_FEATURE_SG := y
+endif
+
+ifeq ($(CONFIG_ARCH_MSM8996), y)
+ifneq ($(CONFIG_QCN7605_SUPPORT), y)
+CONFIG_FEATURE_SG := y
+CONFIG_RX_THREAD_PRIORITY := y
+endif
+endif
+
+ifeq ($(CONFIG_FEATURE_SG), y)
+ccflags-y += -DFEATURE_SG
+endif
+
+ifeq ($(CONFIG_RX_THREAD_PRIORITY), y)
+ccflags-y += -DRX_THREAD_PRIORITY
+endif
+
+ifeq ($(CONFIG_SUPPORT_P2P_BY_ONE_INTF_WLAN), y)
+#sta support to tx P2P action frames
+ccflags-y += -DSUPPORT_P2P_BY_ONE_INTF_WLAN
+else
+#Open P2P device interface only for non-Mobile router use cases
+ccflags-$(CONFIG_WLAN_OPEN_P2P_INTERFACE) += -DWLAN_OPEN_P2P_INTERFACE
+endif
+
+ccflags-$(CONFIG_WMI_BCN_OFFLOAD) += -DWLAN_WMI_BCN
+
+#Enable wbuff
+ccflags-$(CONFIG_WLAN_WBUFF) += -DWLAN_FEATURE_WBUFF
+
+#Enable GTK Offload
+ccflags-$(CONFIG_GTK_OFFLOAD) += -DWLAN_FEATURE_GTK_OFFLOAD
+
+#Enable External WoW
+ccflags-$(CONFIG_EXT_WOW) += -DWLAN_FEATURE_EXTWOW_SUPPORT
+
+#Mark it as SMP Kernel
+ccflags-$(CONFIG_SMP) += -DQCA_CONFIG_SMP
+
+#CONFIG_RPS default Y, but depend on CONFIG_SMP
+ccflags-$(CONFIG_RPS) += -DQCA_CONFIG_RPS
+
+ccflags-$(CONFIG_CHNL_MATRIX_RESTRICTION) += -DWLAN_ENABLE_CHNL_MATRIX_RESTRICTION
+
+#Enable ICMP packet disable powersave feature
+ccflags-$(CONFIG_ICMP_DISABLE_PS) += -DWLAN_ICMP_DISABLE_PS
+
+#enable MCC TO SCC switch
+ccflags-$(CONFIG_FEATURE_WLAN_MCC_TO_SCC_SWITCH) += -DFEATURE_WLAN_MCC_TO_SCC_SWITCH
+
+#enable wlan auto shutdown feature
+ccflags-$(CONFIG_FEATURE_WLAN_AUTO_SHUTDOWN) += -DFEATURE_WLAN_AUTO_SHUTDOWN
+
+#enable AP-AP ACS Optimization
+ccflags-$(CONFIG_FEATURE_WLAN_AP_AP_ACS_OPTIMIZE) += -DFEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+
+#Enable 4address scheme
+ccflags-$(CONFIG_FEATURE_WLAN_STA_4ADDR_SCHEME) += -DFEATURE_WLAN_STA_4ADDR_SCHEME
+
+#Optimize GC connection speed by skipping JOIN
+ccflags-$(CONFIG_FEATURE_WLAN_GC_SKIP_JOIN) += -DFEATURE_WLAN_GC_SKIP_JOIN
+
+#enable MDM/SDX special config
+ccflags-$(CONFIG_MDM_PLATFORM) += -DMDM_PLATFORM
+
+#Disable STA-AP Mode DFS support
+ccflags-$(CONFIG_FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) += -DFEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
+
+#Enable 2.4 GHz social channels in 5 GHz only mode for p2p usage
+ccflags-$(CONFIG_WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY) += -DWLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
+
+#Green AP feature
+ccflags-$(CONFIG_QCACLD_FEATURE_GREEN_AP) += -DWLAN_SUPPORT_GREEN_AP
+
+ccflags-$(CONFIG_QCACLD_FEATURE_GAP_LL_PS_MODE) += -DWLAN_SUPPORT_GAP_LL_PS_MODE
+
+ccflags-$(CONFIG_QCACLD_FEATURE_APF) += -DFEATURE_WLAN_APF
+
+ccflags-$(CONFIG_WLAN_FEATURE_SARV1_TO_SARV2) += -DWLAN_FEATURE_SARV1_TO_SARV2
+
+ccflags-$(CONFIG_FEATURE_WLAN_FT_IEEE8021X) += -DFEATURE_WLAN_FT_IEEE8021X
+ccflags-$(CONFIG_FEATURE_WLAN_FT_PSK) += -DFEATURE_WLAN_FT_PSK
+
+#Enable host 11d scan
+ccflags-$(CONFIG_HOST_11D_SCAN) += -DHOST_11D_SCAN
+
+#Stats & Quota Metering feature
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+ifeq ($(CONFIG_QCACLD_FEATURE_METERING), y)
+ccflags-y += -DFEATURE_METERING
+endif
+endif
+
+#Define Max IPA interface
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+ifdef CONFIG_NUM_IPA_IFACE
+ccflags-y += -DMAX_IPA_IFACE=$(CONFIG_NUM_IPA_IFACE)
+else
+NUM_IPA_IFACE ?= 3
+ccflags-y += -DMAX_IPA_IFACE=$(NUM_IPA_IFACE)
+endif
+endif
+
+
+ccflags-$(CONFIG_TUFELLO_DUAL_FW_SUPPORT) += -DCONFIG_TUFELLO_DUAL_FW_SUPPORT
+ccflags-$(CONFIG_CHANNEL_HOPPING_ALL_BANDS) += -DCHANNEL_HOPPING_ALL_BANDS
+
+#Enable Signed firmware support for split binary format
+ccflags-$(CONFIG_QCA_SIGNED_SPLIT_BINARY_SUPPORT) += -DQCA_SIGNED_SPLIT_BINARY_SUPPORT
+
+#Enable single firmware binary format
+ccflags-$(CONFIG_QCA_SINGLE_BINARY_SUPPORT) += -DQCA_SINGLE_BINARY_SUPPORT
+
+#Enable collecting target RAM dump after kernel panic
+ccflags-$(CONFIG_TARGET_RAMDUMP_AFTER_KERNEL_PANIC) += -DTARGET_RAMDUMP_AFTER_KERNEL_PANIC
+
+#Enable/disable secure firmware feature
+ccflags-$(CONFIG_FEATURE_SECURE_FIRMWARE) += -DFEATURE_SECURE_FIRMWARE
+
+ccflags-$(CONFIG_ATH_PCIE_ACCESS_DEBUG) += -DCONFIG_ATH_PCIE_ACCESS_DEBUG
+
+# Enable feature support for Linux version QCMBR
+ccflags-$(CONFIG_LINUX_QCMBR) += -DLINUX_QCMBR
+
+# Enable feature sync tsf between multi devices
+ccflags-$(CONFIG_WLAN_SYNC_TSF) += -DWLAN_FEATURE_TSF
+
+ifeq ($(CONFIG_WLAN_SYNC_TSF_PLUS), y)
+ccflags-y += -DWLAN_FEATURE_TSF_PLUS
+
+ccflags-$(CONFIG_WLAN_SYNC_TSF_ACCURACY) += -DWLAN_FEATURE_TSF_ACCURACY
+
+ifneq ($(CONFIG_WLAN_SYNC_TSF_PLUS_DISABLE_SOCK_TS), y)
+ccflags-y += -DWLAN_FEATURE_TSF_PLUS_SOCK_TS
+endif
+
+endif
+
+# Enable feature sync tsf for chips based on Adrastea arch
+ccflags-$(CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ) += -DWLAN_FEATURE_TSF_PLUS_NOIRQ
+
+ifeq ($(CONFIG_WLAN_TSF_UPLINK_DELAY), y)
+# Enable uplink delay report feature
+ccflags-y += -DWLAN_FEATURE_TSF_UPLINK_DELAY
+CONFIG_WLAN_TSF_AUTO_REPORT := y
+endif
+
+# Enable tx latency stats feature
+ifeq ($(CONFIG_WLAN_TX_LATENCY_STATS), y)
+ccflags-y += -DWLAN_FEATURE_TX_LATENCY_STATS
+CONFIG_WLAN_TSF_AUTO_REPORT := y
+endif
+
+# Enable TSF auto report feature
+ccflags-$(CONFIG_WLAN_TSF_AUTO_REPORT) += -DWLAN_FEATURE_TSF_AUTO_REPORT
+
+ccflags-$(CONFIG_ATH_PROCFS_DIAG_SUPPORT) += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT
+
+ccflags-$(CONFIG_HELIUMPLUS) += -DHELIUMPLUS
+ccflags-$(CONFIG_RX_OL) += -DRECEIVE_OFFLOAD
+ccflags-$(CONFIG_TX_TID_OVERRIDE) += -DATH_TX_PRI_OVERRIDE
+ccflags-$(CONFIG_AR900B) += -DAR900B
+ccflags-$(CONFIG_HTT_PADDR64) += -DHTT_PADDR64
+ccflags-$(CONFIG_OL_RX_INDICATION_RECORD) += -DOL_RX_INDICATION_RECORD
+ccflags-$(CONFIG_TSOSEG_DEBUG) += -DTSOSEG_DEBUG
+ccflags-$(CONFIG_ALLOW_PKT_DROPPING) += -DFEATURE_ALLOW_PKT_DROPPING
+
+# Enable feature for athdiag live debug mode
+ccflags-$(CONFIG_ATH_DIAG_EXT_DIRECT) += -DATH_DIAG_EXT_DIRECT
+
+ccflags-$(CONFIG_ENABLE_DEBUG_ADDRESS_MARKING) += -DENABLE_DEBUG_ADDRESS_MARKING
+ccflags-$(CONFIG_FEATURE_TSO) += -DFEATURE_TSO
+ccflags-$(CONFIG_FEATURE_TSO_DEBUG) += -DFEATURE_TSO_DEBUG
+ccflags-$(CONFIG_FEATURE_TSO_STATS) += -DFEATURE_TSO_STATS
+ccflags-$(CONFIG_FEATURE_FORCE_WAKE) += -DFORCE_WAKE
+ccflags-$(CONFIG_WLAN_LRO) += -DFEATURE_LRO
+
+ccflags-$(CONFIG_FEATURE_AP_MCC_CH_AVOIDANCE) += -DFEATURE_AP_MCC_CH_AVOIDANCE
+
+ccflags-$(CONFIG_FEATURE_EPPING) += -DWLAN_FEATURE_EPPING
+
+ccflags-$(CONFIG_WLAN_OFFLOAD_PACKETS) += -DWLAN_FEATURE_OFFLOAD_PACKETS
+
+ccflags-$(CONFIG_WLAN_FEATURE_DISA) += -DWLAN_FEATURE_DISA
+
+ccflags-$(CONFIG_WLAN_FEATURE_ACTION_OUI) += -DWLAN_FEATURE_ACTION_OUI
+
+ccflags-$(CONFIG_WLAN_FEATURE_FIPS) += -DWLAN_FEATURE_FIPS
+
+ccflags-$(CONFIG_LFR_SUBNET_DETECTION) += -DFEATURE_LFR_SUBNET_DETECTION
+
+ccflags-$(CONFIG_MCC_TO_SCC_SWITCH) += -DFEATURE_WLAN_MCC_TO_SCC_SWITCH
+
+ccflags-$(CONFIG_FEATURE_WLAN_D0WOW) += -DFEATURE_WLAN_D0WOW
+
+ccflags-$(CONFIG_WLAN_FEATURE_PKT_CAPTURE) += -DWLAN_FEATURE_PKT_CAPTURE
+
+ccflags-$(CONFIG_WLAN_FEATURE_PKT_CAPTURE_V2) += -DWLAN_FEATURE_PKT_CAPTURE_V2
+
+ccflags-$(CONFIG_DP_RX_UDP_OVER_PEER_ROAM) += -DDP_RX_UDP_OVER_PEER_ROAM
+
+cppflags-$(CONFIG_WLAN_BOOST_CPU_FREQ_IN_ROAM) += -DWLAN_BOOST_CPU_FREQ_IN_ROAM
+
+ccflags-$(CONFIG_QCA_WIFI_EMULATION) += -DQCA_WIFI_EMULATION
+ccflags-$(CONFIG_SAP_MULTI_LINK_EMULATION) += -DSAP_MULTI_LINK_EMULATION
+ccflags-$(CONFIG_SHADOW_V2) += -DCONFIG_SHADOW_V2
+ccflags-$(CONFIG_SHADOW_V3) += -DCONFIG_SHADOW_V3
+ccflags-$(CONFIG_QCA6290_HEADERS_DEF) += -DQCA6290_HEADERS_DEF
+ccflags-$(CONFIG_QCA_WIFI_QCA6290) += -DQCA_WIFI_QCA6290
+ccflags-$(CONFIG_QCA6390_HEADERS_DEF) += -DQCA6390_HEADERS_DEF
+ccflags-$(CONFIG_QCA6750_HEADERS_DEF) += -DQCA6750_HEADERS_DEF
+ccflags-$(CONFIG_QCA_WIFI_QCA6390) += -DQCA_WIFI_QCA6390
+ccflags-$(CONFIG_QCA6490_HEADERS_DEF) += -DQCA6490_HEADERS_DEF
+ccflags-$(CONFIG_KIWI_HEADERS_DEF) += -DKIWI_HEADERS_DEF
+ccflags-$(CONFIG_WCN6450_HEADERS_DEF) += -DWCN6450_HEADERS_DEF
+ccflags-$(CONFIG_QCA_WIFI_QCA6490) += -DQCA_WIFI_QCA6490
+ccflags-$(CONFIG_QCA_WIFI_QCA6750) += -DQCA_WIFI_QCA6750
+ccflags-$(CONFIG_QCA_WIFI_KIWI) += -DQCA_WIFI_KIWI
+ccflags-$(CONFIG_QCA_WIFI_WCN6450) += -DQCA_WIFI_WCN6450
+ccflags-$(CONFIG_QCA_WIFI_WCN6450) += -DWLAN_40BIT_ADDRESSING_SUPPORT
+ccflags-$(CONFIG_QCA_WIFI_WCN6450) += -DWLAN_64BIT_DATA_SUPPORT
+ccflags-$(CONFIG_CE_LEGACY_MSI_SUPPORT) += -DCE_LEGACY_MSI_SUPPORT
+ccflags-$(CONFIG_HIF_HAL_REG_ACCESS_SUPPORT) += -DHIF_HAL_REG_ACCESS_SUPPORT
+ccflags-$(CONFIG_FEATURE_HIF_DELAYED_REG_WRITE) += -DFEATURE_HIF_DELAYED_REG_WRITE
+ccflags-$(CONFIG_CNSS_KIWI_V2) += -DQCA_WIFI_KIWI_V2
+ccflags-$(CONFIG_CNSS_MANGO) += -DQCA_WIFI_MANGO
+ccflags-$(CONFIG_CNSS_PEACH) += -DQCA_WIFI_PEACH
+ccflags-$(CONFIG_QCA_WIFI_QCA8074) += -DQCA_WIFI_QCA8074
+ccflags-$(CONFIG_SCALE_INCLUDES) += -DSCALE_INCLUDES
+ccflags-$(CONFIG_QCA_WIFI_QCA8074_VP) += -DQCA_WIFI_QCA8074_VP
+ccflags-$(CONFIG_DP_INTR_POLL_BASED) += -DDP_INTR_POLL_BASED
+ccflags-$(CONFIG_TX_PER_PDEV_DESC_POOL) += -DTX_PER_PDEV_DESC_POOL
+ccflags-$(CONFIG_DP_TRACE) += -DCONFIG_DP_TRACE
+ccflags-$(CONFIG_FEATURE_TSO) += -DFEATURE_TSO
+ccflags-$(CONFIG_TSO_DEBUG_LOG_ENABLE) += -DTSO_DEBUG_LOG_ENABLE
+ccflags-$(CONFIG_DP_LFR) += -DDP_LFR
+ccflags-$(CONFIG_DUP_RX_DESC_WAR) += -DDUP_RX_DESC_WAR
+ccflags-$(CONFIG_DP_MEM_PRE_ALLOC) += -DDP_MEM_PRE_ALLOC
+ccflags-$(CONFIG_DP_TXRX_SOC_ATTACH) += -DDP_TXRX_SOC_ATTACH
+ccflags-$(CONFIG_WLAN_FEATURE_BMI) += -DWLAN_FEATURE_BMI
+ccflags-$(CONFIG_QCA_TX_PADDING_CREDIT_SUPPORT) += -DQCA_TX_PADDING_CREDIT_SUPPORT
+ccflags-$(CONFIG_QCN7605_SUPPORT) += -DQCN7605_SUPPORT -DPLATFORM_GENOA
+ccflags-$(CONFIG_HIF_REG_WINDOW_SUPPORT) += -DHIF_REG_WINDOW_SUPPORT
+ccflags-$(CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY) += -DWLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
+ccflags-$(CONFIG_HIF_CE_DEBUG_DATA_BUF) += -DHIF_CE_DEBUG_DATA_BUF
+ccflags-$(CONFIG_IPA_DISABLE_OVERRIDE) += -DIPA_DISABLE_OVERRIDE
+ccflags-$(CONFIG_QCA_LL_TX_FLOW_CONTROL_RESIZE) += -DQCA_LL_TX_FLOW_CONTROL_RESIZE
+ccflags-$(CONFIG_HIF_PCI) += -DCE_SVC_CMN_INIT
+ccflags-$(CONFIG_HIF_IPCI) += -DCE_SVC_CMN_INIT
+ccflags-$(CONFIG_HIF_SNOC) += -DCE_SVC_CMN_INIT
+ccflags-$(CONFIG_RX_DESC_SANITY_WAR) += -DRX_DESC_SANITY_WAR
+ccflags-$(CONFIG_WBM_IDLE_LSB_WR_CNF_WAR) += -DWBM_IDLE_LSB_WRITE_CONFIRM_WAR
+ccflags-$(CONFIG_DYNAMIC_RX_AGGREGATION) += -DWLAN_FEATURE_DYNAMIC_RX_AGGREGATION
+ccflags-$(CONFIG_DP_FEATURE_HW_COOKIE_CONVERSION) += -DDP_FEATURE_HW_COOKIE_CONVERSION
+ccflags-$(CONFIG_DP_HW_COOKIE_CONVERT_EXCEPTION) += -DDP_HW_COOKIE_CONVERT_EXCEPTION
+ccflags-$(CONFIG_TX_ADDR_INDEX_SEARCH) += -DTX_ADDR_INDEX_SEARCH
+ccflags-$(CONFIG_QCA_SUPPORT_TX_MIN_RATES_FOR_SPECIAL_FRAMES) += -DQCA_SUPPORT_TX_MIN_RATES_FOR_SPECIAL_FRAMES
+ccflags-$(CONFIG_QCA_GET_TSF_VIA_REG) += -DQCA_GET_TSF_VIA_REG
+ccflags-$(CONFIG_DP_TX_COMP_RING_DESC_SANITY_CHECK) += -DDP_TX_COMP_RING_DESC_SANITY_CHECK
+ccflags-$(CONFIG_HAL_SRNG_REG_HIS_DEBUG) += -DHAL_SRNG_REG_HIS_DEBUG
+ccflags-$(CONFIG_DP_MLO_LINK_STATS_SUPPORT) += -DDP_MLO_LINK_STATS_SUPPORT
+
+ccflags-$(CONFIG_RX_HASH_DEBUG) += -DRX_HASH_DEBUG
+ccflags-$(CONFIG_DP_PKT_STATS_PER_LMAC) += -DDP_PKT_STATS_PER_LMAC
+ccflags-$(CONFIG_NO_RX_PKT_HDR_TLV) += -DNO_RX_PKT_HDR_TLV
+ccflags-$(CONFIG_DP_TX_PACKET_INSPECT_FOR_ILP) += -DDP_TX_PACKET_INSPECT_FOR_ILP
+
+ifeq ($(CONFIG_QCA6290_11AX), y)
+ccflags-y += -DQCA_WIFI_QCA6290_11AX -DQCA_WIFI_QCA6290_11AX_MU_UL
+endif
+
+ccflags-$(CONFIG_WLAN_TX_FLOW_CONTROL_V2) += -DQCA_AC_BASED_FLOW_CONTROL
+
+# Enable Low latency optimisation mode
+ccflags-$(CONFIG_FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT) += -DFEATURE_NO_DBS_INTRABAND_MCC_SUPPORT
+ccflags-$(CONFIG_HAL_DISABLE_NON_BA_2K_JUMP_ERROR) += -DHAL_DISABLE_NON_BA_2K_JUMP_ERROR
+ccflags-$(CONFIG_ENABLE_HAL_SOC_STATS) += -DENABLE_HAL_SOC_STATS
+ccflags-$(CONFIG_ENABLE_HAL_REG_WR_HISTORY) += -DENABLE_HAL_REG_WR_HISTORY
+ccflags-$(CONFIG_DP_RX_DESC_COOKIE_INVALIDATE) += -DDP_RX_DESC_COOKIE_INVALIDATE
+ccflags-$(CONFIG_MON_ENABLE_DROP_FOR_MAC) += -DMON_ENABLE_DROP_FOR_MAC
+ccflags-$(CONFIG_MON_ENABLE_DROP_FOR_NON_MON_PMAC) += -DMON_ENABLE_DROP_FOR_NON_MON_PMAC
+ccflags-$(CONFIG_DP_WAR_INVALID_FIRST_MSDU_FLAG) += -DDP_WAR_INVALID_FIRST_MSDU_FLAG
+ccflags-$(CONFIG_LITHIUM) += -DDISABLE_MON_RING_MSI_CFG
+ccflags-$(CONFIG_LITHIUM) += -DFEATURE_IRQ_AFFINITY
+ccflags-$(CONFIG_RHINE) += -DFEATURE_IRQ_AFFINITY
+ccflags-$(CONFIG_RHINE) += -DWLAN_SOFTUMAC_SUPPORT
+ccflags-$(CONFIG_BERYLLIUM) += -DFEATURE_IRQ_AFFINITY
+ccflags-$(CONFIG_TX_MULTIQ_PER_AC) += -DTX_MULTIQ_PER_AC
+ccflags-$(CONFIG_PCI_LINK_STATUS_SANITY) += -DPCI_LINK_STATUS_SANITY
+ccflags-$(CONFIG_DDP_MON_RSSI_IN_DBM) += -DDP_MON_RSSI_IN_DBM
+ccflags-$(CONFIG_SYSTEM_PM_CHECK) += -DSYSTEM_PM_CHECK
+ccflags-$(CONFIG_DISABLE_EAPOL_INTRABSS_FWD) += -DDISABLE_EAPOL_INTRABSS_FWD
+ccflags-$(CONFIG_TX_AGGREGATION_SIZE_ENABLE) += -DTX_AGGREGATION_SIZE_ENABLE
+ccflags-$(CONFIG_TX_MULTI_TCL) += -DTX_MULTI_TCL
+ccflags-$(CONFIG_WLAN_DP_DISABLE_TCL_CMD_CRED_SRNG) += -DWLAN_DP_DISABLE_TCL_CMD_CRED_SRNG
+ccflags-$(CONFIG_WLAN_DP_DISABLE_TCL_STATUS_SRNG) += -DWLAN_DP_DISABLE_TCL_STATUS_SRNG
+ccflags-$(CONFIG_DP_WAR_VALIDATE_RX_ERR_MSDU_COOKIE) += -DDP_WAR_VALIDATE_RX_ERR_MSDU_COOKIE
+ccflags-$(CONFIG_WLAN_DP_SRNG_USAGE_WM_TRACKING) += -DWLAN_DP_SRNG_USAGE_WM_TRACKING
+ccflags-$(CONFIG_WLAN_FEATURE_DP_CFG_EVENT_HISTORY) += -DWLAN_FEATURE_DP_CFG_EVENT_HISTORY
+ccflags-$(CONFIG_WLAN_DP_VDEV_NO_SELF_PEER) += -DWLAN_DP_VDEV_NO_SELF_PEER
+ccflags-$(CONFIG_DP_RX_MSDU_DONE_FAIL_HISTORY) += -DDP_RX_MSDU_DONE_FAIL_HISTORY
+ccflags-$(CONFIG_DP_RX_PEEK_MSDU_DONE_WAR) += -DDP_RX_PEEK_MSDU_DONE_WAR
+
+# Enable Low latency
+ccflags-$(CONFIG_WLAN_FEATURE_LL_MODE) += -DWLAN_FEATURE_LL_MODE
+
+# Enable PCI low power interrupt register configuration
+ccflags-$(CONFIG_PCI_LOW_POWER_INT_REG) += -DCONFIG_PCI_LOW_POWER_INT_REG
+
+ccflags-$(CONFIG_WLAN_CLD_PM_QOS) += -DCLD_PM_QOS
+ccflags-$(CONFIG_WLAN_CLD_DEV_PM_QOS) += -DCLD_DEV_PM_QOS
+ccflags-$(CONFIG_REO_DESC_DEFER_FREE) += -DREO_DESC_DEFER_FREE
+ccflags-$(CONFIG_WLAN_FEATURE_11AX) += -DWLAN_FEATURE_11AX
+ccflags-$(CONFIG_WLAN_FEATURE_11AX) += -DWLAN_FEATURE_11AX_BSS_COLOR
+ccflags-$(CONFIG_WLAN_FEATURE_11AX) += -DSUPPORT_11AX_D3
+ccflags-$(CONFIG_RXDMA_ERR_PKT_DROP) += -DRXDMA_ERR_PKT_DROP
+ccflags-$(CONFIG_MAX_ALLOC_PAGE_SIZE) += -DMAX_ALLOC_PAGE_SIZE
+ccflags-$(CONFIG_DELIVERY_TO_STACK_STATUS_CHECK) += -DDELIVERY_TO_STACK_STATUS_CHECK
+ccflags-$(CONFIG_WLAN_TRACE_HIDE_MAC_ADDRESS) += -DWLAN_TRACE_HIDE_MAC_ADDRESS
+ccflags-$(CONFIG_WLAN_TRACE_HIDE_SSID) += -DWLAN_TRACE_HIDE_SSID
+ccflags-$(CONFIG_WLAN_FEATURE_11BE) += -DWLAN_FEATURE_11BE
+ccflags-$(CONFIG_WLAN_FEATURE_11BE_MLO) += -DWLAN_FEATURE_11BE_MLO
+ccflags-$(CONFIG_WLAN_FEATURE_11BE_MLO) += -DWLAN_FEATURE_11BE_MLO_ADV_FEATURE
+ccflags-$(CONFIG_WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) += -DWLAN_HDD_MULTI_VDEV_SINGLE_NDEV
+ccflags-$(CONFIG_WLAN_FEATURE_11BE_MLO) += -DWLAN_SUPPORT_11BE_D3_0
+ccflags-$(CONFIG_FIX_TXDMA_LIMITATION) += -DFIX_TXDMA_LIMITATION
+ccflags-$(CONFIG_FEATURE_AST) += -DFEATURE_AST
+ccflags-$(CONFIG_PEER_PROTECTED_ACCESS) += -DPEER_PROTECTED_ACCESS
+ccflags-$(CONFIG_SERIALIZE_QUEUE_SETUP) += -DSERIALIZE_QUEUE_SETUP
+ccflags-$(CONFIG_DP_RX_PKT_NO_PEER_DELIVER) += -DDP_RX_PKT_NO_PEER_DELIVER
+ccflags-$(CONFIG_DP_RX_DROP_RAW_FRM) += -DDP_RX_DROP_RAW_FRM
+ccflags-$(CONFIG_FEATURE_ALIGN_STATS_FROM_DP) += -DFEATURE_ALIGN_STATS_FROM_DP
+ccflags-$(CONFIG_DP_RX_SPECIAL_FRAME_NEED) += -DDP_RX_SPECIAL_FRAME_NEED
+ccflags-$(CONFIG_FEATURE_STATS_EXT_V2) += -DFEATURE_STATS_EXT_V2
+ccflags-$(CONFIG_WLAN_FEATURE_CAL_FAILURE_TRIGGER) += -DWLAN_FEATURE_CAL_FAILURE_TRIGGER
+ccflags-$(CONFIG_WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE) += -DWLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
+ccflags-$(CONFIG_WLAN_FEATURE_SAP_ACS_OPTIMIZE) += -DWLAN_FEATURE_SAP_ACS_OPTIMIZE
+ccflags-$(CONFIG_WLAN_FEATURE_NO_STA_SAP_CONCURRENCY) += -DWLAN_FEATURE_NO_STA_SAP_CONCURRENCY
+ccflags-$(CONFIG_WLAN_FEATURE_NO_STA_NAN_CONCURRENCY) += -DWLAN_FEATURE_NO_STA_NAN_CONCURRENCY
+ccflags-$(CONFIG_WLAN_FEATURE_NO_P2P_CONCURRENCY) += -DWLAN_FEATURE_NO_P2P_CONCURRENCY
+ccflags-$(CONFIG_WLAN_FEATURE_NO_SAP_NAN_CONCURRENCY) += -DWLAN_FEATURE_NO_SAP_NAN_CONCURRENCY
+
+ccflags-$(CONFIG_VERBOSE_DEBUG) += -DENABLE_VERBOSE_DEBUG
+ccflags-$(CONFIG_RX_DESC_DEBUG_CHECK) += -DRX_DESC_DEBUG_CHECK
+ccflags-$(CONFIG_REGISTER_OP_DEBUG) += -DHAL_REGISTER_WRITE_DEBUG
+ccflags-$(CONFIG_ENABLE_QDF_PTR_HASH_DEBUG) += -DENABLE_QDF_PTR_HASH_DEBUG
+#Enable STATE MACHINE HISTORY
+ccflags-$(CONFIG_SM_ENG_HIST) += -DSM_ENG_HIST_ENABLE
+ccflags-$(CONFIG_FEATURE_VDEV_OPS_WAKELOCK) += -DFEATURE_VDEV_OPS_WAKELOCK
+
+# Vendor Commands
+ccflags-$(CONFIG_FEATURE_RSSI_MONITOR) += -DFEATURE_RSSI_MONITOR
+ccflags-$(CONFIG_FEATURE_BSS_TRANSITION) += -DFEATURE_BSS_TRANSITION
+ccflags-$(CONFIG_FEATURE_STATION_INFO) += -DFEATURE_STATION_INFO
+ccflags-$(CONFIG_FEATURE_TX_POWER) += -DFEATURE_TX_POWER
+ccflags-$(CONFIG_FEATURE_OTA_TEST) += -DFEATURE_OTA_TEST
+ccflags-$(CONFIG_FEATURE_ACTIVE_TOS) += -DFEATURE_ACTIVE_TOS
+ccflags-$(CONFIG_FEATURE_SAR_LIMITS) += -DFEATURE_SAR_LIMITS
+ccflags-$(CONFIG_FEATURE_CONCURRENCY_MATRIX) += -DFEATURE_CONCURRENCY_MATRIX
+ccflags-$(CONFIG_FEATURE_SAP_COND_CHAN_SWITCH) += -DFEATURE_SAP_COND_CHAN_SWITCH
+ccflags-$(CONFIG_FEATURE_WLAN_CH_AVOID_EXT) += -DFEATURE_WLAN_CH_AVOID_EXT
+ccflags-$(CONFIG_WLAN_FEATURE_MDNS_OFFLOAD) += -DWLAN_FEATURE_MDNS_OFFLOAD
+
+#if converged p2p is enabled
+ifeq ($(CONFIG_CONVERGED_P2P_ENABLE), y)
+ccflags-$(CONFIG_FEATURE_P2P_LISTEN_OFFLOAD) += -DFEATURE_P2P_LISTEN_OFFLOAD
+endif
+
+#Enable support to get ANI value
+ifeq ($(CONFIG_ANI_LEVEL_REQUEST), y)
+ccflags-y += -DFEATURE_ANI_LEVEL_REQUEST
+endif
+
+#Flags to enable/disable WMI APIs
+ccflags-$(CONFIG_WMI_ROAM_SUPPORT) += -DWMI_ROAM_SUPPORT
+ccflags-$(CONFIG_WMI_CONCURRENCY_SUPPORT) += -DWMI_CONCURRENCY_SUPPORT
+ccflags-$(CONFIG_WMI_STA_SUPPORT) += -DWMI_STA_SUPPORT
+
+ifdef CONFIG_HIF_LARGE_CE_RING_HISTORY
+ccflags-y += -DHIF_CE_HISTORY_MAX=$(CONFIG_HIF_LARGE_CE_RING_HISTORY)
+endif
+
+ccflags-$(CONFIG_WLAN_HANG_EVENT) += -DHIF_CE_LOG_INFO
+ccflags-$(CONFIG_WLAN_HANG_EVENT) += -DHIF_BUS_LOG_INFO
+ccflags-$(CONFIG_WLAN_HANG_EVENT) += -DDP_SUPPORT_RECOVERY_NOTIFY
+
+ccflags-$(CONFIG_ENABLE_SIZE_OPTIMIZE) += -Os
+
+# DFS component
+ccflags-$(CONFIG_WLAN_DFS_STATIC_MEM_ALLOC) += -DWLAN_DFS_STATIC_MEM_ALLOC
+ccflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DMOBILE_DFS_SUPPORT
+ifeq ($(CONFIG_WLAN_FEATURE_DFS_OFFLOAD), y)
+ccflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DWLAN_DFS_FULL_OFFLOAD
+else
+ccflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DWLAN_DFS_PARTIAL_OFFLOAD
+endif
+ccflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DDFS_COMPONENT_ENABLE
+ccflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_DFS_USE_POLICY_MANAGER
+ccflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_DFS_NOL_PLATFORM_DRV_SUPPORT
+ccflags-$(CONFIG_QCA_DFS_BW_PUNCTURE) += -DQCA_DFS_BW_PUNCTURE
+
+ccflags-$(CONFIG_WLAN_DEBUGFS) += -DWLAN_DEBUGFS
+ccflags-$(CONFIG_WLAN_DEBUGFS) += -DWLAN_DBGLOG_DEBUGFS
+ccflags-$(CONFIG_WLAN_STREAMFS) += -DWLAN_STREAMFS
+
+ccflags-$(CONFIG_DYNAMIC_DEBUG) += -DFEATURE_MULTICAST_HOST_FW_MSGS
+
+ccflags-$(CONFIG_ENABLE_SMMU_S1_TRANSLATION) += -DENABLE_SMMU_S1_TRANSLATION
+
+#Flag to enable/disable Line number logging
+ccflags-$(CONFIG_LOG_LINE_NUMBER) += -DLOG_LINE_NUMBER
+
+#Flag to enable/disable MTRACE feature
+ccflags-$(CONFIG_ENABLE_MTRACE_LOG) += -DENABLE_MTRACE_LOG
+
+ccflags-$(CONFIG_FUNC_CALL_MAP) += -DFUNC_CALL_MAP
+
+#Flag to enable/disable Adaptive 11r feature
+ccflags-$(CONFIG_ADAPTIVE_11R) += -DWLAN_ADAPTIVE_11R
+
+#Flag to enable/disable sae single pmk feature feature
+ccflags-$(CONFIG_SAE_SINGLE_PMK) += -DWLAN_SAE_SINGLE_PMK
+
+#Flag to enable/disable multi client low latency feature support
+ccflags-$(CONFIG_MULTI_CLIENT_LL_SUPPORT) += -DMULTI_CLIENT_LL_SUPPORT
+
+#Flag to enable/disable vendor handoff control feature support
+ccflags-$(CONFIG_WLAN_VENDOR_HANDOFF_CONTROL) += -DWLAN_VENDOR_HANDOFF_CONTROL
+
+#Flag to enable/disable mscs feature
+ccflags-$(CONFIG_FEATURE_MSCS) += -DWLAN_FEATURE_MSCS
+
+#Flag to enable NUD tracking
+ccflags-$(CONFIG_WLAN_NUD_TRACKING) += -DWLAN_NUD_TRACKING
+
+#Flag to enable set and get disable channel list feature
+ccflags-$(CONFIG_DISABLE_CHANNEL_LIST) += -DDISABLE_CHANNEL_LIST
+
+#Flag to enable/disable WIPS feature
+ccflags-$(CONFIG_WLAN_BCN_RECV_FEATURE) += -DWLAN_BCN_RECV_FEATURE
+
+#Flag to enable/disable thermal mitigation
+ccflags-$(CONFIG_FW_THERMAL_THROTTLE) += -DFW_THERMAL_THROTTLE
+
+#Flag to enable/disable LTE COEX support
+ccflags-$(CONFIG_LTE_COEX) += -DLTE_COEX
+
+#Flag to enable/disable HOST_OPCLASS
+ccflags-$(CONFIG_HOST_OPCLASS) += -DHOST_OPCLASS
+ccflags-$(CONFIG_HOST_OPCLASS) += -DHOST_OPCLASS_EXT
+
+#Flag to enable/disable TARGET_11D_SCAN
+ccflags-$(CONFIG_TARGET_11D_SCAN) += -DTARGET_11D_SCAN
+
+#Flag to enable/disable avoid acs frequency list feature
+ccflags-$(CONFIG_SAP_AVOID_ACS_FREQ_LIST) += -DSAP_AVOID_ACS_FREQ_LIST
+
+#Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode)
+ccflags-$(CONFIG_WLAN_DYNAMIC_CVM) += -DFEATURE_WLAN_DYNAMIC_CVM
+
+#Flag to enable get firmware state feature
+ccflags-$(CONFIG_QCACLD_FEATURE_FW_STATE) += -DFEATURE_FW_STATE
+
+#Flag to enable set coex configuration feature
+ccflags-$(CONFIG_QCACLD_FEATURE_COEX_CONFIG) += -DFEATURE_COEX_CONFIG
+
+#Flag to enable MPTA helper feature
+ccflags-$(CONFIG_QCACLD_FEATURE_MPTA_HELPER) += -DFEATURE_MPTA_HELPER
+
+#Flag to enable get hw capability
+ccflags-$(CONFIG_QCACLD_FEATURE_HW_CAPABILITY) += -DFEATURE_HW_CAPABILITY
+
+#Flag to enable set btc chain mode feature
+ccflags-$(CONFIG_QCACLD_FEATURE_BTC_CHAIN_MODE) += -DFEATURE_BTC_CHAIN_MODE
+
+ccflags-$(CONFIG_DATA_CE_SW_INDEX_NO_INLINE_UPDATE) += -DDATA_CE_SW_INDEX_NO_INLINE_UPDATE
+
+#Flag to enable Multi page memory allocation for RX descriptor pool
+ccflags-$(CONFIG_QCACLD_RX_DESC_MULTI_PAGE_ALLOC) += -DRX_DESC_MULTI_PAGE_ALLOC
+
+#Flag to enable SAR Safety Feature
+ccflags-$(CONFIG_SAR_SAFETY_FEATURE) += -DSAR_SAFETY_FEATURE
+
+ccflags-$(CONFIG_CONNECTION_ROAMING_CFG) += -DCONNECTION_ROAMING_CFG
+ccflags-$(CONFIG_FEATURE_SET) += -DFEATURE_SET
+ccflags-$(CONFIG_WLAN_FEATURE_LL_LT_SAP) += -DWLAN_FEATURE_LL_LT_SAP
+
+ccflags-$(CONFIG_WLAN_FEATURE_NEAR_FULL_IRQ) += -DWLAN_FEATURE_NEAR_FULL_IRQ
+ccflags-$(CONFIG_WLAN_FEATURE_DP_EVENT_HISTORY) += -DWLAN_FEATURE_DP_EVENT_HISTORY
+ccflags-$(CONFIG_WLAN_FEATURE_DP_RX_RING_HISTORY) += -DWLAN_FEATURE_DP_RX_RING_HISTORY
+ccflags-$(CONFIG_WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY) += -DWLAN_FEATURE_DP_MON_STATUS_RING_HISTORY
+ccflags-$(CONFIG_WLAN_FEATURE_DP_TX_DESC_HISTORY) += -DWLAN_FEATURE_DP_TX_DESC_HISTORY
+ccflags-$(CONFIG_REO_QDESC_HISTORY) += -DREO_QDESC_HISTORY
+ccflags-$(CONFIG_DP_TX_HW_DESC_HISTORY) += -DDP_TX_HW_DESC_HISTORY
+ifdef CONFIG_QDF_NBUF_HISTORY_SIZE
+ccflags-y += -DQDF_NBUF_HISTORY_SIZE=$(CONFIG_QDF_NBUF_HISTORY_SIZE)
+endif
+ccflags-$(CONFIG_WLAN_DP_PER_RING_TYPE_CONFIG) += -DWLAN_DP_PER_RING_TYPE_CONFIG
+ccflags-$(CONFIG_WLAN_CE_INTERRUPT_THRESHOLD_CONFIG) += -DWLAN_CE_INTERRUPT_THRESHOLD_CONFIG
+ccflags-$(CONFIG_SAP_DHCP_FW_IND) += -DSAP_DHCP_FW_IND
+ccflags-$(CONFIG_WLAN_DP_PENDING_MEM_FLUSH) += -DWLAN_DP_PENDING_MEM_FLUSH
+ccflags-$(CONFIG_WLAN_SUPPORT_DATA_STALL) += -DWLAN_SUPPORT_DATA_STALL
+ccflags-$(CONFIG_WLAN_SUPPORT_TXRX_HL_BUNDLE) += -DWLAN_SUPPORT_TXRX_HL_BUNDLE
+ccflags-$(CONFIG_QCN7605_PCIE_SHADOW_REG_SUPPORT) += -DQCN7605_PCIE_SHADOW_REG_SUPPORT
+ccflags-$(CONFIG_QCN7605_PCIE_GOLBAL_RESET_SUPPORT) += -DQCN7605_PCIE_GOLBAL_RESET_SUPPORT
+ccflags-$(CONFIG_MARK_ICMP_REQ_TO_FW) += -DWLAN_DP_FEATURE_MARK_ICMP_REQ_TO_FW
+ccflags-$(CONFIG_EMULATION_2_0) += -DCONFIG_KIWI_EMULATION_2_0
+ccflags-$(CONFIG_WORD_BASED_TLV) += -DCONFIG_WORD_BASED_TLV
+ccflags-$(CONFIG_4_BYTES_TLV_TAG) += -DCONFIG_4_BYTES_TLV_TAG
+ccflags-$(CONFIG_WLAN_SKIP_BAR_UPDATE) += -DWLAN_SKIP_BAR_UPDATE
+ccflags-$(CONFIG_WLAN_TRACEPOINTS) += -DWLAN_TRACEPOINTS
+
+ccflags-$(CONFIG_QCACLD_FEATURE_SON) += -DFEATURE_PERPKT_INFO
+ccflags-$(CONFIG_QCACLD_FEATURE_SON) += -DQCA_ENHANCED_STATS_SUPPORT
+ccflags-$(CONFIG_WLAN_FEATURE_CE_RX_BUFFER_REUSE) += -DWLAN_FEATURE_CE_RX_BUFFER_REUSE
+
+CONFIG_NUM_SOC_PERF_CLUSTER ?= 1
+ccflags-y += -DNUM_SOC_PERF_CLUSTER=$(CONFIG_NUM_SOC_PERF_CLUSTER)
+
+ifeq ($(CONFIG_QMI_COMPONENT_ENABLE), y)
+ccflags-y += -DQMI_COMPONENT_ENABLE
+ifeq ($(CONFIG_QMI_WFDS), y)
+ccflags-y += -DQMI_WFDS
+endif
+endif
+
+ifdef CONFIG_MAX_LOGS_PER_SEC
+ccflags-y += -DWLAN_MAX_LOGS_PER_SEC=$(CONFIG_MAX_LOGS_PER_SEC)
+endif
+
+ifeq ($(CONFIG_NON_QC_PLATFORM), y)
+ccflags-y += -DWLAN_DUMP_LOG_BUF_CNT=$(CONFIG_DUMP_LOG_BUF_CNT)
+endif
+
+ifdef CONFIG_SCHED_HISTORY_SIZE
+ccflags-y += -DWLAN_SCHED_HISTORY_SIZE=$(CONFIG_SCHED_HISTORY_SIZE)
+endif
+
+ifdef CONFIG_QDF_TIMER_MULTIPLIER_FRAC
+ccflags-y += -DQDF_TIMER_MULTIPLIER_FRAC=$(CONFIG_QDF_TIMER_MULTIPLIER_FRAC)
+endif
+
+ifdef CONFIG_DP_LEGACY_MODE_CSM_DEFAULT_DISABLE
+ccflags-y += -DDP_LEGACY_MODE_CSM_DEFAULT_DISABLE=$(CONFIG_DP_LEGACY_MODE_CSM_DEFAULT_DISABLE)
+endif
+
+ifdef CONFIG_HANDLE_RX_REROUTE_ERR
+ccflags-y += -DHANDLE_RX_REROUTE_ERR
+endif
+
+# configure log buffer size
+ifdef CONFIG_CFG_NUM_DP_TRACE_RECORD
+ccflags-y += -DMAX_QDF_DP_TRACE_RECORDS=$(CONFIG_CFG_NUM_DP_TRACE_RECORD)
+endif
+
+ifdef CONFIG_CFG_NUM_HTC_CREDIT_HISTORY
+ccflags-y += -DHTC_CREDIT_HISTORY_MAX=$(CONFIG_CFG_NUM_HTC_CREDIT_HISTORY)
+endif
+
+ifdef CONFIG_CFG_NUM_WMI_EVENT_HISTORY
+ccflags-y += -DWMI_EVENT_DEBUG_MAX_ENTRY=$(CONFIG_CFG_NUM_WMI_EVENT_HISTORY)
+endif
+
+ifdef CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY
+ccflags-y += -DWMI_MGMT_EVENT_DEBUG_MAX_ENTRY=$(CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY)
+endif
+
+ifdef CONFIG_CFG_NUM_TX_RX_HISTOGRAM
+ccflags-y += -DNUM_TX_RX_HISTOGRAM=$(CONFIG_CFG_NUM_TX_RX_HISTOGRAM)
+endif
+
+ifdef CONFIG_CFG_NUM_RX_IND_RECORD
+ccflags-y += -DOL_RX_INDICATION_MAX_RECORDS=$(CONFIG_CFG_NUM_RX_IND_RECORD)
+endif
+
+ifdef CONFIG_CFG_NUM_ROAM_DEBUG_RECORD
+ccflags-y += -DWLAN_ROAM_DEBUG_MAX_REC=$(CONFIG_CFG_NUM_ROAM_DEBUG_RECORD)
+endif
+
+ifdef CONFIG_CFG_PMO_WOW_FILTERS_MAX
+ccflags-y += -DPMO_WOW_FILTERS_MAX=$(CONFIG_CFG_PMO_WOW_FILTERS_MAX)
+endif
+
+ifdef CONFIG_CFG_GTK_OFFLOAD_MAX_VDEV
+ccflags-y += -DCFG_TGT_DEFAULT_GTK_OFFLOAD_MAX_VDEV=$(CONFIG_CFG_GTK_OFFLOAD_MAX_VDEV)
+endif
+
+ifdef CONFIG_TGT_NUM_MSDU_DESC
+ccflags-y += -DCFG_TGT_NUM_MSDU_DESC=$(CONFIG_TGT_NUM_MSDU_DESC)
+endif
+
+ifdef CONFIG_HTC_MAX_MSG_PER_BUNDLE_TX
+ccflags-y += -DCFG_HTC_MAX_MSG_PER_BUNDLE_TX=$(CONFIG_HTC_MAX_MSG_PER_BUNDLE_TX)
+endif
+
+ifdef CONFIG_CFG_BMISS_OFFLOAD_MAX_VDEV
+ccflags-y += -DCFG_TGT_DEFAULT_BMISS_OFFLOAD_MAX_VDEV=$(CONFIG_CFG_BMISS_OFFLOAD_MAX_VDEV)
+endif
+
+ifdef CONFIG_WLAN_UMAC_MLO_MAX_DEV
+ccflags-y += -DWLAN_UMAC_MLO_MAX_DEV=$(CONFIG_WLAN_UMAC_MLO_MAX_DEV)
+endif
+
+ifdef CONFIG_CFG_ROAM_OFFLOAD_MAX_VDEV
+ccflags-y += -DCFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_VDEV=$(CONFIG_CFG_ROAM_OFFLOAD_MAX_VDEV)
+endif
+
+ifdef CONFIG_CFG_MAX_PERIODIC_TX_PTRNS
+ccflags-y += -DMAXNUM_PERIODIC_TX_PTRNS=$(CONFIG_CFG_MAX_PERIODIC_TX_PTRNS)
+endif
+
+ifdef CONFIG_CFG_MAX_STA_VDEVS
+ccflags-y += -DCFG_TGT_DEFAULT_MAX_STA_VDEVS=$(CONFIG_CFG_MAX_STA_VDEVS)
+endif
+
+ifdef CONFIG_CFG_NUM_OF_ADDITIONAL_FW_PEERS
+ccflags-y += -DNUM_OF_ADDITIONAL_FW_PEERS=$(CONFIG_CFG_NUM_OF_ADDITIONAL_FW_PEERS)
+endif
+
+ifdef CONFIG_CFG_NUM_OF_TDLS_CONN_TABLE_ENTRIES
+ccflags-y += -DCFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES=$(CONFIG_CFG_NUM_OF_TDLS_CONN_TABLE_ENTRIES)
+endif
+
+ifdef CONFIG_CFG_TGT_AST_SKID_LIMIT
+ccflags-y += -DCFG_TGT_AST_SKID_LIMIT=$(CONFIG_CFG_TGT_AST_SKID_LIMIT)
+endif
+
+ifdef CONFIG_TX_RESOURCE_HIGH_TH_IN_PER
+ccflags-y += -DTX_RESOURCE_HIGH_TH_IN_PER=$(CONFIG_TX_RESOURCE_HIGH_TH_IN_PER)
+endif
+
+ifdef CONFIG_TX_RESOURCE_LOW_TH_IN_PER
+ccflags-y += -DTX_RESOURCE_LOW_TH_IN_PER=$(CONFIG_TX_RESOURCE_LOW_TH_IN_PER)
+endif
+
+CONFIG_WLAN_MAX_PSOCS ?= 1
+ccflags-y += -DWLAN_MAX_PSOCS=$(CONFIG_WLAN_MAX_PSOCS)
+
+CONFIG_WLAN_MAX_PDEVS ?= 1
+ccflags-y += -DWLAN_MAX_PDEVS=$(CONFIG_WLAN_MAX_PDEVS)
+
+ifeq ($(CONFIG_WLAN_FEATURE_11BE_MLO), y)
+CONFIG_WLAN_MAX_ML_VDEVS ?= 3
+else
+CONFIG_WLAN_MAX_ML_VDEVS ?= 0
+endif
+ccflags-y += -DWLAN_MAX_ML_VDEVS=$(CONFIG_WLAN_MAX_ML_VDEVS)
+
+CONFIG_WLAN_MAX_VDEVS ?= 6
+ccflags-y += -DWLAN_MAX_VDEVS=$(CONFIG_WLAN_MAX_VDEVS)
+
+ifdef CONFIG_WLAN_FEATURE_11BE_MLO
+CONFIG_WLAN_MAX_MLD ?= 2
+else
+CONFIG_WLAN_MAX_MLD ?= 1
+endif
+ccflags-y += -DWLAN_MAX_MLD=$(CONFIG_WLAN_MAX_MLD)
+
+ifdef CONFIG_WLAN_FEATURE_11BE_MLO
+CONFIG_WLAN_MAX_ML_DEFAULT_LINK ?= 2
+else
+CONFIG_WLAN_MAX_ML_DEFAULT_LINK  ?= 1
+endif
+ccflags-y += -DWLAN_MAX_ML_DEFAULT_LINK=$(CONFIG_WLAN_MAX_ML_DEFAULT_LINK)
+
+ifdef CONFIG_WLAN_FEATURE_11BE_MLO
+ifndef CONFIG_WLAN_DEFAULT_REC_LINK_VALUE
+CONFIG_WLAN_DEFAULT_REC_LINK_VALUE  ?= 2
+endif
+else
+ifndef CONFIG_WLAN_DEFAULT_REC_LINK_VALUE
+CONFIG_WLAN_DEFAULT_REC_LINK_VALUE  ?= 2
+endif
+endif
+ccflags-y += -DWLAN_DEFAULT_REC_LINK_VALUE=$(CONFIG_WLAN_DEFAULT_REC_LINK_VALUE)
+
+ifdef CONFIG_WLAN_FEATURE_11BE_MLO
+CONFIG_WLAN_MAX_ML_BSS_LINKS ?= 3
+else
+CONFIG_WLAN_MAX_ML_BSS_LINKS ?= 1
+endif
+ccflags-y += -DWLAN_MAX_ML_BSS_LINKS=$(CONFIG_WLAN_MAX_ML_BSS_LINKS)
+
+ifdef CONFIG_WLAN_FEATURE_EMLSR
+CONFIG_WLAN_EMLSR_ENABLE ?= 1
+else
+CONFIG_WLAN_EMLSR_ENABLE ?= 0
+endif
+ccflags-y += -DWLAN_EMLSR_ENABLE=$(CONFIG_WLAN_EMLSR_ENABLE)
+
+#Maximum pending commands for a vdev is calculated in vdev create handler
+#by WLAN_SER_MAX_PENDING_CMDS/WLAN_SER_MAX_VDEVS. For SAP case, we will need
+#to accommodate 32 Pending commands to handle multiple STA sending
+#deauth/disassoc at the same time and for STA vdev,4 non scan pending commands
+#are supported. So calculate WLAN_SER_MAX_PENDING_COMMANDS based on the SAP
+#modes supported and no of STA vdev total non scan pending queue. Reserve
+#additional 3 pending commands for WLAN_SER_MAX_PENDING_CMDS_AP to account for
+#other commands like hardware mode change.
+
+ifdef CONFIG_SIR_SAP_MAX_NUM_PEERS
+CONFIG_WLAN_SER_MAX_PENDING_CMDS_AP ?=$(CONFIG_SIR_SAP_MAX_NUM_PEERS)
+else
+CONFIG_WLAN_SER_MAX_PENDING_CMDS_AP ?=32
+endif
+ccflags-y += -DWLAN_SER_MAX_PENDING_CMDS_AP=$(CONFIG_WLAN_SER_MAX_PENDING_CMDS_AP)+3
+
+CONFIG_WLAN_SER_MAX_PENDING_CMDS_STA ?= 4
+ccflags-y += -DWLAN_SER_MAX_PENDING_CMDS_STA=$(CONFIG_WLAN_SER_MAX_PENDING_CMDS_STA)
+
+CONFIG_WLAN_MAX_PENDING_CMDS ?= $(CONFIG_WLAN_SER_MAX_PENDING_CMDS_AP)*3+$(CONFIG_WLAN_SER_MAX_PENDING_CMDS_STA)*2
+
+ccflags-y += -DWLAN_SER_MAX_PENDING_CMDS=$(CONFIG_WLAN_MAX_PENDING_CMDS)
+
+CONFIG_WLAN_PDEV_MAX_VDEVS ?= $(CONFIG_WLAN_MAX_VDEVS)
+ccflags-y += -DWLAN_PDEV_MAX_VDEVS=$(CONFIG_WLAN_PDEV_MAX_VDEVS)
+
+CONFIG_WLAN_PSOC_MAX_VDEVS ?= $(CONFIG_WLAN_MAX_VDEVS)
+ccflags-y += -DWLAN_PSOC_MAX_VDEVS=$(CONFIG_WLAN_PSOC_MAX_VDEVS)
+
+CONFIG_MAX_SCAN_CACHE_SIZE ?= 500
+ccflags-y += -DMAX_SCAN_CACHE_SIZE=$(CONFIG_MAX_SCAN_CACHE_SIZE)
+CONFIG_SCAN_MAX_REST_TIME ?= 0
+ccflags-y += -DSCAN_MAX_REST_TIME=$(CONFIG_SCAN_MAX_REST_TIME)
+CONFIG_SCAN_MIN_REST_TIME ?= 0
+ccflags-y += -DSCAN_MIN_REST_TIME=$(CONFIG_SCAN_MIN_REST_TIME)
+CONFIG_SCAN_BURST_DURATION ?= 0
+ccflags-y += -DSCAN_BURST_DURATION=$(CONFIG_SCAN_BURST_DURATION)
+CONFIG_SCAN_PROBE_SPACING_TIME ?= 0
+ccflags-y += -DSCAN_PROBE_SPACING_TIME=$(CONFIG_SCAN_PROBE_SPACING_TIME)
+CONFIG_SCAN_PROBE_DELAY ?= 0
+ccflags-y += -DSCAN_PROBE_DELAY=$(CONFIG_SCAN_PROBE_DELAY)
+CONFIG_SCAN_MAX_SCAN_TIME ?= 30000
+ccflags-y += -DSCAN_MAX_SCAN_TIME=$(CONFIG_SCAN_MAX_SCAN_TIME)
+CONFIG_SCAN_NETWORK_IDLE_TIMEOUT ?= 0
+ccflags-y += -DSCAN_NETWORK_IDLE_TIMEOUT=$(CONFIG_SCAN_NETWORK_IDLE_TIMEOUT)
+CONFIG_HIDDEN_SSID_TIME ?= 0xFFFFFFFF
+ccflags-y += -DHIDDEN_SSID_TIME=$(CONFIG_HIDDEN_SSID_TIME)
+CONFIG_SCAN_CHAN_STATS_EVENT_ENAB ?= false
+ccflags-y += -DSCAN_CHAN_STATS_EVENT_ENAB=$(CONFIG_SCAN_CHAN_STATS_EVENT_ENAB)
+CONFIG_MAX_BCN_PROBE_IN_SCAN_QUEUE ?= 150
+ccflags-y += -DMAX_BCN_PROBE_IN_SCAN_QUEUE=$(CONFIG_MAX_BCN_PROBE_IN_SCAN_QUEUE)
+
+#CONFIG_RX_DIAG_WQ_MAX_SIZE maximum number FW diag events that can be queued in
+#FW diag events work queue. Host driver will discard the all diag events after
+#this limit is reached.
+#
+# Value 0 represents no limit and any non zero value represents the maximum
+# size of the work queue.
+CONFIG_RX_DIAG_WQ_MAX_SIZE ?= 1000
+ccflags-y += -DRX_DIAG_WQ_MAX_SIZE=$(CONFIG_RX_DIAG_WQ_MAX_SIZE)
+
+CONFIG_MGMT_DESC_POOL_MAX ?= 64
+ccflags-y += -DMGMT_DESC_POOL_MAX=$(CONFIG_MGMT_DESC_POOL_MAX)
+
+ifdef CONFIG_SIR_SAP_MAX_NUM_PEERS
+ccflags-y += -DSIR_SAP_MAX_NUM_PEERS=$(CONFIG_SIR_SAP_MAX_NUM_PEERS)
+endif
+
+ifdef CONFIG_BEACON_TX_OFFLOAD_MAX_VDEV
+ccflags-y += -DCFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV=$(CONFIG_BEACON_TX_OFFLOAD_MAX_VDEV)
+endif
+
+ifdef CONFIG_LIMIT_IPA_TX_BUFFER
+ccflags-y += -DLIMIT_IPA_TX_BUFFER=$(CONFIG_LIMIT_IPA_TX_BUFFER)
+endif
+
+ifdef CONFIG_LOCK_STATS_ON
+ccflags-y += -DQDF_LOCK_STATS=1
+ccflags-y += -DQDF_LOCK_STATS_DESTROY_PRINT=0
+ifneq ($(CONFIG_ARCH_SDXPRAIRIE), y)
+ccflags-y += -DQDF_LOCK_STATS_BUG_ON=1
+endif
+ccflags-$(CONFIG_VCPU_TIMESTOLEN) += -DVCPU_TIMESTOLEN
+ccflags-y += -DQDF_LOCK_STATS_LIST=1
+ccflags-y += -DQDF_LOCK_STATS_LIST_SIZE=256
+endif
+
+ifdef CONFIG_FW_THERMAL_THROTTLE
+ccflags-y += -DFW_THERMAL_THROTTLE_SUPPORT
+endif
+
+ccflags-$(CONFIG_FEATURE_RX_LINKSPEED_ROAM_TRIGGER) += -DFEATURE_RX_LINKSPEED_ROAM_TRIGGER
+#DP_RATETABLE_SUPPORT is enabled when CONFIG_FEATURE_RX_LINKSPEED_ROAM_TRIGGER is enabled
+ccflags-$(CONFIG_FEATURE_RX_LINKSPEED_ROAM_TRIGGER) += -DDP_RATETABLE_SUPPORT
+
+ccflags-$(CONFIG_BAND_6GHZ) += -DCONFIG_BAND_6GHZ
+ccflags-$(CONFIG_6G_SCAN_CHAN_SORT_ALGO) += -DFEATURE_6G_SCAN_CHAN_SORT_ALGO
+ccflags-$(CONFIG_AFC_SUPPORT) += -DCONFIG_AFC_SUPPORT
+ccflags-$(CONFIG_WLAN_FEATURE_AFC_DCS_SKIP_ACS_RANGE) += -DWLAN_FEATURE_AFC_DCS_SKIP_ACS_RANGE
+
+ccflags-$(CONFIG_RX_FISA) += -DWLAN_SUPPORT_RX_FISA
+ccflags-$(CONFIG_RX_FISA_HISTORY) += -DWLAN_SUPPORT_RX_FISA_HIST
+
+ccflags-$(CONFIG_DP_SWLM) += -DWLAN_DP_FEATURE_SW_LATENCY_MGR
+
+ccflags-$(CONFIG_RX_DEFRAG_DO_NOT_REINJECT) += -DRX_DEFRAG_DO_NOT_REINJECT
+
+ccflags-$(CONFIG_HANDLE_BC_EAP_TX_FRM) += -DHANDLE_BROADCAST_EAPOL_TX_FRAME
+
+ccflags-$(CONFIG_MORE_TX_DESC) += -DTX_TO_NPEERS_INC_TX_DESCS
+
+ccflags-$(CONFIG_HASTINGS_BT_WAR) += -DHASTINGS_BT_WAR
+
+ccflags-$(CONFIG_HIF_DEBUG) += -DHIF_CONFIG_SLUB_DEBUG_ON
+ccflags-$(CONFIG_HAL_DEBUG) += -DHAL_CONFIG_SLUB_DEBUG_ON
+
+ccflags-$(CONFIG_FOURTH_CONNECTION) += -DFEATURE_FOURTH_CONNECTION
+ccflags-$(CONFIG_FOURTH_CONNECTION_AUTO) += -DFOURTH_CONNECTION_AUTO
+ccflags-$(CONFIG_WMI_SEND_RECV_QMI) += -DWLAN_FEATURE_WMI_SEND_RECV_QMI
+
+ccflags-$(CONFIG_WDI3_STATS_UPDATE) += -DWDI3_STATS_UPDATE
+ccflags-$(CONFIG_WDI3_STATS_BW_MONITOR) += -DWDI3_STATS_BW_MONITOR
+
+ccflags-$(CONFIG_IPA_P2P_SUPPORT) += -DIPA_P2P_SUPPORT
+
+ccflags-$(CONFIG_WLAN_CUSTOM_DSCP_UP_MAP) += -DWLAN_CUSTOM_DSCP_UP_MAP
+ccflags-$(CONFIG_WLAN_SEND_DSCP_UP_MAP_TO_FW) += -DWLAN_SEND_DSCP_UP_MAP_TO_FW
+
+ccflags-$(CONFIG_SMMU_S1_UNMAP) += -DCONFIG_SMMU_S1_UNMAP
+ccflags-$(CONFIG_HIF_CPU_PERF_AFFINE_MASK) += -DHIF_CPU_PERF_AFFINE_MASK
+ccflags-$(CONFIG_HIF_CPU_CLEAR_AFFINITY) += -DHIF_CPU_CLEAR_AFFINITY
+
+ccflags-$(CONFIG_GENERIC_SHADOW_REGISTER_ACCESS_ENABLE) += -DGENERIC_SHADOW_REGISTER_ACCESS_ENABLE
+ccflags-$(CONFIG_IPA_SET_RESET_TX_DB_PA) += -DIPA_SET_RESET_TX_DB_PA
+ccflags-$(CONFIG_DEVICE_FORCE_WAKE_ENABLE) += -DDEVICE_FORCE_WAKE_ENABLE
+ccflags-$(CONFIG_WINDOW_REG_PLD_LOCK_ENABLE) += -DWINDOW_REG_PLD_LOCK_ENABLE
+ccflags-$(CONFIG_DUMP_REO_QUEUE_INFO_IN_DDR) += -DDUMP_REO_QUEUE_INFO_IN_DDR
+ccflags-$(CONFIG_DP_RX_REFILL_CPU_PERF_AFFINE_MASK) += -DDP_RX_REFILL_CPU_PERF_AFFINE_MASK
+ccflags-$(CONFIG_WLAN_FEATURE_AFFINITY_MGR) += -DWLAN_FEATURE_AFFINITY_MGR
+ccflags-$(CONFIG_FEATURE_ENABLE_CE_DP_IRQ_AFFINE) += -DFEATURE_ENABLE_CE_DP_IRQ_AFFINE
+found = $(shell if grep -qF "walt_get_cpus_taken" $(srctree)/kernel/sched/walt/walt.c; then echo "yes" ;else echo "no" ;fi;)
+ifeq ($(findstring yes, $(found)), yes)
+ccflags-y += -DWALT_GET_CPU_TAKEN_SUPPORT
+endif
+
+ifdef CONFIG_MAX_CLIENTS_ALLOWED
+ccflags-y += -DWLAN_MAX_CLIENTS_ALLOWED=$(CONFIG_MAX_CLIENTS_ALLOWED)
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_RX_BUFFER_POOL), y)
+ccflags-y += -DWLAN_FEATURE_RX_PREALLOC_BUFFER_POOL
+ifdef CONFIG_DP_RX_BUFFER_POOL_SIZE
+ccflags-y += -DDP_RX_BUFFER_POOL_SIZE=$(CONFIG_DP_RX_BUFFER_POOL_SIZE)
+endif
+ifdef CONFIG_DP_RX_BUFFER_POOL_ALLOC_THRES
+ccflags-y += -DDP_RX_BUFFER_POOL_ALLOC_THRES=$(CONFIG_DP_RX_BUFFER_POOL_ALLOC_THRES)
+endif
+ifdef CONFIG_DP_RX_REFILL_BUFF_POOL_SIZE
+ccflags-y += -DDP_RX_REFILL_BUFF_POOL_SIZE=$(CONFIG_DP_RX_REFILL_BUFF_POOL_SIZE)
+endif
+ifdef CONFIG_DP_RX_REFILL_THRD_THRESHOLD
+ccflags-y += -DDP_RX_REFILL_THRD_THRESHOLD=$(CONFIG_DP_RX_REFILL_THRD_THRESHOLD)
+endif
+endif
+
+ccflags-$(CONFIG_DP_FT_LOCK_HISTORY) += -DDP_FT_LOCK_HISTORY
+
+ccflags-$(CONFIG_INTRA_BSS_FWD_OFFLOAD) += -DINTRA_BSS_FWD_OFFLOAD
+ccflags-$(CONFIG_GET_DRIVER_MODE) += -DFEATURE_GET_DRIVER_MODE
+
+ifeq ($(CONFIG_FEATURE_IPA_PIPE_CHANGE_WDI1), y)
+ccflags-y += -DFEATURE_IPA_PIPE_CHANGE_WDI1
+endif
+
+ccflags-$(CONFIG_WLAN_BOOTUP_MARKER) += -DWLAN_BOOTUP_MARKER
+ifdef CONFIG_WLAN_PLACEMARKER_PREFIX
+ccflags-y += -DWLAN_PLACEMARKER_PREFIX=\"$(CONFIG_WLAN_PLACEMARKER_PREFIX)\"
+endif
+
+ccflags-$(CONFIG_FEATURE_STA_MODE_VOTE_LINK) += -DFEATURE_STA_MODE_VOTE_LINK
+ccflags-$(CONFIG_WLAN_ENABLE_GPIO_WAKEUP) += -DWLAN_ENABLE_GPIO_WAKEUP
+ccflags-$(CONFIG_WLAN_MAC_ADDR_UPDATE_DISABLE) += -DWLAN_MAC_ADDR_UPDATE_DISABLE
+
+ifeq ($(CONFIG_SMP), y)
+ifeq ($(CONFIG_HIF_DETECTION_LATENCY_ENABLE), y)
+ccflags-y += -DHIF_DETECTION_LATENCY_ENABLE
+ccflags-y += -DDETECTION_TIMER_TIMEOUT=4000
+ccflags-y += -DDETECTION_LATENCY_THRESHOLD=3900
+endif
+endif
+
+#Flags to enable/disable WDS specific features
+ccflags-$(CONFIG_FEATURE_WDS) += -DFEATURE_WDS
+ccflags-$(CONFIG_FEATURE_MEC) += -DFEATURE_MEC
+ccflags-$(CONFIG_FEATURE_MCL_REPEATER) += -DFEATURE_MCL_REPEATER
+ccflags-$(CONFIG_WDS_CONV_TARGET_IF_OPS_ENABLE) += -DWDS_CONV_TARGET_IF_OPS_ENABLE
+ccflags-$(CONFIG_BYPASS_WDS_OL_OPS) += -DBYPASS_OL_OPS
+
+ccflags-$(CONFIG_IPA_WDI3_TX_TWO_PIPES) += -DIPA_WDI3_TX_TWO_PIPES
+
+ccflags-$(CONFIG_DP_TX_TRACKING) += -DDP_TX_TRACKING
+
+ifdef CONFIG_CHIP_VERSION
+ccflags-y += -DCHIP_VERSION=$(CONFIG_CHIP_VERSION)
+endif
+
+ccflags-$(CONFIG_WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET) += -DWLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET
+
+ccflags-$(CONFIG_SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND) += -DSHUTDOWN_WLAN_IN_SYSTEM_SUSPEND
+
+ifeq ($(CONFIG_WLAN_FEATURE_MCC_QUOTA), y)
+ccflags-y += -DWLAN_FEATURE_MCC_QUOTA
+ifdef CONFIG_WLAN_MCC_MIN_CHANNEL_QUOTA
+ccflags-y += -DWLAN_MCC_MIN_CHANNEL_QUOTA=$(CONFIG_WLAN_MCC_MIN_CHANNEL_QUOTA)
+endif
+endif
+
+ccflags-$(CONFIG_WLAN_FEATURE_PEER_TXQ_FLUSH_CONF) += -DWLAN_FEATURE_PEER_TXQ_FLUSH_CONF
+
+ifeq ($(CONFIG_DP_HW_TX_DELAY_STATS_ENABLE), y)
+ccflags-y += -DHW_TX_DELAY_STATS_ENABLE
+endif
+
+# Config MAX SAP interface number
+ifdef CONFIG_QDF_MAX_NO_OF_SAP_MODE
+ccflags-y += -DQDF_MAX_NO_OF_SAP_MODE=$(CONFIG_QDF_MAX_NO_OF_SAP_MODE)
+endif
+
+#Flags to enable/disable Dynamic WLAN interface control feature
+ifeq ($(CONFIG_CNSS_HW_SECURE_DISABLE), y)
+ccflags-y += -DFEATURE_CNSS_HW_SECURE_DISABLE
+endif
+
+#DBAM feature needs COEX feature to be enabled
+ifeq ($(CONFIG_FEATURE_COEX), y)
+ccflags-$(CONFIG_WLAN_FEATURE_COEX_DBAM) += -DWLAN_FEATURE_DBAM_CONFIG
+endif
+
+# Flag to enable Constrained Application Protocol feature
+ccflags-$(CONFIG_WLAN_FEATURE_COAP) += -DWLAN_FEATURE_COAP
+
+# SSR driver dump config
+ccflags-$(CONFIG_CNSS2_SSR_DRIVER_DUMP) += -DWLAN_FEATURE_SSR_DRIVER_DUMP
+
+# Currently, for versions of gcc which support it, the kernel Makefile
+# is disabling the maybe-uninitialized warning.  Re-enable it for the
+# WLAN driver.  Note that we must use ccflags-y here so that it
+# will override the kernel settings.
+ifeq ($(call cc-option-yn, -Wmaybe-uninitialized), y)
+ccflags-y += -Wmaybe-uninitialized
+ifneq (y,$(CONFIG_ARCH_MSM))
+ccflags-y += -Wframe-larger-than=4096
+endif
+endif
+ccflags-y += -Wmissing-prototypes
+
+ifeq ($(call cc-option-yn, -Wheader-guard), y)
+ccflags-y += -Wheader-guard
+endif
+# If the module name is not "wlan", then the define MULTI_IF_NAME to be the
+# same a the QCA CHIP name. The host driver will then append MULTI_IF_NAME to
+# any string that must be unique for all instances of the driver on the system.
+# This allows multiple instances of the driver with different module names.
+# If the module name is wlan, leave MULTI_IF_NAME undefined and the code will
+# treat the driver as the primary driver.
+#
+# If DYNAMIC_SINGLE_CHIP is defined and MULTI_IF_NAME is undefined, which means
+# there are multiple possible drivers, but only 1 driver will be loaded at
+# a time(WLAN dynamic detect), no matter what the module name is, then
+# host driver will only append DYNAMIC_SINGLE_CHIP to the path of
+# firmware/mac/ini file.
+#
+# If DYNAMIC_SINGLE_CHIP & MULTI_IF_NAME defined, which means there are
+# multiple possible drivers, we also can load multiple drivers together.
+# And we can use DYNAMIC_SINGLE_CHIP to distinguish the ko name, and use
+# MULTI_IF_NAME to make cnss2 platform driver to figure out which wlanhost
+# driver attached. Moreover, as the first priority, host driver will only
+# append DYNAMIC_SINGLE_CHIP to the path of firmware/mac/ini file.
+
+ifneq ($(DYNAMIC_SINGLE_CHIP),)
+ccflags-y += -DDYNAMIC_SINGLE_CHIP=\"$(DYNAMIC_SINGLE_CHIP)\"
+ifneq ($(MULTI_IF_NAME),)
+ccflags-y += -DMULTI_IF_NAME=\"$(MULTI_IF_NAME)\"
+endif
+#
+else
+
+ifneq ($(MODNAME), wlan)
+CHIP_NAME ?= $(MODNAME)
+ccflags-y += -DMULTI_IF_NAME=\"$(CHIP_NAME)\"
+endif
+
+endif #DYNAMIC_SINGLE_CHIP
+
+# WLAN_HDD_ADAPTER_MAGIC must be unique for all instances of the driver on the
+# system. If it is not defined, then the host driver will use the first 4
+# characters (including NULL) of MULTI_IF_NAME to construct
+# WLAN_HDD_ADAPTER_MAGIC.
+ifdef WLAN_HDD_ADAPTER_MAGIC
+ccflags-y += -DWLAN_HDD_ADAPTER_MAGIC=$(WLAN_HDD_ADAPTER_MAGIC)
+endif
+
+# Determine if we are building against an arm architecture host
+ifeq ($(findstring arm, $(ARCH)),)
+	ccflags-y += -DWLAN_HOST_ARCH_ARM=0
+else
+	ccflags-y += -DWLAN_HOST_ARCH_ARM=1
+endif
+
+# Android wifi state control interface
+ifneq ($(WLAN_CTRL_NAME),)
+ccflags-y += -DWLAN_CTRL_NAME=\"$(WLAN_CTRL_NAME)\"
+endif
+
+# inject some build related information
+ifeq ($(CONFIG_BUILD_TAG), y)
+CLD_CHECKOUT = $(shell cd "$(WLAN_ROOT)" && \
+	git reflog | grep -vm1 "}: cherry-pick: " | grep -oE ^[0-f]+)
+CLD_IDS = $(shell cd "$(WLAN_ROOT)" && \
+	git log -50 $(CLD_CHECKOUT)~..HEAD | \
+		sed -nE 's/^\s*Change-Id: (I[0-f]{10})[0-f]{30}\s*$$/\1/p' | \
+		paste -sd "," -)
+
+CMN_CHECKOUT = $(shell cd "$(WLAN_COMMON_INC)" && \
+	git reflog | grep -vm1 "}: cherry-pick: " | grep -oE ^[0-f]+)
+CMN_IDS = $(shell cd "$(WLAN_COMMON_INC)" && \
+	git log -50 $(CMN_CHECKOUT)~..HEAD | \
+		sed -nE 's/^\s*Change-Id: (I[0-f]{10})[0-f]{30}\s*$$/\1/p' | \
+		paste -sd "," -)
+BUILD_TAG = "cld:$(CLD_IDS); cmn:$(CMN_IDS); dev:$(DEVNAME)"
+ccflags-y += -DBUILD_TAG=\"$(BUILD_TAG)\"
+endif
+
+ifeq ($(CONFIG_ARCH_PINEAPPLE), y)
+ccflags-y += -gdwarf-4
+endif
+
+# Module information used by KBuild framework
+obj-$(CONFIG_QCA_CLD_WLAN) += $(MODNAME).o
+ifeq ($(CONFIG_WLAN_RESIDENT_DRIVER), y)
+$(MODNAME)-y := $(HDD_SRC_DIR)/wlan_hdd_main_module.o
+obj-$(CONFIG_QCA_CLD_WLAN) += wlan_resident.o
+wlan_resident-y := $(OBJS)
+else
+$(MODNAME)-y := $(OBJS)
+endif
+OBJS_DIRS += $(dir $(OBJS)) \
+	     $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ \
+	     $(QDF_OBJ_DIR)/ \
+	     $(WLAN_COMMON_ROOT)/$(HIF_PCIE_DIR)/ \
+	     $(WLAN_COMMON_ROOT)/$(HIF_SNOC_DIR)/ \
+	     $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/
+CLEAN_DIRS := $(addsuffix *.o,$(sort $(OBJS_DIRS))) \
+	      $(addsuffix .*.o.cmd,$(sort $(OBJS_DIRS)))
+clean-files := $(CLEAN_DIRS)

+ 2156 - 0
qcom/opensource/wlan/qcacld-3.0/Kconfig

@@ -0,0 +1,2156 @@
+comment "Qualcomm Atheros CLD WLAN module"
+
+config QCA_CLD_WLAN
+	tristate "Qualcomm Atheros CLD WLAN module"
+	default n
+	help
+	Add support for the Qualcomm Atheros CLD WLAN module
+
+if QCA_CLD_WLAN != n
+
+config WLAN_FEATURE_NO_STA_SAP_CONCURRENCY
+	bool "Enable WLAN_FEATURE_NO_STA_SAP_CONCURRENCY"
+	default n
+
+config WLAN_FEATURE_NO_STA_NAN_CONCURRENCY
+	bool "Enable WLAN_FEATURE_NO_STA_NAN_CONCURRENCY"
+	default n
+
+config WLAN_FEATURE_NO_SAP_NAN_CONCURRENCY
+	bool "Enable WLAN_FEATURE_NO_SAP_NAN_CONCURRENCY"
+	default n
+
+config WLAN_FEATURE_NO_P2P_CONCURRENCY
+	bool "Enable WLAN_FEATURE_NO_P2P_CONCURRENCY"
+	default n
+
+config 160MHZ_SUPPORT
+	bool "Enable 160MHZ_SUPPORT"
+	default n
+
+config 64BIT_PADDR
+	bool "Enable 37-bit physical/bus addresses"
+	depends on HELIUMPLUS
+	default n
+
+config 6G_SCAN_CHAN_SORT_ALGO
+	bool "Enable 6G_SCAN_CHAN_SORT_ALGO"
+	default n
+
+config ADAPTIVE_11R
+	bool "Enable ADAPTIVE_11R"
+	default n
+
+config AGEIE_ON_SCAN_RESULTS
+	bool "Enable AGEIE_ON_SCAN_RESULTS"
+	default n
+
+config ALLOW_PKT_DROPPING
+	bool "Enable ALLOW_PKT_DROPPING"
+	default n
+
+config ANI_LEVEL_REQUEST
+	bool "Enable ANI_LEVEL_REQUEST"
+	default n
+
+config AR900B
+	bool "Enable AR900B"
+	default n
+
+config ATH_11AC_TXCOMPACT
+	bool "Enable ATH_11AC_TXCOMPACT"
+	default n
+
+config ATH_BUS_PM
+	bool "Enable ATH_BUS_PM"
+	default n
+
+config ATH_DIAG_EXT_DIRECT
+	bool "Enable ATH_DIAG_EXT_DIRECT"
+	default n
+
+config ATH_PERF_PWR_OFFLOAD
+	bool "Enable ATH_PERF_PWR_OFFLOAD"
+	default n
+
+config BAND_6GHZ
+	bool "Enable BAND_6GHZ"
+	default n
+
+config BERYLLIUM
+	bool "Enable BERYLLIUM"
+	default n
+
+config BUILD_TAG
+	bool "Embed tags and timestamp in wlan version"
+	default n
+
+config BUILD_TIMESTAMP
+	bool "Embed timestamp in wlan version"
+	default n
+
+config BUS_AUTO_SUSPEND
+	bool "enable CONFIG_BUS_AUTO_SUSPEND"
+	default n
+
+config CE_DISABLE_SRNG_TIMER_IRQ
+	bool "Enable CE_DISABLE_SRNG_TIMER_IRQ"
+	default n
+
+config CHECKSUM_OFFLOAD
+	bool "Enable CHECKSUM_OFFLOAD"
+	default n
+
+config CHIP_VERSION
+	int "Enable CHIP_VERSION"
+
+config CNSS_GENL_MODULE
+	bool "Enable CNSS_GENL_MODULE"
+	default n
+
+config CNSS_KIWI
+	bool "Enable CNSS_KIWI"
+	default n
+
+config CNSS_KIWI_V2
+	bool "Enable CNSS_KIWI_V2"
+	default n
+
+config CNSS_PEACH
+	bool "Enable CNSS_PEACH"
+	default n
+
+config CNSS_PEACH_V2
+	bool "Enable CNSS_PEACH_V2"
+	default n
+
+config INCLUDE_HAL_KIWI
+	bool "Enable INCLUDE_HAL_KIWI"
+	default n
+
+config INCLUDE_HAL_PEACH
+	bool "Enable INCLUDE_HAL_PEACH"
+	default n
+
+config CNSS_UTILS_MODULE
+	bool "Enable CNSS_UTILS_MODULE"
+	default n
+
+config CNSS_UTILS
+    tristate "Enable CNSS_UTILS"
+    default n
+
+config CONNECTIVITY_PKTLOG
+	bool "Enable CONNECTIVITY_PKTLOG"
+	default n
+
+config CONVERGED_P2P_ENABLE
+	bool "Enable CONVERGED_P2P_ENABLE"
+	default n
+
+config CP_STATS
+	bool "Enable CP_STATS"
+	default n
+
+config QCA_TARGET_IF_MLME
+	bool "Enable TARGET_IF MLME"
+	default n
+
+config DCS
+	bool "Enable DCS"
+	default n
+
+config DDP_MON_RSSI_IN_DBM
+	bool "Enable DDP_MON_RSSI_IN_DBM"
+	default n
+
+config DEBUG_RX_RING_BUFFER
+	bool "Enable DEBUG_RX_RING_BUFFER"
+	default n
+
+config DELIVERY_TO_STACK_STATUS_CHECK
+	bool "Enable DELIVERY_TO_STACK_STATUS_CHECK"
+	default n
+
+config DESC_DUP_DETECT_DEBUG
+	bool "Enable DESC_DUP_DETECT_DEBUG"
+	default n
+
+config DESC_TIMESTAMP_DEBUG_INFO
+	bool "Enable DESC_TIMESTAMP_DEBUG_INFO"
+	default n
+
+config DEVICE_FORCE_WAKE_ENABLE
+	bool "Enable DEVICE_FORCE_WAKE_ENABLE"
+	default n
+
+config DIRECT_BUF_RX_ENABLE
+	bool "Enable DIRECT_BUF_RX_ENABLE"
+	default n
+
+config DISABLE_CHANNEL_LIST
+	bool "Enable DISABLE_CHANNEL_LIST"
+	default n
+
+config DISABLE_EAPOL_INTRABSS_FWD
+	bool "Enable DISABLE_EAPOL_INTRABSS_FWD"
+	default n
+
+config DISABLE_STATUS_RING_TIMER_WAR
+	bool "Enable DISABLE_STATUS_RING_TIMER_WAR"
+	default n
+
+config DP_BE_WAR
+	bool "Enable DP_BE_WAR"
+	default n
+
+config DP_CON_MON_MSI_ENABLED
+	bool "Enable DP_CON_MON_MSI_ENABLED"
+	default n
+
+config DP_CON_MON_MSI_SKIP_SET
+	bool "Enable DP_CON_MON_MSI_SKIP_SET"
+	default n
+
+config DP_FEATURE_HW_COOKIE_CONVERSION
+	bool "Enable DP_FEATURE_HW_COOKIE_CONVERSION"
+	default n
+
+config DP_HW_COOKIE_CONVERT_EXCEPTION
+	bool "Enable DP_HW_COOKIE_CONVERT_EXCEPTION"
+	default n
+
+config DP_HW_TX_DELAY_STATS_ENABLE
+	bool "Enable DP_HW_TX_DELAY_STATS_ENABLE"
+	default n
+
+config DP_INTR_POLL_BASED
+	bool "Enable DP_INTR_POLL_BASED"
+	default n
+
+config DP_LFR
+	bool "Enable DP_LFR"
+	default n
+
+config DP_MEM_PRE_ALLOC
+	bool "Enable DP_MEM_PRE_ALLOC"
+	default n
+
+config DP_PKT_ADD_TIMESTAMP
+	bool "Enable DP_PKT_ADD_TIMESTAMP"
+	default n
+
+config DP_PKT_STATS_PER_LMAC
+	bool "Enable DP_PKT_STATS_PER_LMAC"
+	default n
+
+config DP_RX_BUFFER_POOL_ALLOC_THRES
+	int "Enable DP_RX_BUFFER_POOL_ALLOC_THRES"
+
+config DP_RX_BUFFER_POOL_SIZE
+	int "Enable DP_RX_BUFFER_POOL_SIZE"
+
+config DP_RX_REFILL_BUFF_POOL_SIZE
+	int "Enable DP_RX_REFILL_BUFF_POOL_SIZE"
+
+config DP_RX_REFILL_THRD_THRESHOLD
+	int "Enable DP_RX_REFILL_THRD_THRESHOLD"
+
+config DP_RX_DROP_RAW_FRM
+	bool "Enable DP_RX_DROP_RAW_FRM"
+	default n
+
+config DP_RX_PKT_NO_PEER_DELIVER
+	bool "Enable DP_RX_PKT_NO_PEER_DELIVER"
+	default n
+
+config DP_RX_REFILL_CPU_PERF_AFFINE_MASK
+	bool "Enable DP_RX_REFILL_CPU_PERF_AFFINE_MASK"
+	default n
+
+config DP_RX_SPECIAL_FRAME_NEED
+	bool "Enable DP_RX_SPECIAL_FRAME_NEED"
+	default n
+
+config DP_TRACE
+	bool "Enable DP_TRACE"
+	default n
+
+config DP_TRAFFIC_END_INDICATION
+	bool "Enable DP_TRAFFIC_END_INDICATION"
+	default n
+
+config DP_TX_COMP_RING_DESC_SANITY_CHECK
+	bool "Enable DP_TX_COMP_RING_DESC_SANITY_CHECK"
+	default n
+
+config DP_TX_HW_DESC_HISTORY
+	bool "Enable DP_TX_HW_DESC_HISTORY"
+	default n
+
+config DP_TXRX_SOC_ATTACH
+	bool "Enable DP_TXRX_SOC_ATTACH"
+	default n
+
+config DP_USE_REDUCED_PEER_ID_FIELD_WIDTH
+	bool "Enable DP_USE_REDUCED_PEER_ID_FIELD_WIDTH"
+	default n
+
+config DP_WAR_INVALID_FIRST_MSDU_FLAG
+	bool "Enable DP_WAR_INVALID_FIRST_MSDU_FLAG"
+	default n
+
+config DSC_DEBUG
+	bool "Enable DSC_DEBUG"
+	default n
+
+config DSC_TEST
+	bool "Enable DSC_TEST"
+	default n
+
+config DUP_RX_DESC_WAR
+	bool "Enable DUP_RX_DESC_WAR"
+	default n
+
+config DYNAMIC_RX_AGGREGATION
+	bool "Enable DYNAMIC_RX_AGGREGATION"
+	default n
+
+config EMULATION_2_0
+	bool "Enable EMULATION_2_0"
+	default n
+
+config ENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST
+	bool "Enable ENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST"
+	default n
+
+config ENABLE_HAL_REG_WR_HISTORY
+	bool "Enable ENABLE_HAL_REG_WR_HISTORY"
+	default n
+
+config ENABLE_HAL_SOC_STATS
+	bool "Enable ENABLE_HAL_SOC_STATS"
+	default n
+
+config ENABLE_MTRACE_LOG
+	bool "Enable ENABLE_MTRACE_LOG"
+	default n
+
+config ENABLE_QDF_PTR_HASH_DEBUG
+	bool "Enable ENABLE_QDF_PTR_HASH_DEBUG"
+	default n
+
+config ENABLE_SMMU_S1_TRANSLATION
+	bool "Enable ENABLE_SMMU_S1_TRANSLATION"
+	default n
+
+config FEATURE_ACTIVE_TOS
+	bool "Enable FEATURE_ACTIVE_TOS"
+	default n
+
+config FEATURE_ALIGN_STATS_FROM_DP
+	bool "Enable FEATURE_ALIGN_STATS_FROM_DP"
+	default n
+
+config FEATURE_BECN_STATS
+	bool "Enable FEATURE_BECN_STATS"
+	default n
+
+config FEATURE_BSS_TRANSITION
+	bool "Enable FEATURE_BSS_TRANSITION"
+	default n
+
+config FEATURE_BUS_BANDWIDTH_MGR
+	bool "Enable FEATURE_BUS_BANDWIDTH_MGR"
+	default n
+
+config FEATURE_CLUB_LL_STATS_AND_GET_STATION
+	bool "Enable FEATURE_CLUB_LL_STATS_AND_GET_STATION"
+	default n
+
+config FEATURE_COEX
+	bool "Enable FEATURE_COEX"
+	default n
+
+config FEATURE_CONCURRENCY_MATRIX
+	bool "Enable FEATURE_CONCURRENCY_MATRIX"
+	default n
+
+config FEATURE_DELAYED_PEER_OBJ_DESTROY
+	bool "Enable FEATURE_DELAYED_PEER_OBJ_DESTROY"
+	default n
+
+config FEATURE_DENYLIST_MGR
+	bool "Enable FEATURE_DENYLIST_MGR"
+	default n
+
+config FEATURE_EPPING
+	bool "Enable FEATURE_EPPING"
+	default n
+
+config FEATURE_FORCE_WAKE
+	bool "Enable FEATURE_FORCE_WAKE"
+	default n
+
+config FEATURE_FW_LOG_PARSING
+	bool "Enable FEATURE_FW_LOG_PARSING"
+	default n
+
+config FEATURE_GPIO_CFG
+	bool "Enable FEATURE_GPIO_CFG"
+	default n
+
+config FEATURE_HAL_DELAYED_REG_WRITE
+	bool "Enable FEATURE_HAL_DELAYED_REG_WRITE"
+	default n
+
+config FEATURE_HAL_RECORD_SUSPEND_WRITE
+	bool "Enable FEATURE_HAL_RECORD_SUSPEND_WRITE"
+	default n
+
+config FEATURE_HIF_LATENCY_PROFILE_ENABLE
+	bool "Enable FEATURE_HIF_LATENCY_PROFILE_ENABLE"
+	default n
+
+config FEATURE_HTC_CREDIT_HISTORY
+	bool "Enable FEATURE_HTC_CREDIT_HISTORY"
+	default n
+
+config FEATURE_INTEROP_ISSUES_AP
+	bool "Enable FEATURE_INTEROP_ISSUES_AP"
+	default n
+
+config FEATURE_MEMDUMP_ENABLE
+	bool "Enable FEATURE_MEMDUMP_ENABLE"
+	default n
+
+config FEATURE_MONITOR_MODE_SUPPORT
+	bool "Enable FEATURE_MONITOR_MODE_SUPPORT"
+	default n
+
+config FEATURE_MSCS
+	bool "Enable FEATURE_MSCS"
+	default n
+
+config FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT
+	bool "Enable FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT"
+	default n
+
+config FEATURE_OEM_DATA
+	bool "Enable FEATURE_OEM_DATA"
+	default n
+
+config FEATURE_OTA_TEST
+	bool "Enable FEATURE_OTA_TEST"
+	default n
+
+config FEATURE_P2P_LISTEN_OFFLOAD
+	bool "Enable FEATURE_P2P_LISTEN_OFFLOAD"
+	default n
+
+config FEATURE_RADAR_HISTORY
+	bool "Enable FEATURE_RADAR_HISTORY"
+	default n
+
+config FEATURE_ROAM_DEBUG
+	bool "Enable FEATURE_ROAM_DEBUG"
+	default n
+
+config FEATURE_RSSI_MONITOR
+	bool "Enable FEATURE_RSSI_MONITOR"
+	default n
+
+config FEATURE_RX_LINKSPEED_ROAM_TRIGGER
+	bool "Enable FEATURE_RX_LINKSPEED_ROAM_TRIGGER"
+	default n
+
+config FEATURE_SAP_COND_CHAN_SWITCH
+	bool "Enable FEATURE_SAP_COND_CHAN_SWITCH"
+	default n
+
+config FEATURE_SAR_LIMITS
+	bool "Enable FEATURE_SAR_LIMITS"
+	default n
+
+config FEATURE_SET
+	bool "Enable FEATURE_SET"
+	default n
+
+config FEATURE_STATION_INFO
+	bool "Enable FEATURE_STATION_INFO"
+	default n
+
+config FEATURE_STATS_EXT
+	bool "Enable FEATURE_STATS_EXT"
+	default n
+
+config FEATURE_STATS_EXT_V2
+	bool "Enable FEATURE_STATS_EXT_V2"
+	default n
+
+config FEATURE_TSO
+	bool "Enable TCP Segmentation Offload"
+	default n
+
+config FEATURE_TSO_DEBUG
+	bool "Enable TCP Segmentation Offload with debug"
+	depends on FEATURE_TSO
+	default n
+
+config FEATURE_TSO_STATS
+	bool "Enable FEATURE_TSO_STATS"
+	default n
+
+config FEATURE_TX_POWER
+	bool "Enable FEATURE_TX_POWER"
+	default n
+
+config FEATURE_UNIT_TEST_SUSPEND
+	bool "Enable FEATURE_UNIT_TEST_SUSPEND"
+	default n
+
+config FEATURE_VDEV_OPS_WAKELOCK
+	bool "Enable FEATURE_VDEV_OPS_WAKELOCK"
+	default n
+
+config FEATURE_WLAN_D0WOW
+	bool "Enable FEATURE_WLAN_D0WOW"
+	default n
+
+config FEATURE_WLAN_LPHB
+	bool "Enable FEATURE_WLAN_LPHB"
+	default n
+
+config FEATURE_WLAN_PRE_CAC
+	bool "Enable FEATURE_WLAN_PRE_CAC"
+	default n
+
+config FEATURE_WLAN_RA_FILTERING
+	bool "Enable FEATURE_WLAN_RA_FILTERING"
+	default n
+
+config FEATURE_WLAN_SCAN_PNO
+	bool "Enable FEATURE_WLAN_SCAN_PNO"
+	default n
+
+config WALT_GET_CPU_TAKEN_SUPPORT
+	bool "enable WALT_GET_CPU_TAKEN_SUPPORT"
+	default n
+
+config FEATURE_WLAN_WAPI
+	bool "Enable FEATURE_WLAN_WAPI"
+	default n
+
+config FEATURE_WLM_STATS
+	bool "Enable FEATURE_WLM_STATS"
+	default n
+
+config FIX_TXDMA_LIMITATION
+	bool "Enable FIX_TXDMA_LIMITATION"
+	default n
+
+config FOURTH_CONNECTION
+	bool "Enable FOURTH_CONNECTION"
+	default n
+
+config FW_THERMAL_THROTTLE
+	bool "Enable FW_THERMAL_THROTTLE"
+	default n
+
+config GET_DRIVER_MODE
+	bool "Enable GET_DRIVER_MODE"
+	default n
+
+config GTK_OFFLOAD
+	bool "Enable GTK_OFFLOAD"
+	default n
+
+config HAL_DEBUG
+	bool "Enable HAL_DEBUG"
+	default n
+
+config HAL_DISABLE_NON_BA_2K_JUMP_ERROR
+	bool "Enable HAL_DISABLE_NON_BA_2K_JUMP_ERROR"
+	default n
+
+config HANDLE_BC_EAP_TX_FRM
+	bool "Enable HANDLE_BC_EAP_TX_FRM"
+	default n
+
+config HANDLE_RX_REROUTE_ERR
+	bool "Enable HANDLE_RX_REROUTE_ERR"
+	default n
+
+config HASTINGS_BT_WAR
+	bool "Enable HASTINGS_BT_WAR"
+	default n
+
+config HDD_INIT_WITH_RTNL_LOCK
+	bool "Enable HDD_INIT_WITH_RTNL_LOCK"
+	default n
+
+config HELIUMPLUS
+	bool "Enable Beeliner based descriptor structures for Helium"
+	default n
+
+config HIF_CE_DEBUG_DATA_BUF
+	bool "Enable HIF_CE_DEBUG_DATA_BUF"
+	default n
+
+config HIF_CPU_PERF_AFFINE_MASK
+	bool "Enable HIF_CPU_PERF_AFFINE_MASK"
+	default n
+
+config HIF_DEBUG
+	bool "Enable HIF_DEBUG"
+	default n
+
+config HIF_PCI
+	bool "Enable HIF_PCI"
+	default n
+
+config HIF_REG_WINDOW_SUPPORT
+	bool "Enable HIF_REG_WINDOW_SUPPORT"
+	default n
+
+config HOST_OPCLASS
+	bool "Enable HOST_OPCLASS"
+	default n
+
+config HTT_PADDR64
+	bool "Enable HTT_PADDR64"
+	default n
+
+config ICMP_DISABLE_PS
+	bool "Enable ICMP packet disable powersave feature"
+	default n
+
+config IPA_OFFLOAD
+	bool "Enable IPA_OFFLOAD"
+	default n
+
+config IPA_OPT_WIFI_DP
+	bool "Enable IPA_OPT_WIFI_DP"
+	default n
+
+config IPA_SET_RESET_TX_DB_PA
+	bool "Enable IPA_SET_RESET_TX_DB_PA"
+	default n
+
+config KIWI_HEADERS_DEF
+	bool "Enable KIWI_HEADERS_DEF"
+	default n
+
+config LEAK_DETECTION
+	bool "Enable LEAK_DETECTION"
+	default n
+
+config LFR_SUBNET_DETECTION
+	bool "Enable LFR Subnet Change Detection"
+	default n
+
+config LINUX_QCMBR
+	bool "Enable LINUX_QCMBR"
+	default n
+
+config LITTLE_ENDIAN
+	bool "Enable LITTLE_ENDIAN"
+	default n
+
+config LL_DP_SUPPORT
+	bool "Enable LL_DP_SUPPORT"
+	default n
+
+config LOCK_STATS_ON
+	bool "Enable LOCK_STATS_ON"
+	default n
+
+config LTE_COEX
+	bool "Enable LTE_COEX"
+	default n
+
+config MARK_ICMP_REQ_TO_FW
+	bool "Enable MARK_ICMP_REQ_TO_FW"
+	default n
+
+config MAX_ALLOC_PAGE_SIZE
+	bool "Enable MAX_ALLOC_PAGE_SIZE"
+	default n
+
+config ENABLE_MAX_LOGS_PER_SEC
+	bool "Enable ENABLE_MAX_LOGS_PER_SEC"
+	default n
+
+config MAX_LOGS_PER_SEC
+	int "Enable MAX_LOGS_PER_SEC"
+
+config MCC_TO_SCC_SWITCH
+	bool "Enable MCC to SCC Switch Logic"
+	default n
+
+config MON_ENABLE_DROP_FOR_MAC
+	bool "Enable MON_ENABLE_DROP_FOR_MAC"
+	default n
+
+config MON_ENABLE_DROP_FOR_NON_MON_PMAC
+	bool "Enable MON_ENABLE_DROP_FOR_NON_MON_PMAC"
+	default n
+
+config MORE_TX_DESC
+	bool "Enable MORE_TX_DESC"
+	default n
+
+config MULTI_CLIENT_LL_SUPPORT
+	bool "Enable MULTI_CLIENT_LL_SUPPORT"
+	default n
+
+config NAN_CONVERGENCE
+	bool "Enable NAN_CONVERGENCE feature"
+	default n
+
+config NO_RX_PKT_HDR_TLV
+	bool "Enable NO_RX_PKT_HDR_TLV"
+	default n
+
+config OBSS_PD
+	bool "Enable OBSS_PD"
+	default n
+
+config OFDM_SCRAMBLER_SEED
+	bool "Enable OFDM_SCRAMBLER_SEED"
+	default n
+
+config PCI_LINK_STATUS_SANITY
+	bool "Enable PCI_LINK_STATUS_SANITY"
+	default n
+
+config PCIE_GEN_SWITCH
+	bool "Enable PCIE_GEN_SWITCH"
+	default n
+
+config PEER_PROTECTED_ACCESS
+	bool "Enable PEER_PROTECTED_ACCESS"
+	default n
+
+config PKTLOG_HAS_SPECIFIC_DATA
+	bool "Enable PKTLOG_HAS_SPECIFIC_DATA"
+	default n
+
+config PLD_PCIE_CNSS_FLAG
+	bool "Enable PLD_PCIE_CNSS_FLAG"
+	default n
+
+config PLD_PCIE_INIT_FLAG
+	bool "Enable PLD_PCIE_INIT_FLAG"
+	default n
+
+config POWER_MANAGEMENT_OFFLOAD
+	bool "Enable POWER_MANAGEMENT_OFFLOAD"
+	default n
+
+config PRIMA_WLAN_OKC
+	bool "Enable the Prima WLAN Opportunistic Key Caching feature"
+	default n
+
+config PTT_SOCK_SVC_ENABLE
+	bool "Enable PTT_SOCK_SVC_ENABLE"
+	default n
+
+config QCA_DFS_BW_PUNCTURE
+	bool "Enable QCA_DFS_BW_PUNCTURE"
+	default n
+
+config QCA_DMA_PADDR_CHECK
+	bool "Enable dma memory addr check"
+
+config QCA_GET_TSF_VIA_REG
+	bool "Enable QCA_GET_TSF_VIA_REG"
+	default n
+
+config QCA_MONITOR_PKT_SUPPORT
+	bool "Enable QCA_MONITOR_PKT_SUPPORT"
+	default n
+
+config QCA_SUPPORT_TX_MIN_RATES_FOR_SPECIAL_FRAMES
+	bool "Enable QCA_SUPPORT_TX_MIN_RATES_FOR_SPECIAL_FRAMES"
+	default n
+
+config QCA_SUPPORT_TX_THROTTLE
+	bool "Enable QCA_SUPPORT_TX_THROTTLE"
+	default n
+
+config QCA_WIFI_FTM
+	bool "Enable QCA_WIFI_FTM"
+	default n
+
+config QCA_WIFI_FTM_NL80211
+	bool "Enable QCA_WIFI_FTM_NL80211"
+	depends on NL80211_TESTMODE
+	default n
+
+config QCA_WIFI_KIWI
+	bool "Enable QCA_WIFI_KIWI"
+	default n
+
+config QCA_WIFI_MONITOR_MODE_NO_MSDU_START_TLV_SUPPORT
+	bool "Enable QCA_WIFI_MONITOR_MODE_NO_MSDU_START_TLV_SUPPORT"
+	default n
+
+config QCA_WIFI_QCA8074
+	bool "Enable QCA_WIFI_QCA8074"
+	default n
+
+config QCA_WIFI_QCA8074_VP
+	bool "Enable QCA_WIFI_QCA8074_VP"
+	default n
+
+config QCACLD_FEATURE_APF
+	bool "Enable QCACLD_FEATURE_APF"
+	default n
+
+config QCACLD_FEATURE_FW_STATE
+	bool "Enable QCACLD_FEATURE_FW_STATE"
+	default n
+
+config QCACLD_FEATURE_GAP_LL_PS_MODE
+	bool "Enable QCACLD_FEATURE_GAP_LL_PS_MODE"
+	default n
+
+config QCACLD_FEATURE_GREEN_AP
+	bool "Enable Green AP feature"
+	default n
+
+config QCACLD_FEATURE_NAN
+	bool "Enable NAN feature"
+	default n
+
+config QCACLD_RX_DESC_MULTI_PAGE_ALLOC
+	bool "Enable QCACLD_RX_DESC_MULTI_PAGE_ALLOC"
+	default n
+
+config QCACLD_WLAN_CONNECTIVITY_DIAG_EVENT
+	bool "Enable QCACLD_WLAN_CONNECTIVITY_DIAG_EVENT"
+	default n
+
+config QCACLD_WLAN_LFR2
+	bool "Enable the WLAN Legacy Fast Roaming feature Version 2"
+	default n
+
+config QCACLD_WLAN_LFR3
+	bool "Enable the WLAN Legacy Fast Roaming feature Version 3"
+	default n
+
+config QCOM_ESE
+	bool "Enable QCOM_ESE"
+	default n
+
+config QCOM_LTE_COEX
+	bool "Enable QCOM LTE Coex feature"
+	default n
+
+config QCOM_TDLS
+	bool "Enable TDLS feature"
+	default n
+
+config QCOM_VOWIFI_11R
+	bool "Enable Fast Transition (11r) feature"
+	default n
+
+config QDF_NBUF_HISTORY_SIZE
+	int "Enable QDF_NBUF_HISTORY_SIZE"
+
+config QDF_TEST
+	bool "Enable QDF_TEST"
+	default n
+
+config QMI_SUPPORT
+	bool "Enable QMI_SUPPORT"
+	default n
+
+config REG_CLIENT
+	bool "Enable REG_CLIENT"
+	default n
+
+config REGISTER_OP_DEBUG
+	bool "Enable REGISTER_OP_DEBUG"
+	default n
+
+config REMOVE_PKT_LOG
+	bool "Enable REMOVE_PKT_LOG"
+	default n
+
+config REO_DESC_DEFER_FREE
+	bool "Enable REO_DESC_DEFER_FREE"
+	default n
+
+config REO_QDESC_HISTORY
+	bool "Enable REO_QDESC_HISTORY"
+	default n
+
+config RPS
+	bool "enable CONFIG_QCA_CONFIG_RPS"
+	default n
+
+config RX_DEFRAG_DO_NOT_REINJECT
+	bool "Enable RX_DEFRAG_DO_NOT_REINJECT"
+	default n
+
+config RX_DESC_DEBUG_CHECK
+	bool "Enable RX_DESC_DEBUG_CHECK"
+	default n
+
+config RX_DESC_SANITY_WAR
+	bool "Enable RX_DESC_SANITY_WAR"
+	default n
+
+config RX_FISA
+	bool "Enable RX_FISA"
+	default n
+
+config RX_HASH_DEBUG
+	bool "Enable RX_HASH_DEBUG"
+	default n
+
+config RX_OL
+	bool "Enable RX_OL"
+	default n
+
+config RXDMA_ERR_PKT_DROP
+	bool "Enable RXDMA_ERR_PKT_DROP"
+	default n
+
+config SAE_SINGLE_PMK
+	bool "Enable SAE_SINGLE_PMK"
+	default n
+
+config SAP_AVOID_ACS_FREQ_LIST
+	bool "Enable SAP_AVOID_ACS_FREQ_LIST"
+	default n
+
+config SAP_DHCP_FW_IND
+	bool "Enable SAP_DHCP_FW_IND"
+	default n
+
+config SAR_SAFETY_FEATURE
+	bool "Enable SAR_SAFETY_FEATURE"
+	default n
+
+config SCALE_INCLUDES
+	bool "Enable SCALE_INCLUDES"
+	default n
+
+config ENABLE_SCHED_HISTORY_SIZE
+	bool "Enable ENABLE_SCHED_HISTORY_SIZE"
+	default n
+
+config SCHED_HISTORY_SIZE
+	int "Enable SCHED_HISTORY_SIZE"
+
+config SERIALIZE_QUEUE_SETUP
+	bool "Enable SERIALIZE_QUEUE_SETUP"
+	default n
+
+config SHADOW_V3
+	bool "Enable SHADOW_V3"
+	default n
+
+config SMMU_S1_UNMAP
+	bool "Enable SMMU_S1_UNMAP"
+	default n
+
+config SMP
+	bool "enable CONFIG_SMP"
+	default n
+
+config SOFTAP_CHANNEL_RANGE
+	bool "Enable SOFTAP_CHANNEL_RANGE"
+	default n
+
+config SUPPORT_11AX
+	bool "Enable SUPPORT_11AX"
+	default n
+
+config SYSTEM_PM_CHECK
+	bool "Enable SYSTEM_PM_CHECK"
+	default n
+
+config TALLOC_DEBUG
+	bool "Enable TALLOC_DEBUG"
+	default n
+
+config TARGET_11D_SCAN
+	bool "Enable TARGET_11D_SCAN"
+	default n
+
+config TARGET_RAMDUMP_AFTER_KERNEL_PANIC
+	bool "Enable TARGET_RAMDUMP_AFTER_KERNEL_PANIC"
+	default n
+
+config THERMAL_STATS_SUPPORT
+	bool "Enable THERMAL_STATS_SUPPORT"
+	default n
+
+config TRACE_RECORD_FEATURE
+	bool "Enable TRACE_RECORD_FEATURE"
+	default n
+
+config TSO_DEBUG_LOG_ENABLE
+	bool "Enable TSO_DEBUG_LOG_ENABLE"
+	default n
+
+config TX_ADDR_INDEX_SEARCH
+	bool "Enable TX_ADDR_INDEX_SEARCH"
+	default n
+
+config TX_MULTI_TCL
+	bool "Enable TX_MULTI_TCL"
+	default n
+
+config TX_MULTIQ_PER_AC
+	bool "Enable TX_MULTIQ_PER_AC"
+	default n
+
+config TX_PER_PDEV_DESC_POOL
+	bool "Enable TX_PER_PDEV_DESC_POOL"
+	default n
+
+config TX_TID_OVERRIDE
+	bool "Enable TX_TID_OVERRIDE"
+	default n
+
+config UNIT_TEST
+	bool "Enable UNIT_TEST"
+	default n
+
+config VERBOSE_DEBUG
+	bool "Enable VERBOSE_DEBUG"
+	default n
+
+config WAPI_BIG_ENDIAN
+	bool "Enable WAPI_BIG_ENDIAN"
+	default n
+
+config WCNSS_MEM_PRE_ALLOC_MODULE
+	bool "Enable WCNSS_MEM_PRE_ALLOC_MODULE"
+	default n
+
+config WCNSS_MEM_PRE_ALLOC
+	tristate "Enable WCNSS_MEM_PRE_ALLOC"
+	default n
+
+config WDI_EVENT_ENABLE
+	bool "Enable WDI_EVENT_ENABLE"
+	default n
+
+config WDI3_IPA_OVER_GSI
+	bool "Enable WDI3_IPA_OVER_GSI"
+	default n
+
+config WIFI_MONITOR_SUPPORT
+	bool "Enable WIFI_MONITOR_SUPPORT"
+	default n
+
+config WIFI_POS_CONVERGED
+	bool "Enable WIFI_POS_CONVERGED"
+	default n
+
+config WIFI_POS_PASN
+	bool "Enable WIFI_POS_PASN"
+	default n
+
+config WINDOW_REG_PLD_LOCK_ENABLE
+	bool "Enable WINDOW_REG_PLD_LOCK_ENABLE"
+	default n
+
+config WLAN_BCN_RECV_FEATURE
+	bool "Enable WLAN_BCN_RECV_FEATURE"
+	default n
+
+config WLAN_BMISS
+	bool "Enable WLAN_BMISS"
+	default n
+
+config WLAN_CE_INTERRUPT_THRESHOLD_CONFIG
+	bool "Enable WLAN_CE_INTERRUPT_THRESHOLD_CONFIG"
+	default n
+
+config WLAN_CFR_ENABLE
+	bool "Enable WLAN_CFR_ENABLE"
+	default n
+
+config WLAN_CLD_DEV_PM_QOS
+	bool "Enable WLAN_CLD_DEV_PM_QOS"
+	default n
+
+config WLAN_CLD_PM_QOS
+	bool "Enable WLAN_CLD_PM_QOS"
+	default n
+
+config WLAN_CONV_SPECTRAL_ENABLE
+	bool "Enable WLAN_CONV_SPECTRAL_ENABLE"
+	default n
+
+config WLAN_CUSTOM_DSCP_UP_MAP
+	bool "Enable WLAN_CUSTOM_DSCP_UP_MAP"
+	default n
+
+config WLAN_DEBUG_CRASH_INJECT
+	bool "Enable WLAN_DEBUG_CRASH_INJECT"
+	default n
+
+config WLAN_DEBUG_LINK_VOTE
+	bool "Enable WLAN_DEBUG_LINK_VOTE"
+	default n
+
+config WLAN_DEBUG_VERSION
+	bool "Enable WLAN_DEBUG_VERSION"
+	default n
+
+config WLAN_DEBUGFS
+	bool "Enable WLAN_DEBUGFS"
+	depends on DEBUG_FS
+	default n
+
+config WLAN_DFS_MASTER_ENABLE
+	bool "Enable WLAN_DFS_MASTER_ENABLE"
+	default n
+
+config WLAN_DFS_STATIC_MEM_ALLOC
+	bool "Enable WLAN_DFS_STATIC_MEM_ALLOC"
+	default n
+
+config WLAN_DIAG_VERSION
+	bool "Enable WLAN_DIAG_VERSION"
+	default n
+
+config WLAN_DISABLE_EXPORT_SYMBOL
+	bool "Enable WLAN_DISABLE_EXPORT_SYMBOL"
+	default n
+
+config WLAN_MULTI_CHIP_SUPPORT
+	bool "Enable WLAN_MULTI_CHIP_SUPPORT"
+	select WLAN_DISABLE_EXPORT_SYMBOL
+	default n
+
+config WLAN_DL_MODES
+	bool "Enable WLAN_DL_MODES"
+	default n
+
+config WLAN_DP_DISABLE_TCL_CMD_CRED_SRNG
+	bool "Enable WLAN_DP_DISABLE_TCL_CMD_CRED_SRNG"
+	default n
+
+config WLAN_DP_DISABLE_TCL_STATUS_SRNG
+	bool "Enable WLAN_DP_DISABLE_TCL_STATUS_SRNG"
+	default n
+
+config WLAN_DP_PENDING_MEM_FLUSH
+	bool "Enable WLAN_DP_PENDING_MEM_FLUSH"
+	default n
+
+config WLAN_DP_PER_RING_TYPE_CONFIG
+	bool "Enable WLAN_DP_PER_RING_TYPE_CONFIG"
+	default n
+
+config WLAN_DP_SRNG_USAGE_WM_TRACKING
+	bool "Enable WLAN_DP_SRNG_USAGE_WM_TRACKING"
+	default n
+
+config WLAN_DYNAMIC_CVM
+	bool "Enable WLAN_DYNAMIC_CVM"
+	default n
+
+config WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
+	bool "Enable WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY"
+	default n
+
+config WLAN_ENH_CFR_ENABLE
+	bool "Enable WLAN_ENH_CFR_ENABLE"
+	default n
+
+config WLAN_FASTPATH
+	bool "Enable fastpath for datapackets"
+	default n
+
+config WLAN_FEATURE_11AX
+	bool "Enable 11AX(High Efficiency) feature"
+	default n
+
+config WLAN_FEATURE_11BE
+	bool "Enable WLAN_FEATURE_11BE"
+	default n
+
+config WLAN_FEATURE_11BE_MLO
+	bool "Enable WLAN_FEATURE_11BE_MLO"
+	default n
+
+config WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
+	bool "Enable WLAN_HDD_MULTI_VDEV_SINGLE_NDEV"
+	default n
+
+config WLAN_FEATURE_11W
+	bool "Enable the WLAN 802.11w Protected Management Frames feature"
+	default n
+
+config WLAN_FEATURE_ACTION_OUI
+	bool "Enable WLAN_FEATURE_ACTION_OUI"
+	default n
+
+config WLAN_FEATURE_BIG_DATA_STATS
+	bool "Enable WLAN_FEATURE_BIG_DATA_STATS"
+	default n
+
+config WLAN_FEATURE_CAL_FAILURE_TRIGGER
+	bool "Enable WLAN_FEATURE_CAL_FAILURE_TRIGGER"
+	default n
+
+config WLAN_FEATURE_COAP
+	bool "Enable WLAN_FEATURE_COAP"
+	default n
+
+config WLAN_FEATURE_COEX_DBAM
+	bool "Enable WLAN_FEATURE_COEX_DBAM"
+	default n
+
+config WLAN_FEATURE_DFS_OFFLOAD
+	bool "Enable dfs offload feature"
+	default n
+
+config WLAN_FEATURE_DISA
+	bool "Enable DISA certification feature"
+	default n
+
+config WLAN_FEATURE_DP_BUS_BANDWIDTH
+	bool "Enable WLAN_FEATURE_DP_BUS_BANDWIDTH"
+	default n
+
+config WLAN_FEATURE_DP_CFG_EVENT_HISTORY
+	bool "Enable WLAN_FEATURE_DP_CFG_EVENT_HISTORY"
+	default n
+
+config WLAN_FEATURE_DP_EVENT_HISTORY
+	bool "Enable WLAN_FEATURE_DP_EVENT_HISTORY"
+	default n
+
+config WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY
+	bool "Enable WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY"
+	default n
+
+config WLAN_FEATURE_DP_RX_RING_HISTORY
+	bool "Enable WLAN_FEATURE_DP_RX_RING_HISTORY"
+	default n
+
+config WLAN_FEATURE_DP_RX_THREADS
+	bool "Enable WLAN_FEATURE_DP_RX_THREADS"
+	default n
+
+config WLAN_FEATURE_DP_TX_DESC_HISTORY
+	bool "Enable WLAN_FEATURE_DP_TX_DESC_HISTORY"
+	default n
+
+config WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
+	bool "Enable WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE"
+	default n
+
+config WLAN_FEATURE_ELNA
+	bool "Enable WLAN_FEATURE_ELNA"
+	default n
+
+config WLAN_FEATURE_FILS
+	bool "Enable FILS feature"
+	default n
+
+config WLAN_FEATURE_FIPS
+	bool "Enable FIPS certification feature"
+	default n
+
+config WLAN_FEATURE_LL_LT_SAP
+	bool "Enable Low latency low throughput SAP feature"
+	default n
+
+config WLAN_FEATURE_GET_USABLE_CHAN_LIST
+	bool "Enable WLAN_FEATURE_GET_USABLE_CHAN_LIST"
+	default n
+
+config WLAN_FEATURE_ICMP_OFFLOAD
+	bool "Enable WLAN_FEATURE_ICMP_OFFLOAD"
+	default n
+
+config WLAN_FEATURE_IGMP_OFFLOAD
+	bool "Enable WLAN_FEATURE_IGMP_OFFLOAD"
+	default n
+
+config WLAN_FEATURE_LINK_LAYER_STATS
+	bool "Enable WLAN_FEATURE_LINK_LAYER_STATS"
+	default n
+
+config WLAN_FEATURE_LPSS
+	bool "Enable the WLAN LPSS feature"
+	default n
+
+config WLAN_FEATURE_LRO_CTX_IN_CB
+	bool "Enable WLAN_FEATURE_LRO_CTX_IN_CB"
+	default n
+
+config WLAN_FEATURE_MBSSID
+	bool "Enable WLAN_FEATURE_MBSSID"
+	default n
+
+config WLAN_FEATURE_MCC_QUOTA
+	bool "Enable WLAN_FEATURE_MCC_QUOTA"
+	default n
+
+config WLAN_FEATURE_MDNS_OFFLOAD
+	bool "Enable WLAN_FEATURE_MDNS_OFFLOAD"
+	default n
+
+config WLAN_FEATURE_MEDIUM_ASSESS
+	bool "Enable WLAN_FEATURE_MEDIUM_ASSESS"
+	default n
+
+config WLAN_FEATURE_MIB_STATS
+	bool "Enable WLAN_FEATURE_MIB_STATS"
+	depends on WLAN_DEBUGFS
+	default n
+
+config WLAN_FEATURE_NEAR_FULL_IRQ
+	bool "Enable WLAN_FEATURE_NEAR_FULL_IRQ"
+	default n
+
+config WLAN_FEATURE_P2P_DEBUG
+	bool "Enable WLAN_FEATURE_P2P_DEBUG"
+	default n
+
+config WLAN_FEATURE_P2P_P2P_STA
+	bool "Enable WLAN_FEATURE_P2P_P2P_STA"
+	default n
+
+config WLAN_FEATURE_PACKET_FILTERING
+	bool "Enable WLAN_FEATURE_PACKET_FILTERING"
+	default n
+
+config WLAN_FEATURE_PEER_TXQ_FLUSH_CONF
+	bool "Enable WLAN_FEATURE_PEER_TXQ_FLUSH_CONF"
+	default n
+
+config WLAN_FEATURE_ROAM_INFO_STATS
+	bool "Enable WLAN_FEATURE_ROAM_INFO_STATS"
+	default n
+
+config WLAN_FEATURE_RX_BUFFER_POOL
+	bool "Enable WLAN_FEATURE_RX_BUFFER_POOL"
+	default n
+
+config WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
+	bool "Enable WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT"
+	default n
+
+config WLAN_FEATURE_SAE
+	bool "Enable WLAN_FEATURE_SAE"
+	default n
+
+config WLAN_FEATURE_SAP_ACS_OPTIMIZE
+	bool "Enable WLAN_FEATURE_SAP_ACS_OPTIMIZE"
+	default n
+
+config FEATURE_WLAN_GC_SKIP_JOIN
+	bool "enable CONFIG_FEATURE_WLAN_GC_SKIP_JOIN"
+	default n
+
+config WLAN_FEATURE_SARV1_TO_SARV2
+	bool "Enable conversion of SAR v1 to v2 feature"
+	default n
+
+config WLAN_FEATURE_SR
+	bool "Enable WLAN_FEATURE_SR"
+	default n
+
+config WLAN_FEATURE_TWT
+	bool "Enable WLAN_FEATURE_TWT"
+	default n
+
+config WLAN_FEATURE_WMI_DIAG_OVER_CE7
+	bool "Enable WLAN_FEATURE_WMI_DIAG_OVER_CE7"
+	default n
+
+config WLAN_FREQ_LIST
+	bool "Enable WLAN_FREQ_LIST"
+	default n
+
+config WLAN_FW_OFFLOAD
+	bool "Enable WLAN_FW_OFFLOAD"
+	default n
+
+config WLAN_GTX_BW_MASK
+	bool "Enable WLAN_GTX_BW_MASK"
+	default n
+
+config WLAN_HANG_EVENT
+	bool "Enable WLAN_HANG_EVENT"
+	default n
+
+config WLAN_LOG_DEBUG
+	bool "Enable WLAN_LOG_DEBUG"
+	default n
+
+config WLAN_LOG_ENTER
+	bool "Enable WLAN_LOG_ENTER"
+	default n
+
+config WLAN_LOG_ERROR
+	bool "Enable WLAN_LOG_ERROR"
+	default n
+
+config WLAN_LOG_EXIT
+	bool "Enable WLAN_LOG_EXIT"
+	default n
+
+config WLAN_LOG_FATAL
+	bool "Enable WLAN_LOG_FATAL"
+	default n
+
+config WLAN_LOG_INFO
+	bool "Enable WLAN_LOG_INFO"
+	default n
+
+config WLAN_LOG_WARN
+	bool "Enable WLAN_LOG_WARN"
+	default n
+
+config WLAN_LOGGING_SOCK_SVC
+	bool "Enable WLAN_LOGGING_SOCK_SVC"
+	default n
+
+config WLAN_LRO
+	bool "Enable Large Receive Offload"
+	depends on HELIUMPLUS
+	depends on INET_LRO
+	default n
+
+config WLAN_MWS_INFO_DEBUGFS
+	bool "Enable WLAN_MWS_INFO_DEBUGFS"
+	depends on WLAN_DEBUGFS
+	default n
+
+config WLAN_NAPI
+	bool "Enable NAPI - datapath rx"
+	default n
+
+config WLAN_NAPI_DEBUG
+	bool "Enable debug logging on NAPI"
+	depends on WLAN_NAPI
+	default n
+
+config WLAN_NS_OFFLOAD
+	bool "Enable WLAN_NS_OFFLOAD"
+	default n
+
+config WLAN_NUD_TRACKING
+	bool "Enable WLAN_NUD_TRACKING"
+	default n
+
+config WLAN_OBJMGR_DEBUG
+	bool "Enable WLAN Obj Mgr Debug services"
+	default n
+
+config WLAN_OBJMGR_REF_ID_TRACE
+	bool "Enable WLAN_OBJMGR_REF_ID_TRACE"
+	default n
+
+config WLAN_OFFLOAD_PACKETS
+	bool "Enable offload packets feature"
+	default n
+
+config WLAN_OPEN_P2P_INTERFACE
+	bool "Enable WLAN_OPEN_P2P_INTERFACE"
+	default n
+
+config WLAN_PDEV_VDEV_SEND_MULTI_PARAM
+	bool "Enable WLAN_PDEV_VDEV_SEND_MULTI_PARAM"
+	default n
+
+config WLAN_PMO_ENABLE
+	bool "Enable WLAN_PMO_ENABLE"
+	default n
+
+config WLAN_POLICY_MGR_ENABLE
+	bool "Enable WLAN_POLICY_MGR_ENABLE"
+	default n
+
+config WLAN_POWER_DEBUG
+	bool "Enable WLAN_POWER_DEBUG"
+	default n
+
+config WLAN_REASSOC
+	bool "Enable WLAN_REASSOC"
+	default n
+
+config WLAN_RECORD_RX_PADDR
+	bool "Enable WLAN_RECORD_RX_PADDR"
+	default n
+
+config WLAN_RX_MON_PARSE_CMN_USER_INFO
+	bool "Enable WLAN_RX_MON_PARSE_CMN_USER_INFO"
+	default n
+
+config WLAN_SCAN_DISABLE
+	bool "Enable WLAN_SCAN_DISABLE"
+	default n
+
+config WLAN_SKIP_BAR_UPDATE
+	bool "Enable WLAN_SKIP_BAR_UPDATE"
+	default n
+
+config WLAN_SPECTRAL_ENABLE
+	bool "Enable WLAN_SPECTRAL_ENABLE"
+	default n
+
+config WLAN_STREAMFS
+	bool "Enable WLAN_STREAMFS"
+	depends on RELAY
+	default n
+
+config WLAN_SUPPORT_DATA_STALL
+	bool "Enable WLAN_SUPPORT_DATA_STALL"
+	default n
+
+config WLAN_SYNC_TSF
+	bool "Enable QCOM sync multi devices tsf feature"
+	default n
+
+config WLAN_SYNC_TSF_PLUS
+	bool "Enable WLAN_SYNC_TSF_PLUS"
+	default n
+
+config WLAN_SYNC_TSF_TIMER
+	bool "Enable WLAN_SYNC_TSF_TIMER"
+	default n
+
+config WLAN_SYSFS
+	bool "Enable WLAN_SYSFS"
+	depends on SYSFS
+	default n
+
+config WLAN_SYSFS_CHANNEL
+	bool "Enable WLAN_SYSFS_CHANNEL"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_CONNECT_INFO
+	bool "Enable WLAN_SYSFS_CONNECT_INFO"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_DCM
+	bool "Enable WLAN_SYSFS_DCM"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_DFSNOL
+	bool "Enable WLAN_SYSFS_DFSNOL"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_DP_STATS
+	bool "Enable WLAN_SYSFS_DP_STATS"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_DP_TRACE
+	bool "Enable WLAN_SYSFS_DP_TRACE"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_EHT_RATE
+	bool "Enable WLAN_SYSFS_EHT_RATE"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_FW_MODE_CFG
+	bool "Enable WLAN_SYSFS_FW_MODE_CFG"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_HE_BSS_COLOR
+	bool "Enable WLAN_SYSFS_HE_BSS_COLOR"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_LOG_BUFFER
+	bool "Enable WLAN_SYSFS_LOG_BUFFER"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_MEM_STATS
+	bool "Enable WLAN_SYSFS_MEM_STATS"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_MONITOR_MODE_CHANNEL
+	bool "Enable WLAN_SYSFS_MONITOR_MODE_CHANNEL"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_RADAR
+	bool "Enable WLAN_SYSFS_RADAR"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_RANGE_EXT
+	bool "Enable WLAN_SYSFS_RANGE_EXT"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_RTS_CTS
+	bool "Enable WLAN_SYSFS_RTS_CTS"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_SCAN_CFG
+	bool "Enable WLAN_SYSFS_SCAN_CFG"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_STA_INFO
+	bool "Enable WLAN_SYSFS_STA_INFO"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_STATS
+	bool "Enable WLAN_SYSFS_STATS"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_TDLS_PEERS
+	bool "Enable WLAN_SYSFS_TDLS_PEERS"
+	depends on WLAN_SYSFS
+	depends on QCOM_TDLS
+	default n
+
+config WLAN_SYSFS_TEMPERATURE
+	bool "Enable WLAN_SYSFS_TEMPERATURE"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_TX_STBC
+	bool "Enable WLAN_SYSFS_TX_STBC"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_WLAN_DBG
+	bool "Enable WLAN_SYSFS_WLAN_DBG"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_SYSFS_BITRATES
+	bool "enable WLAN_SYSFS_BITRATES"
+	depends on WLAN_SYSFS
+	default n
+
+config WLAN_THERMAL_CFG
+	bool "Enable WLAN_THERMAL_CFG"
+	default n
+
+config WLAN_THERMAL_MULTI_CLIENT_SUPPORT
+	bool "Enable WLAN_THERMAL_MULTI_CLIENT_SUPPORT"
+	default n
+
+config WLAN_TRACEPOINTS
+	bool "Enable WLAN_TRACEPOINTS"
+	default n
+
+config WLAN_TSF_AUTO_REPORT
+	bool "Enable WLAN_TSF_AUTO_REPORT"
+	default n
+
+config WLAN_TSF_UPLINK_DELAY
+	bool "Enable WLAN_TSF_UPLINK_DELAY"
+	depends on WLAN_TSF_AUTO_REPORT
+	default n
+
+config WLAN_TX_LATENCY_STATS
+	bool "Enable WLAN_TX_LATENCY_STATS"
+	depends on WLAN_TSF_AUTO_REPORT
+	default n
+
+config WLAN_TWT_CONVERGED
+	bool "Enable WLAN_TWT_CONVERGED"
+	default n
+
+config WLAN_TWT_SAP_PDEV_COUNT
+	bool "Enable WLAN_TWT_SAP_PDEV_COUNT"
+	default n
+
+config WLAN_TWT_SAP_STA_COUNT
+	bool "Enable WLAN_TWT_SAP_STA_COUNT"
+	default n
+
+config WLAN_TX_FLOW_CONTROL_V2
+	bool "Enable tx flow control version:2"
+	default n
+
+config WLAN_TXRX_FW_ST_RST
+	bool "Enable WLAN_TXRX_FW_ST_RST"
+	default n
+
+config WLAN_TXRX_FW_STATS
+	bool "Enable WLAN_TXRX_FW_STATS"
+	default n
+
+config WLAN_TXRX_STATS
+	bool "Enable WLAN_TXRX_STATS"
+	default n
+
+config WLAN_UMAC_MLO_MAX_DEV
+	int "Enable WLAN_UMAC_MLO_MAX_DEV"
+
+config WLAN_VENDOR_HANDOFF_CONTROL
+	bool "Enable WLAN_VENDOR_HANDOFF_CONTROL"
+	default n
+
+config WLAN_WBUFF
+	bool "Enable WLAN_WBUFF"
+	default n
+
+config WLAN_WEXT_SUPPORT_ENABLE
+	bool "Enable WLAN_WEXT_SUPPORT_ENABLE"
+	default n
+
+config WLAN_WOW_ITO
+	bool "Enable WLAN_WOW_ITO"
+	default n
+
+config WLAN_WOWL_ADD_PTRN
+	bool "Enable WLAN_WOWL_ADD_PTRN"
+	default n
+
+config WLAN_WOWL_DEL_PTRN
+	bool "Enable WLAN_WOWL_DEL_PTRN"
+	default n
+
+config WMI_BCN_OFFLOAD
+	bool "Enable WMI_BCN_OFFLOAD"
+	default n
+
+config WMI_CMD_STRINGS
+	bool "Enable WMI_CMD_STRINGS"
+	default n
+
+config WMI_CONCURRENCY_SUPPORT
+	bool "Enable WMI_CONCURRENCY_SUPPORT"
+	default n
+
+config WMI_DBR_SUPPORT
+	bool "Enable WMI_DBR_SUPPORT"
+	default n
+
+config WMI_INTERFACE_EVENT_LOGGING
+	bool "Enable WMI_INTERFACE_EVENT_LOGGING"
+	default n
+
+config WMI_ROAM_SUPPORT
+	bool "Enable WMI_ROAM_SUPPORT"
+	default n
+
+config WMI_SEND_RECV_QMI
+	bool "Enable WMI_SEND_RECV_QMI"
+	default n
+
+config WMI_STA_SUPPORT
+	bool "Enable WMI_STA_SUPPORT"
+	default n
+
+config PADDR_CHECK_ON_3RD_PARTY_PLATFORM
+	bool "Enable data path memory addr check on third-party platforms"
+	default n
+
+config CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT
+	bool "Enable CONFIG_CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT"
+	default n
+
+config CFG80211_RU_PUNCT_NOTIFY
+	bool "Enable CFG80211_RU_PUNCT_NOTIFY"
+	default n
+
+config CFG80211_EXTERNAL_AUTH_MLO_SUPPORT
+	bool "Enable CFG80211_EXTERNAL_AUTH_MLO_SUPPORT"
+	default n
+
+config CFG80211_MLO_KEY_OPERATION_SUPPORT
+	bool "Enable CFG80211_MLO_KEY_OPERATION_SUPPORT"
+	default n
+
+config CFG80211_WEXT
+	bool "Enable CFG80211_WEXT"
+	default n
+
+config FEATURE_PKTLOG
+	bool "Enable CONFIG_FEATURE_PKTLOG"
+	default n
+
+config FEATURE_PKTLOG_EN_NON_LEGACY
+	bool "Enable FEATURE_PKTLOG_EN_NON_LEGACY"
+	default n
+
+config WLAN_CTRL_NAME
+	string "Enable CONFIG_WLAN_CTRL_NAME"
+	default \"wlan\"
+
+config LL_DP_SUPPORT_NON_LITH
+	bool "ENABLE CONFIG_LL_DP_SUPPORT_NON_LITH"
+	default n
+
+config QCA_SUPPORT_TX_THROTTLE_NON_LITH
+	bool "Enable CONFIG_QCA_SUPPORT_TX_THROTTLE_NON_LITH"
+	default n
+
+config PANIC_ON_BUG
+	bool "Enable PANIC_ON_BUG"
+	default n
+
+config CFG80211_LINK_STA_PARAMS_PRESENT
+	bool "Enable CONFIG_CFG80211_LINK_STA_PARAMS_PRESENT"
+	default n
+
+config ARCH_MSM
+	bool "Enable CONFIG_ARCH_MSM"
+	default n
+
+config WLAN_HOST_ARCH_ARM
+	bool "Enable if host arch is arm"
+	default n
+
+config WLAN_WARN_ON_ASSERT
+	bool "Enable WLAN_WARN_ON_ASSERT"
+	default n
+
+config WIFI_MONITOR_SUPPORT_2_0
+	bool "Enable WIFI MONITOR SUPPORT 2_0"
+	default n
+
+config WLAN_TX_MON_2_0_Y_WLAN_DP_LOCAL_PKT_CAPTURE
+	bool "Enable WLAN_TX_MON_2_0_Y_DP_LOCAL_PKT_CAPTURE"
+	default n
+
+config WIFI_MONITOR_SUPPORT_Y_WLAN_TX_MON_2_0
+	bool "Enable WIFI_MONITOR_SUPPORT_Y_WLAN_TX_MON_2_0"
+	default n
+
+config WLAN_DP_LOCAL_PKT_CAPTURE
+	bool "Enable CONFIG_WLAN_DP_LOCAL_PKT_CAPTURE"
+	default n
+
+config DP_TX_PACKET_INSPECT_FOR_ILP
+	bool "enable DP_TX_PACKET_INSPECT_FOR_ILP"
+	default n
+
+config NUM_SOC_PERF_CLUSTER
+	int "enable NUM_SOC_PERF_CLUSTER"
+	default 0
+
+config WLAN_OPEN_SOURCE
+	bool "enable WLAN_OPEN_SOURCE"
+	default n
+
+config CFG80211_EXT_FEATURE_SECURE_NAN
+	bool "enable CFG80211_EXT_FEATURE_SECURE_NAN"
+	default n
+
+config CNSS_OUT_OF_TREE
+        bool "enable CNSS_OUT_OF_TREE"
+        default n
+
+config CFG80211_MLD_AP_STA_CONNECT_UPSTREAM_SUPPORT
+	bool "enable CFG80211_MLD_AP_STA_CONNECT_UPSTREAM_SUPPORT"
+	default n
+
+config DP_MULTIPASS_SUPPORT
+	bool "enable CONFIG_DP_MULTIPASS_SUPPORT"
+	default n
+
+config WLAN_FEATURE_LL_LT_SAP
+	bool "enable CONFIG_WLAN_FEATURE_LL_LT_SAP"
+	default n
+
+config WLAN_DP_VDEV_NO_SELF_PEER
+	bool "enable CONFIG_WLAN_DP_VDEV_NO_SELF_PEER"
+	default n
+
+config WLAN_FEATURE_AFFINITY_MGR
+	bool "enable CONFIG_WLAN_FEATURE_AFFINITY_MGR"
+	default n
+
+config NL80211_EXT_FEATURE_PUNCT_SUPPORT
+	bool "enable CONFIG_NL80211_EXT_FEATURE_PUNCT_SUPPORT"
+	default n
+
+config NL80211_TESTMODE
+	bool "enable CONFIG_NL80211_TESTMODE"
+	default n
+
+config DYNAMIC_DEBUG
+	bool "enable CONFIG_DYNAMIC_DEBUG"
+	default n
+
+config WLAN_CHIPSET_STATS
+	bool "enable WLAN_CHIPSET_STATS"
+	default n
+
+config DP_MLO_LINK_STATS_SUPPORT
+	bool "enable CONFIG_DP_MLO_LINK_STATS_SUPPORT"
+	default n
+
+config MULTI_IF_NAME
+	string "set MULTI_IF_NAME"
+	default \"wlan\"
+
+config CFG80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA
+	bool "enable CFG80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA"
+	default n
+
+config WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY
+	bool "enable WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY"
+	default n
+
+config FEATURE_WLAN_CH_AVOID_EXT
+	bool "enable FEATURE_WLAN_CH_AVOID_EXT"
+	default n
+
+config WLAN_TRACE_HIDE_MAC_ADDRESS_DISABLE
+	bool "enable CONFIG_WLAN_TRACE_HIDE_MAC_ADDRESS_DISABLE"
+	default n
+
+config 4_BYTES_TLV_TAG
+	bool "enable 4_BYTES_TLV_TAG"
+	default n
+
+config QCA_WIFI_EMULATION
+	bool "enable CONFIG_QCA_WIFI_EMULATION"
+	default n
+
+config QDF_TIMER_MULTIPLIER_FRAC
+	int "set QDF_TIMER_MULTIPLIER_FRAC"
+
+config QDF_TIMER_MULTIPLIER_FRAC_ENABLE
+	bool "enable QDF_TIMER_MULTIPLIER_FRAC_ENABLE"
+	default n
+
+config QCA_WIFI_PEACH
+	bool "enable QCA_WIFI_PEACH"
+	default n
+
+config BCN_RATECODE_ENABLE
+	bool "enable CONFIG_BCN_RATECODE_ENABLE"
+	default n
+
+config WLAN_SYSFS_RF_TEST_MODE
+	bool "enable CONFIG_WLAN_SYSFS_RF_TEST_MODE"
+	default n
+
+config WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET
+	bool "enable WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET"
+	default n
+
+config CNSS2_MODULE
+	bool "Enable CONFIG_CNSS2_MODULE"
+	default n
+
+config DP_RX_DESC_COOKIE_INVALIDATE
+	bool "Enable CONFIG_DP_RX_DESC_COOKIE_INVALIDATE"
+	default n
+
+config DP_SWLM
+	bool "Enable DP_SWLM"
+	default n
+
+config DP_TX_TRACKING
+	bool "Enable DP_TX_TRACKING"
+	default n
+
+config DP_WAR_VALIDATE_RX_ERR_MSDU_COOKIE
+	bool "Enable DP_WAR_VALIDATE_RX_ERR_MSDU_COOKIE"
+	default n
+
+config FEATURE_AST
+	bool "Enable FEATURE_AST"
+	default n
+
+config HIF_IPCI
+	bool "Enable HIF_IPCI"
+	default n
+
+config HOST_WAKEUP_OVER_QMI
+	bool "Enable HOST_WAKEUP_OVER_QMI"
+	default n
+
+config LITHIUM
+	bool "Enable LITHIUM"
+	default n
+
+config QCA6750_HEADERS_DEF
+	bool "Enable QCA6750_HEADERS_DEF"
+	default n
+
+config QCA_TARGET_IF_MLME
+	bool "Enable QCA_TARGET_IF_MLME"
+	default n
+
+config QCA_WIFI_QCA6750
+	bool "Enable QCA_WIFI_QCA6750"
+	default n
+
+config PLD_IPCI_ICNSS_FLAG
+	bool "Enable PLD_IPCI_ICNSS_FLAG"
+	default n
+
+config SHADOW_V2
+	bool "Enable SHADOW_V2"
+	default n
+
+config WLAN_DP_PROFILE_SUPPORT
+	bool "Enable WLAN_DP_PROFILE_SUPPORT"
+	default n
+
+config WLAN_FEATURE_CE_RX_BUFFER_REUSE
+	bool "Enable WLAN_FEATURE_CE_RX_BUFFER_REUSE"
+	default n
+
+config WLAN_STREAMFS
+	bool "Enable WLAN_STREAMFS"
+	default n
+
+config WLAN_SYSFS_ROAM_TRIGGER_BITMAP
+	bool "Enable WLAN_SYSFS_ROAM_TRIGGER_BITMAP"
+	default n
+
+config WLAN_SYSFS_WDS_MODE
+	bool "Enable WLAN_SYSFS_WDS_MODE"
+	default n
+
+config WLAN_TRACE_HIDE_MAC_ADDRESS
+	bool "Enable WLAN_TRACE_HIDE_MAC_ADDRESS"
+	default n
+
+config CNSS_QCA6750
+	bool "Enable CNSS_QCA6750"
+	default n
+
+config CNSS_ADRASTEA
+        bool "Enable CNSS_ADRASTEA"
+        default n
+
+config WLAN_FEATURE_EMLSR
+	bool "Enable EMLSR feature"
+	default n
+
+if CNSS_KIWI_V2
+config CFG_BMISS_OFFLOAD_MAX_VDEV
+	int "Enable CFG_BMISS_OFFLOAD_MAX_VDEV"
+
+config CFG_MAX_STA_VDEVS
+	int "Enable CFG_MAX_STA_VDEVS"
+
+config ROME_IF
+	string "Enable ROME_IF"
+	default pci
+endif
+
+if CNSS_QCA6750
+config ROME_IF
+	string "Enable ROME_IF"
+	default ipci
+
+config DP_LEGACY_MODE_CSM_DEFAULT_DISABLE
+        int "Enable CONFIG_DP_LEGACY_MODE_CSM_DEFAULT_DISABLE"
+endif
+
+if CNSS_ADRASTEA
+config ROME_IF
+	string "Enable ROME_IF"
+	default snoc
+endif
+
+config DP_RX_MSDU_DONE_FAIL_HISTORY
+	bool "Enable DP_RX_MSDU_DONE_FAIL_HISTORY"
+	default n
+
+config DP_RX_PEEK_MSDU_DONE_WAR
+	bool "Enable DP_RX_PEEK_MSDU_DONE_WAR"
+	default n
+
+config QCACLD_FEATURE_METERING
+	bool "Enable QCACLD_FEATURE_METERING"
+	default n
+
+config WIFI_3_0_ADRASTEA
+	bool "Enable WIFI_3_0_ADRASTEA"
+	default n
+
+config ADRASTEA_RRI_ON_DDR
+	bool "Enable ADRASTEA_RRI_ON_DDR"
+	default n
+
+config ATH_PROCFS_DIAG_SUPPORT
+	bool "Enable ATH_PROCFS_DIAG_SUPPORT"
+	default n
+
+config ADRASTEA_SHADOW_REGISTERS
+	bool "Enable ADRASTEA_SHADOW_REGISTERS"
+	default n
+
+config FEATURE_ENABLE_CE_DP_IRQ_AFFINE
+	bool "Enable FEATURE_ENABLE_CE_DP_IRQ_AFFINE"
+	default n
+
+config HIF_SNOC
+	bool "Enable HIF_SNOC"
+	default n
+
+config PKTLOG_LEGACY
+	bool "Enable PKTLOG_LEGACY"
+	default n
+
+config WLAN_SEND_DSCP_UP_MAP_TO_FW
+	bool "Enable WLAN_SEND_DSCP_UP_MAP_TO_FW"
+	default n
+
+config ENABLE_DEBUG_ADDRESS_MARKING
+	bool "Enable ENABLE_DEBUG_ADDRESS_MARKING"
+	default n
+
+config CHANNEL_HOPPING_ALL_BANDS
+	bool "Enable CHANNEL_HOPPING_ALL_BANDS"
+	default n
+
+config PKT_LOG
+	bool "Enable PKT_LOG"
+	default ni
+
+config WLAN_DUMP_IN_PROGRESS
+	bool "Enable WLAN_DUMP_IN_PROGRESS"
+	default n
+
+config WLAN_TX_FLOW_CONTROL_V2_HL
+	bool "Enable WLAN_TX_FLOW_CONTROL_V2_HL"
+	default n
+
+config LL_DP_SUPPORT_LEGACY
+	bool "Enable LL_DP_SUPPORT_LEGACY"
+	default n
+
+config WLAN_FASTPATH_LEGACY
+	bool "Enable WLAN_FASTPATH_LEGACY"
+	default n
+
+config QCA_SUPPORT_TX_THROTTLE_LEGACY
+	bool "Enable QCA_SUPPORT_TX_THROTTLE_LEGACY"
+	default n
+
+config PLD_SNOC_ICNSS_FLAG
+	bool "Enable PLD_SNOC_ICNSS_FLAG"
+	default n
+
+config ICNSS2_HELIUM
+	bool "Enable ICNSS2_HELIUM"
+	default n
+endif # QCA_CLD_WLAN

+ 40 - 0
qcom/opensource/wlan/qcacld-3.0/Makefile

@@ -0,0 +1,40 @@
+KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
+
+# The Make variable $(M) must point to the directory that contains the module
+# source code (which includes this Makefile). It can either be an absolute or a
+# relative path. If it is a relative path, then it must be relative to the
+# kernel source directory (KERNEL_SRC). An absolute path can be obtained very
+# easily through $(shell pwd). Generating a path relative to KERNEL_SRC is
+# difficult and we accept some outside help by letting the caller override the
+# variable $(M). Allowing a relative path for $(M) enables us to have the build
+# system put output/object files (.o, .ko.) into a directory different from the
+# module source directory.
+M ?= $(shell pwd)
+
+ifeq ($(WLAN_ROOT),)
+# WLAN_ROOT must contain an absolute path (i.e. not a relative path)
+KBUILD_OPTIONS := WLAN_ROOT=$(shell cd $(KERNEL_SRC); readlink -e $(M))
+
+# MODNAME should be qca_cld3_wlan for helium based wear target
+ifeq (qca_cld3, $(WLAN_WEAR_CHIPSET))
+KBUILD_OPTIONS += MODNAME?=$(WLAN_WEAR_CHIPSET)_wlan
+else
+KBUILD_OPTIONS += MODNAME?=wlan
+endif
+
+#By default build for CLD
+WLAN_SELECT := CONFIG_QCA_CLD_WLAN=m
+KBUILD_OPTIONS += CONFIG_QCA_WIFI_ISOC=0
+KBUILD_OPTIONS += CONFIG_QCA_WIFI_2_0=1
+KBUILD_OPTIONS += $(WLAN_SELECT)
+KBUILD_OPTIONS += $(KBUILD_EXTRA) # Extra config if any
+endif
+
+all:
+	$(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS)
+
+modules_install:
+	$(MAKE) INSTALL_MOD_STRIP=1 M=$(M) -C $(KERNEL_SRC) modules_install
+
+clean:
+	$(MAKE) -C $(KERNEL_SRC) M=$(M) clean $(KBUILD_OPTIONS)

+ 1 - 0
qcom/opensource/wlan/qcacld-3.0/README.txt

@@ -0,0 +1 @@
+This is CNSS WLAN Host Driver for products starting from iHelium

+ 1 - 0
qcom/opensource/wlan/qcacld-3.0/api

@@ -0,0 +1 @@
+../fw-api

+ 1 - 0
qcom/opensource/wlan/qcacld-3.0/cmn

@@ -0,0 +1 @@
+../qca-wifi-host-cmn

+ 173 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/inc/wlan_action_oui_main.h

@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Declare private API which shall be used internally only
+ * in action_oui component. This file shall include prototypes of
+ * various notification handlers and logging functions.
+ *
+ * Note: This API should be never accessed out of action_oui component.
+ */
+
+#ifndef _WLAN_ACTION_OUI_MAIN_H_
+#define _WLAN_ACTION_OUI_MAIN_H_
+
+#include <qdf_types.h>
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_priv.h"
+#include "wlan_action_oui_objmgr.h"
+
+#define action_oui_log(level, args...) \
+	QDF_TRACE(QDF_MODULE_ID_ACTION_OUI, level, ## args)
+
+#define action_oui_logfl(level, format, args...) \
+	action_oui_log(level, FL(format), ## args)
+
+#define action_oui_fatal(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
+#define action_oui_err(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
+#define action_oui_warn(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
+#define action_oui_info(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
+#define action_oui_debug(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
+
+#define ACTION_OUI_ENTER() action_oui_debug("enter")
+#define ACTION_OUI_EXIT() action_oui_debug("exit")
+
+/**
+ * action_oui_psoc_create_notification(): Handler for psoc create notify.
+ * @psoc: psoc which is going to be created by objmgr
+ * @arg: argument for notification handler.
+ *
+ * Allocate and attach psoc private object.
+ *
+ * Return: QDF_STATUS status in case of success else return error.
+ */
+QDF_STATUS
+action_oui_psoc_create_notification(struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * action_oui_psoc_destroy_notification(): Handler for psoc destroy notify.
+ * @psoc: psoc which is going to be destroyed by objmgr
+ * @arg: argument for notification handler.
+ *
+ * Deallocate and detach psoc private object.
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+action_oui_psoc_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * wlan_action_oui_search() - Check for OUIs and related info in IE data.
+ * @psoc: objmgr psoc object
+ * @attr: pointer to structure containing type of action, beacon IE data etc.,
+ * @action_id: type of action to be checked
+ *
+ * This is a wrapper function which invokes internal function to search
+ * for OUIs and related info (specified from ini file) in vendor specific
+ * data of beacon IE for given action.
+ *
+ * Return: If search is successful return true else false.
+ */
+#ifdef WLAN_FEATURE_ACTION_OUI
+bool wlan_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id);
+
+/**
+ * wlan_action_oui_is_empty() - Check action oui present or not
+ * @psoc: psoc object
+ * @action_id: action oui id
+ *
+ * This function will check action oui present or not for specific action type.
+ *
+ * Return: True if no action oui for the action type.
+ */
+bool wlan_action_oui_is_empty(struct wlan_objmgr_psoc *psoc,
+			      enum action_oui_id action_id);
+
+/**
+ * wlan_action_oui_cleanup() - Remove all of existing oui entry.
+ * @psoc_priv: action oui objmgr private context
+ * @action_id: type of action to be removed
+ *
+ * This is a wrapper function which invokes internal function to remove
+ * all of existing oui entry.
+ *
+ * Return: QDF_STATUS_SUCCESS If remove is successful.
+ */
+QDF_STATUS
+wlan_action_oui_cleanup(struct action_oui_psoc_priv *psoc_priv,
+			enum action_oui_id action_id);
+
+/**
+ * action_oui_psoc_enable() - Notify action OUI psoc enable
+ * @psoc: objmgr psoc object
+ *
+ * Return: void
+ */
+void action_oui_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * action_oui_psoc_disable() - Notify action OUI psoc disable
+ * @psoc: objmgr psoc object
+ *
+ * Return: void
+ */
+void action_oui_psoc_disable(struct wlan_objmgr_psoc *psoc);
+
+#else
+static inline
+bool wlan_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id)
+{
+	return false;
+}
+
+static inline
+bool wlan_action_oui_is_empty(struct wlan_objmgr_psoc *psoc,
+			      enum action_oui_id action_id)
+{
+	return true;
+}
+
+static inline QDF_STATUS
+wlan_action_oui_cleanup(struct action_oui_psoc_priv *psoc_priv,
+			enum action_oui_id action_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+void action_oui_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void action_oui_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+#endif
+#endif /* end  of _WLAN_ACTION_OUI_MAIN_H_ */

+ 79 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/inc/wlan_action_oui_objmgr.h

@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+/**
+ * DOC: This file contains various object manager related wrappers and helpers
+ */
+
+#ifndef _WLAN_ACTION_OUI_OBJMGR_H
+#define _WLAN_ACTION_OUI_OBJMGR_H
+
+#include "wlan_cmn.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_psoc_obj.h"
+
+/**
+ * action_oui_psoc_get_ref() - Wrapper to increment action_oui ref count
+ * @psoc: psoc object
+ *
+ * Wrapper for action_oui to increment ref count after checking valid
+ * object state.
+ *
+ * Return: SUCCESS/FAILURE
+ */
+static inline
+QDF_STATUS action_oui_psoc_get_ref(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_try_get_ref(psoc, WLAN_ACTION_OUI_ID);
+}
+
+/**
+ * action_oui_psoc_put_ref() - Wrapper to decrement action_oui ref count
+ * @psoc: psoc object
+ *
+ * Wrapper for action_oui to decrement ref count of psoc.
+ *
+ * Return: SUCCESS/FAILURE
+ */
+static inline
+void action_oui_psoc_put_ref(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_release_ref(psoc, WLAN_ACTION_OUI_ID);
+}
+
+/**
+ * action_oui_psoc_get_priv(): Wrapper to retrieve psoc priv obj
+ * @psoc: psoc pointer
+ *
+ * Wrapper for action_oui to get psoc private object pointer.
+ *
+ * Return: Private object of psoc
+ */
+static inline struct action_oui_psoc_priv *
+action_oui_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+
+	psoc_priv = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+					WLAN_UMAC_COMP_ACTION_OUI);
+	QDF_BUG(psoc_priv);
+
+	return psoc_priv;
+}
+
+#endif /* _WLAN_ACTION_OUI_OBJMGR_H */

+ 185 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/inc/wlan_action_oui_priv.h

@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Declare private API which shall be used internally only
+ * in action_oui component. This file shall include prototypes of
+ * action_oui parsing and send logic.
+ *
+ * Note: This API should be never accessed out of action_oui component.
+ */
+
+#ifndef _WLAN_ACTION_OUI_PRIV_STRUCT_H_
+#define _WLAN_ACTION_OUI_PRIV_STRUCT_H_
+
+#include <qdf_list.h>
+#include <qdf_types.h>
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_tgt_api.h"
+#include "wlan_action_oui_objmgr.h"
+
+/**
+ * enum action_oui_token_type - String token types expected.
+ * @ACTION_OUI_TOKEN: oui string
+ * @ACTION_OUI_DATA_LENGTH_TOKEN: data length string
+ * @ACTION_OUI_DATA_TOKEN: OUI data string
+ * @ACTION_OUI_DATA_MASK_TOKEN: data mask string
+ * @ACTION_OUI_INFO_MASK_TOKEN: info mask string
+ * @ACTION_OUI_MAC_ADDR_TOKEN: mac addr string
+ * @ACTION_OUI_MAC_MASK_TOKEN: mac mask string
+ * @ACTION_OUI_CAPABILITY_TOKEN: capability string
+ * @ACTION_OUI_END_TOKEN: end of one oui extension
+ */
+enum action_oui_token_type {
+	ACTION_OUI_TOKEN = 1 << 0,
+	ACTION_OUI_DATA_LENGTH_TOKEN = 1 << 1,
+	ACTION_OUI_DATA_TOKEN = 1 << 2,
+	ACTION_OUI_DATA_MASK_TOKEN = 1 << 3,
+	ACTION_OUI_INFO_MASK_TOKEN = 1 << 4,
+	ACTION_OUI_MAC_ADDR_TOKEN = 1 << 5,
+	ACTION_OUI_MAC_MASK_TOKEN = 1 << 6,
+	ACTION_OUI_CAPABILITY_TOKEN = 1 << 7,
+	ACTION_OUI_END_TOKEN = 1 << 8,
+};
+
+/**
+ * struct action_oui_extension_priv - Private contents of extension.
+ * @item: list element
+ * @extension: Extension contents
+ *
+ * This structure encapsulates action_oui_extension and list item.
+ */
+struct action_oui_extension_priv {
+	qdf_list_node_t item;
+	struct action_oui_extension extension;
+};
+
+/**
+ * struct action_oui_priv - Each action info.
+ * @id: type of action
+ * @extension_list: list of extensions
+ * @extension_lock: lock to control access to @extension_list
+ *
+ * All extensions of action specified by action_id are stored
+ * at @extension_list as linked list.
+ */
+struct action_oui_priv {
+	enum action_oui_id id;
+	qdf_list_t extension_list;
+	qdf_mutex_t extension_lock;
+};
+
+/**
+ * struct action_oui_psoc_priv - Private object to be stored in psoc
+ * @psoc: pointer to psoc object
+ * @action_oui_enable: action oui enable
+ * @action_oui_str: oui configuration strings
+ * @total_extensions: total count of extensions from all actions
+ * @host_only_extensions: total host only only extensions from all actions
+ * @max_extensions: Max no. of extensions that can be configured to the firmware
+ * @oui_priv: array of pointers used to refer each action info
+ * @tx_ops: call-back functions to send OUIs to firmware
+ */
+struct action_oui_psoc_priv {
+	struct wlan_objmgr_psoc *psoc;
+	bool action_oui_enable;
+	uint8_t action_oui_str[ACTION_OUI_MAXIMUM_ID][ACTION_OUI_MAX_STR_LEN];
+	uint32_t total_extensions;
+	uint32_t host_only_extensions;
+	uint32_t max_extensions;
+	struct action_oui_priv *oui_priv[ACTION_OUI_MAXIMUM_ID];
+	struct action_oui_tx_ops tx_ops;
+};
+
+/**
+ * action_oui_parse() - Parse action oui string
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ * @oui_string: string to be parsed
+ * @action_id: type of the action to be parsed
+ *
+ * This function parses the action oui string, extracts extensions and
+ * stores them @action_oui_priv using list data structure.
+ *
+ * Return: QDF_STATUS
+ *
+ */
+QDF_STATUS
+action_oui_parse(struct action_oui_psoc_priv *psoc_priv,
+		 uint8_t *oui_string, enum action_oui_id action_id);
+
+/**
+ * action_oui_parse_string() - Parse action oui string
+ * @psoc: psoc object
+ * @in_str: string to be parsed
+ * @action_id: type of the action to be parsed
+ *
+ * This function will validate the input string and call action_oui_parse
+ * to parse it.
+ *
+ * Return: QDF_STATUS
+ *
+ */
+QDF_STATUS
+action_oui_parse_string(struct wlan_objmgr_psoc *psoc,
+			const uint8_t *in_str,
+			enum action_oui_id action_id);
+
+/**
+ * action_oui_send() - Send action oui extensions to target_if.
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ * @action_id: type of the action to send
+ *
+ * This function sends action oui extensions to target_if.
+ *
+ * Return: QDF_STATUS
+ *
+ */
+QDF_STATUS
+action_oui_send(struct action_oui_psoc_priv *psoc_priv,
+		enum action_oui_id action_id);
+
+/**
+ * action_oui_search() - Check if Vendor OUIs are present in IE buffer
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ * @attr: pointer to structure containing type of action, beacon IE data etc.,
+ * @action_id: type of action to be checked
+ *
+ * This function parses the IE buffer and finds if any of the vendor OUI
+ * and related attributes are present in it.
+ *
+ * Return: If vendor OUI is present return true else false
+ */
+bool
+action_oui_search(struct action_oui_psoc_priv *psoc_priv,
+		  struct action_oui_search_attr *attr,
+		  enum action_oui_id action_id);
+
+/**
+ * action_oui_is_empty() - Check action oui present or not
+ * @psoc_priv: action psoc private object
+ * @action_id: action oui id
+ *
+ * This function will check action oui present or not for specific action type.
+ *
+ * Return: True if no action oui for the action type.
+ */
+bool
+action_oui_is_empty(struct action_oui_psoc_priv *psoc_priv,
+		    enum action_oui_id action_id);
+#endif /* End  of _WLAN_ACTION_OUI_PRIV_STRUCT_H_ */

+ 503 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/src/wlan_action_oui_main.c

@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Implement various notification handlers which are accessed
+ * internally in action_oui component only.
+ */
+#include "cfg_ucfg_api.h"
+#include "wlan_action_oui_cfg.h"
+#include "wlan_action_oui_main.h"
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_tgt_api.h"
+#include "target_if_action_oui.h"
+
+/**
+ * action_oui_allocate() - Allocates memory for various actions.
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ *
+ * This function allocates memory for all the action_oui types
+ * and initializes the respective lists to store extensions
+ * extracted from action_oui_extract().
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+action_oui_allocate(struct action_oui_psoc_priv *psoc_priv)
+{
+	struct action_oui_priv *oui_priv;
+	uint32_t i;
+	uint32_t j;
+
+	for (i = 0; i < ACTION_OUI_MAXIMUM_ID; i++) {
+		oui_priv = qdf_mem_malloc(sizeof(*oui_priv));
+		if (!oui_priv) {
+			action_oui_err("Mem alloc failed for oui_priv id: %u",
+					i);
+			goto free_mem;
+		}
+		oui_priv->id = i;
+		qdf_list_create(&oui_priv->extension_list,
+				ACTION_OUI_MAX_EXTENSIONS);
+		qdf_mutex_create(&oui_priv->extension_lock);
+		psoc_priv->oui_priv[i] = oui_priv;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+free_mem:
+	for (j = 0; j < i; j++) {
+		oui_priv = psoc_priv->oui_priv[j];
+		if (!oui_priv)
+			continue;
+
+		qdf_list_destroy(&oui_priv->extension_list);
+		qdf_mutex_destroy(&oui_priv->extension_lock);
+		psoc_priv->oui_priv[j] = NULL;
+	}
+
+	return QDF_STATUS_E_NOMEM;
+}
+
+/**
+ * action_oui_destroy() - Deallocates memory for various actions.
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ *
+ * This function Deallocates memory for all the action_oui types.
+ * As a part of deallocate, all extensions are destroyed.
+ *
+ * Return: None
+ */
+static void
+action_oui_destroy(struct action_oui_psoc_priv *psoc_priv)
+{
+	struct action_oui_priv *oui_priv;
+	struct action_oui_extension_priv *ext_priv;
+	qdf_list_t *ext_list;
+	QDF_STATUS status;
+	qdf_list_node_t *node = NULL;
+	uint32_t i;
+
+	psoc_priv->total_extensions = 0;
+	psoc_priv->max_extensions = 0;
+	psoc_priv->host_only_extensions = 0;
+
+	for (i = 0; i < ACTION_OUI_MAXIMUM_ID; i++) {
+		oui_priv = psoc_priv->oui_priv[i];
+		psoc_priv->oui_priv[i] = NULL;
+		if (!oui_priv)
+			continue;
+
+		ext_list = &oui_priv->extension_list;
+		qdf_mutex_acquire(&oui_priv->extension_lock);
+		while (!qdf_list_empty(ext_list)) {
+			status = qdf_list_remove_front(ext_list, &node);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				action_oui_err("Invalid delete in action: %u",
+						oui_priv->id);
+				break;
+			}
+			ext_priv = qdf_container_of(node,
+					struct action_oui_extension_priv,
+					item);
+			qdf_mem_free(ext_priv);
+			ext_priv = NULL;
+		}
+
+		qdf_list_destroy(ext_list);
+		qdf_mutex_release(&oui_priv->extension_lock);
+		qdf_mutex_destroy(&oui_priv->extension_lock);
+		qdf_mem_free(oui_priv);
+		oui_priv = NULL;
+	}
+}
+
+static void action_oui_load_config(struct action_oui_psoc_priv *psoc_priv)
+{
+	struct wlan_objmgr_psoc *psoc = psoc_priv->psoc;
+
+	psoc_priv->action_oui_enable =
+		cfg_get(psoc, CFG_ENABLE_ACTION_OUI);
+
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_CONNECT_1X1],
+		      cfg_get(psoc, CFG_ACTION_OUI_CONNECT_1X1),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_ITO_EXTENSION],
+		      cfg_get(psoc, CFG_ACTION_OUI_ITO_EXTENSION),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_CCKM_1X1],
+		      cfg_get(psoc, CFG_ACTION_OUI_CCKM_1X1),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_ITO_ALTERNATE],
+		      cfg_get(psoc, CFG_ACTION_OUI_ITO_ALTERNATE),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_SWITCH_TO_11N_MODE],
+		      cfg_get(psoc, CFG_ACTION_OUI_SWITCH_TO_11N_MODE),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN],
+		      cfg_get(psoc,
+			      CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_DISABLE_AGGRESSIVE_TX],
+		      cfg_get(psoc,
+			      CFG_ACTION_OUI_DISABLE_AGGRESSIVE_TX),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str
+					  [ACTION_OUI_DISABLE_AGGRESSIVE_EDCA],
+		      cfg_get(psoc,
+			      CFG_ACTION_OUI_DISABLE_AGGRESSIVE_EDCA),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_EXTEND_WOW_ITO],
+		      cfg_get(psoc, CFG_ACTION_OUI_EXTEND_WOW_ITO),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_DISABLE_TWT],
+		      cfg_get(psoc, CFG_ACTION_OUI_DISABLE_TWT),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_HOST_RECONN],
+		      cfg_get(psoc, CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_TAKE_ALL_BAND_INFO],
+		      cfg_get(psoc, CFG_ACTION_OUI_TAKE_ALL_BAND_INFO),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_11BE_OUI_ALLOW],
+		      cfg_get(psoc, CFG_ACTION_OUI_11BE_ALLOW_LIST),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str
+			[ACTION_OUI_DISABLE_DYNAMIC_QOS_NULL_TX_RATE],
+		      cfg_get(psoc,
+			      CFG_ACTION_OUI_DISABLE_DYNAMIC_QOS_NULL_TX_RATE),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str
+			[ACTION_OUI_ENABLE_CTS2SELF_WITH_QOS_NULL],
+		      cfg_get(psoc,
+			      CFG_ACTION_OUI_ENABLE_CTS2SELF_WITH_QOS_NULL),
+		      ACTION_OUI_MAX_STR_LEN);
+
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_ENABLE_CTS2SELF],
+		      cfg_get(psoc, CFG_ACTION_OUI_ENABLE_CTS2SELF),
+		      ACTION_OUI_MAX_STR_LEN);
+
+	qdf_str_lcopy(psoc_priv->action_oui_str
+			[ACTION_OUI_SEND_SMPS_FRAME_WITH_OMN],
+		      cfg_get(psoc,
+			      CFG_ACTION_OUI_SEND_SMPS_FRAME_WITH_OMN),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str
+			[ACTION_OUI_RESTRICT_MAX_MLO_LINKS],
+		      cfg_get(psoc, CFG_ACTION_OUI_RESTRICT_MAX_MLO_LINKS),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str
+			[ACTION_OUI_AUTH_ASSOC_6MBPS_2GHZ],
+		      cfg_get(psoc, CFG_ACTION_OUI_AUTH_ASSOC_6MBPS_2GHZ),
+		      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_DISABLE_BFORMEE],
+		      cfg_get(psoc, CFG_ACTION_OUI_DISABLE_BFORMEE),
+			      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(psoc_priv->action_oui_str[ACTION_OUI_LIMIT_BW],
+		      cfg_get(psoc, CFG_ACTION_OUI_LIMIT_BW),
+			      ACTION_OUI_MAX_STR_LEN);
+}
+
+static void action_oui_parse_config(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	uint32_t id;
+	uint8_t *str;
+	struct action_oui_psoc_priv *psoc_priv;
+
+	if (!psoc) {
+		action_oui_err("Invalid psoc");
+		return;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		return;
+	}
+	if (!psoc_priv->action_oui_enable) {
+		action_oui_debug("action_oui is not enable");
+		return;
+	}
+	for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
+		str = psoc_priv->action_oui_str[id];
+		if (!qdf_str_len(str))
+			continue;
+
+		status = action_oui_parse_string(psoc, str, id);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			action_oui_err("Failed to parse action_oui str: %u",
+				       id);
+	}
+
+	/* FW allocates memory for the extensions only during init time.
+	 * Therefore, send additional legspace for configuring new
+	 * extensions during runtime.
+	 * The current max value is default extensions count + 10.
+	 */
+	psoc_priv->max_extensions = psoc_priv->total_extensions -
+					psoc_priv->host_only_extensions +
+					ACTION_OUI_MAX_ADDNL_EXTENSIONS;
+	action_oui_debug("Extensions - Max: %d Total: %d host_only %d",
+			 psoc_priv->max_extensions, psoc_priv->total_extensions,
+			 psoc_priv->host_only_extensions);
+}
+
+static QDF_STATUS action_oui_send_config(struct wlan_objmgr_psoc *psoc)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint32_t id;
+
+	if (!psoc) {
+		action_oui_err("psoc is NULL");
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+	if (!psoc_priv->action_oui_enable) {
+		action_oui_debug("action_oui is not enable");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
+		if (id >= ACTION_OUI_HOST_ONLY)
+			continue;
+		status = action_oui_send(psoc_priv, id);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			action_oui_err("Failed to send: %u", id);
+	}
+
+exit:
+	return status;
+}
+
+QDF_STATUS
+action_oui_psoc_create_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status;
+
+	ACTION_OUI_ENTER();
+
+	psoc_priv = qdf_mem_malloc(sizeof(*psoc_priv));
+	if (!psoc_priv) {
+		status = QDF_STATUS_E_NOMEM;
+		goto exit;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+				WLAN_UMAC_COMP_ACTION_OUI,
+				(void *)psoc_priv, QDF_STATUS_SUCCESS);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		action_oui_err("Failed to attach priv with psoc");
+		goto free_psoc_priv;
+	}
+
+	target_if_action_oui_register_tx_ops(&psoc_priv->tx_ops);
+	psoc_priv->psoc = psoc;
+	action_oui_load_config(psoc_priv);
+	action_oui_debug("psoc priv attached");
+	goto exit;
+free_psoc_priv:
+	qdf_mem_free(psoc_priv);
+	status = QDF_STATUS_E_INVAL;
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+QDF_STATUS
+action_oui_psoc_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct action_oui_psoc_priv *psoc_priv = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	ACTION_OUI_ENTER();
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+					WLAN_UMAC_COMP_ACTION_OUI,
+					(void *)psoc_priv);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_err("Failed to detach priv with psoc");
+
+	qdf_mem_free(psoc_priv);
+
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+void action_oui_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	ACTION_OUI_ENTER();
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	status = action_oui_allocate(psoc_priv);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		action_oui_err("Failed to alloc action_oui");
+		goto exit;
+	}
+	action_oui_parse_config(psoc);
+	action_oui_send_config(psoc);
+exit:
+	ACTION_OUI_EXIT();
+}
+
+void action_oui_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+
+	ACTION_OUI_ENTER();
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	action_oui_destroy(psoc_priv);
+exit:
+	ACTION_OUI_EXIT();
+}
+
+bool wlan_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	bool found = false;
+
+	if (!psoc || !attr) {
+		action_oui_err("Invalid psoc or search attrs");
+		goto exit;
+	}
+
+	if (action_id >= ACTION_OUI_MAXIMUM_ID) {
+		action_oui_err("Invalid action_oui id: %u", action_id);
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	found = action_oui_search(psoc_priv, attr, action_id);
+
+exit:
+	return found;
+}
+
+QDF_STATUS
+wlan_action_oui_cleanup(struct action_oui_psoc_priv *psoc_priv,
+			enum action_oui_id action_id)
+{
+	struct action_oui_priv *oui_priv;
+	struct action_oui_extension_priv *ext_priv;
+	qdf_list_t *ext_list;
+	QDF_STATUS status;
+	qdf_list_node_t *node = NULL;
+
+	if (action_id >= ACTION_OUI_MAXIMUM_ID)
+		return QDF_STATUS_E_INVAL;
+
+	oui_priv = psoc_priv->oui_priv[action_id];
+	if (!oui_priv)
+		return QDF_STATUS_SUCCESS;
+
+	ext_list = &oui_priv->extension_list;
+	qdf_mutex_acquire(&oui_priv->extension_lock);
+	while (!qdf_list_empty(ext_list)) {
+		status = qdf_list_remove_front(ext_list, &node);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			action_oui_err("Invalid delete in action: %u",
+				       oui_priv->id);
+			break;
+		}
+		ext_priv = qdf_container_of(
+				node,
+				struct action_oui_extension_priv,
+				item);
+		qdf_mem_free(ext_priv);
+		ext_priv = NULL;
+		if (psoc_priv->total_extensions)
+			psoc_priv->total_extensions--;
+		else
+			action_oui_err("unexpected total_extensions 0");
+
+		if (action_id >= ACTION_OUI_HOST_ONLY) {
+			if (!psoc_priv->host_only_extensions)
+				action_oui_err("unexpected total host extensions");
+			else
+				psoc_priv->host_only_extensions--;
+		}
+	}
+	qdf_mutex_release(&oui_priv->extension_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool wlan_action_oui_is_empty(struct wlan_objmgr_psoc *psoc,
+			      enum action_oui_id action_id)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	bool empty = true;
+
+	if (!psoc) {
+		action_oui_err("Invalid psoc");
+		goto exit;
+	}
+
+	if (action_id >= ACTION_OUI_MAXIMUM_ID) {
+		action_oui_err("Invalid action_oui id: %u", action_id);
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	empty = action_oui_is_empty(psoc_priv, action_id);
+
+exit:
+	return empty;
+}
+

+ 1091 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/core/src/wlan_action_oui_parse.c

@@ -0,0 +1,1091 @@
+/*
+ * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Implement parsing logic for action_oui strings, extract
+ * extensions and store them using linked list. Functions defined in
+ * this file can be accessed internally in action_oui component only.
+ */
+
+#include "wlan_action_oui_main.h"
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_tgt_api.h"
+#include "target_if_action_oui.h"
+#include <qdf_str.h>
+#include <wlan_utility.h>
+
+/**
+ * action_oui_string_to_hex() - convert string to uint8_t hex array
+ * @token: string to be converted
+ * @hex: output string to hold converted string
+ * @no_of_lengths: count of possible lengths for input string
+ * @possible_lengths: array holding possible lengths
+ *
+ * This function converts the continuous input string of even length and
+ * containing hexa decimal characters into hexa decimal array of uint8_t type.
+ * Input string needs to be NULL terminated and the length should match with
+ * one of entries in @possible_lengths
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool action_oui_string_to_hex(uint8_t *token, uint8_t *hex,
+			      uint32_t no_of_lengths,
+			      uint32_t *possible_lengths)
+{
+	uint32_t token_len = qdf_str_len(token);
+	uint32_t hex_str_len;
+	uint32_t i;
+	int ret;
+
+	if (!token_len || (token_len & 0x01)) {
+		action_oui_err("Token len is not multiple of 2");
+		return false;
+	}
+
+	for (i = 0; i < no_of_lengths; i++)
+		if (token_len == possible_lengths[i])
+			break;
+
+	if (i == no_of_lengths) {
+		action_oui_err("Token len doesn't match with expected len");
+		return false;
+	}
+
+	hex_str_len = token_len / 2;
+
+	ret = qdf_hex_str_to_binary(hex, token, hex_str_len);
+	if (ret) {
+		action_oui_err("Token doesn't contain hex digits");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * action_oui_token_string() - converts enum value to string
+ * @token_id: enum value to be converted to string
+ *
+ * This function converts the enum value of type action_oui_token_type
+ * to string
+ *
+ * Return: converted string
+ */
+static
+uint8_t *action_oui_token_string(enum action_oui_token_type token_id)
+{
+	switch (token_id) {
+		CASE_RETURN_STRING(ACTION_OUI_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_DATA_LENGTH_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_DATA_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_DATA_MASK_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_INFO_MASK_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_MAC_ADDR_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_MAC_MASK_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_CAPABILITY_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_END_TOKEN);
+	}
+
+	return (uint8_t *) "UNKNOWN";
+}
+
+/**
+ * validate_and_convert_oui() - validate and convert OUI str to hex array
+ * @token: OUI string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the OUI string for action OUI inis, convert them to hex array and store it
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static
+bool validate_and_convert_oui(uint8_t *token,
+			struct action_oui_extension *ext,
+			enum action_oui_token_type *action_token)
+{
+	bool valid;
+	uint32_t expected_token_len[2] = {6, 10};
+
+	valid = action_oui_string_to_hex(token, ext->oui, 2,
+					 expected_token_len);
+	if (!valid)
+		return false;
+
+	ext->oui_length = qdf_str_len(token) / 2;
+
+	*action_token = ACTION_OUI_DATA_LENGTH_TOKEN;
+
+	return valid;
+}
+
+/**
+ * validate_and_convert_data_length() - validate data len str
+ * @token: data length string
+ * @ext: pointer to container which holds hex value formed from input str
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the data length string for action OUI inis, convert it to hex value and
+ * store it in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_data_length(uint8_t *token,
+				struct action_oui_extension *ext,
+				enum action_oui_token_type *action_token)
+{
+	uint32_t token_len = qdf_str_len(token);
+	int ret;
+	uint8_t len = 0;
+
+	if (token_len != 1 && token_len != 2) {
+		action_oui_err("Invalid str token len for action OUI data len");
+		return false;
+	}
+
+	ret = kstrtou8(token, 16, &len);
+	if (ret) {
+		action_oui_err("Invalid char in action OUI data len str token");
+		return false;
+	}
+
+	if ((uint32_t)len > ACTION_OUI_MAX_DATA_LENGTH) {
+		action_oui_err("action OUI data len %d is more than %u",
+			       len, ACTION_OUI_MAX_DATA_LENGTH);
+		return false;
+	}
+
+	ext->data_length = len;
+
+	if (!ext->data_length)
+		*action_token = ACTION_OUI_INFO_MASK_TOKEN;
+	else
+		*action_token = ACTION_OUI_DATA_TOKEN;
+
+	return true;
+}
+
+/**
+ * validate_and_convert_data() - validate and convert data str to hex array
+ * @token: data string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the data string for action OUI inis, convert it to hex array and store in
+ * action_oui extension. After successful parsing update the @action_token
+ * to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_data(uint8_t *token,
+			      struct action_oui_extension *ext,
+			      enum action_oui_token_type *action_token)
+{
+	bool valid;
+	uint32_t expected_token_len[1] = {2 * ext->data_length};
+
+	valid = action_oui_string_to_hex(token, ext->data, 1,
+					 expected_token_len);
+	if (!valid)
+		return false;
+
+	*action_token = ACTION_OUI_DATA_MASK_TOKEN;
+
+	return true;
+}
+
+/**
+ * validate_and_convert_data_mask() - validate and convert data mask str
+ * @token: data mask string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the data mask string for action OUI inis, convert it to hex array and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_data_mask(uint8_t *token,
+				   struct action_oui_extension *ext,
+				   enum action_oui_token_type *action_token)
+{
+	bool valid;
+	uint32_t expected_token_len[1];
+	uint32_t data_mask_length;
+	uint32_t data_length = ext->data_length;
+
+	if (data_length % 8 == 0)
+		data_mask_length = data_length / 8;
+	else
+		data_mask_length = ((data_length / 8) + 1);
+
+	if (data_mask_length > ACTION_OUI_MAX_DATA_MASK_LENGTH)
+		return false;
+
+	expected_token_len[0] = 2 * data_mask_length;
+
+	valid = action_oui_string_to_hex(token, ext->data_mask, 1,
+				  expected_token_len);
+	if (!valid)
+		return false;
+
+	ext->data_mask_length = data_mask_length;
+
+	*action_token = ACTION_OUI_INFO_MASK_TOKEN;
+
+	return valid;
+}
+
+/**
+ * validate_and_convert_info_mask() - validate and convert info mask str
+ * @token: info mask string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the info mask string for action OUI inis, convert it to hex array and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_info_mask(uint8_t *token,
+				   struct action_oui_extension *ext,
+				   enum action_oui_token_type *action_token)
+{
+	uint32_t token_len = qdf_str_len(token);
+	uint8_t hex_value = 0;
+	uint32_t info_mask;
+	int ret;
+
+	if (token_len != 2) {
+		action_oui_err("action OUI info mask str token len is not of 2 chars");
+		return false;
+	}
+
+	ret = kstrtou8(token, 16, &hex_value);
+	if (ret) {
+		action_oui_err("Invalid char in action OUI info mask str token");
+		return false;
+	}
+
+	info_mask = hex_value;
+
+	ext->info_mask = info_mask;
+
+	if (!info_mask || !(info_mask & ~ACTION_OUI_INFO_OUI)) {
+		*action_token = ACTION_OUI_END_TOKEN;
+		return true;
+	}
+
+	if (info_mask & ~ACTION_OUI_INFO_MASK) {
+		action_oui_err("Invalid bits are set in action OUI info mask");
+		return false;
+	}
+
+	/*
+	 * If OUI bit is not set in the info presence, we need to ignore the
+	 * OUI and OUI Data. Set OUI and OUI data length to 0 here.
+	 */
+	if (!(info_mask & ACTION_OUI_INFO_OUI)) {
+		ext->oui_length = 0;
+		ext->data_length = 0;
+		ext->data_mask_length = 0;
+	}
+
+	if (info_mask & ACTION_OUI_INFO_MAC_ADDRESS) {
+		*action_token = ACTION_OUI_MAC_ADDR_TOKEN;
+		return true;
+	}
+
+	*action_token = ACTION_OUI_CAPABILITY_TOKEN;
+	return true;
+}
+
+/**
+ * validate_and_convert_mac_addr() - validate and convert mac addr str
+ * @token: mac address string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the mac address string for action OUI inis, convert it to hex array and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_mac_addr(uint8_t *token,
+				  struct action_oui_extension *ext,
+				  enum action_oui_token_type *action_token)
+{
+	uint32_t expected_token_len[1] = {2 * QDF_MAC_ADDR_SIZE};
+	bool valid;
+
+	valid = action_oui_string_to_hex(token, ext->mac_addr, 1,
+				  expected_token_len);
+	if (!valid)
+		return false;
+
+	ext->mac_addr_length = QDF_MAC_ADDR_SIZE;
+
+	*action_token = ACTION_OUI_MAC_MASK_TOKEN;
+
+	return true;
+}
+
+/**
+ * validate_and_convert_mac_mask() - validate and convert mac mask
+ * @token: mac mask string
+ * @ext: pointer to container which holds converted hex value
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the mac mask string for action OUI inis, convert it to hex value and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_mac_mask(uint8_t *token,
+				  struct action_oui_extension *ext,
+				  enum action_oui_token_type *action_token)
+{
+	uint32_t expected_token_len[1] = {2};
+	uint32_t info_mask = ext->info_mask;
+	bool valid;
+	uint32_t mac_mask_length;
+
+	valid = action_oui_string_to_hex(token, ext->mac_mask, 1,
+				  expected_token_len);
+	if (!valid)
+		return false;
+
+	mac_mask_length = qdf_str_len(token) / 2;
+	if (mac_mask_length > ACTION_OUI_MAC_MASK_LENGTH) {
+		action_oui_err("action OUI mac mask str token len is more than %u chars",
+			expected_token_len[0]);
+		return false;
+	}
+
+	ext->mac_mask_length = mac_mask_length;
+
+	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) ||
+	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_HT) ||
+	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_VHT) ||
+	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND)) {
+		*action_token = ACTION_OUI_CAPABILITY_TOKEN;
+		return true;
+	}
+
+	*action_token = ACTION_OUI_END_TOKEN;
+	return true;
+}
+
+/**
+ * validate_and_convert_capability() - validate and convert capability str
+ * @token: capability string
+ * @ext: pointer to container which holds converted hex value
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the capability string for action OUI inis, convert it to hex value and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_capability(uint8_t *token,
+				struct action_oui_extension *ext,
+				enum action_oui_token_type *action_token)
+{
+	uint32_t expected_token_len[1] = {2};
+	uint32_t info_mask = ext->info_mask;
+	uint32_t capability_length;
+	uint8_t caps_0;
+	bool valid;
+
+	valid = action_oui_string_to_hex(token, ext->capability, 1,
+				  expected_token_len);
+	if (!valid)
+		return false;
+
+	capability_length = qdf_str_len(token) / 2;
+	if (capability_length > ACTION_OUI_MAX_CAPABILITY_LENGTH) {
+		action_oui_err("action OUI capability str token len is more than %u chars",
+			expected_token_len[0]);
+		return false;
+	}
+
+	caps_0 = ext->capability[0];
+
+	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) &&
+	    (!(caps_0 & ACTION_OUI_CAPABILITY_NSS_MASK))) {
+		action_oui_err("Info presence for NSS is set but respective bits in capability are not set");
+		return false;
+	}
+
+	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND) &&
+	    (!(caps_0 & ACTION_OUI_CAPABILITY_BAND_MASK))) {
+		action_oui_err("Info presence for BAND is set but respective bits in capability are not set");
+		return false;
+	}
+
+	ext->capability_length = capability_length;
+
+	*action_token = ACTION_OUI_END_TOKEN;
+
+	return true;
+}
+
+/**
+ * action_oui_extension_store() - store action oui extension
+ * @psoc_priv: pointer to action_oui priv obj
+ * @oui_priv: type of the action
+ * @ext: oui extension to store in sme
+ *
+ * This function stores the parsed oui extension
+ *
+ * Return: QDF_STATUS
+ *
+ */
+static QDF_STATUS
+action_oui_extension_store(struct action_oui_psoc_priv *psoc_priv,
+			   struct action_oui_priv *oui_priv,
+			   struct action_oui_extension ext)
+{
+	struct action_oui_extension_priv *ext_priv;
+
+	qdf_mutex_acquire(&oui_priv->extension_lock);
+	if (qdf_list_size(&oui_priv->extension_list) ==
+			  ACTION_OUI_MAX_EXTENSIONS) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		action_oui_err("Reached maximum OUI extensions");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ext_priv = qdf_mem_malloc(sizeof(*ext_priv));
+	if (!ext_priv) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	ext_priv->extension = ext;
+	qdf_list_insert_back(&oui_priv->extension_list, &ext_priv->item);
+	psoc_priv->total_extensions++;
+	qdf_mutex_release(&oui_priv->extension_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+action_oui_parse(struct action_oui_psoc_priv *psoc_priv,
+		 uint8_t *oui_string, enum action_oui_id action_id)
+{
+	struct action_oui_extension ext = {0};
+	enum action_oui_token_type action_token = ACTION_OUI_TOKEN;
+	char *str1;
+	char *str2;
+	char *token;
+	bool valid = true;
+	bool oui_count_exceed = false;
+	uint32_t oui_index = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct action_oui_priv *oui_priv;
+
+	if (!oui_string) {
+		action_oui_err("Invalid string for action oui: %u", action_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	oui_priv = psoc_priv->oui_priv[action_id];
+	if (!oui_priv) {
+		action_oui_err("action oui priv not allocated");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!psoc_priv->action_oui_enable) {
+		action_oui_debug("action_oui is not enable");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	str1 = qdf_str_trim((char *)oui_string);
+
+	while (str1) {
+		str2 = (char *)qdf_str_left_trim(str1);
+		if (str2[0] == '\0') {
+			action_oui_err("Invalid spaces in action oui: %u at extension: %u for token: %s",
+				action_id,
+				oui_index + 1,
+				action_oui_token_string(action_token));
+			valid = false;
+			break;
+		}
+
+		token = strsep(&str2, " ");
+		if (!token) {
+			action_oui_err("Invalid string for token: %s at extension: %u in action oui: %u",
+				action_oui_token_string(action_token),
+				oui_index + 1, action_id);
+			valid = false;
+			break;
+		}
+
+		str1 = str2;
+
+		switch (action_token) {
+
+		case ACTION_OUI_TOKEN:
+			valid = validate_and_convert_oui(token, &ext,
+							 &action_token);
+			break;
+
+		case ACTION_OUI_DATA_LENGTH_TOKEN:
+			valid = validate_and_convert_data_length(token, &ext,
+								&action_token);
+			break;
+
+		case ACTION_OUI_DATA_TOKEN:
+			valid = validate_and_convert_data(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_DATA_MASK_TOKEN:
+			valid = validate_and_convert_data_mask(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_INFO_MASK_TOKEN:
+			valid = validate_and_convert_info_mask(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_MAC_ADDR_TOKEN:
+			valid = validate_and_convert_mac_addr(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_MAC_MASK_TOKEN:
+			valid = validate_and_convert_mac_mask(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_CAPABILITY_TOKEN:
+			valid = validate_and_convert_capability(token, &ext,
+							&action_token);
+			break;
+
+		default:
+			valid = false;
+			break;
+		}
+
+		if (!valid) {
+			action_oui_err("Invalid string for token: %s at extension: %u in action oui: %u",
+				action_oui_token_string(action_token),
+				oui_index + 1,
+				action_id);
+			break;
+		}
+
+		if (action_token != ACTION_OUI_END_TOKEN)
+			continue;
+
+		status = action_oui_extension_store(psoc_priv, oui_priv, ext);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			valid = false;
+			action_oui_err("sme set of extension: %u for action oui: %u failed",
+				oui_index + 1, action_id);
+			break;
+		}
+
+		if (action_id >= ACTION_OUI_HOST_ONLY) {
+			qdf_mutex_acquire(&oui_priv->extension_lock);
+			psoc_priv->host_only_extensions++;
+			qdf_mutex_release(&oui_priv->extension_lock);
+		}
+
+		oui_index++;
+		if (oui_index == ACTION_OUI_MAX_EXTENSIONS) {
+			if (str1)
+				oui_count_exceed = true;
+			break;
+		}
+
+		/* reset the params for next action OUI parse */
+		action_token = ACTION_OUI_TOKEN;
+		qdf_mem_zero(&ext, sizeof(ext));
+	}
+
+	if (oui_count_exceed) {
+		action_oui_err("Reached Maximum extensions: %u in action_oui: %u, ignoring the rest",
+			ACTION_OUI_MAX_EXTENSIONS, action_id);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (action_token != ACTION_OUI_TOKEN &&
+	    action_token != ACTION_OUI_END_TOKEN &&
+	    valid && !str1) {
+		action_oui_err("No string for token: %s at extension: %u in action oui: %u",
+			action_oui_token_string(action_token),
+			oui_index + 1,
+			action_id);
+		valid = false;
+	}
+
+	if (!oui_index) {
+		action_oui_err("Not able to parse any extension in action oui: %u",
+			action_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (valid)
+		action_oui_debug("All extensions: %u parsed successfully in action oui: %u",
+			  oui_index, action_id);
+	else
+		action_oui_err("First %u extensions parsed successfully in action oui: %u",
+			oui_index, action_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+action_oui_parse_string(struct wlan_objmgr_psoc *psoc,
+			const uint8_t *in_str,
+			enum action_oui_id action_id)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint8_t *oui_str;
+	int len;
+
+	ACTION_OUI_ENTER();
+
+	if (!psoc) {
+		action_oui_err("psoc is NULL");
+		goto exit;
+	}
+
+	if (action_id >= ACTION_OUI_MAXIMUM_ID) {
+		action_oui_err("Invalid action_oui id: %u", action_id);
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	len = qdf_str_len(in_str);
+	if (len <= 0 || len > ACTION_OUI_MAX_STR_LEN - 1) {
+		action_oui_err("Invalid string length: %u", action_id);
+		goto exit;
+	}
+
+	oui_str = qdf_mem_malloc(len + 1);
+	if (!oui_str) {
+		status = QDF_STATUS_E_NOMEM;
+		goto exit;
+	}
+
+	qdf_mem_copy(oui_str, in_str, len);
+	oui_str[len] = '\0';
+
+	status = action_oui_parse(psoc_priv, oui_str, action_id);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_err("Failed to parse: %u", action_id);
+
+	qdf_mem_free(oui_str);
+
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+QDF_STATUS action_oui_send(struct action_oui_psoc_priv *psoc_priv,
+			enum action_oui_id action_id)
+{
+	QDF_STATUS status;
+	struct action_oui_request *req;
+	struct action_oui_priv *oui_priv;
+	struct action_oui_extension *extension;
+	struct action_oui_extension_priv *ext_priv;
+	qdf_list_node_t *node = NULL;
+	qdf_list_node_t *next_node = NULL;
+	qdf_list_t *extension_list;
+	uint32_t len;
+	uint32_t no_oui_extensions;
+
+	oui_priv = psoc_priv->oui_priv[action_id];
+	if (!oui_priv)
+		return QDF_STATUS_SUCCESS;
+
+	if (!psoc_priv->action_oui_enable) {
+		action_oui_debug("action_oui is not enable");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	extension_list = &oui_priv->extension_list;
+	qdf_mutex_acquire(&oui_priv->extension_lock);
+
+	if (psoc_priv->max_extensions -
+	    (psoc_priv->total_extensions - psoc_priv->host_only_extensions) < 0) {
+		action_oui_err("total_extensions: %d exceeds max_extensions: %d, do not update",
+			       psoc_priv->max_extensions,
+			       (psoc_priv->total_extensions -
+				psoc_priv->host_only_extensions));
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	no_oui_extensions = qdf_list_size(extension_list);
+	len = sizeof(*req) + no_oui_extensions * sizeof(*extension);
+	req = qdf_mem_malloc(len);
+	if (!req) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	req->action_id = oui_priv->id;
+	req->no_oui_extensions = no_oui_extensions;
+	req->total_no_oui_extensions = psoc_priv->max_extensions;
+
+	extension = req->extension;
+	qdf_list_peek_front(extension_list, &node);
+	while (node) {
+		ext_priv = qdf_container_of(node,
+					   struct action_oui_extension_priv,
+					   item);
+		*extension = ext_priv->extension;
+		status = qdf_list_peek_next(extension_list, node,
+						&next_node);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+		node = next_node;
+		next_node = NULL;
+		extension++;
+	}
+
+	qdf_mutex_release(&oui_priv->extension_lock);
+
+	status = tgt_action_oui_send(psoc_priv->psoc, req);
+	qdf_mem_free(req);
+
+	return status;
+}
+
+/**
+ * check_for_vendor_oui_data() - compares for vendor OUI data from IE
+ * and returns true if OUI data matches with the ini
+ * @extension: pointer to action oui extension data
+ * @oui_ptr: pointer to Vendor IE in the beacon
+ *
+ * Return: true or false
+ */
+static bool
+check_for_vendor_oui_data(struct action_oui_extension *extension,
+			  const uint8_t *oui_ptr)
+{
+	const uint8_t *data;
+	uint8_t i, j, elem_len, data_len;
+	uint8_t data_mask = 0x80;
+
+	if (!oui_ptr)
+		return false;
+
+	elem_len = oui_ptr[1];
+	if (elem_len < extension->oui_length)
+		return false;
+
+	data_len = elem_len - extension->oui_length;
+	if (data_len < extension->data_length)
+		return false;
+
+	data = &oui_ptr[2 + extension->oui_length];
+	for (i = 0, j = 0;
+	     (i < data_len && j < extension->data_mask_length);
+	     i++) {
+		if ((extension->data_mask[j] & data_mask) &&
+		    !(extension->data[i] == data[i]))
+			return false;
+		data_mask = data_mask >> 1;
+		if (!data_mask) {
+			data_mask = 0x80;
+			j++;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * check_for_vendor_ap_mac() - compares for vendor AP MAC in the ini with
+ * bssid from the session and returns true if matches
+ * @extension: pointer to action oui extension data
+ * @attr: pointer to structure containing mac_addr (bssid) of AP
+ *
+ * Return: true or false
+ */
+static bool
+check_for_vendor_ap_mac(struct action_oui_extension *extension,
+			struct action_oui_search_attr *attr)
+{
+	uint8_t i;
+	uint8_t mac_mask = 0x80;
+	uint8_t *mac_addr = attr->mac_addr;
+
+	for (i = 0; i < QDF_MAC_ADDR_SIZE; i++) {
+		if ((*extension->mac_mask & mac_mask) &&
+		    !(extension->mac_addr[i] == mac_addr[i]))
+			return false;
+		mac_mask = mac_mask >> 1;
+	}
+
+	return true;
+}
+
+/**
+ * check_for_vendor_ap_capabilities() - Compares various Vendor AP
+ * capabilities like NSS, HT, VHT, Band from the ini with the AP's capability
+ * from the beacon and returns true if all the capability matches
+ * @extension: pointer to oui extension data
+ * @attr: pointer to structure containing type of action, ap capabilities
+ *
+ * Return: true or false
+ */
+static bool
+check_for_vendor_ap_capabilities(struct action_oui_extension *extension,
+				 struct action_oui_search_attr *attr)
+{
+	uint8_t nss_mask;
+
+	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) {
+		nss_mask = 1 << (attr->nss - 1);
+		if (!((*extension->capability &
+		    ACTION_OUI_CAPABILITY_NSS_MASK) &
+		    nss_mask))
+		return false;
+	}
+
+	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_HT) {
+		if (*extension->capability &
+		    ACTION_OUI_CAPABILITY_HT_ENABLE_MASK) {
+			if (!attr->ht_cap)
+				return false;
+		} else {
+			if (attr->ht_cap)
+				return false;
+		}
+	}
+
+	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_VHT) {
+		if (*extension->capability &
+		    ACTION_OUI_CAPABILITY_VHT_ENABLE_MASK) {
+			if (!attr->vht_cap)
+				return false;
+		} else {
+			if (attr->vht_cap)
+				return false;
+		}
+	}
+
+	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND &&
+	    ((attr->enable_5g &&
+	    !(*extension->capability & ACTION_CAPABILITY_5G_BAND_MASK)) ||
+	    (attr->enable_2g &&
+	    !(*extension->capability & ACTION_OUI_CAPABILITY_2G_BAND_MASK))))
+		return false;
+
+	return true;
+}
+
+static const uint8_t *
+action_oui_get_oui_ptr(struct action_oui_extension *extension,
+		       struct action_oui_search_attr *attr)
+{
+	if (!attr->ie_data || !attr->ie_length)
+		return NULL;
+
+	return wlan_get_vendor_ie_ptr_from_oui(extension->oui,
+					       extension->oui_length,
+					       attr->ie_data,
+					       attr->ie_length);
+}
+
+bool
+action_oui_is_empty(struct action_oui_psoc_priv *psoc_priv,
+		    enum action_oui_id action_id)
+{
+	struct action_oui_priv *oui_priv;
+	qdf_list_t *extension_list;
+
+	oui_priv = psoc_priv->oui_priv[action_id];
+	if (!oui_priv)
+		return true;
+
+	extension_list = &oui_priv->extension_list;
+	qdf_mutex_acquire(&oui_priv->extension_lock);
+	if (qdf_list_empty(extension_list)) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return true;
+	}
+	qdf_mutex_release(&oui_priv->extension_lock);
+
+	return false;
+}
+
+static bool validate_vendor_oui_data(struct action_oui_extension *extension,
+				     struct action_oui_search_attr *attr)
+{
+	uint8_t elem_id, elem_len;
+	int32_t left;
+	uint8_t eid = WLAN_MAC_EID_VENDOR;
+	const uint8_t *ptr = NULL;
+	const uint8_t *oui = extension->oui;
+
+	if (!attr->ie_data || !attr->ie_length || !oui)
+		return false;
+
+	ptr = attr->ie_data;
+	left = attr->ie_length;
+
+	while (left >= 2) {
+		elem_id  = ptr[0];
+		elem_len = ptr[1];
+		left -= 2;
+
+		if (elem_len > left)
+			return false;
+
+		if (eid == elem_id) {
+			/*
+			 * if oui is provided and oui_size is more than left
+			 * bytes, then we cannot have match
+			 */
+			if (extension->oui_length > left)
+				return false;
+
+			if (qdf_mem_cmp(&ptr[2], extension->oui,
+					extension->oui_length) == 0 &&
+			    check_for_vendor_oui_data(extension, ptr))
+				return true;
+		}
+
+		left -= elem_len;
+		ptr += (elem_len + 2);
+	}
+
+	return false;
+}
+
+bool
+action_oui_search(struct action_oui_psoc_priv *psoc_priv,
+		  struct action_oui_search_attr *attr,
+		  enum action_oui_id action_id)
+{
+	struct action_oui_priv *oui_priv;
+	struct action_oui_extension_priv *priv_ext;
+	struct action_oui_extension *extension;
+	qdf_list_node_t *node = NULL;
+	qdf_list_node_t *next_node = NULL;
+	qdf_list_t *extension_list;
+	QDF_STATUS qdf_status;
+	const uint8_t *oui_ptr;
+	bool wildcard_oui = false;
+
+	oui_priv = psoc_priv->oui_priv[action_id];
+	if (!oui_priv) {
+		action_oui_debug("action oui for id %d is empty",
+				 action_id);
+		return false;
+	}
+
+	extension_list = &oui_priv->extension_list;
+	qdf_mutex_acquire(&oui_priv->extension_lock);
+	if (qdf_list_empty(extension_list)) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return false;
+	}
+
+	qdf_list_peek_front(extension_list, &node);
+	while (node) {
+		priv_ext = qdf_container_of(node,
+					   struct action_oui_extension_priv,
+					   item);
+		extension = &priv_ext->extension;
+
+		/*
+		 * If a wildcard OUI bit is not set in the info_mask, proceed
+		 * to other checks skipping the OUI and vendor data checks
+		 */
+
+		if (!(extension->info_mask & ACTION_OUI_INFO_OUI))
+			wildcard_oui = true;
+
+		oui_ptr = action_oui_get_oui_ptr(extension, attr);
+
+		if (!oui_ptr  && !wildcard_oui)
+			goto next;
+
+		if (extension->data_length && !wildcard_oui &&
+		    !validate_vendor_oui_data(extension, attr))
+			goto next;
+
+		if ((extension->info_mask & ACTION_OUI_INFO_MAC_ADDRESS) &&
+		    !check_for_vendor_ap_mac(extension, attr))
+			goto next;
+
+		if (!check_for_vendor_ap_capabilities(extension, attr))
+			goto next;
+
+		action_oui_debug("Vendor AP/STA found for OUI");
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   extension->oui, extension->oui_length);
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return true;
+next:
+		qdf_status = qdf_list_peek_next(extension_list,
+						node, &next_node);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			break;
+
+		node = next_node;
+		next_node = NULL;
+		wildcard_oui = false;
+	}
+
+	qdf_mutex_release(&oui_priv->extension_lock);
+	return false;
+}

+ 914 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/inc/wlan_action_oui_cfg.h

@@ -0,0 +1,914 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: This file contains centralized definitions of action oui configuration.
+ */
+#ifndef __WLAN_ACTION_OUI_CFG_H__
+#define __WLAN_ACTION_OUI_CFG_H__
+/*
+ * Start of action oui inis
+ *
+ * To enable action oui feature, set gEnableActionOUI
+ *
+ * Each action oui is expected in the following format:
+ * <Extension 1> <Extension 2> ..... <Extension 10> (maximum 10)
+ *
+ * whereas, each Extension is separated by space and have the following format:
+ * <Token1> <Token2> <Token3> <Token4> <Token5> <Token6> <Token7> <Token8>
+ * where each Token is a string of hexa-decimal digits and
+ * following are the details about each token
+ *
+ * Token1 = OUI
+ * Token2 = Data_Length
+ * Token3 = Data
+ * Token4 = Data_Mask
+ * Token5 = Info_Presence_Bit
+ * Token6 = MAC_Address
+ * Token7 = Mac_Address Mask
+ * Token8 = Capability
+ *
+ * <OUI> is mandatory and it can be either 3 or 5 bytes means 6 or 10
+ * hexa-decimal characters
+ * If the OUI and Data checks needs to be ignored, the oui FFFFFF
+ * needs to be provided as OUI and bit 0 of Info_Presence_Bit should
+ * be set to 0.
+ *
+ * <Data_Length> is mandatory field and should give length of
+ * the <Data> if present else zero
+ *
+ * Presence of <Data> is controlled by <Data_Length>, if <Data_Length> is 0,
+ * then <Data> is not expected else Data of the size Data Length bytes are
+ * expected which means the length of Data string is 2 * Data Length,
+ * since every byte constitutes two hexa-decimal characters.
+ *
+ * <Data_Mask> is mandatory if <Data> is present and length of the
+ * Data mask string depends on the <Data Length>
+ * If <Data Length> is 06, then length of Data Mask string is
+ * 2 characters (represents 1 byte)
+ * data_mask_length = ((Data_Length - (Data_Length % 8)) / 8) +
+ *		      ((Data_Length % 8) ? 1 : 0)
+ * and <Data_Mask> has to be constructed from left to right.
+ *
+ * Presence of <Mac_Address> and <Capability> is
+ * controlled by <Info_Presence_Bit> which is mandatory
+ * <Info_Presence_Bit> will give the information for
+ *   OUI – bit 0 Should be set to 1
+ *		 Setting to 0 will ignore OUI and data check
+ *   Mac Address present – bit 1
+ *   NSS – bit 2
+ *   HT check – bit 3
+ *   VHT check – bit 4
+ *   Band info – bit 5
+ *   reserved – bit 6 (should always be zero)
+ *   reserved – bit 7 (should always be zero)
+ * and should be constructed from right to left (b7b6b5b4b3b2b1b0)
+ *
+ * <Mac_Address_Mask> for <Mac_Address> should be constructed from left to right
+ *
+ * <Capability> is 1 byte long and it contains the below info
+ *   NSS – 4 bits starting from LSB (b0 – b3)
+ *   HT enabled – bit 4
+ *   VHT enabled – bit 5
+ *   2G band – bit 6
+ *   5G band – bit 7
+ * and should be constructed from right to left (b7b6b5b4b3b2b1b0)
+ * <Capability> is present if at least one of the bit is set
+ * from b2 - b6 in <Info_Presence_Bit>
+ *
+ * Example 1:
+ *
+ * OUI is 00-10-18, data length is 05 (hex form), data is 02-11-04-5C-DE and
+ * need to consider first 3 bytes and last byte of data for comparison
+ * mac-addr EE-1A-59-FE-FD-AF is present and first 3 bytes and last byte of
+ * mac address should be considered for comparison
+ * capability is not present
+ * then action OUI for gActionOUIITOExtension is as follows:
+ *
+ * gActionOUIITOExtension=001018 05 0211045CDE E8 03 EE1A59FEFDAF E4
+ *
+ * data mask calculation in above example:
+ * Data[0] = 02 ---- d0 = 1
+ * Data[1] = 11 ---- d1 = 1
+ * Data[2] = 04 ---- d2 = 1
+ * Data[3] = 5C ---- d3 = 0
+ * Data[4] = DE ---- d4 = 1
+ * data_mask = d0d1d2d3d4 + append with zeros to complete 8-bit = 11101000 = E8
+ *
+ * mac mask calculation in above example:
+ * mac_addr[0] = EE ---- m0 = 1
+ * mac_addr[1] = 1A ---- m1 = 1
+ * mac_addr[2] = 59 ---- m2 = 1
+ * mac_addr[3] = FE ---- m3 = 0
+ * mac_addr[4] = FD ---- m4 = 0
+ * mac_addr[5] = AF ---- m5 = 1
+ * mac_mask = m0m1m2m3m4m5 + append with zeros to complete 8-bit = 11100100 = E4
+ *
+ * Example 2:
+ *
+ * OUI is 00-10-18, data length is 00 and no Mac Address and capability
+ *
+ * gActionOUIITOExtension=001018 00 01
+ *
+ */
+
+/*
+ * <ini>
+ * gEnableActionOUI - Enable/Disable action oui feature
+ * @Min: 0 (disable)
+ * @Max: 1 (enable)
+ * @Default: 1 (enable)
+ *
+ * This ini is used to enable the action oui feature to control
+ * mode of connection, connected AP's in-activity time, Tx rate etc.,
+ *
+ * Related: If gEnableActionOUI is set, then at least one of the following inis
+ * must be set with the proper action oui extensions:
+ * gActionOUIConnect1x1, gActionOUIITOExtension, gActionOUICCKM1X1
+ *
+ * Supported Feature: action ouis
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_ACTION_OUI CFG_INI_BOOL( \
+	"gEnableActionOUI", \
+	1, \
+	"Enable/Disable action oui feature")
+
+/*
+ * <ini>
+ * gActionOUIConnect1x1 - Used to specify action OUIs for 1x1 connection
+ * @Default: 000C43 00 25 C2 001018 06 02FFF02C0000 BC 25 42 001018 06 02FF040C0000 BC 25 42 00037F 00 35 6C 001018 06 02FF009C0000 BC 25 48
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1 : 000C43
+ *   OUI data Len : 00
+ *   Info Mask : 25 - Check for NSS and Band
+ *   Capabilities: C2 - NSS == 2 && Band == 2G || Band == 5G
+ * OUI 2 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FFF02C0000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 25 - Check for NSS and Band
+ *   Capabilities: 42 - NSS == 2 && Band == 2G
+ * OUI 3 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FF040C0000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 25 - Check for NSS and Band
+ *   Capabilities: 42 - NSS == 2 && Band == 2G
+ * OUI 4 : 00037F
+ *   OUI data Len : 00
+ *   Info Mask : 35 - Check for NSS, VHT Caps and Band
+ *   Capabilities: 6C - (NSS == 3 or 4) && VHT Caps Preset && Band == 2G
+ * OUI 5 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FF009C0000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 25 - Check for NSS and Band
+ *   Capabilities: 48 - NSS == 4 && Band == 2G
+ *
+ * This ini is used to specify the AP OUIs with which only 1x1 connection
+ * is allowed.
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_CONNECT_1X1 CFG_INI_STRING( \
+	"gActionOUIConnect1x1", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"000C43 00 25 C2 001018 06 02FFF02C0000 BC 25 42 001018 06 02FF040C0000 BC 25 42 00037F 00 35 6C 001018 06 02FF009C0000 BC 25 48", \
+	"Used to specify action OUIs for 1x1 connection")
+
+/*
+ * <ini>
+ * gActionOUIITOExtension - Used to extend in-activity time for specified APs
+ * @Default: 00037F 06 01010000FF7F FC 01 000AEB 02 0100 C0 01 000B86 03 010408 E0 01
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1: 00037F
+ *   OUI data Len: 06
+ *   OUI Data: 01010000FF7F
+ *   OUI data Mask: FC - 11111100
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * OUI 2: 000AEB
+ *   OUI data Len: 02
+ *   OUI Data: 0100
+ *   OUI data Mask: C0 - 11000000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * OUI 3: 000B86
+ *   OUI data Len: 03
+ *   OUI Data: 010408
+ *   OUI data Mask: E0 - 11100000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * This ini is used to specify AP OUIs using which station's in-activity time
+ * can be extended with the respective APs
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_ITO_EXTENSION CFG_INI_STRING( \
+	"gActionOUIITOExtension", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"00037F 06 01010000FF7F FC 01 000AEB 02 0100 C0 01 000B86 03 010408 E0 01", \
+	"Used to extend in-activity time for specified APs")
+
+/*
+ * <ini>
+ * gActionOUICCKM1X1 - Used to specify action OUIs to control station's TX rates
+ *
+ * This ini is used to specify AP OUIs for which station's CCKM TX rates
+ * should be 1x1 only.
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_CCKM_1X1 CFG_INI_STRING( \
+	"gActionOUICCKM1X1", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"Used to specify action OUIs to control station's TX rates")
+
+/*
+ * <ini>
+ * gActionOUIITOAlternate - Used to specify action OUIs to have alternate ITO in
+ * weak RSSI state
+ *
+ * This ini is used to specify AP OUIs for which the stations will have
+ * alternate ITOs for the case when the RSSI is weak.
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_ITO_ALTERNATE CFG_INI_STRING( \
+	"gActionOUIITOAlternate", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"001018 06 0202001c0000 FC 01", \
+	"Used to specify action OUIs to have alternate ITO")
+
+/*
+ * <ini>
+ * gActionOUISwitchTo11nMode - Used to specify action OUIs for switching to 11n
+ *
+ * This ini is used to specify which AP for which the connection has to be
+ * made in 2x2 mode with HT capabilities only and not VHT.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1 : 00904C
+ *   OUI data Len : 03
+ *   OUI Data : 0418BF
+ *   OUI data Mask: E0 - 11100000
+ *   Info Mask : 21 - Check for Band
+ *   Capabilities: 40 - Band == 2G
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_SWITCH_TO_11N_MODE CFG_INI_STRING( \
+	"gActionOUISwitchTo11nMode", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"00904C 05 0418BF0CB2 F8 21 40", \
+	"Used to specify action OUIs for switching to 11n")
+
+/*
+ * <ini>
+ * gActionOUIConnect1x1with1TxRxChain - Used to specify action OUIs for
+ *					 1x1 connection with one Tx/Rx Chain
+ * @Default:
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FFF0040000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 21 - Check for Band
+ *   Capabilities: 40 - Band == 2G
+ *
+ * OUI 2 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FFF0050000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 21 - Check for Band
+ *   Capabilities: 40 - Band == 2G
+ *
+ * OUI 3 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FFF4050000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 21 - Check for Band
+ *   Capabilities: 40 - Band == 2G
+ *
+ * This ini is used to specify the AP OUIs with which only 1x1 connection
+ * with one Tx/Rx Chain is allowed.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN CFG_INI_STRING( \
+	 "gActionOUIConnect1x1with1TxRxChain", \
+	 0, \
+	 ACTION_OUI_MAX_STR_LEN, \
+	 "001018 06 02FFF0040000 BC 21 40 001018 06 02FFF0050000 BC 21 40 001018 06 02FFF4050000 BC 21 40", \
+	 "Used to specify action OUIs for 1x1 connection with one Tx/Rx Chain")
+
+/*
+ * <ini>
+ * gActionOUIDisableAggressiveTX - Used to specify action OUIs to disable
+ * Aggressive TX feature when operating in softap.
+ *
+ * @Default:
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs:
+ *
+ * OUI 1 : FFFFFF
+ *   OUI data Len : 00
+ *   OUI Data: No data
+ *   OUI data Mask: No data mask
+ *   Info Mask:  2A - Check for mac-addr, HT capability and Band
+ *   Mac-addr: F8:59:71:00:00:00 - first 3 bytes
+ *   Mac-mask: E0 - Match only first 3 bytes of peer mac-addr
+ *   Capabilities: 50 – HT should be enabled, and band should be 2.4GHz
+ *
+ * OUI 2 : FFFFFF
+ *   OUI data Len : 00
+ *   OUI Data: No data
+ *   OUI data Mask: No data mask
+ *   Info Mask:  2A - Check for mac-addr, HT capability and Band
+ *   Mac-addr: 14:AB:C5:00:00:00 - first 3 bytes
+ *   Mac-mask: E0 - Match only first 3 bytes of peer mac-addr
+ *   Capabilities: 50 – HT should be enabled, and band should be 2.4GHz
+ *
+ * When operating in Softap mode, this ini is used to specify
+ * STA (peer) OUIs/mac-addr for which aggressive tx is disabled after
+ * association is successful.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_DISABLE_AGGRESSIVE_TX CFG_INI_STRING( \
+	"gActionOUIDisableAggressiveTX", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"FFFFFF 00 2A F85971000000 E0 50 FFFFFF 00 2A 14ABC5000000 E0 50", \
+	"Used to specify action OUIs to disable aggressive TX")
+
+/*
+ * <ini>
+ * gActionOUIDisableAggressiveEDCA - Used to specify action OUIs to control
+ * EDCA configuration when join the candidate AP
+ *
+ * @Default: NULL
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * This ini is used to specify AP OUIs. The station's EDCA should follow the
+ * APs' when connecting to those AP, even if the gEnableEdcaParams is set.
+ * For example, it follows the AP's EDCA whose OUI is 0050F2 with the
+ * following setting:
+ *     gActionOUIDisableAggressiveEDCA=0050F2 00 01
+ *          Explain: 0050F2: OUI
+ *                   00: data length is 0
+ *                   01: info mask, only OUI present in Info mask
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableEdcaParams, gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_DISABLE_AGGRESSIVE_EDCA CFG_INI_STRING( \
+	"gActionOUIDisableAggressiveEDCA", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"Used to specify action OUIs to control edca configuration")
+
+/*
+ * <ini>
+ * gActionOUIExtendWowITO - Used to extend ITO(Inactivity Time-Out) value under
+ * WoWLAN mode for specified APs.
+ *
+ * @Default: NULL
+ *
+ * Some APs sometimes don't honor Qos null frames under WoWLAN mode if
+ * station's ITO is too small. This ini is used to specify AP OUIs which
+ * exhibit this behavior. When connected to such an AP, the station's ITO
+ * value will be extended when in WoWLAN mode.
+ * For example, it extends the ITO value(under WoWLAN mode) when connected
+ * to AP whose OUI is 001018 and vendor specific data is 0201009C0000 with
+ * the following setting:
+ *     gActionOUIExtendWowITO=001018 06 0201009C0000 FC 01
+ *         OUI: 001018
+ *         OUI data Len : 06
+ *         OUI Data : 0201009C0000
+ *         OUI data Mask: FC - 11111100
+ *         Info Mask : 01 - only OUI present in Info mask
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_EXTEND_WOW_ITO CFG_INI_STRING( \
+	"gActionOUIExtendWowITO", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"Used to extend inactivity time out under WoWLAN mode for specified APs")
+
+/*
+ * <ini>
+ * gActionOUIReconnAssocTimeout - Used to specify action OUIs to
+ * reconnect to same BSSID when wait for association response timeout
+ *
+ * This ini is used to specify AP OUIs. Some of AP doesn't response our
+ * first association request, but it would response our second association
+ * request. Add such OUI configuration INI to apply reconnect logic when
+ * association timeout happends with such AP.
+ * For default:
+ *     gActionOUIReconnAssocTimeout=00E04C 00 01
+ *          Explain: 00E04C: OUI
+ *                   00: data length is 0
+ *                   01: info mask, only OUI present in Info mask
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT CFG_INI_STRING( \
+	"gActionOUIReconnAssocTimeout", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"00E04C 00 01", \
+	"Used to specify action OUIs to reconnect when assoc timeout")
+
+/*
+ * <ini>
+ * gActionOUIDisableTWT - Used to specify action OUIs to control TWT param
+ * while joining the candidate AP
+ *
+ * This ini is used to specify AP OUIs. Some APs advertise TWT but do not
+ * follow through when the STA reaches out to them. Thus, TWT will be
+ * disabled when we receive OUIs of those APs.
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1: 001018
+ *   OUI data Len: 00
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * OUI 2: 000986
+ *   OUI data Len: 00
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * OUI 3: 000ce7
+ *   OUI data Len: 00
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * OUI 4: 00e0fc
+ *   OUI data Len: 00
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_DISABLE_TWT CFG_INI_STRING( \
+	"gActionOUIDisableTWT", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"001018 00 01 000986 00 01 000ce7 00 01 00e0fc 00 01", \
+	"Used to specify action OUIs to control TWT configuration")
+
+/*
+ * <ini>
+ * gActionOUITakeAllBandInfo - Used to specify action OUIs to check
+ * whether country ie need take all band channel information.
+ *
+ * This ini is used to specify STA association request OUIs. Some STA
+ * need AP country ie take all band channel information when do BSS
+ * transition across band. Thus, AP will take all band channel info
+ * when we receive association request with this OUIs.
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1: 0017f2
+ *   OUI data Len: 01
+ *   OUI Data : 0a
+ *   OUI data Mask: 80 - 10000000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_TAKE_ALL_BAND_INFO CFG_INI_STRING( \
+	"gActionOUITakeAllBandInfo", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"0017f2 01 0a 80 01", \
+	"Used to specify action OUIs to control country ie")
+
+/*
+ * <ini>
+ * g11be_oui_allow_list - Used to specify 802.11be allowed ap oui list
+ *
+ * This ini is used to specify AP OUIs for which station can connect
+ * in 802.11be mode with the 802.11be AP.
+ * If no OUI set, then allow STA to connect to All 802.11be AP in 802.11be
+ * mode.
+ * If INI is set to "ffffff 00 01", then STA is not allowed to connect to
+ * any AP in 802.11be mode.
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_11BE_ALLOW_LIST CFG_INI_STRING( \
+	"g11be_oui_allow_list", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"Used to specify 11be allowed ap oui list")
+
+/*
+ * <ini>
+ * gActionOUIDisableDynamicQosNullTxRate - Used to turn off FW's dynamic qos
+ * null tx rate feature if specific vendor OUI received in beacon
+ *
+ * Some APs sometimes don't honor Qos null frames with some specific rate.
+ * This ini will disable dynamic qos null tx rate feature for specified APs.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1: 00e04c
+ *   OUI data Len: 03
+ *   OUI Data : 020160
+ *   OUI data Mask: E0 - 11100000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * OUI 2: 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FF009C0000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 01 - only OUI present in Info mask
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_DISABLE_DYNAMIC_QOS_NULL_TX_RATE CFG_INI_STRING( \
+	"gActionOUIDisableDynamicQosNullTxRate", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"00e04c 03 020160 E0 01 001018 06 02FF009c0000 BC 01", \
+	"Used to turn off FW's dynamic qos null tx rate for specified APs")
+
+/*
+ * <ini>
+ * gActionOUIAuthAssoc6Mbps2GHz - Used to send auth/assoc req with 6 Mbps rate
+ * on 2.4 GHz for specified AP
+ *
+ * Some AP sometimes doesn't honor auth/assoc with CCK rate.
+ * This ini will provide 6 Mbps rate for auth/assoc in 2.4 GHz.
+ *
+ * Example OUIs: (All values in Hex)
+ * OUI 1: 000c43
+ *       OUI data Len: 04
+ *       OUI Data : 03000000
+ *       OUI data Mask: F0 - 11110000
+ *       Info Mask : 01 - only OUI present in Info mask
+ *
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_AUTH_ASSOC_6MBPS_2GHZ CFG_INI_STRING( \
+	"gActionOUIAuthAssoc6Mbps2GHz", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"send auth/assoc req with 6 Mbps rate on 2.4 GHz for specified APs")
+
+/*
+ * <ini>
+ * CFG_ACTION_OUI_DISABLE_BFORMEE - Used to disable SU/MU beamformee
+ * capability for specified AP with some conditions
+ *
+ * Example OUIs: (All values in Hex)
+ * OUI 1: 000c43
+ *       OUI data Len: 04
+ *       OUI Data : 03000000
+ *       OUI data Mask: F0 - 11110000
+ *       Info Mask : 01 - only OUI present in Info mask
+ *
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_DISABLE_BFORMEE CFG_INI_STRING( \
+	"gActionOUIDisableBFORMEE", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"disable SU/MU beamformee capability for specified AP")
+
+/*
+ * <ini>
+ * gActionOUIEnableCTS2SelfWithQoSNull - Used to enable CTS2SELF with QoS null
+ * frame for specified APs
+ *
+ * Sample OUIs: (All values in Hex)
+ * OUI 1: 000c43
+ *   OUI data Len: 04
+ *   OUI Data : 03000000
+ *   OUI data Mask: F0 - 11110000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * gActionOUIEnableCTS2SelfWithQoSNull=000c43 04 03000000 F0 01
+ *
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_ENABLE_CTS2SELF_WITH_QOS_NULL CFG_INI_STRING( \
+	"gActionOUIEnableCTS2SelfWithQoSNull", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"Used to enable CTS2SELF with QoS null frame for specified APs")
+
+/*
+ * <ini>
+ * g_action_oui_enable_cts_2_self - Used to enable CTS2SELF for specified APs
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1: 000C43
+ * OUI data Len: 04
+ * OUI Data : 07000000
+ * OUI data Mask: F0 - 11110000
+ * Info Mask : 21 - 0010 0001 Check for OUI and Band
+ * Capabilities: C0 - 1100 0000 Band == 2 GHz || Band == 5 GHz
+ *
+ * OUI 2 : 000C43
+ * OUI data Len : 04
+ * OUI Data : 03000000
+ * OUI data Mask: F0 - 11110000
+ * Info Mask : 21 - 0010 0001 Check for OUI and Band
+ * Capabilities: C0 - 1100 0000 Band == 2 GHz || Band == 5 GHz
+ *
+ * g_action_oui_enable_cts_2_self=000C43 04 07000000 F0 21 C0 000C43 04 03000000 F0 21 C0
+ *
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_ENABLE_CTS2SELF CFG_INI_STRING( \
+	"g_action_oui_enable_cts_2_self", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"000C43 04 07000000 F0 21 C0 000C43 04 03000000 F0 21 C0", \
+	"Used to enable CTS2SELF frame for specified APs")
+
+/*
+ * <ini>
+ * gActionOUISendSMPSFrameWithOMN - Used to send SMPS frame along with OMN
+ * for specified APs
+ *
+ * Sample OUIs: (All values in Hex)
+ * OUI 1: 000ce7
+ *   OUI data Len: 04
+ *   OUI Data : 88000000
+ *   OUI data Mask: F0 - 11110000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * gActionOUISendSMPSFrameWithOMN=000ce7 04 88000000 F0 01
+ *
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_SEND_SMPS_FRAME_WITH_OMN CFG_INI_STRING( \
+	"gActionOUISendSMPSFrameWithOMN", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"Used to send SMPS frame along with OMN for specified APs")
+
+/*
+ * <ini>
+ * gActionOUIRestrictMaxMLOLinks - Used to downgrade 3 link to 2 link ML
+ * connection for specific AP build version.
+ *
+ * Sample OUIs: (All values in Hex)
+ * OUI 3 : 8CFDF0
+ *   OUI data Len : 13
+ *   OUI Data : 040000494c510302097201cb17000009110000
+ *   OUI data Mask: FFFFE0 - 1111 1111 1111 1111 1110 0000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * gActionOUIRestrictMaxMLOLinks=8CFDF0 13 040000494c510c00203000cb17000009110000 FFFFE0 01
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_RESTRICT_MAX_MLO_LINKS CFG_INI_STRING( \
+	"gActionOUIRestrictMaxMLOLinks", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"8CFDF0 13 040000494c510302097201cb17000009110000 FFFFE0 01", \
+	"To restrict matching OUI APs to two link connection at max")
+
+/*
+ * <ini>
+ * CFG_ACTION_OUI_LIMIT_BW - Used to limit BW for specified AP
+ *
+ * Example OUIs: (All values in Hex)
+ * OUI 1: 00904c
+ *       OUI data Len: 04
+ *       OUI Data : 0201009C
+ *       OUI data Mask: F0 - 11110000
+ *       Info Mask : 01 - only OUI present in Info mask
+ *
+ * Refer to gEnableActionOUI for more detail about the format.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_LIMIT_BW CFG_INI_STRING( \
+	"gActionOUILimitBW", \
+	0, \
+	ACTION_OUI_MAX_STR_LEN, \
+	"", \
+	"Limit BW for specified AP")
+
+#define CFG_ACTION_OUI \
+	CFG(CFG_ACTION_OUI_CCKM_1X1) \
+	CFG(CFG_ACTION_OUI_CONNECT_1X1) \
+	CFG(CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN) \
+	CFG(CFG_ACTION_OUI_ITO_ALTERNATE) \
+	CFG(CFG_ACTION_OUI_ITO_EXTENSION) \
+	CFG(CFG_ACTION_OUI_DISABLE_AGGRESSIVE_TX) \
+	CFG(CFG_ACTION_OUI_DISABLE_AGGRESSIVE_EDCA) \
+	CFG(CFG_ACTION_OUI_EXTEND_WOW_ITO) \
+	CFG(CFG_ACTION_OUI_SWITCH_TO_11N_MODE) \
+	CFG(CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT) \
+	CFG(CFG_ACTION_OUI_DISABLE_TWT) \
+	CFG(CFG_ACTION_OUI_TAKE_ALL_BAND_INFO) \
+	CFG(CFG_ACTION_OUI_11BE_ALLOW_LIST) \
+	CFG(CFG_ACTION_OUI_DISABLE_DYNAMIC_QOS_NULL_TX_RATE) \
+	CFG(CFG_ACTION_OUI_ENABLE_CTS2SELF) \
+	CFG(CFG_ACTION_OUI_ENABLE_CTS2SELF_WITH_QOS_NULL) \
+	CFG(CFG_ACTION_OUI_RESTRICT_MAX_MLO_LINKS) \
+	CFG(CFG_ACTION_OUI_SEND_SMPS_FRAME_WITH_OMN) \
+	CFG(CFG_ACTION_OUI_AUTH_ASSOC_6MBPS_2GHZ) \
+	CFG(CFG_ACTION_OUI_DISABLE_BFORMEE) \
+	CFG(CFG_ACTION_OUI_LIMIT_BW) \
+	CFG(CFG_ENABLE_ACTION_OUI)
+#endif

+ 260 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h

@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Declare structs and macros which can be accessed by various
+ * components and modules.
+ */
+
+#ifndef _WLAN_ACTION_OUI_PUBLIC_STRUCT_H_
+#define _WLAN_ACTION_OUI_PUBLIC_STRUCT_H_
+
+#include <wlan_cmn.h>
+#include <qdf_status.h>
+#include <qdf_types.h>
+
+/*
+ * Maximum ini string length of actions oui extensions,
+ * (n * 83) + (n - 1) spaces + 1 (terminating character),
+ * where n is the no of oui extensions
+ * currently, max no of oui extensions is 10
+ */
+#define ACTION_OUI_MAX_STR_LEN 840
+
+/*
+ * Maximum number of action oui extensions supported in
+ * each action oui category
+ */
+#define ACTION_OUI_MAX_EXTENSIONS 10
+
+/*
+ * Firmware allocates memory for the extensions only during init time.
+ * Therefore, inaddition to the total extensions configured during
+ * init time, driver has to add extra space to allow runtime extensions.
+ *
+ * Example: ACTION_OUI_11BE_OUI_ALLOW
+ *
+ * Max. value should be increased with the addition of new runtime extensions.
+ */
+#define ACTION_OUI_MAX_ADDNL_EXTENSIONS 10
+
+#define ACTION_OUI_MAX_OUI_LENGTH 5
+#define ACTION_OUI_MAX_DATA_LENGTH 20
+#define ACTION_OUI_MAX_DATA_MASK_LENGTH 3
+#define ACTION_OUI_MAC_MASK_LENGTH 1
+#define ACTION_OUI_MAX_CAPABILITY_LENGTH 1
+
+/*
+ * NSS Mask and NSS Offset to extract NSS info from
+ * capability field of action oui extension
+ */
+#define ACTION_OUI_CAPABILITY_NSS_MASK 0x0f
+#define ACTION_OUI_CAPABILITY_NSS_OFFSET 0
+#define ACTION_OUI_CAPABILITY_NSS_MASK_1X1 1
+#define ACTION_OUI_CAPABILITY_NSS_MASK_2X2 2
+#define ACTION_OUI_CAPABILITY_NSS_MASK_3X3 4
+#define ACTION_OUI_CAPABILITY_NSS_MASK_4X4 8
+
+/*
+ * Mask and offset to extract HT and VHT info from
+ * capability field of action oui extension
+ */
+#define ACTION_OUI_CAPABILITY_HT_ENABLE_MASK 0x10
+#define ACTION_OUI_CAPABILITY_HT_ENABLE_OFFSET 4
+#define ACTION_OUI_CAPABILITY_VHT_ENABLE_MASK 0x20
+#define ACTION_OUI_CAPABILITY_VHT_ENABLE_OFFSET 5
+
+/*
+ * Mask and offset to extract Band (2G and 5G) info from
+ * capability field of action oui extension
+ */
+#define ACTION_OUI_CAPABILITY_BAND_MASK 0xC0
+#define ACTION_OUI_CAPABILITY_BAND_OFFSET 6
+#define ACTION_OUI_CAPABILITY_2G_BAND_MASK 0x40
+#define ACTION_OUI_CAPABILITY_2G_BAND_OFFSET 6
+#define ACTION_CAPABILITY_5G_BAND_MASK 0x80
+#define ACTION_CAPABILITY_5G_BAND_OFFSET 7
+
+/* Invalid OUI ID action */
+#define ACTION_OUI_INVALID "ffffff 00 01"
+
+/**
+ * enum action_oui_id - to identify type of action oui
+ * @ACTION_OUI_CONNECT_1X1: for 1x1 connection only
+ * @ACTION_OUI_ITO_EXTENSION: for extending inactivity time of station
+ * @ACTION_OUI_CCKM_1X1: for TX with CCKM 1x1 only
+ * @ACTION_OUI_ITO_ALTERNATE: alternate ITO extensions used by firmware
+ * @ACTION_OUI_SWITCH_TO_11N_MODE: connect in 11n
+ * @ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN: connect in 1x1 & disable diversity gain
+ * @ACTION_OUI_DISABLE_AGGRESSIVE_TX: disable aggressive TX in firmware
+ * @ACTION_OUI_DISABLE_AGGRESSIVE_EDCA: disable aggressive EDCA with the ap
+ * @ACTION_OUI_DISABLE_TWT: disable TWT with the ap
+ * @ACTION_OUI_EXTEND_WOW_ITO: extend ITO under WOW mode if vendor OUI is
+ * received in beacon.
+ * @ACTION_OUI_11BE_OUI_ALLOW: ap oui for which station can connect with
+ * 11be mode
+ * @ACTION_OUI_DISABLE_DYNAMIC_QOS_NULL_TX_RATE: Turn off FW's dynamic qos
+ * null tx rate feature if specific vendor OUI received in beacon
+ * @ACTION_OUI_ENABLE_CTS2SELF_WITH_QOS_NULL: Enable CTS2SELF with QoS null
+ * frame for specified IoT APs.
+ * @ACTION_OUI_SEND_SMPS_FRAME_WITH_OMN: Send SMPS frame along with OMN
+ * frame for specified IoT APs.
+ * @ACTION_OUI_HOST_ONLY: host only action id start - placeholder.
+ * New Firmware related "ACTION" needs to be added before this placeholder.
+ * @ACTION_OUI_HOST_RECONN: reconnect to the same BSSID when wait for
+ * association response timeout from AP
+ * @ACTION_OUI_TAKE_ALL_BAND_INFO: let AP country ie take all band info
+ * @ACTION_OUI_AUTH_ASSOC_6MBPS_2GHZ: send auth/assoc req with 6 Mbps rate
+ * on 2.4 GHz
+ * @ACTION_OUI_DISABLE_BFORMEE: disable SU/MU beam formee capability for
+ * specified AP
+ * @ACTION_OUI_ENABLE_CTS2SELF: enable cts to self for specified AP's
+ * @ACTION_OUI_RESTRICT_MAX_MLO_LINKS: Downgrade MLO if particular AP
+ *                                     build present.
+ * @ACTION_OUI_LIMIT_BW: Limit BW if vendor OUI is received in beacon.
+ * @ACTION_OUI_MAXIMUM_ID: maximum number of action oui types
+ */
+enum action_oui_id {
+	ACTION_OUI_CONNECT_1X1 = 0,
+	ACTION_OUI_ITO_EXTENSION = 1,
+	ACTION_OUI_CCKM_1X1 = 2,
+	ACTION_OUI_ITO_ALTERNATE = 3,
+	ACTION_OUI_SWITCH_TO_11N_MODE = 4,
+	ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN = 5,
+	ACTION_OUI_DISABLE_AGGRESSIVE_TX = 6,
+	ACTION_OUI_DISABLE_TWT = 7,
+	ACTION_OUI_EXTEND_WOW_ITO = 8,
+	ACTION_OUI_11BE_OUI_ALLOW = 9,
+	ACTION_OUI_DISABLE_DYNAMIC_QOS_NULL_TX_RATE = 10,
+	ACTION_OUI_ENABLE_CTS2SELF_WITH_QOS_NULL = 11,
+	ACTION_OUI_SEND_SMPS_FRAME_WITH_OMN = 12,
+	/* host&fw interface add above here */
+
+	ACTION_OUI_HOST_ONLY,
+	ACTION_OUI_HOST_RECONN = ACTION_OUI_HOST_ONLY,
+	ACTION_OUI_TAKE_ALL_BAND_INFO,
+	ACTION_OUI_AUTH_ASSOC_6MBPS_2GHZ,
+	ACTION_OUI_DISABLE_BFORMEE,
+	ACTION_OUI_DISABLE_AGGRESSIVE_EDCA,
+	ACTION_OUI_ENABLE_CTS2SELF,
+	ACTION_OUI_RESTRICT_MAX_MLO_LINKS,
+	ACTION_OUI_LIMIT_BW,
+	ACTION_OUI_MAXIMUM_ID
+};
+
+/**
+ * enum action_oui_info - to indicate presence of various action OUI
+ * fields in action oui extension, following identifiers are to be set in
+ * the info mask field of action oui extension
+ * @ACTION_OUI_INFO_OUI: to indicate presence of OUI string
+ * @ACTION_OUI_INFO_MAC_ADDRESS: to indicate presence of mac address
+ * @ACTION_OUI_INFO_AP_CAPABILITY_NSS: to indicate presence of nss info
+ * @ACTION_OUI_INFO_AP_CAPABILITY_HT: to indicate presence of HT cap
+ * @ACTION_OUI_INFO_AP_CAPABILITY_VHT: to indicate presence of VHT cap
+ * @ACTION_OUI_INFO_AP_CAPABILITY_BAND: to indicate presence of band info
+ */
+enum action_oui_info {
+	/*
+	 * OUI centric parsing, expect OUI in each action OUI extension,
+	 * hence, ACTION_OUI_INFO_OUI is dummy
+	 */
+	ACTION_OUI_INFO_OUI = 1 << 0,
+	ACTION_OUI_INFO_MAC_ADDRESS = 1 << 1,
+	ACTION_OUI_INFO_AP_CAPABILITY_NSS = 1 << 2,
+	ACTION_OUI_INFO_AP_CAPABILITY_HT = 1 << 3,
+	ACTION_OUI_INFO_AP_CAPABILITY_VHT = 1 << 4,
+	ACTION_OUI_INFO_AP_CAPABILITY_BAND = 1 << 5,
+};
+
+/* Total mask of all enum action_oui_info IDs */
+#define ACTION_OUI_INFO_MASK 0x3F
+
+/**
+ * struct action_oui_extension - action oui extension contents
+ * @info_mask: info mask
+ * @oui_length: length of the oui, either 3 or 5 bytes
+ * @data_length: length of the oui data
+ * @data_mask_length: length of the data mask
+ * @mac_addr_length: length of the mac addr
+ * @mac_mask_length: length of the mac mask
+ * @capability_length: length of the capability
+ * @oui: oui value
+ * @data: data buffer
+ * @data_mask: data mask buffer
+ * @mac_addr: mac addr
+ * @mac_mask: mac mask
+ * @capability: capability buffer
+ */
+struct action_oui_extension {
+	uint32_t info_mask;
+	uint32_t oui_length;
+	uint32_t data_length;
+	uint32_t data_mask_length;
+	uint32_t mac_addr_length;
+	uint32_t mac_mask_length;
+	uint32_t capability_length;
+	uint8_t oui[ACTION_OUI_MAX_OUI_LENGTH];
+	uint8_t data[ACTION_OUI_MAX_DATA_LENGTH];
+	uint8_t data_mask[ACTION_OUI_MAX_DATA_MASK_LENGTH];
+	uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+	uint8_t mac_mask[ACTION_OUI_MAC_MASK_LENGTH];
+	uint8_t capability[ACTION_OUI_MAX_CAPABILITY_LENGTH];
+};
+
+/**
+ * struct action_oui_request - Contains specific action oui information
+ * @action_id: type of action from enum action_oui_info
+ * @no_oui_extensions: number of action oui extensions of type @action_id
+ * @total_no_oui_extensions: total no of oui extensions from all
+ * action oui types, this is just a total count needed by firmware
+ * @extension: pointer to zero length array, to indicate this structure is
+ * followed by a array of @no_oui_extensions structures of
+ * type struct action_oui_extension
+ */
+struct action_oui_request {
+	enum action_oui_id action_id;
+	uint32_t no_oui_extensions;
+	uint32_t total_no_oui_extensions;
+	struct action_oui_extension extension[];
+};
+
+/**
+ * struct action_oui_search_attr - Used to check against action_oui ini input
+ *
+ * @ie_data: beacon ie data
+ * @ie_length: length of ie data
+ * @mac_addr: bssid of access point
+ * @nss: AP spatial stream info
+ * @ht_cap: Whether AP is HT capable
+ * @vht_cap: Whether AP is VHT capable
+ * @enable_2g: Whether 2.4GHz band is enabled in AP
+ * @enable_5g: Whether 5GHz band is enabled in AP
+ */
+struct action_oui_search_attr {
+	uint8_t *ie_data;
+	uint32_t ie_length;
+	uint8_t *mac_addr;
+	uint32_t nss;
+	bool ht_cap;
+	bool vht_cap;
+	bool enable_2g;
+	bool enable_5g;
+};
+
+#endif /* _WLAN_ACTION_OUI_PUBLIC_STRUCT_H_ */

+ 51 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/inc/wlan_action_oui_tgt_api.h

@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * DOC: Declare public API for action_oui to interact with target/WMI
+ */
+
+#ifndef _WLAN_ACTION_OUI_TGT_API_H_
+#define _WLAN_ACTION_OUI_TGT_API_H_
+
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_objmgr.h"
+
+#define GET_ACTION_OUI_TX_OPS_FROM_PSOC(psoc) \
+	(&action_oui_psoc_get_priv(psoc)->tx_ops)
+
+/**
+ * tgt_action_oui_send() - Send request to target if
+ * @psoc: objmgr psoc object
+ * @req: action_oui request to be send
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_action_oui_send(struct wlan_objmgr_psoc *psoc,
+				struct action_oui_request *req);
+
+/**
+ * struct action_oui_tx_ops - structure of tx operations
+ * @send_req: Pointer to hold target_if send function
+ */
+struct action_oui_tx_ops {
+	QDF_STATUS (*send_req)(struct wlan_objmgr_psoc *psoc,
+			       struct action_oui_request *req);
+};
+
+#endif /* _WLAN_ACTION_OUI_TGT_API_H_ */

+ 331 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/inc/wlan_action_oui_ucfg_api.h

@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Declare public API related to the action_oui called by north bound
+ * HDD/OSIF/LIM
+ */
+
+#ifndef _WLAN_ACTION_OUI_UCFG_API_H_
+#define _WLAN_ACTION_OUI_UCFG_API_H_
+
+#include <qdf_status.h>
+#include <qdf_types.h>
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_objmgr.h"
+
+#ifdef WLAN_FEATURE_ACTION_OUI
+
+/**
+ * ucfg_action_oui_init() - Register notification handlers.
+ *
+ * This function registers action_oui notification handlers which are
+ * invoked from psoc create/destroy handlers.
+ *
+ * Return: For successful registration - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+QDF_STATUS ucfg_action_oui_init(void);
+
+/**
+ * ucfg_action_oui_deinit() - Unregister notification handlers.
+ *
+ * This function Unregisters action_oui notification handlers which are
+ * invoked from psoc create/destroy handlers.
+ *
+ * Return: None
+ */
+void ucfg_action_oui_deinit(void);
+
+/**
+ * ucfg_action_oui_psoc_enable() - Notify action oui psoc enable
+ * @psoc: psoc object
+ *
+ * Return: None
+ */
+void ucfg_action_oui_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_action_oui_psoc_disable() - Notify action oui psoc disable
+ * @psoc: psoc object
+ *
+ * Return: None
+ */
+void ucfg_action_oui_psoc_disable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_action_oui_parse() - Parse input string and extract extensions.
+ * @psoc: objmgr psoc object
+ * @in_str: input string to be parsed
+ * @action_id: action to which given string corresponds
+ *
+ * This is a wrapper function which invokes internal function
+ * action_oui_extract() to extract OUIs and related attributes.
+ *
+ * Return: For successful parse - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+QDF_STATUS
+ucfg_action_oui_parse(struct wlan_objmgr_psoc *psoc,
+		      const uint8_t *in_str,
+		      enum action_oui_id action_id);
+
+/**
+ * ucfg_action_oui_send() - Send action_oui and related attributes to Fw.
+ * @psoc: objmgr psoc object
+ *
+ * This is a wrapper function which invokes internal function
+ * action_oui_send() to send OUIs and related attributes to firmware.
+ *
+ * Return: For successful send - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+QDF_STATUS ucfg_action_oui_send(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_action_oui_enabled() - State of action_oui component
+ * @psoc: psoc object
+ *
+ * Return: True if action oui is enabled
+ */
+bool ucfg_action_oui_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_action_oui_search() - Check for OUIs and related info in IE data.
+ * @psoc: objmgr psoc object
+ * @attr: pointer to structure containing type of action, beacon IE data etc.,
+ * @action_id: type of action to be checked
+ *
+ * This is a wrapper function which invokes internal function to search
+ * for OUIs and related info (specified from ini file) in vendor specific
+ * data of beacon IE for given action.
+ *
+ * Return: If search is successful return true else false.
+ */
+bool ucfg_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id);
+
+/**
+ * ucfg_action_oui_cleanup() - Remove all in existing oui entry.
+ * @psoc: objmgr psoc object
+ * @action_id: type of action to be removed
+ *
+ * This is a wrapper function which invokes internal function to remove
+ * all the existing oui entry.
+ *
+ * Return: QDF_STATUS_SUCCESS If remove is successful.
+ */
+QDF_STATUS
+ucfg_action_oui_cleanup(struct wlan_objmgr_psoc *psoc,
+			enum action_oui_id action_id);
+
+/**
+ * ucfg_action_oui_send_by_id() - Send action oui for action id
+ * @psoc: objmgr psoc object
+ * @id: type of action to be sent
+ *
+ * This is a wrapper function which invokes internal function to send
+ * action oui entry to firmware.
+ *
+ * Return: QDF_STATUS_SUCCESS If sending is successful.
+ */
+QDF_STATUS ucfg_action_oui_send_by_id(struct wlan_objmgr_psoc *psoc,
+				      enum action_oui_id id);
+
+/**
+ * ucfg_action_oui_get_config() - Get current action INI config
+ * @psoc: objmgr psoc object
+ * @action_id: type of action to get
+ *
+ * Return: config string.
+ */
+uint8_t *
+ucfg_action_oui_get_config(struct wlan_objmgr_psoc *psoc,
+			   enum action_oui_id action_id);
+#else
+
+/**
+ * ucfg_action_oui_init() - Register notification handlers.
+ *
+ * This function registers action_oui notification handlers which are
+ * invoked from psoc create/destroy handlers.
+ *
+ * Return: For successful registration - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+static inline
+QDF_STATUS ucfg_action_oui_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_action_oui_deinit() - Unregister notification handlers.
+ *
+ * This function Unregisters action_oui notification handlers which are
+ * invoked from psoc create/destroy handlers.
+ *
+ * Return: None
+ */
+static inline
+void ucfg_action_oui_deinit(void)
+{
+}
+
+/**
+ * ucfg_action_oui_psoc_enable() - Notify action oui psoc enable
+ * @psoc: psoc object
+ *
+ * Return: None
+ */
+static inline
+void ucfg_action_oui_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+/**
+ * ucfg_action_oui_psoc_disable() - Notify action oui psoc disable
+ * @psoc: psoc object
+ *
+ * Return: None
+ */
+static inline
+void ucfg_action_oui_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+/**
+ * ucfg_action_oui_parse() - Parse input string of action_id specified.
+ * @psoc: objmgr psoc object
+ * @in_str: input string to be parsed
+ * @action_id: action to which given string corresponds
+ *
+ * This is a wrapper function which invokes internal function
+ * action_oui_extract() to extract OUIs and related attributes.
+ *
+ * Return: For successful parse - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+static inline QDF_STATUS
+ucfg_action_oui_parse(struct wlan_objmgr_psoc *psoc,
+		      const uint8_t *in_str,
+		      enum action_oui_id action_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_action_oui_send() - Send action_oui and related attributes to Fw.
+ * @psoc: objmgr psoc object
+ *
+ * This is a wrapper function which invokes internal function
+ * action_oui_send() to send OUIs and related attributes to firmware.
+ *
+ * Return: For successful send - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+static inline
+QDF_STATUS ucfg_action_oui_send(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_action_oui_enabled() - State of action_oui component
+ *
+ * Return: When action_oui component is present return true
+ *	   else return false.
+ */
+static inline bool ucfg_action_oui_enabled(void)
+{
+	return false;
+}
+
+/**
+ * ucfg_action_oui_search() - Check for OUIs and related info in IE data.
+ * @psoc: objmgr psoc object
+ * @attr: pointer to structure containing type of action, beacon IE data etc.,
+ * @action_id: type of action to be checked
+ *
+ * This is a wrapper function which invokes internal function to search
+ * for OUIs and related info (specified from ini file) in vendor specific
+ * data of beacon IE for given action.
+ *
+ * Return: If search is successful return true else false.
+ */
+static inline
+bool ucfg_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id)
+{
+	return false;
+}
+
+/**
+ * ucfg_action_oui_cleanup() - Remove all of existing oui entry
+ * @psoc: objmgr psoc object
+ * @action_id: type of action to be removed
+ *
+ * This is a wrapper function which invokes internal function to remove
+ * all the existing oui entry.
+ *
+ * Return: QDF_STATUS_SUCCESS If remove is successful.
+ */
+static inline
+QDF_STATUS
+ucfg_action_oui_cleanup(struct wlan_objmgr_psoc *psoc,
+			enum action_oui_id action_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_action_oui_send_by_id() - Send action oui for action id
+ * @psoc: objmgr psoc object
+ * @id: type of action to be sent
+ *
+ * This is a wrapper function which invokes internal function to send
+ * action oui entry to firmware.
+ *
+ * Return: QDF_STATUS_SUCCESS If sending is successful.
+ */
+static inline
+QDF_STATUS ucfg_action_oui_send_by_id(struct wlan_objmgr_psoc *psoc,
+				      enum action_oui_id id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_action_oui_get_config() - Get current action INI config
+ * @psoc: objmgr psoc object
+ * @action_id: type of action to get
+ *
+ * Return: config string.
+ */
+static inline uint8_t *
+ucfg_action_oui_get_config(struct wlan_objmgr_psoc *psoc,
+			   enum action_oui_id action_id)
+{
+	return "";
+}
+#endif /* WLAN_FEATURE_ACTION_OUI */
+
+#endif /* _WLAN_ACTION_OUI_UCFG_API_H_ */

+ 43 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/src/wlan_action_oui_tgt_api.c

@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * DOC: Implements public API for action_oui to interact with target/WMI
+ */
+
+#include "wlan_action_oui_tgt_api.h"
+#include "wlan_action_oui_main.h"
+#include "wlan_action_oui_public_struct.h"
+
+QDF_STATUS tgt_action_oui_send(struct wlan_objmgr_psoc *psoc,
+			       struct action_oui_request *req)
+{
+	struct action_oui_tx_ops *tx_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	ACTION_OUI_ENTER();
+
+	tx_ops = GET_ACTION_OUI_TX_OPS_FROM_PSOC(psoc);
+	QDF_ASSERT(tx_ops->send_req);
+	if (tx_ops->send_req)
+		status = tx_ops->send_req(psoc, req);
+
+	ACTION_OUI_EXIT();
+
+	return status;
+}

+ 233 - 0
qcom/opensource/wlan/qcacld-3.0/components/action_oui/dispatcher/src/wlan_action_oui_ucfg_api.c

@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2012-2018, 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Public API implementation of action_oui called by north bound HDD/OSIF.
+ */
+
+#include "wlan_action_oui_ucfg_api.h"
+#include "wlan_action_oui_main.h"
+#include "target_if_action_oui.h"
+#include "wlan_action_oui_tgt_api.h"
+#include <qdf_str.h>
+
+QDF_STATUS ucfg_action_oui_init(void)
+{
+	QDF_STATUS status;
+
+	ACTION_OUI_ENTER();
+
+	status = wlan_objmgr_register_psoc_create_handler(
+				WLAN_UMAC_COMP_ACTION_OUI,
+				action_oui_psoc_create_notification, NULL);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		action_oui_err("Failed to register psoc create handler");
+		goto exit;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+				WLAN_UMAC_COMP_ACTION_OUI,
+				action_oui_psoc_destroy_notification, NULL);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		action_oui_debug("psoc create/delete notifications registered");
+		goto exit;
+	}
+
+	action_oui_err("Failed to register psoc delete handler");
+	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_ACTION_OUI,
+			action_oui_psoc_create_notification, NULL);
+
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+void ucfg_action_oui_deinit(void)
+{
+	QDF_STATUS status;
+
+	ACTION_OUI_ENTER();
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+				WLAN_UMAC_COMP_ACTION_OUI,
+				action_oui_psoc_create_notification, NULL);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_err("Failed to unregister psoc create handler");
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+				WLAN_UMAC_COMP_ACTION_OUI,
+				action_oui_psoc_destroy_notification,
+				NULL);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_err("Failed to unregister psoc delete handler");
+
+	ACTION_OUI_EXIT();
+}
+
+void ucfg_action_oui_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	action_oui_psoc_enable(psoc);
+}
+
+void ucfg_action_oui_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	action_oui_psoc_disable(psoc);
+}
+
+bool ucfg_action_oui_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		return false;
+	}
+
+	return psoc_priv->action_oui_enable;
+}
+
+uint8_t *
+ucfg_action_oui_get_config(struct wlan_objmgr_psoc *psoc,
+			   enum action_oui_id action_id)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		return "";
+	}
+	if (action_id >= ACTION_OUI_MAXIMUM_ID) {
+		action_oui_err("Invalid action_oui id: %u", action_id);
+		return "";
+	}
+
+	return psoc_priv->action_oui_str[action_id];
+}
+
+
+QDF_STATUS
+ucfg_action_oui_parse(struct wlan_objmgr_psoc *psoc,
+		      const uint8_t *in_str,
+		      enum action_oui_id action_id)
+{
+	return action_oui_parse_string(psoc, in_str, action_id);
+}
+
+QDF_STATUS
+ucfg_action_oui_cleanup(struct wlan_objmgr_psoc *psoc,
+			enum action_oui_id action_id)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	ACTION_OUI_ENTER();
+
+	if (action_id >= ACTION_OUI_MAXIMUM_ID) {
+		action_oui_err("Invalid action_oui id: %u", action_id);
+		goto exit;
+	}
+
+	if (!psoc) {
+		action_oui_err("psoc is NULL");
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	status = wlan_action_oui_cleanup(psoc_priv, action_id);
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+QDF_STATUS ucfg_action_oui_send(struct wlan_objmgr_psoc *psoc)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint32_t id;
+
+	if (!psoc) {
+		action_oui_err("psoc is NULL");
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
+		if (id >= ACTION_OUI_HOST_ONLY)
+			continue;
+		status = action_oui_send(psoc_priv, id);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			action_oui_debug("Failed to send: %u", id);
+	}
+
+exit:
+	return status;
+}
+
+QDF_STATUS ucfg_action_oui_send_by_id(struct wlan_objmgr_psoc *psoc,
+				      enum action_oui_id id)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	ACTION_OUI_ENTER();
+
+	if (!psoc) {
+		action_oui_err("psoc is NULL");
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	if (id >= ACTION_OUI_HOST_ONLY) {
+		action_oui_err("id %d not for firmware", id);
+		status = QDF_STATUS_SUCCESS;
+		goto exit;
+	}
+
+	status = action_oui_send(psoc_priv, id);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_debug("Failed to send: %u", id);
+exit:
+	ACTION_OUI_EXIT();
+
+	return status;
+}
+
+bool ucfg_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id)
+{
+	return wlan_action_oui_search(psoc, attr, action_id);
+}

+ 74 - 0
qcom/opensource/wlan/qcacld-3.0/components/cfg/cfg_all.h

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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 "cfg_policy_mgr.h"
+#include "cfg_define.h"
+#include "cfg_converged.h"
+#include "cfg_mlme.h"
+#include "cfg_fwol.h"
+#include "cfg_ipa.h"
+
+#ifdef CONVERGED_P2P_ENABLE
+#include "cfg_p2p.h"
+#else
+#define CFG_P2P_ALL
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+#include "cfg_tdls.h"
+#else
+#define CFG_TDLS_ALL
+#endif
+
+#ifdef WLAN_FEATURE_NAN
+#include "cfg_nan.h"
+#else
+#define CFG_NAN_ALL
+#endif
+
+#include "cfg_ftm_time_sync.h"
+
+#include "wlan_pmo_cfg.h"
+#include "wlan_dp_cfg.h"
+#include "hdd_config.h"
+#include "hdd_dp_cfg.h"
+#include "cfg_legacy_dp.h"
+#include "cfg_dlm.h"
+#include "cfg_pkt_capture.h"
+#include "wlan_action_oui_cfg.h"
+
+/* Maintain Alphabetic order here while adding components */
+#define CFG_ALL \
+	CFG_DENYLIST_MGR_ALL \
+	CFG_CONVERGED_ALL \
+	CFG_FWOL_ALL \
+	CFG_POLICY_MGR_ALL \
+	CFG_HDD_ALL \
+	CFG_HDD_DP_ALL \
+	CFG_DP_ALL \
+	CFG_LEGACY_DP_ALL \
+	CFG_MLME_ALL \
+	CFG_NAN_ALL \
+	CFG_P2P_ALL \
+	CFG_PMO_ALL \
+	CFG_TDLS_ALL \
+	CFG_PKT_CAPTURE_MODE_ALL \
+	CFG_TIME_SYNC_FTM_ALL \
+	CFG_ACTION_OUI
+

+ 199 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/interface_mgr/inc/wlan_if_mgr_roam.h

@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains interface manager public api
+ */
+
+#ifndef _WLAN_IF_MGR_ROAM_H_
+#define _WLAN_IF_MGR_ROAM_H_
+
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_if_mgr_public_struct.h"
+#include "wlan_if_mgr_roam.h"
+
+/**
+ * struct change_roam_state_arg - Contains roam state arguments
+ * @requestor: Driver disabled roaming requestor
+ * @curr_vdev_id: virtual device ID
+ *
+ * This structure is used to pass the roam state change information to the
+ * callback
+ */
+struct change_roam_state_arg {
+	enum wlan_cm_rso_control_requestor requestor;
+	uint8_t curr_vdev_id;
+};
+
+/**
+ * struct bssid_search_arg - Contains candidate validation arguments
+ * @peer_addr: MAC address of the BSS
+ * @vdev_id: virtual device ID
+ *
+ * This structure is used to pass the candidate validation information to the
+ * callback
+ */
+struct bssid_search_arg {
+	struct qdf_mac_addr peer_addr;
+	uint8_t vdev_id;
+};
+
+/**
+ * enum allow_mcc_go_diff_bi_definition - Defines the config values for allowing
+ * different beacon intervals between P2P-G0 and STA
+ * @ALLOW_MCC_GO_DIFF_BI_WFA_CERT: GO Beacon interval is not changed.
+ *	MCC GO doesn't work well in optimized way. In worst scenario, it may
+ *	invite STA disconnection.
+ * @ALLOW_MCC_GO_DIFF_BI_WORKAROUND: Workaround 1 disassoc all the clients and
+ *	update beacon Interval.
+ * @ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN: Tear down the P2P link in
+ *	auto/Non-autonomous -GO case.
+ * @ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT: Don't disconnect the P2P client in
+ *	autonomous/Non-autonomous -GO case update the BI dynamically
+ */
+enum allow_mcc_go_diff_bi_definition {
+	ALLOW_MCC_GO_DIFF_BI_WFA_CERT = 1,
+	ALLOW_MCC_GO_DIFF_BI_WORKAROUND,
+	ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN,
+	ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT,
+};
+
+/**
+ * struct beacon_interval_arg - Contains beacon interval validation arguments
+ * @curr_vdev_id: current iterator vdev ID
+ * @curr_bss_opmode: current iterator BSS's opmode
+ * @ch_freq: current operating channel frequency
+ * @bss_beacon_interval: beacon interval that can be updated by callee
+ * @status: status to be filled by callee
+ * @is_done: boolean to stop iterating
+ * @update_beacon_interval: boolean to mark beacon interval as updated by callee
+ *
+ * This structure is used to pass the candidate validation information to the
+ * callback
+ */
+struct beacon_interval_arg {
+	uint8_t curr_vdev_id;
+	enum QDF_OPMODE curr_bss_opmode;
+	qdf_freq_t ch_freq;
+	uint16_t bss_beacon_interval;
+	QDF_STATUS status;
+	bool is_done;
+	bool update_beacon_interval;
+};
+
+/**
+ * if_mgr_enable_roaming() - interface manager enable roaming
+ * @pdev: pdev object
+ * @vdev: vdev object
+ * @requestor: RSO enable requestor
+ *
+ * Interface manager api to enable roaming for all other active vdev id's
+ *
+ * Context: It should run in thread context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS if_mgr_enable_roaming(struct wlan_objmgr_pdev *pdev,
+				 struct wlan_objmgr_vdev *vdev,
+				 enum wlan_cm_rso_control_requestor requestor);
+
+/**
+ * if_mgr_disable_roaming() - interface manager disable roaming
+ * @pdev: pdev object
+ * @vdev: vdev object
+ * @requestor: RSO disable requestor
+ *
+ * Interface manager api to disable roaming for all other active vdev id's
+ *
+ * Context: It should run in thread context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_pdev *pdev,
+				  struct wlan_objmgr_vdev *vdev,
+				  enum wlan_cm_rso_control_requestor requestor);
+
+/**
+ * if_mgr_enable_roaming_on_connected_sta() - interface manager disable roaming
+ * on connected STA
+ * @pdev: pdev object
+ * @vdev: vdev object
+ *
+ * Loops through connected vdevs and disables roaming if it is STA
+ *
+ * Context: It should run in thread context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
+				       struct wlan_objmgr_vdev *vdev);
+
+/**
+ * if_mgr_enable_roaming_after_p2p_disconnect() - interface manager enable
+ * roaming after p2p disconnect
+ * @pdev: pdev object
+ * @vdev: vdev object
+ * @requestor: RSO enable requestor
+ *
+ * Disables roaming on p2p vdevs if the state is disconnected
+ *
+ * Context: It should run in thread context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect(
+				struct wlan_objmgr_pdev *pdev,
+				struct wlan_objmgr_vdev *vdev,
+				enum wlan_cm_rso_control_requestor requestor);
+
+/**
+ * if_mgr_is_beacon_interval_valid() - checks if the concurrent session is
+ * valid
+ * @pdev: pdev object
+ * @vdev_id: vdev ID
+ * @candidate: concurrent candidate info
+ *
+ * This function validates the beacon interval with all other active vdevs.
+ *
+ * Context: It should run in thread context
+ *
+ * Return: true if session is valid, false if not
+ */
+bool if_mgr_is_beacon_interval_valid(struct wlan_objmgr_pdev *pdev,
+				     uint8_t vdev_id,
+				     struct validate_bss_data *candidate);
+
+/**
+ * if_mgr_validate_candidate() - validate candidate event handler
+ * @vdev: vdev object
+ * @event_data: Interface mgr event data
+ *
+ * This function will validate the candidate to see if it is a suitable option
+ * for roaming to.
+ *
+ * Context: It should run in thread context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
+				     struct if_mgr_event_data *event_data);
+
+#endif

+ 1007 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c

@@ -0,0 +1,1007 @@
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains interface manager roam public api
+ */
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_policy_mgr_i.h"
+#include "wlan_if_mgr_roam.h"
+#include "wlan_if_mgr_public_struct.h"
+#include "wlan_cm_roam_api.h"
+#include "wlan_if_mgr_main.h"
+#include "wlan_p2p_ucfg_api.h"
+#include "cds_api.h"
+#include "sme_api.h"
+#include "wlan_vdev_mgr_utils_api.h"
+#include "wni_api.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+#include "wlan_cm_api.h"
+#include "wlan_scan_api.h"
+#include "wlan_mlo_mgr_roam.h"
+#include "wlan_mlo_mgr_sta.h"
+#include "wlan_mlo_mgr_link_switch.h"
+#include <wlan_action_oui_main.h>
+
+
+#ifdef WLAN_FEATURE_11BE_MLO
+static inline bool
+if_mgr_is_assoc_link_of_vdev(struct wlan_objmgr_pdev *pdev,
+			     struct wlan_objmgr_vdev *vdev,
+			     uint8_t cur_vdev_id)
+{
+	struct wlan_objmgr_vdev *cur_vdev, *assoc_vdev;
+
+	cur_vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, cur_vdev_id,
+							WLAN_IF_MGR_ID);
+	if (!cur_vdev)
+		return false;
+
+	assoc_vdev = wlan_mlo_get_assoc_link_vdev(cur_vdev);
+
+	wlan_objmgr_vdev_release_ref(cur_vdev, WLAN_IF_MGR_ID);
+	if (vdev == assoc_vdev)
+		return true;
+
+	return false;
+}
+#else
+static inline bool
+if_mgr_is_assoc_link_of_vdev(struct wlan_objmgr_pdev *pdev,
+			     struct wlan_objmgr_vdev *vdev,
+			     uint8_t cur_vdev_id)
+{
+	return false;
+}
+#endif
+
+static void if_mgr_enable_roaming_on_vdev(struct wlan_objmgr_pdev *pdev,
+					  void *object, void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	struct change_roam_state_arg *roam_arg = arg;
+	uint8_t vdev_id, curr_vdev_id;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+	curr_vdev_id = roam_arg->curr_vdev_id;
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		return;
+
+	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev) ||
+	    if_mgr_is_assoc_link_of_vdev(pdev, vdev, curr_vdev_id))
+		return;
+
+	if (curr_vdev_id != vdev_id &&
+	    vdev->vdev_mlme.mlme_state == WLAN_VDEV_S_UP) {
+		ifmgr_debug("Enable roaming for vdev_id %d", vdev_id);
+		wlan_cm_enable_rso(pdev, vdev_id,
+				   roam_arg->requestor,
+				   REASON_DRIVER_ENABLED);
+	}
+}
+
+QDF_STATUS if_mgr_enable_roaming(struct wlan_objmgr_pdev *pdev,
+				 struct wlan_objmgr_vdev *vdev,
+				 enum wlan_cm_rso_control_requestor requestor)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct change_roam_state_arg roam_arg;
+	uint8_t vdev_id;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+
+	roam_arg.requestor = requestor;
+	roam_arg.curr_vdev_id = vdev_id;
+
+	status = wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
+						if_mgr_enable_roaming_on_vdev,
+						&roam_arg, 0,
+						WLAN_IF_MGR_ID);
+
+	return status;
+}
+
+static void if_mgr_disable_roaming_on_vdev(struct wlan_objmgr_pdev *pdev,
+					   void *object, void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	struct change_roam_state_arg *roam_arg = arg;
+	uint8_t vdev_id, curr_vdev_id;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+	curr_vdev_id = roam_arg->curr_vdev_id;
+
+	if (curr_vdev_id == vdev_id ||
+	    wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE ||
+	    wlan_cm_is_vdev_roam_sync_inprogress(vdev) ||
+	    vdev->vdev_mlme.mlme_state != WLAN_VDEV_S_UP)
+		return;
+
+	/*
+	 * Disable roaming only for the STA vdev which is not is roam sync state
+	 * and VDEV is in UP state.
+	 */
+	ifmgr_debug("Roaming disabled on vdev_id %d", vdev_id);
+	wlan_cm_disable_rso(pdev, vdev_id, roam_arg->requestor,
+			    REASON_DRIVER_DISABLED);
+}
+
+QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_pdev *pdev,
+				  struct wlan_objmgr_vdev *vdev,
+				  enum wlan_cm_rso_control_requestor requestor)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct change_roam_state_arg roam_arg;
+	uint8_t vdev_id;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+
+	roam_arg.requestor = requestor;
+	roam_arg.curr_vdev_id = vdev_id;
+
+	status = wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
+						if_mgr_disable_roaming_on_vdev,
+						&roam_arg, 0,
+						WLAN_IF_MGR_ID);
+
+	return status;
+}
+
+QDF_STATUS
+if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
+				       struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		return QDF_STATUS_E_FAILURE;
+
+	/*
+	 * When link switch is in progress, don't send RSO Enable before vdev
+	 * is up. RSO Enable will be sent as part of install keys once
+	 * link switch connect sequence is complete.
+	 */
+	if (mlo_mgr_is_link_switch_in_progress(vdev))
+		return QDF_STATUS_SUCCESS;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	if (policy_mgr_is_sta_active_connection_exists(psoc) &&
+	    mlo_is_enable_roaming_on_connected_sta_allowed(vdev)) {
+		wlan_cm_enable_roaming_on_connected_sta(pdev, vdev_id);
+		policy_mgr_set_pcl_for_connected_vdev(psoc, vdev_id, true);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect(
+				struct wlan_objmgr_pdev *pdev,
+				struct wlan_objmgr_vdev *vdev,
+				enum wlan_cm_rso_control_requestor requestor)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_objmgr_psoc *psoc;
+	struct change_roam_state_arg roam_arg;
+	uint8_t vdev_id;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+
+	roam_arg.requestor = requestor;
+	roam_arg.curr_vdev_id = vdev_id;
+
+	/*
+	 * Due to audio share glitch with P2P clients due
+	 * to roam scan on concurrent interface, disable
+	 * roaming if "p2p_disable_roam" ini is enabled.
+	 * Re-enable roaming again once the p2p client
+	 * gets disconnected.
+	 */
+	if (ucfg_p2p_is_roam_config_disabled(psoc) &&
+	    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) {
+		ifmgr_debug("P2P client disconnected, enable roam");
+		status = wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
+					      if_mgr_enable_roaming_on_vdev,
+					      &roam_arg, 0,
+					      WLAN_IF_MGR_ID);
+	}
+
+	return status;
+}
+
+/**
+ * if_mgr_calculate_mcc_beacon_interval() - Calculates the new beacon interval
+ * @sta_bi: station beacon interval
+ * @go_given_bi: P2P GO's given beacon interval
+ *
+ * This function has 3 stages. First it modifies the input go_given_bi to be
+ * within 100 to 199. Then it checks if the sta_bi and go_given_bi are multiples
+ * of each other. If they are, that means the 2 values are compatible, and just
+ * return as is, otherwise, find new compatible BI for P2P GO
+ *
+ * Return: valid beacon interval value
+ */
+static uint16_t if_mgr_calculate_mcc_beacon_interval(uint16_t sta_bi,
+						     uint16_t go_given_bi)
+{
+	uint8_t num_beacons, is_multiple;
+	uint16_t go_calculated_bi, go_final_bi, sta_calculated_bi;
+
+	/* ensure BI ranges between 100 and 200 */
+	if (go_given_bi < 100)
+		go_calculated_bi = 100;
+	else
+		go_calculated_bi = 100 + (go_given_bi % 100);
+
+	if (sta_bi == 0) {
+		/* There is possibility to receive zero as value.
+		 * Which will cause divide by zero. Hence initialise with 100
+		 */
+		sta_bi = 100;
+		ifmgr_warn("sta_bi 2nd parameter is zero, initialize to %d",
+			   sta_bi);
+	}
+	/* check, if either one is multiple of another */
+	if (sta_bi > go_calculated_bi)
+		is_multiple = !(sta_bi % go_calculated_bi);
+	else
+		is_multiple = !(go_calculated_bi % sta_bi);
+
+	/* if it is multiple, then accept GO's beacon interval
+	 * range [100,199] as it is
+	 */
+	if (is_multiple)
+		return go_calculated_bi;
+
+	/* else , if it is not multiple, then then check for number of beacons
+	 * to be inserted based on sta BI
+	 */
+	num_beacons = sta_bi / 100;
+	if (num_beacons) {
+		/* GO's final beacon interval will be aligned to sta beacon
+		 * interval, but in the range of [100, 199].
+		 */
+		sta_calculated_bi = sta_bi / num_beacons;
+		go_final_bi = sta_calculated_bi;
+	} else {
+		/* if STA beacon interval is less than 100, use GO's change
+		 * beacon interval instead of updating to STA's beacon interval.
+		 */
+		go_final_bi = go_calculated_bi;
+	}
+
+	return go_final_bi;
+}
+
+static QDF_STATUS
+if_mgr_send_chng_mcc_beacon_interval(struct wlan_objmgr_vdev *vdev,
+				     struct beacon_interval_arg *bss_arg)
+{
+	struct scheduler_msg msg = {0};
+	struct wlan_change_bi *p_msg;
+	uint16_t len = 0;
+	QDF_STATUS status;
+	uint8_t *mac_addr;
+
+	if (!bss_arg->update_beacon_interval)
+		return QDF_STATUS_SUCCESS;
+
+	bss_arg->update_beacon_interval = false;
+
+	len = sizeof(*p_msg);
+	p_msg = qdf_mem_malloc(len);
+	if (!p_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	p_msg->message_type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
+	p_msg->length = len;
+
+	mac_addr = wlan_vdev_get_hw_macaddr(vdev);
+	qdf_mem_copy(&p_msg->bssid, mac_addr, QDF_MAC_ADDR_SIZE);
+	ifmgr_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr));
+	p_msg->session_id = wlan_vdev_get_id(vdev);
+	ifmgr_debug("session %d BeaconInterval %d", p_msg->session_id,
+			bss_arg->bss_beacon_interval);
+	p_msg->beacon_interval = bss_arg->bss_beacon_interval;
+
+	msg.type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
+	msg.bodyval = 0;
+	msg.bodyptr = p_msg;
+
+	status = scheduler_post_message(QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_PE, &msg);
+
+	if (status != QDF_STATUS_SUCCESS)
+		qdf_mem_free(p_msg);
+
+	return status;
+}
+
+static void if_mgr_update_beacon_interval(struct wlan_objmgr_pdev *pdev,
+					  void *object, void *arg)
+{
+	struct wlan_objmgr_psoc *psoc;
+	uint8_t allow_mcc_go_diff_bi;
+	struct wlan_objmgr_peer *peer;
+	enum wlan_peer_type bss_persona;
+	struct beacon_interval_arg *bss_arg = arg;
+	struct wlan_objmgr_vdev *vdev = object;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return;
+
+	policy_mgr_get_allow_mcc_go_diff_bi(psoc, &allow_mcc_go_diff_bi);
+
+	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
+	if (!peer)
+		return;
+
+	bss_persona = wlan_peer_get_peer_type(peer);
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);
+
+	/*
+	 * If GO in MCC support different beacon interval,
+	 * change the BI of the P2P-GO
+	 */
+	if (bss_persona == WLAN_PEER_P2P_GO)
+		return;
+	/*
+	 * Handle different BI scenario based on the
+	 * configuration set. If Config is not set to 0x04 then
+	 * Disconnect all the P2P clients associated. If config
+	 * is set to 0x04 then update the BI without
+	 * disconnecting all the clients
+	 */
+	if (allow_mcc_go_diff_bi == ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT &&
+	    bss_arg->update_beacon_interval) {
+		bss_arg->status =
+			if_mgr_send_chng_mcc_beacon_interval(vdev, bss_arg);
+		return;
+	} else if (bss_arg->update_beacon_interval) {
+		/*
+		 * If the configuration of fAllowMCCGODiffBI is set to
+		 * other than 0x04
+		 */
+		bss_arg->status = wlan_sap_disconnect_all_p2p_client(vdev_id);
+		return;
+	}
+}
+
+static QDF_STATUS
+if_mgr_update_mcc_p2p_beacon_interval(struct wlan_objmgr_vdev *vdev,
+				      struct beacon_interval_arg *bss_arg)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	uint8_t enable_mcc_mode;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	/* If MCC is not supported just break and return SUCCESS */
+	wlan_mlme_get_mcc_feature(psoc, &enable_mcc_mode);
+	if (!enable_mcc_mode)
+		return QDF_STATUS_E_FAILURE;
+
+	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
+					  if_mgr_update_beacon_interval,
+					  bss_arg, 0, WLAN_IF_MGR_ID);
+
+	return bss_arg->status;
+}
+
+static bool if_mgr_validate_sta_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
+					   struct beacon_interval_arg *bss_arg)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct vdev_mlme_obj *vdev_mlme;
+	struct wlan_objmgr_peer *peer;
+	uint16_t new_bcn_interval;
+	uint32_t beacon_interval;
+	struct wlan_channel *chan;
+	enum QDF_OPMODE curr_persona;
+	uint8_t allow_mcc_go_diff_bi;
+	uint8_t conc_rule1 = 0, conc_rule2 = 0;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return false;
+
+	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
+	if (!peer)
+		return false;
+
+	curr_persona = wlan_vdev_mlme_get_opmode(vdev);
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);
+
+	if (curr_persona == QDF_STA_MODE ||
+	    curr_persona == QDF_P2P_CLIENT_MODE) {
+		ifmgr_debug("Bcn Intrvl validation not require for STA/CLIENT");
+		return false;
+	}
+
+	chan = wlan_vdev_get_active_channel(vdev);
+	if (!chan) {
+		ifmgr_err("failed to get active channel");
+		return false;
+	}
+
+	vdev_mlme =
+		wlan_objmgr_vdev_get_comp_private_obj(vdev,
+						      WLAN_UMAC_COMP_MLME);
+	if (!vdev_mlme) {
+		QDF_ASSERT(0);
+		return false;
+	}
+
+	wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
+				      &beacon_interval);
+
+	if (curr_persona == QDF_SAP_MODE &&
+	    (chan->ch_cfreq1 != bss_arg->ch_freq ||
+	     chan->ch_cfreq2 != bss_arg->ch_freq)) {
+		ifmgr_debug("*** MCC with SAP+STA sessions ****");
+		bss_arg->status = QDF_STATUS_SUCCESS;
+		return true;
+	}
+
+	if (curr_persona == QDF_P2P_GO_MODE &&
+	    (chan->ch_cfreq1 != bss_arg->ch_freq ||
+	     chan->ch_cfreq2 != bss_arg->ch_freq) &&
+	    beacon_interval != bss_arg->bss_beacon_interval) {
+		policy_mgr_get_allow_mcc_go_diff_bi(psoc,
+						    &allow_mcc_go_diff_bi);
+
+		switch (allow_mcc_go_diff_bi) {
+		case ALLOW_MCC_GO_DIFF_BI_WFA_CERT:
+			bss_arg->status = QDF_STATUS_SUCCESS;
+			return true;
+		case ALLOW_MCC_GO_DIFF_BI_WORKAROUND:
+			fallthrough;
+		case ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT:
+			policy_mgr_get_conc_rule1(psoc, &conc_rule1);
+			policy_mgr_get_conc_rule2(psoc, &conc_rule2);
+			if (conc_rule1 || conc_rule2)
+				new_bcn_interval = CUSTOM_CONC_GO_BI;
+			else
+				new_bcn_interval =
+					if_mgr_calculate_mcc_beacon_interval(
+						bss_arg->bss_beacon_interval,
+						beacon_interval);
+
+			ifmgr_debug("Peer AP BI : %d, new Beacon Interval: %d",
+				    bss_arg->bss_beacon_interval,
+				    new_bcn_interval);
+
+			/* Update the beacon interval */
+			if (new_bcn_interval != beacon_interval) {
+				ifmgr_err("Beacon Interval got changed config used: %d",
+					  allow_mcc_go_diff_bi);
+				bss_arg->bss_beacon_interval = new_bcn_interval;
+				bss_arg->update_beacon_interval = true;
+				bss_arg->status =
+					if_mgr_update_mcc_p2p_beacon_interval(
+								vdev,
+								bss_arg);
+				return true;
+			}
+			bss_arg->status = QDF_STATUS_SUCCESS;
+			return true;
+		case ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN:
+			bss_arg->update_beacon_interval = false;
+			bss_arg->status = wlan_sap_stop_bss(vdev_id);
+			return true;
+		default:
+			ifmgr_err("BcnIntrvl is diff can't connect to preferred AP");
+			bss_arg->status = QDF_STATUS_E_FAILURE;
+			return true;
+		}
+	}
+	return false;
+}
+
+static bool if_mgr_validate_p2pcli_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
+				       struct beacon_interval_arg *bss_arg)
+{
+	enum QDF_OPMODE curr_persona;
+	enum wlan_peer_type bss_persona;
+	uint32_t beacon_interval;
+	struct wlan_channel *chan;
+	struct wlan_objmgr_peer *peer;
+	struct vdev_mlme_obj *vdev_mlme;
+
+	curr_persona = wlan_vdev_mlme_get_opmode(vdev);
+
+	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
+	if (!peer)
+		return false;
+
+	bss_persona = wlan_peer_get_peer_type(peer);
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);
+
+	chan = wlan_vdev_get_active_channel(vdev);
+	if (!chan) {
+		ifmgr_err("failed to get active channel");
+		return false;
+	}
+
+	vdev_mlme =
+		wlan_objmgr_vdev_get_comp_private_obj(vdev,
+						      WLAN_UMAC_COMP_MLME);
+	if (!vdev_mlme) {
+		QDF_ASSERT(0);
+		return false;
+	}
+
+	wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
+				      &beacon_interval);
+
+	if (curr_persona == QDF_STA_MODE) {
+		ifmgr_debug("Ignore Beacon Interval Validation...");
+	} else if (bss_persona == WLAN_PEER_P2P_GO) {
+		if ((chan->ch_cfreq1 != bss_arg->ch_freq ||
+		     chan->ch_cfreq2 != bss_arg->ch_freq) &&
+		    beacon_interval != bss_arg->bss_beacon_interval) {
+			ifmgr_err("BcnIntrvl is diff can't connect to P2P_GO network");
+			bss_arg->status = QDF_STATUS_E_FAILURE;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static bool
+if_mgr_validate_p2pgo_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
+				 struct beacon_interval_arg *bss_arg)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct vdev_mlme_obj *vdev_mlme;
+	enum QDF_OPMODE curr_persona;
+	uint32_t beacon_interval;
+	struct wlan_channel *chan;
+	uint8_t conc_rule1 = 0, conc_rule2 = 0;
+	uint16_t new_bcn_interval;
+
+	curr_persona = wlan_vdev_mlme_get_opmode(vdev);
+
+	chan = wlan_vdev_get_active_channel(vdev);
+	if (!chan) {
+		ifmgr_err("failed to get active channel");
+		return false;
+	}
+
+	vdev_mlme =
+		wlan_objmgr_vdev_get_comp_private_obj(vdev,
+						      WLAN_UMAC_COMP_MLME);
+	if (!vdev_mlme) {
+		QDF_ASSERT(0);
+		return false;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return false;
+
+	wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
+				      &beacon_interval);
+
+	if ((curr_persona == QDF_P2P_CLIENT_MODE) ||
+	    (curr_persona == QDF_STA_MODE)) {
+		/* check for P2P_client scenario */
+		if ((chan->ch_cfreq1 == 0) && (chan->ch_cfreq2 == 0) &&
+		    (beacon_interval == 0))
+			return false;
+
+		if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_UP &&
+		    (chan->ch_cfreq1 != bss_arg->ch_freq ||
+		     chan->ch_cfreq2 != bss_arg->ch_freq) &&
+		    beacon_interval != bss_arg->bss_beacon_interval) {
+			/*
+			 * Updated beaconInterval should be used only when
+			 * we are starting a new BSS not incase of
+			 * client or STA case
+			 */
+			policy_mgr_get_conc_rule1(psoc, &conc_rule1);
+			policy_mgr_get_conc_rule2(psoc, &conc_rule2);
+
+			/* Calculate beacon Interval for P2P-GO incase of MCC */
+			if (conc_rule1 || conc_rule2) {
+				new_bcn_interval = CUSTOM_CONC_GO_BI;
+			} else {
+				new_bcn_interval =
+					if_mgr_calculate_mcc_beacon_interval(
+						beacon_interval,
+						bss_arg->bss_beacon_interval);
+			}
+			if (new_bcn_interval != bss_arg->bss_beacon_interval)
+				bss_arg->bss_beacon_interval = new_bcn_interval;
+			bss_arg->status = QDF_STATUS_SUCCESS;
+			return true;
+		}
+	}
+	return false;
+}
+
+static void if_mgr_validate_beacon_interval(struct wlan_objmgr_pdev *pdev,
+					    void *object, void *arg)
+{
+	struct beacon_interval_arg *bss_arg = arg;
+	struct wlan_objmgr_vdev *vdev = object;
+	uint8_t iter_vdev_id = wlan_vdev_get_id(vdev);
+	bool is_done = false;
+
+	if (iter_vdev_id == bss_arg->curr_vdev_id)
+		return;
+
+	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP)
+		return;
+
+	if (bss_arg->is_done)
+		return;
+
+	switch (bss_arg->curr_bss_opmode) {
+	case QDF_STA_MODE:
+		is_done = if_mgr_validate_sta_bcn_intrvl(vdev, bss_arg);
+		break;
+	case QDF_P2P_CLIENT_MODE:
+		is_done = if_mgr_validate_p2pcli_bcn_intrvl(vdev, bss_arg);
+		break;
+	case QDF_SAP_MODE:
+	case QDF_IBSS_MODE:
+		break;
+	case QDF_P2P_GO_MODE:
+		is_done = if_mgr_validate_p2pgo_bcn_intrvl(vdev, bss_arg);
+		break;
+	default:
+		ifmgr_err("BSS opmode not supported: %d",
+			  bss_arg->curr_bss_opmode);
+	}
+
+	if (is_done)
+		bss_arg->is_done = is_done;
+}
+
+bool if_mgr_is_beacon_interval_valid(struct wlan_objmgr_pdev *pdev,
+				     uint8_t vdev_id,
+				     struct validate_bss_data *candidate)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct beacon_interval_arg bss_arg;
+	uint8_t enable_mcc_mode;
+	struct wlan_objmgr_vdev *vdev;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return false;
+
+	wlan_mlme_get_mcc_feature(psoc, &enable_mcc_mode);
+	if (!enable_mcc_mode)
+		return false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_IF_MGR_ID);
+	if (!vdev)
+		return false;
+
+	bss_arg.curr_vdev_id = vdev_id;
+	bss_arg.curr_bss_opmode = wlan_vdev_mlme_get_opmode(vdev);
+	bss_arg.ch_freq = candidate->chan_freq;
+	bss_arg.bss_beacon_interval = candidate->beacon_interval;
+	bss_arg.is_done = false;
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_IF_MGR_ID);
+
+	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
+					  if_mgr_validate_beacon_interval,
+					  &bss_arg, 0,
+					  WLAN_IF_MGR_ID);
+
+	if (!bss_arg.is_done)
+		return true;
+
+	if (bss_arg.is_done && QDF_IS_STATUS_SUCCESS(bss_arg.status))
+		return true;
+
+	return false;
+}
+
+static void if_mgr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
+					  void *object, void *arg)
+{
+	struct bssid_search_arg *bssid_arg = arg;
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	struct wlan_objmgr_peer *peer;
+
+	if (!(wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
+	      wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE))
+		return;
+
+	/* Need to check the connection manager state when that becomes
+	 * available
+	 */
+	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP)
+		return;
+
+	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
+	if (!peer)
+		return;
+
+	if (WLAN_ADDR_EQ(bssid_arg->peer_addr.bytes,
+			 wlan_peer_get_macaddr(peer)) == QDF_STATUS_SUCCESS)
+		bssid_arg->vdev_id = wlan_vdev_get_id(vdev);
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * if_mgr_get_conc_ext_flags() - get extended flags for concurrency check
+ * @vdev: pointer to vdev on which new connection is coming up
+ * @candidate_info: interface manager validate candidate data
+ *
+ * Return: extended flags for concurrency check
+ */
+static inline uint32_t
+if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev,
+			  struct validate_bss_data *candidate_info)
+{
+	struct qdf_mac_addr *mld_addr;
+
+	/* If connection is happening on non-ML VDEV
+	 * force the ML AP candidate as non-MLO to
+	 * downgrade connection to 11ax.
+	 */
+	mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
+	if (qdf_is_macaddr_zero(mld_addr))
+		return policy_mgr_get_conc_ext_flags(vdev, false);
+
+	return policy_mgr_get_conc_ext_flags(vdev, candidate_info->is_mlo);
+}
+
+static void if_mgr_update_candidate(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_objmgr_vdev *vdev,
+				    struct validate_bss_data *candidate_info)
+{
+	struct scan_cache_entry *scan_entry = candidate_info->scan_entry;
+	struct action_oui_search_attr attr = {0};
+	int8_t i, allowed_partner_links = 0;
+	uint8_t mlo_support_link_num;
+
+	if (!(scan_entry->ie_list.multi_link_bv || scan_entry->ie_list.ehtcap ||
+	      scan_entry->ie_list.ehtop))
+		return;
+
+	attr.ie_data = util_scan_entry_ie_data(scan_entry);
+	attr.ie_length = util_scan_entry_ie_len(scan_entry);
+
+	if (!mlme_get_bss_11be_allowed(psoc, &candidate_info->peer_addr,
+				       attr.ie_data, attr.ie_length) ||
+	    wlan_vdev_mlme_get_user_dis_eht_flag(vdev) ||
+	    !wlan_reg_phybitmap_support_11be(wlan_vdev_get_pdev(vdev))) {
+		scan_entry->ie_list.multi_link_bv = NULL;
+		scan_entry->ie_list.ehtcap = NULL;
+		scan_entry->ie_list.ehtop = NULL;
+		qdf_mem_zero(&scan_entry->ml_info, sizeof(scan_entry->ml_info));
+		candidate_info->is_mlo = false;
+		return;
+	}
+
+	mlo_support_link_num = wlan_mlme_get_sta_mlo_conn_max_num(psoc);
+
+	if (mlo_support_link_num <= WLAN_MAX_ML_DEFAULT_LINK)
+		return;
+
+	if (!wlan_action_oui_search(psoc, &attr,
+				    ACTION_OUI_RESTRICT_MAX_MLO_LINKS))
+		return;
+
+	for (i = 0; i < scan_entry->ml_info.num_links; i++) {
+		if (i < WLAN_MAX_ML_DEFAULT_LINK - 1) {
+			allowed_partner_links++;
+			continue;
+		}
+
+		scan_entry->ml_info.link_info[i].is_valid_link = false;
+	}
+
+	if (allowed_partner_links != scan_entry->ml_info.num_links)
+		ifmgr_nofl_debug("Downgrade " QDF_MAC_ADDR_FMT " partner links from %d to %d",
+				 QDF_MAC_ADDR_REF(scan_entry->ml_info.mld_mac_addr.bytes),
+				 scan_entry->ml_info.num_links,
+				 allowed_partner_links);
+}
+#else
+static inline uint32_t
+if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev,
+			  struct validate_bss_data *candidate_info)
+{
+	return 0;
+}
+
+static void if_mgr_update_candidate(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_objmgr_vdev *vdev,
+				    struct validate_bss_data *candidate_info)
+{
+}
+#endif
+
+QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
+				     struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	enum QDF_OPMODE op_mode;
+	enum policy_mgr_con_mode mode;
+	struct bssid_search_arg bssid_arg;
+	struct validate_bss_data *candidate_info =
+		&event_data->validate_bss_info;
+	uint32_t chan_freq = candidate_info->chan_freq;
+	uint32_t conc_freq = 0, conc_ext_flags;
+
+	op_mode = wlan_vdev_mlme_get_opmode(vdev);
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	if_mgr_update_candidate(psoc, vdev, candidate_info);
+	/*
+	 * Do not allow STA to connect on 6Ghz or indoor channel for non dbs
+	 * hardware if SAP and skip_6g_and_indoor_freq_scan ini are present
+	 */
+	if (op_mode == QDF_STA_MODE &&
+	    !policy_mgr_is_sta_chan_valid_for_connect_and_roam(pdev,
+							       chan_freq)) {
+		ifmgr_debug("STA connection not allowed on bssid: "QDF_MAC_ADDR_FMT" with freq: %d (6Ghz or indoor(%d)), as not valid for connection",
+			    QDF_MAC_ADDR_REF(candidate_info->peer_addr.bytes),
+			    chan_freq,
+			    wlan_reg_is_freq_indoor(pdev, chan_freq));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/*
+	 * This is a temporary check and will be removed once ll_lt_sap CSA
+	 * support is added.
+	 */
+	if (policy_mgr_get_ll_lt_sap_freq(psoc) == chan_freq) {
+		ifmgr_debug("STA connection not allowed on LL_LT_SAP freq %d",
+			    chan_freq);
+		return QDF_STATUS_E_INVAL;
+	}
+	/*
+	 * Ignore the BSS if any other vdev is already connected to it.
+	 */
+	qdf_copy_macaddr(&bssid_arg.peer_addr,
+			 &candidate_info->peer_addr);
+	bssid_arg.vdev_id = WLAN_INVALID_VDEV_ID;
+	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
+					  if_mgr_get_vdev_id_from_bssid,
+					  &bssid_arg, 0,
+					  WLAN_IF_MGR_ID);
+
+	if (bssid_arg.vdev_id != WLAN_INVALID_VDEV_ID) {
+		ifmgr_info("vdev_id %d already connected to "QDF_MAC_ADDR_FMT". select next bss for vdev_id %d",
+			   bssid_arg.vdev_id,
+			   QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes),
+			   wlan_vdev_get_id(vdev));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/*
+	 * If concurrency enabled take the concurrent connected channel first.
+	 * Valid multichannel concurrent sessions exempted
+	 */
+	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode,
+						    wlan_vdev_get_id(vdev));
+
+	/* If concurrency is not allowed select next bss */
+	conc_ext_flags = if_mgr_get_conc_ext_flags(vdev, candidate_info);
+	/*
+	 * Apply concurrency check only for non ML and ML assoc links only
+	 * For non-assoc ML link if concurrency check fails its will be forced
+	 * disabled in peer assoc.
+	 */
+	if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev) &&
+	    !policy_mgr_is_concurrency_allowed(psoc, mode, chan_freq,
+					       HW_MODE_20_MHZ, conc_ext_flags,
+					       NULL)) {
+		ifmgr_info("Concurrency not allowed for this channel freq %d bssid "QDF_MAC_ADDR_FMT", selecting next",
+			   chan_freq,
+			   QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/*
+	 * check if channel is allowed for current hw mode, if not fetch
+	 * next BSS.
+	 */
+	if (!policy_mgr_is_hwmode_set_for_given_chnl(psoc, chan_freq)) {
+		ifmgr_info("HW mode isn't properly set, freq %d BSSID "QDF_MAC_ADDR_FMT,
+			   chan_freq,
+			   QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* validate beacon interval */
+	if (policy_mgr_concurrent_open_sessions_running(psoc) &&
+	    !if_mgr_is_beacon_interval_valid(pdev, wlan_vdev_get_id(vdev),
+					     candidate_info)) {
+		conc_freq = wlan_get_conc_freq();
+		ifmgr_debug("csr Conc Channel freq: %d",
+			    conc_freq);
+
+		if (conc_freq) {
+			if ((conc_freq == chan_freq) ||
+			    (policy_mgr_is_hw_sbs_capable(psoc) &&
+			     policy_mgr_are_sbs_chan(psoc, conc_freq,
+			     chan_freq)) ||
+			    (policy_mgr_is_hw_dbs_capable(psoc) &&
+			    !wlan_reg_is_same_band_freqs(conc_freq,
+							 chan_freq))) {
+				/*
+				 * make this 0 because we do not want the below
+				 * check to pass as we don't want to connect on
+				 * other channel
+				 */
+				ifmgr_debug("Conc chnl freq match: %d",
+					    conc_freq);
+				conc_freq = 0;
+			}
+		}
+	}
+
+	if (conc_freq)
+		return QDF_STATUS_E_INVAL;
+
+	/* Check low latency SAP and STA/GC concurrency are valid or not */
+	if (!policy_mgr_is_ll_sap_concurrency_valid(psoc, chan_freq, mode)) {
+		ifmgr_debug("STA connection not allowed on bssid: "QDF_MAC_ADDR_FMT" with freq: %d due to LL SAP present",
+			    QDF_MAC_ADDR_REF(candidate_info->peer_addr.bytes),
+			    chan_freq);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}

+ 235 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c

@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains interface manager public api
+ */
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_if_mgr_public_struct.h"
+#include "wlan_if_mgr_ap.h"
+#include "wlan_if_mgr_roam.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_if_mgr_main.h"
+#include "wlan_p2p_cfg_api.h"
+#include "wlan_tdls_api.h"
+#include "wlan_p2p_api.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+#include "wlan_p2p_ucfg_api.h"
+#include "wlan_vdev_mgr_utils_api.h"
+#include "wlan_tdls_tgt_api.h"
+#include "wlan_policy_mgr_ll_sap.h"
+
+QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev,
+			       struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	QDF_STATUS status;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	wlan_tdls_notify_start_bss(psoc, vdev);
+
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE ||
+	    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
+		wlan_handle_emlsr_sta_concurrency(psoc, true, false);
+
+	if (policy_mgr_is_hw_mode_change_in_progress(psoc)) {
+		if (!QDF_IS_STATUS_SUCCESS(
+		    policy_mgr_wait_for_connection_update(psoc))) {
+			ifmgr_err("qdf wait for event failed!!");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	if (policy_mgr_is_chan_switch_in_progress(psoc)) {
+		status = policy_mgr_wait_chan_switch_complete_evt(psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			ifmgr_err("qdf wait for csa event failed!!");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	if (policy_mgr_is_sta_active_connection_exists(psoc))
+		/* Disable Roaming on all vdev's before starting bss */
+		if_mgr_disable_roaming(pdev, vdev, RSO_START_BSS);
+
+	/* abort p2p roc before starting the BSS for sync event */
+	ucfg_p2p_cleanup_roc_by_psoc(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+if_mgr_ap_start_bss_complete(struct wlan_objmgr_vdev *vdev,
+			     struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	/*
+	 * Due to audio share glitch with P2P GO caused by
+	 * roam scan on concurrent interface, disable
+	 * roaming if "p2p_disable_roam" ini is enabled.
+	 * Donot re-enable roaming again on other STA interface
+	 * if p2p GO is active on any vdev.
+	 */
+	if (cfg_p2p_is_roam_config_disabled(psoc) &&
+	    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) {
+		ifmgr_debug("p2p go mode, keep roam disabled");
+	} else {
+		/* Enable Roaming after start bss in case of failure/success */
+		if_mgr_enable_roaming(pdev, vdev, RSO_START_BSS);
+	}
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
+		policy_mgr_check_sap_go_force_scc(psoc, vdev,
+						  CSA_REASON_GO_BSS_STARTED);
+	ifmgr_debug("check for SAP restart");
+
+	if (policy_mgr_is_vdev_ll_lt_sap(psoc, wlan_vdev_get_id(vdev)))
+		policy_mgr_ll_lt_sap_restart_concurrent_sap(psoc, true);
+	else
+		policy_mgr_check_concurrent_intf_and_restart_sap(
+				psoc,
+				wlan_util_vdev_mgr_get_acs_mode_for_vdev(vdev));
+	/*
+	 * Enable TDLS again on concurrent STA
+	 */
+	if (event_data && QDF_IS_STATUS_ERROR(event_data->status))
+		wlan_tdls_notify_start_bss_failure(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS if_mgr_ap_stop_bss(struct wlan_objmgr_vdev *vdev,
+			      struct if_mgr_event_data *event_data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+if_mgr_ap_stop_bss_complete(struct wlan_objmgr_vdev *vdev,
+			    struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	uint8_t mcc_scc_switch;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE ||
+	    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
+		wlan_handle_emlsr_sta_concurrency(psoc, false, true);
+	/*
+	 * Due to audio share glitch with P2P GO caused by
+	 * roam scan on concurrent interface, disable
+	 * roaming if "p2p_disable_roam" ini is enabled.
+	 * Re-enable roaming on other STA interface if p2p GO
+	 * is active on any vdev.
+	 */
+	if (cfg_p2p_is_roam_config_disabled(psoc) &&
+	    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) {
+		ifmgr_debug("p2p go disconnected enable roam");
+		if_mgr_enable_roaming(pdev, vdev, RSO_START_BSS);
+	}
+
+	ifmgr_debug("SAP/P2P-GO is stopped, re-enable roaming if it's stopped due to SAP/P2P-GO CSA");
+	if_mgr_enable_roaming(pdev, vdev, RSO_SAP_CHANNEL_CHANGE);
+
+	policy_mgr_get_mcc_scc_switch(psoc, &mcc_scc_switch);
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE &&
+	    mcc_scc_switch == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)
+		policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false);
+
+	if (policy_mgr_is_vdev_ll_lt_sap(psoc, wlan_vdev_get_id(vdev)))
+		policy_mgr_ll_lt_sap_restart_concurrent_sap(psoc, false);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+if_mgr_ap_csa_complete(struct wlan_objmgr_vdev *vdev,
+		       struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	status = wlan_p2p_check_and_force_scc_go_plus_go(psoc, vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		ifmgr_err("force scc failure with status: %d", status);
+
+	wlan_tdls_notify_channel_switch_complete(psoc, wlan_vdev_get_id(vdev));
+
+	return status;
+}
+
+QDF_STATUS
+if_mgr_ap_csa_start(struct wlan_objmgr_vdev *vdev,
+		    struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	enum QDF_OPMODE op_mode;
+
+	op_mode = wlan_vdev_mlme_get_opmode(vdev);
+	if (op_mode != QDF_SAP_MODE && op_mode != QDF_P2P_GO_MODE)
+		return QDF_STATUS_SUCCESS;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	/*
+	 * Disable TDLS off-channel before VDEV restart
+	 */
+	wlan_tdls_notify_channel_switch_start(psoc, vdev);
+
+	return QDF_STATUS_SUCCESS;
+}

+ 288 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c

@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains interface manager public api
+ */
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_if_mgr_public_struct.h"
+#include "wlan_if_mgr_sta.h"
+#include "wlan_if_mgr_roam.h"
+#include "wlan_if_mgr_main.h"
+#include "nan_ucfg_api.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_p2p_ucfg_api.h"
+#include "wlan_tdls_ucfg_api.h"
+#include "wlan_tdls_api.h"
+#include <wlan_cm_api.h>
+#include <wlan_mlo_mgr_public_structs.h>
+#include <wlan_mlo_mgr_cmn.h>
+#include <wlan_cm_roam_api.h>
+#include "wlan_nan_api.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+#include <wlan_mlo_mgr_sta.h>
+#include "wlan_vdev_mgr_utils_api.h"
+#include "wlan_tdls_api.h"
+#include "wlan_mlo_mgr_link_switch.h"
+#include "wlan_ll_sap_api.h"
+
+QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev,
+				struct if_mgr_event_data *event_data)
+{
+	uint8_t sta_cnt, sap_cnt;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	enum QDF_OPMODE op_mode;
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS], i;
+	bool disable_nan = true;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	/*
+	 * Disable NAN Discovery if incoming connection is P2P or if a STA
+	 * connection already exists and if this is a case of STA+STA
+	 * or SAP+STA concurrency
+	 */
+	sta_cnt = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							 vdev_id_list,
+							 PM_STA_MODE);
+	sap_cnt = policy_mgr_get_sap_mode_info(psoc, NULL,
+					       &vdev_id_list[sta_cnt]);
+
+	op_mode = wlan_vdev_mlme_get_opmode(vdev);
+
+	if (op_mode == QDF_STA_MODE || op_mode == QDF_P2P_CLIENT_MODE)
+		wlan_handle_emlsr_sta_concurrency(psoc, true, false);
+
+	if (op_mode == QDF_P2P_CLIENT_MODE || sap_cnt || sta_cnt) {
+		for (i = 0; i < sta_cnt + sap_cnt; i++) {
+			if (vdev_id_list[i] == wlan_vdev_get_id(vdev))
+				disable_nan = false;
+			/* 1. Don't disable nan if firmware supports
+			 *    ML STA + NAN + NDP.
+			 * 2. Disable nan if legacy sta + nan +
+			 *    ML STA(primary link) comes up.
+			 */
+			if (wlan_vdev_mlme_is_mlo_link_vdev(vdev) &&
+			    wlan_is_mlo_sta_nan_ndi_allowed(psoc))
+				disable_nan = false;
+		}
+		if (disable_nan)
+			ucfg_nan_disable_concurrency(psoc);
+	}
+
+	if (op_mode == QDF_P2P_CLIENT_MODE)
+		wlan_tdls_handle_p2p_client_connect(psoc, vdev);
+
+	/*
+	 * STA+NDI concurrency gets preference over NDI+NDI. Disable
+	 * first NDI in case an NDI+NDI concurrency exists if FW does
+	 * not support 4 port concurrency of two NDI + NAN with STA.
+	 */
+	if (!ucfg_nan_is_sta_nan_ndi_4_port_allowed(psoc))
+		ucfg_nan_check_and_disable_unsupported_ndi(psoc,
+							   false);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS if_mgr_connect_active(struct wlan_objmgr_vdev *vdev,
+				 struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev)) {
+		/*
+		 * In case of STA+STA concurrency, firmware might try to roam
+		 * to same AP where host is trying to do association on the other
+		 * STA iface. Roaming is disabled on all the ifaces to avoid
+		 * this scenario.
+		 */
+		if_mgr_disable_roaming(pdev, vdev, RSO_CONNECT_START);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev,
+				   struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	QDF_STATUS status = event_data->status;
+	uint8_t vdev_id;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/*
+		 * Due to audio share glitch with P2P clients caused by roam
+		 * scan on concurrent interface, disable roaming if
+		 * "p2p_disable_roam" ini is enabled. Donot re-enable roaming
+		 * again on other STA interface if p2p client connection is
+		 * active on any vdev.
+		 */
+		if (ucfg_p2p_is_roam_config_disabled(psoc) &&
+		    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) {
+			ifmgr_debug("p2p client active, keep roam disabled");
+		} else {
+			ifmgr_debug("set pcl when connection on vdev id:%d",
+				     vdev_id);
+			policy_mgr_set_pcl_for_connected_vdev(psoc, vdev_id,
+							      false);
+			/*
+			 * Enable roaming on other STA iface except this one.
+			 * Firmware doesn't support connection on one STA iface
+			 * while roaming on other STA iface.
+			 */
+			if_mgr_enable_roaming(pdev, vdev, RSO_CONNECT_START);
+		}
+	} else {
+		/* notify connect failure on final failure */
+		ucfg_tdls_notify_connect_failure(psoc);
+
+		/*
+		 * Enable roaming on other STA iface except this one.
+		 * Firmware doesn't support connection on one STA iface
+		 * while roaming on other STA iface.
+		 */
+		if_mgr_enable_roaming(pdev, vdev, RSO_CONNECT_START);
+	}
+
+	policy_mgr_check_n_start_opportunistic_timer(psoc);
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE &&
+	    wlan_vdev_mlme_is_mlo_vdev(vdev))
+		wlan_handle_emlsr_sta_concurrency(psoc, false, true);
+
+	if (!wlan_cm_is_vdev_roaming(vdev))
+		policy_mgr_check_concurrent_intf_and_restart_sap(psoc,
+				wlan_util_vdev_mgr_get_acs_mode_for_vdev(vdev));
+
+	wlan_ll_sap_switch_bearer_on_sta_connect_complete(psoc, vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS if_mgr_disconnect_start(struct wlan_objmgr_vdev *vdev,
+				   struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_runtime_pm_prevent_suspend(&mlme_priv->disconnect_runtime_lock);
+
+	if (mlo_mgr_is_link_switch_in_progress(vdev))
+		wlan_tdls_delete_all_peers(vdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev,
+				      struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct mlme_legacy_priv *mlme_priv;
+	QDF_STATUS status;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_runtime_pm_allow_suspend(&mlme_priv->disconnect_runtime_lock);
+
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
+	    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE)
+		wlan_handle_emlsr_sta_concurrency(psoc, false, true);
+
+	status = if_mgr_enable_roaming_after_p2p_disconnect(pdev, vdev,
+							    RSO_CONNECT_START);
+	if (status) {
+		ifmgr_err("Failed to enable roaming after p2p disconnect");
+		return status;
+	}
+	if (!mlo_is_mld_sta(vdev) || !mlo_mgr_is_link_switch_in_progress(vdev))
+		policy_mgr_check_concurrent_intf_and_restart_sap(
+			psoc, wlan_util_vdev_mgr_get_acs_mode_for_vdev(vdev));
+
+	status = if_mgr_enable_roaming_on_connected_sta(pdev, vdev);
+	if (status) {
+		ifmgr_err("Failed to enable roaming on connected sta");
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+if_mgr_sta_csa_complete(struct wlan_objmgr_vdev *vdev,
+			struct if_mgr_event_data *event_data)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_FAILURE;
+
+	wlan_tdls_notify_channel_switch_complete(psoc, wlan_vdev_get_id(vdev));
+
+	return QDF_STATUS_SUCCESS;
+}

+ 1713 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/logging/inc/wlan_connectivity_logging.h

@@ -0,0 +1,1713 @@
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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_cm_roam_logging.c
+ *
+ * Implementation for the Connect/roaming logging.
+ */
+
+#ifndef _WLAN_CONNECTIVITY_LOGGING_H_
+#define _WLAN_CONNECTIVITY_LOGGING_H_
+
+#include "wlan_logging_sock_svc.h"
+#include "wlan_cm_roam_public_struct.h"
+#include "wlan_mlo_mgr_public_structs.h"
+
+#define WLAN_MAX_LOGGING_FREQ 120
+
+/**
+ * enum wlan_main_tag  - Main Tag used in logging
+ * @WLAN_CONNECTING: Connecting
+ * @WLAN_CONNECTING_FAIL: Connection failure
+ * @WLAN_AUTH_REQ: Authentication request frame
+ * @WLAN_AUTH_RESP: Authentication response frame
+ * @WLAN_ASSOC_REQ: Association request frame
+ * @WLAN_ASSOC_RSP: Association response frame
+ * @WLAN_REASSOC_REQ: Reassociation request frame
+ * @WLAN_REASSOC_RSP: Reassociation response frame
+ * @WLAN_DEAUTH_RX: Deauthentication frame received
+ * @WLAN_DEAUTH_TX: Deauthentication frame sent
+ * @WLAN_DISASSOC_RX: Disassociation frame received
+ * @WLAN_DISASSOC_TX: Disassociation frame sent
+ * @WLAN_DISCONN_BMISS: Disconnection due to beacon miss
+ * @WLAN_ROAM_SCAN_START: ROAM scan start
+ * @WLAN_ROAM_SCAN_DONE: Roam scan done
+ * @WLAN_ROAM_SCORE_CURR_AP: Roam score current AP
+ * @WLAN_ROAM_SCORE_CAND_AP: Roam Score Candidate AP
+ * @WLAN_ROAM_RESULT: Roam Result
+ * @WLAN_ROAM_CANCEL: Roam Cancel
+ * @WLAN_BTM_REQ:  BTM request
+ * @WLAN_BTM_QUERY: BTM Query frame
+ * @WLAN_BTM_RESP: BTM response frame
+ * @WLAN_BTM_REQ_CANDI: BTM request candidate info
+ * @WLAN_ROAM_WTC: ROAM WTC trigger logs
+ * @WLAN_DHCP_DISCOVER: DHCP discover frame
+ * @WLAN_DHCP_OFFER: DHCP offer frame
+ * @WLAN_DHCP_REQUEST: DHCP Request frame
+ * @WLAN_DHCP_ACK: DHCP ACK
+ * @WLAN_DHCP_NACK: DHCP NACK
+ * @WLAN_EAPOL_M1: EAPOL M1
+ * @WLAN_EAPOL_M2: EAPOL M2
+ * @WLAN_EAPOL_M3: EAPOL M3
+ * @WLAN_EAPOL_M4: EAPOL M4
+ * @WLAN_GTK_M1: GTK rekey M1 frame
+ * @WLAN_GTK_M2: GTK Rekey M2 frame
+ * @WLAN_EAP_REQUEST: EAP request frame
+ * @WLAN_EAP_RESPONSE: EAP response frame
+ * @WLAN_EAP_SUCCESS: EAP success
+ * @WLAN_EAP_FAILURE: EAP failure
+ * @WLAN_CUSTOM_LOG: Additional WLAN logs
+ * @WLAN_TAG_MAX: MAX tag
+ */
+enum wlan_main_tag {
+	WLAN_CONNECTING,
+	WLAN_CONNECTING_FAIL,
+	WLAN_AUTH_REQ,
+	WLAN_AUTH_RESP,
+	WLAN_ASSOC_REQ,
+	WLAN_ASSOC_RSP,
+	WLAN_REASSOC_REQ,
+	WLAN_REASSOC_RSP,
+	WLAN_DEAUTH_RX,
+	WLAN_DEAUTH_TX,
+	WLAN_DISASSOC_RX,
+	WLAN_DISASSOC_TX,
+	WLAN_DISCONN_BMISS,
+	WLAN_ROAM_SCAN_START,
+	WLAN_ROAM_SCAN_DONE,
+	WLAN_ROAM_SCORE_CURR_AP,
+	WLAN_ROAM_SCORE_CAND_AP,
+	WLAN_ROAM_RESULT,
+	WLAN_ROAM_CANCEL,
+	WLAN_BTM_REQ,
+	WLAN_BTM_QUERY,
+	WLAN_BTM_RESP,
+	WLAN_BTM_REQ_CANDI,
+	WLAN_ROAM_WTC,
+	WLAN_DHCP_DISCOVER,
+	WLAN_DHCP_OFFER,
+	WLAN_DHCP_REQUEST,
+	WLAN_DHCP_ACK,
+	WLAN_DHCP_NACK,
+	WLAN_EAPOL_M1,
+	WLAN_EAPOL_M2,
+	WLAN_EAPOL_M3,
+	WLAN_EAPOL_M4,
+	WLAN_GTK_M1,
+	WLAN_GTK_M2,
+	WLAN_EAP_REQUEST,
+	WLAN_EAP_RESPONSE,
+	WLAN_EAP_SUCCESS,
+	WLAN_EAP_FAILURE,
+	WLAN_CUSTOM_LOG,
+	/* Keep at last */
+	WLAN_TAG_MAX,
+};
+
+/**
+ * enum qca_conn_diag_log_event_type  - Diag Event subtype used in logging
+ * @WLAN_CONN_DIAG_CONNECTING_EVENT: Connecting
+ * @WLAN_CONN_DIAG_CONNECT_FAIL_EVENT: Connection failure
+ * @WLAN_CONN_DIAG_AUTH_REQ_EVENT: Authentication request frame
+ * @WLAN_CONN_DIAG_AUTH_RESP_EVENT: Authentication response frame
+ * @WLAN_CONN_DIAG_ASSOC_REQ_EVENT: Association request frame
+ * @WLAN_CONN_DIAG_ASSOC_RESP_EVENT: Association response frame
+ * @WLAN_CONN_DIAG_REASSOC_REQ_EVENT: Reassociation request frame
+ * @WLAN_CONN_DIAG_REASSOC_RESP_EVENT: Reassociation response frame
+ * @WLAN_CONN_DIAG_DEAUTH_RX_EVENT: Deauthentication frame received
+ * @WLAN_CONN_DIAG_DEAUTH_TX_EVENT: Deauthentication frame sent
+ * @WLAN_CONN_DIAG_DISASSOC_RX_EVENT: Disassociation frame received
+ * @WLAN_CONN_DIAG_DISASSOC_TX_EVENT: Disassociation frame sent
+ * @WLAN_CONN_DIAG_BMISS_EVENT: Disconnection due to beacon miss
+ * @WLAN_CONN_DIAG_ROAM_SCAN_START_EVENT: ROAM scan start
+ * @WLAN_CONN_DIAG_ROAM_SCAN_DONE_EVENT: Roam scan done
+ * @WLAN_CONN_DIAG_ROAM_SCORE_CUR_AP_EVENT: Roam score current AP
+ * @WLAN_CONN_DIAG_ROAM_SCORE_CAND_AP_EVENT: Roam Score Candidate AP
+ * @WLAN_CONN_DIAG_ROAM_RESULT_EVENT: Roam Result
+ * @WLAN_CONN_DIAG_ROAM_CANCEL_EVENT: Roam Cancel
+ * @WLAN_CONN_DIAG_BTM_REQ_EVENT:  BTM request
+ * @WLAN_CONN_DIAG_BTM_QUERY_EVENT: BTM Query frame
+ * @WLAN_CONN_DIAG_BTM_RESP_EVENT: BTM response frame
+ * @WLAN_CONN_DIAG_BTM_REQ_CAND_EVENT: BTM request candidate info
+ * @WLAN_CONN_DIAG_BTM_WTC_EVENT: ROAM WTC trigger logs
+ * @WLAN_CONN_DIAG_DHCP_DISC_EVENT: DHCP discover frame
+ * @WLAN_CONN_DIAG_DHCP_OFFER_EVENT: DHCP offer frame
+ * @WLAN_CONN_DIAG_DHCP_REQUEST_EVENT: DHCP Request frame
+ * @WLAN_CONN_DIAG_DHCP_ACK_EVENT: DHCP ACK
+ * @WLAN_CONN_DIAG_DHCP_NACK_EVENT: DHCP NACK
+ * @WLAN_CONN_DIAG_EAPOL_M1_EVENT: EAPOL M1
+ * @WLAN_CONN_DIAG_EAPOL_M2_EVENT: EAPOL M2
+ * @WLAN_CONN_DIAG_EAPOL_M3_EVENT: EAPOL M3
+ * @WLAN_CONN_DIAG_EAPOL_M4_EVENT: EAPOL M4
+ * @WLAN_CONN_DIAG_GTK_M1_EVENT: GTK rekey M1 frame
+ * @WLAN_CONN_DIAG_GTK_M2_EVENT: GTK Rekey M2 frame
+ * @WLAN_CONN_DIAG_EAP_REQ_EVENT: EAP request frame
+ * @WLAN_CONN_DIAG_EAP_RESP_EVENT: EAP response frame
+ * @WLAN_CONN_DIAG_EAP_SUCC_EVENT: EAP success
+ * @WLAN_CONN_DIAG_EAP_FAIL_EVENT: EAP failure
+ * @WLAN_CONN_DIAG_CUSTOM_EVENT: Additional WLAN logs
+ * @WLAN_CONN_DIAG_EAP_START_EVENT: EAPOL start frame
+ * @WLAN_CONN_DIAG_NBR_RPT_REQ_EVENT: Neighbor report request
+ * @WLAN_CONN_DIAG_NBR_RPT_RESP_EVENT: Neighbor report response
+ * @WLAN_CONN_DIAG_BCN_RPT_REQ_EVENT: Beacon report request
+ * @WLAN_CONN_DIAG_BCN_RPT_RESP_EVENT: Beacon report response
+ * @WLAN_CONN_DIAG_MLO_T2LM_REQ_EVENT: MLO T2LM request
+ * @WLAN_CONN_DIAG_MLO_T2LM_RESP_EVENT: MLO T2LM response
+ * @WLAN_CONN_DIAG_BTM_BLOCK_EVENT: BTM-drop indication
+ * @WLAN_CONN_DIAG_MAX: MAX tag
+ */
+enum qca_conn_diag_log_event_type {
+	WLAN_CONN_DIAG_CONNECTING_EVENT = 0,
+	WLAN_CONN_DIAG_CONNECT_FAIL_EVENT,
+	WLAN_CONN_DIAG_AUTH_REQ_EVENT,
+	WLAN_CONN_DIAG_AUTH_RESP_EVENT,
+	WLAN_CONN_DIAG_ASSOC_REQ_EVENT,
+	WLAN_CONN_DIAG_ASSOC_RESP_EVENT,
+	WLAN_CONN_DIAG_REASSOC_REQ_EVENT,
+	WLAN_CONN_DIAG_REASSOC_RESP_EVENT,
+	WLAN_CONN_DIAG_DEAUTH_RX_EVENT,
+	WLAN_CONN_DIAG_DEAUTH_TX_EVENT,
+	WLAN_CONN_DIAG_DISASSOC_RX_EVENT,
+	WLAN_CONN_DIAG_DISASSOC_TX_EVENT,
+	WLAN_CONN_DIAG_BMISS_EVENT,
+	WLAN_CONN_DIAG_ROAM_SCAN_START_EVENT,
+	WLAN_CONN_DIAG_ROAM_SCAN_DONE_EVENT,
+	WLAN_CONN_DIAG_ROAM_SCORE_CUR_AP_EVENT,
+	WLAN_CONN_DIAG_ROAM_SCORE_CAND_AP_EVENT,
+	WLAN_CONN_DIAG_ROAM_RESULT_EVENT,
+	WLAN_CONN_DIAG_ROAM_CANCEL_EVENT,
+	WLAN_CONN_DIAG_BTM_REQ_EVENT,
+	WLAN_CONN_DIAG_BTM_QUERY_EVENT,
+	WLAN_CONN_DIAG_BTM_RESP_EVENT,
+	WLAN_CONN_DIAG_BTM_REQ_CAND_EVENT,
+	WLAN_CONN_DIAG_BTM_WTC_EVENT,
+	WLAN_CONN_DIAG_DHCP_DISC_EVENT,
+	WLAN_CONN_DIAG_DHCP_OFFER_EVENT,
+	WLAN_CONN_DIAG_DHCP_REQUEST_EVENT,
+	WLAN_CONN_DIAG_DHCP_ACK_EVENT,
+	WLAN_CONN_DIAG_DHCP_NACK_EVENT,
+	WLAN_CONN_DIAG_EAPOL_M1_EVENT,
+	WLAN_CONN_DIAG_EAPOL_M2_EVENT,
+	WLAN_CONN_DIAG_EAPOL_M3_EVENT,
+	WLAN_CONN_DIAG_EAPOL_M4_EVENT,
+	WLAN_CONN_DIAG_GTK_M1_EVENT,
+	WLAN_CONN_DIAG_GTK_M2_EVENT,
+	WLAN_CONN_DIAG_EAP_REQ_EVENT,
+	WLAN_CONN_DIAG_EAP_RESP_EVENT,
+	WLAN_CONN_DIAG_EAP_SUCC_EVENT,
+	WLAN_CONN_DIAG_EAP_FAIL_EVENT,
+	WLAN_CONN_DIAG_CUSTOM_EVENT,
+	WLAN_CONN_DIAG_EAP_START_EVENT,
+	WLAN_CONN_DIAG_NBR_RPT_REQ_EVENT,
+	WLAN_CONN_DIAG_NBR_RPT_RESP_EVENT,
+	WLAN_CONN_DIAG_BCN_RPT_REQ_EVENT,
+	WLAN_CONN_DIAG_BCN_RPT_RESP_EVENT,
+	WLAN_CONN_DIAG_MLO_T2LM_REQ_EVENT,
+	WLAN_CONN_DIAG_MLO_T2LM_RESP_EVENT,
+	WLAN_CONN_DIAG_BTM_BLOCK_EVENT,
+	WLAN_CONN_DIAG_MAX
+};
+
+/*
+ * enum wlan_diag_wifi_band - Enum describing wifi band
+ * @WLAN_INVALID_BAND: invalid band
+ * @WLAN_24GHZ_BAND: 2.4 GHz band
+ * @WLAN_5GHZ_BAND: 5 GHz band
+ * @WLAN_6GHZ_BAND: 6 GHz band
+ */
+enum wlan_diag_wifi_band {
+	WLAN_INVALID_BAND = 0,
+	WLAN_24GHZ_BAND,
+	WLAN_5GHZ_BAND,
+	WLAN_6GHZ_BAND,
+};
+
+/**
+ * enum wlan_diag_mlo_link_switch_reason - MLO link switch reason enumeration
+ * @LINK_STATE_SWITCH_REASON_VDEV_READY: Link switch when vdev is ready
+ * @LINK_STATE_SWITCH_REASON_ULL_MODE: Link switch due to ULL mode configuration
+ * @LINK_STATE_SWITCH_REASON_T2LM_ENABLE: Link switch due to T2LM enable
+ * @LINK_STATE_SWITCH_REASON_T2LM_DISABLE: Link switch due T2LM disable
+ * @LINK_STATE_SWITCH_REASON_FORCE_ENABLED: Link switch when link is
+ * forcibly enable
+ * @LINK_STATE_SWITCH_REASON_FORCE_DISABLED: Link switch when link is
+ * forcibly disable
+ * @LINK_STATE_SWITCH_REASON_LINK_QUALITY: Link switch due to
+ * poor link quality
+ * @LINK_STATE_SWITCH_REASON_LINK_CAPACITY: Link switch due to link capacity
+ * @LINK_STATE_SWITCH_REASON_RSSI: Link switch due to changes in rssi
+ * @LINK_STATE_SWITCH_REASON_BMISS: Link switch due to BMISS
+ * @LINK_STATE_SWITCH_REASON_BT_STATUS: Link switch due to BT status
+ * @LINK_STATE_SWITCH_REASON_MAX: Max value
+ */
+enum wlan_diag_mlo_link_switch_reason {
+	LINK_STATE_SWITCH_REASON_VDEV_READY = 0,
+	LINK_STATE_SWITCH_REASON_ULL_MODE = 1,
+	LINK_STATE_SWITCH_REASON_T2LM_ENABLE = 2,
+	LINK_STATE_SWITCH_REASON_T2LM_DISABLE = 3,
+	LINK_STATE_SWITCH_REASON_FORCE_ENABLED = 4,
+	LINK_STATE_SWITCH_REASON_FORCE_DISABLED = 5,
+	LINK_STATE_SWITCH_REASON_LINK_QUALITY = 6,
+	LINK_STATE_SWITCH_REASON_LINK_CAPACITY = 7,
+	LINK_STATE_SWITCH_REASON_RSSI = 8,
+	LINK_STATE_SWITCH_REASON_BMISS = 9,
+	LINK_STATE_SWITCH_REASON_BT_STATUS = 10,
+	LINK_STATE_SWITCH_REASON_MAX,
+};
+
+/**
+ * enum wlan_bcn_rpt_measurement_mode - Measurement mode enum.
+ * Defined in IEEE Std 802.11‐2020 Table 9-103.
+ * @MEASURE_MODE_PASSIVE: Passive measurement mode
+ * @MEASURE_MODE_ACTIVE: Active measurement mode
+ * @MEASURE_MODE_BCN_TABLE: Beacon table measurement mode
+ * @MEASURE_MODE_RESERVED: Reserved
+ */
+enum wlan_bcn_rpt_measurement_mode {
+	MEASURE_MODE_PASSIVE = 0,
+	MEASURE_MODE_ACTIVE,
+	MEASURE_MODE_BCN_TABLE,
+	MEASURE_MODE_RESERVED = 0xFF
+};
+
+/**
+ * enum wlan_diag_connect_fail_reason - WLAN diag connect fail reason code
+ * @WLAN_DIAG_UNSPECIFIC_REASON: Unspecific reason
+ * @WLAN_DIAG_NO_CANDIDATE_FOUND: No candidate found
+ * @WLAN_DIAG_ABORT_DUE_TO_NEW_REQ_RECVD: Aborted as new command is
+ * received.
+ * @WLAN_DIAG_BSS_SELECT_IND_FAILED: Failed BSS select indication
+ * @WLAN_DIAG_PEER_CREATE_FAILED: peer create failed
+ * @WLAN_DIAG_JOIN_FAILED: Failed in joining state
+ * @WLAN_DIAG_JOIN_TIMEOUT: Did not receive beacon or probe response after
+ * unicast probe request
+ * @WLAN_DIAG_AUTH_FAILED: Auth rejected by AP
+ * @WLAN_DIAG_AUTH_TIMEOUT: No Auth resp from AP
+ * @WLAN_DIAG_ASSOC_FAILED: Assoc rejected by AP
+ * @WLAN_DIAG_ASSOC_TIMEOUT: No Assoc resp from AP
+ * @WLAN_DIAG_HW_MODE_FAILURE: failed to change HW mode
+ * @WLAN_DIAG_SER_FAILURE: Failed to serialize command
+ * @WLAN_DIAG_SER_TIMEOUT: Serialization cmd timeout
+ * @WLAN_DIAG_GENERIC_FAILURE: Generic failure apart from above
+ * @WLAN_DIAG_VALID_CANDIDATE_CHECK_FAIL: Valid Candidate Check fail
+ */
+enum wlan_diag_connect_fail_reason {
+	WLAN_DIAG_UNSPECIFIC_REASON = 0,
+	WLAN_DIAG_NO_CANDIDATE_FOUND = 1,
+	WLAN_DIAG_ABORT_DUE_TO_NEW_REQ_RECVD,
+	WLAN_DIAG_BSS_SELECT_IND_FAILED,
+	WLAN_DIAG_PEER_CREATE_FAILED,
+	WLAN_DIAG_JOIN_FAILED,
+	WLAN_DIAG_JOIN_TIMEOUT,
+	WLAN_DIAG_AUTH_FAILED,
+	WLAN_DIAG_AUTH_TIMEOUT,
+	WLAN_DIAG_ASSOC_FAILED,
+	WLAN_DIAG_ASSOC_TIMEOUT,
+	WLAN_DIAG_HW_MODE_FAILURE,
+	WLAN_DIAG_SER_FAILURE,
+	WLAN_DIAG_SER_TIMEOUT,
+	WLAN_DIAG_GENERIC_FAILURE,
+	WLAN_DIAG_VALID_CANDIDATE_CHECK_FAIL,
+};
+
+/**
+ * enum wlan_diag_btm_block_reason - BTM drop/ignore reason code
+ * @WLAN_DIAG_BTM_BLOCK_MBO_WO_PMF: Connected to MBO without PMF capable AP
+ * @WLAN_DIAG_BTM_BLOCK_UNSUPPORTED_P2P_CONC: p2p go/cli is present which
+ *  restricts BTM roaming
+ */
+enum wlan_diag_btm_block_reason {
+	WLAN_DIAG_BTM_BLOCK_MBO_WO_PMF = 1,
+	WLAN_DIAG_BTM_BLOCK_UNSUPPORTED_P2P_CONC = 2,
+};
+
+/**
+ * struct wlan_connectivity_log_diag_cmn - Structure for diag event
+ * @bssid: bssid
+ * @vdev_id: Vdev id
+ * @timestamp_us: Timestamp(time of the day) in microseconds
+ * @fw_timestamp: FW timestamp in microseconds
+ * @ktime_us: Kernel Timestamp in microseconds
+ */
+struct wlan_connectivity_log_diag_cmn {
+	uint8_t bssid[QDF_MAC_ADDR_SIZE];
+	uint16_t vdev_id;
+	uint64_t timestamp_us;
+	uint64_t fw_timestamp;
+	uint64_t ktime_us;
+} qdf_packed;
+
+#define DIAG_STA_INFO_VERSION 1
+
+/**
+ * struct wlan_diag_sta_info - STA info structure
+ * @diag_cmn: Common diag info
+ * @version: structure version
+ * @is_mlo: MLO connection bit
+ * @mac_2g: 2.4 GHz link station mac address
+ * @mac_5g: 5 GHz link station mac address
+ * @mac_6g: 6 GHz link station mac address
+ */
+struct wlan_diag_sta_info {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t is_mlo;
+	uint8_t mac_2g[QDF_MAC_ADDR_SIZE];
+	uint8_t mac_5g[QDF_MAC_ADDR_SIZE];
+	uint8_t mac_6g[QDF_MAC_ADDR_SIZE];
+} qdf_packed;
+
+/*
+ * struct wlan_diag_mlo_cmn_info - MLO common info
+ * @band: Indicates link on which mlo setup is initiated.
+ * Refer enum enum wlan_diag_wifi_band.
+ * @link_id: Link id of the link when link is accepted
+ * @vdev_id: vdev id associated with the link
+ * @tid_ul: TID-to-link mapping information on the uplink
+ * @tid_dl: TID-to-link mapping information on the downlink
+ * @status: MLO setup status. 0 - Success, 1 - failure
+ * @link_addr: Link address of the link.
+ */
+struct wlan_diag_mlo_cmn_info {
+	uint8_t band;
+	uint8_t link_id;
+	uint8_t vdev_id;
+	uint8_t tid_ul;
+	uint8_t tid_dl;
+	uint8_t status;
+	uint8_t link_addr[QDF_MAC_ADDR_SIZE];
+} qdf_packed;
+
+#define DIAG_MLO_SETUP_VERSION 1
+#define DIAG_MLO_SETUP_VERSION_V2 2
+
+#define MAX_NUM_LINKS_PER_EVENT 3
+/**
+ * struct wlan_diag_mlo_setup - MLO setup structure
+ * @diag_cmn: Common diag info
+ * @version: structure version
+ * @num_links: Number of links associated for MLO setup
+ * @reserved: Reserved field
+ * @status: status code of the link. Non-zero value when link is rejected
+ * @mlo_cmn_info: MLO common info
+ */
+struct wlan_diag_mlo_setup {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t num_links;
+	uint16_t reserved;
+	struct wlan_diag_mlo_cmn_info mlo_cmn_info[MAX_NUM_LINKS_PER_EVENT];
+} qdf_packed;
+
+#define DIAG_MLO_RECONFIG_VERSION 1
+
+/**
+ * struct wlan_diag_mlo_reconfig - MLO reconfig diag event structure
+ * @diag_cmn: Common diag info
+ * @version: structure version
+ * @reserved: Reserved field
+ * @mlo_cmn_info: MLO common info
+ */
+struct wlan_diag_mlo_reconfig {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint32_t version:8;
+	uint32_t reserved:24;
+	struct wlan_diag_mlo_cmn_info mlo_cmn_info;
+} qdf_packed;
+
+#define DIAG_MLO_T2LM_STATUS_VERSION 1
+#define DIAG_MLO_T2LM_STATUS_VERSION_V2 2
+
+/**
+ * struct wlan_diag_mlo_t2lm_status - MLO T2LM status diag event structure
+ * @diag_cmn: Common diag info
+ * @version: structure version
+ * @num_links: Number of links associated for T2LM status
+ * @reserved: Reserved field
+ * @mlo_cmn_info: MLO common info
+ */
+struct wlan_diag_mlo_t2lm_status {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t num_links;
+	uint16_t reserved;
+	struct wlan_diag_mlo_cmn_info mlo_cmn_info[MAX_NUM_LINKS_PER_EVENT];
+} qdf_packed;
+
+#define DIAG_MLO_T2LM_REQ_RESP_VERSION 1
+
+/**
+ * struct wlan_diag_mlo_t2lm_req_resp - MLO T2LM Req/Resp diag event structure
+ * @diag_cmn: Common diag info
+ * @version: Structure version
+ * @band: Indicates the band of the link
+ * @status: status code of TID-to-Link mapping response frame
+ * @token: Dialog Token field of TID-To-Link Mapping Request/Response frame
+ * @is_rx: Indicates the direction of packet. 0 - TX and 1 - RX
+ * @tx_status: tx status of transmitted packet. Refer enum qdf_dp_tx_rx_status
+ * @subtype: Subtype of the event
+ * @reserved: Reserved field
+ */
+struct wlan_diag_mlo_t2lm_req_resp {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t band;
+	uint8_t status;
+	uint8_t token;
+	uint8_t is_rx:1;
+	uint8_t tx_status:7;
+	uint8_t subtype;
+	uint16_t reserved;
+} qdf_packed;
+
+#define DIAG_MLO_T2LM_TEARDOWN_VERSION 1
+
+/**
+ * struct wlan_diag_mlo_t2lm_teardown - MLO T2LM Teardown diag event structure
+ * @diag_cmn: Common diag info
+ * @version: structure version
+ * @band: Indicates the band of the link. Refer enum wlan_diag_wifi_band
+ * @tx_status: tx status of transmitted packet. Refer enum qdf_dp_tx_rx_status
+ * @reserved: Reserved field
+ */
+struct wlan_diag_mlo_t2lm_teardown {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t band;
+	uint8_t tx_status;
+	uint8_t reserved;
+} qdf_packed;
+
+#define DIAG_MLO_LINK_STATUS_VERSION 1
+#define DIAG_MLO_LINK_STATUS_VERSION_2 2
+/**
+ * struct wlan_diag_mlo_link_status - MLO Link status diag event structure
+ * @diag_cmn: Common diag info
+ * @version: structure version
+ * @active_link: List of current active links. BIT 0: 2.4 GHz BIT 1: 5 GHz
+ * BIT 2: 6 GHz
+ * @prev_active_link: List of previous active links. BIT 0: 2.4 G Hz
+ * BIT 1: 5 GHz BIT 2: 6 GHz
+ * @associated_links: Links associated in the current connection.
+ * BIT 0: 2.4 GHz BIT 1: 5 GHz BIT 2: 6 GHz
+ * @reserved: Reserved field
+ * @reason: Reason for changed link status. Refer
+ * enum wlan_diag_mlo_link_switch_reason
+ */
+struct wlan_diag_mlo_link_status {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t active_link:5;
+	uint8_t prev_active_link:5;
+	uint8_t associated_links:5;
+	uint8_t reserved:1;
+	uint8_t reason;
+} qdf_packed;
+
+#define DIAG_NBR_RPT_VERSION 1
+#define DIAG_NBR_RPT_VERSION_2 2
+
+/**
+ * struct wlan_diag_nbr_rpt - Neighbor report structure
+ * @diag_cmn: Common diag info
+ * @version: structure version
+ * @num_rpt: the number of neighbor report elements in response frame.
+ * @subtype: Event Subtype
+ * @token: dialog token. Dialog Token is a nonzero value chosen by the STA
+ * @num_freq: Number of frequency in response frame
+ * @ssid_len: SSID length
+ * @seq_num: Sequence number
+ * @ssid: SSID
+ * @freq: Frequency list in response frame
+ * @band: Band on which packet was received or transmitted.
+ * Refer enum enum wlan_diag_wifi_band
+ * @reserved: Reserved field
+ */
+struct wlan_diag_nbr_rpt {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t num_rpt;
+	uint8_t subtype;
+	uint8_t token;
+	uint16_t num_freq;
+	uint16_t ssid_len;
+	uint32_t seq_num;
+	char ssid[WLAN_SSID_MAX_LEN];
+	uint32_t freq[WLAN_MAX_LOGGING_FREQ];
+	uint32_t band:8;
+	uint32_t reserved:24;
+} qdf_packed;
+
+#define DIAG_BCN_RPT_VERSION 1
+#define DIAG_BCN_RPT_VERSION_2 2
+
+/**
+ * struct wlan_diag_bcn_rpt - Beacon report structure
+ * @diag_cmn: Common diag info
+ * @version: structure version
+ * @subtype: Event Subtype
+ * @diag_token: Dialog token
+ * @op_class: Operating classes that include primary channels
+ * @chan: The channel number field in the beacon report request.
+ * @req_mode: hex value defines Duration mandatory, parallel, enable,
+ * request, and report bits.
+ * @num_rpt: the number of neighbor report elements in response frame.
+ * @meas_token: A nonzero number that is unique among the Measurement Request
+ * elements
+ * @mode: Mode used for measurement.Values defined in IEEE
+ * Std 802.11‐2020 Table 9-103.
+ * @duration: The duration over which the Beacon report was measured.(in ms)
+ * @seq_num: Sequence number.
+ * @band: Band on which packet was received or transmitted.
+ * Refer enum enum wlan_diag_wifi_band
+ * @reserved: Reserved field
+ */
+struct wlan_diag_bcn_rpt {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t subtype;
+	uint8_t diag_token;
+	uint8_t op_class;
+	uint8_t chan;
+	uint8_t req_mode;
+	uint8_t num_rpt;
+	uint8_t meas_token;
+	uint16_t mode;
+	uint16_t duration;
+	uint32_t seq_num;
+	uint32_t band:8;
+	uint32_t reserved:24;
+} qdf_packed;
+
+#define DIAG_ROAM_CAND_VERSION 1
+#define DIAG_ROAM_CAND_VERSION_V2 2
+
+/**
+ * struct wlan_diag_roam_candidate_info  - Roam candidate information for
+ * logging
+ * @diag_cmn: Common diag info
+ * @version: Structure Version
+ * @is_current_ap: Is the entry candidate AP or connected AP
+ * @is_mlo: MLO connection indicator
+ * @reserved: Reserved
+ * @idx: Entry index
+ * @cu_load: Channel utilization load of the AP in percentage
+ * @subtype: diag event subtype defined in enum qca_conn_diag_log_event_type
+ * @total_score: Total candidate AP score
+ * @freq: Candidate AP channel frequency in MHz
+ * @rssi: Candidate AP RSSI in dBm
+ * @etp: Estimated throughput value of the AP in Kbps
+ */
+struct wlan_diag_roam_candidate_info {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t is_current_ap:1;
+	uint8_t is_mlo:1;
+	uint8_t reserved:6;
+	uint16_t idx;
+	uint16_t cu_load;
+	uint16_t subtype;
+	uint32_t total_score;
+	uint32_t freq;
+	int32_t rssi;
+	uint32_t etp;
+} qdf_packed;
+
+#define DIAG_SCAN_DONE_VERSION 1
+
+/**
+ * struct wlan_diag_roam_scan_done - Roam scan related information
+ * @diag_cmn: Common diag info
+ * @version: Structure Version
+ * @btcoex_active: Is there active bluetooth connection
+ * @reserved: Reserved field
+ * @cand_ap_count: Roam candidate AP count
+ * @num_scanned_freq: Number of scanned frequencies
+ * @scan_freq: Array of scanned frequencies value in MHz
+ */
+struct wlan_diag_roam_scan_done {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t btcoex_active:1;
+	uint8_t reserved:7;
+	uint16_t cand_ap_count;
+	uint16_t num_scanned_freq;
+	uint32_t scan_freq[WLAN_MAX_LOGGING_FREQ];
+} qdf_packed;
+
+#define DIAG_ROAM_RESULT_VERSION 1
+
+/**
+ * struct wlan_diag_roam_result - Roam result data
+ * @diag_cmn: Common diag info
+ * @version: Structure Version
+ * @is_roam_successful: True if roamed successfully or false if roaming failed
+ * @is_mlo: Indicates whether the current connection is a MLO connection
+ * @reserved: Reserved
+ * @roam_fail_reason: Roam failure reason code defined in enum
+ * wlan_roam_failure_reason_code
+ */
+struct wlan_diag_roam_result {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t is_roam_successful:1;
+	uint8_t is_mlo:1;
+	uint8_t reserved:6;
+	uint16_t roam_fail_reason;
+} qdf_packed;
+
+#define DIAG_ROAM_SCAN_START_VERSION 1
+#define DIAG_ROAM_SCAN_START_VERSION_V2 2
+
+/**
+ * struct wlan_diag_roam_scan_start - Structure to store roam scan trigger
+ * related data.
+ * @diag_cmn: Common diag info
+ * @version: Structure Version
+ * @is_full_scan: True if the scan is Full scan. False if the roam scan is
+ * partial channel map scan
+ * @band: Band involved in the roaming during a MLO connection.
+ * Refer enum enum wlan_diag_wifi_band
+ * @cu:  Current connected channel load in percentage
+ * @trigger_reason: Roam trigger reason defined by enum roam_trigger_reason
+ * @trigger_sub_reason: Roam scan trigger sub reason indicating if
+ * periodic/inactivity scan timer initiated roam. Defined by enum
+ * roam_trigger_sub_reason
+ * @rssi: Connected AP RSSI in dBm
+ * @rssi_thresh: Roam scan trigger threshold in dBm
+ */
+struct wlan_diag_roam_scan_start {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t is_full_scan:1;
+	uint8_t band:7;
+	uint16_t cu;
+	uint32_t trigger_reason;
+	uint32_t trigger_sub_reason;
+	int32_t rssi;
+	int32_t rssi_thresh;
+} qdf_packed;
+
+#define DIAG_BTM_CAND_VERSION 1
+
+/**
+ * struct wlan_diag_btm_cand_info  - BTM candidate information
+ * @diag_cmn: Common diag info
+ * @version: Structure Version
+ * @pad: Padded field
+ * @idx: Candidate index
+ * @preference: Candidate preference
+ */
+struct wlan_diag_btm_cand_info {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t pad;
+	uint16_t idx;
+	uint32_t preference;
+} qdf_packed;
+
+#define DIAG_BTM_VERSION 1
+#define DIAG_BTM_VERSION_2 2
+
+/**
+ * struct wlan_diag_btm_info - BTM frame related logging data
+ * @diag_cmn: Common diag info
+ * @version: Structure Version
+ * @reason: Query Reason field. Contains one of the values defined in IEEE
+ * Std 802.11‐2020 Table 9-198—Transition and Transition Query reasons
+ * @mode: BTM Request Mode field
+ * @sub_reason: WTC sub reason code field in the BTM WTC vendor specific IE
+ * @cand_lst_cnt: Candidates list in the BTM frame
+ * @status: BSS Transition management status codes defined in
+ * 802.11‐2020 Table 9-428—BTM status code definitions
+ * @delay: BSS Termination Delay field
+ * @is_disassoc_imminent: Disassociation imminent bit
+ * @band: indicates the link involved in MLO conenection.
+ * Refer enum enum wlan_diag_wifi_band
+ * @token: dialog token. Dialog Token is a nonzero value chosen by the STA
+ * @wtc_duration: WTC duration field in minutes
+ * while sending the BTM frame to identify the query/request/response
+ * transaction
+ * @subtype: Event Subtype
+ * @validity_timer: Validity interval in TBTT
+ * @disassoc_tim: Time after which the AP disassociates the STA, defined
+ * in TBTT.
+ */
+struct wlan_diag_btm_info {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t reason;
+	uint8_t mode;
+	uint8_t sub_reason;
+	uint8_t cand_lst_cnt;
+	uint8_t status;
+	uint8_t delay;
+	uint8_t is_disassoc_imminent:1;
+	uint8_t band:7;
+	uint8_t token;
+	uint8_t subtype;
+	uint16_t wtc_duration;
+	uint32_t validity_timer;
+	uint32_t disassoc_tim;
+} qdf_packed;
+
+#define DIAG_MGMT_VERSION 1
+#define DIAG_MGMT_VERSION_V2 2
+#define MAX_VSIE_LEN 255
+
+/**
+ * struct wlan_diag_packet_info - Data packets related info
+ * @diag_cmn: Common diag info
+ * @version: Structure Version
+ * @auth_algo: authentication algorithm number defined in IEEE Std 802.11‐2020
+ * @auth_frame_type: Authentication frame sub-type for SAE authentication
+ * defined in Section 9.4.1.1 Authentication Algorithm Number field in
+ * IEEE Std 802.11‐2020.
+ * @auth_seq_num: Authentication frame transaction sequence number
+ * @status: Frame status code as defined in IEEE Std
+ * 802.11‐2020 Table 9-50—Status codes.
+ * @tx_status: Frame TX status defined by enum qdf_dp_tx_rx_status
+ * @reason: reason code defined in Table 9-49 Reason codes field’ from the
+ * IEEE 802.11 standard document.
+ * @is_retry_frame: Retry frame indicator
+ * @is_tx: Packet direction indicator. 0 - RX, 1 - TX
+ * @supported_links: link id bitmap indicates the links involved
+ * in MLO connection.
+ * @reserved: Reserved field
+ * @subtype: Diag event defined in  enum qca_conn_diag_log_event_type
+ * @assoc_id: Association ID
+ * @eap_len: EAP data length
+ * @eap_type: EAP type. Values defined by IANA at:
+ * https://www.iana.org/assignments/eap-numbers
+ * @sn: Frame sequence number
+ * @rssi: Peer RSSI in dBm
+ * @tx_fail_reason: tx failure reason printed on TX_FAIL status.
+ * Refer enum qdf_dp_tx_rx_status
+ * @mld_addr: MLD mac address
+ * @vsie_len: VSIE length
+ * @vsie: VSIE
+ */
+struct wlan_diag_packet_info {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t auth_algo;
+	uint8_t auth_frame_type;
+	uint8_t auth_seq_num;
+	uint8_t status;
+	uint8_t tx_status;
+	uint8_t reason;
+	uint8_t is_retry_frame:1;
+	uint8_t is_tx:1;
+	uint8_t supported_links:6;
+	uint16_t subtype;
+	uint16_t assoc_id;
+	uint16_t eap_len;
+	uint16_t eap_type;
+	uint32_t sn;
+	int32_t rssi;
+	uint8_t tx_fail_reason;
+	uint8_t mld_addr[QDF_MAC_ADDR_SIZE];
+	uint8_t vsie_len;
+	uint8_t vsie[MAX_VSIE_LEN];
+} qdf_packed;
+
+#define DIAG_CONN_VERSION 1
+
+/**
+ * struct wlan_diag_connect - Connection related info
+ * @diag_cmn: Common diag info
+ * @version: Version number
+ * @auth_algo: Authentication algorithm number field as defined in
+ * IEEE 802.11 - 2020 standard section 9.4.1.1
+ * @bt_coex: Is there active bluetooth connection
+ * @reserved: Reserved field
+ * @ssid_len: Length of SSID
+ * @ssid: SSID
+ * @bssid_hint: BSSID hint provided in the connect request
+ * @reason: failure reason. Refer enum wlan_cm_connect_fail_reason
+ * @akm: Auth key management suite defined in IEEE Std 802.11‐2020
+ * Table 9-151—AKM suite selectors.
+ * @subtype: Event subtype defined in enum qca_conn_diag_log_event_type.
+ * @freq: Frequency in MHz
+ * @freq_hint: Frequency Hint in MHz
+ * @pairwise_cipher: Pairwise suite value as defined in IEEE 802.11 2020
+ * Table 12-10—Integrity and key wrap algorithms.
+ * @grp_cipher: Group cipher suite value as defined in
+ * Table 12-10—Integrity and key wrap algorithm in IEEE 802.11 2020.
+ * @grp_mgmt: Group management cipher suite as defined in
+ * Table 12-10—Integrity and key wrap algorithms in IEEE 802.11 2020.
+ */
+struct wlan_diag_connect {
+	struct wlan_connectivity_log_diag_cmn diag_cmn;
+	uint8_t version;
+	uint8_t auth_algo;
+	uint8_t bt_coex:1;
+	uint8_t reserved:7;
+	uint8_t ssid_len;
+	char ssid[WLAN_SSID_MAX_LEN];
+	uint8_t bssid_hint[6];
+	uint16_t reason;
+	uint32_t akm;
+	uint32_t subtype;
+	uint32_t freq;
+	uint32_t freq_hint;
+	uint32_t pairwise_cipher;
+	uint32_t grp_cipher;
+	uint32_t grp_mgmt;
+} qdf_packed;
+
+/**
+ * struct wlan_roam_candidate_info  - Roam candidate information for logging
+ * @cand_bssid: BSSID of the candidate AP
+ * @is_current_ap: Is the entry candidate AP or connected AP
+ * @idx: Entry index
+ * @cu_load: Channel utilization load of the AP in percentage
+ * @freq: Candidate AP channel frequency in MHz
+ * @total_score: Total candidate AP score
+ * @rssi: Candidate AP RSSI in dBm
+ * @etp: Estimated throughput value of the AP in Kbps
+ */
+struct wlan_roam_candidate_info {
+	struct qdf_mac_addr cand_bssid;
+	bool is_current_ap;
+	uint8_t idx;
+	uint8_t cu_load;
+	qdf_freq_t freq;
+	uint16_t total_score;
+	int32_t rssi;
+	uint32_t etp;
+};
+
+/**
+ * struct wlan_roam_scan_info  - Roam scan related information
+ * @cand_ap_count: Roam candidate AP count
+ * @num_scanned_freq: Number of scanned frequencies
+ * @is_btcoex_active: Is bluetooth coex active
+ * @scan_freq: Array of scanned frequencies value in MHz
+ */
+struct wlan_roam_scan_info {
+	uint8_t cand_ap_count;
+	uint16_t num_scanned_freq;
+	bool is_btcoex_active;
+	qdf_freq_t scan_freq[NUM_CHANNELS];
+};
+
+/**
+ * struct wlan_roam_result_info  - Roam result data
+ * @roam_fail_reason: Roam failure reason code defined in enum
+ * wlan_roam_failure_reason_code
+ * @is_roam_successful: True if roamed successfully or false if roaming failed
+ */
+struct wlan_roam_result_info {
+	enum wlan_roam_failure_reason_code roam_fail_reason;
+	bool is_roam_successful;
+};
+
+/**
+ * struct wlan_roam_trigger_info - Structure to store roam trigger related data.
+ * @is_full_scan: True if the scan is Full scan. False if the roam scan is
+ * partial channel map scan
+ * @trigger_reason: Roam trigger reason defined by enum roam_trigger_reason
+ * @trigger_sub_reason: Roam scan trigger sub reason indicating if
+ * periodic/inactivity scan timer initiated roam. Defined by enum
+ * roam_trigger_sub_reason
+ * @cu_load:  Current connected channel load in percentage
+ * @current_rssi: Connected AP RSSI in dBm
+ * @rssi_threshold: Roam scan trigger threshold in dBm
+ */
+struct wlan_roam_trigger_info {
+	bool is_full_scan;
+	enum roam_trigger_reason trigger_reason;
+	enum roam_trigger_sub_reason trigger_sub_reason;
+	uint8_t cu_load;
+	int32_t current_rssi;
+	int32_t rssi_threshold;
+};
+
+/**
+ * struct wlan_btm_cand_info  - BTM candidate information
+ * @idx: Candidate index
+ * @preference: Candidate preference
+ * @bssid: candidate bssid
+ */
+struct wlan_btm_cand_info {
+	uint8_t idx;
+	uint8_t preference;
+	struct qdf_mac_addr bssid;
+};
+
+/**
+ * struct wlan_roam_btm_info - BTM frame related logging data
+ * @reason: Query Reason field. Contains one of the values defined in IEEE
+ * Std 802.11‐2020 Table 9-198—Transition and Transition Query reasons
+ * @mode: BTM Request Mode field
+ * @sub_reason: WTC sub reason code field in the BTM WTC vendor specific IE
+ * @candidate_list_count: Candidates list in the BTM frame
+ * @btm_status_code: BSS Transition management status codes defined in
+ * 802.11‐2020 Table 9-428—BTM status code definitions
+ * @btm_delay: BSS Termination Delay field
+ * @is_disassoc_imminent: Disassociation imminent bit
+ * @token: dialog token. Dialog Token is a nonzero value chosen by the STA
+ * while sending the BTM frame to identify the query/request/response
+ * transaction
+ * @validity_timer: Validity interval in TBTT
+ * @disassoc_timer: Time after which the AP disassociates the STA, defined
+ * in TBTT.
+ * @wtc_duration: WTC duration field in minutes
+ * @target_bssid: BTM response target bssid field
+ */
+struct wlan_roam_btm_info {
+	uint8_t reason;
+	uint8_t mode;
+	uint8_t sub_reason;
+	uint8_t candidate_list_count;
+	uint8_t btm_status_code;
+	uint8_t btm_delay;
+	bool is_disassoc_imminent;
+	uint8_t token;
+	uint8_t validity_timer;
+	uint16_t disassoc_timer;
+	uint32_t wtc_duration;
+	struct qdf_mac_addr target_bssid;
+};
+
+/**
+ * struct wlan_packet_info  - Data packets related info
+ * @tx_status: Frame TX status defined by enum qdf_dp_tx_rx_status
+ * @eap_type: EAP type. Values defined by IANA at:
+ * https://www.iana.org/assignments/eap-numbers
+ * @eap_len: EAP data length
+ * @auth_algo: authentication algorithm number defined in IEEE Std 802.11‐2020
+ * Section 9.4.1.1 Authentication Algorithm Number field.
+ * @auth_seq_num: Authentication frame transaction sequence number
+ * @auth_type: Authentication frame sub-type for SAE authentication. Possible
+ * values:
+ * 1 - SAE commit frame
+ * 2 - SAE confirm frame
+ * @assoc_id: Association ID received in association response frame as
+ * defined in IEEE Std 802.11-2020 Figure 9-91-AID field format.
+ * @frame_status_code: Frame status code as defined in IEEE Std
+ * 802.11 2020 Table 9-50—Status codes.
+ * @seq_num: Frame sequence number
+ * @rssi: Peer RSSI in dBm
+ * @is_retry_frame: is frame retried
+ */
+struct wlan_packet_info {
+	uint8_t tx_status;
+	uint8_t eap_type;
+	uint16_t eap_len;
+	uint8_t auth_algo;
+	uint8_t auth_seq_num;
+	uint8_t auth_type;
+	uint16_t assoc_id;
+	uint16_t frame_status_code;
+	uint16_t seq_num;
+	int32_t rssi;
+	bool is_retry_frame;
+};
+
+/**
+ * struct wlan_connect_info  - Connection related info
+ * @ssid: SSID
+ * @ssid_len: Length of the SSID
+ * @bssid_hint: BSSID hint provided in the connect request
+ * @freq: Frequency in MHz
+ * @freq_hint: Frequency Hint in MHz
+ * @akm: Auth key management suite defined in IEEE Std 802.11‐2020
+ * Table 9-151—AKM suite selectors.
+ * @pairwise: Pairwise suite value as defined in IEEE 802.11 2020
+ * Table 12-10—Integrity and key wrap algorithms.
+ * @group: Group cipher suite value as defined in
+ * Table 12-10—Integrity and key wrap algorithms.
+ * @group_mgmt: Group management cipher suite as defined in
+ * Table 12-10—Integrity and key wrap algorithms.
+ * @auth_type: Authentication algorithm number field as defined in
+ * IEEE 802.11 - 2020 standard section 9.4.1.1
+ * @conn_status: Connection failure status defined by enum
+ * wlan_cm_connect_fail_reason
+ * @is_bt_coex_active: Is there active bluetooth connection
+ */
+struct wlan_connect_info {
+	char ssid[WLAN_SSID_MAX_LEN];
+	uint8_t ssid_len;
+	struct qdf_mac_addr bssid_hint;
+	qdf_freq_t freq;
+	qdf_freq_t freq_hint;
+	uint32_t akm;
+	uint32_t pairwise;
+	uint32_t group;
+	uint32_t group_mgmt;
+	uint8_t auth_type;
+	enum wlan_cm_connect_fail_reason conn_status;
+	bool is_bt_coex_active;
+};
+
+#define WLAN_MAX_LOG_RECORDS 45
+#define WLAN_MAX_LOG_LEN     256
+#define WLAN_RECORDS_PER_SEC 20
+#define MAX_RECORD_IN_SINGLE_EVT 5
+
+/**
+ * struct wlan_log_record  - Structure for individual records in the ring
+ * buffer
+ * @timestamp_us: Timestamp(time of the day) in microseconds
+ * @fw_timestamp_us: timestamp at which roam scan was triggered
+ * @ktime_us: kernel timestamp (time of the day) in microseconds
+ * @vdev_id: VDEV id
+ * @log_subtype: Tag of the log
+ * @bssid: AP bssid
+ * @is_record_filled: indicates if the current record is empty or not
+ * @conn_info: Connection info
+ * @pkt_info: Packet info
+ * @roam_scan: Roam scan
+ * @ap: Roam candidate AP info
+ * @roam_result: Roam result
+ * @roam_trig: Roam trigger related info
+ * @btm_info: BTM info
+ * @btm_cand: BTM response candidate info
+ */
+struct wlan_log_record {
+	uint64_t timestamp_us;
+	uint64_t fw_timestamp_us;
+	uint64_t ktime_us;
+	uint8_t vdev_id;
+	uint32_t log_subtype;
+	struct qdf_mac_addr bssid;
+	bool is_record_filled;
+	union {
+		struct wlan_connect_info conn_info;
+		struct wlan_packet_info pkt_info;
+		struct wlan_roam_scan_info roam_scan;
+		struct wlan_roam_candidate_info ap;
+		struct wlan_roam_result_info roam_result;
+		struct wlan_roam_trigger_info roam_trig;
+		struct wlan_roam_btm_info btm_info;
+		struct wlan_btm_cand_info btm_cand;
+	};
+};
+
+/**
+ * struct wlan_cl_osif_cbks  - OSIF callbacks to be invoked for connectivity
+ * logging
+ * @wlan_connectivity_log_send_to_usr: Send the log buffer to user space
+ */
+struct wlan_cl_osif_cbks {
+	QDF_STATUS
+	(*wlan_connectivity_log_send_to_usr) (struct wlan_log_record *rec,
+					      void *context,
+					      uint8_t num_records);
+};
+
+/**
+ * struct wlan_connectivity_log_buf_data  - Master structure to hold the
+ * pointers to the ring buffers.
+ * @psoc: Global psoc pointer
+ * @osif_cbks: OSIF callbacks
+ * @osif_cb_context: Pointer to the context to be passed to OSIF
+ * callback
+ * @first_record_timestamp_in_last_sec: First record timestamp
+ * @sent_msgs_count: Total sent messages counter in the last 1 sec
+ * @head: Pointer to the 1st record allocated in the ring buffer.
+ * @read_ptr: Pointer to the next record that can be read.
+ * @write_ptr: Pointer to the next empty record to be written.
+ * @write_ptr_lock: Spinlock to protect the write_ptr from multiple producers.
+ * @max_records: Maximum records in the ring buffer.
+ * @read_idx: Read index
+ * @write_idx: Write index
+ * @dropped_msgs: Dropped logs counter
+ * @is_active: If the global buffer is initialized or not
+ */
+struct wlan_connectivity_log_buf_data {
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_cl_osif_cbks osif_cbks;
+	void *osif_cb_context;
+	uint64_t first_record_timestamp_in_last_sec;
+	uint64_t sent_msgs_count;
+	struct wlan_log_record *head;
+	struct wlan_log_record *read_ptr;
+	struct wlan_log_record *write_ptr;
+	qdf_spinlock_t write_ptr_lock;
+	uint8_t max_records;
+	uint8_t read_idx;
+	uint8_t write_idx;
+	qdf_atomic_t dropped_msgs;
+	qdf_atomic_t is_active;
+};
+
+#define logging_err_rl(params...) \
+	QDF_TRACE_ERROR_RL(QDF_MODULE_ID_MLME, ## params)
+#define logging_warn_rl(params...) \
+	QDF_TRACE_WARN_RL(QDF_MODULE_ID_MLME, ## params)
+#define logging_info_rl(params...) \
+	QDF_TRACE_INFO_RL(QDF_MODULE_ID_MLME, ## params)
+
+#define logging_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_QDF, ## params)
+#define logging_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, ## params)
+#define logging_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_QDF, ## params)
+
+#if (defined(CONNECTIVITY_DIAG_EVENT) && \
+	defined(WLAN_FEATURE_ROAM_OFFLOAD))
+/**
+ * wlan_print_cached_sae_auth_logs() - Enqueue SAE authentication frame logs
+ * @psoc: Global psoc pointer
+ * @bssid:  BSSID
+ * @vdev_id: Vdev id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_print_cached_sae_auth_logs(struct wlan_objmgr_psoc *psoc,
+					   struct qdf_mac_addr *bssid,
+					   uint8_t vdev_id);
+
+/**
+ * wlan_is_log_record_present_for_bssid() - Check if there is existing log
+ * record for the given bssid
+ * @psoc: Global psoc pointer
+ * @bssid: BSSID
+ * @vdev_id: vdev id
+ *
+ * Return: true if record is present else false
+ */
+bool wlan_is_log_record_present_for_bssid(struct wlan_objmgr_psoc *psoc,
+					  struct qdf_mac_addr *bssid,
+					  uint8_t vdev_id);
+
+/**
+ * wlan_is_sae_auth_log_present_for_bssid() - Is cached SAE auth log record
+ * present for the given bssid. This API checks on all the link vdev if the
+ * given vdev_id is an MLO vdev and updates the vdev_id to caller in which
+ * the auth frame was cached.
+ * @psoc: Global psoc pointer
+ * @bssid: BSSID
+ * @vdev_id: vdev id
+ *
+ * Return: True if an entry is found
+ */
+bool
+wlan_is_sae_auth_log_present_for_bssid(struct wlan_objmgr_psoc *psoc,
+				       struct qdf_mac_addr *bssid,
+				       uint8_t *vdev_id);
+
+/**
+ * wlan_clear_sae_auth_logs_cache() - Clear the cached auth related logs
+ * @psoc: Pointer to global psoc object
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void wlan_clear_sae_auth_logs_cache(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id);
+#else
+static inline
+QDF_STATUS wlan_print_cached_sae_auth_logs(struct wlan_objmgr_psoc *psoc,
+					   struct qdf_mac_addr *bssid,
+					   uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+bool wlan_is_log_record_present_for_bssid(struct wlan_objmgr_psoc *psoc,
+					  struct qdf_mac_addr *bssid,
+					  uint8_t vdev_id)
+{
+	return false;
+}
+
+static inline bool
+wlan_is_sae_auth_log_present_for_bssid(struct wlan_objmgr_psoc *psoc,
+				       struct qdf_mac_addr *bssid,
+				       uint8_t *vdev_id)
+{
+	return false;
+}
+
+static inline
+void wlan_clear_sae_auth_logs_cache(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id)
+{}
+#endif
+
+#if defined(CONNECTIVITY_DIAG_EVENT)
+/**
+ * wlan_connectivity_mgmt_event()  - Fill and enqueue a new record
+ * for management frame information.
+ * @psoc: Pointer to global psoc object
+ * @mac_hdr: 802.11 management frame header
+ * @vdev_id: Vdev id
+ * @status_code: Frame status code as defined in IEEE 802.11 - 2020 standard
+ * section 9.4.1.9
+ * @tx_status: Frame TX status defined by enum qdf_dp_tx_rx_status
+ * @peer_rssi: Peer RSSI in dBm
+ * @auth_algo: Authentication algorithm number field as defined in IEEE 802.11 -
+ * 2020 standard section 9.4.1.1
+ * @auth_type: indicates SAE authentication frame type. Possible values are:
+ * 1 - SAE commit frame
+ * 2 - SAE confirm frame
+ * @auth_seq: Authentication frame transaction sequence number as defined in
+ * IEEE 802.11 - 2020 standard section 9.4.1.2
+ * @aid: Association ID
+ * @tag: Record type main tag
+ *
+ * Return: QDF_STATUS
+ */
+void
+wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_frame_hdr *mac_hdr,
+			     uint8_t vdev_id, uint16_t status_code,
+			     enum qdf_dp_tx_rx_status tx_status,
+			     int8_t peer_rssi,
+			     uint8_t auth_algo, uint8_t auth_type,
+			     uint8_t auth_seq, uint16_t aid,
+			     enum wlan_main_tag tag);
+
+/**
+ * wlan_populate_vsie() - Populate VSIE field for logging
+ * @vdev: vdev pointer
+ * @data: Diag packet info data
+ * @is_tx: flag to indicate whether packet transmitted or received
+ *
+ * Return: None
+ */
+void
+wlan_populate_vsie(struct wlan_objmgr_vdev *vdev,
+		   struct wlan_diag_packet_info *data, bool is_tx);
+
+/**
+ * wlan_cdp_set_peer_freq() - API to set frequency to dp peer
+ * @psoc: psoc pointer
+ * @peer_mac: Bssid of peer
+ * @freq: frequency(in MHz)
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void
+wlan_cdp_set_peer_freq(struct wlan_objmgr_psoc *psoc, uint8_t *peer_mac,
+		       uint32_t freq, uint8_t vdev_id);
+
+#ifdef WLAN_FEATURE_11BE_MLO
+
+/**
+ * wlan_connectivity_mlo_reconfig_event() -API to log MLO reconfig event
+ * @vdev: vdev pointer
+ *
+ * Return: None
+ */
+void
+wlan_connectivity_mlo_reconfig_event(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * wlan_connectivity_mlo_setup_event() - Fill and send MLO setup data
+ * @vdev: vdev pointer
+ * @is_band_present: If Band is present(Associated link band is shared by FW)
+ *
+ * Return: None
+ */
+void wlan_connectivity_mlo_setup_event(struct wlan_objmgr_vdev *vdev,
+				       bool is_band_present);
+
+/**
+ * wlan_connectivity_t2lm_req_resp_event - API to send t2lm Req/resp
+ * event logs to userspace
+ * @vdev: vdev pointer
+ * @token: dialog Token
+ * @t2lm_status: T2LM response status code. Refer enum wlan_t2lm_resp_frm_type
+ * @tx_status: TX status
+ * @freq: frequency on which frame was transmitted/received
+ * @is_rx: Flag to inidcate packet being received
+ * @subtype: Determine whether the evnt sent is for t2lm request
+ * or t2lm response
+ *
+ * Return: None
+ */
+void
+wlan_connectivity_t2lm_req_resp_event(struct wlan_objmgr_vdev *vdev,
+				      uint8_t token,
+				      enum wlan_t2lm_resp_frm_type t2lm_status,
+				      enum qdf_dp_tx_rx_status tx_status,
+				      qdf_freq_t freq,
+				      bool is_rx, uint8_t subtype);
+/**
+ * wlan_connectivity_t2lm_status_event() - Fill and send T2LM data
+ * @vdev: vdev pointer
+ *
+ * Return: None
+ */
+void wlan_connectivity_t2lm_status_event(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * wlan_populate_mlo_mgmt_event_param() - API to populate MLO management frame
+ * parameter
+ * @vdev: vdev pointer
+ * @data: Buffer to be filled with MLO parameter
+ * @tag: WLAN event tag. Refer enum wlan_main_tag
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_populate_mlo_mgmt_event_param(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_diag_packet_info *data,
+				   enum wlan_main_tag tag);
+
+/**
+ * wlan_populate_roam_mld_log_param() - Populate roam MLO log parameters
+ * @vdev: Pointer to vdev object
+ * @data: Diag event packet info
+ * @tag: Main Tag
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_populate_roam_mld_log_param(struct wlan_objmgr_vdev *vdev,
+				 struct wlan_diag_packet_info *data,
+				 enum wlan_main_tag tag);
+#else
+static inline void
+wlan_connectivity_mlo_reconfig_event(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline void
+wlan_connectivity_mlo_setup_event(struct wlan_objmgr_vdev *vdev,
+				  bool is_band_present)
+{
+}
+
+static inline void
+wlan_connectivity_t2lm_req_resp_event(struct wlan_objmgr_vdev *vdev,
+				      uint8_t token,
+				      enum wlan_t2lm_resp_frm_type status,
+				      enum qdf_dp_tx_rx_status tx_status,
+				      qdf_freq_t freq,
+				      bool is_rx, uint8_t subtype)
+{}
+
+static inline void
+wlan_connectivity_t2lm_status_event(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline QDF_STATUS
+wlan_populate_mlo_mgmt_event_param(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_diag_packet_info *data,
+				   enum wlan_main_tag tag)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+wlan_populate_roam_mld_log_param(struct wlan_objmgr_vdev *vdev,
+				 struct wlan_diag_packet_info *data,
+				 enum wlan_main_tag tag)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wlan_populate_vsie() - Populate VSIE field for logging
+ * @vdev: vdev pointer
+ * @data: Diag packet info data
+ * @is_tx: flag to indicate whether packet transmitted or received
+ *
+ * Return: None
+ */
+void
+wlan_populate_vsie(struct wlan_objmgr_vdev *vdev,
+		   struct wlan_diag_packet_info *data, bool is_tx);
+/**
+ * wlan_convert_freq_to_diag_band() - API to convert frequency to band value
+ * mentioned in enum wlan_diag_wifi_band
+ * @ch_freq: Frequency(in MHz)
+ *
+ * Return: Band specified in enum wlan_diag_wifi_band
+ */
+enum wlan_diag_wifi_band
+wlan_convert_freq_to_diag_band(uint16_t ch_freq);
+
+static inline void wlan_connectivity_logging_stop(void)
+{}
+
+/**
+ * wlan_connectivity_sta_info_event() - APi to send STA info event
+ * @psoc: Pointer to global psoc object
+ * @vdev_id: Vdev id
+ * @is_roam: Is sta info event for roaming stats
+ *
+ * Return: None
+ */
+void
+wlan_connectivity_sta_info_event(struct wlan_objmgr_psoc *psoc,
+				 uint8_t vdev_id, bool is_roam);
+
+/**
+ * wlan_connectivity_connecting_event() - API to log connecting event
+ * @vdev: vdev pointer
+ * @con_req: Connection request parameter
+ *
+ * Return: None
+ */
+void
+wlan_connectivity_connecting_event(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_cm_connect_req *con_req);
+
+#elif defined(WLAN_FEATURE_CONNECTIVITY_LOGGING)
+/**
+ * wlan_connectivity_logging_start()  - Initialize the connectivity/roaming
+ * logging buffer
+ * @psoc: Global psoc pointer
+ * @osif_cbks: OSIF callbacks
+ * @osif_cb_context: OSIF callback context argument
+ *
+ * Return: None
+ */
+void wlan_connectivity_logging_start(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_cl_osif_cbks *osif_cbks,
+				     void *osif_cb_context);
+
+/**
+ * wlan_connectivity_logging_stop() - Deinitialize the connectivity logging
+ * buffers and spinlocks.
+ *
+ * Return: None
+ */
+void wlan_connectivity_logging_stop(void);
+
+/**
+ * wlan_connectivity_log_dequeue() - Send the connectivity logs to userspace
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_connectivity_log_dequeue(void);
+
+/**
+ * wlan_connectivity_log_enqueue() - Add new record to the logging buffer
+ * @new_record: Pointer to the new record to be added
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_connectivity_log_enqueue(struct wlan_log_record *new_record);
+
+/**
+ * wlan_connectivity_mgmt_event()  - Fill and enqueue a new record
+ * for management frame information.
+ * @psoc: Pointer to global psoc object
+ * @mac_hdr: 802.11 management frame header
+ * @vdev_id: Vdev id
+ * @status_code: Frame status code as defined in IEEE 802.11 - 2020 standard
+ * section 9.4.1.9
+ * @tx_status: Frame TX status defined by enum qdf_dp_tx_rx_status
+ * @peer_rssi: Peer RSSI in dBm
+ * @auth_algo: Authentication algorithm number field as defined in IEEE 802.11 -
+ * 2020 standard section 9.4.1.1
+ * @auth_type: indicates SAE authentication frame type. Possible values are:
+ * 1 - SAE commit frame
+ * 2 - SAE confirm frame
+ * @auth_seq: Authentication frame transaction sequence number as defined in
+ * IEEE 802.11 - 2020 standard section 9.4.1.2
+ * @aid: Association ID
+ * @tag: Record type main tag
+ *
+ * Return: QDF_STATUS
+ */
+void
+wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_frame_hdr *mac_hdr,
+			     uint8_t vdev_id, uint16_t status_code,
+			     enum qdf_dp_tx_rx_status tx_status,
+			     int8_t peer_rssi,
+			     uint8_t auth_algo, uint8_t auth_type,
+			     uint8_t auth_seq, uint16_t aid,
+			     enum wlan_main_tag tag);
+
+/**
+ * wlan_connectivity_connecting_event() - API to log connecting event
+ * @vdev: vdev pointer
+ * @con_req: Connection request parameter
+ *
+ * Return: None
+ */
+void
+wlan_connectivity_connecting_event(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_cm_connect_req *con_req);
+
+/**
+ * wlan_populate_vsie() - Populate VSIE field for logging
+ * @vdev: vdev pointer
+ * @data: Diag packet info data
+ * @is_tx: Flag to indicate whether the packet is transmitted or received
+ *
+ * Return: None
+ */
+void
+wlan_populate_vsie(struct wlan_objmgr_vdev *vdev,
+		   struct wlan_diag_packet_info *data, bool is_tx);
+
+/**
+ * wlan_connectivity_sta_info_event() - APi to send STA info event
+ * @psoc: Pointer to global psoc object
+ * @vdev_id: Vdev id
+ * @is_roam: Is sta info event for roaming stats
+ */
+void
+wlan_connectivity_sta_info_event(struct wlan_objmgr_psoc *psoc,
+				 uint8_t vdev_id, bool is_roam);
+
+/**
+ * wlan_convert_freq_to_diag_band() - API to convert frequency to band value
+ * mentioned in enum wlan_diag_wifi_band
+ * @ch_freq: Frequency(in MHz)
+ *
+ * Return: Band specified in enum wlan_diag_wifi_band
+ */
+enum wlan_diag_wifi_band
+wlan_convert_freq_to_diag_band(uint16_t ch_freq);
+
+/**
+ * wlan_populate_vsie() - Populate VSIE field for logging
+ * @vdev: vdev pointer
+ * @data: Diag packet info data
+ * @is_tx: flag to indicate whether packet transmitted or received
+ *
+ * Return: None
+ */
+void
+wlan_populate_vsie(struct wlan_objmgr_vdev *vdev,
+		   struct wlan_diag_packet_info *data, bool is_tx);
+
+/**
+ * wlan_cdp_set_peer_freq() - API to set frequency to dp peer
+ * @psoc: psoc pointer
+ * @peer_mac: Bssid of peer
+ * @freq: frequency(in MHz)
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void
+wlan_cdp_set_peer_freq(struct wlan_objmgr_psoc *psoc, uint8_t *peer_mac,
+		       uint32_t freq, uint8_t vdev_id);
+
+#else
+static inline
+void wlan_connectivity_logging_start(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_cl_osif_cbks *osif_cbks,
+				     void *osif_cb_context)
+{}
+
+static inline void wlan_connectivity_logging_stop(void)
+{}
+
+static inline QDF_STATUS wlan_connectivity_log_dequeue(void)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline
+QDF_STATUS wlan_connectivity_log_enqueue(struct wlan_log_record *new_record)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline void
+wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_frame_hdr *mac_hdr,
+			     uint8_t vdev_id, uint16_t status_code,
+			     enum qdf_dp_tx_rx_status tx_status,
+			     int8_t peer_rssi,
+			     uint8_t auth_algo, uint8_t auth_type,
+			     uint8_t auth_seq, uint16_t aid,
+			     enum wlan_main_tag tag)
+{}
+
+static inline void
+wlan_populate_vsie(struct wlan_objmgr_vdev *vdev,
+		   struct wlan_diag_packet_info *data, bool is_tx)
+{
+}
+
+static inline enum wlan_diag_wifi_band
+wlan_convert_freq_to_diag_band(uint16_t ch_freq)
+{
+	return WLAN_INVALID_BAND;
+}
+
+static inline QDF_STATUS
+wlan_populate_mlo_mgmt_event_param(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_diag_packet_info *data,
+				   enum wlan_main_tag tag)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+wlan_cdp_set_peer_freq(struct wlan_objmgr_psoc *psoc, uint8_t *peer_mac,
+		       uint32_t freq, uint8_t vdev_id)
+{}
+
+static inline void
+wlan_connectivity_mlo_reconfig_event(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline void
+wlan_connectivity_sta_info_event(struct wlan_objmgr_psoc *psoc,
+				 uint8_t vdev_id, bool is_roam)
+{}
+
+static inline void
+wlan_connectivity_t2lm_req_resp_event(struct wlan_objmgr_vdev *vdev,
+				      uint8_t token,
+				      enum wlan_t2lm_resp_frm_type status,
+				      enum qdf_dp_tx_rx_status tx_status,
+				      qdf_freq_t freq,
+				      bool is_rx, uint8_t subtype)
+{}
+
+static inline void
+wlan_connectivity_t2lm_status_event(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline void
+wlan_connectivity_connecting_event(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_cm_connect_req *con_req)
+{
+}
+#endif
+
+#if defined(CONNECTIVITY_DIAG_EVENT) && defined(WLAN_FEATURE_11BE_MLO)
+/**
+ * wlan_connectivity_mld_link_status_event() - Send connectivity logging
+ * ML Link Status event
+ * @psoc: Pointer to global PSOC object
+ * @src: Src parameters to be sent
+ *
+ * Return: None
+ */
+void
+wlan_connectivity_mld_link_status_event(struct wlan_objmgr_psoc *psoc,
+					struct mlo_link_switch_params *src);
+#else
+static inline
+void wlan_connectivity_mld_link_status_event(struct wlan_objmgr_psoc *psoc,
+					     struct mlo_link_switch_params *src)
+{}
+#endif /* CONNECTIVITY_DIAG_EVENT && WLAN_FEATURE_11BE_MLO */
+#endif /* _WLAN_CONNECTIVITY_LOGGING_H_ */

+ 1231 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/logging/src/wlan_connectivity_logging.c

@@ -0,0 +1,1231 @@
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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_cm_roam_logging.c
+ *
+ * Implementation for the connectivity and roam logging api.
+ */
+#include "wlan_connectivity_logging.h"
+#include "wlan_cm_api.h"
+#include "wlan_mlme_main.h"
+#include "wlan_mlo_mgr_sta.h"
+#include "wlan_mlme_api.h"
+#include "cdp_txrx_ctrl.h"
+#include "wlan_mlo_mgr_peer.h"
+#include "wlan_scan_api.h"
+
+#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
+static struct wlan_connectivity_log_buf_data global_cl;
+
+static void
+wlan_connectivity_logging_register_callbacks(
+				struct wlan_cl_osif_cbks *osif_cbks,
+				void *osif_cb_context)
+{
+	global_cl.osif_cbks.wlan_connectivity_log_send_to_usr =
+			osif_cbks->wlan_connectivity_log_send_to_usr;
+	global_cl.osif_cb_context = osif_cb_context;
+}
+
+void wlan_connectivity_logging_start(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_cl_osif_cbks *osif_cbks,
+				     void *osif_cb_context)
+{
+	global_cl.head = qdf_mem_valloc(sizeof(*global_cl.head) *
+					WLAN_MAX_LOG_RECORDS);
+	if (!global_cl.head) {
+		QDF_BUG(0);
+		return;
+	}
+
+	global_cl.psoc = psoc;
+	global_cl.write_idx = 0;
+	global_cl.read_idx = 0;
+
+	qdf_atomic_init(&global_cl.dropped_msgs);
+	qdf_spinlock_create(&global_cl.write_ptr_lock);
+
+	global_cl.read_ptr = global_cl.head;
+	global_cl.write_ptr = global_cl.head;
+	global_cl.max_records = WLAN_MAX_LOG_RECORDS;
+
+	wlan_connectivity_logging_register_callbacks(osif_cbks,
+						     osif_cb_context);
+	qdf_atomic_set(&global_cl.is_active, 1);
+}
+
+void wlan_connectivity_logging_stop(void)
+{
+	if (!qdf_atomic_read(&global_cl.is_active))
+		return;
+
+	qdf_spin_lock_bh(&global_cl.write_ptr_lock);
+
+	global_cl.psoc = NULL;
+	global_cl.osif_cb_context = NULL;
+	global_cl.osif_cbks.wlan_connectivity_log_send_to_usr = NULL;
+
+	qdf_atomic_set(&global_cl.is_active, 0);
+	global_cl.read_ptr = NULL;
+	global_cl.write_ptr = NULL;
+	global_cl.read_idx = 0;
+	global_cl.write_idx = 0;
+
+	qdf_mem_vfree(global_cl.head);
+	global_cl.head = NULL;
+	qdf_spin_unlock_bh(&global_cl.write_ptr_lock);
+	qdf_spinlock_destroy(&global_cl.write_ptr_lock);
+}
+#endif
+
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \
+	defined(WLAN_FEATURE_11BE_MLO)
+static void
+wlan_clear_ml_vdev_sae_auth_logs(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_mlo_dev_context *mlo_dev_ctx;
+	struct wlan_objmgr_vdev *link_vdev;
+	struct mlme_legacy_priv *mlme_priv;
+	uint8_t i, link_vdev_id;
+
+	mlo_dev_ctx = vdev->mlo_dev_ctx;
+	if (!mlo_dev_ctx) {
+		logging_err_rl("mlo_dev ctx is NULL for vdev:%d",
+			       wlan_vdev_get_id(vdev));
+		return;
+	}
+
+	for (i =  0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
+		if (!mlo_dev_ctx->wlan_vdev_list[i])
+			continue;
+
+		link_vdev_id =
+			wlan_vdev_get_id(mlo_dev_ctx->wlan_vdev_list[i]);
+		link_vdev = mlo_dev_ctx->wlan_vdev_list[i];
+
+		mlme_priv = wlan_vdev_mlme_get_ext_hdl(link_vdev);
+		if (!mlme_priv) {
+			logging_err_rl("vdev:%d legacy private object is NULL",
+				       link_vdev_id);
+			return;
+		}
+
+		logging_debug("vdev:%d clear sae auth logs cache",
+			      link_vdev_id);
+		qdf_mem_zero(mlme_priv->auth_log, sizeof(mlme_priv->auth_log));
+	}
+}
+#else
+static inline void
+wlan_clear_ml_vdev_sae_auth_logs(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_objmgr_vdev *vdev)
+{}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+void wlan_clear_sae_auth_logs_cache(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return;
+	}
+
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		wlan_clear_ml_vdev_sae_auth_logs(psoc, vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		logging_err_rl("vdev legacy private object is NULL");
+		return;
+	}
+
+	logging_debug("vdev:%d clear sae auth logs cache", vdev_id);
+	qdf_mem_zero(mlme_priv->auth_log, sizeof(mlme_priv->auth_log));
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+#endif
+
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(CONNECTIVITY_DIAG_EVENT)
+QDF_STATUS wlan_print_cached_sae_auth_logs(struct wlan_objmgr_psoc *psoc,
+					   struct qdf_mac_addr *bssid,
+					   uint8_t vdev_id)
+{
+	uint8_t i, j;
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		logging_err_rl("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Get the index of matching bssid and queue all the records for
+	 * that bssid
+	 */
+	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
+		if (!mlme_priv->auth_log[i][0].diag_cmn.ktime_us)
+			continue;
+
+		if (qdf_is_macaddr_equal(bssid,
+					 (struct qdf_mac_addr *)mlme_priv->auth_log[i][0].diag_cmn.bssid))
+			break;
+	}
+
+	/*
+	 * No matching bssid found in cached log records.
+	 * So return from here.
+	 */
+	if (i >= MAX_ROAM_CANDIDATE_AP) {
+		logging_debug("No cached SAE auth logs");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (j = 0; j < WLAN_ROAM_MAX_CACHED_AUTH_FRAMES; j++) {
+		if (!mlme_priv->auth_log[i][j].diag_cmn.ktime_us)
+			continue;
+
+		WLAN_HOST_DIAG_EVENT_REPORT(&mlme_priv->auth_log[i][j],
+					    EVENT_WLAN_MGMT);
+		qdf_mem_zero(&mlme_priv->auth_log[i][j],
+			     sizeof(struct wlan_diag_packet_info));
+	}
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool wlan_is_log_record_present_for_bssid(struct wlan_objmgr_psoc *psoc,
+					  struct qdf_mac_addr *bssid,
+					  uint8_t vdev_id)
+{
+	struct wlan_diag_packet_info *pkt_info;
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+	int i;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return false;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		logging_err_rl("vdev legacy private object is NULL");
+		return false;
+	}
+
+	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
+		pkt_info = &mlme_priv->auth_log[i][0];
+		if (!pkt_info->diag_cmn.ktime_us)
+			continue;
+
+		if (qdf_is_macaddr_equal(bssid,
+					 (struct qdf_mac_addr *)pkt_info->diag_cmn.bssid)) {
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+			return true;
+		}
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return false;
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+bool
+wlan_is_sae_auth_log_present_for_bssid(struct wlan_objmgr_psoc *psoc,
+				       struct qdf_mac_addr *bssid,
+				       uint8_t *vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_mlo_dev_context *mlo_dev_ctx;
+	uint8_t i, link_vdev_id;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, *vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", *vdev_id);
+		return false;
+	}
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return wlan_is_log_record_present_for_bssid(psoc, bssid,
+							    *vdev_id);
+	}
+
+	mlo_dev_ctx = vdev->mlo_dev_ctx;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	if (!mlo_dev_ctx) {
+		logging_err_rl("mlo_dev ctx is NULL for vdev:%d", *vdev_id);
+		return wlan_is_log_record_present_for_bssid(psoc, bssid,
+							    *vdev_id);
+	}
+
+	for (i =  0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
+		if (!mlo_dev_ctx->wlan_vdev_list[i])
+			continue;
+
+		link_vdev_id = wlan_vdev_get_id(mlo_dev_ctx->wlan_vdev_list[i]);
+		if (wlan_is_log_record_present_for_bssid(psoc, bssid,
+							 link_vdev_id)) {
+			*vdev_id = link_vdev_id;
+			return true;
+		}
+	}
+
+	return false;
+}
+#else
+bool
+wlan_is_sae_auth_log_present_for_bssid(struct wlan_objmgr_psoc *psoc,
+				       struct qdf_mac_addr *bssid,
+				       uint8_t *vdev_id)
+{
+	return wlan_is_log_record_present_for_bssid(psoc, bssid, *vdev_id);
+}
+#endif
+
+/**
+ * wlan_add_sae_log_record_to_available_slot() - Add a new log record into the
+ * cache for the queue.
+ * @psoc: objmgr psoc object
+ * @vdev: objmgr vdev object
+ * @pkt_info: Log packet record pointer
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+wlan_add_sae_log_record_to_available_slot(struct wlan_objmgr_psoc *psoc,
+					  struct wlan_objmgr_vdev *vdev,
+					  struct wlan_diag_packet_info *pkt_info)
+{
+	struct mlme_legacy_priv *mlme_priv;
+	uint8_t i, j;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	bool is_entry_exist =
+		wlan_is_log_record_present_for_bssid(psoc,
+						     (struct qdf_mac_addr *)pkt_info->diag_cmn.bssid,
+						     vdev_id);
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		logging_err_rl("vdev:%d legacy private object is NULL",
+			       vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
+		if (is_entry_exist &&
+		    mlme_priv->auth_log[i][0].diag_cmn.ktime_us &&
+		    qdf_is_macaddr_equal((struct qdf_mac_addr *)pkt_info->diag_cmn.bssid,
+					 (struct qdf_mac_addr *)mlme_priv->auth_log[i][0].diag_cmn.bssid)) {
+			/*
+			 * Frames for given bssid already exists store the new
+			 * frame in corresponding array in empty slot
+			 */
+			for (j = 0; j < WLAN_ROAM_MAX_CACHED_AUTH_FRAMES; j++) {
+				if (mlme_priv->auth_log[i][j].diag_cmn.ktime_us)
+					continue;
+
+				logging_debug("vdev:%d added at [i][j]:[%d][%d]",
+					      vdev_id, i, j);
+				mlme_priv->auth_log[i][j] = *pkt_info;
+				break;
+			}
+
+		} else if (!is_entry_exist &&
+			   !mlme_priv->auth_log[i][0].diag_cmn.ktime_us) {
+			/*
+			 * For given record, there is no existing bssid
+			 * so add the entry at first available slot
+			 */
+			logging_debug("vdev:%d added entry at [i][j]:[%d][%d]",
+				      vdev_id, i, 0);
+			mlme_priv->auth_log[i][0] = *pkt_info;
+			break;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void
+wlan_cache_connectivity_log(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			    struct wlan_diag_packet_info *pkt_info)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return;
+	}
+
+	wlan_add_sae_log_record_to_available_slot(psoc, vdev, pkt_info);
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+#endif
+
+#define WLAN_SAE_AUTH_ALGO_NUMBER 3
+#ifdef CONNECTIVITY_DIAG_EVENT
+
+#ifdef WLAN_FEATURE_11BE_MLO
+void
+wlan_connectivity_t2lm_req_resp_event(struct wlan_objmgr_vdev *vdev,
+				      uint8_t token,
+				      enum wlan_t2lm_resp_frm_type t2lm_status,
+				      enum qdf_dp_tx_rx_status tx_status,
+				      qdf_freq_t freq,
+				      bool is_rx, uint8_t subtype)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
+				 struct wlan_diag_mlo_t2lm_req_resp);
+
+	wlan_diag_event.diag_cmn.vdev_id = wlan_vdev_get_id(vdev);
+	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
+	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
+
+	wlan_diag_event.version = DIAG_MLO_T2LM_REQ_RESP_VERSION;
+
+	wlan_diag_event.token = token;
+	wlan_diag_event.subtype = subtype;
+
+	wlan_diag_event.status = t2lm_status;
+	wlan_diag_event.tx_status = wlan_get_diag_tx_status(tx_status);
+	wlan_diag_event.is_rx = is_rx;
+
+	wlan_diag_event.band = wlan_convert_freq_to_diag_band(freq);
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
+				    EVENT_WLAN_MLO_T2LM_REQ_RESP);
+}
+
+void
+wlan_connectivity_mlo_reconfig_event(struct wlan_objmgr_vdev *vdev)
+{
+	struct mlo_link_info *link_info = NULL;
+	struct wlan_channel *chan_info = NULL;
+	uint8_t link_id;
+
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
+				 struct wlan_diag_mlo_reconfig);
+
+	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
+	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
+	wlan_diag_event.version = DIAG_MLO_RECONFIG_VERSION;
+
+	link_id = wlan_vdev_get_link_id(vdev);
+	wlan_diag_event.mlo_cmn_info.link_id = link_id;
+
+	if (!vdev->mlo_dev_ctx)
+		return;
+
+	link_info = mlo_mgr_get_ap_link_by_link_id(vdev->mlo_dev_ctx, link_id);
+	if (!link_info) {
+		mlme_err("linl: %d Link info not found", link_id);
+		return;
+	}
+	chan_info = link_info->link_chan_info;
+	if (!chan_info) {
+		mlme_err("link: %d Chan info not found", link_id);
+		return;
+	}
+
+	wlan_diag_event.mlo_cmn_info.band =
+			wlan_convert_freq_to_diag_band(chan_info->ch_freq);
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MLO_RECONFIG);
+}
+
+static QDF_STATUS
+wlan_populate_link_addr(struct wlan_objmgr_vdev *vdev,
+			struct wlan_diag_sta_info *wlan_diag_event)
+{
+	uint i = 0;
+	struct mlo_link_switch_context *link_ctx = vdev->mlo_dev_ctx->link_ctx;
+	struct wlan_channel *link_chan_info;
+
+	if (!link_ctx)
+		return QDF_STATUS_E_FAILURE;
+
+	for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
+		link_chan_info = link_ctx->links_info[i].link_chan_info;
+
+		if (wlan_reg_is_24ghz_ch_freq(
+		    (qdf_freq_t)link_chan_info->ch_freq)) {
+			qdf_mem_copy(wlan_diag_event->mac_2g,
+				     link_ctx->links_info[i].link_addr.bytes,
+				     QDF_MAC_ADDR_SIZE);
+		} else if (wlan_reg_is_5ghz_ch_freq(
+			   (qdf_freq_t)link_chan_info->ch_freq)) {
+			qdf_mem_copy(wlan_diag_event->mac_5g,
+				     link_ctx->links_info[i].link_addr.bytes,
+				     QDF_MAC_ADDR_SIZE);
+		} else if (wlan_reg_is_6ghz_chan_freq(
+			   link_chan_info->ch_freq)) {
+			qdf_mem_copy(wlan_diag_event->mac_6g,
+				     link_ctx->links_info[i].link_addr.bytes,
+				     QDF_MAC_ADDR_SIZE);
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static uint8_t
+wlan_populate_band_bitmap(struct mlo_link_switch_context *link_ctx)
+{
+	uint8_t i, band_bitmap = 0, band;
+	struct wlan_channel *link_chan_info;
+
+	for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
+		link_chan_info = link_ctx->links_info[i].link_chan_info;
+
+		band = wlan_reg_freq_to_band((qdf_freq_t)
+					     link_chan_info->ch_freq);
+
+		band_bitmap |= BIT(band);
+	}
+
+	return band_bitmap;
+}
+
+QDF_STATUS
+wlan_populate_mlo_mgmt_event_param(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_diag_packet_info *data,
+				   enum wlan_main_tag tag)
+{
+	struct mlo_link_switch_context *link_ctx;
+	struct qdf_mac_addr peer_mac, peer_mld_mac;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!mlo_is_mld_sta(vdev))
+		return status;
+
+	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+		return QDF_STATUS_E_INVAL;
+
+	status = wlan_vdev_get_bss_peer_mac(vdev, &peer_mac);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		logging_err("vdev: %d bss peer not found",
+			    wlan_vdev_get_id(vdev));
+		return status;
+	}
+
+	qdf_mem_copy(data->diag_cmn.bssid, peer_mac.bytes, QDF_MAC_ADDR_SIZE);
+
+	status = wlan_vdev_get_bss_peer_mld_mac(vdev, &peer_mld_mac);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		logging_err("vdev: %d failed to get mld mac address of peer",
+			    wlan_vdev_get_id(vdev));
+		return status;
+	}
+
+	qdf_mem_copy(data->mld_addr, peer_mld_mac.bytes, QDF_MAC_ADDR_SIZE);
+
+	if (tag != WLAN_ASSOC_REQ && tag != WLAN_REASSOC_REQ)
+		return status;
+
+	link_ctx = vdev->mlo_dev_ctx->link_ctx;
+	if (!link_ctx) {
+		logging_debug("vdev: %d link_ctx not found",
+			      wlan_vdev_get_id(vdev));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	data->supported_links = wlan_populate_band_bitmap(link_ctx);
+
+	return status;
+}
+
+QDF_STATUS
+wlan_populate_roam_mld_log_param(struct wlan_objmgr_vdev *vdev,
+				 struct wlan_diag_packet_info *data,
+				 enum wlan_main_tag tag)
+{
+	struct wlan_objmgr_pdev *pdev;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return QDF_STATUS_E_INVAL;
+
+	status = wlan_scan_get_mld_addr_by_link_addr(
+			pdev, (struct qdf_mac_addr *)data->diag_cmn.bssid,
+			(struct qdf_mac_addr *)data->mld_addr);
+	if (QDF_IS_STATUS_ERROR(status))
+		logging_err_rl("vdev:%d Not able to fetch MLD addr for link addr: " QDF_MAC_ADDR_FMT,
+			       wlan_vdev_get_id(vdev),
+			       QDF_MAC_ADDR_REF(data->diag_cmn.bssid));
+
+	return status;
+}
+
+enum wlan_diag_wifi_band
+wlan_convert_freq_to_diag_band(uint16_t ch_freq)
+{
+	enum reg_wifi_band band;
+
+	band = wlan_reg_freq_to_band((qdf_freq_t)ch_freq);
+
+	switch (band) {
+	case REG_BAND_2G:
+		return WLAN_24GHZ_BAND;
+	case REG_BAND_5G:
+		return WLAN_5GHZ_BAND;
+	case REG_BAND_6G:
+		return WLAN_6GHZ_BAND;
+	default:
+		return WLAN_INVALID_BAND;
+	}
+}
+
+#define REJECTED_LINK_STATUS 1
+
+void
+wlan_connectivity_mlo_setup_event(struct wlan_objmgr_vdev *vdev,
+				  bool is_band_present)
+{
+	uint i = 0;
+	struct mlo_link_switch_context *link_ctx = NULL;
+	struct wlan_channel *chan_info;
+	uint8_t num_links = 0;
+
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
+				 struct wlan_diag_mlo_setup);
+
+	/*
+	 * MLO setup event need to be logged in the following cases:
+	 *
+	 * 1. When connection request is initiated and the ML
+	 *    candidate is selected.
+	 * 2. When roamed successfully to ML AP
+	 *
+	 */
+	if ((wlan_cm_is_vdev_connecting(vdev) && !mlo_is_mld_sta(vdev)) ||
+	    (wlan_cm_is_vdev_active(vdev) && !is_band_present))
+		return;
+
+	qdf_mem_zero(&wlan_diag_event, sizeof(struct wlan_diag_mlo_setup));
+
+	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
+	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
+	wlan_diag_event.version = DIAG_MLO_SETUP_VERSION_V2;
+
+	if (!vdev->mlo_dev_ctx) {
+		logging_err("vdev: %d MLO dev ctx not found",
+			    wlan_vdev_get_id(vdev));
+		return;
+	}
+
+	link_ctx = vdev->mlo_dev_ctx->link_ctx;
+	if (!link_ctx) {
+		logging_err("vdev: %d mlo link ctx not found",
+			    wlan_vdev_get_id(vdev));
+		return;
+	}
+
+	for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
+		if (link_ctx->links_info[i].link_id == WLAN_INVALID_LINK_ID)
+			continue;
+
+		chan_info = link_ctx->links_info[i].link_chan_info;
+		if (!chan_info) {
+			logging_debug("link %d: chan_info not found",
+				      link_ctx->links_info[i].link_id);
+			continue;
+		}
+
+		wlan_diag_event.mlo_cmn_info[num_links].link_id =
+				link_ctx->links_info[i].link_id;
+		wlan_diag_event.mlo_cmn_info[num_links].vdev_id =
+				link_ctx->links_info[i].vdev_id;
+
+		qdf_mem_copy(wlan_diag_event.mlo_cmn_info[num_links].link_addr,
+			     link_ctx->links_info[i].ap_link_addr.bytes,
+			     QDF_MAC_ADDR_SIZE);
+
+		wlan_diag_event.mlo_cmn_info[num_links].band =
+			wlan_convert_freq_to_diag_band(chan_info->ch_freq);
+
+		if (wlan_diag_event.mlo_cmn_info[num_links].band ==
+							 WLAN_INVALID_BAND)
+			wlan_diag_event.mlo_cmn_info[i].status =
+							REJECTED_LINK_STATUS;
+
+		num_links++;
+	}
+
+	wlan_diag_event.num_links = num_links;
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MLO_SETUP);
+}
+
+#define IS_LINK_SET(link_bitmap, link_id) ((link_bitmap) & (BIT(link_id)))
+#define DEFAULT_TID_MAP 0xFF
+
+static void
+wlan_populate_tid_link_id_bitmap(struct wlan_t2lm_info *t2lm,
+				 struct mlo_link_info *link_info,
+				 struct wlan_diag_mlo_t2lm_status *buf,
+				 uint8_t bss_link)
+{
+	uint8_t link_id;
+	uint8_t dir, i;
+	uint16_t freq;
+
+	link_id = link_info->link_id;
+	freq = link_info->link_chan_info->ch_freq;
+	buf->mlo_cmn_info[bss_link].band =
+		wlan_convert_freq_to_diag_band(freq);
+	buf->mlo_cmn_info[bss_link].vdev_id = link_info->vdev_id;
+
+	for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++) {
+		if (t2lm[dir].default_link_mapping) {
+			buf->mlo_cmn_info[bss_link].tid_ul = DEFAULT_TID_MAP;
+			buf->mlo_cmn_info[bss_link].tid_dl = DEFAULT_TID_MAP;
+			continue;
+		}
+
+		for (i = 0; i < T2LM_MAX_NUM_TIDS; i++) {
+			switch (t2lm[dir].direction) {
+			case WLAN_T2LM_DL_DIRECTION:
+				if (
+				IS_LINK_SET(
+				t2lm[dir].ieee_link_map_tid[i], link_id))
+					buf->mlo_cmn_info[bss_link].tid_dl |=
+									BIT(i);
+				break;
+			case WLAN_T2LM_UL_DIRECTION:
+				if (
+				IS_LINK_SET(
+				t2lm[dir].ieee_link_map_tid[i], link_id))
+					buf->mlo_cmn_info[bss_link].tid_ul |=
+									BIT(i);
+				break;
+			case WLAN_T2LM_BIDI_DIRECTION:
+				if (
+				IS_LINK_SET(
+				t2lm[dir].ieee_link_map_tid[i], link_id)) {
+					buf->mlo_cmn_info[bss_link].tid_dl |=
+									BIT(i);
+					buf->mlo_cmn_info[bss_link].tid_ul |=
+									BIT(i);
+				}
+				break;
+			default:
+				logging_debug("Invalid direction %d",
+					      t2lm[dir].direction);
+				break;
+			}
+		}
+	}
+}
+
+void
+wlan_connectivity_t2lm_status_event(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t i = 0, dir, num_links = 0;
+	QDF_STATUS status;
+	struct mlo_link_info *link_info;
+	struct wlan_t2lm_info t2lm[WLAN_T2LM_MAX_DIRECTION] = {0};
+
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
+				 struct wlan_diag_mlo_t2lm_status);
+
+	if (!mlo_is_mld_sta(vdev))
+		return;
+
+	if (!vdev->mlo_dev_ctx) {
+		logging_err("MLO dev ctx not found");
+		return;
+	}
+	link_info = mlo_mgr_get_ap_link(vdev);
+	if (!link_info) {
+		logging_err("link_info invalid");
+		return;
+	}
+
+	if (mlo_mgr_is_link_switch_in_progress(vdev))
+		return;
+
+	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
+	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
+	wlan_diag_event.version = DIAG_MLO_T2LM_STATUS_VERSION_V2;
+
+	for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++)
+		t2lm[dir].direction = WLAN_T2LM_INVALID_DIRECTION;
+
+	status = wlan_get_t2lm_mapping_status(vdev, t2lm);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		logging_err("Unable to get t2lm_mapping");
+		return;
+	}
+
+	for (i = 0;
+	     i < WLAN_MAX_ML_BSS_LINKS && i < MAX_NUM_LINKS_PER_EVENT; i++) {
+		if (qdf_is_macaddr_zero(&link_info->ap_link_addr) &&
+		    link_info->link_id == WLAN_INVALID_LINK_ID)
+			continue;
+
+		wlan_populate_tid_link_id_bitmap(t2lm, link_info,
+						 &wlan_diag_event, num_links);
+		link_info++;
+		num_links++;
+	}
+
+	wlan_diag_event.num_links = num_links;
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
+				    EVENT_WLAN_MLO_T2LM_STATUS);
+}
+
+#else
+static QDF_STATUS
+wlan_populate_link_addr(struct wlan_objmgr_vdev *vdev,
+			struct wlan_diag_sta_info *wlan_diag_event)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+void
+wlan_cdp_set_peer_freq(struct wlan_objmgr_psoc *psoc, uint8_t *peer_mac,
+		       uint32_t freq, uint8_t vdev_id)
+{
+	ol_txrx_soc_handle soc_txrx_handle;
+	cdp_config_param_type val = {0};
+
+	soc_txrx_handle = wlan_psoc_get_dp_handle(psoc);
+
+	val.cdp_peer_param_freq = freq;
+	cdp_txrx_set_peer_param(soc_txrx_handle, vdev_id, peer_mac,
+				CDP_CONFIG_PEER_FREQ, val);
+}
+
+void
+wlan_connectivity_sta_info_event(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+				 bool is_roam)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev = NULL;
+
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_sta_info);
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_err_rl("Invalid vdev:%d", vdev_id);
+		return;
+	}
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE ||
+	    (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
+	     (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) ||
+	      wlan_vdev_mlme_is_mlo_link_vdev(vdev))))
+		goto out;
+
+	if (!is_roam && !wlan_cm_is_first_candidate_connect_attempt(vdev))
+		goto out;
+
+	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
+	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
+	wlan_diag_event.diag_cmn.vdev_id = vdev_id;
+	wlan_diag_event.is_mlo = wlan_vdev_mlme_is_mlo_vdev(vdev);
+
+	if (wlan_diag_event.is_mlo) {
+		qdf_mem_copy(wlan_diag_event.diag_cmn.bssid,
+			     wlan_vdev_mlme_get_mldaddr(vdev),
+			     QDF_MAC_ADDR_SIZE);
+		status = wlan_populate_link_addr(vdev, &wlan_diag_event);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			logging_err_rl("wlan_populate_link_addr failed");
+			goto out;
+		}
+	} else {
+		qdf_mem_copy(wlan_diag_event.diag_cmn.bssid,
+			     wlan_vdev_mlme_get_macaddr(vdev),
+			     QDF_MAC_ADDR_SIZE);
+	}
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_STA_INFO);
+out:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+
+void
+wlan_populate_vsie(struct wlan_objmgr_vdev *vdev,
+		   struct wlan_diag_packet_info *data,
+		   bool is_tx)
+{
+	struct element_info *vsie_info = NULL;
+
+	if (is_tx)
+		vsie_info = mlme_get_self_disconnect_ies(vdev);
+	else
+		vsie_info = mlme_get_peer_disconnect_ies(vdev);
+
+	if (!vsie_info)
+		return;
+
+	data->vsie_len = vsie_info->len;
+	if (data->vsie_len > MAX_VSIE_LEN)
+		data->vsie_len = MAX_VSIE_LEN;
+
+	qdf_mem_copy(data->vsie, vsie_info->ptr, data->vsie_len);
+}
+
+void
+wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_frame_hdr *mac_hdr,
+			     uint8_t vdev_id, uint16_t status_code,
+			     enum qdf_dp_tx_rx_status tx_status,
+			     int8_t peer_rssi,
+			     uint8_t auth_algo, uint8_t auth_type,
+			     uint8_t auth_seq, uint16_t aid,
+			     enum wlan_main_tag tag)
+{
+	enum QDF_OPMODE opmode;
+	bool cache_sae_frame_cap, is_initial_connection;
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info);
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		logging_debug("Unable to find vdev:%d", vdev_id);
+		return;
+	}
+
+	opmode = wlan_vdev_mlme_get_opmode(vdev);
+	if (opmode != QDF_STA_MODE)
+		goto out;
+
+	is_initial_connection = wlan_cm_is_vdev_connecting(vdev);
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
+	    (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) ||
+	     (is_initial_connection &&
+	      wlan_vdev_mlme_is_mlo_link_vdev(vdev)))) {
+		logging_debug("vdev:%d is_connection:%d | %s skip mgmt event",
+			      vdev_id, is_initial_connection,
+			      wlan_vdev_mlme_is_mlo_link_vdev(vdev) ?
+			      "link_vdev" : wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) ? "link switch in prog" : "");
+		goto out;
+	}
+
+	qdf_mem_zero(&wlan_diag_event, sizeof(struct wlan_diag_packet_info));
+
+	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
+	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
+	wlan_diag_event.diag_cmn.vdev_id = vdev_id;
+	wlan_diag_event.subtype = (uint8_t)tag;
+
+	qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, &mac_hdr->i_addr3[0],
+		     QDF_MAC_ADDR_SIZE);
+
+	if (is_initial_connection) {
+		status = wlan_populate_mlo_mgmt_event_param(vdev,
+							    &wlan_diag_event,
+							    tag);
+		if (QDF_IS_STATUS_ERROR(status))
+			goto out;
+	}
+
+	wlan_diag_event.version = DIAG_MGMT_VERSION_V2;
+	wlan_diag_event.tx_fail_reason = tx_status;
+	wlan_diag_event.tx_status = wlan_get_diag_tx_status(tx_status);
+	wlan_diag_event.rssi = peer_rssi;
+	wlan_diag_event.sn =
+		(le16toh(*(uint16_t *)mac_hdr->i_seq) >> WLAN_SEQ_SEQ_SHIFT);
+	wlan_diag_event.status = status_code;
+	wlan_diag_event.auth_algo = auth_algo;
+	wlan_diag_event.auth_frame_type = auth_type;
+	wlan_diag_event.auth_seq_num = auth_seq;
+	wlan_diag_event.assoc_id = aid;
+
+	if (tag == WLAN_DEAUTH_RX || tag == WLAN_DISASSOC_RX)
+		wlan_populate_vsie(vdev, &wlan_diag_event, false);
+
+	if (wlan_diag_event.subtype > WLAN_CONN_DIAG_REASSOC_RESP_EVENT &&
+	    wlan_diag_event.subtype < WLAN_CONN_DIAG_BMISS_EVENT)
+		wlan_diag_event.reason = status_code;
+
+	wlan_diag_event.is_retry_frame =
+			(mac_hdr->i_fc[1] & IEEE80211_FC1_RETRY);
+
+	/*
+	 * Cache the SAE auth frames info in vdev mlme private and return in
+	 * case of roam preauth
+	 */
+	cache_sae_frame_cap =
+		wlan_psoc_nif_fw_ext2_cap_get(psoc,
+					      WLAN_ROAM_STATS_FRAME_INFO_PER_CANDIDATE);
+	if (!is_initial_connection &&
+	    (tag == WLAN_AUTH_REQ || tag == WLAN_AUTH_RESP) &&
+	    auth_algo == WLAN_SAE_AUTH_ALGO_NUMBER && cache_sae_frame_cap) {
+		wlan_cache_connectivity_log(psoc, vdev_id, &wlan_diag_event);
+		goto out;
+	}
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MGMT);
+
+	if (tag == WLAN_ASSOC_RSP || tag == WLAN_REASSOC_RSP)
+		wlan_connectivity_mlo_setup_event(vdev, false);
+
+out:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+
+void
+wlan_connectivity_connecting_event(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_cm_connect_req *con_req)
+{
+	QDF_STATUS status;
+	struct wlan_cm_connect_req req;
+
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_connect);
+
+	if (!wlan_cm_is_first_candidate_connect_attempt(vdev))
+		return;
+
+	/* for candidate not found case*/
+	if (con_req) {
+		req = *con_req;
+		qdf_mem_zero(&req.scan_ie, sizeof(struct element_info));
+		qdf_mem_zero(&req.assoc_ie, sizeof(struct element_info));
+	} else {
+		status = wlan_cm_get_active_connect_req_param(vdev, &req);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			logging_err("vdev: %d failed to get active cmd request",
+				    wlan_vdev_get_id(vdev));
+			return;
+		}
+	}
+
+	wlan_diag_event.version = DIAG_CONN_VERSION;
+	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
+	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
+	wlan_diag_event.diag_cmn.vdev_id = wlan_vdev_get_id(vdev);
+	wlan_diag_event.subtype = WLAN_CONN_DIAG_CONNECTING_EVENT;
+
+	wlan_diag_event.ssid_len = req.ssid.length;
+
+	if (req.ssid.length > WLAN_SSID_MAX_LEN)
+		wlan_diag_event.ssid_len = WLAN_SSID_MAX_LEN;
+
+	qdf_mem_copy(wlan_diag_event.ssid, req.ssid.ssid,
+		     wlan_diag_event.ssid_len);
+
+	if (!qdf_is_macaddr_zero(&req.bssid))
+		qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, req.bssid.bytes,
+			     QDF_MAC_ADDR_SIZE);
+	else if (!qdf_is_macaddr_zero(&req.bssid_hint))
+		qdf_mem_copy(wlan_diag_event.bssid_hint, req.bssid_hint.bytes,
+			     QDF_MAC_ADDR_SIZE);
+
+	if (req.chan_freq)
+		wlan_diag_event.freq = req.chan_freq;
+	else if (req.chan_freq_hint)
+		wlan_diag_event.freq_hint = req.chan_freq_hint;
+
+	wlan_diag_event.pairwise_cipher	= req.crypto.user_cipher_pairwise;
+	wlan_diag_event.grp_cipher = req.crypto.user_grp_cipher;
+	wlan_diag_event.akm = req.crypto.user_akm_suite;
+	wlan_diag_event.auth_algo = req.crypto.user_auth_type;
+
+	if (req.scan_ie.len) {
+		qdf_mem_free(req.scan_ie.ptr);
+		qdf_mem_zero(&req.scan_ie, sizeof(struct element_info));
+	}
+
+	if (req.assoc_ie.len) {
+		qdf_mem_free(req.assoc_ie.ptr);
+		qdf_mem_zero(&req.assoc_ie, sizeof(struct element_info));
+	}
+
+	wlan_diag_event.bt_coex =
+		wlan_mlme_get_bt_profile_con(wlan_vdev_get_psoc(vdev));
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_CONN);
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+
+#define BAND_TO_BITMAP(band) (band - 1)
+
+static uint8_t
+wlan_convert_link_id_to_diag_band(struct qdf_mac_addr *peer_mld,
+				  uint16_t link_bitmap)
+{
+	uint8_t i, band_bitmap = 0, band;
+	struct wlan_mlo_dev_context *mldev = NULL;
+	struct wlan_mlo_peer_context *mlpeer = NULL;
+	struct mlo_link_info *link_info = NULL;
+	uint32_t freq;
+
+	mlpeer = wlan_mlo_get_mlpeer_by_peer_mladdr(peer_mld, &mldev);
+	if (!mlpeer) {
+		logging_err("ml peer not found");
+		return 0;
+	}
+
+	for (i = 0; i < MAX_MLO_LINK_ID; i++) {
+		if (IS_LINK_SET(link_bitmap, i)) {
+			link_info = mlo_mgr_get_ap_link_by_link_id(mldev, i);
+			if (!link_info) {
+				logging_err("link: %d info does not exist", i);
+				return 0;
+			}
+
+			freq = link_info->link_chan_info->ch_freq;
+			band = wlan_convert_freq_to_diag_band(freq);
+			if (band == WLAN_INVALID_BAND)
+				continue;
+
+			band_bitmap |= BIT(BAND_TO_BITMAP(band));
+		}
+	}
+
+	return band_bitmap;
+}
+
+static uint8_t
+wlan_get_supported_link_band_bitmap(struct mlo_link_switch_context *link_ctx)
+{
+	uint8_t band_bitmap = 0, i = 0;
+	struct mlo_link_info link_info;
+	struct wlan_channel *chan_info;
+	enum wlan_diag_wifi_band band;
+
+	for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
+		link_info = link_ctx->links_info[i];
+
+		chan_info = link_info.link_chan_info;
+		if (!chan_info)
+			continue;
+
+		band = wlan_convert_freq_to_diag_band(chan_info->ch_freq);
+		if (band == WLAN_INVALID_BAND)
+			continue;
+
+		band_bitmap |= BIT(band - 1);
+	}
+
+	return band_bitmap;
+}
+
+void wlan_connectivity_mld_link_status_event(struct wlan_objmgr_psoc *psoc,
+					     struct mlo_link_switch_params *src)
+{
+	struct wlan_mlo_peer_context *ml_peer = NULL;
+	struct wlan_mlo_dev_context *mld_ctx = NULL;
+
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
+				 struct wlan_diag_mlo_link_status);
+
+	qdf_mem_zero(&wlan_diag_event,
+		     sizeof(struct wlan_diag_mlo_link_status));
+
+	ml_peer = wlan_mlo_get_mlpeer_by_peer_mladdr(&src->mld_addr, &mld_ctx);
+
+	if (!mld_ctx) {
+		logging_err("mlo dev ctx for mld_mac: "
+			    QDF_MAC_ADDR_FMT
+			    " not found",
+			    QDF_MAC_ADDR_REF(src->mld_addr.bytes));
+		return;
+	}
+
+	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
+	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
+	wlan_diag_event.version = DIAG_MLO_LINK_STATUS_VERSION_2;
+
+	wlan_diag_event.active_link =
+		wlan_convert_link_id_to_diag_band(&src->mld_addr,
+						  src->active_link_bitmap);
+	if (!wlan_diag_event.active_link)
+		return;
+	wlan_diag_event.prev_active_link =
+		wlan_convert_link_id_to_diag_band(&src->mld_addr,
+						  src->prev_link_bitmap);
+	if (!wlan_diag_event.prev_active_link)
+		return;
+
+	if (!mld_ctx->link_ctx) {
+		logging_err("link ctx for mld_mac: "
+			    QDF_MAC_ADDR_FMT
+			    " not found",
+			    QDF_MAC_ADDR_REF(src->mld_addr.bytes));
+		return;
+	}
+
+	wlan_diag_event.associated_links =
+			wlan_get_supported_link_band_bitmap(mld_ctx->link_ctx);
+
+	if (!wlan_diag_event.associated_links)
+		return;
+
+	wlan_diag_event.reason = src->reason_code;
+	/*
+	 * FW timestamp received from FW in milliseconds and to be sent to
+	 * userspace in microseconds
+	 */
+	wlan_diag_event.diag_cmn.fw_timestamp = src->fw_timestamp * 1000;
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
+				    EVENT_WLAN_MLO_LINK_STATUS);
+}
+#endif
+#endif

+ 781 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/cfg_policy_mgr.h

@@ -0,0 +1,781 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: 6
+ * @Default: 0
+ *
+ * This ini is used to override SAP channel.
+ * If gWlanMccToSccSwitchMode = 0: disabled.
+ * If gWlanMccToSccSwitchMode = 1: deprecated, overwritten to 3 in driver
+ * If gWlanMccToSccSwitchMode = 2: deprecated, overwritten to 3 in driver
+ * If gWlanMccToSccSwitchMode = 3: Force switch without SAP restart.
+ * If gWlanMccToSccSwitchMode = 4: Switch using
+ *                                 fav channel(s)without SAP restart.
+ * If gWlanMccToSccSwitchMode = 5: Force switch without SAP restart.MCC allowed
+ *                                 in exceptional cases.
+ * If gWlanMccToSccSwitchMode = 6: Force Switch without SAP restart only in
+ *                                 user preferred band.
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: 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: 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: External
+ *
+ * </ini>
+ */
+#define CFG_MAX_CONC_CXNS CFG_INI_UINT(\
+					"gMaxConcurrentActiveSessions", \
+					1, 4, 3, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Config max num allowed connections")
+
+#define POLICY_MGR_CH_SELECT_POLICY_DEF         0x00000003
+
+/*
+ * <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, \
+					POLICY_MGR_CH_SELECT_POLICY_DEF, \
+					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: 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: 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: 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: 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: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_MCC_ADAPTIVE_SCH_ENABLED_NAME CFG_INI_BOOL(\
+					"gEnableMCCAdaptiveScheduler", \
+					true, \
+					"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: 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")
+
+/*
+ * <ini>
+ * gAllowMCCGODiffBI - Allow GO in MCC mode to accept different beacon interval
+ * than STA's.
+ * @Min: 0
+ * @Max: 4
+ * @Default: 4
+ *
+ * This ini is used to allow GO in MCC mode to accept different beacon interval
+ * than STA's.
+ * Added for Wi-Fi Cert. 5.1.12
+ * If gAllowMCCGODiffBI = 1
+ *	Set to 1 for WFA certification. GO Beacon interval is not changed.
+ *	MCC GO doesn't work well in optimized way. In worst scenario, it may
+ *	invite STA disconnection.
+ * If gAllowMCCGODiffBI = 2
+ *	If set to 2 workaround 1 disassoc all the clients and update beacon
+ *	Interval.
+ * If gAllowMCCGODiffBI = 3
+ *	If set to 3 tear down the P2P link in auto/Non-autonomous -GO case.
+ * If gAllowMCCGODiffBI = 4
+ *	If set to 4 don't disconnect the P2P client in autonomous/Non-auto-
+ *	nomous -GO case update the BI dynamically
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ALLOW_MCC_GO_DIFF_BI \
+CFG_INI_UINT("gAllowMCCGODiffBI", 0, 4, 4, CFG_VALUE_OR_DEFAULT, \
+	     "Allow GO in MCC mode to accept different BI than STA's")
+
+/*
+ *
+ * <ini>
+ * gDualMacFeatureDisable - Disable Dual MAC feature.
+ * @Min: 0
+ * @Max: 6
+ * @Default: 6
+ *
+ * This ini is used to enable/disable dual MAC feature.
+ * 0 - enable DBS
+ * 1 - disable DBS
+ * 2 - disable DBS for connection but keep DBS for scan
+ * 3 - disable DBS for connection but keep DBS scan with async
+ * scan policy disabled
+ * 4 - enable DBS for connection as well as for scan with async
+ * scan policy disabled
+ * 5 - enable DBS for connection but disable DBS for scan.
+ * 6 - enable DBS for connection but disable simultaneous scan
+ * from upper layer (DBS scan remains enabled in FW).
+ *
+ * Note: INI item value should match 'enum dbs_support'
+ *
+ * Related: None.
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DUAL_MAC_FEATURE_DISABLE \
+CFG_INI_UINT("gDualMacFeatureDisable", 0, 6, 6, CFG_VALUE_OR_DEFAULT, \
+	     "This INI is used to enable/disable Dual MAC feature")
+
+/*
+ *
+ * <ini>
+ * enable_sbs - Enable/Disable SBS.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable SBS feature.
+ * 0 - disable SBS
+ * 1 - enable SBS
+ *
+ *
+ * Related: None.
+ *
+ * Supported Feature: SBS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SBS CFG_INI_BOOL(\
+					"enable_sbs", \
+					true, \
+					"Enable/Disable SBS")
+
+/*
+ * <ini>
+ * g_sta_sap_scc_on_dfs_chan - Allow STA+SAP SCC on DFS channel with master
+ * mode support disabled.
+ * @Min: 0
+ * @Max: 2
+ * @Default: 2
+ *
+ * This ini is used to allow STA+SAP SCC on DFS channel with master mode
+ * support disabled, the value is defined by enum PM_AP_DFS_MASTER_MODE.
+ * 0 - Disallow STA+SAP SCC on DFS channel
+ * 1 - Allow STA+SAP SCC on DFS channel with master mode disabled
+ *       This needs gEnableDFSMasterCap enabled to allow SAP SCC with
+ *       STA on DFS but dfs master mode disabled. Single SAP is not allowed
+ *       on DFS.
+ * 2 - enhance "1" with below requirement
+ *	 a. Allow single SAP (GO) start on DFS channel.
+ *	 b. Allow CAC process on DFS channel in single SAP (GO) mode
+ *	 c. Allow DFS radar event process in single SAP (GO) mode
+ *	 d. Disallow CAC and radar event process in SAP (GO) + STA mode.
+ *	 The value 2 of this ini requires master mode to be enabled so it is
+ *	 mandatory to enable the dfs master mode ini gEnableDFSMasterCap
+ *	 along with it.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Non-DBS, DBS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_STA_SAP_SCC_ON_DFS_CHAN \
+CFG_INI_UINT("g_sta_sap_scc_on_dfs_chan", 0, 2, 2, CFG_VALUE_OR_DEFAULT, \
+	     "Allow STA+SAP SCC on DFS channel with master mode disable")
+
+/*
+ * <ini>
+ * sta_sap_scc_on_indoor_chan - Allow STA+SAP SCC on indoor channel
+ * when STA is connected on indoor channel.
+ * @Min: false
+ * @Max: true
+ * @Default: false
+ *
+ * This ini is used to allow STA+SAP SCC on indoor channel
+ * 0 - Disallow STA+SAP SCC on Indoor only channel
+ * 1 - Allow STA+SAP SCC on DFS channel. SAP will move to indoor channel
+ * once STA is connected on indoor only channel.
+ * When gindoor_channel_support=1, this ini will not be considered and
+ * SAP can come up on indoor channel.
+ *
+ * Related: gindoor_channel_support.
+ *
+ * Supported Feature: Non-DBS, DBS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_STA_SAP_SCC_ON_INDOOR_CHAN CFG_INI_BOOL(\
+			"sta_sap_scc_on_indoor_chan", \
+			false, \
+			"Allow STA+SAP SCC on indoor channel")
+
+/*
+ * <ini>
+ * gForce1x1Exception - force 1x1 when connecting to certain peer
+ * @Min: 0
+ * @Max: 2
+ * @Default: 2
+ *
+ * This INI when enabled will force 1x1 connection with certain peer.
+ * The implementation for this ini would be as follows:-
+ * Value 0: Even if the AP is present in OUI, 1x1 will not be forced
+ * Value 1: If antenna sharing supported, then only do 1x1.
+ * Value 2: If AP present in OUI, force 1x1 connection.
+
+ *
+ * Related: None
+ *
+ * Supported Feature: connection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_FORCE_1X1_FEATURE \
+CFG_INI_UINT("gForce1x1Exception", 0, 2, 1, CFG_VALUE_OR_DEFAULT, \
+	     "force 1x1 when connecting to certain peer")
+
+/*
+ * <ini>
+ * gEnableSAPManadatoryChanList - Enable SAP Mandatory channel list
+ * Options.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable the SAP manadatory chan list
+ * 0 - Disable SAP mandatory chan list
+ * 1 - Enable SAP mandatory chan list
+ *
+ * Supported Feature: SAP
+ *
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_SAP_MANDATORY_CHAN_LIST \
+CFG_INI_UINT("gEnableSAPManadatoryChanList", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \
+	     "Enable SAP Mandatory channel list")
+
+/*
+ * <ini>
+ * g_nan_sap_scc_on_lte_coex_chan - Allow NAN+SAP SCC on LTE coex channel
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to allow NAN+SAP SCC on LTE coex channel
+ * 0 - Disallow NAN+SAP SCC on LTE coex channel
+ * 1 - Allow NAN+SAP SCC on LTE coex channel
+ *
+ * Related: Depends on gWlanMccToSccSwitchMode config.
+ *
+ * Supported Feature: Non-DBS, DBS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_NAN_SAP_SCC_ON_LTE_COEX_CHAN \
+CFG_INI_BOOL("g_nan_sap_scc_on_lte_coex_chan", 1, \
+	     "Allow NAN+SAP SCC on LTE coex channel")
+
+/*
+ * <ini>
+ * g_sta_sap_scc_on_lte_coex_chan - Allow STA+SAP SCC on LTE coex channel
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to allow STA+SAP SCC on LTE coex channel
+ * 0 - Disallow STA+SAP SCC on LTE coex channel
+ * 1 - Allow STA+SAP SCC on LTE coex channel
+ *
+ * Related: None.
+ *
+ * Supported Feature: Non-DBS, DBS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN \
+CFG_INI_UINT("g_sta_sap_scc_on_lte_coex_chan", 0, 1, 1, CFG_VALUE_OR_DEFAULT, \
+	     "Allow STA+SAP SCC on LTE coex channel")
+
+/*
+ * <ini>
+ * g_mark_sap_indoor_as_disable - Enable/Disable Indoor channel
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to mark the Indoor channel as
+ * disable when SAP start and revert it on SAP stop,
+ * so SAP will not turn on indoor channel and
+ * sta will not scan/associate and roam on indoor
+ * channels.
+ *
+ * Related: If g_mark_sap_indoor_as_disable set, turn the
+ * indoor channels to disable and update Wiphy & fw.
+ *
+ * Supported Feature: SAP/STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_MARK_INDOOR_AS_DISABLE_FEATURE \
+CFG_INI_UINT("g_mark_sap_indoor_as_disable", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \
+	     "Enable/Disable Indoor channel")
+
+/*
+ * <ini>
+ * g_enable_go_force_scc - Enable/Disable force SCC on P2P GO
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini and along with "gWlanMccToSccSwitchMode" is used to enable
+ * force SCC on P2P GO interface.
+ *
+ * GO_FORCE_SCC_DISABLED (value 0): GO force scc disabled and GO can come up
+ * in MCC mode
+ * GO_FORCE_SCC_STRICT (value 1): New GO will be forced to form on existing
+ * GO/STA/GC channel in start bss itself.
+ * GO_FORCE_SCC_LIBERAL (value 2): After SET KEY is done, do force SCC for the
+ * first GO to move to new GO channel.
+ *
+ * Supported Feature: P2P GO
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_P2P_GO_ENABLE_FORCE_SCC \
+CFG_INI_UINT("g_enable_go_force_scc", 0, 2, 0, CFG_VALUE_OR_DEFAULT, \
+	     "Enable/Disable P2P GO force SCC")
+
+/*
+ * <ini>
+ * g_pcl_band_priority - Set 5G/6G Channel order
+ * Options.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set preference between 5G and 6G channels during
+ * PCL population.
+ * 0 - Prefer 5G channels, 5G channels will be placed before the 6G channels
+ *	in PCL.
+ * 1 - Prefer 6G channels, 6G channels will be placed before the 5G channels
+ *	in PCL.
+ *
+ * Supported Feature: STA, SAP
+ *
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_PCL_BAND_PRIORITY \
+CFG_INI_UINT("g_pcl_band_priority", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \
+	     "Set 5G and 6G Channel order")
+
+/*
+ * <ini>
+ * g_multi_sap_allowed_on_same_band - Allow multi sap started on same band
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to allow multi sap started on same band or not.
+ * 0 - Disallow multi sap started on same band
+ * 1 - Allow multi sap started on same band
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_MULTI_SAP_ALLOWED_ON_SAME_BAND \
+CFG_INI_BOOL("g_multi_sap_allowed_on_same_band", 1, \
+	     "Allow multi SAP started on same band")
+
+#ifdef WLAN_FEATURE_SR
+/*
+ * <ini>
+ * g_enable_sr_in_same_mac_conc - Enable/Disable SR in same MAC concurrency
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable SR in same MAC concurrency scenarios.
+ * 0 - disable SR in same mac concurrency
+ * 1 - enable SR in same mac concurrency
+ *
+ * Ex- If 1st connection STA operating on MAC0 has enabled Spatial Reuse
+ * already. Then if user tries to bring-up 2nd connection SAP on MAC0
+ * (STA + SAP (SCC)).
+ * Now if this INI is not set to 1, then Spatial Reuse gets disabled for
+ * all the interfaces running on MAC0. Once 2nd connection or concurrency
+ * interface is disabled, Spatial Reuse gets enabled again.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Spatial Reuse
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SR_IN_SAME_MAC_CONC \
+CFG_INI_BOOL("g_enable_sr_in_same_mac_conc", 1, \
+	     "Enable/Disable SR in Same MAC concurrency")
+
+#define CFG_SPATIAL_REUSE CFG(CFG_ENABLE_SR_IN_SAME_MAC_CONC)
+#else
+#define CFG_SPATIAL_REUSE
+#endif
+
+/*
+ * <ini>
+ * g_use_original_bw_for_sap_restart - Set sap default BW when do restart
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set sap default BW when do restart.
+ * 0 - Use maximum BW as default BW
+ * 1 - Use sap original BW as default BW
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SAP_DEFAULT_BW_FOR_RESTART \
+CFG_INI_BOOL("g_use_original_bw_for_sap_restart", 0, \
+	     "Use SAP original bandwidth when do restart")
+
+/*
+ * <ini>
+ * g_move_sap_go_1st_on_dfs_sta_csa - Move SAP / GO first to enforce scc
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini moves SAP / GO first to enforce scc in STA+SAP (GO) DFS SCC
+ * 0 - Keep default MCC to SCC enforcement movement
+ * 1 - Move SAP / GO first before STA's movement to non-DFS channel
+ *
+ * In STA+SAP / GO concurrency, SCC is enforced by moving SAP / GO
+ * to STA's operating channel. STA side, if there is a CSA
+ * then SCC will be enforced only after STA moves to new channel.
+ *
+ * In usecase of STA + GO SCC on DFS channel, CSA is sent with no-TX
+ * and STA's movement will only happen once CSA count becomes 0.
+ * This will block data transmission till then, which will have bad
+ * user experience in case of XR where, it needs to have periodic data
+ * transmission in every 1 second with GO interface.
+ *
+ * To resolve this, it is better to move GO / SAP first to allow 1
+ * second periodic transmissions. And once the STA moves to new channel,
+ * existing logic will be triggered to enforce SCC.
+ *
+ * This INI is added to change the behavior only in this specific case.
+ * If this INI is set, then move SAP / GO first upon receiving very first
+ * CSA from AP to a non-DFS channel. Current MCC to SCC rules will be applied
+ * once STA moves to new channel after CSA count becomes 0.
+ *
+ * Dependency: g_sta_sap_scc_on_dfs_chan, g_enable_go_force_scc
+ *
+ * Supported Feature: SAP / P2P-GO
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_MOVE_SAP_GO_1ST_ON_DFS_STA_CSA \
+CFG_INI_BOOL("g_move_sap_go_1st_on_dfs_sta_csa", 0, \
+	     "Move SAP / GO first to enforce scc on dfs sta csa")
+
+#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_ADAPTIVE_SCH_ENABLED_NAME)\
+		CFG(CFG_ENABLE_STA_CONNECTION_IN_5GHZ)\
+		CFG(CFG_DUAL_MAC_FEATURE_DISABLE)\
+		CFG(CFG_ENABLE_SBS)\
+		CFG(CFG_STA_SAP_SCC_ON_DFS_CHAN)\
+		CFG(CFG_STA_SAP_SCC_ON_INDOOR_CHAN)\
+		CFG(CFG_FORCE_1X1_FEATURE)\
+		CFG(CFG_ENABLE_SAP_MANDATORY_CHAN_LIST)\
+		CFG(CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN)\
+		CFG(CFG_NAN_SAP_SCC_ON_LTE_COEX_CHAN) \
+		CFG(CFG_MARK_INDOOR_AS_DISABLE_FEATURE)\
+		CFG(CFG_ALLOW_MCC_GO_DIFF_BI) \
+		CFG(CFG_P2P_GO_ENABLE_FORCE_SCC) \
+		CFG(CFG_PCL_BAND_PRIORITY) \
+		CFG(CFG_MULTI_SAP_ALLOWED_ON_SAME_BAND) \
+		CFG_SPATIAL_REUSE \
+		CFG(CFG_SAP_DEFAULT_BW_FOR_RESTART) \
+		CFG(CFG_MOVE_SAP_GO_1ST_ON_DFS_STA_CSA)
+#endif

+ 5771 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -0,0 +1,5771 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_mlo_mgr_public_structs.h"
+#include "wlan_policy_mgr_public_struct.h"
+#include "wlan_cm_roam_public_struct.h"
+#include "wlan_utility.h"
+#include "sir_types.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)
+
+/**
+ * enum PM_AP_DFS_MASTER_MODE - AP dfs master mode
+ * @PM_STA_SAP_ON_DFS_DEFAULT: Disallow STA+SAP SCC on DFS channel
+ * @PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED: Allow STA+SAP SCC
+ *        on DFS channel with master mode disabled
+ * @PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX: enhance
+ *        "PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED" with below requirement:
+ *	 a. Allow single SAP (GO) start on DFS channel.
+ *	 b. Allow CAC process on DFS channel in single SAP (GO) mode
+ *	 c. Allow DFS radar event process in single SAP (GO) mode
+ *	 d. Disallow CAC and radar event process in SAP (GO) + STA mode.
+ *
+ * This enum value will be used to set to INI g_sta_sap_scc_on_dfs_chan to
+ * config the sta+sap on dfs channel behaviour expected by user.
+ */
+enum PM_AP_DFS_MASTER_MODE {
+	PM_STA_SAP_ON_DFS_DEFAULT,
+	PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED,
+	PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX,
+};
+
+static inline const char *pcl_type_to_string(uint32_t idx)
+{
+	switch (idx) {
+	CASE_RETURN_STRING(PM_NONE);
+	CASE_RETURN_STRING(PM_24G);
+	CASE_RETURN_STRING(PM_5G);
+	CASE_RETURN_STRING(PM_SCC_CH);
+	CASE_RETURN_STRING(PM_MCC_CH);
+	CASE_RETURN_STRING(PM_SCC_CH_24G);
+	CASE_RETURN_STRING(PM_SCC_CH_5G);
+	CASE_RETURN_STRING(PM_24G_SCC_CH);
+	CASE_RETURN_STRING(PM_5G_SCC_CH);
+	CASE_RETURN_STRING(PM_SCC_ON_5_CH_5G);
+	CASE_RETURN_STRING(PM_SCC_ON_5_SCC_ON_24_24G);
+	CASE_RETURN_STRING(PM_SCC_ON_5_SCC_ON_24_5G);
+	CASE_RETURN_STRING(PM_SCC_ON_5_5G_24G);
+	CASE_RETURN_STRING(PM_SCC_ON_5_5G_SCC_ON_24G);
+	CASE_RETURN_STRING(PM_SCC_ON_24_SCC_ON_5_24G);
+	CASE_RETURN_STRING(PM_SCC_ON_24_SCC_ON_5_5G);
+	CASE_RETURN_STRING(PM_SCC_ON_24_CH_24G);
+	CASE_RETURN_STRING(PM_SCC_ON_5_SCC_ON_24);
+	CASE_RETURN_STRING(PM_SCC_ON_24_SCC_ON_5);
+	CASE_RETURN_STRING(PM_MCC_CH_24G);
+	CASE_RETURN_STRING(PM_MCC_CH_5G);
+	CASE_RETURN_STRING(PM_24G_MCC_CH);
+	CASE_RETURN_STRING(PM_5G_MCC_CH);
+	CASE_RETURN_STRING(PM_SBS_CH);
+	CASE_RETURN_STRING(PM_SBS_CH_5G);
+	CASE_RETURN_STRING(PM_24G_SCC_CH_SBS_CH);
+	CASE_RETURN_STRING(PM_24G_SCC_CH_SBS_CH_5G);
+	CASE_RETURN_STRING(PM_24G_SBS_CH_MCC_CH);
+	/* New PCL type for DBS-SBS HW */
+	CASE_RETURN_STRING(PM_SBS_CH_24G_SCC_CH);
+	CASE_RETURN_STRING(PM_SBS_CH_SCC_CH_24G);
+	CASE_RETURN_STRING(PM_SCC_CH_SBS_CH_24G);
+	CASE_RETURN_STRING(PM_SBS_CH_SCC_CH_5G_24G);
+	CASE_RETURN_STRING(PM_SCC_CH_MCC_CH_SBS_CH_24G);
+	CASE_RETURN_STRING(PM_SBS_CH_2G);
+	CASE_RETURN_STRING(PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G);
+	CASE_RETURN_STRING(PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G);
+	CASE_RETURN_STRING(PM_SCC_ON_5G_HIGH_5G_HIGH_SCC_ON_5G_LOW_PLUS_SHARED_2G);
+	CASE_RETURN_STRING(PM_SBS_CH_MCC_CH);
+	CASE_RETURN_STRING(PM_SBS_5G_MCC_24G);
+	default:
+		return "Unknown";
+	}
+}
+
+static inline const char *device_mode_to_string(uint32_t idx)
+{
+	switch (idx) {
+	CASE_RETURN_STRING(PM_STA_MODE);
+	CASE_RETURN_STRING(PM_SAP_MODE);
+	CASE_RETURN_STRING(PM_P2P_CLIENT_MODE);
+	CASE_RETURN_STRING(PM_P2P_GO_MODE);
+	CASE_RETURN_STRING(PM_NDI_MODE);
+	CASE_RETURN_STRING(PM_NAN_DISC_MODE);
+	CASE_RETURN_STRING(PM_LL_LT_SAP_MODE);
+	default:
+		return "Unknown";
+	}
+};
+
+/**
+ * struct trim_chan_info - trim channel info
+ * @band_capability: band capability
+ * @sap_count: sap count
+ * @trim: enum trim channel list
+ */
+struct trim_chan_info {
+	uint32_t band_capability;
+	uint32_t sap_count;
+	uint16_t trim;
+};
+
+/**
+ * policy_mgr_get_allow_mcc_go_diff_bi() - to get information on whether GO
+ *						can have diff BI than STA in MCC
+ * @psoc: pointer to psoc
+ * @allow_mcc_go_diff_bi: value to be filled
+ *
+ * This API is used to find out whether GO's BI can different than STA in MCC
+ * scenario
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_get_allow_mcc_go_diff_bi(struct wlan_objmgr_psoc *psoc,
+				    uint8_t *allow_mcc_go_diff_bi);
+/**
+ * policy_mgr_get_dual_mac_feature() - to find out if DUAL MAC feature is
+ *				       enabled
+ * @psoc: pointer to psoc
+ * @dual_mac_feature: value to be filled
+ *
+ * This API is used to find out whether dual mac (dual radio) specific feature
+ * is enabled or not
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_dual_mac_feature(struct wlan_objmgr_psoc *psoc,
+					   uint8_t *dual_mac_feature);
+
+/**
+ * policy_mgr_allow_multiple_sta_connections() - to find out if STA+STA feature
+ * is enabled.
+ * @psoc: pointer to psoc
+ *
+ * This API is used to find out whether STA+STA specific feature is enabled
+ * or not
+ *
+ * Return: true if supports else false.
+ */
+bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_set_dual_mac_feature() - to set the dual mac feature value
+ * @psoc: pointer to psoc
+ * @dual_mac_feature: value to be updated
+ *
+ * This API is used to update the dual mac (dual radio) specific feature value
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_set_dual_mac_feature(struct wlan_objmgr_psoc *psoc,
+					   uint8_t dual_mac_feature);
+
+/**
+ * policy_mgr_get_force_1x1() - to find out if 1x1 connection is enforced
+ *
+ * @psoc: pointer to psoc
+ * @force_1x1: value to be filled
+ *
+ * This API is used to find out if 1x1 connection is enforced.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_force_1x1(struct wlan_objmgr_psoc *psoc,
+				    uint8_t *force_1x1);
+
+/**
+ * policy_mgr_get_max_conc_cxns() - to get configured max concurrent active
+ * connection count
+ *
+ * @psoc: pointer to psoc
+ *
+ * This API is used to query the configured max concurrent active connection
+ * count.
+ *
+ * Return: max active connection count
+ */
+uint32_t policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_set_max_conc_cxns() - to set supported max concurrent active
+ * connection count to policy mgr
+ *
+ * @psoc: pointer to psoc
+ * @max_conc_cxns: max active connection count
+ *
+ * This API is used to update the max concurrent active connection
+ * count to policy mgr
+ *
+ * Return: QDF_STATUS_SUCCESS if set successfully
+ */
+QDF_STATUS policy_mgr_set_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
+					uint32_t max_conc_cxns);
+
+/**
+ * policy_mgr_set_sta_sap_scc_on_dfs_chnl() - to set sta_sap_scc_on_dfs_chnl
+ * @psoc: pointer to psoc
+ * @sta_sap_scc_on_dfs_chnl: value to be set
+ *
+ * This API is used to set sta_sap_scc_on_dfs_chnl
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_set_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc,
+				       uint8_t sta_sap_scc_on_dfs_chnl);
+
+/**
+ * policy_mgr_get_sta_sap_scc_on_dfs_chnl() - to find out if STA and SAP
+ *						   SCC is allowed on DFS channel
+ * @psoc: pointer to psoc
+ * @sta_sap_scc_on_dfs_chnl: value to be filled
+ *
+ * This API is used to find out whether STA and SAP SCC is allowed on
+ * DFS channels
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *sta_sap_scc_on_dfs_chnl);
+
+/**
+ * policy_mgr_set_multi_sap_allowed_on_same_band() - to set
+ * multi_sap_allowed_on_same_band
+ * @psoc: pointer to psoc
+ * @multi_sap_allowed_on_same_band: value to be set
+ *
+ * This API is used to set multi_sap_allowed_on_same_band
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_set_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc *psoc,
+				bool multi_sap_allowed_on_same_band);
+
+/**
+ * policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl() - Get if STA-SAP scc is
+ * allowed on indoor channel
+ * @psoc: Global psoc pointer
+ *
+ * Return: true if STA-SAP SCC on indoor channel is allowed
+ */
+bool policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(
+				struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_multi_sap_allowed_on_same_band() - to find out if multi sap
+ * is allowed on same band
+ * @psoc: pointer to psoc
+ * @multi_sap_allowed_on_same_band: value to be filled
+ *
+ * This API is used to find out whether multi sap is allowed on same band
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_get_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc *psoc,
+				bool *multi_sap_allowed_on_same_band);
+
+/**
+ * policy_mgr_set_original_bw_for_sap_restart() - to set use_sap_original_bw
+ * @psoc: pointer to psoc
+ * @use_sap_original_bw: value to be set
+ *
+ * This API is used to set use_sap_original_bw
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_set_original_bw_for_sap_restart(struct wlan_objmgr_psoc *psoc,
+					   bool use_sap_original_bw);
+
+/**
+ * policy_mgr_get_original_bw_for_sap_restart() - to find out if sap original
+ * bw is used as default BW when do sap restart
+ * @psoc: pointer to psoc
+ * @use_sap_original_bw: value to be filled
+ *
+ * This API is used to find out whether sap original BW is used as default BW
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_get_original_bw_for_sap_restart(struct wlan_objmgr_psoc *psoc,
+					   bool *use_sap_original_bw);
+
+/**
+ * policy_mgr_get_dfs_sta_sap_go_scc_movement() - returns SAP / GO's movement
+ * in STA+SAP DFS SCC concurrency to whether SAP / GO should be moved first
+ * or not.
+ * @psoc: pointer to psoc
+ * @move_sap_go_first: value to be filled
+ *
+ * In STA+SAP DFS SCC concurrency, this API returns config on whether to move
+ * SAP / GO first on getting CSA STA side or not.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_get_dfs_sta_sap_go_scc_movement(struct wlan_objmgr_psoc *psoc,
+					   bool *move_sap_go_first);
+
+ /**
+  * policy_mgr_nss_update_cb() - callback from SME confirming nss
+  * update
+  * @psoc: psoc handle
+  * @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
+  * @request_id: request ID
+  *
+  * This function is the callback registered with SME at nss
+  * update request time
+  *
+  * Return: None
+  */
+
+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 request_id);
+/*
+ * policy_mgr_get_connected_vdev_band_mask() - to get the connected vdev band
+ * mask
+ * @vdev: pointer to vdev
+ *
+ * This API is used to get band of the frequency.
+ *
+ * Return: band mask of the frequency associated with the vdev
+ */
+uint32_t policy_mgr_get_connected_vdev_band_mask(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * policy_mgr_get_dfs_master_dynamic_enabled() - support dfs master or not
+ * on AP interface when STA+SAP(GO) concurrency
+ * @psoc: pointer to psoc
+ * @vdev_id: sap vdev id
+ *
+ * This API is used to check AP dfs master functionality enabled or not when
+ * STA+SAP(GO) concurrency.
+ * If g_sta_sap_scc_on_dfs_chan is non-zero, the STA+SAP(GO) concurrency
+ * is allowed on DFS channel SCC and the SAP's DFS master functionality
+ * should be enable/disable according to:
+ * 1. g_sta_sap_scc_on_dfs_chan is 0: function return true - dfs master
+ *     capability enabled.
+ * 2. g_sta_sap_scc_on_dfs_chan is 1: function return false - dfs master
+ *     capability disabled.
+ * 3. g_sta_sap_scc_on_dfs_chan is 2: dfs master capability based on STA on
+ *     5G or not:
+ *      a. 5G STA active - return false
+ *      b. no 5G STA active -return true
+ *
+ * Return: true if dfs master functionality should be enabled.
+ */
+bool
+policy_mgr_get_dfs_master_dynamic_enabled(struct wlan_objmgr_psoc *psoc,
+					  uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_can_skip_radar_event - Can skip DFS Radar event or not
+ * @psoc: soc obj
+ * @vdev_id: sap vdev id
+ *
+ * This API is used by dfs component to get decision whether to ignore
+ * the radar event or not.
+ *
+ * Return: true if Radar event should be ignored.
+ */
+bool
+policy_mgr_get_can_skip_radar_event(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_sta_sap_scc_lte_coex_chnl() - to find out if STA & SAP
+ *						     SCC is allowed on LTE COEX
+ * @psoc: pointer to psoc
+ * @sta_sap_scc_lte_coex: value to be filled
+ *
+ * This API is used to find out whether STA and SAP scc is allowed on LTE COEX
+ * channel
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_get_sta_sap_scc_lte_coex_chnl(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *sta_sap_scc_lte_coex);
+/**
+ * policy_mgr_get_sap_mandt_chnl() - to find out if SAP mandatory channel
+ *					  support is enabled
+ * @psoc: pointer to psoc
+ * @sap_mandt_chnl: value to be filled
+ *
+ * This API is used to find out whether SAP's mandatory channel support
+ * is enabled
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *sap_mandt_chnl);
+/**
+ * policy_mgr_get_indoor_chnl_marking() - to get if indoor channel can be
+ *						marked as disabled
+ * @psoc: pointer to psoc
+ * @indoor_chnl_marking: value to be filled
+ *
+ * This API is used to find out whether indoor channel can be marked as disabled
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc *psoc,
+				   uint8_t *indoor_chnl_marking);
+/**
+ * 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_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_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_set_ch_select_plcy() - to set channel selection policy
+ * @psoc: pointer to psoc
+ * @ch_select_policy: value to be set
+ *
+ * This API is used to set the ch selection policy.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_set_ch_select_plcy(struct wlan_objmgr_psoc *psoc,
+					 uint32_t ch_select_policy);
+
+/**
+ * policy_mgr_get_dynamic_mcc_adaptive_sch() - to get dynamic mcc adaptive
+ *                                             scheduler
+ * @psoc: pointer to psoc
+ * @dynamic_mcc_adaptive_sched: value to be filled
+ *
+ * This API is used to get dynamic mcc adaptive scheduler
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_get_dynamic_mcc_adaptive_sch(
+				struct wlan_objmgr_psoc *psoc,
+				bool *dynamic_mcc_adaptive_sched);
+
+/**
+ * policy_mgr_set_dynamic_mcc_adaptive_sch() - to set dynamic mcc adaptive
+ *                                             scheduler
+ * @psoc: pointer to psoc
+ * @dynamic_mcc_adaptive_sched: value to be set
+ *
+ * This API is used to set dynamic mcc adaptive scheduler
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS policy_mgr_set_dynamic_mcc_adaptive_sch(
+				struct wlan_objmgr_psoc *psoc,
+				bool dynamic_mcc_adaptive_sched);
+
+/**
+ * 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,
+					   bool *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_connection_count_with_mlo() - provides the count of
+ * current connections
+ * @psoc: PSOC object information
+ *
+ * This function provides the count of current connections, MLD dev count
+ * 1 connection no matter how many links connection.
+ *
+ * Return: connection count
+ */
+uint32_t
+policy_mgr_get_connection_count_with_mlo(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_is_chnl_in_diff_band() - to check that given channel
+ * is in diff band from existing channel or not
+ * @psoc: pointer to psoc
+ * @ch_freq: given channel frequency
+ *
+ * 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,
+				     uint32_t ch_freq);
+
+/**
+ * policy_mgr_is_pcl_weightage_required() - to check that PCL weightage req or
+ * not
+ * @psoc: pointer to psoc
+ *
+ * This API will check that whether PCL weightage need to consider in best
+ * candidate selection or not. If some APs are in PCL list, those AP will get
+ * additional weightage.
+ *
+ * Return: true if pcl weightage is not required
+ */
+bool policy_mgr_is_pcl_weightage_required(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_check_for_session_conc() - Check if concurrency is
+ * allowed for a session
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev ID
+ * @ch_freq: Channel frequency
+ *
+ * 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 vdev_id, uint32_t ch_freq);
+
+/**
+ * policy_mgr_handle_conc_multiport() - to handle multiport concurrency
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev ID
+ * @ch_freq: Channel frequency
+ * @reason: reason for connection update
+ * @request_id: Request id provided by the requester, can be used while
+ * calling callback to the requester
+ *
+ * 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 vdev_id, uint32_t ch_freq,
+				 enum policy_mgr_conn_update_reason reason,
+				 uint32_t request_id);
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
+ * concurrent change intf
+ * @psoc: PSOC object information
+ * @is_acs_mode: Indicates whether SAP is started in ACS mode
+ *
+ * Checks the concurrent change interface and restarts SAP
+ *
+ * Return: None
+ */
+void policy_mgr_check_concurrent_intf_and_restart_sap(
+		struct wlan_objmgr_psoc *psoc, bool is_acs_mode);
+#else
+void policy_mgr_check_concurrent_intf_and_restart_sap(
+		struct wlan_objmgr_psoc *psoc, bool is_acs_mode)
+{
+
+}
+#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
+
+/**
+ * policy_mgr_is_chan_switch_in_progress() - Check if any SAP/GO
+ * CSA is in progress or not
+ * @psoc: PSOC object information
+ *
+ * Return: true if AP CSA is in progress
+ */
+bool policy_mgr_is_chan_switch_in_progress(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_wait_chan_switch_complete_evt() - Wait for SAP/GO CSA complete
+ * event
+ * @psoc: PSOC object information
+ *
+ * Return: QDF_STATUS_SUCCESS if CSA complete
+ */
+QDF_STATUS policy_mgr_wait_chan_switch_complete_evt(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_ap_start_in_progress() - Check if any SAP/GO
+ * start is in progress or not
+ * @psoc: PSOC object information
+ *
+ * Return: true if AP starting is in progress
+ */
+bool policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_conc_vdev_on_same_mac() - Function to get concurrent
+ *                                          vdev on same mac
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @mac_id: mac id
+ *
+ * This function is used to get the concurrent vdev on same mac
+ *
+ * Return: vdev id of the concurrent interface running on same mac
+ *
+ */
+uint32_t policy_mgr_get_conc_vdev_on_same_mac(struct wlan_objmgr_psoc *psoc,
+					      uint32_t vdev_id, uint8_t mac_id);
+
+#ifdef WLAN_FEATURE_SR
+/**
+ * policy_mgr_sr_same_mac_conc_enabled() - Function to check same MAC
+ *					   concurrency support in Spatial Reuse
+ * @psoc: PSOC object information
+ *
+ * This function is used to check whether concurrency is supported
+ * on same mac or not with Spatial Reuse enabled.
+ *
+ * Return: True if same MAC concurrency is supported with Spatial Reuse
+ *	   else False.
+ */
+bool policy_mgr_sr_same_mac_conc_enabled(struct wlan_objmgr_psoc *psoc);
+#else
+static inline
+bool policy_mgr_sr_same_mac_conc_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+#endif
+
+/**
+ * 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_check_bw_with_unsafe_chan_freq() - valid SAP channel bw against
+ *                                               unsafe channel list
+ * @psoc: PSOC object information
+ * @center_freq: SAP channel center frequency
+ * @ch_width: SAP channel width
+ *
+ * Return: true if no unsafe channel fall in SAP channel bandwidth range,
+ *         false otherwise
+ */
+bool policy_mgr_check_bw_with_unsafe_chan_freq(struct wlan_objmgr_psoc *psoc,
+					       qdf_freq_t center_freq,
+					       enum phy_ch_width ch_width);
+/**
+ * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ * @ch_freq: Channel frequency 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: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS
+policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
+				       uint8_t vdev_id, uint32_t ch_freq,
+				       uint32_t ch_width, bool forced);
+
+#else
+static inline QDF_STATUS
+policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
+				       uint8_t vdev_id, uint32_t ch_freq,
+				       uint32_t ch_width, bool forced)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * policy_mgr_sta_sap_dfs_scc_conc_check() - validate and Move SAP channel
+ * using (E)CSA
+ *
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ * @csa_event: Pointer to CSA IE Received event data
+ *
+ * Invoke the function to change SAP channel using (E)CSA for STA+GO / SAP
+ * SCC scenario only. This function will move P2P-GO / SAP first and then STA
+ * will follow.
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS
+policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc *psoc,
+				      uint8_t vdev_id,
+				      struct csa_offload_params *csa_event);
+
+/**
+ * policy_mgr_sta_sap_dfs_enforce_scc() - validate and enforce SCC
+ * using (E)CSA upon receiving 1st beacon
+ *
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ *
+ * Invoke the function to enforce SCC upon receiving 1st beacon. SAP / GO
+ * movement will be triggered using (E)CSA for STA+GO / SAP DFS scenario only.
+ * The pre-requisite for this function is SAP / GO shall already moved to new
+ * channel by policy_mgr_sta_sap_dfs_scc_conc_check() function.
+ *
+ * Return: void
+ */
+void policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id);
+
+#ifdef WLAN_FEATURE_P2P_P2P_STA
+/**
+ * policy_mgr_is_p2p_p2p_conc_supported() - p2p concurrency support
+ * @psoc: pointer to psoc
+ *
+ * This API is used to check whether firmware supports p2p concurrency
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+bool
+policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc);
+#else
+static inline bool
+policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+#endif
+
+/**
+ * policy_mgr_fetch_existing_con_info() - check if another vdev
+ * is present and find mode, freq , vdev id and chan width
+ *
+ * @psoc: psoc object
+ * @vdev_id: vdev id
+ * @curr_go_freq: frequency
+ * @mode: existing vdev mode
+ * @con_freq: existing connection freq
+ * @ch_width: ch_width of existing connection
+ *
+ * This function checks if another vdev is there and fetch connection
+ * info for that vdev.This is mainly for force SCC implementation of GO+GO ,
+ * GO+SAP or GO+STA where we fetch other existing GO, STA, SAP on the same
+ * band with MCC.
+ *
+ * Return: vdev_id
+ */
+uint8_t
+policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id, uint32_t curr_go_freq,
+				   enum policy_mgr_con_mode *mode,
+				   uint32_t *con_freq,
+				   enum phy_ch_width *ch_width);
+
+#define GO_FORCE_SCC_DISABLE 0
+#define GO_FORCE_SCC_STRICT 1
+#define GO_FORCE_SCC_LIBERAL 2
+/*
+ * Stay in MCC for 1 second, in case of first p2p go channel
+ * needs to be moved to curr go channel
+ */
+#define WAIT_BEFORE_GO_FORCESCC_RESTART (1000)
+
+#ifdef WLAN_FEATURE_P2P_P2P_STA
+/**
+ * policy_mgr_is_go_scc_strict() - Get GO force SCC enabled or not
+ * @psoc: psoc object
+ *
+ * This function checks if force SCC logic should be used on GO interface
+ * as a strict mode.
+ *
+ * Return: True if p2p needs o be start on provided channel only.
+ */
+bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_process_forcescc_for_go () - start work queue to move first p2p go
+ * to new p2p go's channel
+ *
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ * @ch_freq: Channel frequency to change
+ * @ch_width: channel width to change
+ * @mode: existing vdev mode
+ *
+ * starts delayed work queue of 1 second to move first p2p go to new
+ * p2p go's channel.
+ *
+ * Return: None
+ */
+void policy_mgr_process_forcescc_for_go(
+		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+		uint32_t ch_freq, uint32_t ch_width,
+		enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_do_go_plus_go_force_scc() - First p2p go
+ * to new p2p go's channel
+ *
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ * @ch_freq: Channel frequency to change
+ * @ch_width: channel width to change
+ *
+ * Move first p2p go to new
+ * p2p go's channel.
+ *
+ * Return: None
+ */
+void policy_mgr_do_go_plus_go_force_scc(
+		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+		uint32_t ch_freq, uint32_t ch_width);
+#else
+static inline
+bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline
+void policy_mgr_process_forcescc_for_go(
+		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+		uint32_t ch_freq, uint32_t ch_width,
+		enum policy_mgr_con_mode mode)
+{}
+
+static inline
+void policy_mgr_do_go_plus_go_force_scc(
+		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+		uint32_t ch_freq, uint32_t ch_width)
+{}
+#endif
+
+/**
+ * policy_mgr_process_force_scc_for_nan () - force SAP scc on nan freq
+ *
+ * @psoc: PSOC object information
+ *
+ * Return: None
+ */
+void policy_mgr_process_force_scc_for_nan(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_check_sap_go_force_scc() - Check SAP GO MCC and save interface
+ * information
+ * @psoc: pointer to psoc
+ * @vdev: initiator vdev
+ * @reason_code: CSA reason code
+ *
+ * This API will check SAP and GO are coexistent on same band MCC or not. If
+ * it is, the interface ids will be saved and a delayed workqueue will be
+ * scheduled. The workqueue will handle the new channel selection and change
+ * the channel of second interface to avoid MCC.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_objmgr_vdev *vdev,
+				  enum sap_csa_reason_code reason_code);
+
+/**
+ * policy_mgr_set_pcl_for_existing_combo() - SET PCL for existing combo
+ * @psoc: PSOC object information
+ * @mode: Adapter mode
+ * @vdev_id: Vdev Id
+ *
+ * Return: None
+ */
+void policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc *psoc,
+					   enum policy_mgr_con_mode mode,
+					   uint8_t vdev_id);
+
+/**
+ * policy_mgr_set_pcl_for_connected_vdev() - Set the PCL for connected vdevs
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev Id
+ * @clear_pcl: option to clear the PCL first before setting the new one
+ *
+ * This API will set the preferred channel list for other connected vdevs aside
+ * from the calling function's vdev
+ *
+ * Context: Any kernel thread
+ * Return: None
+ */
+void policy_mgr_set_pcl_for_connected_vdev(struct wlan_objmgr_psoc *psoc,
+					   uint8_t vdev_id, bool clear_pcl);
+
+/**
+ * policy_mgr_set_pcl() - Set preferred channel list in the FW
+ * @psoc: PSOC object information
+ * @msg: message containing preferred channel list information
+ * @vdev_id: Vdev Id
+ * @clear_vdev_pcl: clear PCL flag
+ *
+ * Sends the set pcl command and PCL info to FW
+ *
+ * Context: Any kernel thread
+ * Return: QDF_STATUS_SUCCESS on successful posting, fail status in any other
+ *	   case
+ */
+QDF_STATUS policy_mgr_set_pcl(struct wlan_objmgr_psoc *psoc,
+			      struct policy_mgr_pcl_list *msg,
+			      uint8_t vdev_id,
+			      bool clear_vdev_pcl);
+
+/**
+ * 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);
+
+/**
+ * polic_mgr_send_pcl_to_fw() - Send PCL to fw
+ * @psoc: PSOC object information
+ * @mode: Adapter mode
+ *
+ * Loop through all existing connections, stop RSO, send PCL to firmware
+ * and start RSO. If Roaming is in progress on any of the interface,
+ * avoid PCL updation as PCL gets updated post roaming.
+ *
+ * Return: None
+ */
+void
+polic_mgr_send_pcl_to_fw(struct wlan_objmgr_psoc *psoc,
+			 enum QDF_OPMODE mode);
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * policy_mgr_mlo_sta_set_nlink() - Set link mode for MLO STA
+ * by link id bitmap
+ * @psoc: psoc object
+ * @vdev_id: vdev id
+ * @reason: reason to set
+ * @mode: mode to set
+ * @link_num: number of link, valid for mode:
+ * MLO_LINK_FORCE_MODE_ACTIVE_NUM, MLO_LINK_FORCE_MODE_INACTIVE_NUM
+ * @link_bitmap: link bitmap, valid for mode:
+ * MLO_LINK_FORCE_MODE_ACTIVE, MLO_LINK_FORCE_MODE_INACTIVE,
+ * MLO_LINK_FORCE_MODE_ACTIVE_NUM, MLO_LINK_FORCE_MODE_INACTIVE_NUM
+ * MLO_LINK_FORCE_MODE_NO_FORCE.
+ * @link_bitmap2: inactive link bitmap, only valid for mode
+ * MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE
+ * @link_control_flags: bitmap of enum link_control_flags.
+ *
+ * Interface to set link mode for MLO STA
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc,
+			     uint8_t vdev_id,
+			     enum mlo_link_force_reason reason,
+			     enum mlo_link_force_mode mode,
+			     uint8_t link_num,
+			     uint16_t link_bitmap,
+			     uint16_t link_bitmap2,
+			     uint32_t link_control_flags);
+
+/**
+ * policy_mgr_mlo_sta_set_link() - Set link mode for MLO STA
+ * @psoc: psoc object
+ * @reason: reason to set
+ * @mode: mode to set
+ * @num_mlo_vdev: number of vdevs
+ * @mlo_vdev_lst: vdev list
+ *
+ * Interface to set link mode for MLO STA
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_mlo_sta_set_link(struct wlan_objmgr_psoc *psoc,
+			    enum mlo_link_force_reason reason,
+			    enum mlo_link_force_mode mode,
+			    uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst);
+
+/**
+ * policy_mgr_is_ml_vdev_id() - check if vdev id is part of ML
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id to check
+ *
+ * Return: true if vdev is part of ml
+ */
+bool policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_disabled_ml_links_count() - provides the count of
+ * disabled ml links
+ * @psoc: PSOC object information
+ *
+ * This function provides the count of disabled ml links
+ *
+ * Return: disabled ml links count
+ */
+uint32_t policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_move_vdev_from_disabled_to_connection_tbl() - re-enable a ml link
+ * and move it from disabled link table to pm_conc_connection_list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void policy_mgr_move_vdev_from_disabled_to_connection_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+
+/**
+ * policy_mgr_move_vdev_from_connection_to_disabled_tbl() - Add/move the link
+ * vdev to disable a ml link table
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void policy_mgr_move_vdev_from_connection_to_disabled_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+
+/**
+ * policy_mgr_ml_link_vdev_need_to_be_disabled() - check if ml link need to be
+ * disabled during connection.
+ * @psoc: psoc
+ * @vdev: vdev
+ * @peer_assoc: check peer assoc command
+ *
+ * Check the vdev need to be moved to disabled policy mgr table.
+ * If peer_assoc = false, the API will check the forced inactive link bitmap
+ * as well. Vdev will be disabled if vdev's link id is forced inactive(includes
+ * dynamic inactive)
+ *
+ * Return: true if STA link is need to be disabled else false.
+ */
+bool
+policy_mgr_ml_link_vdev_need_to_be_disabled(struct wlan_objmgr_psoc *psoc,
+					    struct wlan_objmgr_vdev *vdev,
+					    bool peer_assoc);
+
+/**
+ * policy_mgr_is_set_link_in_progress() - Check set link in progress or not
+ * @psoc: psoc pointer
+ *
+ * Return: true if set link in progress
+ */
+bool policy_mgr_is_set_link_in_progress(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_wait_for_set_link_update() - Wait for set/clear link response
+ * @psoc: psoc pointer
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_wait_for_set_link_update(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_active_vdev_bitmap() - to get active ML STA vdev bitmap
+ * @psoc: PSOC object information
+ *
+ * This API will fetch the active ML STA vdev bitmap.
+ *
+ * Return: vdev bitmap value
+ */
+uint32_t
+policy_mgr_get_active_vdev_bitmap(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_emlsr_sta_concurrency_present() - Check whether eMLSR
+ * concurrency is present or not.
+ * @psoc: PSOC object information
+ *
+ * This API is to check if any other concurrency is present when an eMLSR
+ * STA connection is about to complete(i.e. when first link is connected
+ * and second link is coming up). This helps to let the eMLSR connection
+ * happen but not let firmware enter into eMLSR hw mode by sending
+ * mlo_force_link_inactive=1 in peer_assoc of link when other concurrency is
+ * present.
+ *
+ * Host driver shall disable the one link post connection anyway if concurrency
+ * is present. Once the concurrency is gone, policy_mgr shall evaluate and
+ * re-enable links to let firmware go to eMLSR hw mode.
+ *
+ * Return: true is it's allow otherwise false
+ */
+bool policy_mgr_is_emlsr_sta_concurrency_present(struct wlan_objmgr_psoc *psoc);
+#else
+static inline bool
+policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	return false;
+}
+
+static inline uint32_t
+policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline void
+policy_mgr_move_vdev_from_disabled_to_connection_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id) {}
+
+static inline bool
+policy_mgr_ml_link_vdev_need_to_be_disabled(struct wlan_objmgr_psoc *psoc,
+					    struct wlan_objmgr_vdev *vdev,
+					    bool peer_assoc)
+{
+	return false;
+}
+
+static inline void
+policy_mgr_move_vdev_from_connection_to_disabled_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id) {}
+
+static inline bool
+policy_mgr_is_set_link_in_progress(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline QDF_STATUS
+policy_mgr_wait_for_set_link_update(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline uint32_t
+policy_mgr_get_active_vdev_bitmap(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline bool
+policy_mgr_is_emlsr_sta_concurrency_present(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+#endif
+
+/**
+ * policy_mgr_skip_dfs_ch() - skip dfs channel or not
+ * @psoc: pointer to soc
+ * @skip_dfs_channel: pointer to result
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc,
+				  bool *skip_dfs_channel);
+
+/**
+ * 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 frequency value 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 frequency value
+ */
+uint32_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: Preferred channel freq list
+ * @len: length of the PCL
+ * @pcl_weight: Weights of the PCL
+ * @weight_len: Max length of the weights list
+ * @vdev_id: Vdev id
+ *
+ * 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,
+			      uint32_t *pcl_channels, uint32_t *len,
+			      uint8_t *pcl_weight, uint32_t weight_len,
+			      uint8_t vdev_id);
+
+/**
+ * policy_mgr_init_chan_avoidance() - init channel avoidance in policy manager.
+ * @psoc: PSOC object information
+ * @chan_freq_list: channel frequency list
+ * @chan_cnt: channel count
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc,
+					  qdf_freq_t *chan_freq_list,
+					  uint16_t chan_cnt);
+
+/**
+ * policy_mgr_update_with_safe_channel_list() - provides the safe
+ * channel list
+ * @psoc: PSOC object information
+ * @pcl_channels: channel freq 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,
+					      uint32_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
+ * @vdev_id: Vdev Id
+ *
+ * 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: uint32_t non-dfs channel frequency
+ */
+uint32_t
+policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc,
+					enum policy_mgr_con_mode mode,
+					bool for_existing_conn,
+					uint8_t vdev_id);
+
+/**
+ * policy_mgr_is_any_nondfs_chnl_present() - Find any non-dfs
+ * channel from conc table
+ * @psoc: PSOC object information
+ * @ch_freq: pointer to channel frequency 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,
+					   uint32_t *ch_freq);
+
+/**
+ * policy_mgr_get_dfs_beaconing_session_id() - to find the
+ * first DFS session id
+ * @psoc: PSOC object information
+ *
+ * Return: If any beaconing session such as SAP or GO present and it is on
+ * DFS channel then this function will return its session id
+ *
+ */
+uint32_t policy_mgr_get_dfs_beaconing_session_id(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_any_dfs_beaconing_session_present() - to find
+ * if any DFS session
+ * @psoc: PSOC object information
+ * @ch_freq: pointer to channel frequency that needs to filled
+ * @ch_width: pointer to channel width for the beaconing session
+ *
+ * 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, qdf_freq_t *ch_freq,
+		enum hw_mode_bandwidth *ch_width);
+
+/**
+ * policy_mgr_allow_concurrency() - Check for allowed concurrency
+ * combination consulting the PCL
+ * @psoc: PSOC object information
+ * @mode:	new connection mode
+ * @ch_freq: channel frequency on which new connection is coming up
+ * @bw: Bandwidth requested by the connection (optional)
+ * @ext_flags: extended flags for concurrency check (union conc_ext_flag)
+ * @vdev_id: vdev id
+ *
+ * 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 based on concurrency support
+ */
+bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
+				  enum policy_mgr_con_mode mode,
+				  uint32_t ch_freq,
+				  enum hw_mode_bandwidth bw,
+				  uint32_t ext_flags, uint8_t vdev_id);
+
+/**
+ * policy_mgr_check_scc_channel() - Check if SAP/GO freq need to be updated
+ * as per exiting concurrency
+ * @psoc: PSOC object information
+ * @intf_ch_freq: Channel frequency of existing concurrency
+ * @sap_ch_freq: Given SAP/GO channel frequency
+ * @vdev_id: Vdev id of the SAP/GO
+ * @cc_mode: concurrent switch mode
+ *
+ * When SAP/GO is starting or re-starting, check SAP/GO freq need to be
+ * aligned with the existing concurrencies. i.e. Forced to be on same freq as
+ * exiting concurrency.
+ *
+ * Return: True/False
+ */
+void policy_mgr_check_scc_channel(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t *intf_ch_freq,
+				  qdf_freq_t sap_ch_freq,
+				  uint8_t vdev_id, uint8_t cc_mode);
+
+/**
+ * policy_mgr_handle_go_sap_fav_channel() - Get preferred force SCC
+ * channel frequency using favorite mandatory channel list for GO+SAP
+ * concurrency
+ * @psoc: Pointer to Psoc
+ * @vdev_id: vdev id
+ * @sap_ch_freq: sap/go channel starting channel frequency
+ * @intf_ch_freq: prefer force scc frequency
+ *
+ * SAP should move to 2.4 GHz if P2P GO is on 5G/6G. SAP should move to user
+ * configured channel after P2P GO is stopped
+ *
+ * Return: QDF_STATUS_SUCCESS if a valid favorite SAP channel is found
+ */
+QDF_STATUS
+policy_mgr_handle_go_sap_fav_channel(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id, qdf_freq_t sap_ch_freq,
+				     qdf_freq_t *intf_ch_freq);
+
+/**
+ * policy_mgr_nan_sap_pre_enable_conc_check() - Check if NAN+SAP SCC is
+ *                                              allowed in given ch
+ * @psoc: PSOC object information
+ * @mode: Connection mode
+ * @ch_freq: channel frequency to check
+ *
+ * Return: True if allowed else false
+ */
+bool
+policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc,
+					 enum policy_mgr_con_mode mode,
+					 uint32_t ch_freq);
+
+/**
+ * policy_mgr_allow_concurrency_csa() - Check for allowed concurrency
+ * combination when channel switch
+ * @psoc:	PSOC object information
+ * @mode:	connection mode
+ * @ch_freq:	target channel frequency to switch
+ * @bw:	target channel bandwidth
+ * @vdev_id:	vdev id of channel switch interface
+ * @forced:	forced to chan switch.
+ * @reason:	request reason of CSA
+ *
+ * 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,
+				 uint32_t ch_freq, enum hw_mode_bandwidth bw,
+				 uint32_t vdev_id, bool forced,
+				 enum sap_csa_reason_code reason);
+
+/**
+ * policy_mgr_get_bw() - Convert phy_ch_width to hw_mode_bandwidth.
+ * @chan_width: phy_ch_width
+ *
+ * Return: hw_mode_bandwidth
+ */
+enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width);
+
+/**
+ * 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);
+
+#ifdef FEATURE_FOURTH_CONNECTION
+/**
+ * policy_mgr_get_fourth_connection_pcl_table_index() - provides the
+ * row index to fourthConnectionPclTable to get to the correct
+ * pcl
+ * @psoc: PSOC object information
+ *
+ * This function provides the row index to
+ * fourthConnectionPclTable. 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_three_connection_mode
+	policy_mgr_get_fourth_connection_pcl_table_index(
+		struct wlan_objmgr_psoc *psoc);
+#endif
+
+/**
+ * policy_mgr_incr_connection_count() - adds the new connection to
+ * the current connections list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @mode: Operating mode
+ *
+ * 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,
+					    enum QDF_OPMODE mode);
+
+/**
+ * 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
+ * @ch_freq: Channel frequency on which new connection will be
+ * @reason: Reason for which connection update is required
+ * @request_id: Request id provided by the requester, can be used while
+ * calling callback to the requester
+ *
+ * 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, uint32_t ch_freq,
+				      enum policy_mgr_conn_update_reason reason,
+				      uint32_t request_id);
+
+/**
+ * policy_mgr_change_hw_mode_sta_connect() - Change HW mode for STA connect
+ * @psoc: psoc object
+ * @scan_list: candidates for connection
+ * @vdev_id: vdev id for STA/CLI
+ * @connect_id: connect id of the connect request
+ *
+ * When a new connection is about to come up, change hw mode for STA/CLI
+ * based upon the scan results and hw type.
+ *
+ * Return: status if set HW mode is fail or already taken care of.
+ */
+QDF_STATUS
+policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc,
+				      qdf_list_t *scan_list, uint8_t vdev_id,
+				      uint32_t connect_id);
+
+/**
+ * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
+ * concurreny
+ * @psoc: PSOC object information
+ * @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);
+
+#ifndef WLAN_FEATURE_LL_LT_SAP
+/**
+ * policy_mgr_get_pcl_chlist_for_ll_sap() - Get pcl channel list for LL SAP
+ * @psoc: PSOC object information
+ * @len: length of the PCL
+ * @pcl_channels: Preferred channel freq list
+ * @pcl_weight: Weights of the PCL
+ *
+ * This function provides the preferred channel list on which the ll sap
+ * can come.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_get_pcl_chlist_for_ll_sap(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *len, uint32_t *pcl_channels,
+				     uint8_t *pcl_weight);
+
+/**
+ * policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present() - Get pcl channel
+ * list for SAP/GO when LL SAP is present
+ * @psoc: PSOC object information
+ * @len: length of the PCL
+ * @pcl_channels: Preferred channel freq list
+ * @pcl_weight: Weights of the PCL
+ *
+ * This function provides the preferred channel list for SAP/GO when LL SAP
+ * is present
+ *
+ * Return: QDF_STATUS
+ */
+
+QDF_STATUS
+policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present(
+					struct wlan_objmgr_psoc *psoc,
+					uint32_t *len, uint32_t *pcl_channels,
+					uint8_t *pcl_weight);
+
+/**
+ * policy_mgr_get_pcl_channel_for_ll_sap_concurrency() - Get pcl channel list
+ * for LL SAP concurrency
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ * @pcl_channels: Preferred channel freq list
+ * @pcl_weight: Weights of the PCL
+ * @len: length of the PCL
+ *
+ * Return: QDF_STATUS
+ */
+
+QDF_STATUS
+policy_mgr_get_pcl_channel_for_ll_sap_concurrency(
+					struct wlan_objmgr_psoc *psoc,
+					uint32_t vdev_id,
+					uint32_t *pcl_channels,
+					uint8_t *pcl_weight, uint32_t *len);
+#else
+static inline QDF_STATUS
+policy_mgr_get_pcl_chlist_for_ll_sap(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *len, uint32_t *pcl_channels,
+				     uint8_t *pcl_weight)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present(
+					struct wlan_objmgr_psoc *psoc,
+					uint32_t *len, uint32_t *pcl_channels,
+					uint8_t *pcl_weight)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+policy_mgr_get_pcl_channel_for_ll_sap_concurrency(
+					struct wlan_objmgr_psoc *psoc,
+					uint32_t vdev_id,
+					uint32_t *pcl_channels,
+					uint8_t *pcl_weight, uint32_t *len)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * policy_mgr_is_vdev_ll_sap() - Check whether given vdev is LL SAP or not
+ * @psoc: psoc object
+ * @vdev_id: vdev id
+ *
+ * Return: true if it's present otherwise false
+ */
+bool
+policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc *psoc,
+			  uint32_t vdev_id);
+
+/**
+ * policy_mgr_is_vdev_ll_ht_sap() - Check whether given vdev is HT LL SAP or not
+ * @psoc: psoc object
+ * @vdev_id: vdev id
+ *
+ * Based on vdev id ap profile set via vendor command is get and compared with
+ * ll_ht_type AP type and is return true if profile set is throghput sensitive.
+ *
+ * Return: true if it's present otherwise false
+ */
+bool
+policy_mgr_is_vdev_ll_ht_sap(struct wlan_objmgr_psoc *psoc,
+			     uint32_t vdev_id);
+
+/**
+ * policy_mgr_is_vdev_ll_lt_sap() - Check whether given vdev is LL_LT_SAP or not
+ * @psoc: psoc object
+ * @vdev_id: vdev id
+ *
+ * Based on vdev id ap profile set via vendor command is get and compared with
+ * lt_ll_type AP and is return true if profile set is gaming or losless audio
+ * where latency matters.
+ *
+ * Return: true if it's present otherwise false
+ */
+bool
+policy_mgr_is_vdev_ll_lt_sap(struct wlan_objmgr_psoc *psoc,
+			     uint32_t vdev_id);
+
+/**
+ * policy_mgr_get_preferred_dbs_action_table() - get dbs action table type
+ * @psoc: Pointer to psoc
+ * @vdev_id: vdev Id
+ * @ch_freq: channel frequency 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,
+	uint32_t ch_freq,
+	enum policy_mgr_conn_update_reason reason);
+
+/**
+ * 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);
+
+/**
+ * policy_mgr_qdf_opmode_to_pm_con_mode() - provides the
+ * type translation from QDF to policy manager type
+ * @psoc: psoc
+ * @device_mode: Generic connection mode type
+ * @vdev_id: Vdev id
+ *
+ *
+ * This function provides the type translation
+ *
+ * Return: policy_mgr_con_mode enum
+ */
+enum policy_mgr_con_mode
+policy_mgr_qdf_opmode_to_pm_con_mode(struct wlan_objmgr_psoc *psoc,
+				     enum QDF_OPMODE device_mode,
+				     uint8_t vdev_id);
+
+/**
+ * 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
+ * @action: action to be applied before hw mode change
+ *
+ * @request_id: Request id provided by the requester, can be used while
+ * calling callback to the requester
+ *
+ * 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, enum policy_mgr_conc_next_action action,
+		uint32_t request_id);
+
+/**
+ * typedef 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
+ * @request_id: Request id provided by the requester, can be used while
+ * calling callback to the requester
+ *
+ * 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,
+				uint32_t request_id);
+
+/**
+ * typedef 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
+ * @request_id: cm req 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, uint32_t request_id);
+
+/**
+ * struct policy_mgr_sme_cbacks - SME Callbacks to be invoked
+ * from policy manager
+ * @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_nss_update_request: Update NSS value to FW
+ * @sme_change_mcc_beacon_interval: Set MCC beacon interval to FW
+ * @sme_rso_start_cb: Enable roaming offload callback
+ * @sme_rso_stop_cb: Disable roaming offload callback
+ * @sme_change_sap_csa_count: Change CSA count for SAP/GO, only one
+ *			      time, needs to set again if used once.
+ * @sme_sap_update_ch_width: Update sap ch_width to fw to handle SAP 320MHz
+ *                           concurrencies
+ */
+struct policy_mgr_sme_cbacks {
+	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_nss_update_request)(uint32_t vdev_id,
+		uint8_t new_nss, uint8_t ch_width,
+		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, uint32_t request_id);
+	QDF_STATUS (*sme_change_mcc_beacon_interval)(uint8_t session_id);
+	QDF_STATUS (*sme_rso_start_cb)(
+		mac_handle_t mac_handle, uint8_t vdev_id,
+		uint8_t reason, enum wlan_cm_rso_control_requestor requestor);
+	QDF_STATUS (*sme_rso_stop_cb)(
+		mac_handle_t mac_handle, uint8_t vdev_id,
+		uint8_t reason, enum wlan_cm_rso_control_requestor requestor);
+	QDF_STATUS (*sme_change_sap_csa_count)(uint8_t count);
+	QDF_STATUS (*sme_sap_update_ch_width)(struct wlan_objmgr_psoc *psoc,
+			uint8_t vdev_id,
+			enum phy_ch_width ch_width,
+			enum policy_mgr_conn_update_reason reason,
+			uint8_t conc_vdev_id, uint32_t request_id);
+};
+
+/**
+ * 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_is_chan_switch_in_progress: Check if in any adapter channel switch is in
+ * progress
+ * @hdd_is_cac_in_progress: Check if in any adapter CAC is in progress
+ * @wlan_hdd_set_sap_csa_reason: Set the sap csa reason in cases like NAN.
+ * @hdd_get_ap_6ghz_capable: get ap vdev 6ghz capable info from hdd ap adapter.
+ * @wlan_hdd_indicate_active_ndp_cnt: indicate active ndp cnt to hdd
+ * @wlan_get_ap_prefer_conc_ch_params: get prefer ap channel bw parameters
+ *  based on target channel frequency and concurrent connections.
+ * @wlan_get_sap_acs_band: get acs band from sap config
+ * @wlan_check_cc_intf_cb: get interference frequency of input SAP/GO interface
+ * @wlan_set_tx_rx_nss_cb: set NSS dynamically for STA
+ */
+struct policy_mgr_hdd_cbacks {
+	QDF_STATUS (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc,
+						 uint8_t vdev_id,
+						 uint32_t ch_freq,
+						 uint32_t channel_bw,
+						 bool forced);
+	QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id, uint32_t *ch_freq);
+	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_is_chan_switch_in_progress)(void);
+	bool (*hdd_is_cac_in_progress)(void);
+	void (*wlan_hdd_set_sap_csa_reason)(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id, uint8_t reason);
+	uint32_t (*hdd_get_ap_6ghz_capable)(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id);
+	void (*wlan_hdd_indicate_active_ndp_cnt)(struct wlan_objmgr_psoc *psoc,
+						 uint8_t vdev_id, uint8_t cnt);
+	QDF_STATUS (*wlan_get_ap_prefer_conc_ch_params)(
+			struct wlan_objmgr_psoc *psoc,
+			uint8_t vdev_id, uint32_t chan_freq,
+			struct ch_params *ch_params);
+	uint32_t (*wlan_get_sap_acs_band)(struct wlan_objmgr_psoc *psoc,
+					  uint8_t vdev_id, uint32_t *acs_band);
+	QDF_STATUS (*wlan_check_cc_intf_cb)(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id,
+					    uint32_t *ch_freq);
+	QDF_STATUS (*wlan_set_tx_rx_nss_cb)(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id, uint8_t tx_nss,
+					    uint8_t rx_nss);
+};
+
+/**
+ * struct policy_mgr_conc_cbacks - lim Callbacks to be invoked
+ * from policy manager
+ * @connection_info_update: check and update params based on STA/SAP
+ *                          concurrency.such as EDCA params and RTS threshold.
+ *                          If updated, it will also send the updated parameters
+ *                          to FW.
+ */
+
+struct policy_mgr_conc_cbacks {
+	void (*connection_info_update)(void);
+};
+
+/**
+ * struct policy_mgr_tdls_cbacks - TDLS Callbacks to be invoked
+ * from policy manager
+ * @tdls_notify_increment_session:
+ * @tdls_notify_decrement_session:
+ */
+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
+ * @hdd_ipa_set_perf_level_bw: Callback to set ipa perf level based on BW
+ */
+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);
+	void (*hdd_ipa_set_perf_level_bw)(enum hw_mode_bandwidth bw);
+};
+
+/**
+ * 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
+ * @request_id: Request id provided by the requester, can be used while
+ * calling callback to the requester
+ *
+ * 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,
+		uint32_t request_id);
+
+/**
+ * policy_mgr_validate_dbs_switch() - Check DBS action valid or not
+ * @psoc: Pointer to psoc
+ * @action: action requested
+ *
+ * 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.
+ */
+QDF_STATUS
+policy_mgr_validate_dbs_switch(struct wlan_objmgr_psoc *psoc,
+			       enum policy_mgr_conc_next_action action);
+
+/**
+ * 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_is_scc_with_this_vdev_id() - Check if this vdev_id has SCC with
+ * other vdev_id's
+ * @psoc: PSOC object information
+ * @vdev_id: vdev_id
+ *
+ * This function checks if the given vdev_id has SCC with any other vdev's
+ * or not.
+ *
+ * Return: true if SCC exists, false otherwise
+ */
+bool policy_mgr_is_scc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id);
+
+/**
+ * policy_mgr_is_mcc_with_this_vdev_id() - Is current vdev having MCC
+ * with any other vdev.
+ * @psoc: Pointer to PSOC object
+ * @vdev_id: vdev id
+ * @mcc_vdev_id: Concurrent MCC vdev id
+ *
+ * Return: true if MCC exists, false otherwise
+ */
+bool policy_mgr_is_mcc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id, uint8_t *mcc_vdev_id);
+
+/**
+ * policy_mgr_is_mcc_on_any_sta_vdev() - Check if any sta vdev is in MCC
+ * @psoc: Pointer to PSOC object
+ *
+ * Return: true if STA vdev is in MCC false otherwise
+ */
+bool policy_mgr_is_mcc_on_any_sta_vdev(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * 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_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_reset_hw_mode_change() - Reset the hw mode change.
+ * @psoc: Pointer to PSOC object
+ *
+ * Return: none
+ */
+void policy_mgr_reset_hw_mode_change(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 freq 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 channel 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, uint32_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
+ * @ch_freq: Channel frequency
+ * @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,
+		uint32_t ch_freq, 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
+ * @ch_freq_list: Channel frequency 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(uint32_t *ch_freq_list,
+				       uint32_t list_len);
+
+/**
+ * policy_mgr_get_valid_chans_from_range() - get valid channel from given range
+ * @psoc: PSOC object information
+ * @ch_list: Pointer to the channel frequency list
+ * @ch_cnt: Pointer to the length of the channel list
+ * @mode: Device mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_valid_chans_from_range(struct wlan_objmgr_psoc *psoc,
+						 uint32_t *ch_list,
+						 uint32_t *ch_cnt,
+						 enum policy_mgr_con_mode mode);
+/**
+ * policy_mgr_get_valid_chans() - Get the valid channel list
+ * @psoc: PSOC object information
+ * @ch_freq_list: Pointer to the valid channel frequency 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,
+				      uint32_t *ch_freq_list,
+				      uint32_t *list_len);
+
+/**
+ * policy_mgr_get_nss_for_vdev() - Get the allowed nss value for the
+ * vdev
+ * @psoc: PSOC object information
+ * @mode: connection type.
+ * @nss_2g: Pointer to the 2G Nss parameter.
+ * @nss_5g: 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
+ * @sap_ch_freq: sap current frequency in MHz
+ * @intf_ch_freq: input/out interference channel frequency to sap
+ * @sap_vdev_id: SAP vdev id
+ *
+ * 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 sap_ch_freq,
+				     uint32_t *intf_ch_freq,
+				     uint8_t sap_vdev_id);
+
+/**
+ * policy_mgr_set_sap_mandatory_channels() - Set the mandatory channel for SAP
+ * @psoc: PSOC object information
+ * @ch_freq_list: Channel frequency 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,
+						 uint32_t *ch_freq_list,
+						 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_bw_by_session_id() - Get channel width for a given session ID
+ * @psoc: PSOC object information
+ * @session_id: Session ID
+ *
+ * Return: channel width of the session
+ */
+enum phy_ch_width
+policy_mgr_get_bw_by_session_id(struct wlan_objmgr_psoc *psoc,
+				uint8_t session_id);
+
+/**
+ * policy_mgr_get_chan_by_session_id() - Get channel for a given session ID
+ * @psoc: PSOC object information
+ * @session_id: Session ID
+ * @ch_freq: Pointer to the channel frequency
+ *
+ * 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,
+					     uint32_t *ch_freq);
+
+/**
+ * policy_mgr_get_sap_go_count_on_mac() - Provide the count of sap and go on
+ * given mac
+ * @psoc: PSOC object information
+ * @list: To provide the vdev_id of the satisfied sap and go (optional)
+ * @mac_id: MAC ID
+ *
+ * This function provides the count of the matched sap and go
+ *
+ * Return: count of the satisfied sap and go
+ */
+uint32_t policy_mgr_get_sap_go_count_on_mac(struct wlan_objmgr_psoc *psoc,
+					    uint32_t *list, uint8_t mac_id);
+
+/**
+ * policy_mgr_is_sta_present_on_dfs_channel() - to find whether any DFS STA is
+ *                                              present
+ * @psoc: PSOC object information
+ * @vdev_id: pointer to vdev_id. It will be filled with the vdev_id of DFS STA
+ * @ch_freq: pointer to channel frequency on which DFS STA is present
+ * @ch_width: pointer channel width on which DFS STA is connected
+ * If any STA is connected 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_sta_present_on_dfs_channel(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *vdev_id,
+					      qdf_freq_t *ch_freq,
+					      enum hw_mode_bandwidth *ch_width);
+
+/**
+ * policy_mgr_is_sta_present_on_freq() - Checks whether sta is present on the
+ *                                       given frequency
+ * @psoc: PSOC object information
+ * @vdev_id: pointer to vdev_id. It will be filled with the vdev_id of DFS STA
+ * @ch_freq: channel for which this checks is needed
+ * @ch_width: pointer channel width on which DFS STA is connected
+ *
+ * Return: true if STA is found in ch_freq
+ */
+bool policy_mgr_is_sta_present_on_freq(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *vdev_id, qdf_freq_t ch_freq,
+				       enum hw_mode_bandwidth *ch_width);
+
+/**
+ * policy_mgr_is_sta_gc_active_on_mac() - Is there active sta/gc for a
+ * given mac id
+ * @psoc: PSOC object information
+ * @mac_id: MAC ID
+ *
+ * Checks if there is active sta/gc for a given mac id
+ *
+ * Return: true if there is active sta/gc for a given mac id, false otherwise
+ */
+bool policy_mgr_is_sta_gc_active_on_mac(struct wlan_objmgr_psoc *psoc,
+					uint8_t mac_id);
+
+/**
+ * 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_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 frequency
+ */
+uint32_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
+ * @vdev_id: Vdev Id
+ *
+ * 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,
+		uint32_t *pcl_ch, uint32_t *len,
+		uint8_t *pcl_weight, uint32_t weight_len,
+		bool all_matching_cxn_to_del,
+		uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_pcl_for_vdev_id() - Get PCL for 1 vdev
+ * @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
+ * @vdev_id: vdev id to get PCL
+ *
+ * Get the PCL for a vdev, when vdev need move to another channel, need
+ * get PCL after remove the vdev from connection list.
+ *
+ * Return: None
+ */
+QDF_STATUS policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc *psoc,
+					  enum policy_mgr_con_mode mode,
+					  uint32_t *pcl_ch, uint32_t *len,
+					  uint8_t *pcl_weight,
+					  uint32_t weight_len,
+					  uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_pcl_for_scc_in_same_mode() - Get PCL for vdev and other
+ * connection in same mode and same frequency
+ * @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
+ * @vdev_id: vdev id to get PCL
+ *
+ * If need move connections in same mode and same frequency, need get PCL
+ * after remove them from connection list.
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS
+policy_mgr_get_pcl_for_scc_in_same_mode(struct wlan_objmgr_psoc *psoc,
+					enum policy_mgr_con_mode mode,
+					uint32_t *pcl_ch, uint32_t *len,
+					uint8_t *pcl_weight,
+					uint32_t weight_len,
+					uint8_t vdev_id);
+
+/**
+ * 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
+ * @mode: Policy manager connection mode
+ * @vdev: pointer to vdev on which new connection is coming up
+ *
+ * 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,
+		enum policy_mgr_con_mode mode, struct wlan_objmgr_vdev *vdev);
+
+/**
+ * policy_mgr_set_hw_mode_on_channel_switch() - Set hw mode
+ * after channel switch
+ * @psoc: PSOC object information
+ * @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_check_and_set_hw_mode_for_channel_switch() - check if hw mode
+ * change is required before channel switch for STA/SAP,
+ * this is required if DBS mode is 2x2
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id on which channel switch is required
+ * @ch_freq: New channel frequency to which channel switch is requested
+ * @reason: reason for hw mode change
+ *
+ * Return: QDF_STATUS, success if HW mode change is required else Failure
+ */
+QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch(
+		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+		uint32_t ch_freq, enum policy_mgr_conn_update_reason reason);
+
+/**
+ * policy_mgr_checkn_update_hw_mode_single_mac_mode() - Set hw_mode to SMM
+ * if required
+ * @psoc: PSOC object information
+ * @ch_freq: channel frequency 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, uint32_t ch_freq);
+
+/**
+ * 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_get_macid_by_vdev_id() - get macid from vdev_id
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id to get PCL
+ *
+ * Return: mac id
+ */
+uint32_t policy_mgr_mode_get_macid_by_vdev_id(struct wlan_objmgr_psoc *psoc,
+					      uint32_t vdev_id);
+
+/**
+ * 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_dump_freq_range_n_vdev_map() - Dump freq range of mac and vdev to
+ * mac mapping
+ * @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.
+ * @num_mac_freq: Number of pdev freq mapping that follows
+ * @mac_freq_range: mac_freq_range mapping
+ *
+ * Return: None
+ */
+void
+policy_mgr_dump_freq_range_n_vdev_map(uint32_t num_vdev_mac_entries,
+			struct policy_mgr_vdev_mac_map *vdev_mac_map,
+			uint32_t num_mac_freq,
+			struct policy_mgr_pdev_mac_freq_map *mac_freq_range);
+
+/**
+ * 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.
+ * @num_mac_freq: Number of pdev freq mapping that follows
+ * @mac_freq_range: mac_freq_range mapping
+ * @context:
+ *
+ * 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,
+		uint32_t num_mac_freq,
+		struct policy_mgr_pdev_mac_freq_map *mac_freq_range,
+		struct wlan_objmgr_psoc *context);
+
+/**
+ * policy_mgr_will_freq_lead_to_mcc() - Check if the given freq can lead to
+ * MCC scenario with existing connection
+ * @psoc: psoc pointer
+ * @freq: freq to check with existing connections
+ *
+ * Return: true or false
+ */
+bool policy_mgr_will_freq_lead_to_mcc(struct wlan_objmgr_psoc *psoc,
+				      qdf_freq_t freq);
+
+/**
+ * policy_mgr_current_concurrency_is_scc() - To check the current
+ * concurrency combination if it is doing SCC
+ * @psoc: PSOC object information
+ * This routine is called to check if it is doing SCC
+ *
+ * Return: True - SCC, False - Otherwise
+ */
+bool policy_mgr_current_concurrency_is_scc(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * 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_concurrent_sta_on_different_mac() - To check if
+ * sta concurrency on different mac
+ * @psoc: PSOC object information
+ * This routine is called to check if sta concurrency on different mac
+ *
+ * Return: True - sta concurrency on different mac, False - Otherwise
+ */
+bool policy_mgr_concurrent_sta_on_different_mac(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_sap_p2pgo_on_dfs() - check if there is a P2PGO or SAP
+ * operating in a DFS channel
+ * @psoc: PSOC object information
+ * This routine is called to check if there is a P2PGO/SAP on DFS channel
+ *
+ * Return: True  - P2PGO/SAP present on DFS Channel
+ * False - Otherwise
+ */
+
+bool policy_mgr_is_sap_p2pgo_on_dfs(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_register_conc_cb() - register Lim callbacks
+ * @psoc: PSOC object information
+ * @conc_cbacks: function pointers from lim
+ *
+ * API, allows Lim to register callbacks to be invoked by policy
+ * mgr
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails)
+ */
+
+QDF_STATUS policy_mgr_register_conc_cb(struct wlan_objmgr_psoc *psoc,
+				struct policy_mgr_conc_cbacks *conc_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 DP callbacks
+ * @psoc: PSOC object information
+ * @dp_cbacks: function pointers from DP
+ *
+ * API, allows DP 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_find_if_fw_supports_dbs() - to find if FW/HW supports DBS
+ * @psoc: PSOC object information
+ *
+ * This API checks if legacy service ready event contains DBS or no.
+ * This API doesn't check service ready extension which contains actual
+ * hw mode list that tells if all supported HW modes' caps.
+ *
+ * Return: true (if service ready indication supports DBS or no) else false
+ *
+ */
+bool policy_mgr_find_if_fw_supports_dbs(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * 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_interband_mcc_supported() - Checks for interband MCC support
+ * @psoc: PSOC object information
+ * Checks if target supports interband MCC or not
+ *
+ * Return: True if the target supports interband MCC else False
+ */
+bool policy_mgr_is_interband_mcc_supported(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_dbs_scan_allowed() - Check if DBS scan is allowed or not
+ * @psoc: PSOC object information
+ * Checks if the DBS scan can be performed or not
+ *
+ * Return: true if DBS scan is allowed.
+ */
+bool policy_mgr_is_dbs_scan_allowed(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_hw_emlsr_capable() - Check if HW is EMLSR capable
+ * @psoc: PSOC object information
+ * Checks if the HW is EMLSR capable
+ *
+ * Return: true if the HW is EMLSR capable
+ */
+bool policy_mgr_is_hw_emlsr_capable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_2_freq_always_on_same_mac() - Function to check whether both the
+ * input frequencies are on same mac in all supported mode/freq range
+ * @psoc: Pointer to Psoc
+ * @freq_1: Frequency 1 to check
+ * @freq_2: Frequency 2 to check
+ *
+ * This Function check whether both the input frequency exist in the same mac
+ * in all supported mode/freq range
+ *
+ * Return:True if both the frequency exist on the same mac in all supported
+ * mode/freq range.
+ */
+bool policy_mgr_2_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc,
+					  qdf_freq_t freq_1, qdf_freq_t freq_2);
+
+/**
+ * policy_mgr_are_2_freq_on_same_mac() - Function to check whether both the
+ * input frequencies are on same mac in current freq range
+ * @psoc: Pointer to Psoc
+ * @freq_1: Frequency 1 to check
+ * @freq_2: Frequency 2 to check
+ *
+ * This Function check whether both the input frequency exist in the same mac
+ *
+ * Return:True if both the frequency exist on the same mac.
+ */
+bool
+policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t freq_1,
+				  qdf_freq_t  freq_2);
+
+/**
+ * policy_mgr_3_freq_always_on_same_mac() - Function to check whether all three
+ * input frequencies will always in same mac in all supported mode/freq range
+ * @psoc: Pointer to Psoc
+ * @freq_1: Frequency 1 to check
+ * @freq_2: Frequency 2 to check
+ * @freq_3: Frequency 3 to check
+ *
+ * This Function check whether all three input frequencies exist in the same
+ * mac in all supported mode/freq range.
+ *
+ * Return:True if all three frequency exist on the same mac in all supported
+ * mode/freq range
+ */
+bool
+policy_mgr_3_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc,
+				     qdf_freq_t freq_1, qdf_freq_t freq_2,
+				     qdf_freq_t freq_3);
+
+/**
+ * policy_mgr_are_3_freq_on_same_mac() - Function to check whether all three
+ * input frequencies are in same mac in current freq range
+ * @psoc: Pointer to Psoc
+ * @freq_1: Frequency 1 to check
+ * @freq_2: Frequency 2 to check
+ * @freq_3: Frequency 3 to check
+ *
+ * This Function check whether all three input frequencies exist in the same
+ * mac.
+ *
+ * Return:True if all three frequency exist on the same mac
+ */
+bool
+policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t freq_1, qdf_freq_t freq_2,
+				  qdf_freq_t freq_3);
+
+/**
+ * policy_mgr_allow_4th_new_freq() - Function to check whether 4th freq can
+ * be allowed with existing 3 vifs
+ * @psoc: Pointer to Psoc
+ * @ch_freq: new channel frequency
+ * @mode: new device mode
+ * @ext_flags: extended flags for concurrency check
+ *
+ * Return:True if 4th freq can be allowed with existing 3 vifs
+ */
+#ifdef FEATURE_FOURTH_CONNECTION
+bool
+policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc,
+			      qdf_freq_t ch_freq,
+			      enum policy_mgr_con_mode mode,
+			      uint32_t ext_flags);
+#else
+static inline bool
+policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc,
+			      qdf_freq_t ch_freq,
+			      enum policy_mgr_con_mode mode,
+			      uint32_t ext_flags)
+{
+	return false;
+}
+#endif
+
+/**
+ * policy_mgr_are_sbs_chan() - Function to check whether both the
+ * input frequency are in SBS frequency range
+ *
+ * @psoc: Pointer to Psoc
+ * @freq_1: Frequency 1 to check
+ * @freq_2: Frequency 2 to check
+ *
+ * This Function check whether both the input frequency exist in the SBS
+ * frequency range.
+ *
+ * Return:True if both the frequency exist on the SBS frequency range.
+ *
+ */
+bool
+policy_mgr_are_sbs_chan(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1,
+			qdf_freq_t  freq_2);
+
+/**
+ * policy_mgr_is_current_hwmode_dbs() - Function to check if current HW mode is
+ * DBS
+ *
+ * @psoc: Pointer to Psoc
+ *
+ * This Function checks if current HW mode is DBS
+ *
+ * Return:True if current HW mode is DBS.
+ *
+ */
+bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_current_hwmode_sbs() - Function to check if current HW mode is
+ * SBS
+ *
+ * @psoc: Pointer to Psoc
+ *
+ * This Function checks if current HW mode is SBS
+ *
+ * Return:True if current HW mode is SBS.
+ *
+ */
+bool policy_mgr_is_current_hwmode_sbs(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_curr_hwmode_emlsr() - Function to check if current HW mode is
+ * eMLSR
+ *
+ * @psoc: Pointer to psoc
+ *
+ * This Function checks if current HW mode is eMLSR
+ *
+ * Return:True if current HW mode is eMLSR.
+ *
+ */
+bool policy_mgr_is_curr_hwmode_emlsr(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_dp_hw_dbs_capable() - if hardware is capable of dbs 2x2
+ * or 1X1 for Data Path (HW mode)
+ * @psoc: PSOC object information
+ * This API is for Data Path to get HW mode support dbs.
+ *
+ * Return: true - DBS capable, false - not
+ */
+bool policy_mgr_is_dp_hw_dbs_capable(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_hw_dbs_required_for_band() - Check whether hardware needs DBS
+ * mode to support the given band
+ * @psoc: PSOC object information
+ * @band: band
+ *
+ * The function checks whether DBS mode switching required or not to support
+ * given band based on target capability.
+ * Any HW which doesn't support given band on PHY A will need DBS HW mode when a
+ * connection is coming up on that band.
+ *
+ * Return: true - DBS mode required for requested band
+ */
+bool policy_mgr_is_hw_dbs_required_for_band(struct wlan_objmgr_psoc *psoc,
+					    enum hw_mode_mac_band_cap band);
+
+/*
+ * 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_sap_restart() - Restart SAP when band/channel change
+ * @psoc: Pointer to soc
+ * @vdev_id: Vdev id
+ *
+ * Return: None
+ */
+void
+policy_mgr_check_sap_restart(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
+/**
+ * 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
+ *
+ * Return: 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_init_sbs_fw_config() - Function to initialize SBS
+ * fw mode config in policy manager component
+ * @psoc: PSOC object information
+ * @fw_config: FW config
+ *
+ * This function initialize SBS fw mode config in policy manager component
+ *
+ * Return: void
+ *
+ */
+void policy_mgr_init_sbs_fw_config(struct wlan_objmgr_psoc *psoc,
+				   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_mode_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);
+
+QDF_STATUS policy_mgr_update_sbs_freq(struct wlan_objmgr_psoc *psoc,
+				      struct target_psoc_info *tgt_hdl);
+
+/**
+ * policy_mgr_get_sbs_cut_off_freq() - Function to get SBS 5g cut off freq
+ *
+ * @psoc: PSOC object information
+ *
+ * This function to get sbs cut off freq
+ *
+ * Return: cut of freq
+ *
+ */
+qdf_freq_t policy_mgr_get_sbs_cut_off_freq(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * 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
+ * @old_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
+ * @ch_freq: Channel frequency 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,
+					  uint32_t ch_freq, 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
+ * @channel_select_logic_conc:
+ *
+ * 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
+ * @ch_freq: channel frequency 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,
+				uint32_t ch_freq);
+
+#ifdef FEATURE_WLAN_CH_AVOID_EXT
+/**
+ * policy_mgr_restrict_sap_on_unsafe_chan() - Check if need check unsafe
+ * channel if SAP start on fixed channel.
+ * @psoc: PSOC object information
+ *
+ * Return: true for success, else false
+ */
+bool policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc *psoc);
+#else
+static inline bool
+policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+#endif
+
+/**
+ * policy_mgr_is_sap_freq_allowed - Check if the channel is allowed for sap
+ * @psoc: PSOC object information
+ * @opmode: Current op_mode, helps to check whether it's P2P_GO/SAP
+ * @sap_freq: channel frequency to be checked
+ *
+ * Check the factors as below to decide whether the channel is allowed or not:
+ * If the channel is in LTE coex channel avoidance list;
+ * If it's STA+SAP SCC;
+ * If STA+SAP SCC on LTE coex channel is allowed.
+ *
+ * Return: true for allowed, else false
+ */
+bool policy_mgr_is_sap_freq_allowed(struct wlan_objmgr_psoc *psoc,
+				    enum QDF_OPMODE opmode,
+				    uint32_t sap_freq);
+
+/**
+ * policy_mgr_get_ch_width() - Convert hw_mode_bandwidth to phy_ch_width
+ * @bw: Hardware mode band width used by WMI
+ *
+ * Return: phy_ch_width
+ */
+enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw);
+
+/**
+ * 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_go_scc_enforced() - Get GO force SCC enabled or not
+ * @psoc: psoc object
+ *
+ * This function checks if force SCC logic should be used on GO interface.
+ *
+ * Return: True if allow GO force SCC
+ */
+bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_valid_sap_conc_channel_check() - Check and update
+ * the SAP channel in case of STA+SAP concurrency
+ * @psoc: PSOC object information
+ * @con_ch_freq: pointer to the chan freq on which sap will come up
+ * @sap_ch_freq: initial channel frequency for SAP
+ * @sap_vdev_id: sap vdev id.
+ * @ch_params: sap channel parameters
+ *
+ * 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, uint32_t *con_ch_freq,
+	uint32_t sap_ch_freq, uint8_t sap_vdev_id,
+	struct ch_params *ch_params);
+
+/**
+ * policy_mgr_get_alternate_channel_for_sap() - Get an alternate
+ * channel to move the SAP to
+ * @psoc: PSOC object information
+ * @sap_vdev_id: sap vdev id.
+ * @sap_ch_freq: sap channel frequency.
+ * @pref_band: Preferred band on channel is required
+ *
+ * This function returns an alternate channel for SAP to move to
+ *
+ * Return: The new channel for SAP
+ */
+uint32_t policy_mgr_get_alternate_channel_for_sap(
+	struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id,
+	uint32_t sap_ch_freq,
+	enum reg_wifi_band pref_band);
+
+/**
+ * policy_mgr_con_mode_by_vdev_id() - Get policy mgr con mode from vdev id
+ * @psoc: psoc object
+ * @vdev_id: vdev id
+ *
+ * return: enum policy_mgr_con_mode for the vdev id
+ */
+enum policy_mgr_con_mode
+policy_mgr_con_mode_by_vdev_id(struct wlan_objmgr_psoc *psoc,
+			       uint8_t vdev_id);
+
+/**
+ * policy_mgr_disallow_mcc() - Check for mcc
+ *
+ * @psoc: PSOC object information
+ * @ch_freq: channel frequency 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,
+			     uint32_t ch_freq);
+
+/**
+ * policy_mgr_mode_specific_get_channel() - Get channel for a
+ * connection type
+ * @psoc: PSOC object information
+ * @mode: Connection type
+ *
+ * Get channel frequency for a connection type
+ *
+ * Return: channel frequency
+ */
+uint32_t policy_mgr_mode_specific_get_channel(struct wlan_objmgr_psoc *psoc,
+					      enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_add_sap_mandatory_chan() - Add chan to SAP mandatory channel
+ * list
+ * @psoc: Pointer to soc
+ * @ch_freq: Channel frequency to be added
+ *
+ * Add chan to SAP mandatory channel list
+ *
+ * Return: None
+ */
+void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+				       uint32_t ch_freq);
+
+/**
+ * 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_chan() - Init 2.4G 5G 6G SAP mandatory channel
+ * list
+ * @psoc: Pointer to soc
+ * @org_ch_freq: sap initial channel frequency MHz
+ *
+ * Initialize the 2.4G 5G 6G SAP mandatory channels
+ *
+ * Return: None
+ */
+void  policy_mgr_init_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+					 uint32_t org_ch_freq);
+
+/**
+ * policy_mgr_remove_sap_mandatory_chan() - Remove channel from SAP mandatory
+ * channel list
+ * @psoc: Pointer to soc
+ * @ch_freq: channel frequency to be removed from mandatory list
+ *
+ * Remove channel from SAP mandatory channel list
+ *
+ * Return: None
+ */
+void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+					  uint32_t ch_freq);
+
+/*
+ * 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_disabled_inactive_channels_to_zero() - set weight
+ * of disabled and inactive channels to 0
+ * @psoc: pointer to soc
+ * @pcl: preferred channel freq 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 disabled and inactive channels to 0
+ *
+ * Return: None
+ */
+void policy_mgr_set_weight_of_disabled_inactive_channels_to_zero(
+		struct wlan_objmgr_psoc *psoc, uint32_t *pcl,
+		uint32_t *len, uint8_t *weight_list, uint32_t weight_len);
+/**
+ * policy_mgr_is_sap_allowed_on_dfs_freq() - check if sap allowed on dfs freq
+ * @pdev: id of objmgr pdev
+ * @vdev_id: vdev id
+ * @ch_freq: channel freq
+ * This function is used to check if sta_sap_scc_on_dfs_chan ini is set,
+ * DFS master capability is assumed disabled in the driver.
+ *
+ * Return: true if sap is allowed on dfs freq,
+ * otherwise false
+ */
+bool policy_mgr_is_sap_allowed_on_dfs_freq(struct wlan_objmgr_pdev *pdev,
+					   uint8_t vdev_id, qdf_freq_t ch_freq);
+/**
+ * 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_multi_sap_allowed_on_same_band() - check if multi sap allowed
+ * on same band
+ * @pdev: id of objmgr pdev
+ * @mode: operating mode of interface to be checked
+ * @ch_freq: channel freq
+ * This function is used to check if multi sap can be started on the same band
+ *
+ * Return: true if multi sap is allowed on same band, otherwise false
+ */
+bool policy_mgr_is_multi_sap_allowed_on_same_band(
+					struct wlan_objmgr_pdev *pdev,
+					enum policy_mgr_con_mode mode,
+					qdf_freq_t ch_freq);
+
+/**
+ * policy_mgr_is_special_mode_active_5g() - check if given mode active in 5g
+ * @psoc: pointer to soc
+ * @mode: operating mode of interface to be checked
+ *
+ * Return: true if given mode is active in 5g
+ */
+bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc,
+					  enum policy_mgr_con_mode mode);
+
+/**
+ * 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_is_connected_sta_5g() - check if sta connected in 5 GHz
+ * @psoc: pointer to soc
+ * @freq: Pointer to the frequency on which sta is connected
+ *
+ * Return: true if sta is connected in 5 GHz else false
+ */
+bool policy_mgr_is_connected_sta_5g(struct wlan_objmgr_psoc *psoc,
+				    qdf_freq_t *freq);
+
+/**
+ * policy_mgr_scan_trim_5g_chnls_for_dfs_ap() - check if sta scan should skip
+ * 5g channel when dfs ap is present.
+ *
+ * @psoc: pointer to soc
+ * @freq: DFS freq of concurrent SAP/GO
+ *
+ * Return: true if sta scan 5g chan should be skipped
+ */
+bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc,
+					      qdf_freq_t *freq);
+
+/**
+ * policy_mgr_scan_trim_chnls_for_connected_ap() - check if sta scan
+ * should skip 5g or 2.4g channel when AP/GO connected by clients.
+ * STA + AP 5G (connected) + AP 2.4G		skip 5G scan
+ * STA + AP 5G (connected)			skip 5G scan
+ * STA + AP 2.4G (connected && 2.4G only)	skip 2.4G scan
+ *
+ * @pdev: pointer to pdev
+ *
+ * Return: trim_channel_list
+ */
+uint16_t
+policy_mgr_scan_trim_chnls_for_connected_ap(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * policy_mgr_is_hwmode_set_for_given_chnl() - to check for given channel
+ * if the hw mode is properly set.
+ * @psoc: pointer to psoc
+ * @ch_freq: given channel frequency
+ *
+ * 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,
+					     uint32_t ch_freq);
+
+/**
+ * policy_mgr_get_connection_info() - Get info of all active connections
+ * @psoc: pointer to soc
+ * @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
+ * @psoc: pointer to soc
+ * @mode_change_cb: 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
+ * @psoc: pointer to soc
+ *
+ * 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
+ * @mode: operating mode of interface to be checked
+ * @ch_freq: 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,
+					 uint32_t ch_freq,
+					 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_get_user_config_sap_freq() - Get the user configured channel
+ *
+ * @psoc: pointer to psoc
+ * @vdev_id: vdev id
+ *
+ * Return: user configured frequency
+ */
+qdf_freq_t policy_mgr_get_user_config_sap_freq(struct wlan_objmgr_psoc *psoc,
+					       uint8_t vdev_id);
+
+/**
+ * policy_mgr_nan_sap_post_enable_conc_check() - Do concurrency operations
+ *                                               post nan/sap enable
+ * @psoc: pointer to psoc
+ *
+ * Return: QDF_STATUS
+ **/
+QDF_STATUS
+policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_nan_sap_post_disable_conc_check() - Do concurrency related
+ *                                                operation post nan/sap disable
+ * @psoc: pointer to psoc
+ *
+ * Return: void
+ **/
+void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_sap_restart_required_after_sta_disconnect() - is sap restart
+ * required
+ * after sta disconnection
+ * @psoc: psoc object data
+ * @sap_vdev_id: sap vdev id
+ * @intf_ch_freq: sap channel frequency
+ * @is_acs_mode: Indicates whether SAP is started in ACS mode or fixed 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, uint32_t sap_vdev_id,
+			uint32_t *intf_ch_freq, bool is_acs_mode);
+
+/**
+ * policy_mgr_is_sta_sap_scc() - check whether SAP is doing SCC with
+ * STA
+ * @psoc: pointer to psoc
+ * @sap_ch_freq: operating channel frequency 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,
+			       uint32_t sap_ch_freq);
+
+/**
+ * policy_mgr_nan_sap_scc_on_unsafe_ch_chk() - check whether SAP is doing SCC
+ *                                             with NAN
+ * @psoc: pointer to psoc
+ * @sap_freq: operating channel frequency of SAP interface
+ *
+ * Return: true or false
+ */
+bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc,
+					     uint32_t sap_freq);
+
+/**
+ * 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);
+
+#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)
+/**
+ * policy_mgr_is_6ghz_conc_mode_supported() - Check connection mode supported
+ * on 6ghz or not
+ * @psoc: Pointer to soc
+ * @mode: new connection mode
+ *
+ * Current PORed 6ghz connection modes are STA, SAP, P2P.
+ *
+ * Return: true if supports else false.
+ */
+bool policy_mgr_is_6ghz_conc_mode_supported(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_init_ap_6ghz_capable - Init 6Ghz capable flags
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @ap_6ghz_capable: vdev 6ghz capable flag
+ *
+ * Init 6Ghz capable flags for active connection in policy mgr conn table
+ *
+ * Return: void
+ */
+void policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id,
+				     enum conn_6ghz_flag ap_6ghz_capable);
+
+/**
+ * policy_mgr_set_ap_6ghz_capable - Set 6Ghz capable flags to connection list
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @set: set or clear
+ * @ap_6ghz_capable: vdev 6ghz capable flag
+ *
+ * Set/Clear 6Ghz capable flags for active connection in policy mgr conn table
+ *
+ * Return: void
+ */
+void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id,
+				    bool set,
+				    enum conn_6ghz_flag ap_6ghz_capable);
+
+/**
+ * policy_mgr_get_ap_6ghz_capable - Get 6Ghz capable info for a vdev
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @conn_flag: output conntion flags
+ *
+ * Get 6Ghz capable flag for ap vdev (SAP). When SAP on 5G, for same reason
+ * the AP needs to be moved to 6G and this API will be called to check whether
+ * AP is 6Ghz capable or not.
+ * AP is allowed on 6G band only when all of below statements are true:
+ * a. SAP config includes WPA3 security - SAE,OWE,SuiteB.
+ * b. SAP is configured by ACS range which includes any 6G channel or
+ *    configured by 6G Fixed channel.
+ * c. SAP has no legacy clients (client doesn't support 6G band).
+ *    legacy client (non 6ghz capable): association request frame has no
+ *    6G band global operating Class.
+ *
+ * Return: true if AP is 6ghz capable
+ */
+bool policy_mgr_get_ap_6ghz_capable(
+	struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t *conn_flag);
+#else
+static inline bool policy_mgr_is_6ghz_conc_mode_supported(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
+{
+	return false;
+}
+
+static inline void policy_mgr_init_ap_6ghz_capable(
+	struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+	enum conn_6ghz_flag ap_6ghz_capable)
+{}
+
+static inline
+void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id,
+				    bool set,
+				    enum conn_6ghz_flag ap_6ghz_capable)
+{}
+
+static inline bool policy_mgr_get_ap_6ghz_capable(
+	struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t *conn_flag)
+{
+	return false;
+}
+
+#endif
+
+/**
+ * policy_mgr_update_nan_vdev_mac_info() - Update the NAN vdev id and MAC id in
+ * policy manager
+ * @psoc: psoc object
+ * @nan_vdev_id: NAN Discovery pseudo vdev id
+ * @mac_id: NAN Discovery MAC ID
+ *
+ * Stores NAN Discovery related vdev and MAC id in policy manager
+ *
+ * Return: QDF Success
+ */
+QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc,
+					       uint8_t nan_vdev_id,
+					       uint8_t mac_id);
+
+/**
+ * policy_mgr_get_mode_specific_conn_info() - Get active mode specific
+ * channel and vdev id
+ * @psoc: PSOC object information
+ * @ch_freq_list: Mode specific channel freq 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,
+						uint32_t *ch_freq_list,
+						uint8_t *vdev_id,
+						enum policy_mgr_con_mode mode);
+
+/*
+ * policy_mgr_get_ml_and_non_ml_sta_count() - get ML and non ML STA count
+ * also fills the freq and non ML/ML list
+ * @psoc: Objmgr psoc
+ * @num_ml: num ML as output
+ * @ml_idx: ML vdev index as output
+ * @num_non_ml: num non ML as output
+ * @non_ml_idx: non ML vdev index as output
+ * @freq_list: freq list of each sta vdev
+ * @vdev_id_list: vdev id list
+ *
+ * Return: void
+ */
+void policy_mgr_get_ml_and_non_ml_sta_count(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *num_ml, uint8_t *ml_idx,
+					    uint8_t *num_non_ml,
+					    uint8_t *non_ml_idx,
+					    qdf_freq_t *freq_list,
+					    uint8_t *vdev_id_list);
+
+/**
+ * policy_mgr_is_sap_go_on_2g() - check if sap/go is on 2g
+ * @psoc: PSOC object information
+ *
+ * Return: true or false
+ */
+bool policy_mgr_is_sap_go_on_2g(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_dump_channel_list() - Print channel list
+ * @len: Length of pcl list
+ * @pcl_channels: pcl channels list
+ * @pcl_weight: pcl weight list
+ *
+ *
+ * Return: True or false
+ */
+bool policy_mgr_dump_channel_list(uint32_t len,
+				  uint32_t *pcl_channels,
+				  uint8_t *pcl_weight);
+
+/**
+ * policy_mgr_filter_passive_ch() -filter out passive channels from the list
+ * @pdev: Pointer to pdev
+ * @ch_freq_list: pointer to channel frequency list
+ * @ch_cnt: number of channels in list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_filter_passive_ch(struct wlan_objmgr_pdev *pdev,
+					uint32_t *ch_freq_list,
+					uint32_t *ch_cnt);
+
+/**
+ * policy_mgr_is_restart_sap_required() - check whether sap need restart
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @freq: sap current freq
+ * @scc_mode: mcc to scc switch mode
+ *
+ * If there is no STA/P2P CLI on same MAC of SAP/P2P GO,
+ * SAP/P2P Go needn't switch channel to force scc.
+ *
+ * Return: True or false
+ */
+bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id,
+					qdf_freq_t freq,
+					tQDF_MCC_TO_SCC_SWITCH_MODE scc_mode);
+
+/**
+ * policy_mgr_get_roam_enabled_sta_session_id() - get the session id of the sta
+ * on which roaming is enabled.
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id of the requestor
+ *
+ * The function checks if any sta(other than the provided vdev_id) is present
+ * and has roaming enabled and return the session id of the sta with roaming
+ * enabled else if roaming is not enabled on any STA return
+ * WLAN_UMAC_VDEV_ID_MAX.
+ *
+ * Return: session id of STA on which roaming is enabled
+ */
+uint8_t policy_mgr_get_roam_enabled_sta_session_id(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+
+/**
+ * policy_mgr_is_sta_mon_concurrency() - check if MONITOR and STA concurrency
+ * is UP.
+ * @psoc: pointer to psoc object
+ *
+ * Return: True - if STA and monitor concurrency is there, else False
+ *
+ */
+bool policy_mgr_is_sta_mon_concurrency(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_check_mon_concurrency() - Checks if monitor intf can be added.
+ * @psoc: pointer to psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS if allowed, else send failure
+ *
+ */
+QDF_STATUS policy_mgr_check_mon_concurrency(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_hw_dbs_max_bw() - Computes DBS BW
+ * @psoc: PSOC object information
+ * @bw_dbs: BW info of both MAC0 and MAC1
+ * This function computes BW info of both MAC0 and MAC1
+ *
+ * Return: void
+ */
+void policy_mgr_get_hw_dbs_max_bw(struct wlan_objmgr_psoc *psoc,
+				  struct dbs_bw *bw_dbs);
+
+/**
+ * policy_mgr_get_radio_combinations() - Query the supported radio combinations
+ * @psoc: soc object
+ * @comb: combination buffer
+ * @comb_max: max combination number can be saved to comb buffer
+ * @comb_num: returned combination number
+ *
+ * This function returns the radio combination information supported by target.
+ *
+ * Return: QDF_STATUS_SUCCESS if query successfully
+ */
+QDF_STATUS policy_mgr_get_radio_combinations(struct wlan_objmgr_psoc *psoc,
+					     struct radio_combination *comb,
+					     uint32_t comb_max,
+					     uint32_t *comb_num);
+
+/**
+ * policy_mgr_is_mlo_sta_disconnected() - Check all STA in mlo are disconnected
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id for sta
+ *
+ * if any link is associated the API will return false.
+ *
+ * Return: True if all sta links are disconnected
+ */
+bool policy_mgr_is_mlo_sta_disconnected(struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id);
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * policy_mgr_is_ml_sta_links_in_mcc() - Check ML links are in MCC or not
+ * @psoc: psoc ctx
+ * @ml_freq_lst: ML STA freq list
+ * @ml_vdev_lst: ML STA vdev id list
+ * @ml_linkid_lst: ML STA link id list
+ * @num_ml_sta: Number of total ML STA links
+ * @affected_linkid_bitmap: link id bitmap which home channels are in MCC
+ * with each other
+ *
+ * Return: true if ML link in MCC else false
+ */
+bool
+policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t *ml_freq_lst,
+				  uint8_t *ml_vdev_lst,
+				  uint8_t *ml_linkid_lst,
+				  uint8_t num_ml_sta,
+				  uint32_t *affected_linkid_bitmap);
+
+/**
+ * policy_mgr_is_ml_links_in_mcc_allowed() - Check ML links are in MCC or not
+ * @psoc: psoc ctx
+ * @vdev: Pointer to vdev object
+ * @ml_sta_vdev_lst: ML STA vdev id list
+ * @num_ml_sta: Number of total ML STA links
+ *
+ * Return: QDF_STATUS_SUCCESS if ML link in MCC is allowed
+ */
+QDF_STATUS
+policy_mgr_is_ml_links_in_mcc_allowed(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      uint8_t *ml_sta_vdev_lst,
+				      uint8_t *num_ml_sta);
+
+/**
+ * policy_mgr_is_vdev_high_tput_or_low_latency() - Check vdev has
+ * high througput or low latency flag
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ *
+ * Return: true if vdev has high throughput or low latency flag
+ */
+bool
+policy_mgr_is_vdev_high_tput_or_low_latency(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id);
+
+/**
+ * policy_mgr_check_2ghz_only_sap_affected_link() - Check force inactive
+ * link is needed for 2.4 GHz only sap
+ * @psoc: PSOC object information
+ * @sap_vdev_id: sap vdev id
+ * @sap_ch_freq: sap channel frequency
+ * @ml_ch_freq_num: ML STA link num
+ * @ml_freq_lst: ML STA link frequency list
+ *
+ * Return: true if 2.4 GHz only sap present and need to force inactive
+ * ML link
+ */
+bool
+policy_mgr_check_2ghz_only_sap_affected_link(
+			struct wlan_objmgr_psoc *psoc,
+			uint8_t sap_vdev_id,
+			qdf_freq_t sap_ch_freq,
+			uint8_t ml_ch_freq_num,
+			qdf_freq_t *ml_freq_lst);
+
+/**
+ * policy_mgr_vdev_is_force_inactive() - Check force inactive or not
+ * for the vdev id
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ *
+ * Return: true if the vdev is in force inactive
+ */
+bool policy_mgr_vdev_is_force_inactive(struct wlan_objmgr_psoc *psoc,
+				       uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_legacy_conn_info() - Get legacy connection info
+ * @psoc: PSOC object information
+ * @vdev_lst: vdev id list
+ * @freq_lst: channel frequency list
+ * @mode_lst: vdev mode list
+ * @lst_sz: array size of above parameters
+ *
+ * This API will return the legacy STA/SAP/P2P connection info.
+ * If a connection want to avoid MCC with ML STA, that connection
+ * will be put in head of array list. And in 3 Port concurrency
+ * case (ML STA + 2 legacy Connections), usually we can only meet
+ * the high priority connection's MCC avoidance, so this API will
+ * return sorted lists based on the priority. Right now we don't
+ * clear requirement on which legacy interface has higher priority,
+ * here we follow this order: STA, SAP, P2P.
+ *
+ * Return: number of legacy connection count
+ */
+uint8_t
+policy_mgr_get_legacy_conn_info(struct wlan_objmgr_psoc *psoc,
+				uint8_t *vdev_lst,
+				qdf_freq_t *freq_lst,
+				enum policy_mgr_con_mode *mode_lst,
+				uint8_t lst_sz);
+
+/*
+ * policy_mgr_get_ml_sta_info_psoc() - Get number of ML STA vdev ids and
+ * freq list
+ * @pm_ctx: pm_ctx ctx
+ * @num_ml_sta: Return number of ML STA present
+ * @num_disabled_ml_sta: Return number of disabled ML STA links
+ * @ml_vdev_lst: Return ML STA vdev id list
+ * @ml_freq_lst: Return ML STA freq list
+ * @num_non_ml: Return number of non-ML STA present
+ * @non_ml_vdev_lst: Return non-ML STA vdev id list
+ * @non_ml_freq_lst: Return non-ML STA freq list
+ *
+ * Return: void
+ */
+void
+policy_mgr_get_ml_sta_info_psoc(struct wlan_objmgr_psoc *psoc,
+				uint8_t *num_ml_sta,
+				uint8_t *num_disabled_ml_sta,
+				uint8_t *ml_vdev_lst,
+				qdf_freq_t *ml_freq_lst,
+				uint8_t *num_non_ml,
+				uint8_t *non_ml_vdev_lst,
+				qdf_freq_t *non_ml_freq_lst);
+
+/**
+ * policy_mgr_handle_link_removal_on_vdev() - Handle AP link removal for
+ * MLO STA
+ * @vdev: objmgr vdev
+ *
+ * Handle link removal for STA vdev:
+ * Send force link command to target if MLO STA link number > 1.
+ * Select other inactive link to active if possible.
+ *
+ * Return: void
+ */
+void policy_mgr_handle_link_removal_on_vdev(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * policy_mgr_handle_link_removal_on_standby() - Handle AP link removal for
+ * MLO STA standby links
+ * @vdev: objmgr vdev
+ * @reconfig_info: link reconfig info
+ *
+ * Handle link removal for ML STA standby links:
+ * Send force link command to target with link removal reason code
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_handle_link_removal_on_standby(struct wlan_objmgr_vdev *vdev,
+					  struct ml_rv_info *reconfig_info);
+
+/**
+ * policy_mgr_is_mlo_sap_concurrency_allowed() - Check for mlo sap allowed
+ *                                               concurrency combination
+ * @psoc: PSOC object information
+ * @is_new_vdev_mlo: Is new vdev a mlo device or not
+ * @new_vdev_id: new vdev id which need concurrency check
+ *
+ * When a new connection is about to come up check if current
+ * concurrency combination including the new connection is
+ * allowed or not. Currently no concurrency support for mlo sap
+ *
+ * Return: True if concurrency is supported, otherwise false.
+ */
+bool policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
+					       bool is_new_vdev_mlo,
+					       uint8_t new_vdev_id);
+
+/**
+ * policy_mgr_get_conc_ext_flags() - get extended flags for concurrency check
+ * @vdev: pointer to vdev on which new connection is coming up
+ * @force_mlo: true means it's a MLO connection, false means uncertain
+ *
+ * In some scenario the flag WLAN_VDEV_FEXT2_MLO may not set for vdev when
+ * checking concurrency, then caller can set force_mlo accordingly to get
+ * proper extended flags.
+ *
+ * Return: extended flags for concurrency check
+ */
+uint32_t
+policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo);
+
+/**
+ * policy_mgr_is_non_ml_sta_present() - Check whether Non-ML STA is present
+ * @psoc: PSOC object information
+ *
+ * Return: True if non-ML STA is present, otherwise false.
+ */
+bool policy_mgr_is_non_ml_sta_present(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_mlo_sta_present() - Check whether MLO STA is present
+ * @psoc: PSOC object information
+ *
+ * Return: True if MLO STA is present, otherwise false.
+ */
+bool policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_is_mlo_in_mode_sbs() - Check whether MLO present is SBS (with both
+ * links on 5/6 ghz band)
+ * @psoc: PSOC object information
+ * @mode: mlo mode to check
+ * @mlo_vdev_lst: Pointer to mlo vdev list, this function will fill this with
+ *                list of mlo vdev
+ * @num_mlo: Pointer to number of mlo link, this function will fill this with
+ *           number of mlo links
+ *
+ * Return: True if MLO is present with both links on 5 and 6ghz band
+ */
+bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo);
+
+/**
+ * policy_mgr_is_mlo_in_mode_dbs() - Check whether MLO present is DBS
+ * @psoc: PSOC object information
+ * @mode: mlo mode to check
+ * @mlo_vdev_lst: Pointer to mlo vdev list, this function will fill this with
+ *                list of mlo vdev
+ * @num_mlo: Pointer to number of mlo link, this function will fill this with
+ *           number of mlo links
+ *
+ * Return: True if MLO one link is on 2 GHz band and other links on
+ * 5/6 GHz band
+ */
+bool policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo);
+
+/**
+ * policy_mgr_is_mlo_in_mode_emlsr() - Check whether current connection is eMLSR
+ * @psoc: PSOC object information
+ * @mlo_vdev_lst: Pointer to mlo vdev list, this function will fill this with
+ *                list of mlo vdev
+ * @num_mlo: Pointer to number of mlo link, this function will fill this with
+ *           number of mlo links
+ *
+ * Return: True if current connection is in eMLSR mode i.e. Both STA and AP
+ *         support eMLSR connection along with vendor command selection
+ */
+bool policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *mlo_vdev_lst, uint8_t *num_mlo);
+
+/**
+ * policy_mgr_handle_ml_sta_links_on_vdev_up_csa() - Handle enable/disable
+ * link on vdev UP and channel change
+ * @psoc: objmgr psoc
+ * @mode: mode of vdev that went UP or changed channel
+ * @vdev_id: vdev_id which went UP or changed channel
+ *
+ * Return: void
+ */
+void
+policy_mgr_handle_ml_sta_links_on_vdev_up_csa(struct wlan_objmgr_psoc *psoc,
+					      enum QDF_OPMODE mode,
+					      uint8_t vdev_id);
+
+/**
+ * policy_mgr_handle_ml_sta_link_on_traffic_type_change() - Handle
+ * enable/disable link on vdev traffic type change on SAP/P2P vdev
+ * @psoc: objmgr psoc
+ * @vdev: vdev on which traffic type change
+ *
+ * Context: Should be called only from north bound context and never from
+ * schedular thread as it has wait for completed.
+ *
+ * Return: void
+ */
+void policy_mgr_handle_ml_sta_link_on_traffic_type_change(
+						struct wlan_objmgr_psoc *psoc,
+						struct wlan_objmgr_vdev *vdev);
+
+/**
+ * policy_mgr_handle_ml_sta_links_on_vdev_down() - Handle enable
+ * link on any vdev down
+ * @psoc: objmgr psoc
+ * @mode: mode of vdev that went down
+ * @vdev_id: vdev_id which went down
+ *
+ * Return: void
+ */
+void policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc *psoc,
+						 enum QDF_OPMODE mode,
+						 uint8_t vdev_id);
+
+/**
+ * policy_mgr_handle_emlsr_sta_concurrency() - Handle concurrency scenarios with
+ * EMLSR STA.
+ * @psoc: objmgr psoc
+ * @conc_con_coming_up: Indicates if any concurrent connection is coming up
+ * @emlsr_sta_coming_up: Carries true when eMLSR STA is coming up.
+ *			 Carries true when an unsupported concurrency is
+ *			 gone, so that host can let firmware go to eMLSR mode.
+ *
+ * The API handles concurrency scenarios with existing EMLSR connection when a
+ * new connection request is received OR with an existing legacy connection when
+ * an EMLSR sta comes up.
+ *
+ * Return: none
+ */
+void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc,
+					     bool conc_con_coming_up,
+					     bool emlsr_sta_coming_up);
+
+/**
+ * policy_mgr_clear_ml_links_settings_in_fw() - Process
+ * QCA_WLAN_VENDOR_ATTR_LINK_STATE_CONTROL_MODE in default mode
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev_id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_clear_ml_links_settings_in_fw(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id);
+
+/**
+ * policy_mgr_activate_mlo_links_nlink() - Force active ML links based on user
+ * requested link mac address with link bitmap
+ * @psoc: objmgr psoc
+ * @session_id: session id
+ * @num_links: number of links to be forced active
+ * @active_link_addr: link mac address of links to be forced active
+ *
+ * Return: void
+ */
+void policy_mgr_activate_mlo_links_nlink(struct wlan_objmgr_psoc *psoc,
+					 uint8_t session_id, uint8_t num_links,
+					 struct qdf_mac_addr *active_link_addr);
+
+/**
+ * policy_mgr_activate_mlo_links() - Force active ML links based on user
+ * requested link mac address with vdev bitmap
+ * @psoc: objmgr psoc
+ * @session_id: session id
+ * @num_links: number of links to be forced active
+ * @active_link_addr: link mac address of links to be forced active
+ *
+ * Return: void
+ */
+void policy_mgr_activate_mlo_links(struct wlan_objmgr_psoc *psoc,
+				   uint8_t session_id, uint8_t num_links,
+				   struct qdf_mac_addr *active_link_addr);
+
+/**
+ * policy_mgr_update_mlo_links_based_on_linkid() - Force active ML links based
+ * on user requested coming via QCA_NL80211_VENDOR_SUBCMD_MLO_LINK_STATE
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @num_links: number of links to be forced active
+ * @link_id_list: link id(s) list coming from user space
+ * @config_state_list: config state list coming from user space
+ *
+ * Return: success if the command gets processed successfully
+ */
+QDF_STATUS
+policy_mgr_update_mlo_links_based_on_linkid(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id,
+					    uint8_t num_links,
+					    uint8_t *link_id_list,
+					    uint32_t *config_state_list);
+
+/**
+ * policy_mgr_update_active_mlo_num_links() - Force active ML links based
+ * on user requested coming via LINK_STATE_MIXED_MODE_ACTIVE_NUM_LINKS
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @num_links: number of links to be forced active
+ *
+ * Return: success if the command gets processed successfully
+ */
+QDF_STATUS policy_mgr_update_active_mlo_num_links(struct wlan_objmgr_psoc *psoc,
+						  uint8_t vdev_id,
+						  uint8_t num_links);
+#else
+static inline bool
+policy_mgr_vdev_is_force_inactive(struct wlan_objmgr_psoc *psoc,
+				  uint8_t vdev_id)
+{
+	return false;
+}
+
+static inline bool policy_mgr_is_mlo_sap_concurrency_allowed(
+			struct wlan_objmgr_psoc *psoc,
+			bool is_new_vdev_mlo,
+			uint8_t new_vdev_id)
+{
+	return true;
+}
+
+static inline uint32_t
+policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo)
+{
+	return 0;
+}
+
+static inline bool
+policy_mgr_is_non_ml_sta_present(struct wlan_objmgr_psoc *psoc)
+{
+	return true;
+}
+
+static inline bool policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline
+bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	return false;
+}
+
+static inline
+bool policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	return false;
+}
+
+static inline void
+policy_mgr_handle_ml_sta_links_on_vdev_up_csa(struct wlan_objmgr_psoc *psoc,
+					      enum QDF_OPMODE mode,
+					      uint8_t vdev_id)
+{
+}
+
+static inline void
+policy_mgr_handle_ml_sta_link_on_traffic_type_change(
+						struct wlan_objmgr_psoc *psoc,
+						struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline
+bool policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	return false;
+}
+
+static inline
+void policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc *psoc,
+						 enum QDF_OPMODE mode,
+						 uint8_t vdev_id)
+{
+}
+#endif
+
+/**
+ * policy_mgr_is_hwmode_offload_enabled() - Check for HW mode selection offload
+ *  support
+ * @psoc: PSOC object information
+ *
+ * Check if target supports HW mode selection offload or not
+ *
+ * Return: True if the target supports HW mode selection offload,
+ *         False otherwise.
+ */
+bool policy_mgr_is_hwmode_offload_enabled(struct wlan_objmgr_psoc *psoc);
+/**
+ * policy_mgr_is_3rd_conn_on_same_band_allowed() - Check the third connection
+ * on same band allowed or not
+ * list for third connection
+ * @psoc: PSOC object information
+ * @mode: Device mode
+ * @ch_freq: 3rd channel frequency
+ *
+ * This function checks whether to allow third connection on same band or not
+ * based on pcl table
+ *
+ * Return: TRUE/FALSE
+ */
+bool policy_mgr_is_3rd_conn_on_same_band_allowed(struct wlan_objmgr_psoc *psoc,
+						 enum policy_mgr_con_mode mode,
+						 qdf_freq_t ch_freq);
+
+/**
+ * policy_mgr_get_connected_roaming_vdev_band_mask() - get connected vdev
+ * band mask
+ * @psoc: PSOC object
+ * @vdev_id: Vdev id
+ *
+ * Return: reg wifi band mask
+ */
+uint32_t
+policy_mgr_get_connected_roaming_vdev_band_mask(struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+
+/**
+ * policy_mgr_is_sta_chan_valid_for_connect_and_roam  - Check if given
+ * channel is valid for STA connection/roam pcl channels
+ * @pdev: pdev
+ * @freq: frequency
+ *
+ * Return: true if channel is valid else false
+ */
+bool policy_mgr_is_sta_chan_valid_for_connect_and_roam(
+					struct wlan_objmgr_pdev *pdev,
+					qdf_freq_t freq);
+
+/**
+ * policy_mgr_is_ap_ap_mcc_allow() - Check AP AP MCC allow or not
+ * @psoc: psoc object
+ * @pdev: pdev object
+ * @vdev: vdev object of new SAP or P2P GO
+ * @ch_freq: channel frequency of up coming vdev
+ * @ch_width: channel width
+ * @con_vdev_id: concurrent SAP/GO vdev id
+ * @con_freq: concurrent SAP/GO home channel.
+ *
+ * Check if AP AP MCC allow or not when new SAP or P2P GO creating.
+ * If not allowed, the concurrency SAP/GO vdev and channel will
+ * be returned.
+ *
+ * Return: True if the target allow AP AP MCC,
+ *         False otherwise.
+ */
+bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
+				   struct wlan_objmgr_pdev *pdev,
+				   struct wlan_objmgr_vdev *vdev,
+				   uint32_t ch_freq,
+				   enum phy_ch_width ch_width,
+				   uint8_t *con_vdev_id,
+				   uint32_t *con_freq);
+
+/**
+ * policy_mgr_any_other_vdev_on_same_mac_as_freq() - Function to check
+ * whether more than one vdev are present on same mac or not
+ * @psoc: PSOC object
+ * @freq: Channel frequency
+ * @vdev_id: Vdev id
+ *
+ * Return: True if more than one vdev are present on same mac
+ *
+ */
+bool policy_mgr_any_other_vdev_on_same_mac_as_freq(
+				struct wlan_objmgr_psoc *psoc,
+				uint32_t freq, uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_sbs_cfg() - Get SBS INI value
+ * @psoc: PSOC object
+ * @sbs: output sbs cfg value
+ *
+ */
+QDF_STATUS policy_mgr_get_sbs_cfg(struct wlan_objmgr_psoc *psoc, bool *sbs);
+
+/**
+ * policy_mgr_get_ll_sap_freq()- Function to get ll sap freq if it's present
+ * @psoc: PSOC object
+ *
+ * Based on vdev id ap profile set via vendor command is get and compared with
+ * ll_type_any AP type and return freq for that SAP if profile set is latency
+ * sensitive or throghput sensitive.
+ *
+ * Return: freq if it's LL SAP otherwise 0
+ *
+ */
+qdf_freq_t policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_ll_lt_sap_freq()- Function to get LT LL sap freq if it's
+ * present
+ * @psoc: PSOC object
+ *
+ * Based on vdev id ap profile set via vendor command is get and compared with
+ * lt_ll_type AP type and return freq for that SAP if profile set is latency
+ * sensitive example gaming or losless audio.
+ *
+ * Return: freq if it's LT LL SAP otherwise 0
+ *
+ */
+qdf_freq_t policy_mgr_get_ll_lt_sap_freq(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_ll_ht_sap_freq()- Function to get LL HT sap freq if it's
+ * present
+ * @psoc: PSOC object
+ *
+ * Based on vdev id ap profile set via vendor command is get and compared with
+ * ll_ht_type AP type and return freq for that SAP if profile set is throghput
+ * sensitive.
+ *
+ * Return: freq if it's HT LL SAP otherwise 0
+ *
+ */
+qdf_freq_t policy_mgr_get_ll_ht_sap_freq(struct wlan_objmgr_psoc *psoc);
+
+#ifndef WLAN_FEATURE_LL_LT_SAP
+/**
+ * policy_mgr_is_ll_sap_concurrency_valid() - Function to check whether
+ * low latency SAP + STA/SAP/GC/GO concurrency allowed or not
+ * @psoc: PSOC object
+ * @freq: Channel frequency
+ * @mode: Device mode
+ *
+ * Return: True if concurrency are allowed otherwise false
+ *
+ */
+bool policy_mgr_is_ll_sap_concurrency_valid(struct wlan_objmgr_psoc *psoc,
+					    qdf_freq_t freq,
+					    enum policy_mgr_con_mode mode);
+#else
+static inline
+bool policy_mgr_is_ll_sap_concurrency_valid(struct wlan_objmgr_psoc *psoc,
+					    qdf_freq_t freq,
+					    enum policy_mgr_con_mode mode)
+{
+	return true;
+}
+#endif
+/**
+ * policy_mgr_update_indoor_concurrency() - Function to update the indoor
+ * concurrency related regulatory changes
+ *
+ * @psoc: pointer to psoc
+ * @vdev_id: vdev id
+ * @discon_freq: disconnect frequency
+ * @type: enum indoor_conc_update_type
+ *
+ * Return: True if need to compute pdev current channel list
+ */
+bool
+policy_mgr_update_indoor_concurrency(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id,
+				     uint32_t discon_freq,
+				     enum indoor_conc_update_type type);
+/**
+ * policy_mgr_is_conc_sap_present_on_sta_freq() - Function to check if
+ * SAP or GO exists on the STA frequency
+ *
+ * @psoc: pointer to psoc
+ * @mode: interface mode
+ * @ch_freq: channel frequency
+ *
+ * Return: AP mode exists
+ */
+bool
+policy_mgr_is_conc_sap_present_on_sta_freq(struct wlan_objmgr_psoc *psoc,
+					   enum policy_mgr_con_mode mode,
+					   uint32_t ch_freq);
+
+/**
+ * policy_mgr_get_connection_count_with_ch_freq() - Get number of active
+ * connections on the channel frequecy
+ * @ch_freq: channel frequency
+ *
+ * Return: number of active connection on the specific frequency
+ */
+uint32_t policy_mgr_get_connection_count_with_ch_freq(uint32_t ch_freq);
+
+/**
+ * policy_mgr_is_sap_go_interface_allowed_on_indoor() - Check if SAP or GO
+ * interface is allowed on the indoor channel
+ *
+ * @pdev: pointer to pdev
+ * @vdev_id: vdev id
+ * @ch_freq: SAP frequency
+ *
+ * Return: is SAP allowed
+ */
+bool
+policy_mgr_is_sap_go_interface_allowed_on_indoor(struct wlan_objmgr_pdev *pdev,
+						 uint8_t vdev_id,
+						 qdf_freq_t ch_freq);
+
+#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
+/**
+ * policy_mgr_get_allowed_tdls_offchannel_freq() - Check if TDLS off-channel is
+ * allowed during concurrency. When off-channel is allowed, update the provided
+ * input channel frequency with concurrent vdev frequency in DBS case.
+ * Fill the provided channel frequency as 0 if all 5GHz/6GHz channels are
+ * allowed for off-channel operation in SCC case.
+ * Don't allow off channel operation in any MCC case.
+ * @psoc: psoc pointer
+ * @vdev: vdev pointer
+ * @ch_freq: Frequency pointer
+ *
+ * Return: true or false based on current concurrency combination
+ */
+bool
+policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc,
+					    struct wlan_objmgr_vdev *vdev,
+					    qdf_freq_t *ch_freq);
+#endif /* WLAN_FEATURE_TDLS_CONCURRENCIES */
+
+/**
+ * policy_mgr_is_sap_mode() - Check if mode is SAP mode
+ * @mode: Policy manager concurrency mode
+ *
+ * Return: true if mode is SAP mode else false
+ */
+bool policy_mgr_is_sap_mode(enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_is_beaconing_mode() - Check if mode represents beaconing entity
+ * @mode: Policy manager concurrency mode
+ *
+ * Return: true if mode represents beaconing entity else false
+ */
+bool policy_mgr_is_beaconing_mode(enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_get_nan_sap_scc_on_lte_coex_chnl() -Get if NAN + SAP SCC on
+ * lte coex channel is allowed on lte coex channel or not
+ * @psoc: psoc pointer
+ *
+ * Return: cfg value of nan sap scc is allowed or not on lte coex channel
+ */
+
+bool policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_reset_sap_mandatory_channels() - Reset the SAP mandatory channels
+ * @psoc: psoc object
+ *
+ * Resets the SAP mandatory channel list and the length of the list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_reset_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_sap_mode_count() - Get SAP interface counts
+ * @psoc: psoc object
+ * @list: To provide the indices on pm_conc_connection_list
+ *	(optional)
+ *
+ * Return: No of SAP interface counts
+ */
+uint32_t policy_mgr_get_sap_mode_count(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *list);
+
+/**
+ * policy_mgr_get_beaconing_mode_count() - Get Beaconing interface counts
+ * @psoc: psoc object
+ * @list: To provide the indices on pm_conc_connection_list
+ *	(optional)
+ *
+ * Return: No of Beaconing interface counts
+ */
+uint32_t policy_mgr_get_beaconing_mode_count(struct wlan_objmgr_psoc *psoc,
+					     uint32_t *list);
+
+/**
+ * policy_mgr_get_sap_mode_info() - Get active SAP channels and vdev ids
+ * @psoc: PSOC object information
+ * @ch_freq_list: Mode specific channel freq list
+ * @vdev_id: Mode specific vdev id (list)
+ *
+ * Get active SAP channel and vdev id
+ *
+ * Return: number of SAP connections found
+ */
+uint32_t policy_mgr_get_sap_mode_info(struct wlan_objmgr_psoc *psoc,
+				      uint32_t *ch_freq_list, uint8_t *vdev_id);
+
+/**
+ * policy_mgr_get_beaconing_mode_info() - Get active beaconing entity
+ * channels and vdev ids
+ * @psoc: PSOC object information
+ * @ch_freq_list: Mode specific channel freq list
+ * @vdev_id: Mode specific vdev id (list)
+ *
+ * Get active beaconing entity channels and vdev ids
+ *
+ * Return: number of beaconing entities found
+ */
+uint32_t policy_mgr_get_beaconing_mode_info(struct wlan_objmgr_psoc *psoc,
+					    uint32_t *ch_freq_list,
+					    uint8_t *vdev_id);
+
+/**
+ * policy_mgr_is_freq_on_mac_id() - Check if given freq belongs to given mac id
+ * @freq_range: Frequency range pointer
+ * @freq: Frequency which needs to be checked
+ * @mac_id: MAC id on which this frequency needs to be checked
+ *
+ * Return: True if given frequency belongs to the given MAC id
+ */
+bool policy_mgr_is_freq_on_mac_id(struct policy_mgr_freq_range *freq_range,
+				  qdf_freq_t freq, uint8_t mac_id);
+
+/**
+ * policy_mgr_is_conn_lead_to_dbs_sbs() - New freq leads to DBS/SBS
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id of the caller
+ * @freq: New connection frequency
+ *
+ * This API loops through existing connections from policy_mgr connection table
+ *
+ * Return: True if new frequency causes DBS/SBS with existing connections
+ */
+bool
+policy_mgr_is_conn_lead_to_dbs_sbs(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id, qdf_freq_t freq);
+
+/**
+ * policy_mgr_sap_ch_width_update() - Update SAP ch_width
+ * @psoc: PSOC object information
+ * @next_action: next action to happen in order to update bandwidth
+ * @reason: reason for ch_width update
+ * @conc_vdev_id: Concurrent connection vdev_id that is causing ch_width update
+ * @request_id: request id for connection manager
+ *
+ * Update ch_width as per next_action
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_sap_ch_width_update(struct wlan_objmgr_psoc *psoc,
+			       enum policy_mgr_conc_next_action next_action,
+			       enum policy_mgr_conn_update_reason reason,
+			       uint8_t conc_vdev_id, uint32_t request_id);
+
+/*
+ * policy_mgr_get_vdev_same_freq_new_conn() - Get vdev_id of the first
+ *					      connection that has same
+ *					      channel frequency as new_freq
+ * @psoc: psoc object pointer
+ * @new_freq: channel frequency for the new connection
+ * @vdev_id: Output parameter to return vdev id of the first existing connection
+ *	     that has same channel frequency as @new_freq
+ *
+ * This function is to return the first connection that has same
+ * channel frequency as @new_freq.
+ *
+ * Return: true if connection that has same channel frequency as
+ *	   @new_freq exists. Otherwise false.
+ */
+bool policy_mgr_get_vdev_same_freq_new_conn(struct wlan_objmgr_psoc *psoc,
+					    uint32_t new_freq,
+					    uint8_t *vdev_id);
+
+/*
+ * policy_mgr_get_vdev_diff_freq_new_conn() - Get vdev id of the first
+ *					      connection that has different
+ *					      channel freq from new_freq
+ * @psoc: psoc object pointer
+ * @new_freq: channel frequency for the new connection
+ * @vdev_id: Output parameter to return vdev id of the first existing connection
+ *	     that has different channel frequency from @new_freq
+ *
+ * This function is to return the first connection that has different
+ * channel frequency from @new_freq.
+ *
+ * Return: true if connection that has different channel frequency from
+ *	   @new_freq exists. Otherwise false.
+ */
+bool policy_mgr_get_vdev_diff_freq_new_conn(struct wlan_objmgr_psoc *psoc,
+					    uint32_t new_freq,
+					    uint8_t *vdev_id);
+
+/**
+ * policy_mgr_sap_on_non_psc_channel() - Check if STA operates in PSC or Non-PSC
+ *					 channel to restart SAP on Non-PSC
+ *					 channel
+ * @psoc: PSOC object information
+ * @intf_ch_freq: input/out interference channel frequency to sap
+ * @sap_vdev_id: SAP vdev id
+ *
+ * This function is to check if STA operates in PSC or Non-PSC channel
+ * to restart SAP on Non-PSC channel.
+ *
+ * Return: None
+ */
+void
+policy_mgr_sap_on_non_psc_channel(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t *intf_ch_freq,
+				  uint8_t sap_vdev_id);
+
+#ifdef WLAN_FEATURE_LL_LT_SAP
+/**
+ * policy_mgr_get_pcl_ch_list_for_ll_sap() - Get PCL channel list for LL_LT_SAP
+ * @psoc: psoc object
+ * @pcl: pcl list
+ * @vdev_id: vdev id
+ * @info: pointer to connection_info structure
+ * @connection_count: total number of existing connection present
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_pcl_ch_list_for_ll_sap(
+					struct wlan_objmgr_psoc *psoc,
+					struct policy_mgr_pcl_list *pcl,
+					uint8_t vdev_id,
+					struct connection_info *info,
+					uint8_t *connection_count);
+#endif
+
+/**
+ * policy_mgr_is_given_freq_5g_low() - API to check whether given freq
+ * is 5GHz low or not
+ * @psoc: psoc object
+ * @given_freq: given freq
+ *
+ * Return: True if it 5GHz low otherwise false
+ */
+bool policy_mgr_is_given_freq_5g_low(struct wlan_objmgr_psoc *psoc,
+				     qdf_freq_t given_freq);
+#endif /* __WLAN_POLICY_MGR_API_H */

+ 133 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ll_sap.h

@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains policy manager ll_sap definitions specific to the ll_sap module
+ */
+#ifndef WLAN_POLICY_MGR_LL_SAP_H
+#define WLAN_POLICY_MGR_LL_SAP_H
+
+#include "wlan_objmgr_psoc_obj.h"
+
+#ifdef WLAN_FEATURE_LL_LT_SAP
+/**
+ * policy_mgr_ll_lt_sap_get_valid_freq() - Check and get valid frequency for
+ * the current interface (SAP/P2PGO/LL_LT_SAP)
+ * @psoc: PSOC object
+ * @pdev: PDEV pointer
+ * @vdev_id: Vdev id of the current interface
+ * @sap_ch_freq: Frequency of the current interface
+ * @cc_switch_mode: Channel switch mode
+ * @new_sap_freq: Updated frequency
+ * @is_ll_lt_sap_present: Indicates if ll_lt_sap is present or not
+ *
+ * This API checks if ll_lt_sap is present or not and if ll_lt_sap is present
+ * then if current frequency of the ll_lt_sap or concurrent SAP or concurrent
+ * P2PGO is valid or not according to ll_lt_sap concurrency, if valid, does not
+ * fill anything in the new_sap_freq and if not valid, update the new_sap_freq
+ * with some new valid frequency.
+ *
+ * Return: true/false
+ */
+void policy_mgr_ll_lt_sap_get_valid_freq(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_objmgr_pdev *pdev,
+					 uint8_t vdev_id,
+					 qdf_freq_t sap_ch_freq,
+					 uint8_t cc_switch_mode,
+					 qdf_freq_t *new_sap_freq,
+					 bool *is_ll_lt_sap_present);
+
+/**
+ * wlan_policy_mgr_get_ll_lt_sap_vdev_id() - Get ll_lt_sap vdev id
+ * @psoc: PSOC object
+ *
+ * API to find ll_lt_sap vdev id
+ *
+ * Return: vdev id
+ */
+uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev_id(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * __policy_mgr_is_ll_lt_sap_restart_required() - Check in ll_lt_sap restart is
+ * required
+ * @psoc: PSOC object
+ * @func: Function pointer of the caller function.
+ *
+ * This API checks if ll_lt_sap restart is required or not
+ *
+ * Return: true/false
+ */
+bool __policy_mgr_is_ll_lt_sap_restart_required(struct wlan_objmgr_psoc *psoc,
+						const char *func);
+
+#define policy_mgr_is_ll_lt_sap_restart_required(psoc) \
+	__policy_mgr_is_ll_lt_sap_restart_required(psoc, __func__)
+
+/**
+ * policy_mgr_ll_lt_sap_restart_concurrent_sap() - Check and restart
+ * concurrent SAP or ll_lt_sap
+ * @psoc: PSOC object
+ * @is_ll_lt_sap_enabled: Indicates if ll_lt_sap is getting enabled or
+ * getting disabled
+ *
+ * This API checks and restarts concurrent SAP or ll_lt_sap when ll_lt_sap comes
+ * up or goes down.
+ * Concurrent SAP and ll_lt_sap should always be on different MAC.
+ * restart the concurrent SAP in below scenario:
+ * If ll_lt_sap is coming up and HW is not sbs capable and concurrent SAP is
+ * operating on 5 GHz, then move concurrent SAP to 2.4 Ghz MAC to allow
+ * ll_lt_sap on 5 GHz
+ * If ll_lt_sap is going down and if concurrent SAP is on 2.4 GHz then try to
+ * restart concurrent SAP on its original user configured frequency
+ * If ll_lt_sap interface has come up and in parallel if some other interface
+ * comes up on the ll_lt_sap frequency, then ll_lt_sap needs to be restarted.
+ *
+ * Return: None
+ */
+void policy_mgr_ll_lt_sap_restart_concurrent_sap(struct wlan_objmgr_psoc *psoc,
+						 bool is_ll_lt_sap_enabled);
+#else
+
+static inline bool
+policy_mgr_is_ll_lt_sap_restart_required(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline
+void policy_mgr_ll_lt_sap_get_valid_freq(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_objmgr_pdev *pdev,
+					 uint8_t vdev_id,
+					 qdf_freq_t sap_ch_freq,
+					 uint8_t cc_switch_mode,
+					 qdf_freq_t *new_sap_freq,
+					 bool *is_ll_lt_sap_present)
+{
+}
+
+static inline
+uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev_id(struct wlan_objmgr_psoc *psoc)
+{
+	return WLAN_INVALID_VDEV_ID;
+}
+
+static inline void
+policy_mgr_ll_lt_sap_restart_concurrent_sap(struct wlan_objmgr_psoc *psoc,
+					    bool is_ll_lt_sap_enabled)
+{
+}
+#endif
+#endif /* WLAN_POLICY_MGR_LL_SAP_H */

+ 1911 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h

@@ -0,0 +1,1911 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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>
+
+/*
+ *  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
+
+#ifdef FEATURE_FOURTH_CONNECTION
+#define MAX_NUMBER_OF_CONC_CONNECTIONS 4
+#else
+#define MAX_NUMBER_OF_CONC_CONNECTIONS 3
+#endif
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/* Max MLO VDEVS for disabled link table */
+#define MAX_NUMBER_OF_DISABLE_LINK WLAN_UMAC_MLO_MAX_VDEVS
+#endif
+
+/* BIT 0 for low latency and BIT 1 for HIGH TPUT */
+#define PM_VDEV_TRAFFIC_LOW_LATENCY 0x1
+#define PM_VDEV_TRAFFIC_HIGH_TPUT 0x2
+
+/* Policy manager default request id */
+#define POLICY_MGR_DEF_REQ_ID 0
+
+typedef int (*send_mode_change_event_cb)(void);
+
+/**
+ * enum sap_csa_reason_code - SAP channel switch reason code
+ * @CSA_REASON_UNKNOWN: Unknown reason
+ * @CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS: STA connection from DFS to NON DFS.
+ * @CSA_REASON_USER_INITIATED: User initiated form north bound.
+ * @CSA_REASON_PEER_ACTION_FRAME: Action frame received on sta iface.
+ * @CSA_REASON_PRE_CAC_SUCCESS: Pre CAC success.
+ * @CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL: concurrent sta changed channel.
+ * @CSA_REASON_UNSAFE_CHANNEL: Unsafe channel.
+ * @CSA_REASON_LTE_COEX: LTE coex.
+ * @CSA_REASON_CONCURRENT_NAN_EVENT: NAN concurrency.
+ * @CSA_REASON_BAND_RESTRICTED: band disabled or re-enabled
+ * @CSA_REASON_DCS: DCS
+ * @CSA_REASON_CHAN_DISABLED: channel is disabled
+ * @CSA_REASON_CHAN_PASSIVE: channel is passive
+ * @CSA_REASON_GO_BSS_STARTED: P2P go started
+ * @CSA_REASON_SAP_ACS: 2.4 GHz preferred SAP ACS starting
+ * @CSA_REASON_SAP_FIX_CH_CONC_WITH_GO: SAP fix channel start
+ * @CSA_REASON_CONCURRENT_LL_LT_SAP_EVENT: LL_LT_SAP concurrency
+ *  and move GO to other band
+ */
+enum sap_csa_reason_code {
+	CSA_REASON_UNKNOWN,
+	CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS,
+	CSA_REASON_USER_INITIATED,
+	CSA_REASON_PEER_ACTION_FRAME,
+	CSA_REASON_PRE_CAC_SUCCESS,
+	CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL,
+	CSA_REASON_UNSAFE_CHANNEL,
+	CSA_REASON_LTE_COEX,
+	CSA_REASON_CONCURRENT_NAN_EVENT,
+	CSA_REASON_BAND_RESTRICTED,
+	CSA_REASON_DCS,
+	CSA_REASON_CHAN_DISABLED,
+	CSA_REASON_CHAN_PASSIVE,
+	CSA_REASON_GO_BSS_STARTED,
+	CSA_REASON_SAP_ACS,
+	CSA_REASON_SAP_FIX_CH_CONC_WITH_GO,
+	CSA_REASON_CONCURRENT_LL_LT_SAP_EVENT
+};
+
+/*
+ * enum link_control_flags: This enum is used for setting
+ * mlo_control_flags by api policy_mgr_mlo_sta_set_nlink.
+ * @link_ctrl_f_overwrite_active_bitmap: indicate overwrite all earlier
+ * force_active bitmaps. Used with MLO_LINK_FORCE_MODE_ACTIVE or
+ * MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE
+ * @link_ctrl_f_overwrite_inactive_bitmap: indicate overwrite all earlier
+ * force_inactive bitmaps. Used with MLO_LINK_FORCE_MODE_INACTIVE or
+ * MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE.
+ * @link_ctrl_f_dynamic_force_link_num: indicate fw to use force link number
+ * instead of force link bitmaps. Used with MLO_LINK_FORCE_MODE_ACTIVE_NUM.
+ * MLO_LINK_FORCE_MODE_INACTIVE_NUM, MLO_LINK_FORCE_MODE_NO_FORCE.
+ * @link_ctrl_f_post_re_evaluate: run link state check again after command
+ * response handled.
+ */
+enum link_control_flags {
+	link_ctrl_f_overwrite_active_bitmap =   1 << 0,
+	link_ctrl_f_overwrite_inactive_bitmap = 1 << 1,
+	link_ctrl_f_dynamic_force_link_num =    1 << 2,
+	link_ctrl_f_post_re_evaluate =          1 << 3,
+};
+
+/**
+ * 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_emlsr_capab - EMLSR HW mode capability
+ * @HW_MODE_EMLSR_NONE: Non EMLSR capable
+ * @HW_MODE_EMLSR: EMLSR capable
+ */
+enum hw_mode_emlsr_capab {
+	HW_MODE_EMLSR_NONE,
+	HW_MODE_EMLSR,
+};
+
+/**
+ * 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 force_1x1_type - enum to specify the type of forced 1x1 ini provided.
+ * @FORCE_1X1_DISABLED: even if the AP is present in OUI, 1x1 will not be forced
+ * @FORCE_1X1_ENABLED_FOR_AS: If antenna sharing supported, then only do 1x1.
+ * @FORCE_1X1_ENABLED_FORCED: If AP present in OUI, force 1x1 connection.
+ */
+enum force_1x1_type {
+	FORCE_1X1_DISABLED,
+	FORCE_1X1_ENABLED_FOR_AS,
+	FORCE_1X1_ENABLED_FORCED,
+};
+
+/**
+ * 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,
+};
+
+/**
+ * enum 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
+ * @POLICY_MGR_PCL_ORDER_2G: 2G channels
+ * @POLICY_MGR_PCL_ORDER_5G: 5G channels
+ * @POLICY_MGR_PCL_ORDER_SCC_5G_LOW_5G_LOW: 5G Low SCC frequency followed by
+ * 5G low band i.e 5G freq < sbs cutoff freq
+ * @POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH: 5G High SCC frequency followed by
+ * 5G High band i.e 5G freq > sbs cutoff freq
+ * @POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH_SCC_5G_LOW: 5 GHz High SCC
+ * frequency followed by 5G High band i.e 5G freq > sbs cutoff freq, add 5 GHz
+ * Low SCC frequency
+ * @POLICY_MGR_PCL_ORDER_SCC_5G_LOW: SCC channel on 5G low
+ * @POLICY_MGR_PCL_ORDER_SCC_5G_HIGH: SCC channel on 5G high
+ * @POLICY_MGR_PCL_ORDER_SCC_5G_LOW_MCC_5G_HIGH: SCC channels on 5G low
+ * followed by MCC channels on 5G high
+ * @POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_MCC_5G_LOW: SCC channels on 5G high
+ * followed by MCC channels on 5G low
+ *
+ * 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,
+	POLICY_MGR_PCL_ORDER_2G,
+	POLICY_MGR_PCL_ORDER_5G,
+	POLICY_MGR_PCL_ORDER_SCC_5G_LOW_5G_LOW,
+	POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH,
+	POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH_SCC_5G_LOW,
+	POLICY_MGR_PCL_ORDER_SCC_5G_LOW,
+	POLICY_MGR_PCL_ORDER_SCC_5G_HIGH,
+	POLICY_MGR_PCL_ORDER_SCC_5G_LOW_MCC_5G_HIGH,
+	POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_MCC_5G_LOW,
+};
+
+/**
+ * enum policy_mgr_pcl_band_priority - Band priority between 5G and 6G channel
+ * @POLICY_MGR_PCL_BAND_5G_THEN_6G: 5 Ghz channel followed by 6 Ghz channel
+ * @POLICY_MGR_PCL_BAND_6G_THEN_5G: 6 Ghz channel followed by 5 Ghz channel
+ *
+ *  Band priority between 5G and 6G
+ */
+enum policy_mgr_pcl_band_priority {
+	POLICY_MGR_PCL_BAND_5G_THEN_6G = 0,
+	POLICY_MGR_PCL_BAND_6G_THEN_5G,
+};
+
+/**
+ * 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
+ * @POLICY_MGR_RX_NSS_MAX: maximum enumeration
+ *
+ * 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_NDI_MODE: NDI mode
+ * @PM_NAN_DISC_MODE: NAN Discovery mode
+ * @PM_LL_LT_SAP_MODE: Low latency low throughput SAP
+ * @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_NDI_MODE,
+	PM_NAN_DISC_MODE,
+	PM_LL_LT_SAP_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_CH_5G: 5 Ghz SCC channel & 5 Ghz channels
+ * @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_5_5G_24G: SCC channel on 5 Ghz, 5 Ghz channels & 2.4 Ghz channels
+ * @PM_SCC_ON_5_5G_SCC_ON_24G: SCC channel on 5 Ghz, 5 Ghz channels &
+ *	SCC channel on 2.4 Ghz
+ * @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_24_CH_24G: SCC channel on 2.4 GHz & 2.4 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_SBS_CH_24G_SCC_CH:
+ * @PM_SBS_CH_SCC_CH_24G:
+ * @PM_SCC_CH_SBS_CH_24G:
+ * @PM_SBS_CH_SCC_CH_5G_24G:
+ * @PM_SCC_CH_MCC_CH_SBS_CH_24G:
+ * @PM_SBS_CH_2G: SBS channels & 2.4 Ghz channels
+ * @PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G: 5 GHz low SCC channel followed by
+ * 5 GHz low frequencies, add 2.4 GHz if its shared with 5 GHz low
+ * @PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G: 5GHZ high SCC channel followed by
+ * 5 GHz high frequencies, add 2.4 GHZ if its shared with 5GHz high
+ * @PM_SCC_ON_5G_HIGH_5G_HIGH_SCC_ON_5G_LOW_PLUS_SHARED_2G: 5GHZ high SCC
+ * channel followed by 5 GHz high frequencies and 5 GHz low SCC channel,
+ * add 2.4 GHZ if its shared with 5GHz high
+ * @PM_SBS_CH_MCC_CH: SBS channels followed by MCC channels
+ * @PM_SBS_5G_MCC_24G: SBS channels, 5G MCC channels and 2.4GHz channels
+ * @PM_SCC_ON_24G: SCC channels on 2.4 Ghz
+ * @PM_SCC_ON_5G_LOW: SCC channels on 5G low frequencies
+ * @PM_SCC_ON_5G_HIGH: SCC channels on 5G high frequencies
+ * @PM_SBS_CH_MCC_CH_SCC_ON_24_24G: SBS channels followed by MCC channels
+ * followed by SCC channels on 2.4 GHz followed by 2.4 GHz channels
+ * @PM_5G_24G: 5 GHz channels, followed by 2.4 GHz channels
+ * @PM_MCC_CH_SCC_ON_24G: MCC chanenls followed by SCC channels on 2.4 Ghz
+ * @PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH: SCC channels on 5G low frequencies
+ * followed by MCC channels on 5G high frequencies
+ * @PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW: SCC channels on 5G high frequencies
+ * followed by MCC channels on 5G low frequencies
+ *
+ * @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_CH_5G,
+	PM_SCC_ON_5_SCC_ON_24_24G,
+	PM_SCC_ON_5_SCC_ON_24_5G,
+	PM_SCC_ON_5_5G_24G,
+	PM_SCC_ON_5_5G_SCC_ON_24G,
+	PM_SCC_ON_24_SCC_ON_5_24G,
+	PM_SCC_ON_24_SCC_ON_5_5G,
+	PM_SCC_ON_24_CH_24G,
+	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,
+	/* New PCL type for DBS-SBS HW */
+	PM_SBS_CH_24G_SCC_CH,
+	PM_SBS_CH_SCC_CH_24G,
+	PM_SCC_CH_SBS_CH_24G,
+	PM_SBS_CH_SCC_CH_5G_24G,
+	PM_SCC_CH_MCC_CH_SBS_CH_24G,
+	PM_SBS_CH_2G,
+	PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G,
+	PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G,
+	PM_SCC_ON_5G_HIGH_5G_HIGH_SCC_ON_5G_LOW_PLUS_SHARED_2G,
+
+	PM_SBS_CH_MCC_CH,
+	PM_SBS_5G_MCC_24G,
+	PM_SCC_ON_24G,
+	PM_SCC_ON_5G_LOW,
+	PM_SCC_ON_5G_HIGH,
+	PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+	PM_5G_24G,
+	PM_MCC_CH_SCC_ON_24G,
+	PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH,
+	PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW,
+
+	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_2x2: SAP connection using 2x2@5 Ghz
+ * @PM_NAN_DISC_24_1x1:  NAN Discovery using [email protected] Ghz
+ * @PM_NAN_DISC_24_2x2:  NAN Discovery using [email protected] Ghz
+ * @PM_NDI_24_1x1:  NAN Datapath using [email protected] Ghz
+ * @PM_NDI_24_2x2:  NAN Datapath using [email protected] Ghz
+ * @PM_NDI_5_1x1:  NAN Datapath using 1x1@5 Ghz
+ * @PM_NDI_5_2x2:  NAN Datapath using 2x2@5 Ghz
+ * @PM_LL_LT_SAP_5_1x1: Low latency low throughput SAP using 1x1@5 Ghz
+ * @PM_LL_LT_SAP_5_2x2: Low latency low throughput SAP 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_NAN_DISC_24_1x1,
+	PM_NAN_DISC_24_2x2,
+	PM_NDI_24_1x1,
+	PM_NDI_24_2x2,
+	PM_NDI_5_1x1,
+	PM_NDI_5_2x2,
+	PM_LL_LT_SAP_5_1x1,
+	PM_LL_LT_SAP_5_2x2 = PM_LL_LT_SAP_5_1x1,
+
+	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_MCC_24_5_1x1:
+ * @PM_STA_SAP_MCC_24_5_2x2:
+ * @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_SAP_SBS_5_2x2: STA & SAP connection on 5G SBS using 2x2
+ * @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_MCC_24_5_1x1:
+ * @PM_STA_P2P_GO_MCC_24_5_2x2:
+ * @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_GO_SBS_5_2x2: STA & P2P GO connection on 5G SBS
+ *			using 2x2
+ * @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_MCC_24_5_1x1:
+ * @PM_STA_P2P_CLI_MCC_24_5_2x2:
+ * @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_STA_P2P_CLI_SBS_5_2x2: STA & P2P CLI connection on 5G
+ *			SBS using 2x2
+ * @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_MCC_24_5_1x1:
+ * @PM_P2P_GO_P2P_CLI_MCC_24_5_2x2:
+ * @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_P2P_CLI_SBS_5_2x2: P2P GO & P2P CLI connection
+ *			on 5G SBS using 2x2
+ * @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_MCC_24_5_1x1:
+ * @PM_P2P_GO_SAP_MCC_24_5_2x2:
+ * @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_GO_SAP_SBS_5_2x2: P2P GO & SAP connection on 5G SBS
+ *			using 2x2
+ * @PM_P2P_GO_P2P_GO_SCC_24_1x1: P2P GO & P2P GO SCC on 2.4G using 1x1
+ * @PM_P2P_GO_P2P_GO_SCC_24_2x2: P2P GO & P2P GO SCC on 2.4G using 2x2
+ * @PM_P2P_GO_P2P_GO_MCC_24_1x1: P2P GO & P2P GO MCC on 2.4G using 1x1
+ * @PM_P2P_GO_P2P_GO_MCC_24_2x2: P2P GO & P2P GO MCC on 2.4G using 2x2
+ * @PM_P2P_GO_P2P_GO_SCC_5_1x1: P2P GO & P2P GO SCC on 5G using 1x1
+ * @PM_P2P_GO_P2P_GO_SCC_5_2x2: P2P GO & P2P GO SCC on 5G using 2x2
+ * @PM_P2P_GO_P2P_GO_MCC_5_1x1: P2P GO & P2P GO MCC on 5G using 1x1
+ * @PM_P2P_GO_P2P_GO_MCC_5_2x2: P2P GO & P2P GO MCC on 5G using 2x2
+ * @PM_P2P_GO_P2P_GO_MCC_24_5_1x1: P2P GO 2.4G & P2P GO 5G dual band MCC
+ *                                 using 1x1
+ * @PM_P2P_GO_P2P_GO_MCC_24_5_2x2: P2P GO 2.4G & P2P GO 5G dual band MCC
+ *                                 using 2x2
+ * @PM_P2P_GO_P2P_GO_DBS_1x1: P2P GO & P2P GO on DBS using 1x1
+ * @PM_P2P_GO_P2P_GO_DBS_2x2: P2P GO & P2P GO on DBS using 2x2
+ * @PM_P2P_GO_P2P_GO_SBS_5_1x1: P2P GO & P2P GO on SBS using 1x1
+ * @PM_P2P_GO_P2P_GO_SBS_5_2x2: P2P GO & P2P GO on SBS using 2x2
+ * @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
+ * @PM_P2P_CLI_SAP_MCC_24_5_1x1: CLI and SAP connecting on MCC
+ *			in 2.4 and 5GHz 1x1
+ * @PM_P2P_CLI_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_P2P_CLI_SAP_SBS_5_2x2: P2P CLI & SAP connection on 5G SBS
+ *			using 2x2
+ * @PM_P2P_CLI_P2P_CLI_SCC_24_1x1: P2P CLI & P2P CLI SCC on 2.4G using 1x1
+ * @PM_P2P_CLI_P2P_CLI_SCC_24_2x2: P2P CLI & P2P CLI SCC on 2.4G using 2x2
+ * @PM_P2P_CLI_P2P_CLI_MCC_24_1x1: P2P CLI & P2P CLI MCC on 2.4G using 1x1
+ * @PM_P2P_CLI_P2P_CLI_MCC_24_2x2: P2P CLI & P2P CLI MCC on 2.4G using 2x2
+ * @PM_P2P_CLI_P2P_CLI_SCC_5_1x1: P2P CLI & P2P CLI SCC on 5G using 1x1
+ * @PM_P2P_CLI_P2P_CLI_SCC_5_2x2: P2P CLI & P2P CLI SCC on 5G using 2x2
+ * @PM_P2P_CLI_P2P_CLI_MCC_5_1x1: P2P CLI & P2P CLI MCC on 5G using 1x1
+ * @PM_P2P_CLI_P2P_CLI_MCC_5_2x2: P2P CLI & P2P CLI MCC on 5G using 2x2
+ * @PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1: P2P CLI 2.4G & P2P CLI 5G dual band MCC
+ *                                 using 1x1
+ * @PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2: P2P CLI 2.4G & P2P CLI 5G dual band MCC
+ *                                 using 2x2
+ * @PM_P2P_CLI_P2P_CLI_DBS_1x1: P2P CLI & P2P CLI on DBS using 1x1
+ * @PM_P2P_CLI_P2P_CLI_DBS_2x2: P2P CLI & P2P CLI on DBS using 2x2
+ * @PM_P2P_CLI_P2P_CLI_SBS_5_1x1: P2P CLI & P2P CLI on SBS using 1x1
+ * @PM_P2P_CLI_P2P_CLI_SBS_5_2x2: P2P CLI & P2P CLI on SBS using 2x2
+ * @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_SAP_SAP_SBS_5_2x2: SAP & SAP connection on 5G SBS using 2x2
+ * @PM_SAP_NAN_DISC_SCC_24_1x1: SAP & NAN connection on
+ *			SCC using [email protected] Ghz
+ * @PM_SAP_NAN_DISC_SCC_24_2x2: SAP & NAN connection on
+ *			SCC using [email protected] Ghz
+ * @PM_SAP_NAN_DISC_MCC_24_1x1: SAP & NAN connection on
+ *			MCC using [email protected] Ghz
+ * @PM_SAP_NAN_DISC_MCC_24_2x2: SAP & NAN connection on
+ *			SCC using [email protected] Ghz
+ * @PM_SAP_NAN_DISC_DBS_1x1: SAP & NAN connection on DBS using 1x1
+ * @PM_SAP_NAN_DISC_DBS_2x2: SAP & NAN connection on DBS using 2x2
+ * @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
+ * @PM_STA_STA_SBS_5_2x2: STA & STA connection on 5G SBS using 2x2
+ * @PM_STA_NAN_DISC_SCC_24_1x1: NAN & STA connection on SCC using 1x1 on 2.4 GHz
+ * @PM_STA_NAN_DISC_SCC_24_2x2: NAN & STA connection on SCC using 2x2 on 2.4 GHz
+ * @PM_STA_NAN_DISC_MCC_24_1x1: NAN & STA connection on MCC using 1x1 on 2.4 GHz
+ * @PM_STA_NAN_DISC_MCC_24_2x2: NAN & STA connection on MCC using 2x2 on 2.4 GHz
+ * @PM_STA_NAN_DISC_DBS_1x1: NAN & STA connection on DBS using 1x1
+ * @PM_STA_NAN_DISC_DBS_2x2: NAN & STA connection on DBS using 2x2
+ * @PM_NAN_DISC_NDI_SCC_24_1x1: NAN & NDI connection on SCC using 1x1 on 2.4 GHz
+ * @PM_NAN_DISC_NDI_SCC_24_2x2: NAN & NDI connection on SCC using 2x2 on 2.4 GHz
+ * @PM_NAN_DISC_NDI_MCC_24_1x1: NAN & NDI connection on MCC using 1x1 on 2.4 GHz
+ * @PM_NAN_DISC_NDI_MCC_24_2x2: NAN & NDI connection on MCC using 2x2 on 2.4 GHz
+ * @PM_NAN_DISC_NDI_DBS_1x1: NAN & NDI connection on DBS using 1x1
+ * @PM_NAN_DISC_NDI_DBS_2x2: NAN & NDI connection on DBS using 2x2
+ * @PM_STA_24_LL_LT_SAP_DBS_1x1: STA & LL_LT_SAP connection in DBS using 1x1
+ * @PM_STA_24_LL_LT_SAP_DBS_2x2: STA & LL_LT_SAP connection in DBS using 2x2
+ * @PM_STA_5_LL_LT_SAP_MCC_1x1: STA & LL_LT_SAP connection in MCC on 5 GHz
+ * using 1x1
+ * @PM_STA_5_LL_LT_SAP_MCC_2x2: STA & LL_LT_SAP connection in MCC on 5 GHz
+ * using 2x2
+ * @PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1: STA on 5G low & LL_LT_SAP on 5G high
+ * connection in SBS using 1x1
+ * @PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2: STA on 5G low & LL_LT_SAP on 5G high
+ * connection in SBS using 2x2
+ * @PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1: STA on 5G high & LL_LT_SAP on 5G low
+ * connection in SBS using 1x1
+ * @PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2: STA on 5G high & LL_LT_SAP on 5G low
+ * connection in SBS using 1x1
+ * @PM_SAP_24_LL_LT_SAP_DBS_1x1: SAP & LL_LT_SAP connection in DBS using 1x1
+ * @PM_SAP_24_LL_LT_SAP_DBS_2x2: SAP & LL_LT_SAP connection in DBS using 2x2
+ * @PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1: SAP on 5G low & LL_LT_SAP on 5G high
+ * connection in SBS using 1x1
+ * @PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2: SAP on 5G low & LL_LT_SAP on 5G high
+ * connection in SBS using 2x2
+ * @PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1: SAP on 5G high & LL_LT_SAP on 5G low
+ * connection in SBS using 1x1
+ * @PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2: SAP on 5G high & LL_LT_SAP on 5G low
+ * connection in SBS using 1x1
+ * @PM_P2P_GO_24_LL_LT_SAP_DBS_1x1: P2P GO & LL_LT_SAP connection in DBS
+ * using 1x1
+ * @PM_P2P_GO_24_LL_LT_SAP_DBS_2x2: P2P GO & LL_LT_SAP connection in DBS
+ * using 2x2
+ * @PM_P2P_GO_5_LL_LT_SAP_MCC_1x1: GO & LL_LT_SAP connection in MCC using 1x1
+ * @PM_P2P_GO_5_LL_LT_SAP_MCC_2x2: GO & LL_LT_SAP connection in MCC using 2x2
+ * @PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1: GO on 5G low & LL_LT_SAP on 5G
+ * high connection in SBS using 1x1
+ * @PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2: GO on 5G low & LL_LT_SAP on 5G
+ * high connection in SBS using 2x2
+ * @PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1: GO on 5G high & LL_LT_SAP on 5G
+ * low connection in SBS using 1x1
+ * @PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2: GO on 5G high & LL_LT_SAP on 5G
+ * low connection in SBS using 2x2
+ * @PM_P2P_CLI_24_LL_LT_SAP_DBS_1x1: CLI & LL_LT_SAP connection in DBS using 1x1
+ * @PM_P2P_CLI_24_LL_LT_SAP_DBS_2x2: CLI & LL_LT_SAP connection in DBS using 2x2
+ * @PM_P2P_CLI_5_LL_LT_SAP_MCC_1x1: CLI & LL_LT_SAP connection in MCC on 5 GHz
+ * using 1x1
+ * @PM_P2P_CLI_5_LL_LT_SAP_MCC_2x2: CLI & LL_LT_SAP connection in MCC on 5 GHz
+ * using 2x2
+ * @PM_P2P_CLI_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1: CLI on 5G low & LL_LT_SAP on 5G
+ * high connection in SBS using 1x1
+ * @PM_P2P_CLI_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2: CLI on 5G low & LL_LT_SAP on 5G
+ * high connection in SBS using 2x2
+ * @PM_P2P_CLI_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1: CLI on 5G high & LL_LT_SAP on 5G
+ * low connection in SBS using 1x1
+ * @PM_P2P_CLI_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2: CLI on 5G high & LL_LT_SAP on 5G
+ * low connection in SBS using 2x2
+ * @PM_MAX_TWO_CONNECTION_MODE: Max enumeration
+ *
+ * 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_SAP_SBS_5_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_GO_SBS_5_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_STA_P2P_CLI_SBS_5_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_P2P_CLI_SBS_5_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_GO_SAP_SBS_5_2x2 = PM_P2P_GO_SAP_SBS_5_1x1,
+	PM_P2P_GO_P2P_GO_SCC_24_1x1,
+	PM_P2P_GO_P2P_GO_SCC_24_2x2,
+	PM_P2P_GO_P2P_GO_MCC_24_1x1,
+	PM_P2P_GO_P2P_GO_MCC_24_2x2,
+	PM_P2P_GO_P2P_GO_SCC_5_1x1,
+	PM_P2P_GO_P2P_GO_SCC_5_2x2,
+	PM_P2P_GO_P2P_GO_MCC_5_1x1,
+	PM_P2P_GO_P2P_GO_MCC_5_2x2,
+	PM_P2P_GO_P2P_GO_MCC_24_5_1x1,
+	PM_P2P_GO_P2P_GO_MCC_24_5_2x2,
+	PM_P2P_GO_P2P_GO_DBS_1x1,
+	PM_P2P_GO_P2P_GO_DBS_2x2,
+	PM_P2P_GO_P2P_GO_SBS_5_1x1,
+	PM_P2P_GO_P2P_GO_SBS_5_2x2 = PM_P2P_GO_P2P_GO_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_P2P_CLI_SAP_SBS_5_2x2 = PM_P2P_CLI_SAP_SBS_5_1x1,
+	PM_P2P_CLI_P2P_CLI_SCC_24_1x1,
+	PM_P2P_CLI_P2P_CLI_SCC_24_2x2,
+	PM_P2P_CLI_P2P_CLI_MCC_24_1x1,
+	PM_P2P_CLI_P2P_CLI_MCC_24_2x2,
+	PM_P2P_CLI_P2P_CLI_SCC_5_1x1,
+	PM_P2P_CLI_P2P_CLI_SCC_5_2x2,
+	PM_P2P_CLI_P2P_CLI_MCC_5_1x1,
+	PM_P2P_CLI_P2P_CLI_MCC_5_2x2,
+	PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1,
+	PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2,
+	PM_P2P_CLI_P2P_CLI_DBS_1x1,
+	PM_P2P_CLI_P2P_CLI_DBS_2x2,
+	PM_P2P_CLI_P2P_CLI_SBS_5_1x1,
+	PM_P2P_CLI_P2P_CLI_SBS_5_2x2 = PM_P2P_CLI_P2P_CLI_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_SAP_SAP_SBS_5_2x2 = PM_SAP_SAP_SBS_5_1x1,
+	PM_SAP_NAN_DISC_SCC_24_1x1,
+	PM_SAP_NAN_DISC_SCC_24_2x2,
+	PM_SAP_NAN_DISC_MCC_24_1x1,
+	PM_SAP_NAN_DISC_MCC_24_2x2,
+	PM_SAP_NAN_DISC_DBS_1x1,
+	PM_SAP_NAN_DISC_DBS_2x2,
+	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_STA_STA_SBS_5_2x2 = PM_STA_STA_SBS_5_1x1,
+	PM_STA_NAN_DISC_SCC_24_1x1,
+	PM_STA_NAN_DISC_SCC_24_2x2,
+	PM_STA_NAN_DISC_MCC_24_1x1,
+	PM_STA_NAN_DISC_MCC_24_2x2,
+	PM_STA_NAN_DISC_DBS_1x1,
+	PM_STA_NAN_DISC_DBS_2x2,
+	PM_NAN_DISC_NDI_SCC_24_1x1,
+	PM_NAN_DISC_NDI_SCC_24_2x2,
+	PM_NAN_DISC_NDI_MCC_24_1x1,
+	PM_NAN_DISC_NDI_MCC_24_2x2,
+	PM_NAN_DISC_NDI_DBS_1x1,
+	PM_NAN_DISC_NDI_DBS_2x2,
+	PM_STA_24_LL_LT_SAP_DBS_1x1,
+	PM_STA_24_LL_LT_SAP_DBS_2x2 = PM_STA_24_LL_LT_SAP_DBS_1x1,
+	PM_STA_5_LL_LT_SAP_MCC_1x1,
+	PM_STA_5_LL_LT_SAP_MCC_2x2 = PM_STA_5_LL_LT_SAP_MCC_1x1,
+	PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1,
+	PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2 =
+					PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1,
+	PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1,
+	PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2 =
+					PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1,
+	PM_SAP_24_LL_LT_SAP_DBS_1x1,
+	PM_SAP_24_LL_LT_SAP_DBS_2x2 = PM_SAP_24_LL_LT_SAP_DBS_1x1,
+	PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1,
+	PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2 =
+					PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1,
+	PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1,
+	PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2 =
+					PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1,
+	PM_P2P_GO_24_LL_LT_SAP_DBS_1x1,
+	PM_P2P_GO_24_LL_LT_SAP_DBS_2x2 = PM_P2P_GO_24_LL_LT_SAP_DBS_1x1,
+	PM_P2P_GO_5_LL_LT_SAP_MCC_1x1,
+	PM_P2P_GO_5_LL_LT_SAP_MCC_2x2 = PM_P2P_GO_5_LL_LT_SAP_MCC_1x1,
+	PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1,
+	PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2 =
+				PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1,
+	PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1,
+	PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2 =
+				PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1,
+	PM_P2P_CLI_24_LL_LT_SAP_DBS_1x1,
+	PM_P2P_CLI_24_LL_LT_SAP_DBS_2x2 = PM_P2P_CLI_24_LL_LT_SAP_DBS_1x1,
+	PM_P2P_CLI_5_LL_LT_SAP_MCC_1x1,
+	PM_P2P_CLI_5_LL_LT_SAP_MCC_2x2 = PM_P2P_CLI_5_LL_LT_SAP_MCC_1x1,
+	PM_P2P_CLI_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1,
+	PM_P2P_CLI_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2 =
+				PM_P2P_CLI_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1,
+	PM_P2P_CLI_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1,
+	PM_P2P_CLI_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2 =
+				PM_P2P_CLI_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1,
+
+	PM_MAX_TWO_CONNECTION_MODE
+};
+
+#ifdef FEATURE_FOURTH_CONNECTION
+/**
+ * enum policy_mgr_three_connection_mode - Combination of first three
+ * connections type, concurrency state, band used.
+ *
+ * @PM_STA_SAP_SCC_24_SAP_5_DBS: STA & SAP connection on 2.4 GHZ, another
+ * SAP on 5 GHZ
+ * @PM_STA_SAP_SCC_5_SAP_24_DBS: STA & SAP connection on 5 GHZ,
+ * another SAP on 2.4 GHZ
+ * @PM_24_SCC_MCC_PLUS_5_DBS: ANY 2 link on 2.4 GHZ SCC/MCC mac and one link on
+ * 5 GHZ doing DBS
+ * @PM_STA_SAP_24_STA_5_DBS: STA & SAP connection on 2.4 GHZ SCC/MCC,
+ * another STA on 5 GHZ
+ * @PM_5_SCC_MCC_PLUS_24_DBS: ANY 2 link on 5 GHZ SCC/MCC mac and one link on
+ * 2.4 GHZ doing DBS
+ * @PM_STA_SAP_5_STA_24_DBS: STA & SAP connection on 5 GHZ SCC/MCC,
+ * STA on 2.4 GHZ
+ * @PM_STA_STA_5_SAP_24_DBS: STA & STA connection on 5 GHZ SCC/MCC,
+ * SAP on 2.4 GHZ
+ * @PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS: NAN_DISC & SAP connection on 2.4 Ghz SCC,
+ * NDI/NDP on 5 G
+ * @PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS: NAN_DISC & NDI/NDP connection on 2.4 Ghz
+ * SCC, SAP on 5 G
+ * @PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS: SAP & NDI/NDP connection on 5 Ghz,
+ * NAN_DISC on 24 Ghz
+ * @PM_NAN_DISC_STA_24_NDI_5_DBS: STA and NAN Disc on 2.4Ghz and NDI on 5ghz DBS
+ * @PM_NAN_DISC_NDI_24_STA_5_DBS: NDI and NAN Disc on 2.4Ghz and STA on 5ghz DBS
+ * @PM_STA_NDI_5_NAN_DISC_24_DBS: STA, NDI on 5ghz and NAN Disc on 2.4Ghz DBS
+ * @PM_STA_NDI_NAN_DISC_24_SMM: STA, NDI, NAN Disc all on 2.4ghz SMM
+ * @PM_NAN_DISC_NDI_24_NDI_5_DBS: NDI and NAN Disc on 2.4Ghz and second NDI in
+ * 5ghz DBS
+ * @PM_NDI_NDI_5_NAN_DISC_24_DBS: Both NDI on 5ghz and NAN Disc on 2.4Ghz DBS
+ * @PM_NDI_NDI_NAN_DISC_24_SMM: Both NDI, NAN Disc on 2.4ghz SMM
+ * @PM_SAP_SAP_SCC_24_SAP_5_DBS: Both SAP on 2.4Ghz and another SAP on 5Ghz DBS
+ * @PM_SAP_SAP_SCC_5_SAP_24_DBS: Both SAP on 5Ghz and another SAP on 2.4Ghz DBS
+ * @PM_STA_STA_5_NAN_DISC_24_DBS: Both STA on 5Ghz and NAN Disc on 2.4Ghz DBS
+ * @PM_NAN_DISC_24_STA_STA_5_DBS: NAN Disc on 2.4Ghz and both STA on 5Ghz DBS
+ * @PM_STA_STA_24_NAN_DISC_24_SMM: Both STA on 2.4Ghz and NAN Disc on 2.4Ghz SMM
+ * @PM_NAN_DISC_24_STA_STA_24_SMM: NAN Disc on 2.4Ghz and both STA on 2.4Ghz SMM
+ * @PM_STA_24_STA_5_NAN_DISC_24_SMM: First STA on 2.4Ghz and second STA on 5Ghz
+ * and NAN Disc on 2.4Ghz SMM
+ * @PM_STA_24_STA_5_NAN_DISC_24_DBS: First STA on 2.4Ghz and second STA on 5Ghz
+ * and NAN Disc on 2.4Ghz DBS
+ * @PM_STA_5_STA_24_NAN_DISC_24_SMM: First STA on 5Ghz and second STA on 2.4Ghz
+ * and NAN Disc on 2.4Ghz SMM
+ * @PM_STA_5_STA_24_NAN_DISC_24_DBS: First STA on 5Ghz and second STA on 2.4Ghz
+ * and NAN Disc on 2.4Ghz DBS
+ * @PM_NAN_DISC_24_STA_5_STA_24_SMM: NAN Disc on 2.4Ghz and first STA on 5Ghz
+ * and second STA on 2.4Ghz SMM
+ * @PM_NAN_DISC_24_STA_5_STA_24_DBS: NAN Disc on 2.4Ghz and first STA on 5Ghz
+ * and second STA on 2.4Ghz DBS
+ * @PM_NAN_DISC_24_STA_24_STA_5_SMM: NAN Disc on 2.4Ghz and first STA on 2.4Ghz
+ * and second STA on 5Ghz SMM
+ * @PM_NAN_DISC_24_STA_24_STA_5_DBS: NAN Disc on 2.4Ghz and first STA on 2.4Ghz
+ * and second STA on 5Ghz DBS
+ * @PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS: ANY 2 link on 5 GHZ high mac
+ * and one link on 5 GHZ low doing SBS
+ * @PM_STA_24_SAP_5_HIGH_MCC_STA_5_LOW_SBS : First STA on 2.4 GHZ & SAP on high
+ * 5 GHZ MCC on mac 0 and second STA on low 5 GHZ on mac1 doing SBS
+ * @PM_STA_24_STA_5_HIGH_MCC_SAP_5_LOW_SBS : First STA on 2.4 GHZ & second STA
+ * on high 5 GHZ MCC on mac 0 and SAP on high 5 GHZ on mac1 doing SBS
+ * @PM_STA_SAP_5_HIGH_STA_5_LOW_SBS : First STA on high 5 GHZ & SAP on high
+ * 5 GHZ SCC/MCC on mac0 and second STA on low 5 GHZ on mac1 doing SBS
+ * @PM_STA_5_HIGH_SAP_24_MCC_STA_5_LOW_SBS : First STA on high 5 GHZ & SAP on
+ * 2.4 GHZ MCC on mac0 and second STA on low 5 GHZ on mac1 doing SBS
+ * @PM_STA_STA_5_HIGH_MCC_SAP_5_LOW_SBS : First STA on high 5 GHZ & Second STA
+ * on high 5 GHZ MCC on mac0 and SAP on low 5 GHZ on mac1 doing SBS
+ * @PM_STA_24_STA_5_MCC_SAP_5_HIGH_SBS: MLO STA 2+5/6 GHz, SAP on 5/6 GHz
+ * high band, the current hw mode is SBS.
+ * @PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS: Any 2 link on low 5 GHZ mac
+ * and one link on high 5 GHZ freq doing SBS
+ * @PM_STA_24_SAP_5_LOW_MCC_STA_5_HIGH_SBS : First STA on 2.4 GHZ & SAP on low
+ * 5 GHZ MCC on mac 0 and second STA on high 5 GHZ on mac1 doing SBS
+ * @PM_STA_24_STA_5_LOW_MCC_SAP_5_HIGH_SBS : First STA on 2.4 & second STA on
+ * low 5G MCC on mac 0 and SAP on high 5g on mac1 doing SBS
+ * @PM_STA_SAP_5_LOW_STA_5_HIGH_SBS : First STA on low 5 GHZ & SAP on low 5 GHZ
+ * SCC/MCC on mac0 and second STA on high 5 GHZ on mac1 doing SBS
+ * @PM_STA_5_LOW_SAP_24_MCC_STA_5_HIGH_SBS : First STA on low 5 GHZ & SAP on
+ * 2.4 GHZ MCC on mac0 and second STA on high 5 GHZ on mac1 doing SBS
+ * @PM_STA_STA_5_LOW_MCC_SAP_5_HIGH_SBS : First STA on high 5 GHZ & Second STA
+ * on high 5 GHZ MCC on mac0 and SAP on low 5 GHZ on mac1 doing SBS
+ * @PM_STA_24_STA_5_MCC_SAP_5_LOW_SBS: MLO STA 2+5/6 GHz, SAP on 5/6 GHz
+ * low band, the current hw mode is SBS.
+ * @PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS:
+ * @PM_SAP_24_STA_5_STA_5_LOW_N_HIGH_SHARE_SBS: The 2.4 GHZ SAP creating MCC/SCC
+ * with STA of low 5 GHZ or high 5 GHZ (dynamic SBS) on mac 0 and one STA on
+ * high 5 GHZ or low 5 GHZ freq respectively on mac 1 doing SBS
+ * @PM_STA_24_SAP_5_STA_5_LOW_N_HIGH_SHARE_SBS: The 2.4 GHZ STA creating MCC/SCC
+ * with SAP of low 5 GHZ or high 5 GHZ (dynamic SBS) on mac 0 and one STA on
+ * high 5 GHZ or low 5 GHZ freq respectively on mac 1 doing SBS
+ * @PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS: (not dynamic SBS) MLO STA 2+5/6 GHz,
+ * SAP on 5/6 GHz, and target only support 2.4 GHz shared with 5 GHz low band
+ * or 5 GHz high band but not both.
+ * @PM_MAX_THREE_CONNECTION_MODE: Maximum enumeration
+ */
+enum policy_mgr_three_connection_mode {
+	PM_STA_SAP_SCC_24_SAP_5_DBS,
+	PM_STA_SAP_SCC_5_SAP_24_DBS,
+	PM_24_SCC_MCC_PLUS_5_DBS,
+	PM_STA_SAP_24_STA_5_DBS = PM_24_SCC_MCC_PLUS_5_DBS,
+	PM_5_SCC_MCC_PLUS_24_DBS,
+	PM_STA_SAP_5_STA_24_DBS = PM_5_SCC_MCC_PLUS_24_DBS,
+	PM_STA_STA_5_SAP_24_DBS = PM_5_SCC_MCC_PLUS_24_DBS,
+	PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS,
+	PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS,
+	PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS,
+	PM_NAN_DISC_STA_24_NDI_5_DBS,
+	PM_NAN_DISC_NDI_24_STA_5_DBS,
+	PM_STA_NDI_5_NAN_DISC_24_DBS,
+	PM_STA_NDI_NAN_DISC_24_SMM,
+	PM_NAN_DISC_NDI_24_NDI_5_DBS,
+	PM_NDI_NDI_5_NAN_DISC_24_DBS,
+	PM_NDI_NDI_NAN_DISC_24_SMM,
+	PM_SAP_SAP_SCC_24_SAP_5_DBS,
+	PM_SAP_SAP_SCC_5_SAP_24_DBS,
+	PM_STA_STA_5_NAN_DISC_24_DBS,
+	PM_NAN_DISC_24_STA_STA_5_DBS,
+	PM_STA_STA_24_NAN_DISC_24_SMM,
+	PM_NAN_DISC_24_STA_STA_24_SMM,
+	PM_STA_24_STA_5_NAN_DISC_24_SMM,
+	PM_STA_24_STA_5_NAN_DISC_24_DBS,
+	PM_STA_5_STA_24_NAN_DISC_24_SMM,
+	PM_STA_5_STA_24_NAN_DISC_24_DBS,
+	PM_NAN_DISC_24_STA_5_STA_24_SMM,
+	PM_NAN_DISC_24_STA_5_STA_24_DBS,
+	PM_NAN_DISC_24_STA_24_STA_5_SMM,
+	PM_NAN_DISC_24_STA_24_STA_5_DBS,
+	PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS,
+	PM_STA_24_SAP_5_HIGH_MCC_STA_5_LOW_SBS =
+		PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS,
+	PM_STA_24_STA_5_HIGH_MCC_SAP_5_LOW_SBS =
+		PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS,
+	PM_STA_SAP_5_HIGH_STA_5_LOW_SBS =
+		PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS,
+	PM_STA_5_HIGH_SAP_24_MCC_STA_5_LOW_SBS =
+		PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS,
+	PM_STA_STA_5_HIGH_MCC_SAP_5_LOW_SBS =
+		PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS,
+	PM_STA_24_STA_5_MCC_SAP_5_HIGH_SBS =
+		PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS,
+	PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS,
+	PM_STA_24_SAP_5_LOW_MCC_STA_5_HIGH_SBS =
+		PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS,
+	PM_STA_24_STA_5_LOW_MCC_SAP_5_HIGH_SBS =
+		PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS,
+	PM_STA_SAP_5_LOW_STA_5_HIGH_SBS =
+		PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS,
+	PM_STA_5_LOW_SAP_24_MCC_STA_5_HIGH_SBS =
+		PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS,
+	PM_STA_STA_5_LOW_MCC_SAP_5_HIGH_SBS =
+		PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS,
+	PM_STA_24_STA_5_MCC_SAP_5_LOW_SBS =
+		PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS,
+	PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS,
+	PM_SAP_24_STA_5_STA_5_LOW_N_HIGH_SHARE_SBS =
+			PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS,
+	PM_STA_24_SAP_5_STA_5_LOW_N_HIGH_SHARE_SBS =
+			PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS,
+	PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS,
+
+	PM_MAX_THREE_CONNECTION_MODE,
+};
+#endif
+
+/**
+ * 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_DOWNGRADE_BW: Downgrade SAP bandwidth.
+ * @PM_UPGRADE_BW: Upgrade SAP bandwidth.
+ * @PM_MAX_CONC_NEXT_ACTION: 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_DOWNGRADE_BW,
+	PM_UPGRADE_BW,
+
+	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_TIMER_START: This is to decide whether to start the
+ *                                        timer or not
+ * @POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN: Set probable operating channel
+ * @POLICY_MGR_UPDATE_REASON_START_AP: Start AP
+ * @POLICY_MGR_UPDATE_REASON_NORMAL_STA: Connection to Normal STA
+ * @POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC: Opportunistic HW mode update
+ * @POLICY_MGR_UPDATE_REASON_NSS_UPDATE: NSS update
+ * @POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH: After Channel switch
+ * @POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA: Before Channel switch for STA
+ * @POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP: Before Channel switch for SAP
+ * @POLICY_MGR_UPDATE_REASON_PRE_CAC: Pre-CAC
+ * @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.
+ * @POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY: NAN Discovery related
+ * @POLICY_MGR_UPDATE_REASON_NDP_UPDATE: NAN Datapath related update
+ * @POLICY_MGR_UPDATE_REASON_LFR2_ROAM: LFR2 Roaming
+ * @POLICY_MGR_UPDATE_REASON_STA_CONNECT: STA/CLI connection to peer
+ * @POLICY_MGR_UPDATE_REASON_LFR3_ROAM: LFR3 Roaming
+ * @POLICY_MGR_UPDATE_REASON_MAX: Reason code to indicate that it's not a
+ * valid operation, should always be maintained at the end of enum.
+ */
+enum policy_mgr_conn_update_reason {
+	POLICY_MGR_UPDATE_REASON_TIMER_START,
+	POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN,
+	POLICY_MGR_UPDATE_REASON_START_AP,
+	POLICY_MGR_UPDATE_REASON_NORMAL_STA,
+	POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC,
+	POLICY_MGR_UPDATE_REASON_NSS_UPDATE,
+	POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH,
+	POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA,
+	POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP,
+	POLICY_MGR_UPDATE_REASON_PRE_CAC,
+	POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE,
+	POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY,
+	POLICY_MGR_UPDATE_REASON_NDP_UPDATE,
+	POLICY_MGR_UPDATE_REASON_LFR2_ROAM,
+	POLICY_MGR_UPDATE_REASON_STA_CONNECT,
+	POLICY_MGR_UPDATE_REASON_LFR3_ROAM,
+	POLICY_MGR_UPDATE_REASON_MAX,
+};
+
+/**
+ * enum hw_mode_bandwidth - bandwidth of wifi channel.
+ * @HW_MODE_BW_NONE: no bandwidth configured
+ * @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_320_MHZ: 320 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_320_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
+ * @SET_HW_MODE_STATUS_ALREADY: Requested hw mode is already applied to FW.
+ */
+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,
+	SET_HW_MODE_STATUS_ALREADY,
+};
+
+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,
+};
+
+/**
+ * enum conn_6ghz_flag - structure to define connection 6ghz capable info
+ * in policy mgr conn info struct
+ *
+ * @CONN_6GHZ_FLAG_VALID: The 6ghz flag is valid (has been initialized)
+ * @CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED: AP is configured in 6ghz band capable
+ *   by user:
+ *   a. ACS channel range includes 6ghz.
+ *   b. SAP is started in 6ghz fix channel.
+ * @CONN_6GHZ_FLAG_SECURITY_ALLOWED: AP has security mode which is permitted in
+ *   6ghz band.
+ * @CONN_6GHZ_FLAG_NO_LEGACY_CLIENT: AP has no legacy client connected
+ */
+enum conn_6ghz_flag {
+	CONN_6GHZ_FLAG_VALID = 0x0001,
+	CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED = 0x0002,
+	CONN_6GHZ_FLAG_SECURITY_ALLOWED = 0x0004,
+	CONN_6GHZ_FLAG_NO_LEGACY_CLIENT = 0x0008,
+};
+
+#ifdef WLAN_FEATURE_AFC_DCS_SKIP_ACS_RANGE
+/* To support DCS to 6 Ghz channel when AFC response receive */
+#define CONN_6GHZ_CAPABLE (CONN_6GHZ_FLAG_VALID | \
+			     CONN_6GHZ_FLAG_SECURITY_ALLOWED | \
+			     CONN_6GHZ_FLAG_NO_LEGACY_CLIENT)
+#else
+#define CONN_6GHZ_CAPABLE (CONN_6GHZ_FLAG_VALID | \
+			     CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED | \
+			     CONN_6GHZ_FLAG_SECURITY_ALLOWED | \
+			     CONN_6GHZ_FLAG_NO_LEGACY_CLIENT)
+#endif
+
+/**
+ * struct policy_mgr_conc_connection_info - information of all existing
+ * connections in the wlan system
+ *
+ * @mode: connection type
+ * @freq: Channel frequency
+ * @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
+ * @ch_flagext: Channel extension flags.
+ * @conn_6ghz_flag: connection 6ghz capable flags
+ */
+struct policy_mgr_conc_connection_info {
+	enum policy_mgr_con_mode mode;
+	uint32_t      freq;
+	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;
+	uint16_t      ch_flagext;
+	enum conn_6ghz_flag conn_6ghz_flag;
+};
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * struct policy_mgr_disabled_ml_link_info - information of all existing
+ * disabled ml link
+ * @in_use: if the table entry is active
+ * @mode: connection type
+ * @freq: Channel frequency
+ * @vdev_id: vdev id of the connection
+ */
+struct policy_mgr_disabled_ml_link_info {
+	bool in_use;
+	enum policy_mgr_con_mode mode;
+	qdf_freq_t freq;
+	uint8_t vdev_id;
+};
+#endif
+
+/**
+ * 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
+ * @sbs_cap: SBS capability
+ * @emlsr_cap: eMLSR capability
+ * @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;
+	uint8_t emlsr_cap;
+	enum policy_mgr_conc_next_action action_type;
+};
+
+/**
+ * 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
+ * @action: current hw change action to be done
+ * @context: psoc context
+ * @request_id: Request id provided by the requester, can be used while
+ * calling callback to the requester
+ */
+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;
+	enum policy_mgr_conc_next_action action;
+	struct wlan_objmgr_psoc *context;
+	uint32_t request_id;
+};
+
+/**
+ * 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 {
+	uint32_t pcl_list[NUM_CHANNELS];
+	uint8_t weight_list[NUM_CHANNELS];
+	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 {
+	uint32_t pcl_list[NUM_CHANNELS];
+	uint32_t pcl_len;
+	uint32_t saved_chan_list[NUM_CHANNELS];
+	uint32_t saved_num_chan;
+	uint8_t weighed_valid_list[NUM_CHANNELS];
+	uint8_t weight_list[NUM_CHANNELS];
+};
+
+/**
+ * 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
+ * @ch_flagext: Channel extension flags.
+ */
+struct policy_mgr_vdev_entry_info {
+	uint32_t type;
+	uint32_t sub_type;
+	uint32_t mhz;
+	uint32_t chan_width;
+	uint32_t mac_id;
+	uint16_t ch_flagext;
+};
+
+/**
+ * struct policy_mgr_freq_range - hw mode freq range for the pdev
+ * @low_2ghz_freq: lower 2.4GHz channels
+ * @high_2ghz_freq: higher 2.4 GHz channels
+ * @low_5ghz_freq: lower 5 GHz channels
+ * @high_5ghz_freq: higher 5 GHz channels
+ */
+struct policy_mgr_freq_range {
+	qdf_freq_t low_2ghz_freq;
+	qdf_freq_t high_2ghz_freq;
+	qdf_freq_t low_5ghz_freq;
+	qdf_freq_t high_5ghz_freq;
+};
+
+/**
+ * enum policy_mgr_mode - enum for host mode
+ * @MODE_SMM:               Single mac mode
+ * @MODE_DBS:               DBS mode
+ * @MODE_SBS:               SBS mode with either high share or low share
+ * @MODE_SBS_UPPER_SHARE:   Higher 5Ghz shared with 2.4Ghz
+ * @MODE_SBS_LOWER_SHARE:   LOWER 5Ghz shared with 2.4Ghz
+ * @MODE_EMLSR:             eMLSR mode
+ * @MODE_EMLSR_SINGLE:      eMLSR single mode
+ * @MODE_EMLSR_SPLIT:       eMLSR split mode
+ * @MODE_HW_MAX: MAX
+ */
+enum policy_mgr_mode {
+	MODE_SMM,
+	MODE_DBS,
+	MODE_SBS,
+	MODE_SBS_UPPER_SHARE,
+	MODE_SBS_LOWER_SHARE,
+	MODE_EMLSR,
+	MODE_EMLSR_SINGLE,
+	MODE_EMLSR_SPLIT,
+	MODE_HW_MAX,
+};
+
+/**
+ * struct dbs_hw_mode_info - WLAN_DBS_HW_MODES_TLV Format
+ * @hw_mode_list: WLAN_DBS_HW_MODE_LIST entries
+ * @sbs_lower_band_end_freq: value with which range will be divided
+ * @freq_range_caps: Initial capability and range for different modes for both
+ *                   pdev
+ * @cur_mac_freq_range: Current freq range for both pdev, this can be used to
+ *                      reject if 2 home channels on a MAC, depending on opmode
+ *                      and current HW mode.
+ */
+struct dbs_hw_mode_info {
+	uint64_t *hw_mode_list;
+	qdf_freq_t sbs_lower_band_end_freq;
+	struct policy_mgr_freq_range freq_range_caps[MODE_HW_MAX][MAX_MAC];
+	struct policy_mgr_freq_range cur_mac_freq_range[MAX_MAC];
+};
+
+/**
+ * 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;
+};
+
+/**
+ * struct dbs_bw - Max BW supported in DBS mode
+ * @mac0_bw: BW of MAC0
+ * @mac1_bw: BW of MAC1
+ */
+struct dbs_bw {
+	enum hw_mode_bandwidth mac0_bw;
+	enum hw_mode_bandwidth mac1_bw;
+};
+
+/**
+ * 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
+ * @single_mac0_band_cap: Mac0 band capability for single mac hw mode
+ */
+struct dbs_nss {
+	enum hw_mode_ss_config mac0_ss;
+	enum hw_mode_ss_config mac1_ss;
+	uint32_t single_mac0_band_cap;
+};
+
+/*
+ * Max radio combination numbers
+ */
+#define MAX_RADIO_COMBINATION 16
+
+/**
+ * struct radio_combination - Radio combination
+ * @hw_mode: hw mode type
+ * @band_mask: band support type for each mac
+ * @antenna: antenna support for each mac
+ */
+struct radio_combination {
+	enum policy_mgr_mode hw_mode;
+	uint8_t band_mask[MAX_MAC];
+	uint8_t antenna[MAX_MAC];
+};
+
+/**
+ * struct connection_info - connection information
+ * @mac_id: The HW mac it is running
+ * @vdev_id: vdev id
+ * @channel: channel of the connection
+ * @ch_freq: channel freq in Mhz
+ */
+struct connection_info {
+	uint8_t mac_id;
+	uint8_t vdev_id;
+	uint8_t channel;
+	uint32_t ch_freq;
+};
+
+/**
+ * struct go_plus_go_force_scc - structure to hold p2p go
+ * params for forcescc restart
+ *
+ * @vdev_id: vdev id of first p2p go which needs to do csa
+ * @ch_freq: ch freq of curr p2p go
+ * @ch_width: ch width of curr p2p go
+ */
+struct go_plus_go_force_scc {
+	uint8_t vdev_id;
+	uint32_t ch_freq;
+	uint32_t ch_width;
+};
+
+/**
+ * struct sap_plus_go_force_scc - structure to hold
+ * params for forcescc restart in sap plus go
+ *
+ * @reason: channel change reason code
+ * @initiator_vdev_id: the first interface ID to trigger CSA
+ * @responder_vdev_id: the second interface ID to follow CSA
+ */
+struct sap_plus_go_force_scc {
+	enum sap_csa_reason_code reason;
+	uint8_t initiator_vdev_id;
+	uint8_t responder_vdev_id;
+};
+
+/**
+ * struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work
+ * related info
+ * @psoc: pointer to PSOC object information
+ * @go_plus_go_force_scc: structure to hold params of
+ *			  curr and first p2p go ctx
+ * @sap_plus_go_force_scc: sap p2p force SCC ctx
+ * @nan_force_scc_in_progress: NAN force scc in progress
+ */
+struct sta_ap_intf_check_work_ctx {
+	struct wlan_objmgr_psoc *psoc;
+	struct go_plus_go_force_scc go_plus_go_force_scc;
+	struct sap_plus_go_force_scc sap_plus_go_force_scc;
+	uint8_t nan_force_scc_in_progress;
+};
+
+/**
+ * union conc_ext_flag - extended flags for concurrency check
+ *
+ * @mlo: the new connection is MLO
+ * @mlo_link_assoc_connected: the new connection is secondary MLO link and
+ *  the corresponding assoc link is connected
+ * @value: uint32 value for extended flags
+ */
+union conc_ext_flag {
+	struct {
+		uint32_t mlo: 1;
+		uint32_t mlo_link_assoc_connected: 1;
+	};
+
+	uint32_t value;
+};
+
+/**
+ * enum indoor_conc_update_type - Indoor concurrency update type
+ * @CONNECT: On a new STA connection
+ * @DISCONNECT_WITHOUT_CONCURRENCY: On a STA disconnection with no active
+ * sessions on the same frequency
+ * @DISCONNECT_WITH_CONCURRENCY: On a STA disconnection with an active
+ * session on the same frequency
+ * @SWITCH_WITH_CONCURRENCY: On a STA roam or CSA to a different channel
+ * with a concurrent SAP on previous frequency
+ * @SWITCH_WITHOUT_CONCURRENCY: On a STA roam or CSA to a different channel
+ * without any concurrent SAP on previous frequency
+ */
+enum indoor_conc_update_type {
+	CONNECT,
+	DISCONNECT_WITHOUT_CONCURRENCY,
+	DISCONNECT_WITH_CONCURRENCY,
+	SWITCH_WITHOUT_CONCURRENCY,
+	SWITCH_WITH_CONCURRENCY,
+};
+
+#endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */

+ 470 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h

@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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"
+#include "wlan_policy_mgr_public_struct.h"
+
+/**
+ * ucfg_policy_mgr_psoc_open() - This API sets CFGs to policy manager context
+ * @psoc: pointer to psoc
+ *
+ * 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
+ * @psoc: pointer to psoc
+ *
+ * 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_radio_combinations() - Query the supported radio
+ * combinations
+ * @psoc: soc object
+ * @comb: combination buffer
+ * @comb_max: max combination number can be saved to comb buffer
+ * @comb_num: returned combination number
+ *
+ * This function returns the radio combination information supported by target.
+ *
+ * Return: QDF_STATUS_SUCCESS if query successfully
+ */
+QDF_STATUS
+ucfg_policy_mgr_get_radio_combinations(struct wlan_objmgr_psoc *psoc,
+				       struct radio_combination *comb,
+				       uint32_t comb_max,
+				       uint32_t *comb_num);
+
+/**
+ * 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_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_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);
+/**
+ * ucfg_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,
+				     bool *enable_mcc_adaptive_sch);
+
+/**
+ * ucfg_policy_mgr_get_dynamic_mcc_adaptive_sch() - to get dynamic mcc adaptive
+ *                                                  scheduler
+ * @psoc: pointer to psoc
+ * @dynamic_mcc_adaptive_sch: value to be filled
+ *
+ * This API is used to get dynamic mcc adaptive scheduler
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+ucfg_policy_mgr_get_dynamic_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
+					     bool *dynamic_mcc_adaptive_sch);
+
+/**
+ * ucfg_policy_mgr_set_dynamic_mcc_adaptive_sch() - to set dynamic mcc adaptive
+ *                                                  scheduler
+ * @psoc: pointer to psoc
+ * @dynamic_mcc_adaptive_sch: value to be set
+ *
+ * This API is used to set dynamic mcc adaptive scheduler
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+ucfg_policy_mgr_set_dynamic_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
+					     bool dynamic_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);
+/**
+ * ucfg_policy_mgr_get_allow_mcc_go_diff_bi() - to get information on whether GO
+ *						can have diff BI than STA in MCC
+ * @psoc: pointer to psoc
+ * @allow_mcc_go_diff_bi: value to be filled
+ *
+ * This API is used to find out whether GO's BI can different than STA in MCC
+ * scenario
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+ucfg_policy_mgr_get_allow_mcc_go_diff_bi(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *allow_mcc_go_diff_bi);
+/**
+ * ucfg_policy_mgr_get_dual_mac_feature() - to find out if DUAL MAC feature is
+ *					    enabled
+ * @psoc: pointer to psoc
+ * @dual_mac_feature: value to be filled
+ *
+ * This API is used to find out whether dual mac (dual radio) specific feature
+ * is enabled or not
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_dual_mac_feature(struct wlan_objmgr_psoc *psoc,
+						uint8_t *dual_mac_feature);
+
+/**
+ * ucfg_policy_mgr_get_dual_sta_feature() - to find out if DUAL STA feature is
+ *					    enabled
+ * @psoc: pointer to psoc
+ *
+ * This API is used to find out whether dual sta specific feature is enabled
+ * or not.
+ *
+ * Return: true if feature is enabled, otherwise false.
+ */
+bool ucfg_policy_mgr_get_dual_sta_feature(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_policy_mgr_get_force_1x1() - to find out if 1x1 connection is enforced
+ *
+ * @psoc: pointer to psoc
+ * @force_1x1: value to be filled
+ *
+ * This API is used to find out if 1x1 connection is enforced.
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_force_1x1(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *force_1x1);
+
+/**
+ * ucfg_policy_mgr_get_max_conc_cxns() - to get configured max concurrent active
+ * connection count
+ *
+ * @psoc: pointer to psoc
+ *
+ * This API is used to query the configured max concurrent active connection
+ * count.
+ *
+ * Return: max active connection count
+ */
+uint32_t ucfg_policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_policy_mgr_set_max_conc_cxns() - to set supported max concurrent active
+ * connection count to policy mgr
+ *
+ * @psoc: pointer to psoc
+ * @max_conc_cxns: max active connection count
+ *
+ * This API is used to update the max concurrent active connection
+ * count to policy mgr
+ *
+ * Return: QDF_STATUS_SUCCESS if set successfully
+ */
+QDF_STATUS ucfg_policy_mgr_set_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
+					     uint32_t max_conc_cxns);
+
+/**
+ * ucfg_policy_mgr_get_sta_sap_scc_on_dfs_chnl() - to find out if STA and SAP
+ *						   SCC is allowed on DFS channel
+ * @psoc: pointer to psoc
+ * @sta_sap_scc_on_dfs_chnl: value to be filled
+ *
+ * This API is used to find out whether STA and SAP SCC is allowed on
+ * DFS channels
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+ucfg_policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *sta_sap_scc_on_dfs_chnl);
+/**
+ * ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl() - to find out if STA & SAP
+ *						     SCC is allowed on LTE COEX
+ * @psoc: pointer to psoc
+ * @sta_sap_scc_lte_coex: value to be filled
+ *
+ * This API is used to find out whether STA and SAP scc is allowed on LTE COEX
+ * channel
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *sta_sap_scc_lte_coex);
+
+/**
+ * ucfg_policy_mgr_get_dfs_master_dynamic_enabled() - support dfs master or not
+ *  AP interface when STA+SAP(GO) concurrency
+ * @psoc: pointer to psoc
+ * @vdev_id: sap vdev id
+ *
+ * This API is used to check SAP (GO) dfs master functionality enabled or not
+ * when STA+SAP(GO) concurrency.
+ * If g_sta_sap_scc_on_dfs_chan is non-zero, the STA+SAP(GO) is allowed on DFS
+ * channel SCC and the SAP's DFS master functionality should be enable/disable
+ * according to:
+ * 1. g_sta_sap_scc_on_dfs_chan is 0: function return true - dfs master
+ *     capability enabled.
+ * 2. g_sta_sap_scc_on_dfs_chan is 1: function return false - dfs master
+ *     capability disabled.
+ * 3. g_sta_sap_scc_on_dfs_chan is 2: dfs master capability based on STA on
+ *     5G or not:
+ *      a. 5G STA active - return false
+ *      b. no 5G STA active -return true
+ *
+ * Return: true if dfs master functionality should be enabled.
+ */
+bool
+ucfg_policy_mgr_get_dfs_master_dynamic_enabled(struct wlan_objmgr_psoc *psoc,
+					       uint8_t vdev_id);
+
+/**
+ * ucfg_policy_mgr_init_chan_avoidance() - init channel avoidance in policy
+ *					   manager
+ * @psoc: pointer to psoc
+ * @chan_freq_list: channel frequency list
+ * @chan_cnt: channel count
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+ucfg_policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc,
+				    qdf_freq_t *chan_freq_list,
+				    uint16_t chan_cnt);
+
+/**
+ * ucfg_policy_mgr_get_sap_mandt_chnl() - to find out if SAP mandatory channel
+ *					  support is enabled
+ * @psoc: pointer to psoc
+ * @sap_mandt_chnl: value to be filled
+ *
+ * This API is used to find out whether SAP's mandatory channel support
+ * is enabled
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS ucfg_policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *sap_mandt_chnl);
+/**
+ * ucfg_policy_mgr_get_indoor_chnl_marking() - to get if indoor channel can be
+ *						marked as disabled
+ * @psoc: pointer to psoc
+ * @indoor_chnl_marking: value to be filled
+ *
+ * This API is used to find out whether indoor channel can be marked as disabled
+ *
+ * Return: QDF_STATUS_SUCCESS up on success and any other status for failure.
+ */
+QDF_STATUS
+ucfg_policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc *psoc,
+					uint8_t *indoor_chnl_marking);
+
+/**
+ * ucfg_policy_mgr_get_sta_sap_scc_on_indoor_chnl() - to get if
+ * sta sap scc on indoor channel is allowed
+ * @psoc: pointer to psoc
+ *
+ * This API is used to get the value of  sta+sap scc on indoor channel
+ *
+ * Return: TRUE or FALSE
+ */
+
+bool
+ucfg_policy_mgr_get_sta_sap_scc_on_indoor_chnl(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_policy_mgr_is_fw_supports_dbs() - to check whether FW supports DBS or
+ * not
+ * @psoc: pointer to psoc
+ *
+ * Return: true if DBS is supported else false
+ */
+bool ucfg_policy_mgr_is_fw_supports_dbs(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_policy_mgr_get_connection_count() - Get number of connections
+ * @psoc: pointer to psoc
+ *
+ * This API is used to get the count of current connections.
+ *
+ * Return: connection count
+ */
+uint32_t ucfg_policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_policy_mgr_is_hw_sbs_capable() - Check if HW is SBS capable
+ * @psoc: pointer to psoc
+ *
+ * This API is to check if the HW is SBS capable.
+ *
+ * Return: true if the HW is SBS capable
+ */
+bool ucfg_policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * ucfg_policy_mgr_get_vdev_same_freq_new_conn() - Get vdev_id of the first
+ *					           connection that has same
+ *					           channel frequency as new_freq
+ * @psoc: psoc object pointer
+ * @new_freq: channel frequency for the new connection
+ * @vdev_id: Output parameter to return vdev id of the first existing connection
+ *	     that has same channel frequency as @new_freq
+ *
+ * This function is to return the first connection that has same
+ * channel frequency as @new_freq.
+ *
+ * Return: true if connection that has same channel frequency as
+ *	   @new_freq exists. Otherwise false.
+ */
+bool ucfg_policy_mgr_get_vdev_same_freq_new_conn(struct wlan_objmgr_psoc *psoc,
+						 uint32_t new_freq,
+						 uint8_t *vdev_id);
+/*
+ * ucfg_policy_mgr_get_vdev_diff_freq_new_conn() - Get vdev id of the first
+ *						   connection that has different
+ *						   channel freq from new_freq
+ * @psoc: psoc object pointer
+ * @new_freq: channel frequency for the new connection
+ * @vdev_id: Output parameter to return vdev id of the first existing connection
+ *	     that has different channel frequency from @new_freq
+ *
+ * This function is to return the first connection that has different
+ * channel frequency from @new_freq.
+ *
+ * Return: true if connection that has different channel frequency from
+ *	   @new_freq exists. Otherwise false.
+ */
+bool ucfg_policy_mgr_get_vdev_diff_freq_new_conn(struct wlan_objmgr_psoc *psoc,
+						 uint32_t new_freq,
+						 uint8_t *vdev_id);
+
+/**
+ * ucfg_policy_mgr_get_dbs_hw_modes() - to get the DBS HW modes
+ *
+ * @psoc: pointer to psoc
+ * @one_by_one_dbs: 1x1 DBS capability of HW
+ * @two_by_two_dbs: 2x2 DBS capability of HW
+ *
+ * Return: Failure in case of error otherwise success
+ */
+QDF_STATUS ucfg_policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc,
+					    bool *one_by_one_dbs,
+					    bool *two_by_two_dbs);
+
+#endif //__WLAN_POLICY_MGR_UCFG

+ 4321 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -0,0 +1,4321 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_i.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_objmgr_global_obj.h"
+#include "qdf_platform.h"
+#include "wlan_nan_api.h"
+#include "nan_ucfg_api.h"
+#include "wlan_mlme_api.h"
+#include "sap_api.h"
+#include "wlan_mlme_api.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "target_if.h"
+#include "wlan_cm_api.h"
+#include "wlan_mlo_link_force.h"
+#include "wlan_mlo_mgr_sta.h"
+#include "wlan_mlo_mgr_link_switch.h"
+#include "wlan_psoc_mlme_api.h"
+#include "wlan_policy_mgr_ll_sap.h"
+
+enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr)
+	(struct wlan_objmgr_psoc *psoc);
+
+#define HW_MODE_DUMP_MAX_LEN 100
+void
+policy_mgr_dump_freq_range_n_vdev_map(uint32_t num_vdev_mac_entries,
+			struct policy_mgr_vdev_mac_map *vdev_mac_map,
+			uint32_t num_mac_freq,
+			struct policy_mgr_pdev_mac_freq_map *mac_freq_range)
+{
+	char log_str[HW_MODE_DUMP_MAX_LEN] = {0};
+	uint32_t str_len = HW_MODE_DUMP_MAX_LEN;
+	uint32_t len = 0;
+	uint32_t i;
+
+	if (mac_freq_range) {
+		for (i = 0, len = 0; i < num_mac_freq; i++)
+			len += qdf_scnprintf(log_str + len, str_len - len,
+					    "mac %d: %d => %d ",
+					    mac_freq_range[i].mac_id,
+					    mac_freq_range[i].start_freq,
+					    mac_freq_range[i].end_freq);
+		if (num_mac_freq)
+			policymgr_nofl_debug("Freq range:: %s", log_str);
+	}
+
+	if (!vdev_mac_map || !num_vdev_mac_entries)
+		return;
+
+	for (i = 0, len = 0; i < num_vdev_mac_entries; i++)
+		len += qdf_scnprintf(log_str + len, str_len - len,
+				     "vdev %d -> mac %d ",
+				     vdev_mac_map[i].vdev_id,
+				     vdev_mac_map[i].mac_id);
+	policymgr_nofl_debug("Vdev Map:: %s", log_str);
+}
+
+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,
+			uint32_t num_mac_freq,
+			struct policy_mgr_pdev_mac_freq_map *mac_freq_range,
+			struct wlan_objmgr_psoc *context)
+{
+	QDF_STATUS status;
+	struct policy_mgr_hw_mode_params hw_mode;
+	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;
+	}
+
+	status = policy_mgr_get_hw_mode_from_idx(context, new_hw_mode_index,
+						 &hw_mode);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Get HW mode for index %d reason: %d",
+			       new_hw_mode_index, status);
+		return;
+	}
+
+	policy_mgr_debug("HW mode: old %d new %d, DBS %d Agile %d SBS %d, MAC0:: SS:Tx %d Rx %d, BW %d band %d, MAC1:: SS:Tx %d Rx %d, BW %d",
+			 old_hw_mode_index, new_hw_mode_index, hw_mode.dbs_cap,
+			 hw_mode.agile_dfs_cap, hw_mode.sbs_cap,
+			 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
+			 hw_mode.mac0_bw, hw_mode.mac0_band_cap,
+			 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
+			 hw_mode.mac1_bw);
+	policy_mgr_dump_freq_range_n_vdev_map(num_vdev_mac_entries,
+					      vdev_mac_map, num_mac_freq,
+					      mac_freq_range);
+
+	/* update pm_conc_connection_list */
+	policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries,
+					    vdev_mac_map, hw_mode,
+					    num_mac_freq, mac_freq_range);
+
+	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;
+	enum policy_mgr_conn_update_reason reason =
+				POLICY_MGR_UPDATE_REASON_TIMER_START;
+
+	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, &reason)) {
+	/* 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, enum policy_mgr_conc_next_action action,
+		uint32_t request_id)
+{
+	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 (!pm_ctx->sme_cbacks.sme_pdev_set_hw_mode) {
+		policy_mgr_debug("NOT supported");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	/*
+	 * 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;
+	}
+
+	/* Don't send WMI_PDEV_SET_HW_MODE_CMDID to FW if existing SAP / GO is
+	 * in CAC-in-progress state. Host is blocking this command as FW is
+	 * having design limitation and FW don't expect this command when CAC
+	 * is in progress state.
+	 */
+	if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_cac_in_progress() &&
+	    !policy_mgr_is_hw_dbs_2x2_capable(psoc)) {
+		policy_mgr_err("SAP CAC_IN_PROGRESS state, drop WMI_PDEV_SET_HW_MODE_CMDID");
+		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.action = action;
+	msg.context = psoc;
+	msg.request_id = request_id;
+
+	policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d action %d request_id %d",
+			 msg.hw_mode_index, msg.session_id, msg.reason, action,
+			 msg.request_id);
+
+	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;
+}
+
+/**
+ * policy_mgr_get_sap_bw() - get current SAP bandwidth
+ * @psoc: Pointer to psoc
+ * @bw: Buffer to update the bandwidth
+ *
+ * Get the current SAP bandwidth. This API supports only single SAP
+ * concurrencies and doesn't cover multi SAP(e.g. SAP+SAP).
+ *
+ * return : QDF_STATUS
+ */
+static QDF_STATUS
+policy_mgr_get_sap_bw(struct wlan_objmgr_psoc *psoc, enum phy_ch_width *bw)
+{
+	uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
+	struct wlan_objmgr_vdev *vdev;
+
+	if (policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0],
+						   &vdev_id_list[0],
+						   PM_SAP_MODE) != 1 ||
+	    !WLAN_REG_IS_6GHZ_CHAN_FREQ(freq_list[0]))
+		return QDF_STATUS_E_NOSUPPORT;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id_list[0],
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d is NULL", vdev_id_list[0]);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*bw = wlan_mlme_get_ap_oper_ch_width(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_get_sap_ch_width_update_action() - get SAP ch_width update action
+ * @psoc: Pointer to psoc
+ * @vdev_id: Vdev id of the caller
+ * @ch_freq: channel frequency of new connection
+ * @next_action: next action to happen in order to update bandwidth
+ * @reason: Bandwidth upgrade/downgrade reason
+ *
+ * Check if current operating SAP needs a downgrade to 160MHz or an upgrade
+ * to 320MHz based on the new connection.
+ *
+ * return : None
+ */
+static void
+policy_mgr_get_sap_ch_width_update_action(struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id, qdf_freq_t ch_freq,
+				enum policy_mgr_conc_next_action *next_action,
+				enum policy_mgr_conn_update_reason *reason)
+{
+	enum phy_ch_width cur_bw;
+	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
+	bool eht_capab = false;
+
+	/*
+	 * Stop any running opportunistic timer as it will be started after
+	 * decision if required.
+	 */
+	policy_mgr_stop_opportunistic_timer(psoc);
+	if (QDF_IS_STATUS_ERROR(wlan_psoc_mlme_get_11be_capab(psoc,
+							      &eht_capab)) ||
+	    !eht_capab ||
+	    QDF_IS_STATUS_ERROR(policy_mgr_get_sap_bw(psoc, &cur_bw)) ||
+	    cur_bw < CH_WIDTH_160MHZ)
+		return;
+
+	policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0],
+					       &vdev_id_list[0], PM_SAP_MODE);
+	if (cur_bw == CH_WIDTH_320MHZ && ch_freq &&
+	    policy_mgr_is_conn_lead_to_dbs_sbs(psoc, vdev_id, ch_freq))
+		*next_action = PM_DOWNGRADE_BW;
+	else if (cur_bw == CH_WIDTH_160MHZ &&
+		 !ch_freq &&
+		 !policy_mgr_is_conn_lead_to_dbs_sbs(psoc,
+					vdev_id_list[0], freq_list[0]) &&
+		 (reason &&
+		  (*reason == POLICY_MGR_UPDATE_REASON_TIMER_START ||
+		   *reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC)))
+		*next_action = PM_UPGRADE_BW;
+}
+
+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;
+
+	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
+		policy_mgr_get_sap_ch_width_update_action(psoc,
+							  WLAN_INVALID_VDEV_ID,
+							  0, &upgrade,
+							  reason);
+		return upgrade;
+	}
+
+	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_rl_debug("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].freq,
+			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_required_for_band(
+					psoc, HW_MODE_MAC_BAND_2G) &&
+			    WLAN_REG_IS_24GHZ_CH_FREQ(
+				pm_conc_connection_list[conn_index].freq)) {
+				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, ch_freq, cur_freq;
+	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;
+	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++;
+	}
+
+	if (!found) {
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		/* err msg */
+		policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
+			vdev_id);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+	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) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			policy_mgr_err("can't find vdev_id %d in connection table",
+			vdev_id);
+			return status;
+		}
+	} else {
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		policy_mgr_err("wma_get_connection_info is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cur_freq = pm_conc_connection_list[conn_index].freq;
+
+	mode = policy_mgr_qdf_opmode_to_pm_con_mode(
+					psoc,
+					wlan_get_opmode_from_vdev_id(
+								pm_ctx->pdev,
+								vdev_id),
+					vdev_id);
+
+	ch_freq = 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_FREQ(ch_freq) && nss_2g > 1) ||
+		    (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1))
+			chain_mask = POLICY_MGR_TWO_TWO;
+		else
+			chain_mask = POLICY_MGR_ONE_ONE;
+		nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? 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, ch_freq,
+			policy_mgr_get_bw(conn_table_entry.chan_width),
+			conn_table_entry.mac_id, chain_mask,
+			nss, vdev_id, true, true, conn_table_entry.ch_flagext);
+	policy_mgr_dump_current_concurrency(psoc);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	/* do we need to change the HW mode */
+	policy_mgr_check_n_start_opportunistic_timer(psoc);
+
+	if (policy_mgr_is_conc_sap_present_on_sta_freq(psoc, mode, cur_freq) &&
+	    policy_mgr_update_indoor_concurrency(psoc, vdev_id, 0,
+						 SWITCH_WITH_CONCURRENCY))
+		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
+	else if (policy_mgr_update_indoor_concurrency(psoc, vdev_id, cur_freq,
+						SWITCH_WITHOUT_CONCURRENCY))
+		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
+	else if (wlan_reg_get_keep_6ghz_sta_cli_connection(pm_ctx->pdev) &&
+		 (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE))
+		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
+
+	ml_nlink_conn_change_notify(
+		psoc, vdev_id, ml_nlink_connection_updated_evt, NULL);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t session_id,
+		uint32_t ch_freq,
+		enum policy_mgr_conn_update_reason reason)
+{
+	QDF_STATUS status;
+
+	policy_mgr_debug("session:%d ch_freq:%d reason:%d",
+			 session_id, ch_freq, 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, ch_freq, reason,
+			POLICY_MGR_DEF_REQ_ID);
+	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;
+}
+
+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;
+	case PM_NAN_DISC_MODE:
+		switch (new_conn_mode) {
+		case QDF_STA_MODE:
+		case QDF_SAP_MODE:
+		case QDF_NDI_MODE:
+			return true;
+		default:
+			return false;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
+				     uint32_t ch_freq)
+{
+	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 false;
+	}
+
+	/*
+	 * check given channel freq against already existing connections'
+	 * channel freqs. 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++) {
+		if (pm_conc_connection_list[i].in_use)
+			if (!WLAN_REG_IS_SAME_BAND_FREQS(
+			    ch_freq, pm_conc_connection_list[i].freq)) {
+				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,
+					     uint32_t ch_freq)
+{
+	enum policy_mgr_band band;
+	bool is_hwmode_dbs, dbs_required_for_2g;
+
+	if (policy_mgr_is_hwmode_offload_enabled(psoc))
+		return true;
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) == false)
+		return true;
+
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
+		band = POLICY_MGR_BAND_24;
+	else
+		band = POLICY_MGR_BAND_5;
+
+	is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
+	dbs_required_for_2g = policy_mgr_is_hw_dbs_required_for_band(
+					psoc, HW_MODE_MAC_BAND_2G);
+	/*
+	 * 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 && dbs_required_for_2g &&
+	    !is_hwmode_dbs) {
+		policy_mgr_err("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,
+	uint32_t ch_freq,
+	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;
+	uint32_t ch_freq_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 && ch_freq) {
+		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_qdf_opmode_to_pm_con_mode(psoc,
+							     new_conn_op_mode,
+							     vdev_id);
+		if (new_conn_mode == PM_MAX_NUM_OF_MODE)
+			policy_mgr_debug("new vdev %d op_mode %d freq %d reason %d: not prioritized",
+					 vdev_id, new_conn_op_mode,
+					 ch_freq, reason);
+		else
+			policy_mgr_debug("new vdev %d op_mode %d freq %d : reason %d",
+					 vdev_id, new_conn_op_mode, ch_freq,
+					 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, ch_freq_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], ch_freq_list[i],
+					 pri_conn_mode);
+
+			if (new_conn_mode == pri_conn_mode &&
+			    vdev_list[i] == vdev_id) {
+				ch_freq_list[i] = ch_freq;
+				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) {
+			ch_freq_list[vdev_count] = ch_freq;
+			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_FREQ(ch_freq_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
+ * @ch_freq: channel frequency 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,
+	uint32_t ch_freq,
+	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, ch_freq, 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
+ * @ch_freq: channel frequency 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,
+	uint32_t ch_freq,
+	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, ch_freq, reason);
+	switch (preferred_action) {
+	case PM_DBS2:
+		return next_action_three_connection_2x2_2g_1x1_5g_table;
+	default:
+		return next_action_three_connection_table;
+	}
+}
+
+bool
+policy_mgr_is_conn_lead_to_dbs_sbs(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id, qdf_freq_t freq)
+{
+	struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint32_t connection_count, i;
+
+	connection_count = policy_mgr_get_connection_info(psoc, info);
+	for (i = 0; i < connection_count; i++) {
+		/* Ignore the vdev id for which freq is passed */
+		if (vdev_id == info[i].vdev_id)
+			continue;
+		if (!policy_mgr_2_freq_always_on_same_mac(psoc, freq,
+							  info[i].ch_freq))
+			return true;
+	}
+	return false;
+}
+
+static QDF_STATUS
+policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc,
+			   uint32_t session_id,
+			   uint32_t ch_freq,
+			   enum policy_mgr_conn_update_reason reason,
+			   enum policy_mgr_conc_next_action *next_action)
+{
+	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;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
+
+	if (!next_action) {
+		policy_mgr_err("next_action is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
+		*next_action = PM_NOP;
+		policy_mgr_get_sap_ch_width_update_action(psoc, session_id,
+							  ch_freq,
+							  next_action, &reason);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
+		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 freq=%d",
+			 num_connections, ch_freq);
+
+	switch (num_connections) {
+	case 0:
+		if (band == POLICY_MGR_BAND_24)
+			if (policy_mgr_is_hw_dbs_required_for_band(
+					psoc, HW_MODE_MAC_BAND_2G))
+				*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");
+			return QDF_STATUS_E_FAILURE;
+		}
+		second_conn_table = policy_mgr_get_second_conn_action_table(
+			psoc, session_id, ch_freq, 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");
+			return QDF_STATUS_E_FAILURE;
+		}
+		third_conn_table = policy_mgr_get_third_conn_action_table(
+			psoc, session_id, ch_freq, reason);
+		*next_action = (*third_conn_table)[third_index][band];
+		break;
+	default:
+		policy_mgr_err("unexpected num_connections value %d",
+			num_connections);
+		break;
+	}
+
+	/*
+	 * There is no adapter associated with NAN Discovery, hence skip the
+	 * HDD callback and fill separately.
+	 */
+	if (reason == POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY)
+		new_conn_mode = QDF_NAN_DISC_MODE;
+	else 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;
+
+	policy_mgr_debug("idx2=%d idx3=%d next_action=%d, band=%d reason=%d session_id=%d",
+			 second_index, third_index, *next_action, band,
+			 reason, session_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static bool
+policy_mgr_is_hw_mode_change_required(struct wlan_objmgr_psoc *psoc,
+				      uint32_t ch_freq, uint8_t vdev_id)
+{
+	if (policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G)) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
+			return true;
+	} else {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) &&
+		    policy_mgr_is_any_mode_active_on_band_along_with_session
+			(psoc, vdev_id, POLICY_MGR_BAND_5))
+			return true;
+
+		if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
+		    policy_mgr_is_any_mode_active_on_band_along_with_session
+			(psoc, vdev_id, POLICY_MGR_BAND_24))
+			return true;
+	}
+
+	return false;
+}
+
+static bool
+policy_mgr_is_ch_width_downgrade_required(struct wlan_objmgr_psoc *psoc,
+					  uint8_t vdev_id,
+					  struct scan_cache_entry *entry,
+					  qdf_list_t *scan_list)
+
+{
+	if (policy_mgr_is_conn_lead_to_dbs_sbs(psoc, vdev_id,
+					       entry->channel.chan_freq) ||
+	    wlan_cm_bss_mlo_type(psoc, entry, scan_list))
+		return true;
+
+	return false;
+}
+
+static uint32_t
+policy_mgr_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
+				    qdf_list_t *scan_list, uint8_t vdev_id)
+{
+
+	struct scan_cache_node *scan_node = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	uint32_t ch_freq = 0;
+	struct scan_cache_entry *entry;
+	bool eht_capab =  false, check_sap_bw_downgrade = false;
+	enum phy_ch_width cur_bw = CH_WIDTH_INVALID;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev)
+		goto end;
+
+	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
+		/*
+		 * Stop any running opportunistic timer as it will be started
+		 * after decision if required.
+		 */
+		policy_mgr_stop_opportunistic_timer(psoc);
+		wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab);
+		if (eht_capab &&
+		    QDF_IS_STATUS_SUCCESS(policy_mgr_get_sap_bw(psoc,
+								&cur_bw)) &&
+						cur_bw == CH_WIDTH_320MHZ &&
+		    !mlo_mgr_is_link_switch_in_progress(vdev))
+			check_sap_bw_downgrade = true;
+		else
+			goto end;
+	}
+
+	if (!scan_list || !qdf_list_size(scan_list)) {
+		policy_mgr_debug("Scan list is NULL or No BSSIDs present");
+		goto end;
+	}
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
+		policy_mgr_debug("Driver isn't DBS capable");
+		goto end;
+	}
+
+	if (check_sap_bw_downgrade)
+		goto ch_width_update;
+
+	if (!policy_mgr_is_dbs_allowed_for_concurrency(psoc, QDF_STA_MODE)) {
+		policy_mgr_debug("DBS not allowed for concurrency combo");
+		goto end;
+	}
+
+	if (!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
+	    !policy_mgr_is_hw_dbs_required_for_band(psoc,
+						    HW_MODE_MAC_BAND_2G) &&
+	    !policy_mgr_get_connection_count(psoc)) {
+		policy_mgr_debug("1x1 DBS with no existing connection, HW mode change not required");
+		goto end;
+	}
+
+ch_width_update:
+	qdf_list_peek_front(scan_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(scan_list, cur_node, &next_node);
+
+		scan_node = qdf_container_of(cur_node, struct scan_cache_node,
+					     node);
+		entry = scan_node->entry;
+		ch_freq = entry->channel.chan_freq;
+
+		if (policy_mgr_is_hw_mode_change_required(psoc, ch_freq,
+							  vdev_id) ||
+		    policy_mgr_is_ch_width_downgrade_required(psoc, vdev_id,
+							      entry,
+							      scan_list)) {
+			policy_mgr_debug("Scan list has BSS of freq %d hw mode/SAP ch_width:%d update required",
+					 ch_freq, cur_bw);
+			break;
+		}
+
+		ch_freq = 0;
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+end:
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return ch_freq;
+}
+
+QDF_STATUS
+policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc,
+				      qdf_list_t *scan_list, uint8_t vdev_id,
+				      uint32_t connect_id)
+{
+	QDF_STATUS status;
+	uint32_t ch_freq;
+
+	ch_freq = policy_mgr_check_for_hw_mode_change(psoc, scan_list, vdev_id);
+	if (!ch_freq)
+		return QDF_STATUS_E_ALREADY;
+
+	status = policy_mgr_current_connections_update(psoc, vdev_id, ch_freq,
+			POLICY_MGR_UPDATE_REASON_STA_CONNECT, connect_id);
+
+	/*
+	 * If status is success then the callback of policy mgr hw mode change
+	 * would be called.
+	 * If status is no support then the DUT is already in required HW mode.
+	 */
+
+	if (status == QDF_STATUS_E_FAILURE)
+		policy_mgr_err("Hw mode change failed");
+	else if (status == QDF_STATUS_E_NOSUPPORT)
+		status = QDF_STATUS_E_ALREADY;
+
+	return status;
+}
+
+QDF_STATUS
+policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
+				      uint32_t session_id, uint32_t ch_freq,
+				      enum policy_mgr_conn_update_reason
+				      reason, uint32_t request_id)
+{
+	enum policy_mgr_conc_next_action next_action = PM_NOP;
+	QDF_STATUS status;
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
+		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	status = policy_mgr_get_next_action(psoc, session_id, ch_freq, reason,
+					    &next_action);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	if (PM_NOP != next_action)
+		status = policy_mgr_next_actions(psoc, session_id,
+						next_action, reason,
+						request_id);
+	else
+		status = QDF_STATUS_E_NOSUPPORT;
+
+	policy_mgr_debug("next_action %d reason=%d session_id=%d request_id %x",
+			 next_action, reason, session_id, request_id);
+
+	return status;
+}
+
+/**
+ * policy_mgr_dbs1_dbs2_need_action() - whether more actions are needed
+ *                                      in DBS1 and DBS2 hw mode
+ * @psoc: psoc object
+ * @action: action type
+ * @hw_mode: hardware mode
+ *
+ * The function checks further action are needed or not for DBS1 and DBS2.
+ *
+ * Return: true if more action are needed, otherwise
+ *         return false
+ */
+static bool
+policy_mgr_dbs1_dbs2_need_action(struct wlan_objmgr_psoc *psoc,
+				 enum policy_mgr_conc_next_action action,
+				 struct policy_mgr_hw_mode_params *hw_mode)
+{
+	if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
+	    policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
+		policy_mgr_debug("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_debug("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed",
+					 hw_mode->action_type, action);
+			return false;
+		} else if (hw_mode->action_type == PM_DBS2 &&
+			   ((action == PM_DBS2 ||
+			   action == PM_DBS2_DOWNGRADE))) {
+			policy_mgr_debug("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed",
+					 hw_mode->action_type, action);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+QDF_STATUS
+policy_mgr_validate_dbs_switch(struct wlan_objmgr_psoc *psoc,
+			       enum policy_mgr_conc_next_action action)
+{
+	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 ((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
+		 */
+		if (hw_mode.sbs_cap) {
+			policy_mgr_notice("current mode is already SBS");
+			return QDF_STATUS_E_ALREADY;
+		}
+		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)) {
+		if (!policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
+			return QDF_STATUS_E_ALREADY;
+	} else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) ||
+		   (action == PM_DBS_UPGRADE)) {
+		policy_mgr_debug("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;
+}
+
+/**
+ * policy_mgr_validate_unsupported_action() - unsupported action validation
+ * @psoc: psoc object
+ * @action: action type
+ *
+ * The help function checks the Action supported by HW or not.
+ *
+ * Return: QDF_STATUS_SUCCESS if supported by HW, otherwise
+ *         return QDF_STATUS_E_NOSUPPORT
+ */
+static QDF_STATUS policy_mgr_validate_unsupported_action
+		(struct wlan_objmgr_psoc *psoc,
+		 enum policy_mgr_conc_next_action action)
+{
+	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;
+		}
+	}
+
+	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,
+		uint32_t request_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct dbs_nss nss_dbs = {0};
+	struct dbs_bw bw_dbs = {0};
+	struct policy_mgr_hw_mode_params hw_mode;
+	enum policy_mgr_conc_next_action next_action;
+	bool is_sbs_supported;
+	enum hw_mode_sbs_capab sbs_capab;
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
+		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+	status = policy_mgr_validate_unsupported_action(psoc, action);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+	/* 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;
+	}
+
+	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, request_id);
+		break;
+	case PM_DBS:
+		(void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
+		policy_mgr_get_hw_dbs_max_bw(psoc, &bw_dbs);
+		is_sbs_supported = policy_mgr_is_hw_sbs_capable(psoc);
+		sbs_capab = is_sbs_supported ? HW_MODE_SBS : HW_MODE_SBS_NONE;
+		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
+						     nss_dbs.mac0_ss,
+						     bw_dbs.mac0_bw,
+						     nss_dbs.mac1_ss,
+						     bw_dbs.mac1_bw,
+						     HW_MODE_MAC_BAND_NONE,
+						     HW_MODE_DBS,
+						     HW_MODE_AGILE_DFS_NONE,
+						     sbs_capab,
+						     reason, PM_NOP, PM_DBS,
+						     request_id);
+		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,
+						PM_SINGLE_MAC_UPGRADE,
+						request_id);
+		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, PM_SINGLE_MAC,
+						request_id);
+		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,
+						PM_DBS_UPGRADE, request_id);
+		break;
+	case PM_SBS_DOWNGRADE:
+		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
+					PM_SBS, reason, session_id, request_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, PM_SBS,
+						request_id);
+		break;
+	case PM_DOWNGRADE:
+		/*
+		 * check if we have a beaconing entity that advertised 2x2
+		 * initially. 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, request_id);
+		break;
+	case PM_UPGRADE:
+		/*
+		 * check if we have a beaconing entity that advertised 2x2
+		 * initially. 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, request_id);
+		break;
+	case PM_DBS1_DOWNGRADE:
+		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
+			status = policy_mgr_complete_action(psoc,
+							    POLICY_MGR_RX_NSS_1,
+							    PM_DBS1, reason,
+							    session_id,
+							    request_id);
+		else
+			status = QDF_STATUS_E_ALREADY;
+		break;
+	case PM_DBS2_DOWNGRADE:
+		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
+			status = policy_mgr_complete_action(psoc,
+							    POLICY_MGR_RX_NSS_1,
+							    PM_DBS2, reason,
+							    session_id,
+							    request_id);
+		else
+			status = QDF_STATUS_E_ALREADY;
+		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 (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) {
+			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, PM_DBS1,
+					request_id);
+		} else {
+			status = QDF_STATUS_E_ALREADY;
+		}
+		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 (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) {
+			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, PM_DBS2,
+						request_id);
+		} else {
+			status = QDF_STATUS_E_ALREADY;
+		}
+		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, request_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, request_id);
+		break;
+	case PM_DOWNGRADE_BW:
+	case PM_UPGRADE_BW:
+		policy_mgr_sap_ch_width_update(psoc, action, reason,
+					       session_id, request_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 vdev_id, uint32_t ch_freq,
+				 enum policy_mgr_conn_update_reason reason,
+				 uint32_t request_id)
+{
+	QDF_STATUS status;
+	uint8_t num_cxn_del = 0;
+	struct policy_mgr_conc_connection_info info = {0};
+
+	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
+						      &info, &num_cxn_del);
+
+	if (!policy_mgr_check_for_session_conc(psoc, vdev_id, ch_freq)) {
+		policy_mgr_err("Conc not allowed for the vdev %d", vdev_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, vdev_id,
+						       ch_freq, reason,
+						       request_id);
+	if (QDF_STATUS_E_FAILURE == status)
+		policy_mgr_err("connections update failed");
+
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, &info,
+						     num_cxn_del);
+
+	return status;
+}
+
+enum policy_mgr_con_mode
+policy_mgr_con_mode_by_vdev_id(struct wlan_objmgr_psoc *psoc,
+			       uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
+	enum QDF_OPMODE op_mode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return mode;
+	}
+
+	op_mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+	return policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id);
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+qdf_freq_t
+policy_mgr_get_user_config_sap_freq(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	qdf_freq_t freq;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev is NULL");
+		return 0;
+	}
+	freq = wlan_get_sap_user_config_freq(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return freq;
+}
+
+/**
+ * policy_mgr_is_sap_go_existed() - Check if restart SAP/Go exist
+ * @psoc: PSOC object data
+ *
+ * To simplify, if SAP/P2P Go exist, they may need switch channel for
+ * forcing scc with sta or band capability change.
+ * Restart: true or false
+ */
+static bool policy_mgr_is_sap_go_existed(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t ap_present, go_present;
+
+	ap_present = policy_mgr_get_sap_mode_count(psoc, NULL);
+	if (ap_present)
+		return true;
+
+	go_present = policy_mgr_mode_specific_connection_count(
+				psoc, PM_P2P_GO_MODE, NULL);
+	if (go_present)
+		return true;
+
+	return false;
+}
+
+#ifdef FEATURE_WLAN_CH_AVOID_EXT
+bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
+				uint32_t ch_freq)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool is_safe = true;
+	uint8_t j;
+	unsigned long restriction_mask;
+
+	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)
+		return is_safe;
+
+	restriction_mask =
+		(unsigned long)policy_mgr_get_freq_restriction_mask(pm_ctx);
+	for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
+		if ((ch_freq == pm_ctx->unsafe_channel_list[j]) &&
+		    (qdf_test_bit(QDF_SAP_MODE, &restriction_mask) ||
+		     !wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
+								     psoc))) {
+			is_safe = false;
+			policy_mgr_warn("Freq %d is not safe, restriction mask %lu", ch_freq, restriction_mask);
+			break;
+		}
+	}
+
+	return is_safe;
+}
+
+bool policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	unsigned long restriction_mask;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return false;
+	}
+
+	restriction_mask =
+		(unsigned long)policy_mgr_get_freq_restriction_mask(pm_ctx);
+	return qdf_test_bit(QDF_SAP_MODE, &restriction_mask);
+}
+#else
+bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
+				uint32_t ch_freq)
+{
+	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)
+		return is_safe;
+
+	for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
+		if (ch_freq == pm_ctx->unsafe_channel_list[j]) {
+			is_safe = false;
+			policy_mgr_warn("Freq %d is not safe", ch_freq);
+			break;
+		}
+	}
+
+	return is_safe;
+}
+#endif
+
+bool policy_mgr_is_sap_freq_allowed(struct wlan_objmgr_psoc *psoc,
+				    enum QDF_OPMODE opmode,
+				    uint32_t sap_freq)
+{
+	uint32_t nan_2g_freq, nan_5g_freq;
+
+	/*
+	 * Ignore safe channel validation when the mode is P2P_GO and user
+	 * configures the corresponding bit in ini coex_unsafe_chan_nb_user_prefer.
+	 */
+	if ((opmode == QDF_P2P_GO_MODE &&
+	     wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_p2p_go(psoc)) ||
+	    policy_mgr_is_safe_channel(psoc, sap_freq))
+		return true;
+
+	/*
+	 * Return true if it's STA+SAP SCC and
+	 * STA+SAP SCC on LTE coex channel is allowed.
+	 */
+	if (policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) &&
+	    policy_mgr_is_sta_sap_scc(psoc, sap_freq)) {
+		policy_mgr_debug("unsafe freq %d for sap is allowed", sap_freq);
+		return true;
+	}
+
+	nan_2g_freq =
+		policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE);
+	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
+
+	if ((WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq) ||
+	     WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) &&
+	    policy_mgr_is_force_scc(psoc) &&
+	    policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc)) {
+		policy_mgr_debug("NAN+SAP SCC on unsafe freq %d is allowed",
+				  sap_freq);
+		return true;
+	}
+
+	return false;
+}
+
+bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t sap_vdev_id, uint32_t *intf_ch_freq,
+			bool is_acs_mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t curr_sap_freq = 0, new_sap_freq = 0;
+	bool sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+	bool sta_sap_scc_on_lte_coex_chan =
+		policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc);
+	uint8_t sta_sap_scc_on_dfs_chnl_config_value = 0;
+	uint32_t cc_count, i, go_index_start, pcl_len = 0;
+	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
+	enum policy_mgr_con_mode mode;
+	uint32_t pcl_channels[NUM_CHANNELS + 1];
+	uint8_t pcl_weight[NUM_CHANNELS + 1];
+	struct policy_mgr_conc_connection_info info = {0};
+	uint8_t num_cxn_del = 0;
+	QDF_STATUS status;
+	uint32_t sta_gc_present = 0;
+	qdf_freq_t user_config_freq = 0;
+	enum reg_wifi_band user_band, op_band;
+
+	if (intf_ch_freq)
+		*intf_ch_freq = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return false;
+	}
+
+	policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl_config_value);
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		if (policy_mgr_get_connection_count(psoc) > 1)
+			return false;
+
+	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
+							  &op_ch_freq_list[0],
+							  &vdev_id[0],
+							  PM_SAP_MODE);
+	go_index_start = cc_count;
+	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
+		cc_count += policy_mgr_get_mode_specific_conn_info(
+					psoc, &op_ch_freq_list[cc_count],
+					&vdev_id[cc_count], PM_P2P_GO_MODE);
+
+	sta_gc_present =
+		policy_mgr_mode_specific_connection_count(psoc,
+							  PM_STA_MODE, NULL) +
+		policy_mgr_mode_specific_connection_count(psoc,
+							  PM_P2P_CLIENT_MODE,
+							  NULL);
+
+	for (i = 0 ; i < cc_count; i++) {
+		if (sap_vdev_id != INVALID_VDEV_ID &&
+		    sap_vdev_id != vdev_id[i])
+			continue;
+
+		sap_vdev_id = vdev_id[i];
+		user_config_freq =
+			policy_mgr_get_user_config_sap_freq(psoc, sap_vdev_id);
+
+		if (policy_mgr_is_any_mode_active_on_band_along_with_session(
+				psoc,  vdev_id[i],
+				WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) ?
+				POLICY_MGR_BAND_24 : POLICY_MGR_BAND_5))
+			continue;
+
+		if (sta_sap_scc_on_dfs_chan &&
+		    (sta_sap_scc_on_dfs_chnl_config_value != 2) &&
+		     wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
+					      op_ch_freq_list[i]) &&
+		     pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) {
+			curr_sap_freq = op_ch_freq_list[i];
+			policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_sap_scc_on_dfs_chnl_config_value %u, dfs sap_ch_freq %u",
+					 sta_sap_scc_on_dfs_chan,
+					 sta_sap_scc_on_dfs_chnl_config_value,
+					 curr_sap_freq);
+			break;
+		}
+
+		if ((is_acs_mode ||
+		     policy_mgr_restrict_sap_on_unsafe_chan(psoc)) &&
+		    sta_sap_scc_on_lte_coex_chan &&
+		    !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[i]) &&
+		    pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) {
+			curr_sap_freq = op_ch_freq_list[i];
+			policy_mgr_debug("sta_sap_scc_on_lte_coex_chan %u unsafe sap_ch_freq %u",
+					 sta_sap_scc_on_lte_coex_chan,
+					 curr_sap_freq);
+			break;
+		}
+		/* When STA+SAP SCC is allowed on indoor channel,
+		 * Restart the SAP when :
+		 * 1. The user configured SAP frequency is not
+		 * the same as current freq. (or)
+		 * 2. The frequency is not allowed in the indoor
+		 * channel.
+		 */
+		if (pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i] &&
+		    !policy_mgr_is_sap_go_interface_allowed_on_indoor(
+							pm_ctx->pdev,
+							sap_vdev_id,
+							op_ch_freq_list[i])) {
+			curr_sap_freq = op_ch_freq_list[i];
+			policy_mgr_debug("indoor sap_ch_freq %u",
+					 curr_sap_freq);
+			break;
+		}
+
+		/*
+		 * STA got disconnected & SAP has previously moved to 2.4 GHz
+		 * due to concurrency, then move SAP back to user configured
+		 * frequency if the user configured band is better than
+		 * the current operating band.
+		 */
+		op_band = wlan_reg_freq_to_band(op_ch_freq_list[i]);
+		user_band = wlan_reg_freq_to_band(user_config_freq);
+
+		if (!sta_gc_present && user_config_freq &&
+		    op_band < user_band) {
+			curr_sap_freq = op_ch_freq_list[i];
+			policy_mgr_debug("Move sap to user configured freq: %d",
+					 user_config_freq);
+			break;
+		}
+	}
+
+	if (!curr_sap_freq) {
+		policy_mgr_debug("SAP restart is not required");
+		return false;
+	}
+
+	mode = i >= go_index_start ? PM_P2P_GO_MODE : PM_SAP_MODE;
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id,
+						      &info, &num_cxn_del);
+
+	/* Add the user config ch as first condidate */
+	pcl_channels[0] = user_config_freq;
+	pcl_weight[0] = 0;
+	status = policy_mgr_get_pcl(psoc, mode, &pcl_channels[1], &pcl_len,
+				    &pcl_weight[1],
+				    QDF_ARRAY_SIZE(pcl_weight) - 1,
+				    sap_vdev_id);
+	if (status == QDF_STATUS_SUCCESS)
+		pcl_len++;
+	else
+		pcl_len = 1;
+
+
+	for (i = 0; i < pcl_len; i++) {
+		if (pcl_channels[i] == curr_sap_freq)
+			continue;
+
+		if (!policy_mgr_is_safe_channel(psoc, pcl_channels[i]) ||
+		    wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i]))
+			continue;
+
+		/* SAP moved to 2.4 GHz, due to STA on DFS or Indoor where
+		 * concurrency is not allowed, now that there is no
+		 * STA/GC in 5 GHz band, move 2.4 GHz SAP to 5 GHz band if SAP
+		 * was initially started on 5 GHz band.
+		 * Checking again here as pcl_channels[0] could be
+		 * on indoor which is not removed in policy_mgr_get_pcl
+		 */
+		if (!sta_gc_present &&
+		    !policy_mgr_is_sap_go_interface_allowed_on_indoor(
+							pm_ctx->pdev,
+							sap_vdev_id,
+							pcl_channels[i])) {
+			policy_mgr_debug("Do not allow SAP on indoor frequency, STA is absent");
+			continue;
+		}
+
+		new_sap_freq = pcl_channels[i];
+		break;
+	}
+
+	/* Restore the connection entry */
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (new_sap_freq == 0 || curr_sap_freq == new_sap_freq)
+		return false;
+	if (!intf_ch_freq)
+		return true;
+
+	*intf_ch_freq = new_sap_freq;
+	policy_mgr_debug("Standalone SAP(vdev_id %d) will be moved to channel %u",
+			 sap_vdev_id, *intf_ch_freq);
+
+	return true;
+}
+
+/**
+ * policy_mgr_is_nan_sap_unsafe_ch_scc_allowed() - Check if NAN+SAP SCC is
+ *                                               allowed in LTE COEX unsafe ch
+ * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context
+ * @ch_freq: Channel frequency to check
+ *
+ * Return: True if allowed else false
+ */
+static bool
+policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(struct policy_mgr_psoc_priv_obj
+					    *pm_ctx, uint32_t ch_freq)
+{
+	if (policy_mgr_is_safe_channel(pm_ctx->psoc, ch_freq) ||
+	    pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl)
+		return true;
+
+	return false;
+}
+
+/**
+ * policy_mgr_nan_disable_work() - qdf defer function wrapper for NAN disable
+ * @data: qdf_work data
+ *
+ * Return: None
+ */
+static void policy_mgr_nan_disable_work(void *data)
+{
+	struct wlan_objmgr_psoc *psoc = data;
+
+	ucfg_nan_disable_concurrency(psoc);
+}
+
+bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc,
+					     uint32_t sap_freq)
+{
+	uint32_t nan_2g_freq, nan_5g_freq;
+	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;
+	}
+
+	nan_2g_freq = policy_mgr_mode_specific_get_channel(psoc,
+							   PM_NAN_DISC_MODE);
+	if (nan_2g_freq == 0) {
+		policy_mgr_debug("No NAN+SAP SCC");
+		return false;
+	}
+	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
+
+	policy_mgr_debug("Freq SAP: %d NAN: %d %d", sap_freq,
+			 nan_2g_freq, nan_5g_freq);
+	if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq)) {
+		if (policy_mgr_is_force_scc(pm_ctx->psoc) &&
+		    policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx,
+								nan_2g_freq))
+			return true;
+	} else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) {
+		if (policy_mgr_is_force_scc(pm_ctx->psoc) &&
+		    policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx,
+								nan_5g_freq))
+			return true;
+	} else {
+		/*
+		 * NAN + SAP in different bands. Continue to check for
+		 * SAP in unsafe channel
+		 */
+		return false;
+	}
+	policy_mgr_info("NAN+SAP unsafe ch SCC not allowed. Disabling NAN");
+	/* change context to worker since this is executed in sched thread ctx*/
+	qdf_create_work(0, &pm_ctx->nan_sap_conc_work,
+			policy_mgr_nan_disable_work, psoc);
+	qdf_sched_work(0, &pm_ctx->nan_sap_conc_work);
+
+	return false;
+}
+
+bool
+policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc,
+					 enum policy_mgr_con_mode mode,
+					 uint32_t ch_freq)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t sap_freq, nan_2g_freq, nan_5g_freq;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	if (!policy_mgr_is_sap_mode(mode) || mode == PM_NAN_DISC_MODE) {
+		policy_mgr_debug("Not NAN or SAP mode");
+		return true;
+	}
+
+	if (!ch_freq) {
+		policy_mgr_err("Invalid channel");
+		return false;
+	}
+
+	if (!wlan_nan_get_sap_conc_support(pm_ctx->psoc)) {
+		policy_mgr_debug("NAN+SAP not supported in fw");
+		/* Reject NAN as SAP is of high priority */
+		if (mode == PM_NAN_DISC_MODE)
+			return false;
+		/* Before SAP start disable NAN */
+		ucfg_nan_disable_concurrency(pm_ctx->psoc);
+		return true;
+	}
+
+	if (mode == PM_NAN_DISC_MODE) {
+		sap_freq = policy_mgr_mode_specific_get_channel(pm_ctx->psoc,
+								PM_SAP_MODE);
+		policy_mgr_debug("FREQ SAP: %d NAN: %d", sap_freq, ch_freq);
+		if (!sap_freq) {
+			sap_freq = policy_mgr_mode_specific_get_channel(
+							pm_ctx->psoc,
+							PM_LL_LT_SAP_MODE);
+			policy_mgr_debug("FREQ LL_LT_SAP: %d NAN: %d",
+					 sap_freq, ch_freq);
+		}
+		if (ucfg_is_nan_dbs_supported(pm_ctx->psoc) &&
+		    !WLAN_REG_IS_SAME_BAND_FREQS(sap_freq, ch_freq))
+			return true;
+
+		if (sap_freq == ch_freq) {
+			policy_mgr_debug("NAN+SAP SCC");
+			return true;
+		}
+
+		if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
+			policy_mgr_debug("SAP force SCC disabled");
+			return false;
+		}
+		if (!policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
+						pm_ctx, ch_freq)) {
+			policy_mgr_debug("NAN+SAP unsafe ch SCC disabled");
+			return false;
+		}
+		if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
+		    pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) {
+			policy_mgr_debug("DFS CAC in progress, reject NAN enable");
+			return false;
+		}
+	} else if (policy_mgr_is_sap_mode(mode)) {
+		nan_2g_freq =
+			policy_mgr_mode_specific_get_channel(pm_ctx->psoc,
+							     PM_NAN_DISC_MODE);
+		nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc);
+		policy_mgr_debug("SAP CH: %d NAN Ch: %d %d", ch_freq,
+				 nan_2g_freq, nan_5g_freq);
+		if (ucfg_is_nan_conc_control_supported(pm_ctx->psoc) &&
+		    !ucfg_is_nan_dbs_supported(pm_ctx->psoc) &&
+		    !WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq)) {
+			if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
+				policy_mgr_debug("NAN and SAP are in different bands but SAP force SCC disabled");
+				ucfg_nan_disable_concurrency(pm_ctx->psoc);
+				return true;
+			}
+		} else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) ||
+			   WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)) {
+			if (ch_freq == nan_2g_freq || ch_freq == nan_5g_freq) {
+				policy_mgr_debug("NAN+SAP SCC");
+				return true;
+			}
+			if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
+				policy_mgr_debug("SAP force SCC disabled");
+				ucfg_nan_disable_concurrency(pm_ctx->psoc);
+				return true;
+			}
+			if ((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
+			     !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
+			     pm_ctx, nan_5g_freq)) ||
+			    (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) &&
+			     !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
+			     pm_ctx, nan_2g_freq))) {
+				policy_mgr_debug("NAN+SAP unsafe ch SCC disabled");
+				ucfg_nan_disable_concurrency(pm_ctx->psoc);
+				return true;
+			}
+		}
+	}
+	return true;
+}
+
+QDF_STATUS
+policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_conc_connection_info *sap_info = NULL;
+	uint8_t i;
+	qdf_freq_t nan_freq_2g, nan_freq_5g;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if (policy_mgr_is_sap_mode(pm_conc_connection_list[i].mode) &&
+		    pm_conc_connection_list[i].in_use) {
+			sap_info = &pm_conc_connection_list[i];
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (!sap_info)
+		goto end;
+	if (sap_info->freq == 0)
+		goto end;
+	nan_freq_2g = policy_mgr_mode_specific_get_channel(psoc,
+							   PM_NAN_DISC_MODE);
+	nan_freq_5g = wlan_nan_get_disc_5g_ch_freq(psoc);
+	if (sap_info->freq == nan_freq_2g || sap_info->freq == nan_freq_5g) {
+		policy_mgr_debug("NAN and SAP already in SCC");
+		goto end;
+	}
+	if (nan_freq_2g == 0)
+		goto end;
+
+	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
+		policy_mgr_debug("channel switch is already in progress");
+		return status;
+	}
+
+	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
+		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc,
+					sap_info->vdev_id,
+					CSA_REASON_CONCURRENT_NAN_EVENT);
+
+	/* SAP should be moved to 2g NAN channel on non-DBS platforms */
+	if (!ucfg_is_nan_dbs_supported(pm_ctx->psoc) ||
+	    WLAN_REG_IS_24GHZ_CH_FREQ(sap_info->freq)) {
+		policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d",
+				 nan_freq_2g);
+		status =
+		policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
+						       nan_freq_2g,
+						       policy_mgr_get_ch_width(
+						       sap_info->bw),
+						       true);
+		if (status == QDF_STATUS_SUCCESS)
+			status = QDF_STATUS_E_PENDING;
+	} else if (nan_freq_5g && WLAN_REG_IS_5GHZ_CH_FREQ(sap_info->freq)) {
+		policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d",
+				 nan_freq_5g);
+		status =
+		policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
+						       nan_freq_5g,
+						       policy_mgr_get_ch_width(
+						       sap_info->bw),
+						       true);
+		if (status == QDF_STATUS_SUCCESS)
+			status = QDF_STATUS_E_PENDING;
+	}
+
+end:
+	pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = false;
+
+	return status;
+}
+
+void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_conc_connection_info *sap_info = NULL;
+	uint32_t sap_freq = 0, i;
+	QDF_STATUS status;
+	uint32_t user_config_freq;
+	uint8_t band_mask = 0;
+	uint8_t chn_idx, num_chan;
+	struct regulatory_channel *channel_list;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return;
+	}
+
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if (pm_conc_connection_list[i].mode == PM_SAP_MODE &&
+		    pm_conc_connection_list[i].in_use) {
+			sap_info = &pm_conc_connection_list[i];
+			sap_freq = sap_info->freq;
+			break;
+		}
+	}
+	if (sap_freq == 0 || policy_mgr_is_safe_channel(psoc, sap_freq))
+		return;
+
+	user_config_freq = policy_mgr_get_user_config_sap_freq(
+						psoc, sap_info->vdev_id);
+
+	sap_freq = policy_mgr_get_nondfs_preferred_channel(psoc, PM_SAP_MODE,
+							   false,
+							   sap_info->vdev_id);
+	policy_mgr_debug("User/ACS orig Freq: %d New SAP Freq: %d",
+			 user_config_freq, sap_freq);
+
+	if (wlan_reg_is_enable_in_secondary_list_for_freq(pm_ctx->pdev,
+							  user_config_freq) &&
+	    policy_mgr_is_safe_channel(psoc, user_config_freq)) {
+		policy_mgr_debug("Give preference to user config freq");
+		sap_freq = user_config_freq;
+	} else {
+		channel_list = qdf_mem_malloc(
+					sizeof(struct regulatory_channel) *
+					       NUM_CHANNELS);
+		if (!channel_list)
+			return;
+
+		band_mask |= BIT(wlan_reg_freq_to_band(user_config_freq));
+		num_chan = wlan_reg_get_band_channel_list_for_pwrmode(
+						pm_ctx->pdev,
+						band_mask,
+						channel_list,
+						REG_CURRENT_PWR_MODE);
+		for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
+			if (wlan_reg_is_enable_in_secondary_list_for_freq(
+					pm_ctx->pdev,
+					channel_list[chn_idx].center_freq) &&
+			    policy_mgr_is_safe_channel(
+					psoc,
+					channel_list[chn_idx].center_freq)) {
+				policy_mgr_debug("Prefer user config band freq %d",
+						 channel_list[chn_idx].center_freq);
+				sap_freq = channel_list[chn_idx].center_freq;
+			}
+		}
+		qdf_mem_free(channel_list);
+	}
+
+	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
+		policy_mgr_debug("wait as 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_ERROR(status))
+			policy_mgr_err("wait for event failed, still continue with channel switch");
+	}
+
+	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
+		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
+				psoc, sap_info->vdev_id,
+				CSA_REASON_CONCURRENT_NAN_EVENT);
+
+	policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
+					       sap_freq,
+					       policy_mgr_get_ch_width(
+					       sap_info->bw), true);
+}
+
+void policy_mgr_check_sap_restart(struct wlan_objmgr_psoc *psoc,
+				  uint8_t vdev_id)
+{
+	QDF_STATUS status;
+	uint32_t ch_freq;
+	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
+
+	if (!psoc) {
+		policy_mgr_err("Invalid psoc");
+		return;
+	}
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+
+	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
+		policy_mgr_debug("channel switch is already in progress");
+		return;
+	}
+
+	/*
+	 * Restart should be handled by sap_fsm_validate_and_change_channel(),
+	 * after SAP starts.
+	 */
+	if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) {
+		policy_mgr_debug("DFS CAC in progress, do not restart SAP");
+		return;
+	}
+
+	if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
+		policy_mgr_err("SAP restart get channel callback in NULL");
+		goto end;
+	}
+	status =
+		pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart(psoc,
+								      vdev_id,
+								      &ch_freq);
+	if (status == QDF_STATUS_SUCCESS)
+		policy_mgr_debug("SAP vdev id %d switch to new ch freq: %d",
+				 vdev_id, ch_freq);
+
+end:
+	pm_ctx->last_disconn_sta_freq = 0;
+}
+
+/**
+ * policy_mgr_handle_sap_plus_go_force_scc() - Do SAP/GO force SCC
+ * @psoc: soc object
+ *
+ * This function will check SAP/GO channel state and select channel
+ * to avoid MCC, then do channel change on the second interface.
+ *
+ * Return: QDF_STATUS_SUCCESS if successfully handle the SAP/GO
+ * force SCC.
+ */
+static QDF_STATUS
+policy_mgr_handle_sap_plus_go_force_scc(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
+	enum policy_mgr_con_mode vdev_con_mode;
+	uint32_t existing_ch_freq, chan_freq, intf_ch_freq;
+	enum phy_ch_width existing_ch_width;
+	uint8_t vdev_id;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct sta_ap_intf_check_work_ctx *work_info;
+	struct ch_params ch_params = {0};
+	enum QDF_OPMODE opmode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	work_info = pm_ctx->sta_ap_intf_check_work_info;
+	if (!work_info) {
+		policy_mgr_err("invalid work info");
+		return status;
+	}
+	if (work_info->sap_plus_go_force_scc.reason == CSA_REASON_UNKNOWN)
+		return status;
+
+	vdev_id = work_info->sap_plus_go_force_scc.initiator_vdev_id;
+	chan_freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id);
+	opmode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+	vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode,
+							     vdev_id);
+
+	existing_vdev_id =
+		policy_mgr_fetch_existing_con_info(
+				psoc,
+				vdev_id,
+				chan_freq,
+				&existing_vdev_mode,
+				&existing_ch_freq, &existing_ch_width);
+	policy_mgr_debug("initiator vdev %d mode %d freq %d, existing vdev %d mode %d freq %d reason %d",
+			 vdev_id, vdev_con_mode, chan_freq, existing_vdev_id,
+			 existing_vdev_mode, existing_ch_freq,
+			 work_info->sap_plus_go_force_scc.reason);
+
+	if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
+		goto force_scc_done;
+
+	if (!((vdev_con_mode == PM_P2P_GO_MODE &&
+	       existing_vdev_mode == PM_SAP_MODE) ||
+	      (vdev_con_mode == PM_SAP_MODE &&
+	       existing_vdev_mode == PM_P2P_GO_MODE)))
+		goto force_scc_done;
+
+	if (!pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb)
+		goto force_scc_done;
+
+	intf_ch_freq = 0;
+	status = pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb(psoc,
+							  existing_vdev_id,
+							  &intf_ch_freq);
+	policy_mgr_debug("vdev %d freq %d intf %d status %d",
+			 existing_vdev_id, existing_ch_freq,
+			 intf_ch_freq, status);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto force_scc_done;
+	if (!intf_ch_freq || intf_ch_freq == existing_ch_freq)
+		goto force_scc_done;
+
+	ch_params.ch_width = existing_ch_width;
+	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) {
+		status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
+			psoc, existing_vdev_id, intf_ch_freq, &ch_params);
+		if (QDF_IS_STATUS_ERROR(status))
+			policy_mgr_debug("no candidate valid bw for vdev %d intf %d",
+					 existing_vdev_id, intf_ch_freq);
+	}
+
+	status = policy_mgr_valid_sap_conc_channel_check(
+		    psoc, &intf_ch_freq, existing_ch_freq, existing_vdev_id,
+		    &ch_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("warning no candidate freq for vdev %d freq %d intf %d",
+			       existing_vdev_id, existing_ch_freq,
+			       intf_ch_freq);
+		goto force_scc_done;
+	}
+
+	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
+		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
+				psoc, existing_vdev_id,
+				work_info->sap_plus_go_force_scc.reason);
+
+	status = policy_mgr_change_sap_channel_with_csa(
+			psoc, existing_vdev_id, intf_ch_freq,
+			ch_params.ch_width, true);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("warning sap/go vdev %d freq %d intf %d csa failed",
+			       existing_vdev_id, existing_ch_freq,
+			       intf_ch_freq);
+	}
+
+force_scc_done:
+	work_info->sap_plus_go_force_scc.reason = CSA_REASON_UNKNOWN;
+	work_info->sap_plus_go_force_scc.initiator_vdev_id =
+					WLAN_UMAC_VDEV_ID_MAX;
+	work_info->sap_plus_go_force_scc.responder_vdev_id =
+					WLAN_UMAC_VDEV_ID_MAX;
+
+	return status;
+}
+
+QDF_STATUS
+policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_objmgr_vdev *vdev,
+				  enum sap_csa_reason_code reason_code)
+{
+	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
+	enum policy_mgr_con_mode vdev_con_mode;
+	uint32_t con_freq, chan_freq;
+	enum phy_ch_width ch_width;
+	uint8_t vdev_id;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct sta_ap_intf_check_work_ctx *work_info;
+	enum QDF_OPMODE opmode;
+
+	if (reason_code != CSA_REASON_GO_BSS_STARTED &&
+	    reason_code != CSA_REASON_USER_INITIATED)
+		return QDF_STATUS_SUCCESS;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+	if (pm_ctx->cfg.mcc_to_scc_switch ==
+		QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)
+		return QDF_STATUS_SUCCESS;
+
+	if (!vdev) {
+		policy_mgr_err("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	vdev_id = wlan_vdev_get_id(vdev);
+	opmode = wlan_vdev_mlme_get_opmode(vdev);
+	work_info = pm_ctx->sta_ap_intf_check_work_info;
+	if (!work_info) {
+		policy_mgr_err("invalid work info");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	chan_freq = wlan_get_operation_chan_freq(vdev);
+	vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode,
+							     vdev_id);
+
+	existing_vdev_id =
+		policy_mgr_fetch_existing_con_info(psoc,
+						   vdev_id,
+						   chan_freq,
+						   &existing_vdev_mode,
+						   &con_freq, &ch_width);
+	if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
+		return QDF_STATUS_SUCCESS;
+
+	if (!((vdev_con_mode == PM_P2P_GO_MODE &&
+	       existing_vdev_mode == PM_SAP_MODE) ||
+	      (vdev_con_mode == PM_SAP_MODE &&
+	       existing_vdev_mode == PM_P2P_GO_MODE)))
+		return QDF_STATUS_SUCCESS;
+
+	work_info->sap_plus_go_force_scc.reason = reason_code;
+	work_info->sap_plus_go_force_scc.initiator_vdev_id = vdev_id;
+	work_info->sap_plus_go_force_scc.responder_vdev_id = existing_vdev_id;
+
+	policy_mgr_debug("initiator vdev %d freq %d, existing vdev %d freq %d reason %d",
+			 vdev_id, chan_freq, existing_vdev_id,
+			 con_freq, reason_code);
+
+	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
+				    WAIT_BEFORE_GO_FORCESCC_RESTART))
+		policy_mgr_debug("change interface request already queued");
+
+	return QDF_STATUS_E_PENDING;
+}
+
+/**
+ * policy_mgr_is_any_conn_in_transition() - Check if any STA/CLI
+ * connection is disconnecting or roaming state
+ * @psoc: PSOC object information
+ *
+ * This function will check connection table and find any STA/CLI
+ * in transition state such as disconnecting, link switch or roaming.
+ *
+ * Return: true if there is one STA/CLI in transition state.
+ */
+static bool
+policy_mgr_is_any_conn_in_transition(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i;
+	struct policy_mgr_conc_connection_info *conn_info;
+	struct wlan_objmgr_vdev *vdev;
+	bool non_connected = false;
+	bool in_link_switch = false;
+	uint8_t vdev_id;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return false;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		conn_info = &pm_conc_connection_list[i];
+		if (!(conn_info->in_use &&
+		      (conn_info->mode == PM_STA_MODE ||
+		       conn_info->mode == PM_P2P_CLIENT_MODE)))
+			continue;
+		vdev_id = conn_info->vdev_id;
+		vdev = wlan_objmgr_get_vdev_by_id_from_pdev(
+				pm_ctx->pdev, vdev_id, WLAN_POLICY_MGR_ID);
+		if (!vdev) {
+			policy_mgr_err("vdev %d: not found", vdev_id);
+			continue;
+		}
+
+		non_connected = !wlan_cm_is_vdev_connected(vdev);
+
+		if (mlo_is_mld_sta(vdev) &&
+		    mlo_mgr_is_link_switch_in_progress(vdev))
+			in_link_switch = true;
+
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		if (non_connected) {
+			policy_mgr_debug("vdev %d: is in transition state",
+					 vdev_id);
+			break;
+		}
+		if (in_link_switch) {
+			policy_mgr_debug("vdev %d: sta mld is in link switch state",
+					 vdev_id);
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return non_connected || in_link_switch;
+}
+
+static void __policy_mgr_check_sta_ap_concurrent_ch_intf(
+				struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	uint32_t mcc_to_scc_switch, cc_count = 0, i;
+	QDF_STATUS status;
+	uint32_t ch_freq;
+	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	struct sta_ap_intf_check_work_ctx *work_info;
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+	work_info = pm_ctx->sta_ap_intf_check_work_info;
+
+	if (work_info->nan_force_scc_in_progress) {
+		policy_mgr_nan_sap_post_enable_conc_check(pm_ctx->psoc);
+		return;
+	}
+	/*
+	 * Check if force scc is required for GO + GO case. vdev id will be
+	 * valid in case of GO+GO force scc only. So, for valid vdev id move
+	 * first GO to newly formed GO channel.
+	 */
+	policy_mgr_debug("p2p go vdev id: %d csa reason: %d",
+			 work_info->go_plus_go_force_scc.vdev_id,
+			 work_info->sap_plus_go_force_scc.reason);
+	if (pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id <
+	    WLAN_UMAC_VDEV_ID_MAX) {
+		policy_mgr_do_go_plus_go_force_scc(
+			pm_ctx->psoc, work_info->go_plus_go_force_scc.vdev_id,
+			work_info->go_plus_go_force_scc.ch_freq,
+			work_info->go_plus_go_force_scc.ch_width);
+		work_info->go_plus_go_force_scc.vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+		goto end;
+	}
+	/*
+	 * Check if force scc is required for GO + SAP case.
+	 */
+	if (pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason !=
+	    CSA_REASON_UNKNOWN) {
+		status = policy_mgr_handle_sap_plus_go_force_scc(pm_ctx->psoc);
+		goto end;
+	}
+
+	mcc_to_scc_switch =
+		policy_mgr_get_mcc_to_scc_switch_mode(pm_ctx->psoc);
+
+	policy_mgr_debug("Concurrent open sessions running: %d",
+			 policy_mgr_concurrent_open_sessions_running(pm_ctx->psoc));
+
+	if (!policy_mgr_is_sap_go_existed(pm_ctx->psoc))
+		goto end;
+
+	cc_count = policy_mgr_get_sap_mode_info(pm_ctx->psoc,
+						&op_ch_freq_list[cc_count],
+						&vdev_id[cc_count]);
+
+	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(
+					pm_ctx->psoc, &op_ch_freq_list[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;
+	}
+
+	/* When any STA/CLI is transition state, such as roaming or
+	 * disconnecting, skip force scc for this time.
+	 */
+	if (policy_mgr_is_any_conn_in_transition(pm_ctx->psoc)) {
+		policy_mgr_debug("defer sap conc check to a later time due to another sta/cli dicon/roam pending");
+		qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
+				       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
+		goto end;
+	}
+
+	if (policy_mgr_is_ap_start_in_progress(pm_ctx->psoc)) {
+		policy_mgr_debug("defer sap conc check to a later time due to another sap/go start pending");
+		qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
+				       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
+		goto end;
+	}
+	if (policy_mgr_is_set_link_in_progress(pm_ctx->psoc)) {
+		policy_mgr_debug("defer sap conc check to a later time due to ml sta set link in progress");
+		qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
+				       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
+		goto end;
+	}
+
+	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
+		policy_mgr_debug("wait as 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_ERROR(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
+					(pm_ctx->psoc, vdev_id[i], &ch_freq);
+			if (status == QDF_STATUS_SUCCESS) {
+				policy_mgr_debug("SAP vdev id %d restarts, old ch freq :%d new ch freq: %d",
+						 vdev_id[i],
+						 op_ch_freq_list[i], ch_freq);
+				break;
+			}
+		}
+
+end:
+	pm_ctx->last_disconn_sta_freq = 0;
+}
+
+void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
+{
+	struct qdf_op_sync *op_sync;
+	struct policy_mgr_psoc_priv_obj *pm_ctx = data;
+	int ret;
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+
+	ret = qdf_op_protect(&op_sync);
+	if (ret) {
+		if (ret == -EAGAIN) {
+			if (qdf_is_driver_unloading() ||
+			    qdf_is_recovering() ||
+			    qdf_is_driver_state_module_stop()) {
+				policy_mgr_debug("driver not ready");
+				return;
+			}
+
+			if (!pm_ctx->sta_ap_intf_check_work_info)
+				return;
+
+			pm_ctx->work_fail_count++;
+			policy_mgr_debug("qdf_op start fail, ret %d, work_fail_count %d",
+					 ret, pm_ctx->work_fail_count);
+			if (pm_ctx->work_fail_count > 1) {
+				pm_ctx->work_fail_count = 0;
+				return;
+			}
+			qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
+					       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
+		}
+		return;
+	}
+	pm_ctx->work_fail_count = 0;
+	__policy_mgr_check_sta_ap_concurrent_ch_intf(data);
+
+	qdf_op_unprotect(op_sync);
+}
+
+static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
+						uint32_t sta_ch_freq)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel;
+
+	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);
+	if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) &&
+	    sta_sap_scc_on_dfs_chan) {
+		policy_mgr_debug("STA, SAP SCC is allowed on DFS chan %u",
+				 sta_ch_freq);
+		return true;
+	}
+
+	sta_sap_scc_on_indoor_channel =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+	if (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) &&
+	    sta_sap_scc_on_indoor_channel) {
+		policy_mgr_debug("STA, SAP SCC is allowed on indoor chan %u",
+				 sta_ch_freq);
+		return true;
+	}
+
+	if ((wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) &&
+	     !sta_sap_scc_on_dfs_chan) ||
+	    wlan_reg_is_passive_or_disable_for_pwrmode(
+	    pm_ctx->pdev, sta_ch_freq, REG_CURRENT_PWR_MODE) ||
+	    (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) &&
+	     !sta_sap_scc_on_indoor_channel) ||
+	    (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) &&
+	     !policy_mgr_is_safe_channel(psoc, sta_ch_freq))) {
+		if (policy_mgr_is_hw_dbs_capable(psoc))
+			return true;
+		else
+			return false;
+	}
+	else
+		return true;
+}
+
+static bool policy_mgr_get_srd_enable_for_vdev(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	enum QDF_OPMODE vdev_opmode;
+	bool enable_srd_channel = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev is NULL");
+		return false;
+	}
+
+	vdev_opmode = wlan_vdev_mlme_get_opmode(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	wlan_mlme_get_srd_master_mode_for_vdev(psoc, vdev_opmode,
+					       &enable_srd_channel);
+	return enable_srd_channel;
+}
+
+QDF_STATUS
+policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc *psoc,
+					uint32_t *con_ch_freq,
+					uint32_t sap_ch_freq,
+					uint8_t sap_vdev_id,
+					struct ch_params *ch_params)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t ch_freq = *con_ch_freq;
+	bool find_alternate = false;
+	enum phy_ch_width old_ch_width;
+	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel;
+	bool is_dfs;
+	bool is_6ghz_cap;
+	bool is_sta_sap_scc;
+	enum policy_mgr_con_mode con_mode;
+	uint32_t nan_2g_freq, nan_5g_freq;
+
+	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, it could be STA/SAP SCC,
+	 * check further if SAP can start on STA home channel or
+	 * select other band channel if not.
+	 */
+	if (!ch_freq) {
+		if (!policy_mgr_any_other_vdev_on_same_mac_as_freq(psoc,
+								   sap_ch_freq,
+								   sap_vdev_id))
+			return QDF_STATUS_SUCCESS;
+
+		ch_freq = sap_ch_freq;
+	}
+
+	if (!ch_freq)
+		return QDF_STATUS_SUCCESS;
+
+	con_mode = policy_mgr_con_mode_by_vdev_id(psoc, sap_vdev_id);
+
+	is_sta_sap_scc = policy_mgr_is_sta_sap_scc(psoc, ch_freq);
+
+	nan_2g_freq =
+		policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE);
+	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
+
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+
+	sta_sap_scc_on_indoor_channel =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+	old_ch_width = ch_params->ch_width;
+	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
+		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
+			psoc, sap_vdev_id, ch_freq, ch_params);
+
+	is_dfs = wlan_mlme_check_chan_param_has_dfs(
+			pm_ctx->pdev, ch_params, ch_freq);
+	is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL);
+
+	if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && is_dfs &&
+	    !sta_sap_scc_on_dfs_chan && is_sta_sap_scc) {
+		find_alternate = true;
+		policymgr_nofl_debug("sap not capable of DFS SCC on con ch_freq %d",
+				     ch_freq);
+	} else if (wlan_reg_is_disable_for_pwrmode(pm_ctx->pdev, ch_freq,
+						   REG_CURRENT_PWR_MODE)) {
+		find_alternate = true;
+		policymgr_nofl_debug("sap not capable on disabled con ch_freq %d",
+				     ch_freq);
+	} else if (con_mode == PM_P2P_GO_MODE &&
+		   wlan_reg_is_passive_or_disable_for_pwrmode(
+						pm_ctx->pdev,
+						ch_freq,
+						REG_CURRENT_PWR_MODE) &&
+		   !(policy_mgr_is_go_scc_strict(psoc) &&
+		     (!is_sta_sap_scc || sta_sap_scc_on_dfs_chan))) {
+		find_alternate = true;
+		policymgr_nofl_debug("Go not capable on dfs/disabled con ch_freq %d",
+				     ch_freq);
+	} else if (!policy_mgr_is_safe_channel(psoc, ch_freq) &&
+		   !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) &&
+		     is_sta_sap_scc) &&
+		   !(policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc) &&
+		    (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) ||
+		     WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)))) {
+		find_alternate = true;
+		policymgr_nofl_debug("sap not capable unsafe con ch_freq %d",
+				     ch_freq);
+	} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) &&
+		   !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) &&
+		   !is_6ghz_cap) {
+		policymgr_nofl_debug("sap not capable on 6GHZ con ch_freq %d",
+				     ch_freq);
+		find_alternate = true;
+	} else if (wlan_reg_is_etsi_srd_chan_for_freq(pm_ctx->pdev,
+						      ch_freq) &&
+		   !policy_mgr_get_srd_enable_for_vdev(psoc, sap_vdev_id)) {
+		find_alternate = true;
+		policymgr_nofl_debug("sap not capable on SRD con ch_freq %d",
+				     ch_freq);
+	} else if (!policy_mgr_is_sap_go_interface_allowed_on_indoor(
+							pm_ctx->pdev,
+							sap_vdev_id, ch_freq)) {
+		policymgr_nofl_debug("sap not capable on indoor con ch_freq %d is_sta_sap_scc:%d",
+				     ch_freq, is_sta_sap_scc);
+		find_alternate = true;
+	}
+
+	if (find_alternate) {
+		if (policy_mgr_is_hw_dbs_capable(psoc)) {
+			ch_freq = policy_mgr_get_alternate_channel_for_sap(
+						psoc, sap_vdev_id, sap_ch_freq,
+						REG_BAND_UNKNOWN);
+			policymgr_nofl_debug("selected alternate ch %d",
+					     ch_freq);
+			if (!ch_freq) {
+				policymgr_nofl_debug("Sap can't have concurrency on %d in dbs hw",
+						     *con_ch_freq);
+				return QDF_STATUS_E_FAILURE;
+			}
+		} else {
+			/* MCC not supported for non-DBS chip*/
+			ch_freq = 0;
+			if (con_mode == PM_SAP_MODE) {
+				policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d SAP freq %d not supported",
+						     *con_ch_freq, sap_ch_freq);
+				return QDF_STATUS_E_FAILURE;
+			} else {
+				policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d GO freq %d SCC not supported",
+						     *con_ch_freq, sap_ch_freq);
+			}
+		}
+	}
+
+	if (ch_freq != sap_ch_freq || old_ch_width != ch_params->ch_width) {
+		*con_ch_freq = ch_freq;
+		policymgr_nofl_debug("sap conc result con freq %d bw %d org freq %d bw %d",
+				     ch_freq, ch_params->ch_width, sap_ch_freq,
+				     old_ch_width);
+	}
+
+	if (*con_ch_freq &&
+	    pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
+		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
+			psoc, sap_vdev_id, ch_freq, ch_params);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_check_concurrent_intf_and_restart_sap(
+		struct wlan_objmgr_psoc *psoc, bool is_acs_mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t mcc_to_scc_switch;
+	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint32_t cc_count = 0;
+	uint32_t timeout_ms = 0;
+	bool restart_sap = false;
+	uint32_t sap_freq;
+	/*
+	 * if no sta, sap/p2p go may need switch channel for band
+	 * capability change.
+	 * If sta exist, sap/p2p go may need switch channel to force scc
+	 */
+	bool sta_check = false, gc_check = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+	if (!pm_ctx->sta_ap_intf_check_work_info) {
+		policy_mgr_err("Invalid sta_ap_intf_check_work_info");
+		return;
+	}
+	if (!policy_mgr_is_sap_go_existed(psoc)) {
+		policy_mgr_debug(
+			"No action taken at check_concurrent_intf_and_restart_sap");
+		return;
+	}
+
+	if (policy_mgr_is_ll_lt_sap_restart_required(psoc)) {
+		restart_sap = true;
+		goto sap_restart;
+	}
+
+	/*
+	 * 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, INVALID_VDEV_ID, &sap_freq, is_acs_mode)) {
+		policy_mgr_debug("move the SAP to configured channel %u",
+				 sap_freq);
+		restart_sap = true;
+		goto sap_restart;
+	}
+
+	/*
+	 * This is to check the cases where STA got disconnected or
+	 * sta is present on some valid channel where SAP evaluation/restart
+	 * might be needed.
+	 * force SCC with STA+STA+SAP will need some additional logic
+	 */
+	cc_count = policy_mgr_get_mode_specific_conn_info(
+				psoc, &op_ch_freq_list[cc_count],
+				&vdev_id[cc_count], PM_STA_MODE);
+
+	sta_check = !cc_count ||
+		    policy_mgr_valid_sta_channel_check(psoc, op_ch_freq_list[0]);
+
+	cc_count = 0;
+	cc_count = policy_mgr_get_mode_specific_conn_info(
+				psoc, &op_ch_freq_list[cc_count],
+				&vdev_id[cc_count], PM_P2P_CLIENT_MODE);
+
+	gc_check = !!cc_count;
+
+	mcc_to_scc_switch =
+		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
+	policy_mgr_debug("MCC to SCC switch: %d chan: %d sta_check: %d, gc_check: %d",
+			 mcc_to_scc_switch, op_ch_freq_list[0],
+			 sta_check, gc_check);
+
+	cc_count = 0;
+	cc_count = policy_mgr_get_mode_specific_conn_info(
+				psoc, &op_ch_freq_list[cc_count],
+				&vdev_id[cc_count], PM_SAP_MODE);
+
+	/* SAP + SAP case needs additional handling */
+	if (cc_count == 1 && !is_acs_mode &&
+	    target_psoc_get_sap_coex_fixed_chan_cap(
+			wlan_psoc_get_tgt_if_handle(psoc)) &&
+	    !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[0])) {
+		policy_mgr_debug("Avoid channel switch as it's allowed to operate on unsafe channel: %d",
+				 op_ch_freq_list[0]);
+		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) &&
+	    (sta_check || gc_check))) {
+		if (!pm_ctx->sta_ap_intf_check_work_info) {
+			policy_mgr_err("invalid sta_ap_intf_check_work_info");
+			return;
+		}
+
+		policy_mgr_debug("Checking for Concurrent Change interference");
+
+		if (policy_mgr_mode_specific_connection_count(
+					psoc, PM_P2P_GO_MODE, NULL))
+			timeout_ms = MAX_NOA_TIME;
+
+		if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
+					    timeout_ms)) {
+			policy_mgr_debug("change interface request already queued");
+			return;
+		}
+	}
+}
+
+bool policy_mgr_check_bw_with_unsafe_chan_freq(struct wlan_objmgr_psoc *psoc,
+					       qdf_freq_t center_freq,
+					       enum phy_ch_width ch_width)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t freq_start, freq_end, bw, i, unsafe_chan_freq;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return true;
+	}
+
+	if (ch_width <= CH_WIDTH_20MHZ || !center_freq)
+		return true;
+
+	if (!pm_ctx->unsafe_channel_count)
+		return true;
+
+	bw = wlan_reg_get_bw_value(ch_width);
+	freq_start = center_freq - bw / 2;
+	freq_end = center_freq + bw / 2;
+
+	for (i = 0; i < pm_ctx->unsafe_channel_count; i++) {
+		unsafe_chan_freq = pm_ctx->unsafe_channel_list[i];
+		if (unsafe_chan_freq > freq_start &&
+		    unsafe_chan_freq < freq_end) {
+			policy_mgr_debug("unsafe ch freq %d is in range %d-%d",
+					 unsafe_chan_freq,
+					 freq_start,
+					 freq_end);
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
+ * @psoc: PSOC object information
+ * @vdev_id: Vdev id
+ * @ch_freq: 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: QDF_STATUS_SUCCESS for success
+ */
+QDF_STATUS
+policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
+				       uint8_t vdev_id, uint32_t ch_freq,
+				       uint32_t ch_width, bool forced)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct ch_params ch_params = {0};
+	qdf_freq_t center_freq;
+	QDF_STATUS status;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_INVAL;
+	}
+	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) {
+		ch_params.ch_width = ch_width;
+		status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
+			psoc, vdev_id, ch_freq, &ch_params);
+		if (QDF_IS_STATUS_SUCCESS(status) &&
+		    ch_width > ch_params.ch_width)
+			ch_width = ch_params.ch_width;
+	}
+
+	if (ch_params.mhz_freq_seg1)
+		center_freq = ch_params.mhz_freq_seg1;
+	else
+		center_freq = ch_params.mhz_freq_seg0;
+
+	if (!policy_mgr_check_bw_with_unsafe_chan_freq(psoc,
+						       center_freq,
+						       ch_width)) {
+		policy_mgr_info("SAP bw shrink to 20M for unsafe");
+		ch_width = CH_WIDTH_20MHZ;
+	}
+
+	if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
+		policy_mgr_info("SAP change change without restart");
+		status = pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
+								       vdev_id,
+								       ch_freq,
+								       ch_width,
+								       forced);
+	} else {
+		status = QDF_STATUS_E_INVAL;
+	}
+
+	return status;
+}
+#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
+
+QDF_STATUS
+policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc *psoc,
+				      uint8_t vdev_id,
+				      struct csa_offload_params *csa_event)
+{
+	uint8_t concur_vdev_id, i;
+	bool move_sap_go_first;
+	enum hw_mode_bandwidth bw;
+	qdf_freq_t cur_freq, new_freq;
+	struct wlan_objmgr_vdev *vdev, *conc_vdev;
+	struct wlan_objmgr_pdev *pdev;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum policy_mgr_con_mode cur_mode;
+	enum policy_mgr_con_mode concur_mode = PM_MAX_NUM_OF_MODE;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!csa_event) {
+		policy_mgr_err("CSA IE Received event is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first);
+	if (!move_sap_go_first) {
+		policy_mgr_err("g_move_sap_go_1st_on_dfs_sta_csa is disabled");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
+	if (cur_mode != PM_STA_MODE) {
+		policy_mgr_err("CSA received on non-STA connection");
+		return QDF_STATUS_E_INVAL;
+	}
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	pdev = wlan_vdev_get_pdev(vdev);
+	cur_freq = wlan_get_operation_chan_freq_vdev_id(pdev, vdev_id);
+
+	if (!wlan_reg_is_dfs_for_freq(pdev, cur_freq) &&
+	    !wlan_reg_is_freq_indoor(pdev, cur_freq)) {
+		policy_mgr_err("SAP / GO operating channel is non-DFS");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Check if there is any SAP / GO operating on the same channel or not
+	 * If yes, then get the current bandwidth and vdev_id of concurrent SAP
+	 * or GO and trigger channel switch to new channel received in CSA on
+	 * STA interface. If this new channel is DFS then trigger channel
+	 * switch to non-DFS channel. Once STA moves to this new channel and
+	 * when it receives very first beacon, it will then enforce SCC again
+	 */
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if (pm_conc_connection_list[i].in_use &&
+		    pm_conc_connection_list[i].freq == cur_freq &&
+		    pm_conc_connection_list[i].vdev_id != vdev_id &&
+		    (pm_conc_connection_list[i].mode == PM_P2P_GO_MODE ||
+		     pm_conc_connection_list[i].mode == PM_SAP_MODE)) {
+			concur_mode = pm_conc_connection_list[i].mode;
+			bw = pm_conc_connection_list[i].bw;
+			concur_vdev_id = pm_conc_connection_list[i].vdev_id;
+			break;
+		}
+	}
+
+	/* If there is no concurrent SAP / GO, then return */
+	if (concur_mode == PM_MAX_NUM_OF_MODE) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	conc_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, concur_vdev_id,
+							 WLAN_POLICY_MGR_ID);
+	if (!conc_vdev) {
+		policy_mgr_err("conc_vdev is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+	wlan_vdev_mlme_set_sap_go_move_before_sta(conc_vdev, true);
+	wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, true);
+	wlan_objmgr_vdev_release_ref(conc_vdev, WLAN_POLICY_MGR_ID);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	/*Change the CSA count*/
+	if (pm_ctx->sme_cbacks.sme_change_sap_csa_count)
+		/* Total 4 CSA frames are allowed so that GO / SAP
+		 * will move to new channel within 500ms
+		 */
+		pm_ctx->sme_cbacks.sme_change_sap_csa_count(4);
+	new_freq = csa_event->csa_chan_freq;
+
+	/* If the new channel is DFS or indoor, then select another channel
+	 * and switch the SAP / GO to avoid CAC. This will resume traffic on
+	 * SAP / GO interface immediately. Once STA moves to this new channel
+	 * and receives the very first beacon, then it will enforece SCC
+	 */
+	if (wlan_reg_is_dfs_for_freq(pdev, new_freq) ||
+	    wlan_reg_is_freq_indoor(pdev, new_freq)) {
+		if (wlan_reg_is_24ghz_ch_freq(new_freq)) {
+			new_freq = wlan_reg_min_24ghz_chan_freq();
+		} else if (wlan_reg_is_5ghz_ch_freq(new_freq)) {
+			new_freq = wlan_reg_min_5ghz_chan_freq();
+			/* if none of the 5G channel is non-DFS */
+			if (wlan_reg_is_dfs_for_freq(pdev, new_freq) ||
+			    wlan_reg_is_freq_indoor(pdev, new_freq))
+				new_freq = policy_mgr_get_nondfs_preferred_channel(psoc,
+										   concur_mode,
+										   true,
+										   concur_vdev_id);
+		} else {
+			new_freq = wlan_reg_min_6ghz_chan_freq();
+		}
+	}
+	policy_mgr_debug("Restart vdev: %u on freq: %u",
+			 concur_vdev_id, new_freq);
+
+	return policy_mgr_change_sap_channel_with_csa(psoc, concur_vdev_id,
+						      new_freq, bw, true);
+}
+
+void policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id)
+{
+	bool is_sap_go_moved_before_sta, move_sap_go_first;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev;
+	enum policy_mgr_con_mode cur_mode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return;
+	}
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev is NULL");
+		return;
+	}
+	is_sap_go_moved_before_sta =
+			wlan_vdev_mlme_is_sap_go_move_before_sta(vdev);
+	pdev = wlan_vdev_get_pdev(vdev);
+	wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, false);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first);
+	if (!is_sap_go_moved_before_sta || !move_sap_go_first) {
+		policy_mgr_debug("SAP / GO moved before STA: %u INI g_move_sap_go_1st_on_dfs_sta_csa: %u",
+				 is_sap_go_moved_before_sta, move_sap_go_first);
+		return;
+	}
+
+	cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
+	if (cur_mode != PM_STA_MODE) {
+		policy_mgr_err("CSA received on non-STA connection");
+		return;
+	}
+
+	policy_mgr_debug("Enforce SCC");
+	policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false);
+}
+
+#ifdef WLAN_FEATURE_P2P_P2P_STA
+void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id, uint32_t ch_freq,
+					uint32_t ch_width)
+{
+	uint8_t total_connection;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	total_connection = policy_mgr_mode_specific_connection_count(
+						psoc, PM_P2P_GO_MODE, NULL);
+
+	policy_mgr_debug("Total p2p go connection %d", total_connection);
+
+	/* If any p2p disconnected, don't do csa */
+	if (total_connection > 1) {
+		if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
+			pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
+				psoc, vdev_id,
+				CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL);
+
+		policy_mgr_change_sap_channel_with_csa(psoc, vdev_id,
+						       ch_freq, ch_width, true);
+	}
+}
+
+void policy_mgr_process_forcescc_for_go(struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id, uint32_t ch_freq,
+					uint32_t ch_width,
+					enum policy_mgr_con_mode mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct sta_ap_intf_check_work_ctx *work_info;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	if (!pm_ctx->sta_ap_intf_check_work_info) {
+		policy_mgr_err("invalid work info");
+		return;
+	}
+	work_info = pm_ctx->sta_ap_intf_check_work_info;
+	if (mode == PM_P2P_GO_MODE) {
+		work_info->go_plus_go_force_scc.vdev_id = vdev_id;
+		work_info->go_plus_go_force_scc.ch_freq = ch_freq;
+		work_info->go_plus_go_force_scc.ch_width = ch_width;
+	}
+
+	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
+				    WAIT_BEFORE_GO_FORCESCC_RESTART))
+		policy_mgr_debug("change interface request already queued");
+}
+#endif
+
+bool policy_mgr_is_chan_switch_in_progress(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 pm context");
+		return false;
+	}
+	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
+		policy_mgr_debug("channel switch is in progress");
+		return true;
+	}
+
+	return false;
+}
+
+QDF_STATUS policy_mgr_wait_chan_switch_complete_evt(
+		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;
+	}
+
+	status = qdf_wait_single_event(
+				&pm_ctx->channel_switch_complete_evt,
+				CHANNEL_SWITCH_COMPLETE_TIMEOUT);
+	if (QDF_IS_STATUS_ERROR(status))
+		policy_mgr_err("wait for event failed, still continue with channel switch");
+
+	return status;
+}
+
+static void __policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_pdev *pdev,
+						 void *object, void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	uint32_t *ap_starting_vdev_id = (uint32_t *)arg;
+	enum wlan_serialization_cmd_type cmd_type;
+	enum QDF_OPMODE op_mode;
+
+	if (!vdev || !ap_starting_vdev_id)
+		return;
+	if (*ap_starting_vdev_id != WLAN_INVALID_VDEV_ID)
+		return;
+	op_mode = wlan_vdev_mlme_get_opmode(vdev);
+	if (op_mode != QDF_SAP_MODE && op_mode != QDF_P2P_GO_MODE &&
+	    op_mode != QDF_NDI_MODE)
+		return;
+	/* Check AP start is present in active and pending queue or not */
+	cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev);
+	if (cmd_type == WLAN_SER_CMD_VDEV_START_BSS ||
+	    wlan_ser_is_non_scan_cmd_type_in_vdev_queue(
+			vdev, WLAN_SER_CMD_VDEV_START_BSS)) {
+		*ap_starting_vdev_id = wlan_vdev_get_id(vdev);
+		policy_mgr_debug("vdev %d op mode %d start bss is pending",
+				 *ap_starting_vdev_id, op_mode);
+	}
+}
+
+bool policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t ap_starting_vdev_id = WLAN_INVALID_VDEV_ID;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return false;
+	}
+
+	wlan_objmgr_pdev_iterate_obj_list(pm_ctx->pdev, WLAN_VDEV_OP,
+					  __policy_mgr_is_ap_start_in_progress,
+					  &ap_starting_vdev_id, 0,
+					  WLAN_POLICY_MGR_ID);
+
+	return ap_starting_vdev_id != WLAN_INVALID_VDEV_ID;
+}
+
+void policy_mgr_process_force_scc_for_nan(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;
+	}
+	if (!pm_ctx->sta_ap_intf_check_work_info) {
+		policy_mgr_err("invalid work info");
+		return;
+	}
+
+	pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = true;
+
+	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 0))
+		policy_mgr_debug("change interface request already queued");
+}
+
+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;
+}
+
+void policy_mgr_reset_hw_mode_change(struct wlan_objmgr_psoc *psoc)
+{
+	policy_mgr_err("Clear hw mode change and connection update evt");
+	policy_mgr_set_hw_mode_change_in_progress(
+			psoc, POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
+	policy_mgr_reset_connection_update(psoc);
+}
+
+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 *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Set channel_switch_complete_evt only if no vdev has channel switch
+	 * in progress.
+	 */
+	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
+		policy_mgr_info("Not all channel switch completed");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	status = qdf_event_set_all(&pm_ctx->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;
+
+	if (policy_mgr_is_hwmode_offload_enabled(psoc))
+		return QDF_STATUS_E_NOSUPPORT;
+
+	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_hwmode_offload_enabled(psoc))
+		return QDF_STATUS_E_NOSUPPORT;
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
+		policy_mgr_rl_debug("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_AFTER_CHANNEL_SWITCH,
+			POLICY_MGR_DEF_REQ_ID);
+	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;
+}
+
+QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch(
+		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+		uint32_t ch_freq, enum policy_mgr_conn_update_reason reason)
+{
+	QDF_STATUS status;
+	struct policy_mgr_conc_connection_info info;
+	uint8_t num_cxn_del = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum policy_mgr_conc_next_action next_action = PM_NOP;
+	bool eht_capab =  false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab);
+	if (eht_capab &&
+	    policy_mgr_mode_specific_connection_count(psoc,
+						      PM_SAP_MODE,
+						      NULL) == 1) {
+		policy_mgr_stop_opportunistic_timer(psoc);
+		goto ch_width_update;
+	}
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc) ||
+	    (!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
+	    !policy_mgr_is_hw_dbs_required_for_band(
+					psoc, HW_MODE_MAC_BAND_2G)))
+		return QDF_STATUS_E_NOSUPPORT;
+
+	/*
+	 * Stop opportunistic timer as current connection info will change once
+	 * channel is switched and thus if required it will be started once
+	 * channel switch is completed. With new connection info.
+	 */
+	policy_mgr_stop_opportunistic_timer(psoc);
+
+	if (wlan_reg_freq_to_band(ch_freq) != REG_BAND_2G)
+		return QDF_STATUS_E_NOSUPPORT;
+
+ch_width_update:
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	/*
+	 * 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);
+
+	status = policy_mgr_get_next_action(psoc, vdev_id, ch_freq,
+					    reason, &next_action);
+	/* Restore the connection entry */
+	if (num_cxn_del)
+		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		goto chk_opportunistic_timer;
+
+	if (PM_NOP != next_action)
+		status = policy_mgr_next_actions(psoc, vdev_id,
+						 next_action, reason,
+						 POLICY_MGR_DEF_REQ_ID);
+	else
+		status = QDF_STATUS_E_NOSUPPORT;
+
+chk_opportunistic_timer:
+	/*
+	 * If hw mode change failed restart the opportunistic timer to
+	 * Switch to single mac if required.
+	 */
+	if (status == QDF_STATUS_E_FAILURE) {
+		policy_mgr_err("Failed to update HW modeStatus %d", status);
+		policy_mgr_check_n_start_opportunistic_timer(psoc);
+	}
+
+	return status;
+}
+
+void policy_mgr_checkn_update_hw_mode_single_mac_mode(
+		struct wlan_objmgr_psoc *psoc, uint32_t ch_freq)
+{
+	uint8_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool dbs_required_2g;
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return;
+
+	if (QDF_TIMER_STATE_RUNNING == pm_ctx->dbs_opportunistic_timer.state)
+		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
+
+	dbs_required_2g =
+	    policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G);
+
+	if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
+		policy_mgr_debug("DBS required for new connection");
+		return;
+	}
+
+	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_FREQS(
+			    ch_freq, pm_conc_connection_list[i].freq) &&
+			    (WLAN_REG_IS_24GHZ_CH_FREQ(
+			    pm_conc_connection_list[i].freq) ||
+			    WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))) {
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				policy_mgr_debug("DBS required");
+				return;
+			}
+			if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ(
+			    pm_conc_connection_list[i].freq)) {
+				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 =
+					POLICY_MGR_UPDATE_REASON_MAX;
+
+	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,
+							 POLICY_MGR_DEF_REQ_ID);
+			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_debug("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_debug("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_debug("SMM is requested with HW (%d)", hw_mode_index);
+
+ret_value:
+	return value;
+}
+
+#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
+bool
+policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc,
+					    struct wlan_objmgr_vdev *vdev,
+					    qdf_freq_t *ch_freq)
+{
+	struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t connection_count, i, j, sta_vdev_id;
+
+	*ch_freq = 0;
+	/*
+	 * TDLS off channel is not allowed in any MCC scenario
+	 */
+	if (policy_mgr_current_concurrency_is_mcc(psoc)) {
+		policy_mgr_dump_current_concurrency(psoc);
+		policy_mgr_debug("TDLS off channel not allowed in MCC");
+		return false;
+	}
+
+	/*
+	 * TDLS offchannel is done only when STA is connected on 2G channel and
+	 * the current concurrency is not MCC
+	 */
+	if (!policy_mgr_is_sta_connected_2g(psoc)) {
+		policy_mgr_debug("STA not-connected on 2.4 Ghz");
+		return false;
+	}
+
+	/*
+	 * 2 Port DBS scenario - Allow non-STA vdev channel for
+	 * TDLS off-channel operation
+	 *
+	 * 3 Port Scenario - If STA Vdev is on SCC, allow TDLS off-channel on
+	 * the channel of vdev on the other MAC
+	 * If STA vdev is standalone on one mac, and scc on another mac, then
+	 * allow TDLS off channel on other mac scc channel
+	 */
+	sta_vdev_id = wlan_vdev_get_id(vdev);
+	connection_count = policy_mgr_get_connection_info(psoc, info);
+	switch (connection_count) {
+	case 1:
+		return true;
+	case 2:
+		/*
+		 * Allow all the 5GHz/6GHz channels when STA is in SCC
+		 */
+		if (policy_mgr_current_concurrency_is_scc(psoc)) {
+			*ch_freq = 0;
+			return true;
+		} else if (policy_mgr_is_current_hwmode_dbs(psoc)) {
+			/*
+			 * In DBS case, allow off-channel operation on the
+			 * other mac 5GHz/6GHz channel where the STA is not
+			 * present
+			 * Don't consider SBS case since STA should be
+			 * connected in 2.4GHz channel for TDLS
+			 * off-channel and MCC on SBS ex. 3 PORT
+			 * 2.4GHz STA + 5GHz Lower MCC + 5GHz Upper will
+			 * not be allowed
+			 */
+			if (sta_vdev_id == info[0].vdev_id)
+				*ch_freq = info[1].ch_freq;
+			else
+				*ch_freq = info[0].ch_freq;
+
+			return true;
+		}
+
+		break;
+	case 3:
+
+		/*
+		 * 3 Vdev SCC on 2.4GHz band. Allow TDLS off-channel operation
+		 * on all the 5GHz & 6GHz channels
+		 */
+		if (info[0].ch_freq == info[1].ch_freq &&
+		    info[0].ch_freq == info[2].ch_freq) {
+			*ch_freq = 0;
+			return true;
+		}
+
+		/*
+		 * DBS with SCC on one vdev scenario. Allow TDLS off-channel
+		 * on other mac frequency where STA is not present
+		 * SBS case is not considered since STA should be connected
+		 * on 2.4GHz and TDLS off-channel on SBS MCC is not allowed
+		 */
+		for (i = 0; i < connection_count; i++) {
+			for (j = i + 1; j < connection_count; j++) {
+				/*
+				 * Find 2 vdevs such that STA is one of the vdev
+				 * and STA + other vdev are not on same mac.
+				 * Return the foreign vdev frequency which is
+				 * not on same mac along with STA
+				 */
+				if (!policy_mgr_2_freq_always_on_same_mac(
+							psoc, info[i].ch_freq,
+							info[j].ch_freq)) {
+					if (sta_vdev_id == info[i].vdev_id) {
+						*ch_freq = info[j].ch_freq;
+						return true;
+					} else if (sta_vdev_id ==
+						   info[j].vdev_id) {
+						*ch_freq = info[i].ch_freq;
+						return true;
+					}
+				}
+			}
+		}
+
+		return false;
+	default:
+		policy_mgr_debug("TDLS off channel not allowed on > 3 port conc");
+		break;
+	}
+
+	return false;
+}
+#endif

+ 5327 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -0,0 +1,5327 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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"
+#include "wlan_mlme_api.h"
+#include "wlan_cm_roam_api.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "wlan_cm_api.h"
+#include "wlan_reg_ucfg_api.h"
+#ifdef WLAN_FEATURE_11BE_MLO
+#include "wlan_mlo_mgr_cmn.h"
+#include "wlan_mlo_mgr_public_structs.h"
+#endif
+#include "wlan_cm_ucfg_api.h"
+#include "target_if.h"
+
+#define POLICY_MGR_MAX_CON_STRING_LEN   230
+#define LOWER_END_FREQ_5GHZ 4900
+
+static const uint16_t sap_mand_5g_freq_list[] = {5745, 5765, 5785, 5805};
+
+struct policy_mgr_conc_connection_info
+	pm_conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+
+#ifdef WLAN_FEATURE_11BE_MLO
+struct policy_mgr_disabled_ml_link_info
+	pm_disabled_ml_links[MAX_NUMBER_OF_DISABLE_LINK];
+#endif
+
+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;
+}
+
+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;
+	uint32_t conc_scan_config_bits = 0;
+	struct target_psoc_info *tgt_hdl;
+
+	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;
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
+	if (!tgt_hdl) {
+		policy_mgr_err("tgt_hdl NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	conc_scan_config_bits = target_if_get_conc_scan_config_bits(tgt_hdl);
+
+	WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(*scan_config, dbs_scan &
+					   WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(conc_scan_config_bits));
+	WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET(*scan_config,
+					     dbs_plus_agile_scan &
+					     WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(conc_scan_config_bits));
+	WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET(*scan_config,
+						 single_mac_scan_with_dfs &
+						 WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(conc_scan_config_bits));
+
+	policy_mgr_debug("scan_config:%x ", *scan_config);
+	return QDF_STATUS_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;
+}
+
+bool policy_mgr_is_dual_mac_disabled_in_ini(
+		struct wlan_objmgr_psoc *psoc)
+{
+	bool is_disabled = false;
+	uint8_t dbs_type = DISABLE_DBS_CXN_AND_SCAN;
+
+	policy_mgr_get_dual_mac_feature(psoc, &dbs_type);
+	/*
+	 * 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;
+}
+
+#ifdef WLAN_FEATURE_SR
+bool policy_mgr_get_same_mac_conc_sr_status(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.sr_in_same_mac_conc;
+}
+#endif
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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;
+	}
+}
+
+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;
+}
+
+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);
+}
+
+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)
+{
+	uint64_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);
+		hw_mode->emlsr_cap = POLICY_MGR_HW_MODE_EMLSR_MODE_GET(param);
+
+		if (hw_mode_id == idx || hw_mode->emlsr_cap)
+			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;
+}
+
+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;
+}
+
+void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
+		uint32_t conn_index,
+		enum policy_mgr_con_mode mode,
+		uint32_t ch_freq,
+		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,
+		uint16_t ch_flagext)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool mcc_mode;
+	enum hw_mode_bandwidth max_bw;
+
+	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].freq = ch_freq;
+	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;
+	pm_conc_connection_list[conn_index].ch_flagext = ch_flagext;
+	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();
+
+	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 || policy_mgr_is_sap_mode(mode)) {
+		mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc);
+
+		if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb)
+			pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode);
+
+		if (pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw) {
+			max_bw = policy_mgr_get_connection_max_channel_width(
+					psoc);
+			policy_mgr_debug("max channel width %d", max_bw);
+			pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw(max_bw);
+		}
+	}
+
+	if (pm_ctx->conc_cbacks.connection_info_update)
+		pm_ctx->conc_cbacks.connection_info_update();
+}
+
+/**
+ * policy_mgr_store_and_del_conn_info() - Store and del a connection info
+ * @psoc: psoc handle
+ * @mode: Mode whose entry has to be deleted
+ * @all_matching_cxn_to_del: All the specified mode entries should be deleted
+ * @info: Structure 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);
+			pm_ctx->no_of_active_sessions[info->mode]--;
+			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_debug("Mode:%d not available in the conn info",
+				 mode);
+	} else {
+		*num_cxn_del = found_index;
+		policy_mgr_debug("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];
+		pm_ctx->no_of_active_sessions[info->mode]--;
+		/* Deleting the connection entry */
+		policy_mgr_decr_connection_count(
+			psoc,
+			pm_conc_connection_list[conn_index].vdev_id);
+	}
+
+	policy_mgr_debug("vdev id %d, num_cxn_del %d", vdev_id, *num_cxn_del);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+void policy_mgr_store_and_del_conn_info_by_chan_and_mode(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t ch_freq,
+			enum policy_mgr_con_mode mode,
+			struct policy_mgr_conc_connection_info *info,
+			uint8_t *num_cxn_del)
+{
+	uint32_t conn_index = 0;
+	uint8_t found_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);
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if (ch_freq != pm_conc_connection_list[conn_index].freq ||
+		    mode != pm_conc_connection_list[conn_index].mode) {
+			conn_index++;
+			continue;
+		}
+		info[found_index] = pm_conc_connection_list[conn_index];
+		policy_mgr_debug("Stored %d (%d), deleted STA entry with vdev id %d, index %d ch %d",
+				 info[found_index].vdev_id,
+				 info[found_index].mode,
+				 info[found_index].vdev_id, conn_index,
+				 ch_freq);
+		found_index++;
+		conn_index++;
+	}
+	conn_index = 0;
+	while (conn_index < found_index) {
+		policy_mgr_decr_connection_count(
+			psoc, info[conn_index].vdev_id);
+
+		pm_ctx->no_of_active_sessions[info[conn_index].mode]--;
+		conn_index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	*num_cxn_del = found_index;
+}
+
+/**
+ * policy_mgr_restore_deleted_conn_info() - Restore connection info
+ * @psoc: psoc handle
+ * @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;
+	int i;
+
+	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;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	conn_index = policy_mgr_get_connection_count(psoc);
+	if (conn_index + num_cxn_del > MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		policy_mgr_err("Failed to restore the deleted information %d/%d, as it exceed max %d",
+			       conn_index, num_cxn_del,
+			       MAX_NUMBER_OF_CONC_CONNECTIONS);
+		return;
+	}
+
+	qdf_mem_copy(&pm_conc_connection_list[conn_index], info,
+		     num_cxn_del * sizeof(*info));
+	pm_ctx->no_of_active_sessions[info->mode] += num_cxn_del;
+	for (i = 0; i < num_cxn_del; i++)
+		policy_mgr_debug("Restored the deleleted conn info, vdev:%d, index:%d",
+				 info[i].vdev_id, conn_index++);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+static bool
+policy_mgr_is_freq_range_5_6ghz(qdf_freq_t start_freq, qdf_freq_t end_freq)
+{
+	/*
+	 * As Fw is sending the whole hardware range which include 4.9Ghz as
+	 * well. Use LOWER_END_FREQ_5GHZ to differentiate 2.4Ghz and 5Ghz
+	 */
+	if (start_freq >= LOWER_END_FREQ_5GHZ &&
+	    end_freq >= LOWER_END_FREQ_5GHZ)
+		return true;
+
+	return false;
+}
+
+static bool
+policy_mgr_is_freq_range_2ghz(qdf_freq_t start_freq, qdf_freq_t end_freq)
+{
+	/*
+	 * As Fw is sending the whole hardware range which include 4.9Ghz as
+	 * well. Use LOWER_END_FREQ_5GHZ to differentiate 2.4Ghz and 5Ghz
+	 */
+	if (start_freq < LOWER_END_FREQ_5GHZ && end_freq < LOWER_END_FREQ_5GHZ)
+		return true;
+
+	return false;
+}
+
+static void
+policy_mgr_fill_curr_mac_2ghz_freq(uint32_t mac_id,
+				   struct policy_mgr_pdev_mac_freq_map *freq,
+				   struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	pm_ctx->hw_mode.cur_mac_freq_range[mac_id].low_2ghz_freq =
+					QDF_MAX(freq->start_freq,
+						wlan_reg_min_24ghz_chan_freq());
+	pm_ctx->hw_mode.cur_mac_freq_range[mac_id].high_2ghz_freq =
+					QDF_MIN(freq->end_freq,
+						wlan_reg_max_24ghz_chan_freq());
+}
+
+static void
+policy_mgr_fill_curr_mac_5ghz_freq(uint32_t mac_id,
+				   struct policy_mgr_pdev_mac_freq_map *freq,
+				   struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	qdf_freq_t max_5g_freq;
+
+	max_5g_freq = wlan_reg_max_6ghz_chan_freq() ?
+			wlan_reg_max_6ghz_chan_freq() :
+			wlan_reg_max_5ghz_chan_freq();
+
+	pm_ctx->hw_mode.cur_mac_freq_range[mac_id].low_5ghz_freq =
+					QDF_MAX(freq->start_freq,
+						wlan_reg_min_5ghz_chan_freq());
+	pm_ctx->hw_mode.cur_mac_freq_range[mac_id].high_5ghz_freq =
+					QDF_MIN(freq->end_freq, max_5g_freq);
+}
+
+void
+policy_mgr_fill_curr_mac_freq_by_hwmode(struct policy_mgr_psoc_priv_obj *pm_ctx,
+					enum policy_mgr_mode mode_hw)
+{
+	uint8_t i;
+	struct policy_mgr_freq_range *cur_mac_freq, *hwmode_freq;
+
+	cur_mac_freq = pm_ctx->hw_mode.cur_mac_freq_range;
+	hwmode_freq = pm_ctx->hw_mode.freq_range_caps[mode_hw];
+
+	for (i = 0; i < MAX_MAC; i++) {
+		cur_mac_freq[i].low_2ghz_freq = hwmode_freq[i].low_2ghz_freq;
+		cur_mac_freq[i].high_2ghz_freq = hwmode_freq[i].high_2ghz_freq;
+		cur_mac_freq[i].low_5ghz_freq = hwmode_freq[i].low_5ghz_freq;
+		cur_mac_freq[i].high_5ghz_freq = hwmode_freq[i].high_5ghz_freq;
+	}
+}
+
+static void
+policy_mgr_fill_legacy_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				  struct policy_mgr_hw_mode_params hw_mode)
+{
+	enum policy_mgr_mode mode;
+
+	mode = hw_mode.dbs_cap ? MODE_DBS : MODE_SMM;
+	policy_mgr_fill_curr_mac_freq_by_hwmode(pm_ctx, mode);
+}
+
+static QDF_STATUS
+policy_mgr_fill_curr_freq_by_pdev_freq(int32_t num_mac_freq,
+				struct policy_mgr_pdev_mac_freq_map *freq,
+				struct policy_mgr_psoc_priv_obj *pm_ctx,
+				struct policy_mgr_hw_mode_params hw_mode)
+{
+	uint32_t mac_id, i;
+
+	/* memzero before filling it */
+	qdf_mem_zero(pm_ctx->hw_mode.cur_mac_freq_range,
+		     sizeof(pm_ctx->hw_mode.cur_mac_freq_range));
+	for (i = 0; i < num_mac_freq; i++) {
+		mac_id = freq[i].mac_id;
+
+		if (mac_id >= MAX_MAC) {
+			policy_mgr_debug("Invalid pdev id %d", mac_id);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		if (policy_mgr_is_freq_range_2ghz(freq[i].start_freq,
+						  freq[i].end_freq)) {
+			policy_mgr_fill_curr_mac_2ghz_freq(mac_id,
+							   &freq[i],
+							   pm_ctx);
+		} else if (policy_mgr_is_freq_range_5_6ghz(freq[i].start_freq,
+							 freq[i].end_freq)) {
+			policy_mgr_fill_curr_mac_5ghz_freq(mac_id, &freq[i],
+							   pm_ctx);
+		} else  {
+			policy_mgr_err("Invalid different band freq range: mac_id %d start freq %d end_freq %d",
+				       mac_id, freq[i].start_freq,
+				       freq[i].end_freq);
+			return QDF_STATUS_E_INVAL;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void
+policy_mgr_update_curr_mac_freq(uint32_t num_mac_freq,
+				struct policy_mgr_pdev_mac_freq_map *freq,
+				struct policy_mgr_psoc_priv_obj *pm_ctx,
+				struct policy_mgr_hw_mode_params hw_mode)
+{
+	QDF_STATUS status;
+
+	if (num_mac_freq && freq) {
+		status = policy_mgr_fill_curr_freq_by_pdev_freq(num_mac_freq,
+								freq, pm_ctx,
+								hw_mode);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			return;
+	}
+
+	policy_mgr_fill_legacy_freq_range(pm_ctx, hw_mode);
+}
+
+/**
+ * policy_mgr_update_hw_mode_conn_info() - Update connection
+ * info based on HW mode
+ * @psoc: psoc handle
+ * @num_vdev_mac_entries: Number of vdev-mac id entries that follow
+ * @vdev_mac_map: Mapping of vdev-mac id
+ * @hw_mode: HW mode
+ * @num_mac_freq: number of Frequency Range
+ * @freq_info: Pointer to Frequency Range
+ *
+ * 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 num_mac_freq,
+				struct policy_mgr_pdev_mac_freq_map *freq_info)
+{
+	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;
+	}
+
+	policy_mgr_update_curr_mac_freq(num_mac_freq, freq_info, pm_ctx,
+					hw_mode);
+
+	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,
+				uint32_t request_id)
+{
+	QDF_STATUS ret;
+	struct policy_mgr_hw_mode_params hw_mode;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(context);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		goto set_done_event;
+	}
+
+	policy_mgr_set_hw_mode_change_in_progress(context,
+		POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
+
+	if (status == SET_HW_MODE_STATUS_OK ||
+	    status == SET_HW_MODE_STATUS_ALREADY) {
+		policy_mgr_set_connection_update(context);
+	}
+
+	if (status != SET_HW_MODE_STATUS_OK) {
+		policy_mgr_debug("Set HW mode failed with status %d", status);
+		goto next_action;
+	}
+
+	/* vdev mac map for NAN Discovery is expected in NAN Enable resp */
+	if (reason != POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY &&
+	    !vdev_mac_map) {
+		policy_mgr_err("vdev_mac_map is NULL");
+		goto set_done_event;
+	}
+
+	ret = policy_mgr_get_hw_mode_from_idx(context, cfgd_hw_mode_index,
+					      &hw_mode);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		policy_mgr_err("Get HW mode for index %d reason: %d",
+			       cfgd_hw_mode_index, ret);
+		goto set_done_event;
+	}
+	policy_mgr_debug("HW mode idx %d, DBS %d Agile %d SBS %d, MAC0:: SS:Tx %d Rx %d, BW %d band %d. MAC1:: SS:Tx %d Rx %d, BW %d",
+			 cfgd_hw_mode_index, hw_mode.dbs_cap,
+			 hw_mode.agile_dfs_cap, hw_mode.sbs_cap,
+			 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
+			 hw_mode.mac0_bw, hw_mode.mac0_band_cap,
+			 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
+			 hw_mode.mac1_bw);
+	policy_mgr_dump_freq_range_n_vdev_map(num_vdev_mac_entries,
+					      vdev_mac_map, 0, NULL);
+
+	/* update pm_conc_connection_list */
+	policy_mgr_update_hw_mode_conn_info(context,
+					    num_vdev_mac_entries,
+					    vdev_mac_map,
+					    hw_mode, 0, NULL);
+	if (pm_ctx->mode_change_cb)
+		pm_ctx->mode_change_cb();
+
+	/* Notify tdls */
+	if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session)
+		pm_ctx->tdls_cbacks.tdls_notify_decrement_session(pm_ctx->psoc);
+
+next_action:
+	if (PM_NOP != next_action && (status == SET_HW_MODE_STATUS_ALREADY ||
+	    status == SET_HW_MODE_STATUS_OK))
+		policy_mgr_next_actions(context, session_id,
+			next_action, reason, request_id);
+	else
+		policy_mgr_debug("No action needed right now");
+
+set_done_event:
+	ret = policy_mgr_set_opportunistic_update(context);
+	if (!QDF_IS_STATUS_SUCCESS(ret))
+		policy_mgr_err("ERROR: set opportunistic_update event failed");
+}
+
+static char *
+ml_sta_prefix(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+						    vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d",
+			       vdev_id);
+		return "STA";
+	}
+
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return "ML STA";
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return "STA";
+}
+
+static void
+policy_mgr_dump_ml_sta_conc(struct wlan_objmgr_psoc *psoc,
+			    uint8_t *num_mlo_sta)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (!num_mlo_sta)
+		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);
+
+	if (policy_mgr_is_mlo_in_mode_dbs(psoc, PM_STA_MODE, NULL,
+					  num_mlo_sta))
+		policy_mgr_debug("ML STA %d links in DBS band", *num_mlo_sta);
+	else if (policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE, NULL,
+					       num_mlo_sta))
+		policy_mgr_debug("ML STA %d links in SBS band", *num_mlo_sta);
+	else if (*num_mlo_sta > 1)
+		policy_mgr_debug("ML STA %d links in same mac MLSR",
+				 *num_mlo_sta);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+/**
+ * policy_mgr_dump_current_concurrency_one_connection() - To dump the
+ * current concurrency info with one connection
+ * @psoc: psoc object
+ * @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(
+		struct wlan_objmgr_psoc *psoc,
+		char *cc_mode, uint32_t length)
+{
+	uint32_t count = 0;
+	enum policy_mgr_con_mode mode;
+	char buf[9] = {0};
+
+	mode = pm_conc_connection_list[0].mode;
+	qdf_scnprintf(buf, sizeof(buf), "(vdev %d)",
+		      pm_conc_connection_list[0].vdev_id);
+
+	switch (mode) {
+	case PM_STA_MODE:
+		count = strlcat(cc_mode,
+				ml_sta_prefix(
+				psoc, pm_conc_connection_list[0].vdev_id),
+				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_NAN_DISC_MODE:
+		count = strlcat(cc_mode, "NAN DISC", length);
+		break;
+	case PM_NDI_MODE:
+		count = strlcat(cc_mode, "NDI", length);
+		break;
+	case PM_LL_LT_SAP_MODE:
+		count = strlcat(cc_mode, "LT_SAP", length);
+		break;
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+	count += strlcat(cc_mode, buf, length);
+
+	return count;
+}
+
+/**
+ * policy_mgr_dump_current_concurrency_two_connection() - To dump the
+ * current concurrency info with two connections
+ * @psoc: psoc object
+ * @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(
+		struct wlan_objmgr_psoc *psoc,
+		char *cc_mode, uint32_t length)
+{
+	uint32_t count = 0;
+	enum policy_mgr_con_mode mode;
+	char buf[9] = {0};
+
+	mode = pm_conc_connection_list[1].mode;
+	qdf_scnprintf(buf, sizeof(buf), "(vdev %d)",
+		      pm_conc_connection_list[1].vdev_id);
+
+	switch (mode) {
+	case PM_STA_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+", length);
+		count += strlcat(cc_mode,
+				 ml_sta_prefix(
+				 psoc, pm_conc_connection_list[1].vdev_id),
+				 length);
+		break;
+	case PM_SAP_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+SAP",
+					length);
+		break;
+	case PM_P2P_CLIENT_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+P2P CLI",
+					length);
+		break;
+	case PM_P2P_GO_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+P2P GO",
+					length);
+		break;
+	case PM_NDI_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+NDI",
+					length);
+		break;
+	case PM_NAN_DISC_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+NAN Disc", length);
+		break;
+	case PM_LL_LT_SAP_MODE:
+		count = policy_mgr_dump_current_concurrency_one_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+LT_SAP",
+					length);
+		break;
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+	count += strlcat(cc_mode, buf, length);
+
+	return count;
+}
+
+/**
+ * policy_mgr_dump_current_concurrency_three_connection() - To dump the
+ * current concurrency info with three connections
+ * @psoc: psoc object
+ * @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(
+		struct wlan_objmgr_psoc *psoc,
+		char *cc_mode, uint32_t length)
+{
+	uint32_t count = 0;
+	enum policy_mgr_con_mode mode;
+	char buf[9] = {0};
+
+	mode = pm_conc_connection_list[2].mode;
+	qdf_scnprintf(buf, sizeof(buf), "(vdev %d)",
+		      pm_conc_connection_list[2].vdev_id);
+
+	switch (mode) {
+	case PM_STA_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+", length);
+		count += strlcat(cc_mode,
+				 ml_sta_prefix(
+				 psoc, pm_conc_connection_list[2].vdev_id),
+				 length);
+		break;
+	case PM_SAP_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+SAP",
+					length);
+		break;
+	case PM_P2P_CLIENT_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+P2P CLI",
+					length);
+		break;
+	case PM_P2P_GO_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+P2P GO",
+					length);
+		break;
+	case PM_NAN_DISC_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+NAN Disc",
+					length);
+		break;
+	case PM_NDI_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+NDI",
+					length);
+		break;
+	case PM_LL_LT_SAP_MODE:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+LT_SAP",
+					length);
+
+		break;
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+	count += strlcat(cc_mode, buf, length);
+
+	return count;
+}
+
+static void
+policy_mgr_dump_dual_mac_concurrency(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				     char *cc_mode, uint32_t length)
+{
+	char buf[26] = {0};
+	uint8_t i;
+	uint8_t j;
+	uint32_t vdev_bit_mask = 0;
+
+	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)
+			continue;
+		for (j = i + 1; j < MAX_NUMBER_OF_CONC_CONNECTIONS; j++) {
+			if (!pm_conc_connection_list[j].in_use)
+				continue;
+			if (policy_mgr_are_2_freq_on_same_mac(
+					pm_ctx->psoc,
+					pm_conc_connection_list[i].freq,
+					pm_conc_connection_list[j].freq)) {
+				qdf_mem_zero(buf, sizeof(buf));
+				qdf_scnprintf(
+					buf, sizeof(buf),
+					": vdev %d & %d %s on mac %d",
+					pm_conc_connection_list[i].vdev_id,
+					pm_conc_connection_list[j].vdev_id,
+					pm_conc_connection_list[i].freq ==
+					pm_conc_connection_list[j].freq ? "SCC"
+					: "MCC",
+					pm_conc_connection_list[i].mac);
+				QDF_SET_PARAM(
+					vdev_bit_mask,
+					pm_conc_connection_list[i].vdev_id);
+				QDF_SET_PARAM(
+					vdev_bit_mask,
+					pm_conc_connection_list[j].vdev_id);
+				strlcat(cc_mode, buf, length);
+			}
+		}
+	}
+
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		/* in_use flag is required to be checked because vdev bit
+		 * mask will be 0 for 4th bit if only 3 port concurrency is
+		 * present on a hardware that can support 4 port concurrency
+		 */
+		if (!pm_conc_connection_list[i].in_use ||
+		    QDF_HAS_PARAM(
+		    vdev_bit_mask, pm_conc_connection_list[i].vdev_id))
+			continue;
+
+		qdf_mem_zero(buf, sizeof(buf));
+		qdf_scnprintf(buf, sizeof(buf), ": vdev %d alone on mac %d",
+			      pm_conc_connection_list[i].vdev_id,
+			      pm_conc_connection_list[i].mac);
+		strlcat(cc_mode, buf, length);
+	}
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+/**
+ * policy_mgr_dump_dbs_concurrency() - To dump the dbs concurrency
+ * combination
+ * @psoc: psoc handle
+ * @cc_mode: connection string
+ * @length: Maximum size of the 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)
+{
+	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);
+	policy_mgr_dump_dual_mac_concurrency(pm_ctx, cc_mode, length);
+}
+
+/**
+ * policy_mgr_dump_sbs_concurrency() - To dump the sbs concurrency
+ * combination
+ * @psoc: psoc handle
+ * @cc_mode: connection string
+ * @length: Maximum size of the string
+ *
+ * This routine is called to dump the concurrency info
+ *
+ * Return: None
+ */
+static void policy_mgr_dump_sbs_concurrency(struct wlan_objmgr_psoc *psoc,
+					    char *cc_mode, uint32_t length)
+{
+	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, " SBS", length);
+	policy_mgr_dump_dual_mac_concurrency(pm_ctx, cc_mode, length);
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+void
+policy_mgr_dump_disabled_ml_links(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	uint8_t buf[POLICY_MGR_MAX_CON_STRING_LEN] = {0};
+	uint32_t len = 0, count = 0, i;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (pm_disabled_ml_links[i].in_use) {
+			len += qdf_scnprintf(buf + len,
+					    POLICY_MGR_MAX_CON_STRING_LEN - len,
+					    "vdev %d :Mode %d freq %d, ",
+					    pm_disabled_ml_links[i].vdev_id,
+					    pm_disabled_ml_links[i].mode,
+					    pm_disabled_ml_links[i].freq);
+			count++;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (count)
+		policy_mgr_debug("Disabled links(%d): %s", count, buf);
+}
+#endif
+
+#ifdef FEATURE_FOURTH_CONNECTION
+/**
+ * policy_mgr_dump_current_concurrency_4_connection() - To dump the
+ * current concurrency info with 4 connections
+ * @psoc: psoc object
+ * @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_4_connection(
+		struct wlan_objmgr_psoc *psoc, char *cc_mode, uint32_t length)
+{
+	uint32_t count = 0;
+	enum policy_mgr_con_mode mode;
+	char buf[9] = {0};
+
+	mode = pm_conc_connection_list[3].mode;
+	qdf_scnprintf(buf, sizeof(buf), "(vdev %d)",
+		      pm_conc_connection_list[3].vdev_id);
+
+	switch (mode) {
+	case PM_STA_MODE:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+", length);
+		count += strlcat(cc_mode,
+				 ml_sta_prefix(
+				 psoc, pm_conc_connection_list[3].vdev_id),
+				 length);
+		break;
+	case PM_SAP_MODE:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+SAP",
+					length);
+		break;
+	case PM_P2P_CLIENT_MODE:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+P2P CLI",
+					length);
+		break;
+	case PM_P2P_GO_MODE:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+P2P GO",
+					length);
+		break;
+	case PM_NAN_DISC_MODE:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+NAN Disc",
+					length);
+		break;
+	case PM_NDI_MODE:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+NDI",
+					length);
+		break;
+	case PM_LL_LT_SAP_MODE:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+				psoc, cc_mode, length);
+		count += strlcat(cc_mode, "+LT_SAP",
+					length);
+		break;
+
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+	count += strlcat(cc_mode, buf, length);
+
+	return count;
+}
+
+static bool
+policy_mgr_handle_dump_4th_connection(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				      uint32_t num_connections,
+				      char *cc_mode, uint32_t len)
+{
+	uint32_t count = 0;
+
+	if (num_connections != 4)
+		return false;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+
+	count = policy_mgr_dump_current_concurrency_4_connection(
+		pm_ctx->psoc, cc_mode, len);
+
+	if (policy_mgr_is_current_hwmode_dbs(pm_ctx->psoc))
+		policy_mgr_dump_dbs_concurrency(pm_ctx->psoc, cc_mode, len);
+	else if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc))
+		policy_mgr_dump_sbs_concurrency(pm_ctx->psoc, cc_mode, len);
+	else
+		strlcat(cc_mode, " MCC", len);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return true;
+}
+#else
+static inline bool
+policy_mgr_handle_dump_4th_connection(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				      uint32_t num_connections,
+				      char *cc_mode, uint32_t len)
+{
+	return false;
+}
+#endif
+
+void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t num_connections = 0;
+	char *cc_mode;
+	uint32_t count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t len = POLICY_MGR_MAX_CON_STRING_LEN;
+	uint8_t num_mlo_sta = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+	if (!num_connections)
+		return;
+
+	cc_mode = qdf_mem_malloc(len);
+	if (!cc_mode)
+		return;
+
+	policy_mgr_dump_connection_status_info(psoc);
+	policy_mgr_dump_ml_sta_conc(psoc, &num_mlo_sta);
+	switch (num_connections) {
+	case 1:
+		policy_mgr_dump_current_concurrency_one_connection(psoc,
+								   cc_mode,
+								   len);
+		policy_mgr_debug("%s Standalone", cc_mode);
+		break;
+	case 2:
+		count = policy_mgr_dump_current_concurrency_two_connection(
+			psoc, cc_mode, len);
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		if (pm_conc_connection_list[0].freq ==
+		    pm_conc_connection_list[1].freq) {
+			strlcat(cc_mode, " SCC", len);
+			/* In some platform 2.4 Ghz can lead to DBS,
+			 * so check for DBS for SCC/MCC case
+			 */
+			if (policy_mgr_is_current_hwmode_dbs(psoc))
+				strlcat(cc_mode, " (DBS)", len);
+		} else if (policy_mgr_2_freq_always_on_same_mac(psoc,
+			   pm_conc_connection_list[0].freq,
+			   pm_conc_connection_list[1].freq)) {
+			strlcat(cc_mode, " MCC", len);
+			if (policy_mgr_is_current_hwmode_dbs(psoc))
+				strlcat(cc_mode, " (DBS)", len);
+		} else if (policy_mgr_is_current_hwmode_dbs(psoc)) {
+			strlcat(cc_mode, " DBS", len);
+		} else if (policy_mgr_is_current_hwmode_sbs(psoc)) {
+			strlcat(cc_mode, " SBS", len);
+		} else {
+			if (num_mlo_sta < 2)
+				strlcat(cc_mode, " MCC", len);
+			else
+				strlcat(cc_mode, " SMM", len);
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		policy_mgr_debug("%s", cc_mode);
+		break;
+	case 3:
+		count = policy_mgr_dump_current_concurrency_three_connection(
+			psoc, cc_mode, len);
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		if (pm_conc_connection_list[0].freq ==
+		    pm_conc_connection_list[1].freq &&
+		    pm_conc_connection_list[0].freq ==
+		    pm_conc_connection_list[2].freq){
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			strlcat(cc_mode, " SCC", len);
+		} else if (policy_mgr_are_3_freq_on_same_mac(psoc,
+				pm_conc_connection_list[0].freq,
+				pm_conc_connection_list[1].freq,
+				pm_conc_connection_list[2].freq)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			if (num_mlo_sta < 2)
+				strlcat(cc_mode, " MCC on single MAC", len);
+			else
+				strlcat(cc_mode, " on single MAC", len);
+		} else {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			if (policy_mgr_is_current_hwmode_dbs(psoc))
+				policy_mgr_dump_dbs_concurrency(psoc, cc_mode,
+								len);
+			else if (policy_mgr_is_current_hwmode_sbs(psoc))
+				policy_mgr_dump_sbs_concurrency(psoc, cc_mode,
+								len);
+			else if (num_mlo_sta < 2)
+				strlcat(cc_mode, " MCC", len);
+			else
+				strlcat(cc_mode, " SMM", len);
+		}
+		policy_mgr_debug("%s", cc_mode);
+		break;
+	case 4:
+		if (policy_mgr_handle_dump_4th_connection(pm_ctx,
+							  num_connections,
+							  cc_mode, len)) {
+			policy_mgr_debug("%s", cc_mode);
+			break;
+		}
+	fallthrough;
+	default:
+		policy_mgr_debug("unexpected num_connections value %d",
+				 num_connections);
+		break;
+	}
+	qdf_mem_free(cc_mode);
+
+	policy_mgr_dump_disabled_ml_links(pm_ctx);
+
+	return;
+}
+
+/**
+ * policy_mgr_set_pcl_for_existing_combo() - Set PCL for existing connection
+ * @psoc: psoc handle
+ * @mode: Connection mode of type 'policy_mgr_con_mode'
+ * @vdev_id: Vdev Id
+ *
+ * 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,
+					   uint8_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct policy_mgr_pcl_list pcl;
+
+	status = policy_mgr_get_pcl_for_vdev_id(psoc, mode, pcl.pcl_list,
+						&pcl.pcl_len,
+						pcl.weight_list,
+						QDF_ARRAY_SIZE(pcl.weight_list),
+						vdev_id);
+	/* Send PCL only if policy_mgr_pdev_get_pcl returned success */
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = policy_mgr_set_pcl(psoc, &pcl, vdev_id, false);
+		if (QDF_IS_STATUS_ERROR(status))
+			policy_mgr_err("Send set PCL to policy mgr failed");
+	}
+}
+
+void policy_mgr_set_pcl_for_connected_vdev(struct wlan_objmgr_psoc *psoc,
+					   uint8_t vdev_id, bool clear_pcl)
+{
+	struct policy_mgr_pcl_list msg = { {0} };
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t roam_enabled_vdev_id;
+	bool sta_concurrency_is_with_different_mac, dual_sta_roam_enabled;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev is NULL");
+		return;
+	}
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return;
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	/*
+	 * Get the vdev id of the STA on which roaming is already
+	 * initialized and set the vdev PCL for that STA vdev if dual
+	 * STA roaming feature is enabled and concurrency is STA + STA.
+	 */
+	roam_enabled_vdev_id = policy_mgr_get_roam_enabled_sta_session_id(psoc,
+								       vdev_id);
+	if (roam_enabled_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
+		return;
+
+	sta_concurrency_is_with_different_mac =
+		policy_mgr_concurrent_sta_on_different_mac(psoc);
+	dual_sta_roam_enabled = wlan_mlme_get_dual_sta_roaming_enabled(psoc);
+	policy_mgr_debug("dual_sta_roam:%d, sta concurrency on different mac:%d, clear_pcl:%d",
+			 dual_sta_roam_enabled,
+			 sta_concurrency_is_with_different_mac,
+			 clear_pcl);
+
+	if (dual_sta_roam_enabled) {
+		if (clear_pcl) {
+			/*
+			 * Here the PCL level should be at vdev level already
+			 * as this is invoked from disconnect handler. Clear the
+			 * vdev pcl for the existing connected STA vdev and this
+			 * is followed by set PDEV pcl.
+			 */
+			policy_mgr_set_pcl(psoc, &msg,
+					   roam_enabled_vdev_id, true);
+			wlan_cm_roam_activate_pcl_per_vdev(psoc,
+							   roam_enabled_vdev_id,
+							   false);
+		} else if (sta_concurrency_is_with_different_mac) {
+			wlan_cm_roam_activate_pcl_per_vdev(psoc,
+							   roam_enabled_vdev_id,
+							   true);
+		}
+		policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE,
+						      roam_enabled_vdev_id);
+	}
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+uint32_t
+policy_mgr_get_connected_vdev_band_mask(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_channel *chan;
+	uint32_t band_mask = 0;
+	struct wlan_objmgr_vdev *ml_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
+	uint16_t ml_vdev_cnt = 0;
+	struct wlan_objmgr_vdev *t_vdev;
+	int i;
+
+	if (!vdev) {
+		policy_mgr_err("vdev is NULL");
+		return band_mask;
+	}
+
+	if (wlan_vdev_mlme_is_link_sta_vdev(vdev)) {
+		policy_mgr_debug("skip mlo link sta");
+		return band_mask;
+	}
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE ||
+	    !wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		chan = wlan_vdev_get_active_channel(vdev);
+		if (!chan) {
+			policy_mgr_err("no active channel");
+			return band_mask;
+		}
+
+		band_mask |= BIT(wlan_reg_freq_to_band(chan->ch_freq));
+		return band_mask;
+	}
+
+	mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, ml_vdev_list);
+	for (i = 0; i < ml_vdev_cnt; i++) {
+		t_vdev = ml_vdev_list[i];
+		if (!ucfg_cm_is_vdev_connected(t_vdev))
+			goto next;
+
+		chan = wlan_vdev_get_active_channel(t_vdev);
+		if (!chan)
+			goto next;
+
+		band_mask |= BIT(wlan_reg_freq_to_band(chan->ch_freq));
+next:
+		mlo_release_vdev_ref(t_vdev);
+	}
+
+	return band_mask;
+}
+#else
+uint32_t
+policy_mgr_get_connected_vdev_band_mask(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_channel *chan;
+	uint32_t band_mask = 0;
+
+	if (!vdev) {
+		policy_mgr_err("vdev is NULL");
+		return band_mask;
+	}
+
+	chan = wlan_vdev_get_active_channel(vdev);
+	if (!chan) {
+		policy_mgr_err("no active channel");
+		return band_mask;
+	}
+
+	band_mask |= BIT(wlan_reg_freq_to_band(chan->ch_freq));
+	return band_mask;
+}
+#endif
+
+/**
+ * policy_mgr_get_connected_roaming_vdev_band_mask() - get connected vdev
+ * band mask
+ * @psoc: PSOC object
+ * @vdev_id: Vdev id
+ *
+ * Return: reg wifi band mask
+ */
+uint32_t
+policy_mgr_get_connected_roaming_vdev_band_mask(struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id)
+{
+	uint32_t band_mask = 0, roam_band_mask, band_mask_for_vdev;
+	struct wlan_objmgr_vdev *vdev;
+	bool dual_sta_roam_active, is_pcl_per_vdev;
+	bool is_sbs_capable = false;
+
+	is_sbs_capable =
+		policy_mgr_is_hw_sbs_capable(psoc);
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev is NULL");
+		return 0;
+	}
+
+	roam_band_mask = wlan_cm_get_roam_band_value(psoc, vdev);
+
+	/*
+	 * If sbs is enabled, just send PCL to F/W directly,  allow SBS<->DBS
+	 * roaming,  not just limit intra band.
+	 */
+	if (is_sbs_capable) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return roam_band_mask;
+	}
+	band_mask_for_vdev = policy_mgr_get_connected_vdev_band_mask(vdev);
+
+	is_pcl_per_vdev = wlan_cm_roam_is_pcl_per_vdev_active(psoc, vdev_id);
+	dual_sta_roam_active = wlan_mlme_get_dual_sta_roaming_enabled(psoc);
+
+	policy_mgr_debug("connected STA vdev_id:%d, pcl_per_vdev:%d, dual_sta_roam_active:%d",
+			 vdev_id, is_pcl_per_vdev,
+			 dual_sta_roam_active);
+
+	if (dual_sta_roam_active && is_pcl_per_vdev) {
+		policy_mgr_debug("connected vdev band mask:%d",
+				 band_mask_for_vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return band_mask_for_vdev;
+	}
+
+	/*
+	 * if vendor command to configure roam band is set , we will
+	 * take this as priority instead of drv cmd "SETROAMINTRABAND" or
+	 * active connection band.
+	 */
+	ucfg_reg_get_band(wlan_vdev_get_pdev(vdev), &band_mask);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	if (roam_band_mask != band_mask) {
+		policy_mgr_debug("roam_band_mask:%d", roam_band_mask);
+		return roam_band_mask;
+	}
+
+	/*
+	 * If PCL command is PDEV level, only one sta is active.
+	 * So fill the band mask if intra band roaming is enabled
+	 */
+	if ((!is_pcl_per_vdev) && ucfg_mlme_is_roam_intra_band(psoc)) {
+		policy_mgr_debug("connected STA band mask:%d",
+				 band_mask_for_vdev);
+		return band_mask_for_vdev;
+	}
+
+	policy_mgr_debug("band_mask:%d", band_mask);
+	return band_mask;
+}
+
+QDF_STATUS policy_mgr_set_pcl(struct wlan_objmgr_psoc *psoc,
+			      struct policy_mgr_pcl_list *msg,
+			      uint8_t vdev_id,
+			      bool clear_vdev_pcl)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg message = {0};
+	struct set_pcl_req *req_msg;
+	uint32_t i;
+
+	if (!msg) {
+		policy_mgr_err("msg is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!MLME_IS_ROAM_INITIALIZED(psoc, vdev_id)) {
+		policy_mgr_debug("Roam is not initialized on vdev:%d", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	req_msg = qdf_mem_malloc(sizeof(*req_msg));
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	req_msg->band_mask =
+		policy_mgr_get_connected_roaming_vdev_band_mask(psoc, vdev_id);
+	for (i = 0; i < msg->pcl_len; i++) {
+		req_msg->chan_weights.pcl_list[i] =  msg->pcl_list[i];
+		req_msg->chan_weights.weight_list[i] =  msg->weight_list[i];
+	}
+
+	req_msg->chan_weights.pcl_len = msg->pcl_len;
+	req_msg->clear_vdev_pcl = clear_vdev_pcl;
+
+	/*
+	 * Set vdev value as WLAN_UMAC_VDEV_ID_MAX, if PDEV level
+	 * PCL command needs to be sent.
+	 */
+	if (!wlan_cm_roam_is_pcl_per_vdev_active(psoc, vdev_id))
+		vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+
+	req_msg->vdev_id = vdev_id;
+
+	/* Serialize the req through MC thread */
+	message.bodyptr = req_msg;
+	message.type    = SIR_HAL_SET_PCL_TO_FW;
+	status = scheduler_post_message(QDF_MODULE_ID_POLICY_MGR,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("scheduler_post_msg failed!(err=%d)", status);
+		qdf_mem_free(req_msg);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+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;
+	struct wlan_objmgr_vdev *vdev;
+
+	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;
+			policy_mgr_debug("Use vdev_id:%d for opportunistic upgrade",
+					 vdev_id);
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (conn_index == MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		vdev = wlan_objmgr_pdev_get_first_vdev(pm_ctx->pdev,
+						       WLAN_POLICY_MGR_ID);
+		if (vdev) {
+			vdev_id = wlan_vdev_get_id(vdev);
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		}
+		policy_mgr_debug("Use default 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 =
+				POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC;
+	struct policy_mgr_psoc_priv_obj *pm_ctx = policy_mgr_get_context(psoc);
+
+	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;
+	} else if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
+		   pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) {
+		policy_mgr_debug("SAP is in CAC_IN_PROGRESS state, restarting");
+		policy_mgr_restart_opportunistic_timer(psoc, false);
+		return;
+	}
+	session_id = pm_get_vdev_id_of_first_conn_idx(psoc);
+	policy_mgr_next_actions(psoc, session_id, action,
+				reason, POLICY_MGR_DEF_REQ_ID);
+}
+
+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_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;
+	case CH_WIDTH_320MHZ:
+		bw = HW_MODE_320_MHZ;
+		break;
+	default:
+		policy_mgr_err("Unknown channel BW type %d", chan_width);
+		break;
+	}
+
+	return bw;
+}
+
+enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw)
+{
+	enum phy_ch_width ch_width = CH_WIDTH_INVALID;
+
+	switch (bw) {
+	case HW_MODE_20_MHZ:
+		ch_width = CH_WIDTH_20MHZ;
+		break;
+	case HW_MODE_40_MHZ:
+		ch_width = CH_WIDTH_40MHZ;
+		break;
+	case HW_MODE_80_MHZ:
+		ch_width = CH_WIDTH_80MHZ;
+		break;
+	case HW_MODE_160_MHZ:
+		ch_width = CH_WIDTH_160MHZ;
+		break;
+	case HW_MODE_80_PLUS_80_MHZ:
+		ch_width = CH_WIDTH_80P80MHZ;
+		break;
+	case HW_MODE_5_MHZ:
+		ch_width = CH_WIDTH_5MHZ;
+		break;
+	case HW_MODE_10_MHZ:
+		ch_width = CH_WIDTH_10MHZ;
+		break;
+	case HW_MODE_320_MHZ:
+		ch_width = CH_WIDTH_320MHZ;
+		break;
+	default:
+		policy_mgr_err("Invalid phy_ch_width type %d", ch_width);
+		break;
+	}
+
+	return ch_width;
+}
+
+static bool
+is_preset_in_chlist(uint32_t chan_freq, const uint32_t *chlist,
+		    uint32_t chlist_len)
+{
+	uint32_t i;
+
+	for (i = 0; i < chlist_len; i++)
+		if (chlist[i] == chan_freq)
+			return true;
+
+	return false;
+}
+
+static void
+get_sbs_chlist(struct wlan_objmgr_psoc *psoc,
+	       uint32_t *sbs_freqs, uint32_t *sbs_num, uint32_t chan_freq,
+	       const uint32_t *chlist1, uint32_t chlist1_len,
+	       const uint32_t *chlist2, uint32_t chlist2_len)
+{
+	uint32_t size_of_sbs = *sbs_num;
+	uint32_t i;
+
+	*sbs_num = 0;
+	for (i = 0; i < chlist1_len; i++) {
+		if (*sbs_num >= size_of_sbs)
+			return;
+		if (policy_mgr_are_sbs_chan(psoc, chan_freq, chlist1[i]))
+			sbs_freqs[(*sbs_num)++] = chlist1[i];
+	}
+	for (i = 0; i < chlist2_len; i++) {
+		if (*sbs_num >= size_of_sbs)
+			return;
+		if (policy_mgr_are_sbs_chan(psoc, chan_freq, chlist2[i]))
+			sbs_freqs[(*sbs_num)++] = chlist2[i];
+	}
+}
+
+static void
+get_rest_chlist(uint32_t *rest_freqs, uint32_t *rest_num,
+		uint32_t *scc_freqs, uint32_t scc_num,
+		uint32_t *sbs_freqs, uint32_t sbs_num,
+		const uint32_t *chlist1, uint32_t chlist1_len,
+		const uint32_t *chlist2, uint32_t chlist2_len)
+{
+	uint32_t size_of_rest = *rest_num;
+	uint32_t i;
+
+	*rest_num = 0;
+	for (i = 0; i < chlist1_len; i++) {
+		if (*rest_num >= size_of_rest)
+			return;
+		if (is_preset_in_chlist(chlist1[i], scc_freqs, scc_num) ||
+		    is_preset_in_chlist(chlist1[i], sbs_freqs, sbs_num))
+			continue;
+		rest_freqs[(*rest_num)++] = chlist1[i];
+	}
+	for (i = 0; i < chlist2_len; i++) {
+		if (*rest_num >= size_of_rest)
+			return;
+		if (is_preset_in_chlist(chlist2[i], scc_freqs, scc_num) ||
+		    is_preset_in_chlist(chlist2[i], sbs_freqs, sbs_num))
+			continue;
+		rest_freqs[(*rest_num)++] = chlist2[i];
+	}
+}
+
+static void
+get_sub_channels(struct wlan_objmgr_psoc *psoc,
+		 uint32_t *sbs_freqs, uint32_t *sbs_num,
+		 uint32_t *scc_freqs, uint32_t *scc_num,
+		 uint32_t *rest_freqs, uint32_t *rest_num,
+		 const uint32_t *chlist_5g, uint32_t chlist_5g_len,
+		 const uint32_t *chlist_6g, uint32_t chlist_6g_len)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i = 0;
+	const uint32_t *chlist1;
+	uint8_t chlist1_len;
+	const uint32_t *chlist2;
+	uint8_t chlist2_len;
+	uint32_t size_of_scc = *scc_num;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		*scc_num = 0;
+		*sbs_num = 0;
+		*rest_num = 0;
+		return;
+	}
+
+	if (pm_ctx->cfg.pcl_band_priority == POLICY_MGR_PCL_BAND_6G_THEN_5G) {
+		chlist1 = chlist_6g;
+		chlist1_len = chlist_6g_len;
+		chlist2 = chlist_5g;
+		chlist2_len = chlist_5g_len;
+	} else {
+		chlist1 = chlist_5g;
+		chlist1_len = chlist_5g_len;
+		chlist2 = chlist_6g;
+		chlist2_len = chlist_6g_len;
+	}
+	*scc_num = 0;
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	/* For SCC channels, 6G first then 5G */
+	i = 0;
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(i)) {
+		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(
+		    pm_conc_connection_list[i].freq)) {
+			if (*scc_num < size_of_scc &&
+			    !is_preset_in_chlist(
+					pm_conc_connection_list[i].freq,
+					scc_freqs, *scc_num))
+				scc_freqs[(*scc_num)++] =
+					pm_conc_connection_list[i].freq;
+		}
+		i++;
+	}
+	i = 0;
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(i)) {
+		if (WLAN_REG_IS_5GHZ_CH_FREQ(
+		    pm_conc_connection_list[i].freq)) {
+			if (*scc_num < size_of_scc &&
+			    !is_preset_in_chlist(
+					pm_conc_connection_list[i].freq,
+					scc_freqs, *scc_num))
+				scc_freqs[(*scc_num)++] =
+					pm_conc_connection_list[i].freq;
+		}
+		i++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	/*
+	 * scc_num is number of existing 5Ghz or 6Ghz connection freqs.
+	 * So check if they are all on same mac in SBS, to get SBS
+	 * freq list.
+	 *
+	 * For scc_num > 2, it will always be with freq across
+	 * both mac, as all 3 cannot be on same mac.
+	 *
+	 * For scc_num == 0, i.e no freq on 5/6Ghz there is no need to
+	 * check for SBS freq.
+	 *
+	 * So check only if scc_num == 1 or 2, with both freq
+	 * on same mac in SBS mode (non-SBS) in case of 2.
+	 *
+	 * sbs_num contains the max number of freq element can be saved in
+	 * sbs_freqs array when this function is called.
+	 * It will contain actual freq element number in the array on return.
+	 * Clear it to 0 if no sbs freq is populated by get_sbs_chlist.
+	 */
+	if (policy_mgr_is_hw_sbs_capable(psoc) &&
+	    (*scc_num == 1 ||
+	     (*scc_num == 2 &&
+	      !policy_mgr_are_sbs_chan(psoc, scc_freqs[0],
+				       scc_freqs[1]))))
+		get_sbs_chlist(psoc, sbs_freqs, sbs_num, scc_freqs[0],
+			       chlist1, chlist1_len, chlist2, chlist2_len);
+	else
+		*sbs_num = 0;
+
+	get_rest_chlist(rest_freqs, rest_num, scc_freqs, *scc_num,
+			sbs_freqs, *sbs_num, chlist1, chlist1_len,
+			chlist2, chlist2_len);
+}
+
+/**
+ * add_sbs_chlist_to_pcl() - add sbs channel list in pcl
+ *
+ * @psoc: psoc object
+ * @pcl_freqs: pcl frequencies
+ * @pcl_weights: pcl weight
+ * @pcl_sz: pcl size
+ * @index: pcl index
+ * @skip_6gh_channel: to skip 6g channels or not
+ * @chlist_5: 5g channel list
+ * @chlist_len_5: 5g channel list length
+ * @chlist_6: 6g channel list
+ * @chlist_len_6: 6g channel list length
+ * @order: pcl order
+ * @high_5_band_scc_present: 5 GHz high band connection present
+ * @low_5_band_scc_present: 5 GHz low band connection present
+ *
+ * Get the pcl list based on current sbs concurrency
+ *
+ * Return: None
+ */
+static void
+add_sbs_chlist_to_pcl(struct wlan_objmgr_psoc *psoc,
+		      uint32_t *pcl_freqs, uint8_t *pcl_weights,
+		      uint32_t pcl_sz, uint32_t *index,
+		      bool skip_6gh_channel,
+		      const uint32_t *chlist_5, uint8_t chlist_len_5,
+		      const uint32_t *chlist_6, uint8_t chlist_len_6,
+		      enum policy_mgr_pcl_channel_order order,
+		      bool *high_5_band_scc_present,
+		      bool *low_5_band_scc_present)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	qdf_freq_t sbs_cut_off_freq;
+	qdf_freq_t scc_freq = 0;
+	uint32_t i, conn_index = 0;
+	struct policy_mgr_conc_connection_info *cl;
+
+	if (!policy_mgr_is_hw_sbs_capable(psoc))
+		return;
+
+	sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc);
+	if (!sbs_cut_off_freq) {
+		policy_mgr_err("Invalid cut off freq");
+		return;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (order == POLICY_MGR_PCL_ORDER_SCC_5G_LOW_5G_LOW) {
+		/* Add 5G low SCC channel*/
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		cl = pm_conc_connection_list;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+			    cl[conn_index].freq < sbs_cut_off_freq) {
+				pcl_freqs[*index] = cl[conn_index].freq;
+				scc_freq = cl[conn_index].freq;
+				pcl_weights[*index] =
+						WEIGHT_OF_GROUP1_PCL_CHANNELS;
+				(*index)++;
+				*low_5_band_scc_present = true;
+				break;
+			}
+
+			conn_index++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		/* Add rest 5G low channels*/
+		for (i = 0; i < chlist_len_5 && *index < pcl_sz; i++) {
+			if (chlist_5[i] > sbs_cut_off_freq)
+				return;
+
+			/* SCC channel is already added in pcl freq*/
+			if (scc_freq == chlist_5[i])
+				continue;
+
+			pcl_freqs[*index] = chlist_5[i];
+			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+			(*index)++;
+		}
+		for (i = 0; i < chlist_len_6 && *index < pcl_sz &&
+		     !skip_6gh_channel; i++) {
+			if (chlist_6[i] > sbs_cut_off_freq)
+				return;
+
+			/* SCC channel is already added in pcl freq*/
+			if (scc_freq == chlist_6[i])
+				continue;
+
+			pcl_freqs[*index] = chlist_6[i];
+			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+			(*index)++;
+		}
+	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH ||
+		   order ==
+		   POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH_SCC_5G_LOW) {
+		/* Add 5G high SCC channel*/
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		cl = pm_conc_connection_list;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+			    cl[conn_index].freq > sbs_cut_off_freq) {
+				pcl_freqs[*index] = cl[conn_index].freq;
+				scc_freq = cl[conn_index].freq;
+				pcl_weights[*index] =
+					WEIGHT_OF_GROUP1_PCL_CHANNELS;
+				(*index)++;
+				*high_5_band_scc_present = true;
+				break;
+			}
+
+			conn_index++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		/* Add rest 5G high channels*/
+		for (i = 0; i < chlist_len_5 && *index < pcl_sz; i++) {
+			if (chlist_5[i] < sbs_cut_off_freq)
+				continue;
+			/* SCC channel is already added in pcl freq*/
+			if (scc_freq == chlist_5[i])
+				continue;
+
+			pcl_freqs[*index] = chlist_5[i];
+			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+			(*index)++;
+		}
+		for (i = 0; i < chlist_len_6 && *index < pcl_sz &&
+		     !skip_6gh_channel; i++) {
+			if (chlist_6[i] < sbs_cut_off_freq)
+				return;
+
+			/* SCC channel is already added in pcl freq*/
+			if (scc_freq == chlist_6[i])
+				continue;
+
+			pcl_freqs[*index] = chlist_6[i];
+			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+			(*index)++;
+		}
+		if (order ==
+		    POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH_SCC_5G_LOW) {
+			conn_index = 0;
+			/* Add 5G low SCC channel*/
+			qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+			cl = pm_conc_connection_list;
+			while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+				if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+				    cl[conn_index].freq < sbs_cut_off_freq) {
+					pcl_freqs[*index] = cl[conn_index].freq;
+					pcl_weights[*index] =
+						WEIGHT_OF_GROUP3_PCL_CHANNELS;
+					(*index)++;
+					break;
+				}
+				conn_index++;
+			}
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		}
+	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_LOW) {
+		/* Add 5 GHz low SCC channel*/
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		cl = pm_conc_connection_list;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+			    cl[conn_index].freq < sbs_cut_off_freq) {
+				pcl_freqs[*index] = cl[conn_index].freq;
+				pcl_weights[*index] =
+						WEIGHT_OF_GROUP1_PCL_CHANNELS;
+				(*index)++;
+				*low_5_band_scc_present = true;
+				break;
+			}
+
+			conn_index++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_HIGH) {
+		/* Add 5 GHz high SCC channel*/
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		cl = pm_conc_connection_list;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+			    cl[conn_index].freq > sbs_cut_off_freq) {
+				pcl_freqs[*index] = cl[conn_index].freq;
+				pcl_weights[*index] =
+					WEIGHT_OF_GROUP1_PCL_CHANNELS;
+				(*index)++;
+				*high_5_band_scc_present = true;
+				break;
+			}
+			conn_index++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_LOW_MCC_5G_HIGH) {
+		/* Add 5 GHz low SCC channel*/
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		cl = pm_conc_connection_list;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+			    cl[conn_index].freq < sbs_cut_off_freq) {
+				pcl_freqs[*index] = cl[conn_index].freq;
+				pcl_weights[*index] =
+						WEIGHT_OF_GROUP1_PCL_CHANNELS;
+				(*index)++;
+				*low_5_band_scc_present = true;
+				break;
+			}
+
+			conn_index++;
+		}
+
+		/* Add 5 GHz high MCC channels*/
+		for (i = 0; i < chlist_len_5 && *index < pcl_sz; i++) {
+			/* Skip 5 GHz low frequencies */
+			if (chlist_5[i] < sbs_cut_off_freq)
+				continue;
+
+			conn_index = 0;
+			/* Skip SCC channels */
+			while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+				if (cl[conn_index].freq == chlist_5[i])
+					break;
+				conn_index++;
+			}
+
+			if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index))
+				continue;
+			pcl_freqs[*index] = chlist_5[i];
+			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+			(*index)++;
+		}
+		for (i = 0; i < chlist_len_6 && *index < pcl_sz &&
+		     !skip_6gh_channel; i++) {
+			if (chlist_6[i] < sbs_cut_off_freq)
+				return;
+
+			conn_index = 0;
+			/* Skip SCC channels */
+			while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+				if (cl[conn_index].freq == chlist_6[i])
+					break;
+				conn_index++;
+			}
+
+			if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index))
+				continue;
+
+			pcl_freqs[*index] = chlist_6[i];
+			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+			(*index)++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_MCC_5G_LOW) {
+		/* Add 5 GHz high SCC channel*/
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		cl = pm_conc_connection_list;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+			    cl[conn_index].freq > sbs_cut_off_freq) {
+				pcl_freqs[*index] = cl[conn_index].freq;
+				pcl_weights[*index] =
+						WEIGHT_OF_GROUP1_PCL_CHANNELS;
+				(*index)++;
+				*high_5_band_scc_present = true;
+				break;
+			}
+
+			conn_index++;
+		}
+
+		/* Add 5 GHz low MCC channels */
+		for (i = 0; i < chlist_len_5 && *index < pcl_sz; i++) {
+			/* Skip 5 GHz high frequencies */
+			if (chlist_5[i] > sbs_cut_off_freq)
+				continue;
+
+			conn_index = 0;
+			/* Skip SCC channels */
+			while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+				if (cl[conn_index].freq == chlist_5[i])
+					break;
+				conn_index++;
+			}
+
+			if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index))
+				continue;
+			pcl_freqs[*index] = chlist_5[i];
+			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
+			(*index)++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	}   else {
+		policy_mgr_debug("invalid order %d", order);
+		return;
+	}
+
+	policy_mgr_debug("new pcl index %d", *index);
+
+}
+
+static void
+add_chlist_to_pcl(struct wlan_objmgr_pdev *pdev,
+		  uint32_t *pcl_freqs, uint8_t *pcl_weights,
+		  uint32_t pcl_sz, uint32_t *index, uint32_t weight,
+		  const uint32_t *chlist, uint8_t chlist_len,
+		  bool skip_6gh_channel)
+{
+	uint32_t i;
+
+	for (i = 0; i < chlist_len && *index < pcl_sz; i++) {
+		if (skip_6gh_channel &&
+		    WLAN_REG_IS_6GHZ_CHAN_FREQ(chlist[i]))
+			continue;
+		pcl_freqs[*index] = chlist[i];
+		pcl_weights[*index] = weight;
+		(*index)++;
+	}
+	policy_mgr_debug("Add chlist len %d index %d",
+			 chlist_len, *index);
+}
+
+/**
+ * policy_mgr_get_connection_channels() - provides the channel(s)
+ * on which current connection(s) is
+ * @psoc: psoc object
+ * @mode: conn mode
+ * @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
+ * @group_id: Next available groups for weight assignment
+ * @pcl_freqs: Pointer to the frequencies of PCL
+ * @pcl_weights: Pointer to the weights of PCL
+ * @pcl_sz: Max length of the PCL list
+ * @index: Index from which the PCL list needs to be populated,
+ *  will increase accordingly if any channel is obtained
+ *
+ * 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,
+				   enum policy_mgr_con_mode mode,
+				   enum policy_mgr_pcl_channel_order order,
+				   bool skip_dfs_channel,
+				   enum policy_mgr_pcl_group_id group_id,
+				   uint32_t *pcl_freqs, uint8_t *pcl_weights,
+				   uint32_t pcl_sz, uint32_t *index)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t conn_index = 0;
+	uint32_t weight1, weight2;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_conc_connection_info *cl;
+	bool add_6ghz = true;
+	uint32_t idx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	if (!pcl_freqs || !pcl_weights || !index || !pcl_sz) {
+		policy_mgr_err("list or index is NULL");
+		status = QDF_STATUS_E_INVAL;
+		return status;
+	}
+
+	idx = *index;
+
+	/* 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 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;
+	}
+	if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode))
+		add_6ghz = false;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	cl = pm_conc_connection_list;
+	if (POLICY_MGR_PCL_ORDER_NONE == order) {
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ(
+				cl[conn_index].freq);
+			if (skip_dfs_channel && wlan_reg_is_dfs_for_freq(
+			    pm_ctx->pdev, cl[conn_index].freq)) {
+				conn_index++;
+			} else if ((idx < pcl_sz) &&
+				   (!is_6ghz_ch || add_6ghz)) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight1;
+				idx++;
+			} else {
+				conn_index++;
+			}
+		}
+	} 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_FREQ(cl[conn_index].freq) &&
+			    idx < pcl_sz) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight1;
+				idx++;
+			} else {
+				conn_index++;
+			}
+		}
+
+		conn_index = 0;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (skip_dfs_channel &&
+			    wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
+						     cl[conn_index].freq)) {
+				conn_index++;
+			} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+					cl[conn_index].freq) &&
+				   (idx < pcl_sz)) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight2;
+				idx++;
+			} else {
+				conn_index++;
+			}
+		}
+		conn_index = 0;
+		while (add_6ghz &&
+		       PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ(
+				cl[conn_index].freq);
+			if (is_6ghz_ch && idx < pcl_sz) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight2;
+				idx++;
+			} else {
+				conn_index++;
+			}
+		}
+	} 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_for_freq(
+			    pm_ctx->pdev, cl[conn_index].freq)) {
+				conn_index++;
+			} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+					cl[conn_index].freq) &&
+				   (idx < pcl_sz)) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight1;
+				idx++;
+			} else {
+				conn_index++;
+			}
+		}
+		conn_index = 0;
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+			    idx < pcl_sz) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight2;
+				idx++;
+
+			} else {
+				conn_index++;
+			}
+		}
+		conn_index = 0;
+		while (add_6ghz &&
+		       PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ(
+				cl[conn_index].freq);
+			if (is_6ghz_ch && idx < pcl_sz) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight2;
+				idx++;
+			} else {
+				conn_index++;
+			}
+		}
+	} else if (order == POLICY_MGR_PCL_ORDER_2G) {
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
+			    idx < pcl_sz) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight1;
+				idx++;
+
+			} else {
+				conn_index++;
+			}
+		}
+	} else if (order == POLICY_MGR_PCL_ORDER_5G) {
+		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			if (skip_dfs_channel &&
+			    wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
+						     cl[conn_index].freq)) {
+				conn_index++;
+			} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+					cl[conn_index].freq) &&
+				   (idx < pcl_sz)) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight1;
+				idx++;
+			} else {
+				conn_index++;
+			}
+		}
+		conn_index = 0;
+		while (add_6ghz &&
+		       PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+			bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ(
+				cl[conn_index].freq);
+			if (is_6ghz_ch && idx < pcl_sz) {
+				pcl_freqs[idx] = cl[conn_index++].freq;
+				pcl_weights[idx] = weight1;
+				idx++;
+			} else {
+				conn_index++;
+			}
+		}
+	} else {
+		policy_mgr_err("unknown order %d", order);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	*index = idx;
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+/**
+ * policy_mgr_set_weight_of_disabled_inactive_channels_to_zero() - set weight
+ * of disabled and inactive channels to 0
+ * @psoc: pointer to soc
+ * @pcl_channels: preferred channel freq 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 disabled and inactive channels to 0
+ *
+ * Return: None
+ */
+void policy_mgr_set_weight_of_disabled_inactive_channels_to_zero(
+		struct wlan_objmgr_psoc *psoc, uint32_t *pcl_channels,
+		uint32_t *len, uint8_t *weight_list, uint32_t weight_len)
+{
+	uint8_t i;
+	uint32_t orig_channel_count = 0;
+	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;
+	}
+
+	if (len)
+		orig_channel_count = QDF_MIN(*len, NUM_CHANNELS);
+	else {
+		policy_mgr_err("invalid number of channel length");
+		return;
+	}
+
+	policy_mgr_debug("Set weight of disabled, inactive channels to 0");
+
+	for (i = 0; i < orig_channel_count; i++) {
+		if (wlan_reg_is_6ghz_chan_freq(pcl_channels[i]) &&
+		    !wlan_reg_is_6ghz_band_set(pm_ctx->pdev)) {
+			weight_list[i] = 0;
+		} else {
+			channel_state = wlan_reg_get_channel_state_for_pwrmode(
+						pm_ctx->pdev, pcl_channels[i],
+						REG_CURRENT_PWR_MODE);
+			if (channel_state == CHANNEL_STATE_DISABLE ||
+			    channel_state == CHANNEL_STATE_INVALID)
+				weight_list[i] = 0;
+		}
+	}
+
+	return;
+}
+
+static bool is_freq_present_in_pcl(uint32_t idx, uint32_t *pcl_freqs,
+				   uint32_t chanlist_freq)
+{
+	uint32_t i;
+
+	for (i = 0; i < idx; i++) {
+		if (pcl_freqs[i] == chanlist_freq)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * policy_mgr_add_5g_to_pcl() - add the 5G/6G channels into PCL
+ * @psoc: psoc object
+ * @pcl_freqs: Pointer to the frequencies of PCL
+ * @pcl_weights: Pointer to the weights of PCL
+ * @pcl_sz: Max length of the PCL list
+ * @index: Index from which the PCL list needs to be populated,
+ *  will increase accordingly if any channel is obtained
+ * @group_id: Next available groups for weight assignment
+ * @chlist_5g: Pointer to the 5G channel list
+ * @chlist_5g_len: Length of the 5G channel list
+ * @chlist_6g: Pointer to the 6G channel list
+ * @chlist_6g_len: Length of the 6G channel list
+ *
+ * Return: None
+ */
+static void
+policy_mgr_add_5g_to_pcl(struct wlan_objmgr_psoc *psoc, uint32_t *pcl_freqs,
+			 uint8_t *pcl_weights, uint32_t pcl_sz, uint32_t *index,
+			 enum policy_mgr_pcl_group_id group_id,
+			 const uint32_t *chlist_5g, uint8_t chlist_5g_len,
+			 const uint32_t *chlist_6g, uint8_t chlist_6g_len)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t weight1, weight2;
+	const uint32_t *chlist1;
+	uint8_t chlist1_len;
+	uint8_t list_len = 0;
+	const uint32_t *chlist2;
+	uint8_t chlist2_len;
+	uint32_t i;
+	uint32_t len = 0, idx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	idx = *index;
+
+	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;
+	}
+	if (pm_ctx->cfg.pcl_band_priority == POLICY_MGR_PCL_BAND_6G_THEN_5G) {
+		chlist1 = chlist_6g;
+		chlist1_len = chlist_6g_len;
+		chlist2 = chlist_5g;
+		chlist2_len = chlist_5g_len;
+	} else {
+		chlist1 = chlist_5g;
+		chlist1_len = chlist_5g_len;
+		chlist2 = chlist_6g;
+		chlist2_len = chlist_6g_len;
+	}
+	if ((chlist1_len + idx) > pcl_sz) {
+		policy_mgr_err("no enough weight len %d chlist1_len %d %d",
+			       pcl_sz, chlist1_len, idx);
+		return;
+	}
+	for (i = 0; i < chlist1_len; i++) {
+		if (is_freq_present_in_pcl(idx, pcl_freqs, chlist1[i]))
+			continue;
+		pcl_freqs[idx] = chlist1[i];
+		pcl_weights[idx] = weight1;
+		idx++;
+		list_len++;
+	}
+
+	len += list_len;
+
+	if ((chlist2_len + idx) > pcl_sz) {
+		policy_mgr_err("no enough weight len chlist2_len %d %d %d",
+			       pcl_sz, chlist2_len, idx);
+		return;
+	}
+	list_len = 0;
+	for (i = 0; i < chlist2_len; i++) {
+		if (is_freq_present_in_pcl(idx, pcl_freqs, chlist2[i]))
+			continue;
+		pcl_freqs[idx] = chlist2[i];
+		pcl_weights[idx] = weight2;
+		idx++;
+		list_len++;
+	}
+	len += list_len;
+
+	*index = idx;
+	policy_mgr_debug("Add 5g chlist len %d 6g chlist len %d len %d index %d order %d",
+			 chlist_5g_len, chlist_6g_len, len, idx,
+			 pm_ctx->cfg.pcl_band_priority);
+}
+
+/**
+ * policy_mgr_add_24g_to_pcl() - add the 2.4G channels into PCL
+ * @pcl_freqs: Pointer to the frequencies of PCL
+ * @pcl_weights: Pointer to the weights of PCL
+ * @pcl_sz: Max length of the PCL list
+ * @index: Index from which the PCL list needs to be populated,
+ *  will increase accordingly if any channel is obtained
+ * @weight: group for weight assignment
+ * @chlist_24g: Pointer to the 2.4G channel list
+ * @chlist_24g_len: Length of the 2.4G channel list
+ *
+ * Return: None
+ */
+static void
+policy_mgr_add_24g_to_pcl(uint32_t *pcl_freqs, uint8_t *pcl_weights,
+			  uint32_t pcl_sz, uint32_t *index, uint32_t weight,
+			  const uint32_t *chlist_24g, uint8_t chlist_24g_len)
+{
+	uint32_t num_to_add, i;
+
+	if (*index >= NUM_CHANNELS || *index >= pcl_sz)
+		return;
+	num_to_add = QDF_MIN((*index + chlist_24g_len), pcl_sz) - *index;
+	for (i = 0; i < num_to_add; i++) {
+		if ((i + *index) >= NUM_CHANNELS || (i + *index) >= pcl_sz)
+			break;
+		pcl_weights[i + *index] = weight;
+		pcl_freqs[i + *index] = chlist_24g[i];
+	}
+
+	*index += i;
+	policy_mgr_debug("Add 24g chlist len %d len %d index %d",
+			 chlist_24g_len, num_to_add, *index);
+}
+
+static bool
+policy_mgr_2ghz_connection_present(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	bool is_2ghz_present = false;
+	uint32_t 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 &&
+		    (WLAN_REG_IS_24GHZ_CH_FREQ(
+				pm_conc_connection_list[conn_index].freq))) {
+			is_2ghz_present = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return is_2ghz_present;
+}
+
+/**
+ * policy_mgr_get_channel_list() - provides the channel list
+ * suggestion for new connection
+ * @psoc: psoc handle
+ * @pcl: The preferred channel list enum
+ * @mode: concurrency mode for which channel list is requested
+ * @pcl_channels: PCL channels
+ * @pcl_weights: Weights of the PCL
+ * @pcl_sz: Max length of the PCL list
+ * @len: length of the PCL obtained
+ *
+ * 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,
+				       enum policy_mgr_con_mode mode,
+				       uint32_t *pcl_channels,
+				       uint8_t *pcl_weights,
+				       uint32_t pcl_sz, uint32_t *len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t num_channels = 0;
+	uint32_t chan_index_24 = 0, chan_index_5 = 0, chan_index_6 = 0;
+	uint32_t i = 0;
+	bool skip_6ghz_channel = false;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t *channel_list, *channel_list_24, *channel_list_5,
+		 *sbs_freqs, *channel_list_6, *scc_freqs, *rest_freqs;
+	uint32_t sbs_num, scc_num, rest_num;
+	bool high_5_band_scc_present = false;
+	bool low_5_band_scc_present = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	if ((!pcl_channels) || (!len)) {
+		policy_mgr_err("pcl_channels or len is NULL");
+		return status;
+	}
+
+	*len = 0;
+	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;
+	}
+
+	channel_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
+	channel_list_24 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
+	channel_list_5 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
+	sbs_freqs = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
+	channel_list_6 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
+	rest_freqs = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
+	scc_freqs = qdf_mem_malloc(
+			MAX_NUMBER_OF_CONC_CONNECTIONS * sizeof(uint32_t));
+	if (!channel_list || !channel_list_24 || !channel_list_5 ||
+	    !sbs_freqs || !channel_list_6 || !rest_freqs || !scc_freqs) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	/* 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");
+		goto end;
+	}
+
+	num_channels = QDF_MIN(num_channels, NUM_CHANNELS);
+
+	/* Let's divide the list in 2.4 & 5 Ghz lists */
+	for (i = 0; i < num_channels; i++) {
+		if (wlan_reg_is_24ghz_ch_freq(channel_list[i])) {
+			channel_list_24[chan_index_24++] = channel_list[i];
+		} else if (wlan_reg_is_5ghz_ch_freq(channel_list[i])) {
+			channel_list_5[chan_index_5++] = channel_list[i];
+		} else if (wlan_reg_is_6ghz_chan_freq(channel_list[i])) {
+			/* Add to 5G list until 6G conc support is enabled */
+			channel_list_6[chan_index_6++] = channel_list[i];
+		}
+	}
+	if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) {
+		chan_index_6 = 0;
+		skip_6ghz_channel = true;
+	}
+	sbs_num = NUM_CHANNELS;
+	scc_num = MAX_NUMBER_OF_CONC_CONNECTIONS;
+	rest_num = NUM_CHANNELS;
+
+	/* 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:
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_5G:
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID1_ID2,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_CH:
+	case PM_MCC_CH:
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_NONE,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_CH_24G:
+	case PM_MCC_CH_24G:
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_NONE,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_CH_5G:
+	case PM_MCC_CH_5G:
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_NONE,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID2_ID3,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_24G_SCC_CH:
+	case PM_24G_MCC_CH:
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_NONE,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID2_ID3,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_5G_SCC_CH:
+	case PM_5G_MCC_CH:
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID1_ID2,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_NONE,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID3_ID4,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_24_SCC_ON_5:
+		policy_mgr_get_connection_channels(
+					psoc, mode,
+					POLICY_MGR_PCL_ORDER_24G_THEN_5G,
+					false,
+					POLICY_MGR_PCL_GROUP_ID1_ID2,
+					pcl_channels, pcl_weights, pcl_sz, len);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_SCC_ON_24:
+		policy_mgr_get_connection_channels(
+					psoc, mode,
+					POLICY_MGR_PCL_ORDER_5G_THEN_2G,
+					false,
+					POLICY_MGR_PCL_GROUP_ID1_ID2,
+					pcl_channels, pcl_weights, pcl_sz, len);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_24_SCC_ON_5_24G:
+		policy_mgr_get_connection_channels(
+					psoc, mode,
+					POLICY_MGR_PCL_ORDER_24G_THEN_5G,
+					false,
+					POLICY_MGR_PCL_GROUP_ID1_ID2,
+					pcl_channels, pcl_weights, pcl_sz, len);
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_24_SCC_ON_5_5G:
+		policy_mgr_get_connection_channels(
+					psoc, mode,
+					POLICY_MGR_PCL_ORDER_24G_THEN_5G,
+					false,
+					POLICY_MGR_PCL_GROUP_ID1_ID2,
+					pcl_channels, pcl_weights, pcl_sz, len);
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID3_ID4,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_24_CH_24G:
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_2G,
+						   true,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_CH_5G:
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_5G,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID2_ID3,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_SCC_ON_24_24G:
+		policy_mgr_get_connection_channels(
+					psoc, mode,
+					POLICY_MGR_PCL_ORDER_5G_THEN_2G,
+					false,
+					POLICY_MGR_PCL_GROUP_ID1_ID2,
+					pcl_channels, pcl_weights, pcl_sz, len);
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_SCC_ON_24_5G:
+		policy_mgr_get_connection_channels(
+					psoc, mode,
+					POLICY_MGR_PCL_ORDER_5G_THEN_2G,
+					false,
+					POLICY_MGR_PCL_GROUP_ID1_ID2,
+					pcl_channels, pcl_weights, pcl_sz, len);
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID3_ID4,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_5G_24G:
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_5G,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID2_ID3,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5_5G_SCC_ON_24G:
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_5G,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID2_ID3,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_2G,
+						   false,
+						   POLICY_MGR_PCL_GROUP_ID3_ID4,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		status = QDF_STATUS_SUCCESS;
+		break;
+
+	case PM_24G_SCC_CH_SBS_CH:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_24G_SCC_CH_SBS_CH_5G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP4_PCL_CHANNELS,
+				  rest_freqs, rest_num,
+				  skip_6ghz_channel);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_24G_SBS_CH_MCC_CH:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH_5G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  rest_freqs, rest_num,
+				  skip_6ghz_channel);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH_24G_SCC_CH:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH_SCC_CH_24G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_CH_SBS_CH_24G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH_SCC_CH_5G_24G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  rest_freqs, rest_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP4_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_CH_MCC_CH_SBS_CH_24G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  scc_freqs, scc_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  rest_freqs, rest_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP4_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH_2G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G:
+		add_sbs_chlist_to_pcl(psoc,  pcl_channels,
+				      pcl_weights, pcl_sz,
+				      len,
+				      skip_6ghz_channel,
+				      channel_list_5, chan_index_5,
+				      channel_list_6, chan_index_6,
+				      POLICY_MGR_PCL_ORDER_SCC_5G_LOW_5G_LOW,
+				      &high_5_band_scc_present,
+				      &low_5_band_scc_present);
+
+		/*
+		 * If no 2.4 GHZ connection is present and If 2.4 GHZ is shared
+		 * with 5 GHz low freq then 2.4 GHz can be added as well.
+		 * If no 5 GHz low band connection, 2.4 GHz can be added.
+		 */
+		if ((!policy_mgr_2ghz_connection_present(pm_ctx) ||
+		     !low_5_band_scc_present) &&
+		    policy_mgr_sbs_24_shared_with_low_5(pm_ctx))
+			add_chlist_to_pcl(pm_ctx->pdev,
+					  pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+					  channel_list_24, chan_index_24,
+					  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G:
+	case PM_SCC_ON_5G_HIGH_5G_HIGH_SCC_ON_5G_LOW_PLUS_SHARED_2G:
+		add_sbs_chlist_to_pcl(psoc,  pcl_channels,
+				      pcl_weights, pcl_sz,
+				      len,
+				      skip_6ghz_channel,
+				      channel_list_5, chan_index_5,
+				      channel_list_6, chan_index_6,
+				      (pcl == PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G) ?
+				      POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH :
+				      POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH_SCC_5G_LOW,
+				      &high_5_band_scc_present,
+				      &low_5_band_scc_present);
+		/*
+		 * If no 2.4 GHZ connection is present and if 2.4 GHZ is shared
+		 * with 5 GHz High freq then 2.4 GHz can be added as well
+		 * If no 5 GHz high band connection, 2.4 GHz can be added.
+		 */
+		if ((!policy_mgr_2ghz_connection_present(pm_ctx) ||
+		     !high_5_band_scc_present) &&
+		    policy_mgr_sbs_24_shared_with_high_5(pm_ctx))
+			add_chlist_to_pcl(pm_ctx->pdev,
+					  pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+					  channel_list_24, chan_index_24,
+					  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH_MCC_CH:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  rest_freqs, rest_num,
+				  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_5G_MCC_24G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  rest_freqs, rest_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
+				  channel_list_24, chan_index_24,
+				  false);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_24G:
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_2G,
+						   true,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5G_LOW:
+		add_sbs_chlist_to_pcl(psoc,  pcl_channels,
+				      pcl_weights, pcl_sz,
+				      len,
+				      skip_6ghz_channel,
+				      channel_list_5, chan_index_5,
+				      channel_list_6, chan_index_6,
+				      POLICY_MGR_PCL_ORDER_SCC_5G_LOW,
+				      &high_5_band_scc_present,
+				      &low_5_band_scc_present);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5G_HIGH:
+		add_sbs_chlist_to_pcl(psoc,  pcl_channels,
+				      pcl_weights, pcl_sz,
+				      len,
+				      skip_6ghz_channel,
+				      channel_list_5, chan_index_5,
+				      channel_list_6, chan_index_6,
+				      POLICY_MGR_PCL_ORDER_SCC_5G_HIGH,
+				      &high_5_band_scc_present,
+				      &low_5_band_scc_present);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SBS_CH_MCC_CH_SCC_ON_24_24G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+				  sbs_freqs, sbs_num,
+				  skip_6ghz_channel);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  rest_freqs, rest_num,
+				  skip_6ghz_channel);
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_2G,
+						   true,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_5G_24G:
+		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
+					 pcl_sz, len,
+					 POLICY_MGR_PCL_GROUP_ID1_ID2,
+					 channel_list_5, chan_index_5,
+					 channel_list_6, chan_index_6);
+		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
+					  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
+					  channel_list_24, chan_index_24);
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_MCC_CH_SCC_ON_24G:
+		get_sub_channels(psoc,
+				 sbs_freqs, &sbs_num,
+				 scc_freqs, &scc_num,
+				 rest_freqs, &rest_num,
+				 channel_list_5, chan_index_5,
+				 channel_list_6, chan_index_6);
+		add_chlist_to_pcl(pm_ctx->pdev,
+				  pcl_channels, pcl_weights, pcl_sz,
+				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
+				  rest_freqs, rest_num,
+				  skip_6ghz_channel);
+		policy_mgr_get_connection_channels(psoc, mode,
+						   POLICY_MGR_PCL_ORDER_2G,
+						   true,
+						   POLICY_MGR_PCL_GROUP_ID1_ID2,
+						   pcl_channels, pcl_weights,
+						   pcl_sz, len);
+		status = QDF_STATUS_SUCCESS;
+		break;
+
+	case PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH:
+		add_sbs_chlist_to_pcl(
+				psoc,  pcl_channels, pcl_weights, pcl_sz, len,
+				skip_6ghz_channel, channel_list_5, chan_index_5,
+				channel_list_6, chan_index_6,
+				POLICY_MGR_PCL_ORDER_SCC_5G_LOW_MCC_5G_HIGH,
+				&high_5_band_scc_present,
+				&low_5_band_scc_present);
+		status = QDF_STATUS_SUCCESS;
+		break;
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW:
+		add_sbs_chlist_to_pcl(
+				psoc,  pcl_channels, pcl_weights, pcl_sz, len,
+				skip_6ghz_channel, channel_list_5, chan_index_5,
+				channel_list_6, chan_index_6,
+				POLICY_MGR_PCL_ORDER_SCC_5G_LOW_MCC_5G_HIGH,
+				&high_5_band_scc_present,
+				&low_5_band_scc_present);
+
+		status = QDF_STATUS_SUCCESS;
+		break;
+	default:
+		policy_mgr_err("unknown pcl value %d", pcl);
+		break;
+	}
+
+	policy_mgr_debug("pcl %s: mode %s", pcl_type_to_string(pcl),
+			 device_mode_to_string(mode));
+	policy_mgr_debug("pcl len %d and weight list sz %d",
+			 *len, pcl_sz);
+
+	policy_mgr_set_weight_of_disabled_inactive_channels_to_zero(psoc,
+			pcl_channels, len, pcl_weights, pcl_sz);
+
+end:
+	qdf_mem_free(channel_list);
+	qdf_mem_free(channel_list_24);
+	qdf_mem_free(channel_list_5);
+	qdf_mem_free(sbs_freqs);
+	qdf_mem_free(channel_list_6);
+	qdf_mem_free(scc_freqs);
+	qdf_mem_free(rest_freqs);
+
+	return status;
+}
+
+bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc,
+			     uint32_t ch_freq)
+{
+	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].freq != ch_freq) {
+				match = true;
+				break;
+			}
+		} else if (!WLAN_REG_IS_24GHZ_CH_FREQ
+			(pm_conc_connection_list[index].freq)) {
+			if (pm_conc_connection_list[index].freq != ch_freq &&
+			    !policy_mgr_are_sbs_chan(psoc, ch_freq,
+					pm_conc_connection_list[index].freq)) {
+				match = true;
+				break;
+			}
+		}
+		index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return match;
+}
+
+/**
+ * policy_mgr_allow_same_mac_diff_freq() - Check whether diff freq are allowed
+ * on same mac
+ *
+ * @psoc: Pointer to Psoc
+ * @ch_freq: channel frequency
+ *
+ * Check whether diff freq are allowed on same mac
+ *
+ * Return: True/False
+ */
+static
+bool policy_mgr_allow_same_mac_diff_freq(struct wlan_objmgr_psoc *psoc,
+					 qdf_freq_t ch_freq)
+{
+	bool allow = true;
+
+	if ((pm_conc_connection_list[0].mode == PM_NAN_DISC_MODE &&
+	     pm_conc_connection_list[1].mode == PM_NDI_MODE) ||
+	    (pm_conc_connection_list[0].mode == PM_NDI_MODE &&
+	     pm_conc_connection_list[1].mode == PM_NAN_DISC_MODE)) {
+		/*
+		 * NAN + NDI are managed in Firmware by dividing
+		 * up slots. Connection on NDI is re-negotiable
+		 * and therefore a 3rd connection with the
+		 * same MAC is possible.
+		 */
+	} else if (!policy_mgr_is_hw_dbs_capable(psoc) &&
+		    policy_mgr_is_interband_mcc_supported(psoc)) {
+		if (ch_freq !=  pm_conc_connection_list[0].freq &&
+		    ch_freq !=  pm_conc_connection_list[1].freq) {
+			policy_mgr_rl_debug("don't allow 3rd home channel on same MAC");
+			allow = false;
+		}
+	} else if (policy_mgr_3_freq_always_on_same_mac(psoc, ch_freq,
+					pm_conc_connection_list[0].freq,
+					pm_conc_connection_list[1].freq)) {
+			policy_mgr_rl_debug("don't allow 3rd home channel on same MAC");
+			allow = false;
+	}
+
+	return allow;
+}
+
+/**
+ * policy_mgr_allow_same_mac_same_freq() - check whether given frequency is
+ * allowed for same mac
+ *
+ * @psoc: Pointer to Psoc
+ * @ch_freq: channel frequency
+ * @mode: Concurrency Mode
+ *
+ * check whether given frequency is allowed for same mac
+ *
+ * Return: True/False
+ */
+static
+bool policy_mgr_allow_same_mac_same_freq(struct wlan_objmgr_psoc *psoc,
+					 qdf_freq_t ch_freq,
+					 enum policy_mgr_con_mode mode)
+{
+	bool allow = true;
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc) &&
+	    policy_mgr_is_interband_mcc_supported(psoc)) {
+		policy_mgr_rl_debug("allow 2 intf SCC + new intf ch %d for legacy hw",
+				    ch_freq);
+	} else if ((pm_conc_connection_list[0].mode == PM_NAN_DISC_MODE &&
+		    pm_conc_connection_list[1].mode == PM_NDI_MODE) ||
+		    (pm_conc_connection_list[0].mode == PM_NDI_MODE &&
+		    pm_conc_connection_list[1].mode == PM_NAN_DISC_MODE)) {
+		/*
+		 * NAN + NDI are managed in Firmware by dividing
+		 * up slots. Connection on NDI is re-negotiable
+		 * and therefore a 3rd connection with the
+		 * same MAC is possible.
+		 */
+	} else if (policy_mgr_2_freq_always_on_same_mac(
+			psoc, ch_freq, pm_conc_connection_list[0].freq) &&
+		   !policy_mgr_is_3rd_conn_on_same_band_allowed(
+			psoc, mode, ch_freq)) {
+			policy_mgr_rl_debug("don't allow 3rd home channel on same MAC for sta+multi-AP");
+			allow = false;
+	}
+
+	return allow;
+}
+
+bool policy_mgr_allow_new_home_channel(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode,
+	qdf_freq_t ch_freq, uint32_t num_connections, bool is_dfs_ch,
+	uint32_t ext_flags)
+{
+	bool status = true;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool on_same_mac = false, force_switch_without_dis = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	force_switch_without_dis =
+		policy_mgr_get_mcc_to_scc_switch_mode(psoc) ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (num_connections == 3) {
+		status = policy_mgr_allow_4th_new_freq(psoc,
+						       ch_freq, mode,
+						       ext_flags);
+	} else if (num_connections == 2) {
+	/* No SCC or MCC combination is allowed with / on DFS channel */
+		on_same_mac = policy_mgr_2_freq_always_on_same_mac(psoc,
+					pm_conc_connection_list[0].freq,
+					pm_conc_connection_list[1].freq);
+		if (force_switch_without_dis && is_dfs_ch &&
+		    ((pm_conc_connection_list[0].ch_flagext &
+		      (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) ||
+		     (pm_conc_connection_list[1].ch_flagext &
+		      (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)))) {
+			policy_mgr_rl_debug("Existing DFS connection, new 3-port DFS connection is not allowed");
+			status = false;
+		} else if (((pm_conc_connection_list[0].freq !=
+			     pm_conc_connection_list[1].freq) ||
+			    force_switch_without_dis) && on_same_mac) {
+			status = policy_mgr_allow_same_mac_diff_freq(psoc,
+								     ch_freq);
+		} else if (on_same_mac) {
+			status = policy_mgr_allow_same_mac_same_freq(psoc,
+								     ch_freq,
+								     mode);
+		}
+	} else if (num_connections == 1 && force_switch_without_dis &&
+		   is_dfs_ch &&
+		   (pm_conc_connection_list[0].ch_flagext &
+		    (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2))) {
+		policy_mgr_rl_debug("Existing DFS connection, new 2-port DFS connection is not allowed");
+		status = false;
+	} else if ((num_connections == 1) &&
+		   !policy_mgr_is_hw_dbs_capable(psoc) &&
+		   !policy_mgr_is_interband_mcc_supported(psoc)) {
+		/* For target which is single mac and doesn't support
+		 * interband MCC
+		 */
+		if ((pm_conc_connection_list[0].mode != PM_NAN_DISC_MODE) &&
+		    (mode != PM_NAN_DISC_MODE))
+			status = policy_mgr_2_freq_always_on_same_mac(psoc,
+								   ch_freq,
+					pm_conc_connection_list[0].freq);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc,
+				uint32_t ch_freq, 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 ((pm_conc_connection_list[list[index]].ch_flagext &
+		     (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
+		    (ch_freq != pm_conc_connection_list[list[index]].freq &&
+		     !policy_mgr_are_sbs_chan(psoc, ch_freq,
+				pm_conc_connection_list[list[index]].freq))) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			policy_mgr_rl_debug("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_get_pref_force_scc_freq() - Get preferred force SCC
+ * channel frequency
+ * @psoc: Pointer to Psoc
+ * @vdev_id: vdev id
+ * @intf_ch_freq: prefer force scc frequency
+ * @sap_ch_freq: sap/go channel starting channel frequency
+ * @acs_band: acs band
+ * @allow_6ghz: allow 6 Ghz channel or not
+ *
+ * This API will consider protocol 6ghz allow flag - allow_6ghz.
+ * Also for regdomain, it will consider PCL allow or not.
+ * For example, if STA is on 6ghz LPI mode, SAP is not allowed
+ * force scc to 6ghz, see API
+ * policy_mgr_modify_sap_pcl_for_6G_channels.
+ *
+ * Return: QDF_STATUS_SUCCESS if get preferred force scc channel.
+ */
+static QDF_STATUS
+policy_mgr_get_pref_force_scc_freq(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   qdf_freq_t *intf_ch_freq,
+				   qdf_freq_t sap_ch_freq,
+				   uint32_t acs_band,
+				   bool allow_6ghz)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum policy_mgr_con_mode mode;
+	QDF_STATUS status;
+	uint32_t i;
+	struct policy_mgr_pcl_list pcl;
+	bool allow_2ghz_only = false;
+	qdf_freq_t scc_ch_freq_on_same_mac = 0;
+	qdf_freq_t scc_ch_freq_on_diff_mac = 0;
+	qdf_freq_t scc_ch_freq_same_as_sap = 0;
+	qdf_freq_t non_scc_ch_freq_on_same_mac = 0;
+	qdf_freq_t non_scc_ch_freq_on_diff_mac = 0;
+	qdf_freq_t non_scc_ch_freq_same_as_sap = 0;
+	enum QDF_OPMODE op_mode;
+	qdf_freq_t pcl_freq;
+	bool same_mac, sbs_ml_sta_present = false, dbs_ml_sta_present = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (policy_mgr_is_mlo_in_mode_dbs(psoc, PM_STA_MODE, NULL, NULL))
+		dbs_ml_sta_present = true;
+	else if (policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE, NULL, NULL))
+		sbs_ml_sta_present = true;
+
+	op_mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id);
+
+	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),
+				    vdev_id);
+	if (QDF_IS_STATUS_ERROR(status) || !pcl.pcl_len) {
+		policy_mgr_err("get pcl failed for mode: %d, pcl len %d", mode,
+			       pcl.pcl_len);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if ((acs_band == QCA_ACS_MODE_IEEE80211B ||
+	     acs_band == QCA_ACS_MODE_IEEE80211G) &&
+	     WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
+		allow_2ghz_only = true;
+
+	/*
+	 * The preferred force SCC channel is SAP original channel,
+	 * and then the SCC channel on the same mac, and then the SCC
+	 * channel on the different mac.
+	 * Make sure the PCL only contains valid channels - not
+	 * causing 3 vif on same mac.
+	 * If none of channels are available, we have to keep SAP channel
+	 * unchanged, and that may cause SAP MCC.
+	 */
+	for (i = 0; i < pcl.pcl_len; i++) {
+		pcl_freq = pcl.pcl_list[i];
+
+		if (!allow_6ghz && WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_freq))
+			continue;
+		if (allow_2ghz_only && !WLAN_REG_IS_24GHZ_CH_FREQ(pcl_freq))
+			continue;
+
+		/*
+		 * If ML STA is present, as ML STA cannot be on same mac,
+		 * check same band logic as per the ML hw mode, else
+		 * use the API which is hw mode agnostic.
+		 */
+		if (dbs_ml_sta_present)
+			same_mac = policy_mgr_2_freq_same_mac_in_dbs(pm_ctx,
+								sap_ch_freq,
+								pcl_freq);
+		else if (sbs_ml_sta_present)
+			same_mac = policy_mgr_2_freq_same_mac_in_sbs(pm_ctx,
+								sap_ch_freq,
+								pcl_freq);
+		else
+			same_mac = policy_mgr_2_freq_always_on_same_mac(psoc,
+								sap_ch_freq,
+								pcl_freq);
+		if (!((pm_conc_connection_list[0].in_use &&
+		       (pcl_freq == pm_conc_connection_list[0].freq)) ||
+		      (pm_conc_connection_list[1].in_use &&
+		       (pcl_freq == pm_conc_connection_list[1].freq)) ||
+		      (pm_conc_connection_list[2].in_use &&
+		       (pcl_freq == pm_conc_connection_list[2].freq)))) {
+			if (sap_ch_freq == pcl_freq)
+				non_scc_ch_freq_same_as_sap = pcl_freq;
+			else if (!non_scc_ch_freq_on_same_mac && same_mac)
+				non_scc_ch_freq_on_same_mac = pcl_freq;
+			else if (!non_scc_ch_freq_on_diff_mac && !same_mac)
+				non_scc_ch_freq_on_diff_mac = pcl_freq;
+			continue;
+		}
+
+		if (sap_ch_freq == pcl_freq)
+			scc_ch_freq_same_as_sap = pcl_freq;
+		else if (!scc_ch_freq_on_same_mac && same_mac)
+			scc_ch_freq_on_same_mac = pcl_freq;
+		else if (!scc_ch_freq_on_diff_mac && !same_mac)
+			scc_ch_freq_on_diff_mac = pcl_freq;
+	}
+
+	if (scc_ch_freq_same_as_sap)
+		*intf_ch_freq = scc_ch_freq_same_as_sap;
+	else if (scc_ch_freq_on_same_mac)
+		*intf_ch_freq = scc_ch_freq_on_same_mac;
+	else if (non_scc_ch_freq_same_as_sap)
+		*intf_ch_freq = non_scc_ch_freq_same_as_sap;
+	else if (scc_ch_freq_on_diff_mac)
+		*intf_ch_freq = scc_ch_freq_on_diff_mac;
+	else if (non_scc_ch_freq_on_same_mac)
+		*intf_ch_freq = non_scc_ch_freq_on_same_mac;
+	else if (non_scc_ch_freq_on_diff_mac)
+		*intf_ch_freq = non_scc_ch_freq_on_diff_mac;
+	else
+		*intf_ch_freq = 0;
+
+	policy_mgr_debug("2ghz_only %d allow_6ghz %d, ml sta SBS:%d DBS:%d, SCC: same_as_sap %d same_mac %d on_diff_mac %d, NON-SCC: same_as_sap %d same_mac %d on_diff_mac %d. intf_ch_freq %d",
+			 allow_2ghz_only, allow_6ghz, sbs_ml_sta_present,
+			 dbs_ml_sta_present, scc_ch_freq_same_as_sap,
+			 scc_ch_freq_on_same_mac, scc_ch_freq_on_diff_mac,
+			 non_scc_ch_freq_same_as_sap,
+			 non_scc_ch_freq_on_same_mac,
+			 non_scc_ch_freq_on_diff_mac, *intf_ch_freq);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_handle_sta_sap_fav_channel() - Get preferred force SCC
+ * channel frequency using favorite mandatory channel list for STA+SAP
+ * concurrency
+ * @psoc: Pointer to Psoc
+ * @pm_ctx: pm ctx
+ * @vdev_id: vdev id
+ * @intf_ch_freq: prefer force scc frequency
+ * @sap_ch_freq: sap/go channel starting channel frequency
+ * @acs_band: acs band
+ *
+ * Return: QDF_STATUS_SUCCESS if a valid favorite mandatory force scc channel
+ * is found.
+ */
+static QDF_STATUS
+policy_mgr_handle_sta_sap_fav_channel(struct wlan_objmgr_psoc *psoc,
+				      struct policy_mgr_psoc_priv_obj *pm_ctx,
+				      uint8_t vdev_id, qdf_freq_t sap_ch_freq,
+				      qdf_freq_t *intf_ch_freq,
+				      uint32_t acs_band)
+{
+	bool sta_sap_scc_on_indoor_channel_allowed;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	qdf_freq_t user_config_freq;
+
+	 /* intf_ch_freq and SAP freq in same band */
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq) ==
+	    WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
+		return policy_mgr_get_sap_mandatory_channel(psoc, sap_ch_freq,
+							intf_ch_freq, vdev_id);
+
+	/* intf_ch_freq and SAP freq in different band */
+	/*
+	 * STA + SAP where doing SCC on 5 GHz indoor channel.
+	 * STA moved/roamed to 2.4 GHz. Move SAP to initially
+	 * started channel.
+	 *
+	 * STA+SAP where STA is moved/roamed to 5GHz indoor
+	 * and SAP is on 2.4 GHz due to previous concurrency.
+	 * Move SAP to STA channel on SCC.
+	 */
+	sta_sap_scc_on_indoor_channel_allowed =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+
+	/*
+	 * SAP and interface freq in different band and 5 GHz freq is
+	 * indoor
+	 */
+	if (sta_sap_scc_on_indoor_channel_allowed &&
+	    ((wlan_reg_is_freq_indoor(pm_ctx->pdev, sap_ch_freq) &&
+	    WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq)) ||
+	    (wlan_reg_is_freq_indoor(pm_ctx->pdev, *intf_ch_freq) &&
+	     WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq) &&
+	     !(acs_band == QCA_ACS_MODE_IEEE80211B ||
+	       acs_band == QCA_ACS_MODE_IEEE80211G)))) {
+		status = policy_mgr_get_sap_mandatory_channel(psoc, sap_ch_freq,
+							      intf_ch_freq,
+							      vdev_id);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			return status;
+	}
+
+	user_config_freq =
+		policy_mgr_get_user_config_sap_freq(psoc, vdev_id);
+
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq) &&
+	    user_config_freq &&
+	    !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq) &&
+	    (wlan_reg_get_channel_state_for_pwrmode(pm_ctx->pdev, *intf_ch_freq,
+			REG_CURRENT_PWR_MODE) == CHANNEL_STATE_ENABLE)) {
+		status = policy_mgr_get_sap_mandatory_channel(psoc, sap_ch_freq,
+							      intf_ch_freq,
+							      vdev_id);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			return status;
+	}
+
+	return status;
+}
+
+QDF_STATUS
+policy_mgr_handle_go_sap_fav_channel(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id, qdf_freq_t sap_ch_freq,
+				     qdf_freq_t *intf_ch_freq)
+{
+	QDF_STATUS status;
+	uint8_t go_count;
+	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	struct policy_mgr_pcl_list pcl;
+	uint32_t i;
+
+	go_count = policy_mgr_get_mode_specific_conn_info(psoc,
+							  op_ch_freq_list,
+							  vdev_id_list,
+							  PM_P2P_GO_MODE);
+	if (!go_count)
+		return QDF_STATUS_E_FAILURE;
+
+	/* According to requirement, SAP should move to 2.4 GHz if P2P GO is
+	 * on 5G/6G.
+	 */
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[0]) ||
+	    WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
+		return QDF_STATUS_E_FAILURE;
+
+	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, vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Unable to get PCL for SAP");
+		return status;
+	}
+
+	for (i = 0; i < pcl.pcl_len; i++) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(pcl.pcl_list[i])) {
+			*intf_ch_freq = pcl.pcl_list[i];
+			policy_mgr_debug("sap move to %d because GO on %d",
+					 *intf_ch_freq, op_ch_freq_list[0]);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * policy_mgr_handle_sap_fav_channel() - Get preferred force SCC
+ * channel frequency using favorite mandatory channel list
+ * @psoc: Pointer to Psoc
+ * @pm_ctx: pm ctx
+ * @vdev_id: vdev id
+ * @intf_ch_freq: prefer force scc frequency
+ * @sap_ch_freq: sap/go channel starting channel frequency
+ * @acs_band: acs band
+ *
+ * Return: QDF_STATUS_SUCCESS if a valid favorite mandatory force scc channel
+ * is found.
+ */
+static QDF_STATUS
+policy_mgr_handle_sap_fav_channel(struct wlan_objmgr_psoc *psoc,
+				  struct policy_mgr_psoc_priv_obj *pm_ctx,
+				  uint8_t vdev_id, qdf_freq_t sap_ch_freq,
+				  qdf_freq_t *intf_ch_freq,
+				  uint32_t acs_band)
+{
+	QDF_STATUS status;
+	uint8_t sta_count, go_count;
+
+	go_count = policy_mgr_mode_specific_connection_count(psoc,
+							     PM_P2P_GO_MODE,
+							     NULL);
+	if (go_count) {
+		status = policy_mgr_handle_go_sap_fav_channel(
+					psoc, vdev_id,
+					sap_ch_freq, intf_ch_freq);
+		if (QDF_IS_STATUS_SUCCESS(status) &&
+		    *intf_ch_freq && *intf_ch_freq != sap_ch_freq)
+			return QDF_STATUS_SUCCESS;
+	}
+
+	sta_count = policy_mgr_mode_specific_connection_count(psoc,
+							      PM_STA_MODE,
+							      NULL);
+	if (sta_count && sta_count < 2)
+		return policy_mgr_handle_sta_sap_fav_channel(
+					psoc, pm_ctx, vdev_id,
+					sap_ch_freq, intf_ch_freq,
+					acs_band);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+void policy_mgr_check_scc_channel(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t *intf_ch_freq,
+				  qdf_freq_t sap_ch_freq,
+				  uint8_t vdev_id, uint8_t cc_mode)
+{
+	uint32_t num_connections, acs_band = QCA_ACS_MODE_IEEE80211ANY;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	uint8_t num_cxn_del = 0;
+	bool allow_6ghz = true;
+	uint8_t sta_count;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	/* Always do force SCC on non-DBS platforms */
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return;
+
+	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
+							      NULL);
+	if (pm_ctx->hdd_cbacks.wlan_get_sap_acs_band) {
+		status = pm_ctx->hdd_cbacks.wlan_get_sap_acs_band(psoc,
+								  vdev_id,
+								  &acs_band);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			policy_mgr_debug("acs_band: %d", acs_band);
+	}
+
+	/* Handle STA/P2P + SAP mandaory freq cases */
+	if (cc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) {
+		status = policy_mgr_handle_sap_fav_channel(
+				psoc, pm_ctx, vdev_id, sap_ch_freq,
+				intf_ch_freq, acs_band);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			return;
+		policy_mgr_debug("no mandatory channels (%d, %d)", sap_ch_freq,
+				 *intf_ch_freq);
+	} else if (sta_count && policy_mgr_is_hw_dbs_capable(psoc)) {
+		policy_mgr_sap_on_non_psc_channel(psoc, intf_ch_freq, vdev_id);
+	}
+
+	/* Get allow 6Gz before interface entry is temporary deleted */
+	if (sap_ch_freq && !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) &&
+	    !policy_mgr_get_ap_6ghz_capable(psoc, vdev_id, NULL))
+		allow_6ghz = false;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	/*
+	 * For SAP restart case SAP entry might be present in table,
+	 * so delete it temporary
+	 */
+	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, info,
+						      &num_cxn_del);
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+	switch (num_connections) {
+	case 0:
+		/* use sap channel */
+		*intf_ch_freq = 0;
+		break;
+	default:
+		if (num_connections > 3) {
+			policy_mgr_debug("invalid num_connections: %d",
+					 num_connections);
+			break;
+		}
+		/* Use PCL and concurrency combo to get the best channel */
+		policy_mgr_get_pref_force_scc_freq(psoc, vdev_id, intf_ch_freq,
+						   sap_ch_freq, acs_band,
+						   allow_6ghz);
+		break;
+	}
+
+	/* Restore the connection entry */
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+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 request_id)
+{
+	uint32_t conn_index = 0;
+	QDF_STATUS 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;
+	}
+
+	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) {
+		if (reason == POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH)
+			policy_mgr_next_actions(psoc, vdev_id, next_action,
+						reason, request_id);
+		else
+			policy_mgr_next_actions(psoc, original_vdev_id,
+						next_action, reason,
+						request_id);
+	} else {
+		if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT ||
+		    reason == POLICY_MGR_UPDATE_REASON_LFR2_ROAM) {
+			sme_debug("Continue connect/reassoc on vdev %d request_id %x reason %d",
+				  vdev_id, request_id, reason);
+			wlan_connect_hw_mode_change_resp(pm_ctx->pdev, vdev_id,
+							 request_id,
+							 QDF_STATUS_SUCCESS);
+		}
+		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_sap_ch_width_update(struct wlan_objmgr_psoc *psoc,
+			       enum policy_mgr_conc_next_action next_action,
+			       enum policy_mgr_conn_update_reason reason,
+			       uint8_t conc_vdev_id, uint32_t request_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t freq;
+	uint8_t sap_vdev_id;
+	enum phy_ch_width target_bw;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	policy_mgr_debug("action: %d reason: %d", next_action, reason);
+
+	policy_mgr_get_mode_specific_conn_info(psoc, &freq,
+					       &sap_vdev_id,
+					       PM_SAP_MODE);
+	if (next_action == PM_DOWNGRADE_BW)
+		target_bw = CH_WIDTH_160MHZ;
+	else
+		target_bw = CH_WIDTH_320MHZ;
+
+	status = pm_ctx->sme_cbacks.sme_sap_update_ch_width(psoc,
+							    sap_vdev_id,
+							    target_bw, reason,
+							    conc_vdev_id,
+							    request_id);
+	if (QDF_IS_STATUS_ERROR(status))
+		policy_mgr_err("vdev %d failed to set BW to %d",
+			       sap_vdev_id, target_bw);
+
+	return status;
+}
+
+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, uint32_t request_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, ch_freq;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum phy_ch_width ch_width = CH_WIDTH_MAX;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+	if (next_action == PM_DBS2 && band == POLICY_MGR_BAND_5)
+		ch_width = CH_WIDTH_40MHZ;
+
+	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;
+		ch_freq = pm_conc_connection_list[list[index]].freq;
+		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_FREQ(ch_freq)) ||
+		    (band == POLICY_MGR_BAND_5 &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)))) {
+			status = pm_ctx->sme_cbacks.sme_nss_update_request(
+					vdev_id, new_nss, ch_width,
+					policy_mgr_nss_update_cb,
+					next_action, psoc, reason,
+					original_vdev_id, request_id);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				policy_mgr_err("sme_nss_update_request() failed for vdev %d",
+				vdev_id);
+			}
+		}
+	}
+
+	count = policy_mgr_get_sap_mode_count(psoc, 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;
+		ch_freq = pm_conc_connection_list[list[index]].freq;
+		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_FREQ(ch_freq)) ||
+		    (band == POLICY_MGR_BAND_5 &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)))) {
+			status = pm_ctx->sme_cbacks.sme_nss_update_request(
+					vdev_id, new_nss, ch_width,
+					policy_mgr_nss_update_cb,
+					next_action, psoc, reason,
+					original_vdev_id, request_id);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				policy_mgr_err("sme_nss_update_request() failed for vdev %d",
+				vdev_id);
+			}
+		}
+	}
+
+	return status;
+}
+
+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, uint32_t request_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_rl_debug("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, request_id);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		status = policy_mgr_next_actions(psoc, session_id,
+						 next_action, reason,
+						 request_id);
+
+	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;
+}
+
+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].freq,
+		pm_conc_connection_list[1].freq,
+		pm_conc_connection_list[2].freq, 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 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
+		if (band1 == REG_BAND_2G)
+			return PM_DBS;
+		else
+			return PM_NOP;
+	case 2:
+		band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
+		band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq);
+		if (band1 == REG_BAND_2G || band2 == REG_BAND_2G) {
+			if (!hw_mode.dbs_cap)
+				return PM_DBS;
+			else
+				return PM_NOP;
+		} else if (band1 == REG_BAND_5G && band2 == REG_BAND_5G) {
+			if (policy_mgr_are_sbs_chan(psoc,
+					pm_conc_connection_list[0].freq,
+					pm_conc_connection_list[1].freq)) {
+				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 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
+		band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq);
+		band3 = wlan_reg_freq_to_band(pm_conc_connection_list[2].freq);
+		if (band1 == REG_BAND_2G || band2 == REG_BAND_2G ||
+		    band3 == REG_BAND_2G) {
+			if (!hw_mode.dbs_cap)
+				return PM_DBS;
+			else
+				return PM_NOP;
+		} else if (band1 == REG_BAND_5G && band2 == REG_BAND_5G &&
+			   band3 == REG_BAND_5G) {
+			if (policy_mgr_are_sbs_chan(psoc,
+					pm_conc_connection_list[0].freq,
+					pm_conc_connection_list[2].freq) &&
+			    policy_mgr_are_sbs_chan(psoc,
+					pm_conc_connection_list[1].freq,
+					pm_conc_connection_list[2].freq) &&
+			    policy_mgr_are_sbs_chan(psoc,
+					pm_conc_connection_list[0].freq,
+					pm_conc_connection_list[1].freq)) {
+				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;
+	}
+}
+
+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].freq,
+		pm_conc_connection_list[1].freq,
+		pm_conc_connection_list[2].freq, 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 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
+		band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq);
+		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 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
+		band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq);
+		band3 = wlan_reg_freq_to_band(pm_conc_connection_list[2].freq);
+		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;
+}
+
+void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+				       uint32_t ch_freq)
+{
+	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 (ch_freq == pm_ctx->sap_mandatory_channels[i])
+			return;
+	}
+	if (pm_ctx->sap_mandatory_channels_len >= NUM_CHANNELS) {
+		policy_mgr_err("mand list overflow (%u)", ch_freq);
+		return;
+	}
+
+	policy_mgr_debug("Ch freq: %u", ch_freq);
+
+	pm_ctx->sap_mandatory_channels[pm_ctx->sap_mandatory_channels_len++]
+		= ch_freq;
+}
+
+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;
+}
+
+#if defined(CONFIG_BAND_6GHZ)
+/**
+ * policy_mgr_add_sap_mandatory_6ghz_chan() - Add 6GHz SAP mandatory channel
+ * list
+ * @psoc: Pointer to soc
+ *
+ * Add the 6GHz PSC VLP channel to SAP mandatory channel list.
+ *
+ * Return: None
+ */
+static
+void  policy_mgr_add_sap_mandatory_6ghz_chan(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t ch_freq_list[NUM_CHANNELS] = {0};
+	uint32_t len = 0;
+	int i;
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool is_psd;
+	uint16_t tx_power;
+	uint16_t eirp_psd_power;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	status = policy_mgr_get_valid_chans(psoc, ch_freq_list, &len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Error in getting valid channels");
+		return;
+	}
+
+	for (i = 0; (i < len) && (i < NUM_CHANNELS) &&
+		    (pm_ctx->sap_mandatory_channels_len < NUM_CHANNELS); i++) {
+		if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i]))
+			continue;
+		if (WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(ch_freq_list[i])) {
+			status = wlan_reg_get_6g_chan_ap_power(
+				pm_ctx->pdev, ch_freq_list[i], &is_psd,
+				&tx_power, &eirp_psd_power);
+			if (status != QDF_STATUS_SUCCESS || !tx_power)
+				continue;
+
+			policy_mgr_debug("Add chan %u to mandatory list",
+					 ch_freq_list[i]);
+			pm_ctx->sap_mandatory_channels[
+				pm_ctx->sap_mandatory_channels_len++] =
+				ch_freq_list[i];
+		}
+	}
+}
+#else
+static inline
+void  policy_mgr_add_sap_mandatory_6ghz_chan(struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+/**
+ * policy_mgr_init_sap_mandatory_chan_by_band() - Init SAP mandatory channel
+ * list based on band
+ * @psoc: Pointer to soc
+ * @band_bitmap: band bitmap of type reg_wifi_band
+ *
+ * Initialize the 2.4G 5G 6G SAP mandatory channels based on band
+ *
+ * Return: None
+ */
+static void
+policy_mgr_init_sap_mandatory_chan_by_band(struct wlan_objmgr_psoc *psoc,
+					   uint32_t band_bitmap)
+{
+	uint32_t ch_freq_list[NUM_CHANNELS] = {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, ch_freq_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 < NUM_CHANNELS); i++) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i])) {
+			policy_mgr_debug("Add chan %u to mandatory list",
+					ch_freq_list[i]);
+			pm_ctx->sap_mandatory_channels[
+				pm_ctx->sap_mandatory_channels_len++] =
+				ch_freq_list[i];
+		}
+	}
+	if (band_bitmap & BIT(REG_BAND_5G))
+		for (i = 0; i < ARRAY_SIZE(sap_mand_5g_freq_list); i++)
+			policy_mgr_add_sap_mandatory_chan(
+				psoc, sap_mand_5g_freq_list[i]);
+	if (band_bitmap & BIT(REG_BAND_6G))
+		policy_mgr_add_sap_mandatory_6ghz_chan(psoc);
+}
+
+void  policy_mgr_init_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+					 uint32_t org_ch_freq)
+{
+	if (WLAN_REG_IS_5GHZ_CH_FREQ(org_ch_freq)) {
+		policy_mgr_debug("channel %u, sap mandatory chan list enabled",
+				 org_ch_freq);
+		policy_mgr_init_sap_mandatory_chan_by_band(
+			psoc, BIT(REG_BAND_2G) | BIT(REG_BAND_5G));
+		policy_mgr_add_sap_mandatory_chan(
+			psoc, org_ch_freq);
+	} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(org_ch_freq)) {
+		policy_mgr_init_sap_mandatory_chan_by_band(
+				psoc,
+				BIT(REG_BAND_2G) | BIT(REG_BAND_5G) |
+				BIT(REG_BAND_6G));
+	} else {
+		policy_mgr_init_sap_mandatory_chan_by_band(
+				psoc, BIT(REG_BAND_2G));
+	}
+}
+
+void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
+					  uint32_t ch_freq)
+{
+	uint32_t ch_freq_list[NUM_CHANNELS] = {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 >= NUM_CHANNELS) {
+		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 (ch_freq == pm_ctx->sap_mandatory_channels[i])
+			continue;
+		ch_freq_list[num_chan++] = pm_ctx->sap_mandatory_channels[i];
+	}
+
+	qdf_mem_zero(pm_ctx->sap_mandatory_channels,
+		     pm_ctx->sap_mandatory_channels_len *
+		     sizeof(*pm_ctx->sap_mandatory_channels));
+	qdf_mem_copy(pm_ctx->sap_mandatory_channels, ch_freq_list,
+		     num_chan * sizeof(*pm_ctx->sap_mandatory_channels));
+	pm_ctx->sap_mandatory_channels_len = num_chan;
+}

+ 13013 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -0,0 +1,13013 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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"
+#include "wlan_nan_api.h"
+#include "nan_public_structs.h"
+#include "wlan_reg_services_api.h"
+#include "wlan_cm_roam_public_struct.h"
+#include "wlan_mlme_api.h"
+#include "wlan_mlme_main.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+#include "wlan_mlo_mgr_sta.h"
+#include "wlan_cm_ucfg_api.h"
+#include "wlan_cm_roam_api.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "wlan_p2p_ucfg_api.h"
+#include "wlan_mlo_link_force.h"
+#include "wlan_connectivity_logging.h"
+#include "wlan_policy_mgr_ll_sap.h"
+
+/* invalid channel id. */
+#define INVALID_CHANNEL_ID 0
+
+#define IS_FREQ_ON_MAC_ID(freq_range, freq, mac_id) \
+	((freq >= freq_range[mac_id].low_2ghz_freq && \
+	  freq <= freq_range[mac_id].high_2ghz_freq) || \
+	(freq >= freq_range[mac_id].low_5ghz_freq && \
+	 freq <= freq_range[mac_id].high_5ghz_freq))
+
+/**
+ * policy_mgr_debug_alert() - fatal error alert
+ *
+ * This function will flush host drv log and
+ * disable all level logs.
+ * It can be called in fatal error detected in policy
+ * manager.
+ * This is to avoid host log overwritten in stress
+ * test to help issue debug.
+ *
+ * Return: none
+ */
+static void
+policy_mgr_debug_alert(void)
+{
+	int module_id;
+	int qdf_print_idx;
+
+	policy_mgr_err("fatal error detected to flush and pause host log");
+	qdf_logging_flush_logs();
+	qdf_print_idx = qdf_get_pidx();
+	for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
+		qdf_print_set_category_verbose(
+					qdf_print_idx,
+					module_id, QDF_TRACE_LEVEL_NONE,
+					0);
+}
+
+QDF_STATUS
+policy_mgr_get_allow_mcc_go_diff_bi(struct wlan_objmgr_psoc *psoc,
+				    uint8_t *allow_mcc_go_diff_bi)
+{
+	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;
+	}
+	*allow_mcc_go_diff_bi = pm_ctx->cfg.allow_mcc_go_diff_bi;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_set_dual_mac_feature(struct wlan_objmgr_psoc *psoc,
+					   uint8_t dual_mac_feature)
+{
+	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.dual_mac_feature = dual_mac_feature;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_dual_mac_feature(struct wlan_objmgr_psoc *psoc,
+					   uint8_t *dual_mac_feature)
+{
+	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;
+	}
+	*dual_mac_feature = pm_ctx->cfg.dual_mac_feature;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_force_1x1(struct wlan_objmgr_psoc *psoc,
+				    uint8_t *force_1x1)
+{
+	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;
+	}
+	*force_1x1 = pm_ctx->cfg.is_force_1x1_enable;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint32_t policy_mgr_get_max_conc_cxns(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 0;
+	}
+
+	return pm_ctx->cfg.max_conc_cxns;
+}
+
+QDF_STATUS policy_mgr_set_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
+					uint32_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;
+	}
+
+	policy_mgr_debug("set max_conc_cxns %d old %d", max_conc_cxns,
+			 pm_ctx->cfg.max_conc_cxns);
+	pm_ctx->cfg.max_conc_cxns = max_conc_cxns;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_set_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc,
+				       uint8_t sta_sap_scc_on_dfs_chnl)
+{
+	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.sta_sap_scc_on_dfs_chnl = sta_sap_scc_on_dfs_chnl;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *sta_sap_scc_on_dfs_chnl)
+{
+	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;
+	}
+	*sta_sap_scc_on_dfs_chnl = pm_ctx->cfg.sta_sap_scc_on_dfs_chnl;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool
+policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(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 false;
+	}
+
+	return pm_ctx->cfg.sta_sap_scc_on_indoor_channel;
+}
+
+QDF_STATUS
+policy_mgr_set_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc *psoc,
+					bool multi_sap_allowed_on_same_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;
+	}
+	pm_ctx->cfg.multi_sap_allowed_on_same_band =
+				multi_sap_allowed_on_same_band;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_get_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc *psoc,
+					bool *multi_sap_allowed_on_same_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;
+	}
+	*multi_sap_allowed_on_same_band =
+				pm_ctx->cfg.multi_sap_allowed_on_same_band;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_set_original_bw_for_sap_restart(struct wlan_objmgr_psoc *psoc,
+					   bool use_sap_original_bw)
+{
+	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.use_sap_original_bw = use_sap_original_bw;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_get_original_bw_for_sap_restart(struct wlan_objmgr_psoc *psoc,
+					   bool *use_sap_original_bw)
+{
+	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;
+	}
+	*use_sap_original_bw = pm_ctx->cfg.use_sap_original_bw;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_get_dfs_sta_sap_go_scc_movement(struct wlan_objmgr_psoc *psoc,
+					   bool *move_sap_go_first)
+{
+	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;
+	}
+	*move_sap_go_first = pm_ctx->cfg.move_sap_go_1st_on_dfs_sta_csa;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static bool
+policy_mgr_update_dfs_master_dynamic_enabled(
+	struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool sta_on_5g = false;
+	bool sta_on_2g = false;
+	uint32_t i;
+	bool enable = true;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return true;
+	}
+
+	if (!pm_ctx->cfg.sta_sap_scc_on_dfs_chnl) {
+		enable = true;
+		goto end;
+	}
+	if (pm_ctx->cfg.sta_sap_scc_on_dfs_chnl ==
+	    PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED) {
+		enable = false;
+		goto end;
+	}
+	if (pm_ctx->cfg.sta_sap_scc_on_dfs_chnl !=
+	    PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX) {
+		policy_mgr_debug("sta_sap_scc_on_dfs_chnl %d unknown",
+				 pm_ctx->cfg.sta_sap_scc_on_dfs_chnl);
+		enable = true;
+		goto end;
+	}
+
+	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 != vdev_id) &&
+		      pm_conc_connection_list[i].in_use &&
+		      (pm_conc_connection_list[i].mode == PM_STA_MODE ||
+		       pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE)))
+			continue;
+		if (WLAN_REG_IS_5GHZ_CH_FREQ(pm_conc_connection_list[i].freq))
+			sta_on_5g = true;
+		else
+			sta_on_2g = true;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (policy_mgr_is_hw_dbs_capable(psoc) && !sta_on_5g)
+		enable = true;
+	else if (!sta_on_5g && !sta_on_2g)
+		enable = true;
+	else
+		enable = false;
+end:
+	pm_ctx->dynamic_dfs_master_disabled = !enable;
+	if (!enable)
+		policy_mgr_debug("sta_sap_scc_on_dfs_chnl %d sta_on_2g %d sta_on_5g %d enable %d",
+				 pm_ctx->cfg.sta_sap_scc_on_dfs_chnl, sta_on_2g,
+				 sta_on_5g, enable);
+
+	return enable;
+}
+
+bool
+policy_mgr_get_dfs_master_dynamic_enabled(
+	struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	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 true;
+	}
+
+	return policy_mgr_update_dfs_master_dynamic_enabled(psoc, vdev_id);
+}
+
+bool
+policy_mgr_get_can_skip_radar_event(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id)
+{
+	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 false;
+	}
+
+	return pm_ctx->dynamic_dfs_master_disabled;
+}
+
+QDF_STATUS
+policy_mgr_get_sta_sap_scc_lte_coex_chnl(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *sta_sap_scc_lte_coex)
+{
+	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;
+	}
+	*sta_sap_scc_lte_coex = pm_ctx->cfg.sta_sap_scc_on_lte_coex_chnl;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *sap_mandt_chnl)
+{
+	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;
+	}
+	*sap_mandt_chnl = pm_ctx->cfg.sap_mandatory_chnl_enable;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc *psoc,
+				   uint8_t *indoor_chnl_marking)
+{
+	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;
+	}
+	*indoor_chnl_marking = pm_ctx->cfg.mark_indoor_chnl_disable;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+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_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_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_set_ch_select_plcy(struct wlan_objmgr_psoc *psoc,
+					 uint32_t ch_select_policy)
+{
+	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.chnl_select_plcy = ch_select_policy;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_set_dynamic_mcc_adaptive_sch(
+				struct wlan_objmgr_psoc *psoc,
+				bool dynamic_mcc_adaptive_sched)
+{
+	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->dynamic_mcc_adaptive_sched = dynamic_mcc_adaptive_sched;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_dynamic_mcc_adaptive_sch(
+				struct wlan_objmgr_psoc *psoc,
+				bool *dynamic_mcc_adaptive_sched)
+{
+	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;
+	}
+	*dynamic_mcc_adaptive_sched = pm_ctx->dynamic_mcc_adaptive_sched;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
+					   bool *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;
+#ifdef WLAN_FEATURE_11BE
+	case WMI_CHAN_WIDTH_320:
+		return HW_MODE_320_MHZ;
+#endif
+	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)
+{
+	qdf_freq_t max_5g_freq;
+
+	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;
+
+	if (caps->supported_bands & WMI_HOST_WLAN_5G_CAPABILITY) {
+		max_5g_freq = wlan_reg_max_6ghz_chan_freq() ?
+				wlan_reg_max_6ghz_chan_freq() :
+				wlan_reg_max_5ghz_chan_freq();
+		max_5g_freq = caps->reg_cap_ext.high_5ghz_chan ?
+				QDF_MIN(caps->reg_cap_ext.high_5ghz_chan,
+					max_5g_freq) : max_5g_freq;
+		info->support_6ghz_band =
+			max_5g_freq > wlan_reg_min_6ghz_chan_freq();
+	}
+}
+
+QDF_STATUS policy_mgr_update_nss_req(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id, uint8_t tx_nss,
+				     uint8_t rx_nss)
+{
+	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;
+	}
+	return pm_ctx->hdd_cbacks.wlan_set_tx_rx_nss_cb(psoc, vdev_id,
+							tx_nss, rx_nss);
+}
+
+/**
+ * policy_mgr_set_hw_mode_params() - sets TX-RX stream,
+ * bandwidth and DBS in hw_mode_list
+ * @psoc: PSOC object information
+ * @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
+ * @emlsr_mode: emlsr_mode for the emlsr_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, uint64_t emlsr_mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint64_t legacy_hwmode_lst;
+
+	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);
+
+	legacy_hwmode_lst = pm_ctx->hw_mode.hw_mode_list[pos];
+	POLICY_MGR_HW_MODE_EMLSR_MODE_SET(
+	    pm_ctx->hw_mode.hw_mode_list[pos],
+	    legacy_hwmode_lst, emlsr_mode);
+}
+
+QDF_STATUS policy_mgr_get_radio_combinations(struct wlan_objmgr_psoc *psoc,
+					     struct radio_combination *comb,
+					     uint32_t comb_max,
+					     uint32_t *comb_num)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct radio_combination *radio_comb;
+	uint32_t i;
+	bool dbs_or_sbs_enabled = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*comb_num = 0;
+	if (policy_mgr_is_hw_dbs_capable(psoc) ||
+	    policy_mgr_is_hw_sbs_capable(psoc))
+		dbs_or_sbs_enabled = true;
+
+	for (i = 0; i < pm_ctx->radio_comb_num; i++) {
+		radio_comb = &pm_ctx->radio_combinations[i];
+		if (!dbs_or_sbs_enabled && radio_comb->hw_mode != MODE_SMM)
+			continue;
+		if (*comb_num >= comb_max) {
+			policy_mgr_err("out of buffer %d max %d",
+				       pm_ctx->radio_comb_num,
+				       comb_max);
+			return QDF_STATUS_E_FAILURE;
+		}
+		policy_mgr_debug("radio %d: mode %d mac0 (0x%x, 0x%x), mac1 (0x%x 0x%x)",
+				 *comb_num,
+				 radio_comb->hw_mode,
+				 radio_comb->band_mask[0],
+				 radio_comb->antenna[0],
+				 radio_comb->band_mask[1],
+				 radio_comb->antenna[1]);
+		qdf_mem_copy(&comb[*comb_num], radio_comb,
+			     sizeof(*radio_comb));
+		(*comb_num)++;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_add_radio_comb() - Add radio combination
+ * @pm_ctx: bandwidth in terms of wmi_channel_width
+ * @radio: radio combination
+ *
+ * This function adds one radio combination to list
+ *
+ * Return: void
+ */
+static void policy_mgr_add_radio_comb(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				      struct radio_combination *radio)
+{
+	uint32_t i;
+	struct radio_combination *comb;
+
+	/* don't add duplicated item */
+	for (i = 0; i < pm_ctx->radio_comb_num; i++) {
+		comb = &pm_ctx->radio_combinations[i];
+		if (radio->hw_mode == comb->hw_mode &&
+		    radio->band_mask[0] == comb->band_mask[0] &&
+		    radio->band_mask[1] == comb->band_mask[1] &&
+		    radio->antenna[0] == comb->antenna[0] &&
+		    radio->antenna[1] == comb->antenna[1])
+			return;
+	}
+	if (pm_ctx->radio_comb_num == MAX_RADIO_COMBINATION) {
+		policy_mgr_err("radio combination overflow %d",
+			       pm_ctx->radio_comb_num);
+		return;
+	}
+	policy_mgr_debug("radio %d: mode %d mac0 (0x%x, 0x%x), mac1 (0x%x 0x%x)",
+			 pm_ctx->radio_comb_num,
+			 radio->hw_mode,
+			 radio->band_mask[0],
+			 radio->antenna[0],
+			 radio->band_mask[1],
+			 radio->antenna[1]);
+
+	qdf_mem_copy(&pm_ctx->radio_combinations[pm_ctx->radio_comb_num],
+		     radio, sizeof(*radio));
+	pm_ctx->radio_comb_num++;
+}
+
+#define SET_RADIO(_radio, _mode, _mac0_band, _mac1_band,\
+		  _mac0_antenna, _mac1_antenna) \
+do { \
+	(_radio)->hw_mode = _mode; \
+	(_radio)->band_mask[0] = _mac0_band; \
+	(_radio)->band_mask[1] = _mac1_band; \
+	(_radio)->antenna[0] = _mac0_antenna; \
+	(_radio)->antenna[1] = _mac1_antenna; \
+} while (0)
+
+/**
+ * policy_mgr_update_radio_combination_matrix() - Update radio combination
+ * list
+ * @psoc: psoc object
+ * @mac0_ss_bw_info: mac 0 band/bw info
+ * @mac1_ss_bw_info: mac 1 band/bw info
+ * @dbs_mode: dbs mode
+ * @sbs_mode: sbs mode
+ *
+ * This function updates radio combination list based on hw mode information.
+ *
+ * Return: void
+ */
+static void
+policy_mgr_update_radio_combination_matrix(
+			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 dbs_mode, uint32_t sbs_mode)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct radio_combination radio;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (!dbs_mode && !sbs_mode) {
+		if (mac0_ss_bw_info.mac_band_cap &
+					WMI_HOST_WLAN_2G_CAPABILITY) {
+			SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_2G), 0,
+				  mac0_ss_bw_info.mac_tx_stream, 0);
+			policy_mgr_add_radio_comb(pm_ctx, &radio);
+		}
+		if (mac0_ss_bw_info.mac_band_cap &
+					WMI_HOST_WLAN_5G_CAPABILITY) {
+			SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_5G), 0,
+				  mac0_ss_bw_info.mac_tx_stream, 0);
+			policy_mgr_add_radio_comb(pm_ctx, &radio);
+			if (mac0_ss_bw_info.support_6ghz_band) {
+				SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_6G),
+					  0, mac0_ss_bw_info.mac_tx_stream, 0);
+				policy_mgr_add_radio_comb(pm_ctx, &radio);
+			}
+		}
+		return;
+	}
+	if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_2G_CAPABILITY) &&
+	    (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY)) {
+		SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G), BIT(REG_BAND_5G),
+			  mac0_ss_bw_info.mac_tx_stream,
+			  mac1_ss_bw_info.mac_tx_stream);
+		policy_mgr_add_radio_comb(pm_ctx, &radio);
+		if (mac1_ss_bw_info.support_6ghz_band) {
+			SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G),
+				  BIT(REG_BAND_6G),
+				  mac0_ss_bw_info.mac_tx_stream,
+				  mac1_ss_bw_info.mac_tx_stream);
+			policy_mgr_add_radio_comb(pm_ctx, &radio);
+		}
+	}
+	if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY) &&
+	    (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_2G_CAPABILITY)) {
+		SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G), BIT(REG_BAND_5G),
+			  mac1_ss_bw_info.mac_tx_stream,
+			  mac0_ss_bw_info.mac_tx_stream);
+		policy_mgr_add_radio_comb(pm_ctx, &radio);
+		if (mac0_ss_bw_info.support_6ghz_band) {
+			SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G),
+				  BIT(REG_BAND_6G),
+				  mac1_ss_bw_info.mac_tx_stream,
+				  mac0_ss_bw_info.mac_tx_stream);
+			policy_mgr_add_radio_comb(pm_ctx, &radio);
+		}
+	}
+	if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY) &&
+	    (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY)) {
+		if (mac0_ss_bw_info.support_6ghz_band) {
+			SET_RADIO(&radio, MODE_SBS, BIT(REG_BAND_5G),
+				  BIT(REG_BAND_6G),
+				  mac1_ss_bw_info.mac_tx_stream,
+				  mac0_ss_bw_info.mac_tx_stream);
+			policy_mgr_add_radio_comb(pm_ctx, &radio);
+		} else if (mac1_ss_bw_info.support_6ghz_band) {
+			SET_RADIO(&radio, MODE_SBS, BIT(REG_BAND_5G),
+				  BIT(REG_BAND_6G),
+				  mac0_ss_bw_info.mac_tx_stream,
+				  mac1_ss_bw_info.mac_tx_stream);
+			policy_mgr_add_radio_comb(pm_ctx, &radio);
+		}
+	}
+}
+
+static void
+policy_mgr_update_24Ghz_freq_info(struct policy_mgr_freq_range *mac_range,
+				  struct wlan_psoc_host_mac_phy_caps *mac_cap)
+{
+	mac_range->low_2ghz_freq = QDF_MAX(mac_cap->reg_cap_ext.low_2ghz_chan,
+					   wlan_reg_min_24ghz_chan_freq());
+	mac_range->high_2ghz_freq = mac_cap->reg_cap_ext.high_2ghz_chan ?
+				    QDF_MIN(mac_cap->reg_cap_ext.high_2ghz_chan,
+					    wlan_reg_max_24ghz_chan_freq()) :
+				    wlan_reg_max_24ghz_chan_freq();
+}
+
+static void
+policy_mgr_update_5Ghz_freq_info(struct policy_mgr_freq_range *mac_range,
+				  struct wlan_psoc_host_mac_phy_caps *mac_cap)
+{
+	qdf_freq_t max_5g_freq;
+
+	max_5g_freq = wlan_reg_max_6ghz_chan_freq() ?
+			wlan_reg_max_6ghz_chan_freq() :
+			wlan_reg_max_5ghz_chan_freq();
+
+	mac_range->low_5ghz_freq = QDF_MAX(mac_cap->reg_cap_ext.low_5ghz_chan,
+					   wlan_reg_min_5ghz_chan_freq());
+	mac_range->high_5ghz_freq = mac_cap->reg_cap_ext.high_5ghz_chan ?
+				    QDF_MIN(mac_cap->reg_cap_ext.high_5ghz_chan,
+					    max_5g_freq) :
+				    max_5g_freq;
+}
+
+static void
+policy_mgr_update_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx,
+			    struct wlan_psoc_host_mac_phy_caps *mac_cap,
+			    enum policy_mgr_mode mode,
+			    uint32_t phy_id)
+{
+	struct policy_mgr_freq_range *mac_range;
+
+	mac_range = &pm_ctx->hw_mode.freq_range_caps[mode][phy_id];
+	if (mac_cap->supported_bands & WMI_HOST_WLAN_2G_CAPABILITY)
+		policy_mgr_update_24Ghz_freq_info(mac_range, mac_cap);
+
+	if (mac_cap->supported_bands & WMI_HOST_WLAN_5G_CAPABILITY)
+		policy_mgr_update_5Ghz_freq_info(mac_range, mac_cap);
+}
+
+static QDF_STATUS
+policy_mgr_modify_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx,
+			   uint8_t phy_id)
+{
+	uint8_t shared_phy_id;
+	struct policy_mgr_freq_range *sbs_mac_range, *shared_mac_range;
+	struct policy_mgr_freq_range *non_shared_range;
+
+	sbs_mac_range = &pm_ctx->hw_mode.freq_range_caps[MODE_SBS][phy_id];
+
+	/*
+	 * if SBS mac range has both 2.4 and 5 Ghz range, i e shared phy_id
+	 * keep the range as it is in SBS
+	 */
+	if (sbs_mac_range->low_2ghz_freq && sbs_mac_range->low_5ghz_freq)
+		return QDF_STATUS_SUCCESS;
+	if (sbs_mac_range->low_2ghz_freq && !sbs_mac_range->low_5ghz_freq) {
+		policy_mgr_err("Invalid DBS/SBS mode with only 2.4Ghz");
+		policy_mgr_dump_freq_range_per_mac(sbs_mac_range, MODE_SBS);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	non_shared_range = sbs_mac_range;
+	/*
+	 * if SBS mac range has only 5Ghz then its the non shared phy, so
+	 * modify the range as per the shared mac.
+	 */
+	shared_phy_id = phy_id ? 0 : 1;
+	shared_mac_range =
+		&pm_ctx->hw_mode.freq_range_caps[MODE_SBS][shared_phy_id];
+
+	if (shared_mac_range->low_5ghz_freq > non_shared_range->low_5ghz_freq) {
+		policy_mgr_debug("High 5Ghz shared");
+		/*
+		 * If the shared mac lower 5Ghz frequency is greater than
+		 * non-shared mac lower 5Ghz frequency then the shared mac has
+		 * HIGH 5Ghz shared with 2.4Ghz. So non-shared mac's 5Ghz high
+		 * freq should be less than the shared mac's low 5Ghz freq.
+		 */
+		if (non_shared_range->high_5ghz_freq >=
+		    shared_mac_range->low_5ghz_freq)
+			non_shared_range->high_5ghz_freq =
+				QDF_MAX(shared_mac_range->low_5ghz_freq - 10,
+					non_shared_range->low_5ghz_freq);
+	} else if (shared_mac_range->high_5ghz_freq <
+		   non_shared_range->high_5ghz_freq) {
+		policy_mgr_debug("LOW 5Ghz shared");
+		/*
+		 * If the shared mac high 5Ghz frequency is less than
+		 * non-shared mac high 5Ghz frequency then the shared mac has
+		 * LOW 5Ghz shared with 2.4Ghz So non-shared mac's 5Ghz low
+		 * freq should be greater than the shared mac's high 5Ghz freq.
+		 */
+		if (shared_mac_range->high_5ghz_freq >=
+		    non_shared_range->low_5ghz_freq)
+			non_shared_range->low_5ghz_freq =
+				QDF_MIN(shared_mac_range->high_5ghz_freq + 10,
+					non_shared_range->high_5ghz_freq);
+	} else {
+		policy_mgr_info("Invalid SBS range with all 5Ghz shared");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static qdf_freq_t
+policy_mgr_get_highest_5ghz_freq_frm_range(struct policy_mgr_freq_range *range)
+{
+	uint8_t phy_id;
+	qdf_freq_t highest_freq = 0;
+	qdf_freq_t max_5g_freq = wlan_reg_max_6ghz_chan_freq() ?
+			wlan_reg_max_6ghz_chan_freq() :
+			wlan_reg_max_5ghz_chan_freq();
+
+	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
+		if (range[phy_id].high_5ghz_freq > highest_freq)
+			highest_freq = range[phy_id].high_5ghz_freq;
+	}
+
+	return highest_freq ? highest_freq : max_5g_freq;
+}
+
+static qdf_freq_t
+policy_mgr_get_lowest_5ghz_freq_frm_range(struct policy_mgr_freq_range *range)
+{
+	uint8_t phy_id;
+	qdf_freq_t lowest_freq = 0;
+
+	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
+		if ((!lowest_freq && range[phy_id].low_5ghz_freq) ||
+		    (range[phy_id].low_5ghz_freq < lowest_freq))
+			lowest_freq = range[phy_id].low_5ghz_freq;
+	}
+
+	return lowest_freq ? lowest_freq : wlan_reg_min_5ghz_chan_freq();
+}
+
+static void
+policy_mgr_fill_lower_share_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				     uint16_t sbs_range_sep,
+				     struct policy_mgr_freq_range *ref_freq)
+{
+	struct policy_mgr_freq_range *lower_sbs_freq_range;
+	uint8_t phy_id;
+
+	lower_sbs_freq_range =
+		pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE];
+
+	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
+		lower_sbs_freq_range[phy_id].low_2ghz_freq =
+						ref_freq[phy_id].low_2ghz_freq;
+		lower_sbs_freq_range[phy_id].high_2ghz_freq =
+						ref_freq[phy_id].high_2ghz_freq;
+
+		/* update for shared mac */
+		if (lower_sbs_freq_range[phy_id].low_2ghz_freq) {
+			lower_sbs_freq_range[phy_id].low_5ghz_freq =
+			    policy_mgr_get_lowest_5ghz_freq_frm_range(ref_freq);
+			lower_sbs_freq_range[phy_id].high_5ghz_freq =
+				sbs_range_sep;
+		} else {
+			lower_sbs_freq_range[phy_id].low_5ghz_freq =
+				sbs_range_sep + 10;
+			lower_sbs_freq_range[phy_id].high_5ghz_freq =
+			   policy_mgr_get_highest_5ghz_freq_frm_range(ref_freq);
+		}
+	}
+}
+
+static void
+policy_mgr_fill_upper_share_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				     uint16_t sbs_range_sep,
+				     struct policy_mgr_freq_range *ref_freq)
+{
+	struct policy_mgr_freq_range *upper_sbs_freq_range;
+	uint8_t phy_id;
+
+	upper_sbs_freq_range =
+		pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE];
+
+	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
+		upper_sbs_freq_range[phy_id].low_2ghz_freq =
+						ref_freq[phy_id].low_2ghz_freq;
+		upper_sbs_freq_range[phy_id].high_2ghz_freq =
+						ref_freq[phy_id].high_2ghz_freq;
+
+		/* update for shared mac */
+		if (upper_sbs_freq_range[phy_id].low_2ghz_freq) {
+			upper_sbs_freq_range[phy_id].low_5ghz_freq =
+				sbs_range_sep + 10;
+			upper_sbs_freq_range[phy_id].high_5ghz_freq =
+			   policy_mgr_get_highest_5ghz_freq_frm_range(ref_freq);
+		} else {
+			upper_sbs_freq_range[phy_id].low_5ghz_freq =
+			    policy_mgr_get_lowest_5ghz_freq_frm_range(ref_freq);
+			upper_sbs_freq_range[phy_id].high_5ghz_freq =
+				sbs_range_sep;
+		}
+	}
+}
+
+static bool
+policy_mgr_both_phy_range_updated(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				  enum policy_mgr_mode hwmode)
+{
+	struct policy_mgr_freq_range *mac_range;
+	uint8_t phy_id;
+
+	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
+		mac_range =
+			&pm_ctx->hw_mode.freq_range_caps[hwmode][phy_id];
+		/* modify SBS/DBS range only when both phy for DBS are filled */
+		if (!mac_range->low_2ghz_freq && !mac_range->low_5ghz_freq)
+			return false;
+	}
+
+	return true;
+}
+
+static void
+policy_mgr_update_sbs_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	uint16_t sbs_range_sep;
+	struct policy_mgr_freq_range *mac_range;
+	uint8_t phy_id;
+	QDF_STATUS status;
+
+	mac_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS];
+
+	/*
+	 * If sbs_lower_band_end_freq has a value Z, then the frequency range
+	 * will be split using that value.
+	 */
+	sbs_range_sep = pm_ctx->hw_mode.sbs_lower_band_end_freq;
+	if (sbs_range_sep) {
+		policy_mgr_fill_upper_share_sbs_freq(pm_ctx, sbs_range_sep,
+						     mac_range);
+		policy_mgr_fill_lower_share_sbs_freq(pm_ctx, sbs_range_sep,
+						     mac_range);
+		/* Reset the SBS range */
+		qdf_mem_zero(mac_range, sizeof(*mac_range) * MAX_MAC);
+		return;
+	}
+
+	/*
+	 * If sbs_lower_band_end_freq is not set that means FW will send one
+	 * shared mac range and one non-shared mac range. so update that freq.
+	 */
+	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
+		status = policy_mgr_modify_sbs_freq(pm_ctx, phy_id);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			/* Reset the SBS range */
+			qdf_mem_zero(mac_range, sizeof(*mac_range) * MAX_MAC);
+			break;
+		}
+	}
+}
+
+static void
+policy_mgr_update_dbs_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	struct policy_mgr_freq_range *mac_range;
+	uint8_t phy_id;
+
+	mac_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS];
+	/* Reset 5Ghz range for shared mac for DBS */
+	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
+		if (mac_range[phy_id].low_2ghz_freq &&
+		    mac_range[phy_id].low_5ghz_freq) {
+			mac_range[phy_id].low_5ghz_freq = 0;
+			mac_range[phy_id].high_5ghz_freq = 0;
+		}
+	}
+}
+
+static void
+policy_mgr_update_mac_freq_info(struct wlan_objmgr_psoc *psoc,
+				struct policy_mgr_psoc_priv_obj *pm_ctx,
+				enum wmi_hw_mode_config_type hw_config_type,
+				uint32_t phy_id,
+				struct wlan_psoc_host_mac_phy_caps *mac_cap)
+{
+	if (phy_id >= MAX_MAC) {
+		policy_mgr_err("mac more than two not supported: %d",
+			       phy_id);
+		return;
+	}
+
+	policy_mgr_debug("hw_mode_cfg: %d mac: %d band: 0x%x, SBS cutoff freq %d, 2Ghz: %d -> %d 5Ghz: %d -> %d",
+			 hw_config_type, phy_id, mac_cap->supported_bands,
+			 pm_ctx->hw_mode.sbs_lower_band_end_freq,
+			 mac_cap->reg_cap_ext.low_2ghz_chan,
+			 mac_cap->reg_cap_ext.high_2ghz_chan,
+			 mac_cap->reg_cap_ext.low_5ghz_chan,
+			 mac_cap->reg_cap_ext.high_5ghz_chan);
+
+	switch (hw_config_type) {
+	case WMI_HW_MODE_SINGLE:
+		if (phy_id) {
+			policy_mgr_debug("MAC Phy 1 is not supported");
+			break;
+		}
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SMM, phy_id);
+		break;
+
+	case WMI_HW_MODE_DBS:
+	case WMI_HW_MODE_DBS_2G_5G:
+		if (!policy_mgr_both_phy_range_updated(pm_ctx, MODE_DBS))
+			policy_mgr_update_freq_info(pm_ctx, mac_cap,
+						    MODE_DBS, phy_id);
+		break;
+	case WMI_HW_MODE_DBS_SBS:
+	case WMI_HW_MODE_DBS_OR_SBS:
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_DBS, phy_id);
+		/*
+		 * fill SBS only if freq is provided by FW or
+		 * pm_ctx->hw_mode.sbs_lower_band_end_freq is set
+		 */
+		if (pm_ctx->hw_mode.sbs_lower_band_end_freq ||
+		    mac_cap->reg_cap_ext.low_5ghz_chan ||
+		    mac_cap->reg_cap_ext.low_2ghz_chan)
+			policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SBS,
+						    phy_id);
+
+		/* Modify the DBS list once both phy info are filled */
+		if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_DBS))
+			policy_mgr_update_dbs_freq_info(pm_ctx);
+		/* Modify the SBS list once both phy info are filled */
+		if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS))
+			policy_mgr_update_sbs_freq_info(pm_ctx);
+		break;
+	case WMI_HW_MODE_2G_PHYB:
+		if (phy_id)
+			policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SMM,
+						    phy_id);
+		break;
+	case WMI_HW_MODE_SBS:
+	case WMI_HW_MODE_SBS_PASSIVE:
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SBS, phy_id);
+		/* Modify the SBS Upper Lower list once both phy are filled */
+		if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS))
+			policy_mgr_update_sbs_freq_info(pm_ctx);
+
+		break;
+	case WMI_HW_MODE_EMLSR:
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR,
+					    phy_id);
+		break;
+	case WMI_HW_MODE_AUX_EMLSR_SINGLE:
+		if (phy_id) {
+			policy_mgr_debug("MAC Phy 1 is not supported");
+			break;
+		}
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR_SINGLE,
+					    phy_id);
+		break;
+	case WMI_HW_MODE_AUX_EMLSR_SPLIT:
+		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR_SPLIT,
+					    phy_id);
+		break;
+	default:
+		policy_mgr_err("HW mode not defined %d",
+			       hw_config_type);
+		break;
+	}
+}
+
+void
+policy_mgr_dump_curr_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	uint32_t i;
+	struct policy_mgr_freq_range *freq_range;
+
+	freq_range = pm_ctx->hw_mode.cur_mac_freq_range;
+	for (i = 0; i < MAX_MAC; i++)
+		if (freq_range[i].low_2ghz_freq || freq_range[i].low_5ghz_freq)
+			policymgr_nofl_debug("PLCY_MGR_FREQ_RANGE_CUR: mac %d: 2Ghz: %d -> %d, 5Ghz: %d -> %d",
+					     i, freq_range[i].low_2ghz_freq,
+					     freq_range[i].high_2ghz_freq,
+					     freq_range[i].low_5ghz_freq,
+					     freq_range[i].high_5ghz_freq);
+}
+
+static const char *policy_mgr_hw_mode_to_str(enum policy_mgr_mode hw_mode)
+{
+	if (hw_mode >= MODE_HW_MAX)
+		return "Unknown";
+
+	switch (hw_mode) {
+	CASE_RETURN_STRING(MODE_SMM);
+	CASE_RETURN_STRING(MODE_DBS);
+	CASE_RETURN_STRING(MODE_SBS);
+	CASE_RETURN_STRING(MODE_SBS_UPPER_SHARE);
+	CASE_RETURN_STRING(MODE_SBS_LOWER_SHARE);
+	CASE_RETURN_STRING(MODE_EMLSR);
+	CASE_RETURN_STRING(MODE_EMLSR_SINGLE);
+	CASE_RETURN_STRING(MODE_EMLSR_SPLIT);
+	default:
+		return "Unknown";
+	}
+}
+
+void
+policy_mgr_dump_freq_range_per_mac(struct policy_mgr_freq_range *freq_range,
+				   enum policy_mgr_mode hw_mode)
+{
+	uint32_t i;
+
+	for (i = 0; i < MAX_MAC; i++)
+		if (freq_range[i].low_2ghz_freq || freq_range[i].low_5ghz_freq)
+			policymgr_nofl_debug("PLCY_MGR_FREQ_RANGE: %s(%d): mac %d: 2Ghz: %d -> %d, 5Ghz: %d -> %d",
+					     policy_mgr_hw_mode_to_str(hw_mode),
+					     hw_mode, i,
+					     freq_range[i].low_2ghz_freq,
+					     freq_range[i].high_2ghz_freq,
+					     freq_range[i].low_5ghz_freq,
+					     freq_range[i].high_5ghz_freq);
+}
+
+static void
+policy_mgr_dump_hw_modes_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	uint32_t i;
+	struct policy_mgr_freq_range *freq_range;
+
+	for (i = MODE_SMM; i < MODE_HW_MAX; i++) {
+		freq_range = pm_ctx->hw_mode.freq_range_caps[i];
+		policy_mgr_dump_freq_range_per_mac(freq_range, i);
+	}
+}
+
+void policy_mgr_dump_sbs_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	uint32_t i;
+	struct policy_mgr_freq_range *freq_range;
+
+	for (i = MODE_SMM; i < MODE_HW_MAX; i++) {
+		if ((i == MODE_SBS) ||
+		    (pm_ctx->hw_mode.sbs_lower_band_end_freq &&
+		    (i == MODE_SBS_LOWER_SHARE || i == MODE_SBS_UPPER_SHARE))) {
+			freq_range = pm_ctx->hw_mode.freq_range_caps[i];
+			policy_mgr_dump_freq_range_per_mac(freq_range, i);
+		}
+	}
+}
+
+static bool
+policy_mgr_sbs_range_present(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS) ||
+	    (pm_ctx->hw_mode.sbs_lower_band_end_freq &&
+	     policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS_LOWER_SHARE) &&
+	     policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS_UPPER_SHARE)))
+		return true;
+
+	return false;
+}
+
+void
+policy_mgr_dump_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	policy_mgr_dump_hw_modes_freq_range(pm_ctx);
+	policy_mgr_dump_curr_freq_range(pm_ctx);
+}
+
+static void
+policy_mgr_update_sbs_lowr_band_end_frq(struct policy_mgr_psoc_priv_obj *pm_ctx,
+					struct tgt_info *info)
+{
+	if (wlan_reg_is_5ghz_ch_freq(info->sbs_lower_band_end_freq) ||
+	    wlan_reg_is_6ghz_chan_freq(info->sbs_lower_band_end_freq))
+		pm_ctx->hw_mode.sbs_lower_band_end_freq =
+						info->sbs_lower_band_end_freq;
+}
+
+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;
+	struct wlan_psoc_host_mac_phy_caps_ext2 *cap;
+	uint32_t i, j = 0;
+	enum wmi_hw_mode_config_type hw_config_type;
+	uint32_t dbs_mode, sbs_mode;
+	uint64_t emlsr_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");
+	}
+
+	/* Reset old freq ranges */
+	qdf_mem_zero(pm_ctx->hw_mode.freq_range_caps,
+		     sizeof(pm_ctx->hw_mode.freq_range_caps));
+	qdf_mem_zero(pm_ctx->hw_mode.cur_mac_freq_range,
+		     sizeof(pm_ctx->hw_mode.cur_mac_freq_range));
+	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) {
+		pm_ctx->num_dbs_hw_modes = 0;
+		return QDF_STATUS_E_NOMEM;
+	}
+	pm_ctx->radio_comb_num = 0;
+	qdf_mem_zero(pm_ctx->radio_combinations,
+		     sizeof(pm_ctx->radio_combinations));
+
+	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);
+		dbs_mode = HW_MODE_DBS_NONE;
+		sbs_mode = HW_MODE_SBS_NONE;
+		emlsr_mode = HW_MODE_EMLSR_NONE;
+		mac1_ss_bw_info.mac_tx_stream = 0;
+		mac1_ss_bw_info.mac_rx_stream = 0;
+		mac1_ss_bw_info.mac_bw = 0;
+
+		hw_config_type = tmp->hw_mode_config_type;
+		if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
+		    WMI_HW_MODE_EMLSR)
+			hw_config_type = WMI_HW_MODE_EMLSR;
+		else if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
+			 WMI_HW_MODE_AUX_EMLSR_SINGLE)
+			hw_config_type = WMI_HW_MODE_AUX_EMLSR_SINGLE;
+		else if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
+			 WMI_HW_MODE_AUX_EMLSR_SPLIT)
+			hw_config_type = WMI_HW_MODE_AUX_EMLSR_SPLIT;
+
+		policy_mgr_update_mac_freq_info(psoc, pm_ctx,
+						hw_config_type,
+						tmp->phy_id, tmp);
+
+		/* 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) ||
+		    (hw_config_type == WMI_HW_MODE_DBS_OR_SBS)) {
+			/* Update for MAC1 */
+			tmp = &info->mac_phy_cap[j++];
+			policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
+			policy_mgr_update_mac_freq_info(psoc, pm_ctx,
+							hw_config_type,
+							tmp->phy_id, tmp);
+			if (hw_config_type == WMI_HW_MODE_DBS ||
+			    hw_config_type == WMI_HW_MODE_DBS_OR_SBS)
+				dbs_mode = HW_MODE_DBS;
+			if (policy_mgr_sbs_range_present(pm_ctx) &&
+			    ((hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
+			    (hw_config_type == WMI_HW_MODE_SBS) ||
+			    (hw_config_type == WMI_HW_MODE_DBS_OR_SBS)))
+				sbs_mode = HW_MODE_SBS;
+		} else if (hw_config_type == WMI_HW_MODE_EMLSR ||
+			hw_config_type == WMI_HW_MODE_AUX_EMLSR_SPLIT) {
+			/* eMLSR mode */
+			tmp = &info->mac_phy_cap[j++];
+			cap = &info->mac_phy_caps_ext2[i];
+			wlan_mlme_set_eml_params(psoc, cap);
+			policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
+			policy_mgr_update_mac_freq_info(psoc, pm_ctx,
+							hw_config_type,
+							tmp->phy_id, tmp);
+			emlsr_mode = HW_MODE_EMLSR;
+		} else if (hw_config_type == WMI_HW_MODE_AUX_EMLSR_SINGLE) {
+			/* eMLSR mode */
+			cap = &info->mac_phy_caps_ext2[i];
+			wlan_mlme_set_eml_params(psoc, cap);
+			policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
+			emlsr_mode = HW_MODE_EMLSR;
+		}
+
+		/* 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, emlsr_mode);
+		/* Update radio combination info */
+		policy_mgr_update_radio_combination_matrix(
+			psoc, mac0_ss_bw_info, mac1_ss_bw_info,
+			dbs_mode, sbs_mode);
+	}
+
+	/*
+	 * Initializing Current frequency with SMM frequency.
+	 */
+	policy_mgr_fill_curr_mac_freq_by_hwmode(pm_ctx, MODE_SMM);
+	policy_mgr_dump_freq_range(pm_ctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_update_sbs_freq(struct wlan_objmgr_psoc *psoc,
+				      struct target_psoc_info *tgt_hdl)
+{
+	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;
+	policy_mgr_debug("sbs_lower_band_end_freq %d",
+			 info->sbs_lower_band_end_freq);
+	policy_mgr_update_sbs_lowr_band_end_frq(pm_ctx, info);
+
+	policy_mgr_update_hw_mode_list(psoc, tgt_hdl);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_freq_t policy_mgr_get_sbs_cut_off_freq(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_freq_range *first_mac_range, *second_mac_range;
+	qdf_freq_t sbs_cut_off_freq = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+
+	if (!policy_mgr_is_hw_sbs_capable(psoc))
+		return 0;
+
+	if (pm_ctx->hw_mode.sbs_lower_band_end_freq)
+		return pm_ctx->hw_mode.sbs_lower_band_end_freq;
+	/*
+	 * if cutoff freq is not available from FW (i.e SBS is not dynamic)
+	 * get it from SBS freq range
+	 */
+	first_mac_range = &pm_ctx->hw_mode.freq_range_caps[MODE_SBS][0];
+
+	second_mac_range =
+		&pm_ctx->hw_mode.freq_range_caps[MODE_SBS][1];
+
+	/*
+	 * SBS range is low 5Ghz shared with 2.4Ghz: The low_5Ghz of shared
+	 * mac will be starting of 5Ghz and low_5Ghz of non-shared mac will be
+	 * the cutoff freq
+	 *
+	 * SBS range is high 5Ghz shared with 2.4Ghz: The low_5Ghz of shared
+	 * mac will be cutoff freq and low_5Ghz of non-shared mac will be
+	 * the starting of 5Ghz
+	 *
+	 * so, maximum of low_5Ghz will be cutoff freq
+	 */
+	sbs_cut_off_freq = QDF_MAX(second_mac_range->low_5ghz_freq,
+				   first_mac_range->low_5ghz_freq) - 1;
+	policy_mgr_debug("sbs cutoff freq %d", sbs_cut_off_freq);
+
+	return sbs_cut_off_freq;
+}
+
+static bool
+policy_mgr_2_freq_same_mac_in_freq_range(
+				struct policy_mgr_psoc_priv_obj *pm_ctx,
+				struct policy_mgr_freq_range *freq_range,
+				qdf_freq_t freq_1, qdf_freq_t freq_2)
+{
+	uint8_t i;
+
+	for (i = 0; i < MAX_MAC; i++) {
+		if (IS_FREQ_ON_MAC_ID(freq_range, freq_1, i) &&
+		    IS_FREQ_ON_MAC_ID(freq_range, freq_2, i))
+			return true;
+	}
+
+	return false;
+}
+
+bool policy_mgr_can_2ghz_share_low_high_5ghz_sbs(
+			struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	if (pm_ctx->hw_mode.sbs_lower_band_end_freq)
+		return true;
+
+	return false;
+}
+
+bool
+policy_mgr_sbs_24_shared_with_high_5(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	qdf_freq_t sbs_cut_off_freq;
+	struct policy_mgr_freq_range freq_range;
+	uint8_t i = 0;
+
+	if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx))
+		return true;
+
+	sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
+	if (!sbs_cut_off_freq) {
+		policy_mgr_err("Invalid cut off freq");
+		return false;
+	}
+
+	for (i = 0; i < MAX_MAC; i++) {
+		freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS][i];
+		/*
+		 * if 5 GHZ start freq of this mac is greater than cutoff
+		 * return true
+		 */
+		if (freq_range.low_2ghz_freq && freq_range.low_5ghz_freq) {
+			if  (sbs_cut_off_freq < freq_range.low_5ghz_freq)
+				return true;
+		}
+	}
+
+	return false;
+}
+
+bool
+policy_mgr_sbs_24_shared_with_low_5(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	qdf_freq_t sbs_cut_off_freq;
+	struct policy_mgr_freq_range freq_range;
+	uint8_t i = 0;
+
+	if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx))
+		return true;
+
+	sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
+	if (!sbs_cut_off_freq) {
+		policy_mgr_err("Invalid cut off freq");
+		return false;
+	}
+
+	for (i = 0; i < MAX_MAC; i++) {
+		freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS][i];
+		if (freq_range.low_2ghz_freq && freq_range.high_5ghz_freq) {
+			/*
+			 * if 5 GHZ end freq of this mac is less than cutoff
+			 * return true
+			 */
+			if  (sbs_cut_off_freq > freq_range.high_5ghz_freq)
+				return true;
+		}
+	}
+
+	return false;
+}
+
+bool
+policy_mgr_2_freq_same_mac_in_dbs(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				  qdf_freq_t freq_1, qdf_freq_t freq_2)
+{
+	struct policy_mgr_freq_range *freq_range;
+
+	/* Return true if non DBS capable HW */
+	if (!policy_mgr_is_hw_dbs_capable(pm_ctx->psoc))
+		return true;
+
+	freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS];
+	return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, freq_range,
+							 freq_1, freq_2);
+}
+
+bool
+policy_mgr_2_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				  qdf_freq_t freq_1, qdf_freq_t freq_2)
+{
+	struct policy_mgr_freq_range *sbs_low_share;
+	struct policy_mgr_freq_range *sbs_uppr_share;
+	struct policy_mgr_freq_range *sbs_range;
+
+	/* Return true if non SBS capable HW */
+	if (!policy_mgr_is_hw_sbs_capable(pm_ctx->psoc))
+		return true;
+
+	if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx)) {
+		sbs_uppr_share =
+			pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE];
+		sbs_low_share =
+			pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE];
+		if (policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
+							     sbs_low_share,
+							     freq_1, freq_2) ||
+		    policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
+							     sbs_uppr_share,
+							     freq_1, freq_2))
+				return true;
+
+		return false;
+	}
+
+	sbs_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS];
+
+	return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, sbs_range,
+							freq_1, freq_2);
+}
+
+static bool
+policy_mgr_is_cur_freq_range_sbs(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_freq_range *freq_range;
+	uint8_t i;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return false;
+
+	/* Check if any of the mac is shared */
+	for (i = 0 ; i < MAX_MAC; i++) {
+		freq_range = &pm_ctx->hw_mode.cur_mac_freq_range[i];
+		if (freq_range->low_2ghz_freq && freq_range->low_5ghz_freq)
+			return true;
+	}
+
+	return false;
+}
+
+bool policy_mgr_2_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc,
+					  qdf_freq_t freq_1, qdf_freq_t freq_2)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool is_dbs_mode_same_mac = true;
+	bool is_sbs_mode_same_mac = true;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return false;
+
+	is_dbs_mode_same_mac =
+		policy_mgr_2_freq_same_mac_in_dbs(pm_ctx, freq_1, freq_2);
+
+	/* if DBS mode leading to same mac, check for SBS mode */
+	if (is_dbs_mode_same_mac)
+		is_sbs_mode_same_mac =
+			policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq_1,
+							  freq_2);
+
+	policy_mgr_rl_debug("freq1 %d freq2 %d: Same mac:: DBS:%d SBS:%d",
+			    freq_1, freq_2, is_dbs_mode_same_mac,
+			    is_sbs_mode_same_mac);
+	/*
+	 * if in SBS and DBS mode, both is leading to freqs on same mac,
+	 * return true else return false.
+	 */
+	if (is_dbs_mode_same_mac && is_sbs_mode_same_mac)
+		return true;
+
+	return false;
+}
+
+bool policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc *psoc,
+				       qdf_freq_t freq_1,
+				       qdf_freq_t  freq_2)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_freq_range *freq_range;
+	struct policy_mgr_hw_mode_params hw_mode;
+	QDF_STATUS status;
+	bool cur_range_sbs = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return false;
+
+	/* if HW is not DBS return true*/
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return true;
+
+	/* HW is DBS/SBS capable */
+	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 false;
+	}
+
+	if (hw_mode.dbs_cap || hw_mode.sbs_cap)
+		cur_range_sbs = policy_mgr_is_cur_freq_range_sbs(psoc);
+
+	freq_range = pm_ctx->hw_mode.cur_mac_freq_range;
+	/* current HW is DBS OR SBS check current DBS/SBS freq range */
+	if (hw_mode.dbs_cap || hw_mode.sbs_cap) {
+		policy_mgr_rl_debug("freq1 %d freq2 %d dbs_cap %d sbs_cap %d, cur range is sbs %d",
+				    freq_1, freq_2, hw_mode.dbs_cap,
+				    hw_mode.sbs_cap, cur_range_sbs);
+		return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
+								freq_range,
+								freq_1, freq_2);
+	}
+
+	/*
+	 * If current HW mode is not DBS/SBS, check if in all supported mode
+	 * it they will be on same mac
+	 */
+	return policy_mgr_2_freq_always_on_same_mac(psoc, freq_1, freq_2);
+}
+
+static bool
+policy_mgr_3_freq_same_mac_in_freq_range(
+				struct policy_mgr_psoc_priv_obj *pm_ctx,
+				struct policy_mgr_freq_range *freq_range,
+				qdf_freq_t freq_1, qdf_freq_t freq_2,
+				qdf_freq_t freq_3)
+{
+	uint8_t i;
+
+	for (i = 0 ; i < MAX_MAC; i++) {
+		if (IS_FREQ_ON_MAC_ID(freq_range, freq_1, i) &&
+		    IS_FREQ_ON_MAC_ID(freq_range, freq_2, i) &&
+		    IS_FREQ_ON_MAC_ID(freq_range, freq_3, i))
+			return true;
+	}
+
+	return false;
+}
+
+static bool
+policy_mgr_3_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				  qdf_freq_t freq_1, qdf_freq_t freq_2,
+				  qdf_freq_t freq_3)
+{
+	struct policy_mgr_freq_range *sbs_low_share;
+	struct policy_mgr_freq_range *sbs_uppr_share;
+	struct policy_mgr_freq_range *sbs_range;
+
+	/* Return true if non SBS capable HW */
+	if (!policy_mgr_is_hw_sbs_capable(pm_ctx->psoc))
+		return true;
+
+	if (pm_ctx->hw_mode.sbs_lower_band_end_freq) {
+		sbs_uppr_share =
+			pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE];
+		sbs_low_share =
+			pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE];
+		if (policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx,
+							     sbs_low_share,
+							     freq_1, freq_2,
+							     freq_3) ||
+		    policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx,
+							     sbs_uppr_share,
+							     freq_1, freq_2,
+							     freq_3))
+			return true;
+
+		return false;
+	}
+
+	sbs_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS];
+	return policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, sbs_range,
+							freq_1, freq_2, freq_3);
+}
+
+bool
+policy_mgr_3_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc,
+				     qdf_freq_t freq_1, qdf_freq_t freq_2,
+				     qdf_freq_t freq_3)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_freq_range *freq_range;
+	bool is_dbs_mode_same_mac = true;
+	bool is_sbs_mode_same_mac = true;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return false;
+
+	/* if HW is not DBS return true*/
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return true;
+
+	/* Check for DBS mode first */
+	freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS];
+	is_dbs_mode_same_mac =
+		policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, freq_range,
+							 freq_1, freq_2,
+							 freq_3);
+
+	/* if DBS mode leading to same mac, check for SBS mode */
+	if (is_dbs_mode_same_mac)
+		is_sbs_mode_same_mac =
+			policy_mgr_3_freq_same_mac_in_sbs(pm_ctx, freq_1,
+							  freq_2, freq_3);
+
+	policy_mgr_rl_debug("freq1 %d freq2 %d freq3 %d: Same mac:: DBS:%d SBS:%d",
+			    freq_1, freq_2, freq_3, is_dbs_mode_same_mac,
+			    is_sbs_mode_same_mac);
+	/*
+	 * if in SBS and DBS mode, both is leading to freqs on same mac,
+	 * return true else return false.
+	 */
+	if (is_dbs_mode_same_mac && is_sbs_mode_same_mac)
+		return true;
+
+	return false;
+}
+
+bool
+policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t freq_1, qdf_freq_t freq_2,
+				  qdf_freq_t freq_3)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_freq_range *freq_range;
+	QDF_STATUS status;
+	struct policy_mgr_hw_mode_params hw_mode;
+	bool cur_range_sbs = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return false;
+
+	/* if HW is not DBS return true*/
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return true;
+
+	/* HW is DBS/SBS capable, get current HW mode */
+	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 false;
+	}
+	if (hw_mode.dbs_cap || hw_mode.sbs_cap)
+		cur_range_sbs = policy_mgr_is_cur_freq_range_sbs(psoc);
+
+	freq_range = pm_ctx->hw_mode.cur_mac_freq_range;
+
+	/* current HW is DBS OR SBS check current DBS/SBS freq range */
+	if (hw_mode.dbs_cap || hw_mode.sbs_cap) {
+		policy_mgr_rl_debug("freq1 %d freq2 %d freq3 %d dbs_cap %d sbs_cap %d, cur range is sbs %d",
+				     freq_1, freq_2, freq_3, hw_mode.dbs_cap,
+				     hw_mode.sbs_cap, cur_range_sbs);
+		return policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx,
+							freq_range,
+							freq_1, freq_2, freq_3);
+	}
+	/*
+	 * If current HW mode is not DBS/SBS, check if in all supported mode
+	 * it they will be on same mac
+	 */
+	return policy_mgr_3_freq_always_on_same_mac(psoc, freq_1, freq_2,
+						    freq_3);
+}
+
+#ifdef FEATURE_FOURTH_CONNECTION
+static void
+policy_mgr_get_mac_freq_list(struct policy_mgr_freq_range *freq_range,
+			     uint8_t mac_id,
+			     uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
+			     uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
+			     uint8_t *mac_freq_num,
+			     qdf_freq_t freq_1, enum policy_mgr_con_mode mode_1,
+			     qdf_freq_t freq_2, enum policy_mgr_con_mode mode_2,
+			     qdf_freq_t freq_3, enum policy_mgr_con_mode mode_3,
+			     qdf_freq_t freq_4, enum policy_mgr_con_mode mode_4)
+{
+	uint8_t j = 0;
+
+	if (freq_1 && IS_FREQ_ON_MAC_ID(freq_range, freq_1, mac_id)) {
+		mac_freq_list[j] = freq_1;
+		mac_mode_list[j++] = mode_1;
+	}
+	if (freq_2 && IS_FREQ_ON_MAC_ID(freq_range, freq_2, mac_id)) {
+		mac_freq_list[j] = freq_2;
+		mac_mode_list[j++] = mode_2;
+	}
+	if (freq_3 && IS_FREQ_ON_MAC_ID(freq_range, freq_3, mac_id)) {
+		mac_freq_list[j] = freq_3;
+		mac_mode_list[j++] = mode_3;
+	}
+	if (freq_4 && IS_FREQ_ON_MAC_ID(freq_range, freq_4, mac_id)) {
+		mac_freq_list[j] = freq_4;
+		mac_mode_list[j++] = mode_4;
+	}
+
+	*mac_freq_num = j;
+}
+
+static bool
+policy_mgr_is_supported_hw_mode(struct wlan_objmgr_psoc *psoc,
+				struct policy_mgr_psoc_priv_obj *pm_ctx,
+				enum policy_mgr_mode hw_mode)
+{
+	if (hw_mode == MODE_SMM)
+		return true;
+
+	if (hw_mode == MODE_DBS)
+		return policy_mgr_is_hw_dbs_capable(psoc);
+
+	if (hw_mode == MODE_SBS_UPPER_SHARE ||
+	    hw_mode == MODE_SBS_LOWER_SHARE)
+		return policy_mgr_is_hw_sbs_capable(psoc) &&
+			pm_ctx->hw_mode.sbs_lower_band_end_freq;
+
+	if (hw_mode == MODE_SBS)
+		return policy_mgr_is_hw_sbs_capable(psoc);
+
+	return false;
+}
+
+static bool
+policy_mgr_mac_freq_list_allow(uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
+			       uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
+			       uint8_t mac_freq_num)
+{
+	uint8_t sta = 0, ap = 0, i;
+
+	switch (mac_freq_num) {
+	case 1:
+	case 2:
+		return true;
+	case 3:
+		/* If 3 vifs are active in same mac, target only support:
+		 * 3 vifs are in SCC and 3 vifs are :
+		 * 1 STA + 2 APs, or 3 APs
+		 */
+		if (mac_freq_list[0] != mac_freq_list[1] ||
+		    mac_freq_list[0] != mac_freq_list[2])
+			return false;
+		for (i = 0; i < mac_freq_num; i++) {
+			if (mac_mode_list[i] == PM_STA_MODE ||
+			    mac_mode_list[i] == PM_P2P_CLIENT_MODE)
+				sta++;
+			else
+				ap++;
+		}
+
+		if (sta == 1 && ap == 2)
+			return true;
+		if (ap == 3)
+			return true;
+		return false;
+	default:
+		return false;
+	}
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+static void
+policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc *psoc,
+			      qdf_freq_t ch_freq,
+			      enum policy_mgr_con_mode mode,
+			      uint32_t ext_flags,
+			      qdf_freq_t *ml_sta_link0_freq,
+			      qdf_freq_t *ml_sta_link1_freq)
+{
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
+	uint8_t num_active_ml_sta;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	union conc_ext_flag conc_ext_flags;
+
+	conc_ext_flags.value = ext_flags;
+	/* find the two active ml sta home channels */
+	policy_mgr_get_ml_sta_info_psoc(psoc, &num_ml_sta,
+					&num_disabled_ml_sta,
+					ml_sta_vdev_lst, ml_freq_lst,
+					NULL, NULL, NULL);
+	if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_ml_sta <= num_disabled_ml_sta) {
+		if (num_ml_sta || num_disabled_ml_sta)
+			policy_mgr_rl_debug("unexpected ml sta num %d %d",
+					    num_ml_sta, num_disabled_ml_sta);
+		return;
+	}
+	num_active_ml_sta = num_ml_sta;
+	if (num_ml_sta >= num_disabled_ml_sta)
+		num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
+	if (num_active_ml_sta > 1) {
+		*ml_sta_link0_freq = ml_freq_lst[0];
+		*ml_sta_link1_freq = ml_freq_lst[1];
+	} else if (num_active_ml_sta > 0 && conc_ext_flags.mlo &&
+		   mode == PM_STA_MODE) {
+		*ml_sta_link0_freq = ml_freq_lst[0];
+		*ml_sta_link1_freq = ch_freq;
+	}
+}
+#else
+static void
+policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc *psoc,
+			      qdf_freq_t ch_freq,
+			      enum policy_mgr_con_mode mode,
+			      uint32_t ext_flags,
+			      qdf_freq_t *ml_sta_link0_freq,
+			      qdf_freq_t *ml_sta_link1_freq)
+{
+}
+#endif
+
+bool
+policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc,
+			      qdf_freq_t ch_freq,
+			      enum policy_mgr_con_mode mode,
+			      uint32_t ext_flags)
+{
+	struct policy_mgr_conc_connection_info *conn = pm_conc_connection_list;
+	uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t mac_freq_num;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	qdf_freq_t ml_sta_link0_freq = 0;
+	qdf_freq_t ml_sta_link1_freq = 0;
+	uint8_t i, j;
+	struct policy_mgr_freq_range *freq_range;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	/* if HW is not DBS return false */
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return false;
+
+	/* Find the two active ml sta home channels */
+	policy_mgr_ml_sta_active_freq(psoc, ch_freq, mode, ext_flags,
+				      &ml_sta_link0_freq,
+				      &ml_sta_link1_freq);
+
+	/* Check if any hw mode can support the 4th channel frequency
+	 * and device mode.
+	 */
+	for (j = 0; j < MODE_HW_MAX; j++) {
+		if (!policy_mgr_is_supported_hw_mode(psoc, pm_ctx, j))
+			continue;
+		freq_range = pm_ctx->hw_mode.freq_range_caps[j];
+
+		/* If ml sta present, the two links should be in
+		 * different mac always. Skip the hw mode which
+		 * causes they in same mac.
+		 */
+		if (ml_sta_link0_freq && ml_sta_link1_freq &&
+		    policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
+							     freq_range,
+							     ml_sta_link0_freq,
+							     ml_sta_link1_freq))
+			continue;
+		for (i = 0; i < MAX_MAC; i++) {
+			/* Get the freq list which are in the MAC
+			 * supported freq range.
+			 */
+			policy_mgr_get_mac_freq_list(
+				freq_range,
+				i,
+				mac_freq_list, mac_mode_list, &mac_freq_num,
+				conn[0].freq, conn[0].mode,
+				conn[1].freq, conn[1].mode,
+				conn[2].freq, conn[2].mode,
+				ch_freq, mode);
+
+			/* Check the freq & mode list support or not in the
+			 * MAC.
+			 */
+			if (!policy_mgr_mac_freq_list_allow(
+				mac_freq_list, mac_mode_list, mac_freq_num))
+				break;
+		}
+
+		/* If the frequency/mode combination meet requirement in the
+		 * hw mode, then the 4th new ch_freq/mode are allowed to start
+		 * in this hw mode.
+		 */
+		if (i == MAX_MAC) {
+			policy_mgr_rl_debug("new freq %d mode %s is allowed in hw mode %s",
+					    ch_freq,
+					    device_mode_to_string(mode),
+					    policy_mgr_hw_mode_to_str(j));
+			return true;
+		}
+	}
+	policy_mgr_debug("the 4th new freq %d mode %s is not allowed in any hw mode",
+			 ch_freq, device_mode_to_string(mode));
+
+	return false;
+}
+#endif
+
+bool policy_mgr_are_sbs_chan(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1,
+			     qdf_freq_t freq_2)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return false;
+
+	if (!policy_mgr_is_hw_sbs_capable(psoc))
+		return false;
+
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(freq_1) ||
+	    WLAN_REG_IS_24GHZ_CH_FREQ(freq_2))
+		return false;
+
+	return !policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq_1, freq_2);
+}
+
+bool policy_mgr_is_current_hwmode_sbs(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_hw_mode_params hw_mode;
+
+	if (!policy_mgr_is_hw_sbs_capable(psoc))
+		return false;
+
+	if (QDF_STATUS_SUCCESS !=
+	    policy_mgr_get_current_hw_mode(psoc, &hw_mode))
+		return false;
+
+	if (hw_mode.sbs_cap && policy_mgr_is_cur_freq_range_sbs(psoc))
+		return true;
+
+	return false;
+}
+
+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) {
+		pm_ctx->num_dbs_hw_modes = 0;
+		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));
+
+	policy_mgr_dump_dbs_hw_mode(psoc);
+}
+
+void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t i;
+	uint32_t param;
+	uint32_t param1;
+
+	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("old_hw_mode_index=%d, new_hw_mode_index=%d",
+			 pm_ctx->old_hw_mode_index, pm_ctx->new_hw_mode_index);
+
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		param1 = pm_ctx->hw_mode.hw_mode_list[i] >> 32;
+		policy_mgr_debug("[%d] 0x%x 0x%x", i, param, param1);
+		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;
+	uint8_t dual_mac_feature;
+
+	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;
+
+	dual_mac_feature = pm_ctx->cfg.dual_mac_feature;
+	/* If dual mac features are disabled in the INI, we
+	 * need not proceed further
+	 */
+	if (dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) {
+		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_init_sbs_fw_config(struct wlan_objmgr_psoc *psoc,
+				   uint32_t fw_config)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool sbs_enabled;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	/*
+	 * If SBS is not enabled from ini, no need to set SBS bits in fw config
+	 */
+	sbs_enabled = pm_ctx->cfg.sbs_enable;
+	if (!sbs_enabled) {
+		policy_mgr_debug("SBS not enabled from ini");
+		return;
+	}
+
+	/* Initialize fw_mode_config_bits with default FW value */
+	WMI_DBS_FW_MODE_CFG_ASYNC_SBS_SET(
+			pm_ctx->dual_mac_cfg.cur_fw_mode_config,
+			WMI_DBS_FW_MODE_CFG_ASYNC_SBS_GET(fw_config));
+
+	policy_mgr_debug("fw_mode config updated from %x to %x",
+			 pm_ctx->dual_mac_cfg.prev_fw_mode_config,
+			 pm_ctx->dual_mac_cfg.cur_fw_mode_config);
+	/* Initialize the previous scan/fw mode config */
+	pm_ctx->dual_mac_cfg.prev_fw_mode_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_find_if_fw_supports_dbs(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wmi_unified *wmi_handle;
+	bool dbs_support;
+
+	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;
+	}
+	dbs_support =
+	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 (!dbs_support)
+		return false;
+
+	return true;
+}
+
+bool policy_mgr_find_if_hwlist_has_dbs(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t param, i, found = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) {
+			found = 1;
+			break;
+		}
+	}
+	if (found)
+		return true;
+
+	return false;
+}
+
+static bool policy_mgr_find_if_hwlist_has_sbs(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t param, i;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool policy_mgr_is_dbs_scan_allowed(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t dbs_type = DISABLE_DBS_CXN_AND_SCAN;
+	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 (!policy_mgr_find_if_fw_supports_dbs(psoc) ||
+	    !policy_mgr_find_if_hwlist_has_dbs(psoc))
+		return false;
+
+	policy_mgr_get_dual_mac_feature(psoc, &dbs_type);
+	/*
+	 * If DBS support for scan is disabled through INI then DBS is not
+	 * supported for scan.
+	 *
+	 * For DBS scan check the INI value explicitly
+	 */
+	switch (dbs_type) {
+	case DISABLE_DBS_CXN_AND_SCAN:
+	case ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN:
+		return false;
+	default:
+		return true;
+	}
+}
+
+bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	if (!policy_mgr_is_dbs_enable(psoc))
+		return false;
+
+	if (!policy_mgr_find_if_fw_supports_dbs(psoc))
+		return false;
+
+	if (!policy_mgr_find_if_hwlist_has_dbs(psoc)) {
+		policymgr_nofl_debug("HW mode list has no DBS");
+		return false;
+	}
+
+	return true;
+}
+
+bool policy_mgr_is_hw_emlsr_capable(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint64_t param, i;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
+		param = pm_ctx->hw_mode.hw_mode_list[i];
+		if (POLICY_MGR_HW_MODE_EMLSR_MODE_GET(param))
+			return true;
+	}
+
+	return false;
+}
+
+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 false;
+
+	/* sbs is not enabled and dbs_cap is set return true */
+	if (!policy_mgr_is_hw_sbs_capable(psoc))
+		return true;
+
+	/* sbs is enabled and dbs_cap is set then check the freq range */
+	if (!policy_mgr_is_cur_freq_range_sbs(psoc))
+		return true;
+
+	return false;
+}
+
+bool policy_mgr_is_pcl_weightage_required(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+	struct dual_sta_policy *dual_sta_policy;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return true;
+
+	dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy;
+
+	if (dual_sta_policy->concurrent_sta_policy  ==
+		QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY &&
+		dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
+		return false;
+	}
+
+	return true;
+}
+
+bool policy_mgr_is_interband_mcc_supported(struct wlan_objmgr_psoc *psoc)
+{
+	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;
+	}
+
+	return !wmi_service_enabled(wmi_handle,
+				    wmi_service_no_interband_mcc_support);
+}
+
+static bool policy_mgr_is_sbs_enable(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 gEnableSBS is not set then policy_mgr_init_sbs_fw_config won't
+	 * enable Async SBS fw config bit
+	 */
+	if (WMI_DBS_FW_MODE_CFG_ASYNC_SBS_GET(
+			pm_ctx->dual_mac_cfg.cur_fw_mode_config))
+		return true;
+
+	return false;
+}
+
+bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	if (!policy_mgr_is_sbs_enable(psoc)) {
+		policy_mgr_rl_debug("SBS INI is disabled");
+		return false;
+	}
+
+	if (!policy_mgr_find_if_fw_supports_dbs(psoc)) {
+		policy_mgr_rl_debug("fw doesn't support dual band");
+		return false;
+	}
+
+	if (!policy_mgr_find_if_hwlist_has_sbs(psoc)) {
+		policy_mgr_rl_debug("HW mode list has no SBS");
+		return false;
+	}
+
+	return true;
+}
+
+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_rl_debug("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;
+
+	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_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_rl_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;
+	}
+
+	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 = {0};
+	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;
+}
+
+bool policy_mgr_is_hw_dbs_required_for_band(struct wlan_objmgr_psoc *psoc,
+					    enum hw_mode_mac_band_cap band)
+{
+	struct dbs_nss nss_dbs = {0};
+	uint32_t nss;
+
+	nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
+	if (nss >= HW_MODE_SS_1x1 && nss_dbs.mac0_ss >= nss_dbs.mac1_ss &&
+	    !(nss_dbs.single_mac0_band_cap & band))
+		return true;
+	else
+		return false;
+}
+
+bool policy_mgr_is_dp_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_find_if_hwlist_has_dbs(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)
+{
+	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_get_connection_count_with_mlo(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t conn_index, count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum policy_mgr_con_mode mode;
+	bool is_mlo = false, count_mlo = false;
+
+	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) {
+			is_mlo = policy_mgr_is_ml_vdev_id(psoc,
+				   pm_conc_connection_list[conn_index].vdev_id);
+			mode = pm_conc_connection_list[conn_index].mode;
+			if (is_mlo && (mode == PM_STA_MODE)) {
+				if (!count_mlo) {
+					count_mlo = true;
+					count++;
+				}
+			} else {
+				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_get_macid_by_vdev_id(struct wlan_objmgr_psoc *psoc,
+					      uint32_t vdev_id)
+{
+	uint32_t conn_index = 0;
+	uint32_t mac_id = 0xFF;
+	enum policy_mgr_con_mode 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 vdev_id;
+	}
+	mode = policy_mgr_con_mode_by_vdev_id(psoc, vdev_id);
+	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 &&
+		    vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
+			mac_id = pm_conc_connection_list[conn_index].mac;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return mac_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)
+				list[count] = conn_index;
+			 count++;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+uint32_t policy_mgr_get_sap_mode_count(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *list)
+{
+	uint32_t count;
+
+	count = policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE,
+							  list);
+
+	count += policy_mgr_mode_specific_connection_count(
+						psoc,
+						PM_LL_LT_SAP_MODE,
+						list ? &list[count] : NULL);
+	return count;
+}
+
+uint32_t policy_mgr_get_beaconing_mode_count(struct wlan_objmgr_psoc *psoc,
+					     uint32_t *list)
+{
+	uint32_t count;
+
+	count = policy_mgr_get_sap_mode_count(psoc, list);
+
+	count += policy_mgr_mode_specific_connection_count(
+						psoc,
+						PM_P2P_GO_MODE,
+						list ? &list[count] : NULL);
+	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_is_scc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i, ch_freq;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	/* Get the channel freq for a given vdev_id */
+	status = policy_mgr_get_chan_by_session_id(psoc, vdev_id,
+						   &ch_freq);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Failed to get channel for vdev:%d", vdev_id);
+		return false;
+	}
+
+	/* Compare given vdev_id freq against other vdev_id's */
+	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 != vdev_id) &&
+		    (pm_conc_connection_list[i].in_use) &&
+		    (pm_conc_connection_list[i].freq == ch_freq)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return true;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return false;
+}
+
+bool policy_mgr_is_mcc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id, uint8_t *mcc_vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i, ch_freq;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (mcc_vdev_id)
+		*mcc_vdev_id = WLAN_INVALID_VDEV_ID;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	/* Get the channel freq for a given vdev_id */
+	status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &ch_freq);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Failed to get channel for vdev:%d", vdev_id);
+		return false;
+	}
+
+	/* Compare given vdev_id freq against other vdev_id's */
+	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 == vdev_id)
+			continue;
+
+		if (!pm_conc_connection_list[i].in_use)
+			continue;
+
+		if (pm_conc_connection_list[i].freq != ch_freq &&
+		    policy_mgr_are_2_freq_on_same_mac(psoc,
+						      pm_conc_connection_list[i].freq,
+						      ch_freq)) {
+			if (mcc_vdev_id)
+				*mcc_vdev_id = pm_conc_connection_list[i].vdev_id;
+
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return true;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return false;
+}
+
+bool policy_mgr_is_mcc_on_any_sta_vdev(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t connection_count, i;
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+
+	connection_count =
+		policy_mgr_get_mode_specific_conn_info(psoc, NULL, vdev_id_list,
+						       PM_STA_MODE);
+	if (!connection_count)
+		return false;
+
+	for (i = 0; i < connection_count; i++)
+		if (policy_mgr_is_mcc_with_this_vdev_id(psoc, vdev_id_list[i],
+							NULL))
+			return true;
+
+	return false;
+}
+
+bool policy_mgr_current_concurrency_is_scc(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t num_connections = 0;
+	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;
+	}
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	switch (num_connections) {
+	case 1:
+		break;
+	case 2:
+		if (pm_conc_connection_list[0].freq ==
+		    pm_conc_connection_list[1].freq &&
+		    policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[0].freq,
+			pm_conc_connection_list[1].freq))
+			is_scc = true;
+		break;
+	case 3:
+		/*
+		 * In DBS/SBS mode 2 freq are different and on different mac.
+		 * Thus if any of 2 freq are same that mean one of the MAC is
+		 * in SCC.
+		 * For non DBS/SBS, if all 3 freq are same then its SCC
+		 */
+		if ((policy_mgr_is_current_hwmode_dbs(psoc) ||
+		     policy_mgr_is_current_hwmode_sbs(psoc)) &&
+		    (pm_conc_connection_list[0].freq ==
+		     pm_conc_connection_list[1].freq ||
+		     pm_conc_connection_list[0].freq ==
+		     pm_conc_connection_list[2].freq ||
+		     pm_conc_connection_list[1].freq ==
+		     pm_conc_connection_list[2].freq))
+			is_scc = true;
+		else if ((pm_conc_connection_list[0].freq ==
+			  pm_conc_connection_list[1].freq) &&
+			 (pm_conc_connection_list[0].freq ==
+			  pm_conc_connection_list[2].freq))
+			is_scc = true;
+
+		break;
+	default:
+		policy_mgr_debug("unexpected num_connections value %d",
+				 num_connections);
+		break;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return is_scc;
+}
+
+bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t num_connections = 0;
+	bool is_mcc = 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_mcc;
+	}
+
+	num_connections = policy_mgr_get_connection_count(psoc);
+	if (!num_connections)
+		return is_mcc;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	switch (num_connections) {
+	case 1:
+		break;
+	case 2:
+		if (pm_conc_connection_list[0].freq !=
+		    pm_conc_connection_list[1].freq &&
+		    policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[0].freq,
+			pm_conc_connection_list[1].freq))
+			is_mcc = true;
+		break;
+	case 3:
+		/*
+		 * Check if any 2 different freq is on same MAC.
+		 * Return true if any of the different freq is on same MAC.
+		 */
+		if ((pm_conc_connection_list[0].freq !=
+		     pm_conc_connection_list[1].freq &&
+		     policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[0].freq,
+			pm_conc_connection_list[1].freq)) ||
+		    (pm_conc_connection_list[0].freq !=
+		     pm_conc_connection_list[2].freq &&
+		     policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[0].freq,
+			pm_conc_connection_list[2].freq)) ||
+		    (pm_conc_connection_list[1].freq !=
+		     pm_conc_connection_list[2].freq &&
+		     policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[1].freq,
+			pm_conc_connection_list[2].freq)))
+			is_mcc = true;
+		break;
+	default:
+		policy_mgr_debug("unexpected num_connections value %d",
+				 num_connections);
+		break;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return is_mcc;
+}
+
+bool policy_mgr_is_sap_p2pgo_on_dfs(struct wlan_objmgr_psoc *psoc)
+{
+	int index, count;
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
+
+	if (psoc)
+		pm_ctx = policy_mgr_get_context(psoc);
+
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	index = 0;
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	count = policy_mgr_mode_specific_connection_count(psoc,
+							  PM_SAP_MODE,
+							  list);
+	while (index < count) {
+		if (pm_conc_connection_list[list[index]].ch_flagext &
+		    (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return true;
+		}
+		index++;
+	}
+	count = policy_mgr_mode_specific_connection_count(psoc,
+							  PM_P2P_GO_MODE,
+							  list);
+	index = 0;
+	while (index < count) {
+		if (pm_conc_connection_list[list[index]].ch_flagext &
+		    (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return true;
+		}
+		index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	return false;
+}
+
+/**
+ * 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_MONITOR_MODE:
+		pm_ctx->concurrency_mode |= (1 << mode);
+		pm_ctx->no_of_open_sessions[mode]++;
+		break;
+	default:
+		break;
+	}
+
+	policy_mgr_debug("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_debug("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_validate_conn_info() - validate conn info list
+ * @psoc: PSOC object data
+ *
+ * This function will check connection list to see duplicated
+ * vdev entry existing or not.
+ *
+ * Return: true if conn list is in abnormal state.
+ */
+static bool
+policy_mgr_validate_conn_info(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t i, j, conn_num = 0;
+	bool panic = 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 true;
+	}
+
+	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) {
+			for (j = i + 1; j < MAX_NUMBER_OF_CONC_CONNECTIONS;
+									j++) {
+				if (pm_conc_connection_list[j].in_use &&
+				    pm_conc_connection_list[i].vdev_id ==
+				    pm_conc_connection_list[j].vdev_id) {
+					policy_mgr_debug(
+					"dup entry %d",
+					pm_conc_connection_list[i].vdev_id);
+					panic = true;
+				}
+			}
+			conn_num++;
+		}
+	}
+	if (panic)
+		policy_mgr_err("dup entry");
+
+	for (i = 0, j = 0; i < QDF_MAX_NO_OF_MODE; i++)
+		j += pm_ctx->no_of_active_sessions[i];
+
+	if (j != conn_num) {
+		policy_mgr_err("active session/conn count mismatch %d %d",
+			       j, conn_num);
+		panic = true;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (panic)
+		policy_mgr_debug_alert();
+
+	return panic;
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+bool policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	bool is_mlo = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev)
+		return is_mlo;
+
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
+		is_mlo = true;
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return is_mlo;
+}
+
+/*
+ * policy_mgr_get_ml_sta_info() - Get number of ML STA vdev ids and freq list
+ * @pm_ctx: pm_ctx ctx
+ * @num_ml_sta: Return number of ML STA present
+ * @num_disabled_ml_sta: Return number of disabled ML STA links
+ * @ml_vdev_lst: Return ML STA vdev id list
+ * @ml_freq_lst: Return ML STA freq list
+ * @num_non_ml: Return number of non-ML STA present
+ * @non_ml_vdev_lst: Return non-ML STA vdev id list
+ * @non_ml_freq_lst: Return non-ML STA freq list
+ *
+ * Return: void
+ */
+static void
+policy_mgr_get_ml_sta_info(struct policy_mgr_psoc_priv_obj *pm_ctx,
+			   uint8_t *num_ml_sta,
+			   uint8_t *num_disabled_ml_sta,
+			   uint8_t *ml_vdev_lst,
+			   qdf_freq_t *ml_freq_lst,
+			   uint8_t *num_non_ml,
+			   uint8_t *non_ml_vdev_lst,
+			   qdf_freq_t *non_ml_freq_lst)
+{
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t vdev_id, conn_index;
+	qdf_freq_t freq;
+
+	*num_ml_sta = 0;
+	*num_disabled_ml_sta = 0;
+	if (num_non_ml)
+		*num_non_ml = 0;
+
+	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)
+			continue;
+		if (pm_conc_connection_list[conn_index].mode != PM_STA_MODE)
+			continue;
+		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+		freq = pm_conc_connection_list[conn_index].freq;
+
+		/* add ml sta vdev and freq list */
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc,
+							    vdev_id,
+							    WLAN_POLICY_MGR_ID);
+		if (!vdev) {
+			policy_mgr_err("invalid vdev for id %d", vdev_id);
+			continue;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+			ml_vdev_lst[*num_ml_sta] = vdev_id;
+			ml_freq_lst[(*num_ml_sta)++] = freq;
+		} else if (num_non_ml) {
+			if (non_ml_vdev_lst)
+				non_ml_vdev_lst[*num_non_ml] = vdev_id;
+			if (non_ml_freq_lst)
+				non_ml_freq_lst[*num_non_ml] = freq;
+			(*num_non_ml)++;
+		}
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+	/* Get disabled link info as well and keep it at last */
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK;
+	     conn_index++) {
+		if (!pm_disabled_ml_links[conn_index].in_use)
+			continue;
+		if (pm_disabled_ml_links[conn_index].mode != PM_STA_MODE)
+			continue;
+		ml_vdev_lst[*num_ml_sta] =
+				pm_disabled_ml_links[conn_index].vdev_id;
+		ml_freq_lst[(*num_ml_sta)++] =
+			pm_disabled_ml_links[conn_index].freq;
+		(*num_disabled_ml_sta)++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+void
+policy_mgr_get_ml_sta_info_psoc(struct wlan_objmgr_psoc *psoc,
+				uint8_t *num_ml_sta,
+				uint8_t *num_disabled_ml_sta,
+				uint8_t *ml_vdev_lst,
+				qdf_freq_t *ml_freq_lst,
+				uint8_t *num_non_ml,
+				uint8_t *non_ml_vdev_lst,
+				qdf_freq_t *non_ml_freq_lst)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm_ctx");
+		return;
+	}
+
+	return policy_mgr_get_ml_sta_info(pm_ctx,
+					  num_ml_sta,
+					  num_disabled_ml_sta,
+					  ml_vdev_lst,
+					  ml_freq_lst,
+					  num_non_ml,
+					  non_ml_vdev_lst,
+					  non_ml_freq_lst);
+}
+
+uint32_t policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t i, count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm_ctx");
+		return count;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (pm_disabled_ml_links[i].in_use)
+			count++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+static QDF_STATUS
+policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				      uint8_t vdev_id)
+{
+	int i;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (pm_disabled_ml_links[i].in_use &&
+		    pm_disabled_ml_links[i].vdev_id == vdev_id) {
+			pm_disabled_ml_links[i].in_use = false;
+			policy_mgr_debug("Disabled link removed for vdev %d",
+					 vdev_id);
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	/* Return failure if not found */
+	if (i >= MAX_NUMBER_OF_DISABLE_LINK)
+		return QDF_STATUS_E_EXISTS;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_move_vdev_from_disabled_to_connection_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status;
+	enum QDF_OPMODE mode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm_ctx");
+		return;
+	}
+	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+	if (mode != QDF_STA_MODE) {
+		policy_mgr_err("vdev %d opmode %d is not STA", vdev_id, mode);
+		return;
+	}
+
+	if (!policy_mgr_is_ml_vdev_id(psoc, vdev_id)) {
+		policy_mgr_err("vdev %d is not ML", vdev_id);
+		return;
+	}
+
+	status = policy_mgr_delete_from_disabled_links(pm_ctx, vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_debug("Disabled link not found for vdev %d",
+				 vdev_id);
+		return;
+	}
+
+	/*
+	 * Add entry to pm_conc_connection_list if remove from disabled links
+	 * was success
+	 */
+	policy_mgr_incr_active_session(psoc, mode, vdev_id);
+}
+
+static QDF_STATUS
+policy_mgr_add_to_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				 qdf_freq_t freq, enum QDF_OPMODE mode,
+				 uint8_t vdev_id)
+{
+	int i;
+	enum policy_mgr_con_mode pm_mode;
+
+	pm_mode = policy_mgr_qdf_opmode_to_pm_con_mode(pm_ctx->psoc, mode,
+						       vdev_id);
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (pm_disabled_ml_links[i].in_use &&
+		    pm_disabled_ml_links[i].vdev_id == vdev_id)
+			break;
+	}
+
+	if (i < MAX_NUMBER_OF_DISABLE_LINK) {
+		pm_disabled_ml_links[i].freq = freq;
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		policy_mgr_debug("Disabled link already present vdev %d, pm_mode %d, update freq %d",
+				 vdev_id, pm_mode, freq);
+
+		return QDF_STATUS_E_EXISTS;
+	}
+
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (!pm_disabled_ml_links[i].in_use) {
+			/* add in empty place */
+			pm_disabled_ml_links[i].vdev_id = vdev_id;
+			pm_disabled_ml_links[i].mode = pm_mode;
+			pm_disabled_ml_links[i].in_use = true;
+			pm_disabled_ml_links[i].freq = freq;
+			policy_mgr_debug("Disabled link added vdev id: %d freq: %d pm_mode %d",
+					 vdev_id, freq, pm_mode);
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (i >= MAX_NUMBER_OF_DISABLE_LINK) {
+		policy_mgr_err("No empty entry found to disable link for vdev %d",
+			       vdev_id);
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_move_vdev_from_connection_to_disabled_tbl(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	qdf_freq_t freq;
+	enum QDF_OPMODE mode;
+	QDF_STATUS status;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm_ctx");
+		return;
+	}
+
+	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+	if (mode != QDF_STA_MODE) {
+		policy_mgr_err("vdev %d opmode %d is not STA", vdev_id, mode);
+		return;
+	}
+
+	if (!policy_mgr_is_ml_vdev_id(psoc, vdev_id)) {
+		policy_mgr_err("vdev %d is not ML", vdev_id);
+		return;
+	}
+	freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id);
+	status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc, PM_STA_MODE,
+							     vdev_id);
+	/*
+	 * Remove entry if present in pm_conc_connection_list, if not just add
+	 * it in disabled table.
+	 */
+	if (QDF_IS_STATUS_SUCCESS(status))
+		policy_mgr_decr_session_set_pcl(psoc, mode, vdev_id);
+	else
+		policy_mgr_debug("Connection tbl dont have vdev %d in STA mode, Add it in disabled tbl",
+				 vdev_id);
+
+	policy_mgr_add_to_disabled_links(pm_ctx, freq, mode, vdev_id);
+	policy_mgr_dump_current_concurrency(psoc);
+}
+
+static bool
+policy_mgr_vdev_disabled_by_link_force(struct wlan_objmgr_psoc *psoc,
+				       struct wlan_objmgr_vdev *vdev,
+				       bool peer_assoc)
+{
+	uint16_t dynamic_inactive = 0, forced_inactive = 0;
+	uint16_t link_id;
+
+	if (ml_is_nlink_service_supported(psoc) &&
+	    !peer_assoc) {
+		ml_nlink_get_dynamic_inactive_links(psoc, vdev,
+						    &dynamic_inactive,
+						    &forced_inactive);
+		link_id = wlan_vdev_get_link_id(vdev);
+		if ((forced_inactive | dynamic_inactive) &
+		    (1 << link_id)) {
+			policy_mgr_debug("vdev %d linkid %d is forced inactived 0x%0x dyn 0x%x",
+					 wlan_vdev_get_id(vdev),
+					 link_id, forced_inactive,
+					 dynamic_inactive);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool
+policy_mgr_ml_link_vdev_need_to_be_disabled(struct wlan_objmgr_psoc *psoc,
+					    struct wlan_objmgr_vdev *vdev,
+					    bool peer_assoc)
+{
+	union conc_ext_flag conc_ext_flags;
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		return false;
+
+	/* Check only for link vdev */
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev) ||
+	    !wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+		return false;
+
+	/* Check vdev is disabled by link force command */
+	if (policy_mgr_vdev_disabled_by_link_force(psoc, vdev,
+						   peer_assoc))
+		return true;
+
+	conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
+	/*
+	 * For non-assoc link vdev set link as disabled if concurrency is
+	 * not allowed
+	 */
+	return !policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE,
+					wlan_get_operation_chan_freq(vdev),
+					HW_MODE_20_MHZ,
+					conc_ext_flags.value, NULL);
+}
+
+static void
+policy_mgr_enable_disable_link_from_vdev_bitmask(struct wlan_objmgr_psoc *psoc,
+						 unsigned long enable_vdev_mask,
+						 unsigned long disable_vdev_mask,
+						 uint8_t start_vdev_id)
+{
+	uint8_t i;
+
+	/* Enable required link if enable_vdev_mask preset */
+	for (i = 0; enable_vdev_mask && i < WLAN_MAX_VDEVS; i++) {
+		if (qdf_test_and_clear_bit(i, &enable_vdev_mask))
+			policy_mgr_move_vdev_from_disabled_to_connection_tbl(
+							psoc,
+							i + start_vdev_id);
+	}
+
+	/* Disable required link if disable_mask preset */
+	for (i = 0; disable_vdev_mask && i < WLAN_MAX_VDEVS; i++) {
+		if (qdf_test_and_clear_bit(i, &disable_vdev_mask))
+			policy_mgr_move_vdev_from_connection_to_disabled_tbl(
+							psoc,
+							i + start_vdev_id);
+	}
+}
+
+static void
+policy_mgr_set_link_in_progress(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				bool set_link_in_progress)
+{
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if (set_link_in_progress)
+		qdf_atomic_inc(&pm_ctx->link_in_progress);
+	else {
+		if (qdf_atomic_read(&pm_ctx->link_in_progress) > 0)
+			qdf_atomic_dec(&pm_ctx->link_in_progress);
+	}
+
+	/* if set link has started reset the event, else complete the event */
+	if (qdf_atomic_read(&pm_ctx->link_in_progress))
+		qdf_event_reset(&pm_ctx->set_link_update_done_evt);
+	else
+		qdf_event_set(&pm_ctx->set_link_update_done_evt);
+
+	policy_mgr_debug("link_in_progress %d",
+			 qdf_atomic_read(&pm_ctx->link_in_progress));
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+static bool
+policy_mgr_get_link_in_progress(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	bool value;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	value = qdf_atomic_read(&pm_ctx->link_in_progress);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (value)
+		policy_mgr_debug("set_link_in_progress %d", value);
+
+	return value;
+}
+
+bool policy_mgr_is_set_link_in_progress(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 policy_mgr_get_link_in_progress(pm_ctx);
+}
+
+/*
+ * policy_mgr_trigger_roam_on_link_removal() - Trigger roam on link removal
+ * @vdev: vdev object
+ *
+ * In multilink ML STA, if one link is removed by AP, and no other active
+ * link, trigger roam by roaming invoke command.
+ *
+ * Return: void
+ */
+static void
+policy_mgr_trigger_roam_on_link_removal(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_vdev *ml_vdev;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
+	uint8_t num_active_ml_sta;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	uint8_t assoc_vdev_id = WLAN_INVALID_VDEV_ID;
+	uint8_t removed_vdev_id = WLAN_INVALID_VDEV_ID;
+	struct qdf_mac_addr bssid;
+	QDF_STATUS status;
+	bool ml_sta_is_not_connected = false;
+	uint32_t i;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		policy_mgr_err("Failed to get psoc");
+		return;
+	}
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		policy_mgr_err("Failed to get pdev");
+		return;
+	}
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst,
+				   NULL, NULL, NULL);
+	if (!num_ml_sta) {
+		policy_mgr_debug("unexpected event, no ml sta");
+		return;
+	}
+	if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_ml_sta <= num_disabled_ml_sta) {
+		policy_mgr_debug("unexpected ml sta num %d %d",
+				 num_ml_sta, num_disabled_ml_sta);
+		return;
+	}
+	num_active_ml_sta = num_ml_sta;
+	if (num_ml_sta >= num_disabled_ml_sta)
+		num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
+
+	for (i = 0; i < num_active_ml_sta; i++) {
+		if (!wlan_get_vdev_link_removed_flag_by_vdev_id(
+					psoc, ml_sta_vdev_lst[i]))
+			break;
+	}
+
+	/* After link removal, one link is still active, no need invoke
+	 * roaming.
+	 * For Single link MLO, FW will do roaming automatically.
+	 */
+	if (i < num_active_ml_sta || num_ml_sta < 2)
+		return;
+
+	/* For multi-link MLO STA, if one link is removed and no other active
+	 * link, then trigger roaming. the other link may have concurrency
+	 * limitation and can't be active.
+	 */
+	for (i = 0; i < num_ml_sta; i++) {
+		if (removed_vdev_id == WLAN_INVALID_VDEV_ID &&
+		    wlan_get_vdev_link_removed_flag_by_vdev_id(
+			psoc, ml_sta_vdev_lst[i])) {
+			policy_mgr_debug("removal link vdev %d is removed ",
+					 vdev_id);
+			removed_vdev_id = ml_sta_vdev_lst[i];
+		}
+		ml_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+						pm_ctx->psoc,
+						ml_sta_vdev_lst[i],
+						WLAN_POLICY_MGR_ID);
+		if (!ml_vdev) {
+			policy_mgr_err("invalid vdev for id %d",
+				       ml_sta_vdev_lst[i]);
+			continue;
+		}
+		if (!wlan_cm_is_vdev_connected(ml_vdev)) {
+			policy_mgr_debug("ml sta vdev %d is not connected state",
+					 ml_sta_vdev_lst[i]);
+			ml_sta_is_not_connected = true;
+		}
+
+		wlan_objmgr_vdev_release_ref(ml_vdev, WLAN_POLICY_MGR_ID);
+
+		if (assoc_vdev_id == WLAN_INVALID_VDEV_ID &&
+		    !wlan_vdev_mlme_get_is_mlo_link(psoc,
+						    ml_sta_vdev_lst[i]))
+			assoc_vdev_id = ml_sta_vdev_lst[i];
+	}
+	if (removed_vdev_id == WLAN_INVALID_VDEV_ID) {
+		policy_mgr_debug("no link removed, unexpected");
+		return;
+	}
+	if (assoc_vdev_id == WLAN_INVALID_VDEV_ID) {
+		policy_mgr_debug("no find assoc vdev, unexpected");
+		return;
+	}
+	if (ml_sta_is_not_connected) {
+		policy_mgr_debug("ml sta is non-connected state, don't trigger roam");
+		return;
+	}
+	/* trigger roaming */
+	policy_mgr_debug("link removal detected, try roaming on vdev id: %d",
+			 assoc_vdev_id);
+	qdf_zero_macaddr(&bssid);
+	status = wlan_cm_roam_invoke(pdev, assoc_vdev_id, &bssid, 0,
+				     CM_ROAMING_LINK_REMOVAL);
+	if (QDF_IS_STATUS_ERROR(status))
+		policy_mgr_err("roam invoke failed");
+}
+
+/*
+ * policy_mgr_update_dynamic_inactive_bitmap() - Update dynamic inactive links
+ * @psoc: psoc object
+ * @vdev: vdev object
+ * @req: req of set link command
+ * @resp: resp of set link command
+ *
+ * If MLO_LINK_FORCE_MODE_INACTIVE_NUM force mode with control flag -
+ * "dynamic_force_link_num" enabled was sent to firmware,
+ * host will need to select same num of links to be dyamic inactive
+ * links. And move corresponding vdevs to disabled policy mgr connection table.
+ *
+ * Return: void
+ */
+static void
+policy_mgr_update_dynamic_inactive_bitmap(
+			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_vdev *vdev,
+			struct mlo_link_set_active_req *req,
+			struct mlo_link_set_active_resp *resp)
+{
+	uint32_t candidate_inactive_links, inactive_links;
+	uint32_t standby_links;
+	uint32_t dyn_inactive_links = 0;
+	uint8_t dyn_num = 0, num = 0, i;
+	uint8_t link_ids[MAX_MLO_LINK_ID * 2];
+	struct ml_link_force_state curr_state = {0};
+	uint8_t force_inactive_num = 0;
+	uint32_t force_inactive_num_bitmap = 0;
+	uint32_t force_inactive_bitmap;
+
+	ml_nlink_get_curr_force_state(psoc, vdev, &curr_state);
+
+	switch (req->param.force_mode) {
+	case MLO_LINK_FORCE_MODE_ACTIVE:
+	case MLO_LINK_FORCE_MODE_INACTIVE:
+	case MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE:
+	case MLO_LINK_FORCE_MODE_ACTIVE_NUM:
+	case MLO_LINK_FORCE_MODE_NO_FORCE:
+		if (!curr_state.curr_dynamic_inactive_bitmap)
+			return;
+
+		force_inactive_num = curr_state.force_inactive_num;
+		force_inactive_num_bitmap =
+			curr_state.force_inactive_num_bitmap;
+		force_inactive_bitmap = curr_state.force_inactive_bitmap;
+		break;
+	case MLO_LINK_FORCE_MODE_INACTIVE_NUM:
+		if (!req->param.control_flags.dynamic_force_link_num) {
+			if (!curr_state.curr_dynamic_inactive_bitmap)
+				return;
+			dyn_inactive_links = 0;
+			dyn_num = 0;
+			goto update;
+		}
+
+		force_inactive_num = curr_state.force_inactive_num;
+		force_inactive_num_bitmap =
+			curr_state.force_inactive_num_bitmap;
+		force_inactive_bitmap = curr_state.force_inactive_bitmap;
+		break;
+	default:
+		return;
+	}
+
+	/* force inactive num "clear" case, return 0 - no
+	 * dynamic inactive links.
+	 */
+	if (!force_inactive_num) {
+		dyn_inactive_links = 0;
+		dyn_num = 0;
+		goto update;
+	}
+
+	/* 1. If standby link is force inactive,
+	 * select the standby link as dynamic inactive link firstly.
+	 */
+	standby_links = ml_nlink_get_standby_link_bitmap(psoc, vdev);
+	candidate_inactive_links =
+		force_inactive_num_bitmap &
+		force_inactive_bitmap &
+		standby_links;
+	inactive_links = candidate_inactive_links;
+	num = ml_nlink_convert_link_bitmap_to_ids(candidate_inactive_links,
+						  QDF_ARRAY_SIZE(link_ids),
+						  link_ids);
+
+	/* 2. If non standby link is force inactive,
+	 *  select the non standby link as second option.
+	 */
+	if (num < force_inactive_num &&
+	    num < QDF_ARRAY_SIZE(link_ids)) {
+		candidate_inactive_links =
+			force_inactive_num_bitmap &
+			force_inactive_bitmap &
+			~inactive_links;
+		num += ml_nlink_convert_link_bitmap_to_ids(
+				candidate_inactive_links,
+				QDF_ARRAY_SIZE(link_ids) - num,
+				&link_ids[num]);
+		inactive_links |= candidate_inactive_links;
+	}
+
+	/* 3. If standby link is present (may not be force inactive),
+	 * select the standby link as dynamic inactive link.
+	 */
+	if (num < force_inactive_num &&
+	    num < QDF_ARRAY_SIZE(link_ids)) {
+		candidate_inactive_links =
+			force_inactive_num_bitmap &
+			standby_links;
+		num += ml_nlink_convert_link_bitmap_to_ids(
+				candidate_inactive_links,
+				QDF_ARRAY_SIZE(link_ids) - num,
+				&link_ids[num]);
+		inactive_links |= candidate_inactive_links;
+	}
+
+	/* 4. If there are links inactive from fw event's
+	 * curr_inactive_linkid_bitmap, select the current inactive
+	 * links as last option. note: those link may not be force
+	 * inactive.
+	 */
+	if (num < force_inactive_num &&
+	    num < QDF_ARRAY_SIZE(link_ids)) {
+		candidate_inactive_links =
+			force_inactive_num_bitmap &
+			resp->curr_inactive_linkid_bitmap &
+			~inactive_links;
+		num += ml_nlink_convert_link_bitmap_to_ids(
+				candidate_inactive_links,
+				QDF_ARRAY_SIZE(link_ids) - num,
+				&link_ids[num]);
+		inactive_links |= candidate_inactive_links;
+	}
+
+	for (i = 0; i < num; i++) {
+		if (dyn_num >= force_inactive_num)
+			break;
+		dyn_inactive_links |= 1 << link_ids[i];
+		dyn_num++;
+	}
+
+update:
+	policy_mgr_debug("inactive link num %d bitmap 0x%x force inactive 0x%x curr 0x%x dyn links 0x%x num %d",
+			 force_inactive_num,
+			 force_inactive_num_bitmap,
+			 resp->inactive_linkid_bitmap,
+			 resp->curr_inactive_linkid_bitmap,
+			 dyn_inactive_links, dyn_num);
+
+	ml_nlink_set_dynamic_inactive_links(psoc, vdev, dyn_inactive_links);
+}
+
+static void
+policy_mgr_handle_vdev_active_inactive_resp(
+					struct wlan_objmgr_psoc *psoc,
+					struct wlan_objmgr_vdev *vdev,
+					struct mlo_link_set_active_req *req,
+					struct mlo_link_set_active_resp *resp)
+{
+	uint8_t i;
+	uint8_t vdev_id_num = 0;
+	uint8_t vdev_ids[WLAN_MLO_MAX_VDEVS] = {0};
+	uint32_t assoc_bitmap = 0;
+	uint16_t dynamic_inactive_bitmap = 0;
+	uint16_t forced_inactive_bitmap = 0;
+
+	/* convert link id to vdev id and update vdev status based
+	 * on both inactive and active bitmap.
+	 * In link bitmap based WMI event (use_ieee_link_id = true),
+	 * target will always indicate current force inactive and
+	 * active bitmaps to host. For links in inactive_linkid_bitmap,
+	 * they will be moved to policy mgr disable connection table.
+	 * for other links, they will be in active tables.
+	 */
+	ml_nlink_get_dynamic_inactive_links(psoc, vdev,
+					    &dynamic_inactive_bitmap,
+					    &forced_inactive_bitmap);
+	resp->inactive_linkid_bitmap |= dynamic_inactive_bitmap;
+	ml_nlink_convert_linkid_bitmap_to_vdev_bitmap(
+		psoc, vdev, resp->inactive_linkid_bitmap,
+		&assoc_bitmap,
+		&resp->inactive_sz, resp->inactive,
+		&vdev_id_num, vdev_ids);
+
+	ml_nlink_convert_linkid_bitmap_to_vdev_bitmap(
+		psoc, vdev,
+		(~resp->inactive_linkid_bitmap) & assoc_bitmap,
+		NULL,
+		&resp->active_sz, resp->active,
+		&vdev_id_num, vdev_ids);
+	for (i = 0; i < resp->inactive_sz; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+				psoc, 0, resp->inactive[i], i * 32);
+	for (i = 0; i < resp->active_sz; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+				psoc, resp->active[i], 0, i * 32);
+}
+
+static void
+policy_mgr_handle_force_active_resp(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_objmgr_vdev *vdev,
+				    struct mlo_link_set_active_req *req,
+				    struct mlo_link_set_active_resp *resp)
+{
+	uint8_t i;
+	uint32_t assoc_bitmap = 0;
+
+	if (resp->use_ieee_link_id) {
+		/* save link force active bitmap */
+		ml_nlink_set_curr_force_active_state(
+			psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap,
+			req->param.control_flags.overwrite_force_active_bitmap ?
+			LINK_OVERWRITE : LINK_ADD);
+
+		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
+							  resp);
+
+		/* update vdev active inactive status */
+		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
+							    resp);
+		return;
+	}
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, req->param.num_vdev_bitmap,
+		req->param.vdev_bitmap, &resp->active_linkid_bitmap,
+		&assoc_bitmap);
+	ml_nlink_set_curr_force_active_state(
+		psoc, vdev, resp->active_linkid_bitmap, LINK_ADD);
+
+	for (i = 0; i < resp->active_sz; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+				psoc, resp->active[i], 0, i * 32);
+}
+
+static void
+policy_mgr_handle_force_inactive_resp(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      struct mlo_link_set_active_req *req,
+				      struct mlo_link_set_active_resp *resp)
+{
+	uint8_t i;
+	uint32_t assoc_bitmap = 0;
+
+	if (resp->use_ieee_link_id) {
+		/* save link force inactive bitmap */
+		ml_nlink_set_curr_force_inactive_state(
+			psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap,
+			req->param.control_flags.overwrite_force_inactive_bitmap ?
+			LINK_OVERWRITE : LINK_ADD);
+
+		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
+							  resp);
+
+		/* update vdev active inactive status */
+		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
+							    resp);
+		return;
+	}
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, req->param.num_vdev_bitmap,
+		req->param.vdev_bitmap, &resp->inactive_linkid_bitmap,
+		&assoc_bitmap);
+	ml_nlink_set_curr_force_inactive_state(
+		psoc, vdev, resp->inactive_linkid_bitmap, LINK_ADD);
+
+	for (i = 0; i < resp->inactive_sz; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+				psoc, 0, resp->inactive[i], i * 32);
+}
+
+static void
+policy_mgr_handle_force_active_num_resp(struct wlan_objmgr_psoc *psoc,
+					struct wlan_objmgr_vdev *vdev,
+					struct mlo_link_set_active_req *req,
+					struct mlo_link_set_active_resp *resp)
+{
+	uint8_t i;
+	uint32_t assoc_bitmap = 0;
+	uint32_t link_bitmap = 0;
+
+	if (resp->use_ieee_link_id) {
+		/* save force num and force num bitmap */
+		ml_nlink_set_curr_force_active_num_state(
+			psoc, vdev, req->param.force_cmd.link_num,
+			req->param.force_cmd.ieee_link_id_bitmap);
+
+		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
+							  resp);
+
+		/* update vdev active inactive status */
+		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
+							    resp);
+		return;
+	}
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, req->param.num_vdev_bitmap,
+		req->param.vdev_bitmap,
+		&link_bitmap,
+		&assoc_bitmap);
+	ml_nlink_set_curr_force_active_num_state(
+		psoc, vdev, req->param.link_num[0].num_of_link,
+		link_bitmap);
+	/*
+	 * When the host sends a set link command with force link num
+	 * and dynamic flag set, FW may not process it immediately.
+	 * In this case FW buffer the request and sends a response as
+	 * success to the host with VDEV bitmap as zero.
+	 * FW ensures that the number of active links will be equal to
+	 * the link num sent via WMI_MLO_LINK_SET_ACTIVE_CMDID command.
+	 * So the host should also fill the mlo policy_mgr table as per
+	 * request.
+	 */
+	if (req->param.control_flags.dynamic_force_link_num) {
+		policy_mgr_debug("Enable ML vdev(s) as sent in req");
+		for (i = 0; i < req->param.num_vdev_bitmap; i++)
+			policy_mgr_enable_disable_link_from_vdev_bitmask(
+				psoc,
+				req->param.vdev_bitmap[i], 0, i * 32);
+		return;
+	}
+
+	/*
+	 * MLO_LINK_FORCE_MODE_ACTIVE_NUM return which vdev is active
+	 * So XOR of the requested ML vdev and active vdev bit will give
+	 * the vdev bits to disable
+	 */
+	for (i = 0; i < resp->active_sz; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+			psoc, resp->active[i],
+			resp->active[i] ^ req->param.vdev_bitmap[i],
+			i * 32);
+}
+
+static void
+policy_mgr_handle_force_inactive_num_resp(
+				struct wlan_objmgr_psoc *psoc,
+				struct wlan_objmgr_vdev *vdev,
+				struct mlo_link_set_active_req *req,
+				struct mlo_link_set_active_resp *resp)
+{
+	uint8_t i;
+	uint32_t assoc_bitmap = 0;
+	uint32_t link_bitmap = 0;
+
+	if (resp->use_ieee_link_id) {
+		/* save force num and force num bitmap */
+		ml_nlink_set_curr_force_inactive_num_state(
+			psoc, vdev, req->param.force_cmd.link_num,
+			req->param.force_cmd.ieee_link_id_bitmap);
+		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
+							  resp);
+
+		/* update vdev active inactive status */
+		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
+							    resp);
+		return;
+	}
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, req->param.num_vdev_bitmap,
+		req->param.vdev_bitmap,
+		&link_bitmap,
+		&assoc_bitmap);
+	ml_nlink_set_curr_force_inactive_num_state(
+		psoc, vdev, req->param.link_num[0].num_of_link,
+		link_bitmap);
+
+	/*
+	 * MLO_LINK_FORCE_MODE_INACTIVE_NUM return which vdev is
+	 * inactive So XOR of the requested ML vdev and inactive vdev
+	 * bit will give the vdev bits to be enable.
+	 */
+	for (i = 0; i < resp->inactive_sz; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+			psoc,
+			resp->inactive[i] ^ req->param.vdev_bitmap[i],
+			resp->inactive[i], i * 32);
+}
+
+static void
+policy_mgr_handle_force_active_inactive_resp(
+				struct wlan_objmgr_psoc *psoc,
+				struct wlan_objmgr_vdev *vdev,
+				struct mlo_link_set_active_req *req,
+				struct mlo_link_set_active_resp *resp)
+{
+	uint8_t i;
+	uint32_t assoc_bitmap = 0;
+
+	if (resp->use_ieee_link_id) {
+		/* save link active/inactive bitmap */
+		ml_nlink_set_curr_force_active_state(
+			psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap,
+			req->param.control_flags.overwrite_force_active_bitmap ?
+			LINK_OVERWRITE : LINK_ADD);
+		ml_nlink_set_curr_force_inactive_state(
+			psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap2,
+			req->param.control_flags.overwrite_force_inactive_bitmap ?
+			LINK_OVERWRITE : LINK_ADD);
+
+		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
+							  resp);
+
+		/* update vdev active inactive status */
+		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
+							    resp);
+		return;
+	}
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, req->param.num_inactive_vdev_bitmap,
+		req->param.inactive_vdev_bitmap,
+		&resp->inactive_linkid_bitmap,
+		&assoc_bitmap);
+	ml_nlink_set_curr_force_inactive_state(
+		psoc, vdev, resp->inactive_linkid_bitmap, LINK_ADD);
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, req->param.num_vdev_bitmap,
+		req->param.vdev_bitmap,
+		&resp->active_linkid_bitmap,
+		&assoc_bitmap);
+	ml_nlink_set_curr_force_active_state(
+		psoc, vdev, resp->active_linkid_bitmap, LINK_ADD);
+
+	for (i = 0; i < resp->inactive_sz; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+				psoc, 0, resp->inactive[i], i * 32);
+	for (i = 0; i < resp->active_sz; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+				psoc, resp->active[i], 0, i * 32);
+}
+
+static void
+policy_mgr_handle_no_force_resp(struct wlan_objmgr_psoc *psoc,
+				struct wlan_objmgr_vdev *vdev,
+				struct mlo_link_set_active_req *req,
+				struct mlo_link_set_active_resp *resp)
+{
+	uint8_t i;
+	uint32_t assoc_bitmap = 0;
+	uint32_t link_bitmap = 0;
+
+	if (resp->use_ieee_link_id) {
+		/* update link inactive/active bitmap */
+		if (req->param.force_cmd.ieee_link_id_bitmap) {
+			ml_nlink_set_curr_force_inactive_state(
+				psoc, vdev,
+				req->param.force_cmd.ieee_link_id_bitmap,
+				LINK_CLR);
+			ml_nlink_set_curr_force_active_state(
+				psoc, vdev,
+				req->param.force_cmd.ieee_link_id_bitmap,
+				LINK_CLR);
+		} else {
+			/* special handling for no force to clear all */
+			ml_nlink_clr_force_state(psoc, vdev);
+		}
+
+		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
+							  resp);
+		/* update vdev active inactive status */
+		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
+							    resp);
+		return;
+	}
+
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, req->param.num_vdev_bitmap,
+		req->param.vdev_bitmap,
+		&link_bitmap, &assoc_bitmap);
+
+	ml_nlink_set_curr_force_inactive_state(
+		psoc, vdev, link_bitmap, LINK_CLR);
+	ml_nlink_set_curr_force_active_state(
+		psoc, vdev, link_bitmap, LINK_CLR);
+	ml_nlink_set_curr_force_active_num_state(
+		psoc, vdev, 0, 0);
+	ml_nlink_set_curr_force_inactive_num_state(
+		psoc, vdev, 0, 0);
+
+	/* Enable all the ML vdev id sent in request */
+	for (i = 0; i < req->param.num_vdev_bitmap; i++)
+		policy_mgr_enable_disable_link_from_vdev_bitmask(
+			psoc, req->param.vdev_bitmap[i], 0, i * 32);
+}
+
+static void
+policy_mgr_handle_link_enable_disable_resp(struct wlan_objmgr_vdev *vdev,
+					  void *arg,
+					  struct mlo_link_set_active_resp *resp)
+{
+	struct mlo_link_set_active_req *req = arg;
+	struct wlan_objmgr_psoc *psoc;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		policy_mgr_err("Psoc is Null");
+		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);
+	if (!req || !resp) {
+		policy_mgr_err("arguments or event empty for vdev %d",
+			       wlan_vdev_get_id(vdev));
+		goto complete_evnt;
+	}
+
+	if (resp->status) {
+		policy_mgr_err("Set link status %d, for mode %d reason %d vdev bitmask 0x%x",
+			       resp->status, req->param.force_mode,
+			       req->param.reason, req->param.vdev_bitmap[0]);
+		goto complete_evnt;
+	}
+
+	policy_mgr_debug("Req mode %d reason %d, bitmask[0] = 0x%x, resp: active %d inactive %d, active[0] 0x%x inactive[0] 0x%x",
+			 req->param.force_mode, req->param.reason,
+			 req->param.vdev_bitmap[0],
+			 resp->active_sz, resp->inactive_sz,
+			 resp->active[0], resp->inactive[0]);
+	switch (req->param.force_mode) {
+	case MLO_LINK_FORCE_MODE_ACTIVE:
+		policy_mgr_handle_force_active_resp(psoc, vdev, req, resp);
+		break;
+	case MLO_LINK_FORCE_MODE_INACTIVE:
+		policy_mgr_handle_force_inactive_resp(psoc, vdev, req, resp);
+		break;
+	case MLO_LINK_FORCE_MODE_ACTIVE_NUM:
+		policy_mgr_handle_force_active_num_resp(psoc, vdev, req, resp);
+		break;
+	case MLO_LINK_FORCE_MODE_INACTIVE_NUM:
+		policy_mgr_handle_force_inactive_num_resp(psoc, vdev, req,
+							  resp);
+		break;
+	case MLO_LINK_FORCE_MODE_NO_FORCE:
+		policy_mgr_handle_no_force_resp(psoc, vdev, req, resp);
+		break;
+	case MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE:
+		policy_mgr_handle_force_active_inactive_resp(psoc, vdev, req,
+							     resp);
+		break;
+	default:
+		policy_mgr_err("Invalid request req mode %d",
+			       req->param.force_mode);
+		break;
+	}
+	if (req->param.reason == MLO_LINK_FORCE_REASON_LINK_REMOVAL)
+		policy_mgr_trigger_roam_on_link_removal(vdev);
+
+complete_evnt:
+	policy_mgr_set_link_in_progress(pm_ctx, false);
+	if (ml_is_nlink_service_supported(psoc) &&
+	    req && resp && !resp->status &&
+	    req->param.control_flags.post_re_evaluate)
+		status = ml_nlink_conn_change_notify(
+			psoc, wlan_vdev_get_id(vdev),
+			ml_nlink_connection_updated_evt, NULL);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	/* reschedule force scc workqueue after link state changes */
+	if (req && resp && !resp->status &&
+	    status == QDF_STATUS_SUCCESS)
+		policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false);
+}
+#else
+static inline QDF_STATUS
+policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				      uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+bool policy_mgr_is_mlo_sta_disconnected(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	bool disconnected;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev)
+		return true;
+	/* mlo mgr has no corresponding protocol api used in non-osif/hdd
+	 * component. Todo: clean up to use internal API
+	 */
+	disconnected = ucfg_mlo_is_mld_disconnected(vdev);
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return disconnected;
+}
+
+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;
+	uint32_t conn_6ghz_flag = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	/*
+	 * Need to acquire 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_NAN_DISC_MODE:
+	case QDF_NDI_MODE:
+		pm_ctx->no_of_active_sessions[mode]++;
+		break;
+	default:
+		break;
+	}
+
+	if (mode == QDF_NDI_MODE &&
+	    pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt)
+		pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt(
+				psoc, session_id,
+				pm_ctx->no_of_active_sessions[mode]);
+
+	if (mode != QDF_NAN_DISC_MODE && pm_ctx->dp_cbacks.hdd_v2_flow_pool_map)
+		pm_ctx->dp_cbacks.hdd_v2_flow_pool_map(session_id);
+	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
+		policy_mgr_get_ap_6ghz_capable(psoc, session_id,
+					       &conn_6ghz_flag);
+
+	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, mode);
+
+	if ((policy_mgr_mode_specific_connection_count(
+		psoc, PM_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) {
+		/* Send set pcl for all the connected STA vdev */
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		polic_mgr_send_pcl_to_fw(psoc, 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 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_get_beaconing_mode_count(psoc, NULL) > 0) ||
+	    (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_CLIENT_MODE, NULL) >
+									0) ||
+	    (policy_mgr_mode_specific_connection_count(psoc,
+						       PM_NDI_MODE,
+						       NULL) > 0)) {
+		if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency)
+			pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(true);
+	};
+
+	/* Enable RPS if SAP interface has come up */
+	if (policy_mgr_get_sap_mode_count(psoc, NULL) == 1) {
+		if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb)
+			pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(true);
+	}
+	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
+		policy_mgr_init_ap_6ghz_capable(psoc, session_id,
+						conn_6ghz_flag);
+	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE ||
+	    mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE)
+		policy_mgr_update_dfs_master_dynamic_enabled(psoc, session_id);
+
+	policy_mgr_dump_current_concurrency(psoc);
+
+	if (policy_mgr_update_indoor_concurrency(psoc, session_id, 0, CONNECT))
+		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
+		ml_nlink_conn_change_notify(
+			psoc, session_id, ml_nlink_ap_started_evt, NULL);
+}
+
+/**
+ * policy_mgr_update_sta_scc_info_for_later_check() - function to update sta/sap
+ * scc channel frequency and later check flag.
+ * @pm_ctx: policy manager context pointer
+ * @mode: operation mode
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+static void policy_mgr_update_sta_scc_info_for_later_check(
+		struct policy_mgr_psoc_priv_obj *pm_ctx,
+		enum QDF_OPMODE mode,
+		uint8_t vdev_id)
+{
+	uint32_t conn_index = 0;
+	qdf_freq_t sta_freq = 0;
+
+	if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
+		return;
+
+	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) {
+			sta_freq = pm_conc_connection_list[conn_index].freq;
+			break;
+		}
+		conn_index++;
+	}
+
+	if (!sta_freq)
+		goto release_mutex;
+
+	/*
+	 * When STA disconnected, we need to move DFS SAP
+	 * to Non-DFS if g_sta_sap_scc_on_dfs_chan enabled.
+	 * The same if g_sta_sap_scc_on_lte_coex_chan enabled,
+	 * need to move SAP on unsafe channel to safe channel.
+	 * The flag will be checked by
+	 * policy_mgr_is_sap_restart_required_after_sta_disconnect.
+	 */
+	conn_index = 0;
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if (pm_conc_connection_list[conn_index].freq == sta_freq &&
+		    (pm_conc_connection_list[conn_index].mode == PM_SAP_MODE ||
+		    pm_conc_connection_list[conn_index].mode ==
+		    PM_P2P_GO_MODE)) {
+			pm_ctx->last_disconn_sta_freq = sta_freq;
+			break;
+		}
+		conn_index++;
+	}
+
+release_mutex:
+	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;
+	uint32_t session_count, cur_freq;
+	enum hw_mode_bandwidth max_bw;
+
+	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_qdf_opmode_to_pm_con_mode(psoc, mode,
+							     session_id),
+			session_id);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		policy_mgr_debug("No connection with mode:%d vdev_id:%d",
+			policy_mgr_qdf_opmode_to_pm_con_mode(psoc, mode,
+							     session_id),
+			session_id);
+		/*
+		 * In case of disconnect try delete the link from disabled link
+		 * as well, if its not present in pm_conc_connection_list,
+		 * it can be present in pm_disabled_ml_links.
+		 */
+		policy_mgr_delete_from_disabled_links(pm_ctx, session_id);
+		policy_mgr_dump_current_concurrency(psoc);
+		return qdf_status;
+	}
+	policy_mgr_update_sta_scc_info_for_later_check(pm_ctx,
+						       mode,
+						       session_id);
+	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_NAN_DISC_MODE:
+	case QDF_NDI_MODE:
+		if (pm_ctx->no_of_active_sessions[mode])
+			pm_ctx->no_of_active_sessions[mode]--;
+		break;
+	default:
+		break;
+	}
+
+	policy_mgr_get_chan_by_session_id(psoc, session_id, &cur_freq);
+
+	policy_mgr_decr_connection_count(psoc, session_id);
+	session_count = pm_ctx->no_of_active_sessions[mode];
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (mode != QDF_NAN_DISC_MODE &&
+	    pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap)
+		pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap(session_id);
+
+	if (mode == QDF_NDI_MODE &&
+	    pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt)
+		pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt(
+				psoc, session_id, session_count);
+
+	policy_mgr_debug("No.# of active sessions for mode %d = %d",
+			 mode, session_count);
+
+	/* 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_get_connection_count(psoc) == 0) ||
+	    ((policy_mgr_mode_specific_connection_count(psoc,
+							PM_STA_MODE,
+							NULL) == 1) &&
+	     (policy_mgr_get_beaconing_mode_count(psoc, NULL) == 0) &&
+	     (policy_mgr_mode_specific_connection_count(psoc,
+							PM_P2P_CLIENT_MODE,
+							NULL) == 0) &&
+	     (policy_mgr_mode_specific_connection_count(psoc,
+							PM_NDI_MODE,
+							NULL) == 0))) {
+		if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency)
+			pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(false);
+	};
+
+	/* Disable RPS if SAP interface has come up */
+	if (policy_mgr_get_sap_mode_count(psoc, NULL) == 0) {
+		if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb)
+			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) {
+		mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc);
+
+		if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb)
+			pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode);
+
+		if (pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw) {
+			max_bw = policy_mgr_get_connection_max_channel_width(
+					psoc);
+			policy_mgr_debug("max channel width %d", max_bw);
+			pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw(max_bw);
+		}
+	}
+
+	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE ||
+	    mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE)
+		policy_mgr_update_dfs_master_dynamic_enabled(psoc, session_id);
+
+	if (!pm_ctx->last_disconn_sta_freq) {
+		if (policy_mgr_update_indoor_concurrency(psoc, session_id,
+		    cur_freq, DISCONNECT_WITHOUT_CONCURRENCY))
+			wlan_reg_recompute_current_chan_list(psoc,
+							     pm_ctx->pdev);
+	}
+
+	if (wlan_reg_get_keep_6ghz_sta_cli_connection(pm_ctx->pdev) &&
+	    (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE))
+		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
+
+	return qdf_status;
+}
+
+QDF_STATUS policy_mgr_incr_connection_count(struct wlan_objmgr_psoc *psoc,
+					    uint32_t vdev_id,
+					    enum QDF_OPMODE op_mode)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t conn_index;
+	struct policy_mgr_vdev_entry_info conn_table_entry = {0};
+	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;
+	uint32_t ch_freq;
+	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 (op_mode == QDF_NAN_DISC_MODE) {
+		status = wlan_nan_get_connection_info(psoc, &conn_table_entry);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			policy_mgr_err("Can't get NAN Connection info");
+			return status;
+		}
+	} else 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_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id);
+
+	ch_freq = 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_FREQ(ch_freq) && nss_2g > 1) ||
+		    (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1))
+			chain_mask = POLICY_MGR_TWO_TWO;
+		else
+			chain_mask = POLICY_MGR_ONE_ONE;
+		nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? 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,
+			ch_freq,
+			policy_mgr_get_bw(conn_table_entry.chan_width),
+			conn_table_entry.mac_id,
+			chain_mask,
+			nss, vdev_id, true, update_conn,
+			conn_table_entry.ch_flagext);
+	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;
+	bool panic = false;
+
+	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].freq =
+			pm_conc_connection_list[next_conn_index].freq;
+		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;
+		pm_conc_connection_list[conn_index].ch_flagext =
+			pm_conc_connection_list[next_conn_index].ch_flagext;
+		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));
+
+	conn_index = 0;
+	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
+		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
+			panic = true;
+			break;
+		}
+		conn_index++;
+	}
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (panic) {
+		policy_mgr_err("dup entry occur");
+		policy_mgr_debug_alert();
+	}
+	if (pm_ctx->conc_cbacks.connection_info_update)
+		pm_ctx->conc_cbacks.connection_info_update();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint32_t policy_mgr_get_mode_specific_conn_info(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *ch_freq_list, 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 (!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 == 1) {
+		if (ch_freq_list)
+			*ch_freq_list =
+				pm_conc_connection_list[list[index]].freq;
+		*vdev_id =
+			pm_conc_connection_list[list[index]].vdev_id;
+	} else {
+		for (index = 0; index < count; index++) {
+			if (ch_freq_list)
+				ch_freq_list[index] =
+			pm_conc_connection_list[list[index]].freq;
+
+			vdev_id[index] =
+			pm_conc_connection_list[list[index]].vdev_id;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+uint32_t policy_mgr_get_sap_mode_info(struct wlan_objmgr_psoc *psoc,
+				      uint32_t *ch_freq_list, uint8_t *vdev_id)
+{
+	uint32_t count;
+
+	count = policy_mgr_get_mode_specific_conn_info(psoc, ch_freq_list,
+						       vdev_id, PM_SAP_MODE);
+
+	count += policy_mgr_get_mode_specific_conn_info(
+				psoc,
+				ch_freq_list ? &ch_freq_list[count] : NULL,
+				vdev_id ? &vdev_id[count] : NULL,
+				PM_LL_LT_SAP_MODE);
+	return count;
+}
+
+uint32_t policy_mgr_get_beaconing_mode_info(struct wlan_objmgr_psoc *psoc,
+					    uint32_t *ch_freq_list,
+					    uint8_t *vdev_id)
+{
+	uint32_t count;
+
+	count = policy_mgr_get_sap_mode_info(psoc, ch_freq_list, vdev_id);
+
+	count += policy_mgr_get_mode_specific_conn_info(
+				psoc,
+				ch_freq_list ? &ch_freq_list[count] : NULL,
+				vdev_id ? &vdev_id[count] : NULL,
+				PM_P2P_GO_MODE);
+	return count;
+}
+
+void policy_mgr_get_ml_and_non_ml_sta_count(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *num_ml, uint8_t *ml_idx,
+					    uint8_t *num_non_ml,
+					    uint8_t *non_ml_idx,
+					    qdf_freq_t *freq_list,
+					    uint8_t *vdev_id_list)
+{
+	uint32_t sta_num = 0;
+	uint8_t i;
+	struct wlan_objmgr_vdev *temp_vdev;
+
+	*num_ml = 0;
+	*num_non_ml = 0;
+
+	sta_num = policy_mgr_get_mode_specific_conn_info(psoc, freq_list,
+							 vdev_id_list,
+							 PM_STA_MODE);
+	if (!sta_num)
+		return;
+
+	for (i = 0; i < sta_num; i++) {
+		temp_vdev =
+			wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+							    vdev_id_list[i],
+							    WLAN_POLICY_MGR_ID);
+		if (!temp_vdev) {
+			policy_mgr_err("invalid vdev for id %d",
+				       vdev_id_list[i]);
+			*num_ml = 0;
+			*num_non_ml = 0;
+			return;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
+			if (ml_idx)
+				ml_idx[*num_ml] = i;
+			(*num_ml)++;
+		} else {
+			if (non_ml_idx)
+				non_ml_idx[*num_non_ml] = i;
+			(*num_non_ml)++;
+		}
+
+		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
+	}
+}
+
+bool policy_mgr_concurrent_sta_on_different_mac(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t num_ml = 0, num_non_ml = 0;
+	uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool is_different_mac = false;
+	int i;
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return false;
+
+	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);
+	policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx,
+					       &num_non_ml, non_ml_idx,
+					       freq_list, vdev_id_list);
+	if (num_ml + num_non_ml < 2 || !num_non_ml)
+		goto out;
+
+	/*
+	 * If more than 1 Non-ML STA is present, check whether they are
+	 * within the same band.
+	 */
+	for (i = 1; i < num_non_ml; i++) {
+		if (!policy_mgr_2_freq_always_on_same_mac(psoc,
+							  freq_list[non_ml_idx[i]],
+							  freq_list[non_ml_idx[0]])) {
+			is_different_mac = true;
+			goto out;
+		}
+	}
+
+	if (num_non_ml >= 2)
+		goto out;
+
+	/* ML STA + Non-ML STA */
+	for (i = 0; i < num_ml; i++) {
+		if (!policy_mgr_2_freq_always_on_same_mac(psoc,
+							  freq_list[ml_idx[i]],
+							  freq_list[non_ml_idx[0]])) {
+			is_different_mac = true;
+			goto out;
+		}
+	}
+
+out:
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_debug("Non-ML STA count %d, ML STA count %d, sta concurrency on different mac %d",
+			 num_non_ml, num_ml, is_different_mac);
+
+	return is_different_mac;
+}
+
+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 (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_allow_wapi_concurrency() - Check if WAPI concurrency is allowed
+ * @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 if the hardware doesn't support WAPI concurrency.
+ *
+ * Return: true - allow
+ */
+static bool
+policy_mgr_allow_wapi_concurrency(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	struct wlan_objmgr_pdev *pdev = pm_ctx->pdev;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+
+	if (!pdev) {
+		policy_mgr_debug("pdev is Null");
+		return false;
+	}
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return false;
+
+	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_wapi_concurrency_supported) &&
+	    mlme_is_wapi_sta_active(pdev) &&
+	    policy_mgr_get_connection_count(pm_ctx->psoc) > 0)
+		return false;
+
+	return true;
+}
+
+#ifdef FEATURE_FOURTH_CONNECTION
+static bool policy_mgr_is_concurrency_allowed_4_port(
+					struct wlan_objmgr_psoc *psoc,
+					enum policy_mgr_con_mode mode,
+					uint32_t ch_freq,
+					struct policy_mgr_pcl_list pcl)
+{
+	uint32_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
+	uint8_t sap_cnt, go_cnt, ll_lt_sap_vdev_id;
+
+	ll_lt_sap_vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc);
+
+	if (ll_lt_sap_vdev_id != WLAN_INVALID_VDEV_ID) {
+		policy_mgr_debug("LL_LT_SAP vdev %d present avoid 4th port concurrency",
+				 ll_lt_sap_vdev_id);
+		return false;
+	}
+	/* new STA may just have ssid, no channel until bssid assigned */
+	if (ch_freq == 0 && mode == PM_STA_MODE)
+		return true;
+
+	sap_cnt = policy_mgr_mode_specific_connection_count(psoc,
+							    PM_SAP_MODE, NULL);
+
+	go_cnt = policy_mgr_mode_specific_connection_count(psoc,
+							   PM_P2P_GO_MODE, NULL);
+	if (sap_cnt || go_cnt) {
+		pm_ctx = policy_mgr_get_context(psoc);
+		if (!pm_ctx) {
+			policy_mgr_err("context is NULL");
+			return false;
+		}
+
+		if (!policy_mgr_is_force_scc(psoc)) {
+			policy_mgr_err("couldn't start 4th port for bad force scc cfg");
+			return false;
+		}
+
+		if (!policy_mgr_is_dbs_enable(psoc)) {
+			policy_mgr_err(
+				"Couldn't start 4th port for bad cfg of dual mac");
+			return false;
+		}
+		for (i = 0; i < pcl.pcl_len; i++)
+			if (ch_freq == pcl.pcl_list[i])
+				return true;
+
+		policy_mgr_err("4th port failed on ch freq %d with mode %d",
+			       ch_freq, mode);
+
+		return false;
+	}
+
+	return true;
+}
+#else
+static inline bool policy_mgr_is_concurrency_allowed_4_port(
+				struct wlan_objmgr_psoc *psoc,
+				enum policy_mgr_con_mode mode,
+				uint32_t ch_freq,
+				struct policy_mgr_pcl_list pcl)
+{return false; }
+#endif
+
+bool
+policy_mgr_allow_multiple_sta_connections(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_sta_plus_sta_support)) {
+		policy_mgr_rl_debug("STA+STA is not supported");
+		return false;
+	}
+
+	return true;
+}
+
+#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)
+bool policy_mgr_is_6ghz_conc_mode_supported(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
+{
+	if (mode == PM_STA_MODE || mode == PM_SAP_MODE ||
+	    mode == PM_P2P_CLIENT_MODE || mode == PM_P2P_GO_MODE)
+		return true;
+	else
+		return false;
+}
+#endif
+
+/**
+ * policy_mgr_is_6g_channel_allowed() - Check new 6Ghz connection
+ * allowed or not
+ * @psoc: Pointer to soc
+ * @mode: new connection mode
+ * @ch_freq: channel freq
+ *
+ * 1. Only STA/SAP are allowed on 6Ghz.
+ * 2. If there is DFS beacon entity existing on 5G band, 5G+6G MCC is not
+ * allowed.
+ *
+ *  Return: true if supports else false.
+ */
+static bool policy_mgr_is_6g_channel_allowed(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode,
+	uint32_t ch_freq)
+{
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_conc_connection_info *conn;
+	bool is_dfs;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) {
+		policy_mgr_rl_debug("Not a 6Ghz channel Freq");
+		return true;
+	}
+	/* Only STA/SAP is supported on 6Ghz currently */
+	if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) {
+		policy_mgr_rl_debug("mode %d for 6ghz not supported", mode);
+		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 = &pm_conc_connection_list[conn_index];
+		if (!conn->in_use)
+			continue;
+		is_dfs = (conn->ch_flagext &
+			(IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) &&
+			WLAN_REG_IS_5GHZ_CH_FREQ(conn->freq);
+		if (policy_mgr_is_beaconing_mode(conn->mode) &&
+		    is_dfs && (ch_freq != conn->freq &&
+			       !policy_mgr_are_sbs_chan(psoc, ch_freq,
+							conn->freq))) {
+			policy_mgr_rl_debug("don't allow MCC if SAP/GO on DFS channel");
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return false;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return true;
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+static bool policy_mgr_is_acs_2ghz_only_sap(struct wlan_objmgr_psoc *psoc,
+					    uint8_t sap_vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t acs_band = QCA_ACS_MODE_IEEE80211ANY;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	if (pm_ctx->hdd_cbacks.wlan_get_sap_acs_band)
+		pm_ctx->hdd_cbacks.wlan_get_sap_acs_band(psoc,
+							 sap_vdev_id,
+							 &acs_band);
+
+	if (acs_band == QCA_ACS_MODE_IEEE80211B ||
+	    acs_band == QCA_ACS_MODE_IEEE80211G)
+		return true;
+
+	return false;
+}
+
+bool policy_mgr_vdev_is_force_inactive(struct wlan_objmgr_psoc *psoc,
+				       uint8_t vdev_id)
+{
+	bool force_inactive = false;
+	uint8_t conn_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 false;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	/* Get disabled link info as well and keep it at last */
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK;
+	     conn_index++) {
+		if (pm_disabled_ml_links[conn_index].in_use &&
+		    pm_disabled_ml_links[conn_index].mode == PM_STA_MODE &&
+		    pm_disabled_ml_links[conn_index].vdev_id == vdev_id) {
+			force_inactive = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return force_inactive;
+}
+
+/* MCC avoidance priority value for different legacy connection type.
+ * Internal macro, not expected used other code.
+ * Bigger value have higher priority.
+ */
+#define PRIORITY_STA	3
+#define PRIORITY_SAP	2
+#define PRIORITY_P2P	1
+#define PRIORITY_OTHER	0
+
+uint8_t
+policy_mgr_get_legacy_conn_info(struct wlan_objmgr_psoc *psoc,
+				uint8_t *vdev_lst,
+				qdf_freq_t *freq_lst,
+				enum policy_mgr_con_mode *mode_lst,
+				uint8_t lst_sz)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t conn_index, j = 0, i, k, n;
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t vdev_id;
+	uint8_t has_priority[MAX_NUMBER_OF_CONC_CONNECTIONS];
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		if (j >= lst_sz)
+			break;
+		if (!pm_conc_connection_list[conn_index].in_use)
+			continue;
+		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+				pm_ctx->psoc, vdev_id, WLAN_POLICY_MGR_ID);
+		if (!vdev) {
+			policy_mgr_err("invalid vdev for id %d", vdev_id);
+			continue;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
+		    pm_conc_connection_list[conn_index].mode ==
+							PM_STA_MODE) {
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+			continue;
+		}
+		if (pm_conc_connection_list[conn_index].mode !=
+							PM_STA_MODE &&
+		    pm_conc_connection_list[conn_index].mode !=
+							PM_SAP_MODE &&
+		    pm_conc_connection_list[conn_index].mode !=
+							PM_P2P_CLIENT_MODE &&
+		    pm_conc_connection_list[conn_index].mode !=
+							PM_P2P_GO_MODE) {
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+			continue;
+		}
+
+		/* Set mcc avoidance priority value. The bigger value
+		 * have higher priority to avoid MCC. In 3 Port concurrency
+		 * case, usually we can only meet the higher priority intf's
+		 * MCC avoidance by force inactive link.
+		 */
+		if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE)
+			has_priority[j] = PRIORITY_STA;
+		else if (pm_conc_connection_list[conn_index].mode ==
+							PM_SAP_MODE &&
+			 policy_mgr_is_acs_2ghz_only_sap(psoc, vdev_id))
+			has_priority[j] = PRIORITY_SAP;
+		else if ((pm_conc_connection_list[conn_index].mode ==
+							PM_P2P_CLIENT_MODE ||
+			  pm_conc_connection_list[conn_index].mode ==
+							PM_P2P_GO_MODE) &&
+			 policy_mgr_is_vdev_high_tput_or_low_latency(
+							psoc, vdev_id))
+			has_priority[j] = PRIORITY_P2P;
+		else
+			has_priority[j] = PRIORITY_OTHER;
+
+		vdev_lst[j] = vdev_id;
+		freq_lst[j] = pm_conc_connection_list[conn_index].freq;
+		mode_lst[j] = pm_conc_connection_list[conn_index].mode;
+		policy_mgr_debug("vdev %d freq %d mode %s pri %d",
+				 vdev_id, freq_lst[j],
+				 device_mode_to_string(mode_lst[j]),
+				 has_priority[j]);
+		j++;
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+	/* sort the list based on priority */
+	for (i = 0; i < j; i++) {
+		uint8_t tmp_vdev_lst;
+		qdf_freq_t tmp_freq_lst;
+		enum policy_mgr_con_mode tmp_mode_lst;
+
+		n = i;
+		for (k = i + 1; k < j; k++) {
+			if (has_priority[n] < has_priority[k])
+				n = k;
+			else if ((has_priority[n] == has_priority[k]) &&
+				 (vdev_lst[n] > vdev_lst[k]))
+				n = k;
+		}
+		if (n == i)
+			continue;
+		tmp_vdev_lst = vdev_lst[i];
+		tmp_freq_lst = freq_lst[i];
+		tmp_mode_lst = mode_lst[i];
+
+		vdev_lst[i] = vdev_lst[n];
+		freq_lst[i] = freq_lst[n];
+		mode_lst[i] = mode_lst[n];
+
+		vdev_lst[n] = tmp_vdev_lst;
+		freq_lst[n] = tmp_freq_lst;
+		mode_lst[n] = tmp_mode_lst;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return j;
+}
+
+static void
+policy_mgr_fill_ml_active_link_vdev_bitmap(struct mlo_link_set_active_req *req,
+					   uint8_t *mlo_vdev_lst,
+					   uint32_t num_mlo_vdev)
+{
+	uint32_t entry_idx, entry_offset, vdev_idx;
+	uint8_t vdev_id;
+
+	for (vdev_idx = 0; vdev_idx < num_mlo_vdev; vdev_idx++) {
+		vdev_id = mlo_vdev_lst[vdev_idx];
+		entry_idx = vdev_id / 32;
+		entry_offset = vdev_id % 32;
+		if (entry_idx >= MLO_LINK_NUM_SZ) {
+			policy_mgr_err("Invalid entry_idx %d num_mlo_vdev %d vdev %d",
+				       entry_idx, num_mlo_vdev, vdev_id);
+			continue;
+		}
+		req->param.vdev_bitmap[entry_idx] |= (1 << entry_offset);
+		/* update entry number if entry index changed */
+		if (req->param.num_vdev_bitmap < entry_idx + 1)
+			req->param.num_vdev_bitmap = entry_idx + 1;
+	}
+
+	policy_mgr_debug("num_vdev_bitmap %d vdev_bitmap[0] = 0x%x, vdev_bitmap[1] = 0x%x",
+			 req->param.num_vdev_bitmap, req->param.vdev_bitmap[0],
+			 req->param.vdev_bitmap[1]);
+}
+
+static void
+policy_mgr_fill_ml_inactive_link_vdev_bitmap(
+				struct mlo_link_set_active_req *req,
+				uint8_t *mlo_inactive_vdev_lst,
+				uint32_t num_mlo_inactive_vdev)
+{
+	uint32_t entry_idx, entry_offset, vdev_idx;
+	uint8_t vdev_id;
+
+	for (vdev_idx = 0; vdev_idx < num_mlo_inactive_vdev; vdev_idx++) {
+		vdev_id = mlo_inactive_vdev_lst[vdev_idx];
+		entry_idx = vdev_id / 32;
+		entry_offset = vdev_id % 32;
+		if (entry_idx >= MLO_LINK_NUM_SZ) {
+			policy_mgr_err("Invalid entry_idx %d num_mlo_vdev %d vdev %d",
+				       entry_idx, num_mlo_inactive_vdev,
+				       vdev_id);
+			continue;
+		}
+		req->param.inactive_vdev_bitmap[entry_idx] |=
+							(1 << entry_offset);
+		/* update entry number if entry index changed */
+		if (req->param.num_inactive_vdev_bitmap < entry_idx + 1)
+			req->param.num_inactive_vdev_bitmap = entry_idx + 1;
+	}
+
+	policy_mgr_debug("num_vdev_bitmap %d inactive_vdev_bitmap[0] = 0x%x, inactive_vdev_bitmap[1] = 0x%x",
+			 req->param.num_inactive_vdev_bitmap,
+			 req->param.inactive_vdev_bitmap[0],
+			 req->param.inactive_vdev_bitmap[1]);
+}
+
+/*
+ * policy_mgr_handle_ml_sta_link_state_allowed() - Check ml sta connection to
+ * allow link state change.
+ * @psoc: psoc object
+ * @reason: set link state reason
+ *
+ * If ml sta is not "connected" state, no need to do link state handling.
+ * After disconnected, target will clear the force active/inactive state
+ * and host will remove the connection entry finally.
+ * After roaming done, active/inactive will be re-calculated.
+ *
+ * Return: QDF_STATUS_SUCCESS if link state is allowed to change
+ */
+static QDF_STATUS
+policy_mgr_handle_ml_sta_link_state_allowed(struct wlan_objmgr_psoc *psoc,
+					    enum mlo_link_force_reason reason)
+{
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	bool ml_sta_is_not_connected = false;
+	bool ml_sta_is_link_removal = false;
+	uint8_t i;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
+				   NULL, NULL);
+	if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		policy_mgr_debug("ml sta num is %d", num_ml_sta);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	for (i = 0; i < num_ml_sta; i++) {
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc,
+							    ml_sta_vdev_lst[i],
+							    WLAN_POLICY_MGR_ID);
+		if (!vdev) {
+			policy_mgr_err("invalid vdev for id %d",
+				       ml_sta_vdev_lst[i]);
+			continue;
+		}
+		if (!wlan_cm_is_vdev_connected(vdev)) {
+			policy_mgr_debug("ml sta vdev %d is not connected state",
+					 ml_sta_vdev_lst[i]);
+			ml_sta_is_not_connected = true;
+		}
+		if (wlan_get_vdev_link_removed_flag_by_vdev_id(
+						psoc, ml_sta_vdev_lst[i])) {
+			policy_mgr_debug("ml sta vdev %d link removed",
+					 ml_sta_vdev_lst[i]);
+			ml_sta_is_link_removal = true;
+		}
+
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+
+	if (ml_sta_is_not_connected) {
+		status = QDF_STATUS_E_FAILURE;
+	} else if (reason != MLO_LINK_FORCE_REASON_LINK_REMOVAL) {
+		if (ml_sta_is_link_removal)
+			status = QDF_STATUS_E_FAILURE;
+	}
+	policy_mgr_debug("set link reason %d status %d rm %d", reason, status,
+			 ml_sta_is_link_removal);
+
+	return status;
+}
+
+/*
+ * policy_mgr_validate_set_mlo_link_cb() - Callback to check whether
+ * it is allowed to set mlo sta link state.
+ * @psoc: psoc object
+ * @param: set mlo link parameter
+ *
+ * This api will be used as callback to be called by mlo_link_set_active
+ * in serialization context.
+ *
+ * Return: QDF_STATUS_SUCCESS if set mlo link is allowed
+ */
+static QDF_STATUS
+policy_mgr_validate_set_mlo_link_cb(struct wlan_objmgr_psoc *psoc,
+				    struct mlo_link_set_active_param *param)
+{
+	return policy_mgr_handle_ml_sta_link_state_allowed(psoc,
+							   param->reason);
+}
+
+uint32_t
+policy_mgr_get_active_vdev_bitmap(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_INVAL;
+	}
+
+	policy_mgr_debug("active link bitmap value: %d",
+			 pm_ctx->active_vdev_bitmap);
+
+	return pm_ctx->active_vdev_bitmap;
+}
+
+/**
+ * policy_mgr_mlo_sta_set_link_by_linkid() - wrapper API to call set link
+ * by link id bitmap API
+ * @psoc: psoc object
+ * @vdev: vdev object
+ * @reason: Reason for which link is forced
+ * @mode: Force reason
+ * @link_num: valid for MLO_LINK_FORCE_MODE_ACTIVE_NUM and
+ *  MLO_LINK_FORCE_MODE_INACTIVE_NUM.
+ * @num_mlo_vdev: number of mlo vdev in array mlo_vdev_lst
+ * @mlo_vdev_lst: MLO STA vdev list
+ * @num_mlo_inactive_vdev: number of mlo vdev in array mlo_inactive_vdev_lst
+ * @mlo_inactive_vdev_lst: MLO STA vdev list
+ *
+ * This is internal wrapper of policy_mgr_mlo_sta_set_nlink to convert
+ * vdev based set link to link id based API for being compatible with old code.
+ * New code to use policy_mgr_mlo_sta_set_nlink directly as much as possible.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+policy_mgr_mlo_sta_set_link_by_linkid(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      enum mlo_link_force_reason reason,
+				      enum mlo_link_force_mode mode,
+				      uint8_t link_num,
+				      uint8_t num_mlo_vdev,
+				      uint8_t *mlo_vdev_lst,
+				      uint8_t num_mlo_inactive_vdev,
+				      uint8_t *mlo_inactive_vdev_lst)
+{
+	uint32_t link_bitmap = 0;
+	uint32_t link_bitmap2 = 0;
+	uint32_t assoc_bitmap = 0;
+	uint32_t vdev_bitmap[MLO_VDEV_BITMAP_SZ];
+	uint32_t vdev_bitmap2[MLO_VDEV_BITMAP_SZ];
+	uint8_t i, idx;
+	uint32_t link_control_flags = 0;
+	uint8_t vdev_per_bitmap = MLO_MAX_VDEV_COUNT_PER_BIMTAP_ELEMENT;
+
+	qdf_mem_zero(vdev_bitmap, sizeof(vdev_bitmap));
+	qdf_mem_zero(vdev_bitmap2, sizeof(vdev_bitmap2));
+
+	for (i = 0; i < num_mlo_vdev; i++) {
+		idx = mlo_vdev_lst[i] / vdev_per_bitmap;
+		if (idx >= MLO_VDEV_BITMAP_SZ)
+			return QDF_STATUS_E_INVAL;
+		vdev_bitmap[idx] |= 1 << (mlo_vdev_lst[i] % vdev_per_bitmap);
+	}
+
+	for (i = 0; i < num_mlo_inactive_vdev; i++) {
+		idx = mlo_inactive_vdev_lst[i] / vdev_per_bitmap;
+		if (idx >= MLO_VDEV_BITMAP_SZ)
+			return QDF_STATUS_E_INVAL;
+		vdev_bitmap2[idx] |=
+			1 << (mlo_inactive_vdev_lst[i] % vdev_per_bitmap);
+	}
+
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, MLO_VDEV_BITMAP_SZ, vdev_bitmap,
+		&link_bitmap, &assoc_bitmap);
+
+	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
+		psoc, vdev, MLO_VDEV_BITMAP_SZ, vdev_bitmap2,
+		&link_bitmap2, &assoc_bitmap);
+
+	switch (mode) {
+	case MLO_LINK_FORCE_MODE_ACTIVE:
+		link_control_flags = link_ctrl_f_overwrite_active_bitmap;
+		break;
+	case MLO_LINK_FORCE_MODE_INACTIVE:
+		if (reason != MLO_LINK_FORCE_REASON_LINK_REMOVAL)
+			link_control_flags =
+				link_ctrl_f_overwrite_inactive_bitmap;
+		break;
+	case MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE:
+		if (reason != MLO_LINK_FORCE_REASON_LINK_REMOVAL)
+			link_control_flags =
+				link_ctrl_f_overwrite_active_bitmap |
+				link_ctrl_f_overwrite_inactive_bitmap;
+		break;
+	case MLO_LINK_FORCE_MODE_ACTIVE_NUM:
+		link_control_flags = link_ctrl_f_dynamic_force_link_num;
+		break;
+	case MLO_LINK_FORCE_MODE_INACTIVE_NUM:
+		link_control_flags = link_ctrl_f_dynamic_force_link_num;
+		break;
+	case MLO_LINK_FORCE_MODE_NO_FORCE:
+		link_control_flags = 0;
+		break;
+	default:
+		policy_mgr_err("Invalid force mode: %d", mode);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return policy_mgr_mlo_sta_set_nlink(psoc, wlan_vdev_get_id(vdev),
+					    reason, mode,
+					    link_num, link_bitmap,
+					    link_bitmap2, link_control_flags);
+}
+
+/**
+ * policy_mgr_mlo_sta_set_link_ext() - Set links for MLO STA
+ * @psoc: psoc object
+ * @reason: Reason for which link is forced
+ * @mode: Force reason
+ * @num_mlo_vdev: number of mlo vdev
+ * @mlo_vdev_lst: MLO STA vdev list
+ * @num_mlo_inactive_vdev: number of mlo vdev
+ * @mlo_inactive_vdev_lst: MLO STA vdev list
+ *
+ * Interface manager Set links for MLO STA. And it supports to
+ * add inactive vdev list.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+policy_mgr_mlo_sta_set_link_ext(struct wlan_objmgr_psoc *psoc,
+				enum mlo_link_force_reason reason,
+				enum mlo_link_force_mode mode,
+				uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst,
+				uint8_t num_mlo_inactive_vdev,
+				uint8_t *mlo_inactive_vdev_lst)
+{
+	struct mlo_link_set_active_req *req;
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!num_mlo_vdev) {
+		policy_mgr_err("invalid 0 num_mlo_vdev");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	/*
+	 * Use one of the ML vdev as, if called from disconnect the caller vdev
+	 * may get deleted, and thus flush serialization command.
+	 */
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, mlo_vdev_lst[0],
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d: invalid vdev", mlo_vdev_lst[0]);
+		qdf_mem_free(req);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_debug("vdev %d: mode %d num_mlo_vdev %d reason %d",
+			 wlan_vdev_get_id(vdev), mode, num_mlo_vdev, reason);
+
+	req->ctx.vdev = vdev;
+	req->param.reason = reason;
+	req->param.force_mode = mode;
+	req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp;
+	req->ctx.validate_set_mlo_link_cb =
+		policy_mgr_validate_set_mlo_link_cb;
+	req->ctx.cb_arg = req;
+
+	/* set MLO vdev bit mask for all case */
+	policy_mgr_fill_ml_active_link_vdev_bitmap(req, mlo_vdev_lst,
+						   num_mlo_vdev);
+
+	pm_ctx->active_vdev_bitmap = req->param.vdev_bitmap[0];
+	pm_ctx->inactive_vdev_bitmap = req->param.vdev_bitmap[1];
+
+	if (mode == MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE)
+		policy_mgr_fill_ml_inactive_link_vdev_bitmap(
+			req, mlo_inactive_vdev_lst, num_mlo_inactive_vdev);
+
+	/*
+	 * Fill number of links for MLO_LINK_FORCE_MODE_ACTIVE_NUM or
+	 * MLO_LINK_FORCE_MODE_INACTIVE_NUM mode.
+	 */
+	if (mode == MLO_LINK_FORCE_MODE_ACTIVE_NUM ||
+	    mode == MLO_LINK_FORCE_MODE_INACTIVE_NUM) {
+		req->param.num_link_entry = 1;
+		req->param.link_num[0].num_of_link = num_mlo_vdev - 1;
+	}
+
+	if (ml_is_nlink_service_supported(psoc)) {
+		status =
+		policy_mgr_mlo_sta_set_link_by_linkid(psoc, vdev, reason,
+						      mode,
+						      req->param.link_num[0].
+						      num_of_link,
+						      num_mlo_vdev,
+						      mlo_vdev_lst,
+						      num_mlo_inactive_vdev,
+						      mlo_inactive_vdev_lst);
+		qdf_mem_free(req);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+		if (status != QDF_STATUS_E_PENDING) {
+			policy_mgr_err("set_link_by_linkid status %d", status);
+			return status;
+		}
+		return QDF_STATUS_SUCCESS;
+	}
+
+	policy_mgr_set_link_in_progress(pm_ctx, true);
+
+	status = mlo_ser_set_link_req(req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d reason %d",
+			       wlan_vdev_get_id(vdev), mode, num_mlo_vdev,
+			       reason);
+		qdf_mem_free(req);
+		policy_mgr_set_link_in_progress(pm_ctx, false);
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	return status;
+}
+
+QDF_STATUS
+policy_mgr_mlo_sta_set_link(struct wlan_objmgr_psoc *psoc,
+			    enum mlo_link_force_reason reason,
+			    enum mlo_link_force_mode mode,
+			    uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst)
+{
+	return policy_mgr_mlo_sta_set_link_ext(psoc, reason, mode, num_mlo_vdev,
+					       mlo_vdev_lst, 0, NULL);
+}
+
+QDF_STATUS
+policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc,
+			     uint8_t vdev_id,
+			     enum mlo_link_force_reason reason,
+			     enum mlo_link_force_mode mode,
+			     uint8_t link_num,
+			     uint16_t link_bitmap,
+			     uint16_t link_bitmap2,
+			     uint32_t link_control_flags)
+{
+	struct mlo_link_set_active_req *req;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	vdev =
+	wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+					     vdev_id,
+					     WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d",
+			       vdev_id);
+		qdf_mem_free(req);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	policy_mgr_set_link_in_progress(pm_ctx, true);
+
+	policy_mgr_debug("vdev %d: mode %d %s reason %d bitmap 0x%x 0x%x ctrl 0x%x",
+			 wlan_vdev_get_id(vdev), mode,
+			 force_mode_to_string(mode), reason,
+			 link_bitmap, link_bitmap2,
+			 link_control_flags);
+
+	req->ctx.vdev = vdev;
+	req->param.reason = reason;
+	req->param.force_mode = mode;
+	req->param.use_ieee_link_id = true;
+	req->param.force_cmd.ieee_link_id_bitmap = link_bitmap;
+	req->param.force_cmd.ieee_link_id_bitmap2 = link_bitmap2;
+	req->param.force_cmd.link_num = link_num;
+	if (link_control_flags & link_ctrl_f_overwrite_active_bitmap)
+		req->param.control_flags.overwrite_force_active_bitmap = true;
+	if (link_control_flags & link_ctrl_f_overwrite_inactive_bitmap)
+		req->param.control_flags.overwrite_force_inactive_bitmap =
+									true;
+	if (link_control_flags & link_ctrl_f_dynamic_force_link_num)
+		req->param.control_flags.dynamic_force_link_num = true;
+	if (link_control_flags & link_ctrl_f_post_re_evaluate)
+		req->param.control_flags.post_re_evaluate = true;
+
+	status =
+	wlan_vdev_get_bss_peer_mld_mac(vdev,
+				       &req->param.force_cmd.ap_mld_mac_addr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("fail to get ap mld addr for vdev %d",
+			       wlan_vdev_get_id(vdev));
+		goto end;
+	}
+	if (qdf_is_macaddr_zero(&req->param.force_cmd.ap_mld_mac_addr)) {
+		policy_mgr_err("get ap zero mld addr for vdev %d",
+			       wlan_vdev_get_id(vdev));
+		goto end;
+	}
+
+	req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp;
+	req->ctx.validate_set_mlo_link_cb =
+		policy_mgr_validate_set_mlo_link_cb;
+	req->ctx.cb_arg = req;
+	status = mlo_ser_set_link_req(req);
+end:
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d reason %d",
+			       wlan_vdev_get_id(vdev), mode, link_num,
+			       reason);
+		qdf_mem_free(req);
+		policy_mgr_set_link_in_progress(pm_ctx, false);
+	} else {
+		status = QDF_STATUS_E_PENDING;
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return status;
+}
+
+uint32_t
+policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo)
+{
+	struct wlan_objmgr_vdev *assoc_vdev;
+	union conc_ext_flag conc_ext_flags;
+
+	conc_ext_flags.value = 0;
+	if (!vdev || wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		return conc_ext_flags.value;
+
+	if (!force_mlo && !wlan_vdev_mlme_is_mlo_vdev(vdev))
+		return conc_ext_flags.value;
+
+	conc_ext_flags.mlo = 1;
+	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) {
+		assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
+		if (assoc_vdev && ucfg_cm_is_vdev_active(assoc_vdev))
+			conc_ext_flags.mlo_link_assoc_connected = 1;
+	}
+
+	return conc_ext_flags.value;
+}
+
+/**
+ * policy_mgr_allow_sta_concurrency() - check whether STA concurrency is allowed
+ * @psoc: Pointer to soc
+ * @freq: frequency to be checked
+ * @ext_flags: extended flags for concurrency check
+ *
+ *  Return: true if supports else false.
+ */
+static bool
+policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc,
+				 qdf_freq_t freq,
+				 uint32_t ext_flags)
+{
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	bool is_mlo, mlo_sta_present = false;
+	uint8_t vdev_id, sta_cnt = 0;
+	enum policy_mgr_con_mode mode;
+	union conc_ext_flag conc_ext_flags;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	conc_ext_flags.value = ext_flags;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		mode = pm_conc_connection_list[conn_index].mode;
+		if (mode != PM_STA_MODE ||
+		    !pm_conc_connection_list[conn_index].in_use)
+			continue;
+
+		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+							    WLAN_POLICY_MGR_ID);
+		if (!vdev)
+			continue;
+
+		is_mlo = wlan_vdev_mlme_is_mlo_vdev(vdev);
+
+		/* Skip the link vdev for MLO STA */
+		if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+			goto next;
+
+		sta_cnt++;
+		if (!is_mlo)
+			goto next;
+
+		mlo_sta_present = true;
+next:
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	/* Reject if multiple STA connections are not allowed */
+	if (sta_cnt &&
+	    !policy_mgr_allow_multiple_sta_connections(psoc)) {
+		policy_mgr_rl_debug("Disallow Multiple STA connections");
+		return false;
+	}
+
+	if (mlo_sta_present && conc_ext_flags.mlo_link_assoc_connected) {
+		policy_mgr_rl_debug("Allow secondary MLO link");
+		return true;
+	}
+
+	if (conc_ext_flags.mlo && mlo_sta_present) {
+		policy_mgr_rl_debug("Disallow ML STA when ML STA is present");
+		return false;
+	}
+
+	/*
+	 * Reject a 3rd STA.
+	 * Treat a MLO STA(including the primary and secondary link vdevs)
+	 * as 1 STA here.
+	 */
+	if (sta_cnt >= 2) {
+		policy_mgr_rl_debug("Disallow 3rd STA");
+		return false;
+	}
+
+	return true;
+}
+
+bool
+policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
+					  bool is_new_vdev_mlo,
+					  uint8_t new_vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_index;
+	bool ret = false, mlo_sap_present = false;
+	struct wlan_objmgr_vdev *vdev;
+	uint32_t vdev_id;
+
+	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].in_use ||
+		    (pm_conc_connection_list[conn_index].mode != PM_SAP_MODE))
+			continue;
+
+		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+		if (vdev_id == new_vdev_id)
+			continue;
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+							    WLAN_POLICY_MGR_ID);
+		if (!vdev) {
+			policy_mgr_err("vdev for vdev_id:%d is NULL", vdev_id);
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return ret;
+		}
+
+		/* As only one ML SAP is allowed, break after one ML SAP
+		 * instance found in the policy manager list.
+		 */
+		if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+			mlo_sap_present = true;
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+			break;
+		}
+
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (is_new_vdev_mlo && mlo_sap_present)
+		ret = false;
+	else
+		ret = true;
+
+	return ret;
+}
+
+QDF_STATUS
+policy_mgr_link_switch_notifier_cb(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_mlo_link_switch_req *req,
+				   enum wlan_mlo_link_switch_notify_reason notify_reason)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t vdev_id = req->vdev_id;
+	uint8_t curr_ieee_link_id = req->curr_ieee_link_id;
+	uint8_t new_ieee_link_id = req->new_ieee_link_id;
+	uint32_t new_primary_freq = req->new_primary_freq;
+	QDF_STATUS status;
+	union conc_ext_flag conc_ext_flags;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	uint8_t num_del = 0;
+	struct ml_nlink_change_event data;
+	uint16_t dyn_inact_bmap = 0, force_inact_bmap = 0;
+
+	if (notify_reason > MLO_LINK_SWITCH_NOTIFY_REASON_PRE_START_POST_SER)
+		return QDF_STATUS_SUCCESS;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	policy_mgr_debug("target link %d freq %d curr link %d notify reason %d link switch reason %d vdev %d",
+			 new_ieee_link_id, new_primary_freq,
+			 curr_ieee_link_id, notify_reason, req->reason,
+			 vdev_id);
+	qdf_mem_zero(&data, sizeof(data));
+	data.evt.link_switch.curr_ieee_link_id = curr_ieee_link_id;
+	data.evt.link_switch.new_ieee_link_id = new_ieee_link_id;
+	data.evt.link_switch.new_primary_freq = new_primary_freq;
+	data.evt.link_switch.reason = req->reason;
+	status = ml_nlink_conn_change_notify(psoc, vdev_id,
+					     ml_nlink_link_switch_start_evt,
+					     &data);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+
+	policy_mgr_store_and_del_conn_info_by_vdev_id(
+		psoc, vdev_id, info, &num_del);
+	conc_ext_flags.value =
+	policy_mgr_get_conc_ext_flags(vdev, true);
+	ml_nlink_get_dynamic_inactive_links(psoc, vdev, &dyn_inact_bmap,
+					    &force_inact_bmap);
+
+	if (!(dyn_inact_bmap & BIT(new_ieee_link_id)) &&
+	    !policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE,
+					       new_primary_freq,
+					       HW_MODE_20_MHZ,
+					       conc_ext_flags.value,
+					       NULL)) {
+		status = QDF_STATUS_E_INVAL;
+		policy_mgr_debug("target link %d freq %d not allowed by conc rule",
+				 new_ieee_link_id, new_primary_freq);
+	}
+
+	if (num_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_del);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+bool policy_mgr_is_non_ml_sta_present(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	bool non_ml_sta_present = false;
+	uint8_t vdev_id;
+
+	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].mode != PM_STA_MODE ||
+		    !pm_conc_connection_list[conn_index].in_use)
+			continue;
+
+		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+							    WLAN_POLICY_MGR_ID);
+		if (!vdev)
+			continue;
+
+		if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+			non_ml_sta_present = true;
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+			break;
+		}
+
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	return non_ml_sta_present;
+}
+
+bool policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t conn_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	bool mlo_sta_present = false;
+	uint8_t vdev_id;
+
+	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 && !mlo_sta_present;
+	     conn_index++) {
+		if (pm_conc_connection_list[conn_index].mode != PM_STA_MODE ||
+		    !pm_conc_connection_list[conn_index].in_use)
+			continue;
+
+		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+							    WLAN_POLICY_MGR_ID);
+		if (!vdev)
+			continue;
+
+		mlo_sta_present = wlan_vdev_mlme_is_mlo_vdev(vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	return mlo_sta_present;
+}
+
+bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	uint32_t mode_num = 0;
+	uint8_t i, mlo_idx = 0;
+	struct wlan_objmgr_vdev *temp_vdev;
+	qdf_freq_t mlo_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	bool is_sbs_link = true;
+
+	mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							 vdev_id_list, mode);
+	if (!mode_num || mode_num < 2)
+		return false;
+
+	for (i = 0; i < mode_num; i++) {
+		temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+							vdev_id_list[i],
+							WLAN_POLICY_MGR_ID);
+		if (!temp_vdev) {
+			policy_mgr_err("invalid vdev for id %d",
+				       vdev_id_list[i]);
+			return false;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
+			if (mlo_vdev_lst)
+				mlo_vdev_lst[mlo_idx] = vdev_id_list[i];
+			mlo_freq_list[mlo_idx] =
+				wlan_get_operation_chan_freq(temp_vdev);
+			if (wlan_reg_is_24ghz_ch_freq(mlo_freq_list[mlo_idx]))
+				is_sbs_link = false;
+			mlo_idx++;
+		}
+		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
+	}
+
+	if (num_mlo)
+		*num_mlo = mlo_idx;
+	if (mlo_idx < 2)
+		is_sbs_link = false;
+	if (is_sbs_link &&
+	    !policy_mgr_are_sbs_chan(psoc, mlo_freq_list[0],
+				     mlo_freq_list[1])) {
+		policy_mgr_debug("Freq %d and %d are not SBS, set SBS false",
+				 mlo_freq_list[0],
+				 mlo_freq_list[1]);
+		is_sbs_link = false;
+	}
+
+	return is_sbs_link;
+}
+
+bool policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	uint32_t mode_num = 0;
+	uint8_t i, mlo_idx = 0;
+	struct wlan_objmgr_vdev *temp_vdev;
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	bool has_2g_link = false;
+	bool has_5g_link = false;
+	qdf_freq_t mlo_freq;
+
+	mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							  vdev_id_list, mode);
+	if (!mode_num || mode_num < 2)
+		return false;
+
+	for (i = 0; i < mode_num; i++) {
+		temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+							psoc,
+							vdev_id_list[i],
+							WLAN_POLICY_MGR_ID);
+		if (!temp_vdev) {
+			policy_mgr_err("invalid vdev for id %d",
+				       vdev_id_list[i]);
+			return false;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
+			if (mlo_vdev_lst)
+				mlo_vdev_lst[mlo_idx] = vdev_id_list[i];
+			mlo_freq =
+				wlan_get_operation_chan_freq(temp_vdev);
+			if (wlan_reg_is_24ghz_ch_freq(mlo_freq))
+				has_2g_link = true;
+			else
+				has_5g_link = true;
+			mlo_idx++;
+		}
+		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
+	}
+
+	if (num_mlo)
+		*num_mlo = mlo_idx;
+
+	return has_2g_link && has_5g_link;
+}
+
+bool policy_mgr_is_curr_hwmode_emlsr(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_hw_mode_params hw_mode;
+
+	if (!policy_mgr_is_hw_emlsr_capable(psoc))
+		return false;
+
+	if (QDF_STATUS_SUCCESS != policy_mgr_get_current_hw_mode(psoc,
+								 &hw_mode))
+		return false;
+
+	if (!hw_mode.emlsr_cap)
+		return false;
+
+	return true;
+}
+
+bool policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	bool emlsr_connection = false;
+	uint32_t mode_num = 0;
+	uint8_t i, mlo_idx = 0;
+	struct wlan_objmgr_vdev *temp_vdev;
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {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;
+	}
+
+	mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							  vdev_id_list,
+							  PM_STA_MODE);
+
+	for (i = 0; i < mode_num; i++) {
+		temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+							psoc, vdev_id_list[i],
+							WLAN_POLICY_MGR_ID);
+		if (!temp_vdev) {
+			policy_mgr_err("invalid vdev for id %d",
+				       vdev_id_list[i]);
+			goto end;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
+			if (mlo_vdev_lst)
+				mlo_vdev_lst[mlo_idx] = vdev_id_list[i];
+			mlo_idx++;
+		}
+		/* Check if existing vdev is eMLSR STA */
+		if (wlan_vdev_mlme_cap_get(temp_vdev, WLAN_VDEV_C_EMLSR_CAP))
+			emlsr_connection = true;
+
+		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
+		if (!pm_disabled_ml_links[i].in_use)
+			continue;
+		if (pm_disabled_ml_links[i].mode != PM_STA_MODE)
+			continue;
+		temp_vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(
+					psoc, pm_disabled_ml_links[i].vdev_id,
+					WLAN_POLICY_MGR_ID);
+		if (!temp_vdev) {
+			policy_mgr_err("invalid inactive vdev for id %d",
+				       pm_disabled_ml_links[i].vdev_id);
+			continue;
+		}
+		/* Check if existing vdev is eMLSR STA */
+		if (wlan_vdev_mlme_cap_get(temp_vdev, WLAN_VDEV_C_EMLSR_CAP))
+			emlsr_connection = true;
+		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+end:
+	if (num_mlo)
+		*num_mlo = mlo_idx;
+
+	return emlsr_connection;
+}
+
+static void policy_mgr_restore_no_force(struct wlan_objmgr_psoc *psoc,
+					uint8_t num_mlo,
+					uint8_t mlo_vdev_lst[],
+					bool conc_con_coming_up)
+{
+	struct ml_link_force_state force_cmd = {0};
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (num_mlo < 1) {
+		policy_mgr_err("invalid num_mlo %d",
+			       num_mlo);
+		return;
+	}
+
+	vdev =
+	wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+					     mlo_vdev_lst[0],
+					     WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d",
+			       mlo_vdev_lst[0]);
+		return;
+	}
+
+	ml_nlink_get_curr_force_state(psoc, vdev, &force_cmd);
+	if (!conc_con_coming_up || force_cmd.force_active_bitmap) {
+		if (ml_is_nlink_service_supported(psoc))
+			status = policy_mgr_mlo_sta_set_nlink(
+					psoc, mlo_vdev_lst[0],
+					MLO_LINK_FORCE_REASON_DISCONNECT,
+					MLO_LINK_FORCE_MODE_NO_FORCE,
+					0, 0, 0, 0);
+		else
+			status = policy_mgr_mlo_sta_set_link(
+					psoc,
+					MLO_LINK_FORCE_REASON_DISCONNECT,
+					MLO_LINK_FORCE_MODE_NO_FORCE,
+					num_mlo, mlo_vdev_lst);
+		/* If concurrency vdev is coming up and force active bitmap
+		 * is present, we need to wait for the respone of no force
+		 * command.
+		 */
+		if (force_cmd.force_active_bitmap && conc_con_coming_up) {
+			if (status == QDF_STATUS_E_PENDING)
+				policy_mgr_wait_for_set_link_update(psoc);
+			else
+				policy_mgr_err("status %d", status);
+
+			ml_nlink_get_curr_force_state(psoc, vdev, &force_cmd);
+			ml_nlink_dump_force_state(&force_cmd, "");
+		}
+	}
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
+void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc,
+					     bool conc_con_coming_up,
+					     bool emlsr_sta_coming_up)
+{
+	uint8_t num_mlo = 0;
+	uint8_t mlo_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	bool is_mlo_emlsr = false;
+	uint8_t num_disabled_ml_sta = 0;
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {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;
+	}
+
+	is_mlo_emlsr = policy_mgr_is_mlo_in_mode_emlsr(psoc, mlo_vdev_lst,
+						       &num_mlo);
+	policy_mgr_debug("num_mlo %d is_mlo_emlsr %d conc_con_coming_up: %d",
+			 num_mlo, is_mlo_emlsr, conc_con_coming_up);
+
+	if (!is_mlo_emlsr)
+		return;
+
+	if (num_mlo < 2) {
+		policy_mgr_debug("conc_con_coming_up %d num mlo sta links %d",
+				 conc_con_coming_up, num_mlo);
+		policy_mgr_get_ml_sta_info(pm_ctx, &num_mlo,
+					   &num_disabled_ml_sta,
+					   mlo_vdev_lst, ml_freq_lst,
+					   NULL, NULL, NULL);
+		if (policy_mgr_get_connection_count(psoc) != 1 ||
+		    !num_disabled_ml_sta)
+			return;
+	}
+
+	if (conc_con_coming_up ||
+	    (emlsr_sta_coming_up &&
+	     policy_mgr_get_connection_count(psoc) > 2)) {
+		/*
+		 * If any force active link bitmap is present, we have to
+		 * clear the force active bitmap from target. Otherwise that
+		 * will be conflict with the force inactive num bitmap, then
+		 * target can't handle force inactive num 1 command to exit
+		 * EMLSR.
+		 */
+		if (conc_con_coming_up)
+			policy_mgr_restore_no_force(psoc, num_mlo,
+						    mlo_vdev_lst,
+						    conc_con_coming_up);
+
+		/*
+		 * Force disable one of the links (FW will decide which link) if
+		 * 1) EMLSR STA is present and SAP/STA/NAN connection comes up.
+		 * 2) There is a legacy connection (SAP/P2P/NAN) and a STA comes
+		 * up in EMLSR mode.
+		 */
+		policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
+					    MLO_LINK_FORCE_MODE_INACTIVE_NUM,
+					    num_mlo, mlo_vdev_lst);
+		return;
+	}
+
+	if (!conc_con_coming_up && emlsr_sta_coming_up)
+		/*
+		 * No force i.e. Re-enable the disabled link if-
+		 * 1) EMLSR STA is present and new SAP/STA/NAN connection goes
+		 *    down. One of the links was disabled while a new connection
+		 *    came up.
+		 * 2) Legacy connection (SAP/P2P/NAN) goes down and if STA is
+		 *    EMLSR capable. One of the links was disabled after EMLSR
+		 *    association.
+		 */
+		policy_mgr_restore_no_force(psoc, num_mlo,
+					    mlo_vdev_lst,
+					    conc_con_coming_up);
+}
+
+bool
+policy_mgr_is_emlsr_sta_concurrency_present(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t num_mlo = 0;
+
+	if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, &num_mlo) &&
+	    num_mlo < policy_mgr_get_connection_count(psoc))
+		return true;
+
+	return false;
+}
+
+static uint8_t
+policy_mgr_get_affected_links_for_sta_sta(struct wlan_objmgr_psoc *psoc,
+					  uint8_t num_ml, qdf_freq_t *freq_list,
+					  uint8_t *vdev_id_list,
+					  uint8_t *ml_vdev_lst,
+					  uint8_t *ml_idx, qdf_freq_t freq)
+{
+	uint8_t i = 0;
+	bool same_band_sta_allowed;
+
+	/*
+	 * STA freq:      ML STA combo:  SBS Action
+	 * ---------------------------------------------------
+	 * 2Ghz           2Ghz+5/6Ghz    Disable 2Ghz(Same MAC)
+	 * 5Ghz           2Ghz+5/6Ghz    Disable 2.4Ghz if 5Ghz lead to SBS
+	 *                               (SBS, same MAC) and same band STA
+	 *                               allowed, else disable 5/6Ghz
+	 *                               (NON SBS, same MAC)
+	 * 5Ghz(lower)    5Ghz+6Ghz      Disable 5Ghz (NON SBS, same MAC)
+	 * 5Ghz(higher)   5Ghz+6Ghz      Disable 6Ghz (NON SBS, Same MAC)
+	 * 2Ghz           5Ghz+6Ghz      Disable Any
+	 */
+
+	/* If non-ML STA is 2.4Ghz disable 2.4Ghz if present OR disable any */
+	if (wlan_reg_is_24ghz_ch_freq(freq)) {
+		while (i < num_ml) {
+			if (wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) {
+				/* Affected ML STA link on 2.4Ghz */
+				ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
+				return 1;
+			}
+			/* Fill non effected vdev in list */
+			ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
+			i++;
+		}
+		/* No link affected return num_ml to disable any */
+		return i;
+	}
+
+	/* This mean non-ML STA is 5Ghz */
+
+	/* check if ML STA is DBS */
+	i = 0;
+	while (i < num_ml &&
+	       !wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]]))
+		i++;
+
+	same_band_sta_allowed = wlan_cm_same_band_sta_allowed(psoc);
+
+	/*
+	 * if ML STA is DBS ie 2.4Ghz link present and if same_band_sta_allowed
+	 * is false, disable 5/6Ghz link to make sure we dont have all link
+	 * on 5Ghz
+	 */
+	if (i < num_ml && !same_band_sta_allowed)
+		goto check_dbs_ml;
+
+	/* check if any link lead to SBS, so that we can disable the other*/
+	i = 0;
+	while (i < num_ml &&
+	       !policy_mgr_are_sbs_chan(psoc, freq, freq_list[ml_idx[i]]))
+		i++;
+
+	/*
+	 * if i < num_ml then i is the SBS link, in this case disable the other
+	 * non SBS link, this mean ML STA is 5+6 or 2+5/6.
+	 */
+	if (i < num_ml) {
+		i = 0;
+		while (i < num_ml) {
+			if (!policy_mgr_are_sbs_chan(psoc, freq,
+						     freq_list[ml_idx[i]])) {
+				/* Affected non SBS ML STA link */
+				ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
+				return 1;
+			}
+			/* Fill non effected vdev in list */
+			ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
+			i++;
+		}
+		/* All link lead to SBS, disable any, This should not happen */
+		return i;
+	}
+
+check_dbs_ml:
+	/*
+	 * None of the link can lead to SBS, i.e. its 2+ 5/6 ML STA in this case
+	 * disable 5Ghz link.
+	 */
+	i = 0;
+	while (i < num_ml) {
+		if (!wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) {
+			/* Affected 5/6Ghz ML STA link */
+			ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
+			return 1;
+		}
+		/* Fill non effected vdev in list */
+		ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
+		i++;
+	}
+
+	/* No link affected, This should not happen */
+	return i;
+}
+
+/*
+ * policy_mgr_get_concurrent_num_links() - get links which are affected
+ * if no affected then return num ml. Also fills the ml_vdev_lst to send.
+ * @num_ml: number of ML vdev
+ * @freq_list: freq list of all vdev
+ * @vdev_id_list: vdev id list
+ * @ml_vdev_lst: ML vdev list
+ * @ml_idx: ML index
+ * @freq: non ML STA freq
+ *
+ * Return: number of the affected links, else total link and ml_vdev_lst list.
+ */
+static uint8_t
+policy_mgr_get_concurrent_num_links(struct wlan_objmgr_vdev *vdev,
+				    uint8_t num_ml, qdf_freq_t *freq_list,
+				    uint8_t *vdev_id_list,
+				    uint8_t *ml_vdev_lst,
+				    uint8_t *ml_idx, qdf_freq_t freq)
+{
+	uint8_t i = 0;
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+
+	if (!psoc)
+		return 0;
+
+	while (i < num_ml && (freq_list[ml_idx[i]] != freq))
+		i++;
+
+	if (i < num_ml) {
+		/* if one link is SCC then no need to disable any link */
+		policy_mgr_debug("vdev %d: ML vdev %d lead to SCC, STA freq %d ML freq %d, no need to disable link",
+				 wlan_vdev_get_id(vdev),
+				 vdev_id_list[ml_idx[i]],
+				 freq, freq_list[ml_idx[i]]);
+		return 0;
+	}
+
+
+	return policy_mgr_get_affected_links_for_sta_sta(psoc, num_ml,
+							 freq_list,
+							 vdev_id_list,
+							 ml_vdev_lst,
+							 ml_idx, freq);
+}
+
+static void
+policy_mgr_ml_sta_concurrency_on_connect(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_objmgr_vdev *vdev,
+				    uint8_t num_ml, uint8_t *ml_idx,
+				    uint8_t num_non_ml, uint8_t *non_ml_idx,
+				    qdf_freq_t *freq_list,
+				    uint8_t *vdev_id_list)
+{
+	qdf_freq_t freq = 0;
+	struct wlan_channel *bss_chan;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	uint8_t ml_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t affected_links = 0;
+	enum mlo_link_force_mode mode = MLO_LINK_FORCE_MODE_ACTIVE_NUM;
+
+	/* non ML STA doesn't exist, no need to change to link.*/
+	if (!num_non_ml)
+		return;
+
+	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		freq = freq_list[non_ml_idx[0]];
+	} else {
+		bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
+		if (bss_chan)
+			freq = bss_chan->ch_freq;
+	}
+	policy_mgr_debug("vdev %d: Freq %d (non ML vdev id %d), is ML STA %d",
+			 vdev_id, freq, vdev_id_list[non_ml_idx[0]],
+			 wlan_vdev_mlme_is_mlo_vdev(vdev));
+	if (!freq)
+		return;
+
+	affected_links =
+		policy_mgr_get_concurrent_num_links(vdev, num_ml, freq_list,
+						    vdev_id_list, ml_vdev_lst,
+						    ml_idx, freq);
+
+	if (!affected_links) {
+		policy_mgr_debug("vdev %d: no affected link found", vdev_id);
+		return;
+	}
+	policy_mgr_debug("affected link found: %u vdev_id: %u",
+			 affected_links, ml_vdev_lst[0]);
+
+	/*
+	 * If affected link is less than num_ml, ie not all link are affected,
+	 * send MLO_LINK_FORCE_MODE_INACTIVE.
+	 */
+	if (affected_links < num_ml &&
+	    affected_links <= MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		if (mlo_is_sta_inactivity_allowed_with_quiet(psoc, vdev_id_list,
+							     num_ml, ml_idx,
+							     affected_links,
+							     ml_vdev_lst)) {
+			mode = MLO_LINK_FORCE_MODE_INACTIVE;
+		} else {
+			policy_mgr_debug("vdev %d: force inactivity is not allowed",
+					 ml_vdev_lst[0]);
+			return;
+		}
+	}
+
+	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
+				    mode, affected_links, ml_vdev_lst);
+}
+
+static void
+policy_mgr_get_disabled_ml_sta_idx(struct wlan_objmgr_psoc *psoc,
+				   uint8_t *ml_sta,
+				   uint8_t *ml_idx,
+				   qdf_freq_t *freq_list,
+				   uint8_t *vdev_id_list, uint8_t next_idx)
+{
+	uint8_t conn_index, fill_index = next_idx;
+	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);
+	/* Get disabled link info as well and keep it at last */
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK;
+	     conn_index++) {
+		if (!pm_disabled_ml_links[conn_index].in_use)
+			continue;
+		if (pm_disabled_ml_links[conn_index].mode != PM_STA_MODE)
+			continue;
+		if ((fill_index >= MAX_NUMBER_OF_CONC_CONNECTIONS) ||
+		    (*ml_sta >= MAX_NUMBER_OF_CONC_CONNECTIONS)) {
+			policy_mgr_err("Invalid fill_index: %d or ml_sta: %d",
+				       fill_index, *ml_sta);
+			break;
+		}
+		vdev_id_list[fill_index] =
+				pm_disabled_ml_links[conn_index].vdev_id;
+		freq_list[fill_index] = pm_disabled_ml_links[conn_index].freq;
+		ml_idx[(*ml_sta)++] = fill_index++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+/**
+ * policy_mgr_handle_ml_sta_link_concurrency() - Handle STA+ML_STA concurrency
+ * @psoc: PSOC object information
+ * @vdev: vdev of the changed interface caller
+ *
+ * Return: void
+ */
+static QDF_STATUS
+policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
+					  struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t num_ml = 0, num_non_ml = 0, next_idx, disabled_links;
+	uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {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_INVAL;
+	}
+
+	/* Skip non STA connection handling */
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		return QDF_STATUS_E_INVAL;
+
+	/*
+	 * Skip this in case of SAP/P2P Concurrencies, to avoid renable of
+	 * the link, disabled by SAP/P2P logic, as this API only consider
+	 * STA specific counts and ignore other counts.
+	 */
+	if (policy_mgr_get_beaconing_mode_count(psoc, NULL) ||
+	    policy_mgr_mode_specific_connection_count(psoc,
+						      PM_P2P_CLIENT_MODE,
+						      NULL)) {
+		policy_mgr_debug("SAP/GO/CLI exist ignore this check");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx,
+					       &num_non_ml, non_ml_idx,
+					       freq_list, vdev_id_list);
+	/* Skip non STA+STA cases */
+	if (!num_ml || !num_non_ml)
+		return QDF_STATUS_E_INVAL;
+
+	next_idx = num_ml + num_non_ml;
+	policy_mgr_get_disabled_ml_sta_idx(psoc, &num_ml, ml_idx,
+					   freq_list, vdev_id_list, next_idx);
+
+	disabled_links = num_ml - (next_idx - num_non_ml);
+	policy_mgr_debug("vdev %d: num_ml %d num_non_ml %d disabled_links: %d",
+			 wlan_vdev_get_id(vdev), num_ml, num_non_ml,
+			 disabled_links);
+
+	/* ML STA is not up or not sufficient links to disable */
+	if (num_ml < 2 || num_ml > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_ml - disabled_links < 2) {
+		policy_mgr_debug("ML STA is not up or not sufficient links to disable");
+		return QDF_STATUS_E_INVAL;
+	}
+	/*
+	 * TODO: Check if both link enable/ link switch is possible when
+	 * secondary STA switch happens to a new channel due to CSA
+	 */
+
+	policy_mgr_ml_sta_concurrency_on_connect(psoc, vdev, num_ml,
+						 ml_idx, num_non_ml,
+						 non_ml_idx, freq_list,
+						 vdev_id_list);
+	return QDF_STATUS_SUCCESS;
+}
+
+static bool
+policy_mgr_is_mode_p2p_sap(enum policy_mgr_con_mode mode)
+{
+	return (policy_mgr_is_beaconing_mode(mode) ||
+		(mode == PM_P2P_CLIENT_MODE));
+}
+
+bool
+policy_mgr_is_vdev_high_tput_or_low_latency(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	bool is_vdev_ll_ht;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d", vdev_id);
+		return false;
+	}
+	is_vdev_ll_ht = wlan_is_vdev_traffic_ll_ht(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return is_vdev_ll_ht;
+}
+
+bool
+policy_mgr_check_2ghz_only_sap_affected_link(
+			struct wlan_objmgr_psoc *psoc,
+			uint8_t sap_vdev_id,
+			qdf_freq_t sap_ch_freq,
+			uint8_t ml_ch_freq_num,
+			qdf_freq_t *ml_freq_lst)
+{
+	uint8_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	enum QDF_OPMODE op_mode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
+		return false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+				psoc, sap_vdev_id,
+				WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_debug("vdev is null %d", sap_vdev_id);
+		return false;
+	}
+	op_mode = wlan_vdev_mlme_get_opmode(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	if (op_mode != QDF_SAP_MODE)
+		return false;
+
+	if (!policy_mgr_is_acs_2ghz_only_sap(psoc, sap_vdev_id))
+		return false;
+
+	/* If 2G ml STA exist, force scc will happen, no link
+	 * to get affected.
+	 */
+	for (i = 0; i < ml_ch_freq_num; i++)
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(ml_freq_lst[i]))
+			return false;
+
+	/* If All ml STA are 5/6 band, force SCC will not happen
+	 * for 2G only SAP, so return true to indicate one
+	 * link get affected.
+	 */
+	return true;
+}
+
+/*
+ * policy_mgr_get_affected_links_for_go_sap_cli() - Check if any of the P2P OR
+ * SAP is causing MCC with a ML link and also is configured high tput or low
+ * latency
+ * @psoc: psoc ctx
+ * @num_ml_sta: Number of ML STA present
+ * @ml_vdev_lst: ML STA vdev id list
+ * @ml_freq_lst: ML STA freq list
+ * @num_p2p_sap: Number of P2P and SAP present
+ * @p2p_sap_vdev_lst: P2P and SAP vdev id list
+ * @p2p_sap_freq_lst: P2P and SAP freq list
+ *
+ * Return: Number of links causing MCC with any of the P2P or SAP which is
+ * configured high tput or low latency
+ */
+static uint8_t
+policy_mgr_get_affected_links_for_go_sap_cli(struct wlan_objmgr_psoc *psoc,
+					     uint8_t num_ml_sta,
+					     uint8_t *ml_vdev_lst,
+					     qdf_freq_t *ml_freq_lst,
+					     uint8_t num_p2p_sap,
+					     uint8_t *p2p_sap_vdev_lst,
+					     qdf_freq_t *p2p_sap_freq_lst)
+{
+	uint8_t i = 0, k = 0, num_affected_links = 0;
+
+	if (!num_p2p_sap || num_ml_sta < 2)
+		return num_affected_links;
+
+	while (i < num_ml_sta) {
+		/* if any link is causing MCC with GO/GC/AP, set mcc as true.*/
+		for (k = 0; k < num_p2p_sap; k++) {
+			/* Continue if SCC */
+			if (ml_freq_lst[i] == p2p_sap_freq_lst[k])
+				continue;
+
+			/* SAP MCC with MLO STA link is not preferred.
+			 * If SAP is 2Ghz only by ACS and two ML link are
+			 * 5/6 band, then force SCC may not happen. In such
+			 * case inactive one link.
+			 */
+			if (policy_mgr_check_2ghz_only_sap_affected_link(
+					psoc, p2p_sap_vdev_lst[k],
+					p2p_sap_freq_lst[k],
+					num_ml_sta, ml_freq_lst)) {
+				policy_mgr_debug("2G only SAP vdev %d ch freq %d is not SCC with any MLO STA link",
+						 p2p_sap_vdev_lst[k],
+						 p2p_sap_freq_lst[k]);
+				num_affected_links++;
+				continue;
+			}
+
+			/* Continue if high tput or low latency is not set */
+			if (!policy_mgr_is_vdev_high_tput_or_low_latency(
+						psoc, p2p_sap_vdev_lst[k]))
+				continue;
+
+			/* If both freq are on same mac then its MCC */
+			if (policy_mgr_are_2_freq_on_same_mac(psoc,
+							ml_freq_lst[i],
+							p2p_sap_freq_lst[k])) {
+				policy_mgr_debug("ml sta vdev %d (freq %d) and p2p/sap vdev %d (freq %d) are MCC",
+						 ml_vdev_lst[i], ml_freq_lst[i],
+						 p2p_sap_vdev_lst[k],
+						 p2p_sap_freq_lst[k]);
+				num_affected_links++;
+			}
+		}
+		i++;
+	}
+
+	return num_affected_links;
+}
+
+/*
+ * policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info() - Get number of ML STA,
+ * P2P and SAP interfaces and their vdev ids and freq list
+ * @pm_ctx: pm_ctx ctx
+ * @num_ml_sta: Return number of ML STA present
+ * @num_disabled_ml_sta: Return number of disabled ML STA links
+ * @ml_vdev_lst: Return ML STA vdev id list
+ * @ml_freq_lst: Return ML STA freq list
+ * @num_p2p_sap: Return number of P2P and SAP present
+ * @p2p_sap_vdev_lst: Return P2P and SAP vdev id list
+ * @p2p_sap_freq_lst: Return P2P and SAP freq list
+ *
+ * Return: void
+ */
+static void
+policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(
+					struct policy_mgr_psoc_priv_obj *pm_ctx,
+					uint8_t *num_ml_sta,
+					uint8_t *num_disabled_ml_sta,
+					uint8_t *ml_vdev_lst,
+					qdf_freq_t *ml_freq_lst,
+					uint8_t *num_p2p_sap,
+					uint8_t *p2p_sap_vdev_lst,
+					qdf_freq_t *p2p_sap_freq_lst)
+{
+	enum policy_mgr_con_mode mode;
+	uint8_t vdev_id, conn_index;
+	qdf_freq_t freq;
+
+	*num_p2p_sap = 0;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_get_ml_sta_info(pm_ctx, num_ml_sta, num_disabled_ml_sta,
+				   ml_vdev_lst, ml_freq_lst, NULL, NULL, NULL);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		if (!pm_conc_connection_list[conn_index].in_use)
+			continue;
+		mode = pm_conc_connection_list[conn_index].mode;
+		if (!policy_mgr_is_mode_p2p_sap(mode))
+			continue;
+		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
+		freq = pm_conc_connection_list[conn_index].freq;
+
+		/* add p2p and sap vdev and freq list */
+		p2p_sap_vdev_lst[*num_p2p_sap] = vdev_id;
+		p2p_sap_freq_lst[(*num_p2p_sap)++] = freq;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+/*
+ * policy_mgr_is_ml_sta_links_in_mcc() - Check ML links are in MCC or not
+ * @psoc: psoc ctx
+ * @ml_freq_lst: ML STA freq list
+ * @ml_vdev_lst: ML STA vdev id list
+ * @ml_linkid_lst: ML STA link id list
+ * @num_ml_sta: Number of total ML STA links
+ * @affected_linkid_bitmap: link id bitmap which home channels are in MCC
+ * with each other
+ *
+ * Return: true if ML link in MCC else false
+ */
+bool
+policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t *ml_freq_lst,
+				  uint8_t *ml_vdev_lst,
+				  uint8_t *ml_linkid_lst,
+				  uint8_t num_ml_sta,
+				  uint32_t *affected_linkid_bitmap)
+{
+	uint8_t i, j;
+	uint32_t link_id_bitmap;
+
+	for (i = 0; i < num_ml_sta; i++) {
+		link_id_bitmap = 0;
+		if (ml_linkid_lst)
+			link_id_bitmap = 1 << ml_linkid_lst[i];
+		for (j = i + 1; j < num_ml_sta; j++) {
+			if (ml_freq_lst[i] != ml_freq_lst[j] &&
+			    policy_mgr_2_freq_always_on_same_mac(
+					psoc, ml_freq_lst[i], ml_freq_lst[j])) {
+				if (ml_vdev_lst)
+					policy_mgr_debug("vdev %d and %d are in MCC with freq %d and freq %d",
+							 ml_vdev_lst[i],
+							 ml_vdev_lst[j],
+							 ml_freq_lst[i],
+							 ml_freq_lst[j]);
+				if (ml_linkid_lst) {
+					link_id_bitmap |= 1 << ml_linkid_lst[j];
+					policy_mgr_debug("link %d and %d are in MCC with freq %d and freq %d",
+							 ml_linkid_lst[i],
+							 ml_linkid_lst[j],
+							 ml_freq_lst[i],
+							 ml_freq_lst[j]);
+					if (affected_linkid_bitmap)
+						*affected_linkid_bitmap =
+							link_id_bitmap;
+				}
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+QDF_STATUS
+policy_mgr_is_ml_links_in_mcc_allowed(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      uint8_t *ml_sta_vdev_lst,
+				      uint8_t *num_ml_sta)
+{
+	uint8_t num_disabled_ml_sta = 0;
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {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;
+	}
+
+	policy_mgr_get_ml_sta_info(pm_ctx, num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst,
+				   NULL, NULL, NULL);
+	if (*num_ml_sta < 2 || *num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_disabled_ml_sta) {
+		policy_mgr_debug("num_ml_sta invalid %d or link already disabled%d",
+				 *num_ml_sta, num_disabled_ml_sta);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!policy_mgr_is_ml_sta_links_in_mcc(psoc, ml_freq_lst,
+					       ml_sta_vdev_lst, NULL,
+					       *num_ml_sta,
+					       NULL))
+		return QDF_STATUS_E_FAILURE;
+
+	/*
+	 * eMLSR is allowed in MCC mode also. So, don't disable any links
+	 * if current connection happens in eMLSR mode.
+	 */
+	if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, NULL)) {
+		policy_mgr_debug("Don't disable eMLSR links");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_handle_mcc_ml_sta() - disables one ML STA link if causing MCC
+ * DBS - if ML STA links on 5 GHz + 6 GHz
+ * SBS - if both ML STA links on 5 GHz high/5 GHz low
+ * non-SBS - any combo (5/6 GHz + 5/6 GHz OR 2 GHz + 5/6 GHz)
+ * @psoc: psoc ctx
+ * @vdev: Pointer to vdev object
+ *
+ * Return: Success if MCC link is disabled else failure
+ */
+static QDF_STATUS
+policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t num_ml_sta = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	QDF_STATUS status;
+
+	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE))
+		return QDF_STATUS_E_FAILURE;
+
+	status = policy_mgr_is_ml_links_in_mcc_allowed(psoc, vdev,
+						       ml_sta_vdev_lst,
+						       &num_ml_sta);
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_FAILURE;
+
+	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
+				    MLO_LINK_FORCE_MODE_ACTIVE_NUM,
+				    num_ml_sta, ml_sta_vdev_lst);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * policy_mgr_sta_ml_link_enable_allowed() - Check with given ML links and
+ * existing concurrencies, a disabled ml link can be enabled back.
+ * @psoc: psoc ctx
+ * @num_disabled_ml_sta: Number of existing disabled links
+ * @num_ml_sta: Number of total ML STA links
+ * @ml_freq_lst: ML STA freq list
+ * @ml_vdev_lst: ML STA vdev id list
+ *
+ * Return: if link can be enabled or not
+ */
+static bool
+policy_mgr_sta_ml_link_enable_allowed(struct wlan_objmgr_psoc *psoc,
+				      uint8_t num_disabled_ml_sta,
+				      uint8_t num_ml_sta,
+				      qdf_freq_t *ml_freq_lst,
+				      uint8_t *ml_vdev_lst)
+{
+	union conc_ext_flag conc_ext_flags;
+	uint8_t disabled_link_vdev_id;
+	qdf_freq_t disabled_link_freq;
+	struct wlan_objmgr_vdev *vdev;
+
+	/* If no link is disabled nothing to do */
+	if (!num_disabled_ml_sta || num_ml_sta < 2)
+		return false;
+	if (policy_mgr_is_ml_sta_links_in_mcc(psoc, ml_freq_lst, ml_vdev_lst,
+					      NULL, num_ml_sta,
+					      NULL))
+		return false;
+	/* Disabled link is at the last index */
+	disabled_link_vdev_id = ml_vdev_lst[num_ml_sta - 1];
+	disabled_link_freq = ml_freq_lst[num_ml_sta - 1];
+	policy_mgr_debug("disabled_link_vdev_id %d disabled_link_freq %d",
+			 disabled_link_vdev_id, disabled_link_freq);
+	if (!disabled_link_freq)
+		return false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, disabled_link_vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("invalid vdev for id %d", disabled_link_vdev_id);
+		return false;
+	}
+	conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE,
+					disabled_link_freq, HW_MODE_20_MHZ,
+					conc_ext_flags.value, NULL);
+}
+
+/*
+ * policy_mgr_re_enable_ml_sta_on_p2p_sap_down() - Handle enable
+ * link on P2P/SAP/ML_STA vdev UP or channel change
+ * @psoc: objmgr psoc
+ * @vdev: vdev which went UP or changed chan
+ *
+ * Return: void
+ */
+static void
+policy_mgr_handle_sap_cli_go_ml_sta_up_csa(struct wlan_objmgr_psoc *psoc,
+					   struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t num_ml_sta = 0, num_p2p_sap = 0, num_disabled_ml_sta = 0;
+	uint8_t num_affected_link;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t p2p_sap_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t p2p_sap_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	status = policy_mgr_handle_ml_sta_link_state_allowed(
+				psoc, MLO_LINK_FORCE_REASON_CONNECT);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
+	/*
+	 * eMLSR API policy_mgr_handle_emlsr_sta_concurrency() takes care of
+	 * eMLSR concurrencies. Currently, eMLSR STA can't operate with any
+	 * cocurrent mode, i.e. one link gets force-disabled when a new
+	 * concurrecy is coming up.
+	 */
+	if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, NULL)) {
+		policy_mgr_debug("STA connected in eMLSR mode, don't enable/disable links");
+		return;
+	}
+
+	if (QDF_IS_STATUS_SUCCESS(policy_mgr_handle_mcc_ml_sta(psoc, vdev)))
+		return;
+
+	status = policy_mgr_handle_ml_sta_link_concurrency(psoc, vdev);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return;
+
+	policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(pm_ctx, &num_ml_sta,
+						      &num_disabled_ml_sta,
+						      ml_sta_vdev_lst,
+						      ml_freq_lst, &num_p2p_sap,
+						      p2p_sap_vdev_lst,
+						      p2p_sap_freq_lst);
+
+	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_p2p_sap %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_p2p_sap);
+	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_p2p_sap > MAX_NUMBER_OF_CONC_CONNECTIONS)
+		return;
+
+	num_affected_link = policy_mgr_get_affected_links_for_go_sap_cli(psoc,
+						num_ml_sta, ml_sta_vdev_lst,
+						ml_freq_lst, num_p2p_sap,
+						p2p_sap_vdev_lst,
+						p2p_sap_freq_lst);
+
+	if (!num_affected_link) {
+		policy_mgr_debug("vdev %d: no affected link found", vdev_id);
+		goto enable_link;
+	}
+
+	if (num_disabled_ml_sta) {
+		policy_mgr_debug("As a link is already disabled and affected link present (%d), No action required",
+				 num_affected_link);
+		return;
+	}
+
+	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
+				    MLO_LINK_FORCE_MODE_ACTIVE_NUM,
+				    num_ml_sta, ml_sta_vdev_lst);
+
+	return;
+enable_link:
+
+	/*
+	 * if no affected link and link can be allowed to enable then renable
+	 * the disabled link.
+	 */
+	if (policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
+						  num_ml_sta, ml_freq_lst,
+						  ml_sta_vdev_lst))
+		policy_mgr_mlo_sta_set_link(psoc,
+					    MLO_LINK_FORCE_REASON_DISCONNECT,
+					    MLO_LINK_FORCE_MODE_NO_FORCE,
+					    num_ml_sta, ml_sta_vdev_lst);
+}
+
+void
+policy_mgr_handle_ml_sta_links_on_vdev_up_csa(struct wlan_objmgr_psoc *psoc,
+					      enum QDF_OPMODE mode,
+					      uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d: invalid vdev", vdev_id);
+		return;
+	}
+
+	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE ||
+	    mode == QDF_P2P_CLIENT_MODE || mode == QDF_P2P_GO_MODE)
+		policy_mgr_handle_sap_cli_go_ml_sta_up_csa(psoc, vdev);
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
+#define SET_LINK_TIMEOUT 6000
+QDF_STATUS policy_mgr_wait_for_set_link_update(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!policy_mgr_get_link_in_progress(pm_ctx)) {
+		policy_mgr_err("link is not in progress");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status =
+		qdf_wait_for_event_completion(&pm_ctx->set_link_update_done_evt,
+					      SET_LINK_TIMEOUT);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_set_link_in_progress(pm_ctx, false);
+		policy_mgr_err("wait for set_link_in_progress failed");
+	}
+
+	return status;
+}
+
+void policy_mgr_handle_ml_sta_link_on_traffic_type_change(
+						struct wlan_objmgr_psoc *psoc,
+						struct wlan_objmgr_vdev *vdev)
+{
+	/* Check if any set link is already progress and thus wait */
+	policy_mgr_wait_for_set_link_update(psoc);
+
+	ml_nlink_conn_change_notify(
+		psoc, wlan_vdev_get_id(vdev),
+		ml_nlink_connection_updated_evt, NULL);
+
+	/*
+	 * Check if traffic type change lead to set link is progress and
+	 * thus wait for it to complete.
+	 */
+	policy_mgr_wait_for_set_link_update(psoc);
+}
+
+static QDF_STATUS
+policy_mgr_handle_ml_sta_link_enable_on_sta_down(struct wlan_objmgr_psoc *psoc,
+						 struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		return QDF_STATUS_E_INVAL;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Handle only when non-ML STA is going down and ML STA is active */
+	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
+				   NULL, NULL);
+	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml);
+
+	/*
+	 * No ML STA is present or sinle link ML is present or
+	 * more no.of links are active than supported concurrent connections
+	 */
+	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS)
+		return QDF_STATUS_E_INVAL;
+
+	/* STA+STA cases */
+
+	/* One ML/non-ML STA is going down and another non ML STA is present */
+	if (num_non_ml) {
+		policy_mgr_debug("non-ML STA is present");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/*
+	 * If no links are disabled or
+	 * link can not be allowed to enable then skip checking further.
+	 */
+	if (!num_disabled_ml_sta ||
+	    !policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
+						  num_ml_sta, ml_freq_lst,
+						  ml_sta_vdev_lst)) {
+		if (num_disabled_ml_sta)
+			policy_mgr_debug("Not re-enabled due to disallowed concurrency");
+		goto done;
+	}
+
+	policy_mgr_mlo_sta_set_link(psoc,
+				    MLO_LINK_FORCE_REASON_DISCONNECT,
+				    MLO_LINK_FORCE_MODE_NO_FORCE,
+				    num_ml_sta, ml_sta_vdev_lst);
+
+done:
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down() - Handle enable
+ * link on P2P/SAP/ML_STA vdev down
+ * @psoc: objmgr psoc
+ * @vdev: vdev which went down
+ *
+ * Return: void
+ */
+static void
+policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down(struct wlan_objmgr_psoc *psoc,
+						struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t num_ml_sta = 0, num_p2p_sap = 0, num_disabled_ml_sta = 0;
+	uint8_t num_affected_link = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t p2p_sap_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t p2p_sap_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status;
+
+	status = policy_mgr_handle_ml_sta_link_state_allowed(
+				psoc, MLO_LINK_FORCE_REASON_DISCONNECT);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
+	status = policy_mgr_handle_ml_sta_link_enable_on_sta_down(psoc, vdev);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(pm_ctx, &num_ml_sta,
+						      &num_disabled_ml_sta,
+						      ml_sta_vdev_lst,
+						      ml_freq_lst, &num_p2p_sap,
+						      p2p_sap_vdev_lst,
+						      p2p_sap_freq_lst);
+
+	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_p2p_sap %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_p2p_sap);
+
+	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_p2p_sap > MAX_NUMBER_OF_CONC_CONNECTIONS)
+		return;
+
+	/* If link can not be allowed to enable then skip checking further. */
+	if (!policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
+						   num_ml_sta, ml_freq_lst,
+						   ml_sta_vdev_lst))
+		return;
+
+	/*
+	 * If num_p2p_sap is non zero, ie p2p or sap still present check if
+	 * disable link is still required, if not enable the link.
+	 *
+	 * If num_p2p_sap is 0, ie only ml sta is present, enable the link.
+	 */
+	if (num_p2p_sap)
+		num_affected_link =
+			policy_mgr_get_affected_links_for_go_sap_cli(psoc,
+						num_ml_sta, ml_sta_vdev_lst,
+						ml_freq_lst, num_p2p_sap,
+						p2p_sap_vdev_lst,
+						p2p_sap_freq_lst);
+
+	if (num_affected_link)
+		policy_mgr_debug("vdev %d: Affected link present, dont reanabe ML link",
+				 vdev_id);
+	else
+		policy_mgr_mlo_sta_set_link(psoc,
+					    MLO_LINK_FORCE_REASON_DISCONNECT,
+					    MLO_LINK_FORCE_MODE_NO_FORCE,
+					    num_ml_sta, ml_sta_vdev_lst);
+}
+
+void policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc *psoc,
+						 enum QDF_OPMODE mode,
+						 uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d: invalid vdev", vdev_id);
+		return;
+	}
+
+	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE ||
+	    mode == QDF_P2P_CLIENT_MODE || mode == QDF_P2P_GO_MODE)
+		policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down(psoc, vdev);
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
+/**
+ * policy_mgr_pick_link_vdev_from_inactive_list() - Get inactive vdev
+ * which can be activated
+ * @psoc: PSOC object information
+ * @vdev: vdev object
+ * @inactive_vdev_num: inactive vdev num in list
+ * @inactive_vdev_lst: inactive vdev list
+ * @inactive_freq_lst: inactive vdev frequency list
+ * @picked_vdev_id: Picked vdev id
+ * @non_removed_vdev_id: not removed inactive vdev id
+ *
+ * If one link is removed and inactivated, pick one of existing inactive
+ * vdev which can be activated by checking concurrency API.
+ *
+ * Return: void
+ */
+static void
+policy_mgr_pick_link_vdev_from_inactive_list(
+	struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev,
+	uint8_t inactive_vdev_num, uint8_t *inactive_vdev_lst,
+	qdf_freq_t *inactive_freq_lst, uint8_t *picked_vdev_id,
+	uint8_t *non_removed_vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	uint8_t num_del = 0;
+	union conc_ext_flag conc_ext_flags = {0};
+	uint8_t i;
+
+	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);
+	policy_mgr_store_and_del_conn_info_by_vdev_id(
+			psoc, wlan_vdev_get_id(vdev),
+			info, &num_del);
+	/* pick one inactive parnter link and make it active */
+	for (i = 0; i < inactive_vdev_num; i++) {
+		struct wlan_objmgr_vdev *partner_vdev;
+
+		if (wlan_get_vdev_link_removed_flag_by_vdev_id(
+				psoc, inactive_vdev_lst[i])) {
+			policy_mgr_debug("skip removed link vdev %d",
+					 inactive_vdev_lst[i]);
+			continue;
+		}
+
+		partner_vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+						     inactive_vdev_lst[i],
+						     WLAN_POLICY_MGR_ID);
+		if (!partner_vdev) {
+			policy_mgr_err("invalid partner_vdev %d ",
+				       inactive_vdev_lst[i]);
+			continue;
+		}
+		*non_removed_vdev_id = inactive_vdev_lst[i];
+
+		conc_ext_flags.value =
+		policy_mgr_get_conc_ext_flags(partner_vdev, false);
+
+		if (policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE,
+						      inactive_freq_lst[i],
+						      HW_MODE_20_MHZ,
+						      conc_ext_flags.value,
+						      NULL)) {
+			*picked_vdev_id = inactive_vdev_lst[i];
+			wlan_objmgr_vdev_release_ref(partner_vdev,
+						     WLAN_POLICY_MGR_ID);
+			break;
+		}
+		wlan_objmgr_vdev_release_ref(partner_vdev, WLAN_POLICY_MGR_ID);
+	}
+	/* Restore the connection info */
+	policy_mgr_restore_deleted_conn_info(psoc, info, num_del);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+}
+
+QDF_STATUS
+policy_mgr_handle_link_removal_on_standby(struct wlan_objmgr_vdev *vdev,
+					  struct ml_rv_info *reconfig_info)
+{
+	struct mlo_link_info *link_info;
+	uint8_t i, link_id;
+	uint32_t removal_link_bitmap = 0;
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+
+	if (!vdev || !vdev->mlo_dev_ctx) {
+		policy_mgr_err("invalid vdev or mlo_dev_ctx");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		policy_mgr_err("psoc is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	for (i = 0; i < reconfig_info->num_links; i++) {
+		if (!(reconfig_info->link_info[i].is_ap_removal_timer_p &&
+		      reconfig_info->link_info[i].ap_removal_timer))
+			continue;
+
+		link_id = reconfig_info->link_info[i].link_id;
+		link_info = mlo_mgr_get_ap_link_by_link_id(vdev->mlo_dev_ctx,
+							   link_id);
+		if (!link_info) {
+			policy_mgr_err("link info null, id %d", link_id);
+			return QDF_STATUS_E_NULL_VALUE;
+		}
+		policy_mgr_debug("AP removal tbtt %d vdev %d link %d flag 0x%x STA MAC " QDF_MAC_ADDR_FMT " BSSID " QDF_MAC_ADDR_FMT,
+				 reconfig_info->link_info[i].ap_removal_timer,
+				 link_info->vdev_id, link_id,
+				 (uint32_t)link_info->link_status_flags,
+				 QDF_MAC_ADDR_REF(link_info->link_addr.bytes),
+				 QDF_MAC_ADDR_REF(link_info->ap_link_addr.bytes));
+
+		if (qdf_is_macaddr_zero(&link_info->ap_link_addr))
+			continue;
+
+		if (link_info->vdev_id != WLAN_INVALID_VDEV_ID)
+			continue;
+
+		if (qdf_atomic_test_and_set_bit(LS_F_AP_REMOVAL_BIT,
+						&link_info->link_status_flags))
+			continue;
+
+		removal_link_bitmap |= 1 << link_id;
+	}
+	if (!removal_link_bitmap)
+		return QDF_STATUS_SUCCESS;
+
+	status = policy_mgr_mlo_sta_set_nlink(
+			psoc, wlan_vdev_get_id(vdev),
+			MLO_LINK_FORCE_REASON_LINK_REMOVAL,
+			MLO_LINK_FORCE_MODE_INACTIVE,
+			0,
+			removal_link_bitmap,
+			0,
+			0);
+	if (status == QDF_STATUS_E_PENDING)
+		status = QDF_STATUS_SUCCESS;
+	else
+		policy_mgr_err("status %d", status);
+
+	return status;
+}
+
+void policy_mgr_handle_link_removal_on_vdev(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i;
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
+	uint8_t num_active_ml_sta;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	uint8_t non_removal_link_vdev_id = WLAN_INVALID_VDEV_ID;
+	uint8_t picked_vdev_id = WLAN_INVALID_VDEV_ID;
+	QDF_STATUS status;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		policy_mgr_err("Failed to get psoc");
+		return;
+	}
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	if (wlan_get_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id)) {
+		policy_mgr_debug("removal link vdev %d is removed already",
+				 vdev_id);
+		return;
+	}
+
+	wlan_connectivity_mlo_reconfig_event(vdev);
+
+	/* mark link removed for vdev */
+	wlan_set_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id,
+						   true);
+	status = policy_mgr_handle_ml_sta_link_state_allowed(
+			psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_set_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id,
+							   false);
+		return;
+	}
+
+	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst,
+				   NULL, NULL, NULL);
+	if (!num_ml_sta) {
+		policy_mgr_debug("unexpected event, no ml sta");
+		return;
+	}
+	if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_ml_sta <= num_disabled_ml_sta) {
+		policy_mgr_debug("unexpected ml sta num %d %d",
+				 num_ml_sta, num_disabled_ml_sta);
+		return;
+	}
+	/* Single link FW should handle BTM/disassoc and do roaming.
+	 * Host will not send inactive command to FW.
+	 */
+	if (num_ml_sta < 2) {
+		policy_mgr_debug("no op for single link mlo, num_ml_sta %d",
+				 num_ml_sta);
+		return;
+	}
+
+	policy_mgr_debug("removal link vdev %d num_ml_sta %d num_disabled_ml_sta %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta);
+
+	num_active_ml_sta = num_ml_sta;
+	if (num_ml_sta >= num_disabled_ml_sta)
+		num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
+
+	for (i = 0; i < num_active_ml_sta; i++)
+		if (ml_sta_vdev_lst[i] == vdev_id)
+			break;
+
+	if (i == num_active_ml_sta) {
+		/* no found in active ml list, it must be in inactive list */
+		policy_mgr_debug("removal link vdev %d is inactive already",
+				 vdev_id);
+
+		/* send inactive command to fw again with "link removal
+		 * reason"
+		 */
+		policy_mgr_mlo_sta_set_link(
+			psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL,
+			MLO_LINK_FORCE_MODE_INACTIVE,
+			1, &vdev_id);
+		return;
+	}
+
+	/* pick one inactive parnter link and make it active */
+	if (num_active_ml_sta < num_ml_sta)
+		policy_mgr_pick_link_vdev_from_inactive_list(
+				psoc, vdev, num_disabled_ml_sta,
+				&ml_sta_vdev_lst[num_active_ml_sta],
+				&ml_freq_lst[num_active_ml_sta],
+				&picked_vdev_id,
+				&non_removal_link_vdev_id);
+	if (picked_vdev_id != WLAN_INVALID_VDEV_ID) {
+		/* find one inactive link can be active, send it to fw with
+		 * the removed link together.
+		 */
+		policy_mgr_debug("active parnter vdev %d, inactive removal vdev %d",
+				 picked_vdev_id, vdev_id);
+		policy_mgr_mlo_sta_set_link_ext(
+				psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL,
+				MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+				1, &picked_vdev_id,
+				1, &vdev_id);
+		return;
+	}
+	if (num_active_ml_sta < 2) {
+		/* For multi-link MLO, one link is removed and
+		 * no find one inactive link can be active:
+		 * 1. If at least one left link is not link removed state,
+		 * host will trigger roaming.
+		 * 2. If all left links are link removed state,
+		 * FW will trigger roaming based on BTM or disassoc frame
+		 */
+		if (non_removal_link_vdev_id != WLAN_INVALID_VDEV_ID) {
+			policy_mgr_debug("trigger roaming, non_removal_link_vdev_id %d",
+					 non_removal_link_vdev_id);
+			policy_mgr_trigger_roam_on_link_removal(vdev);
+		}
+		return;
+	}
+	/* If active link number >= 2 and one link is removed, then at least
+	 * one link is still active, just send inactived command to fw.
+	 */
+	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL,
+				    MLO_LINK_FORCE_MODE_INACTIVE,
+				    1, &vdev_id);
+}
+
+/**
+ * policy_mgr_is_restart_sap_required_with_mlo_sta() - Check SAP required to
+ * restart for force SCC with MLO STA
+ * @psoc: PSOC object information
+ * @sap_vdev_id: sap vdev id
+ * @sap_ch_freq: sap channel frequency
+ *
+ * For MLO STA+SAP case, mlo link maybe in inactive state after connected
+ * and the hw mode maybe not updated, check MCC/SCC by
+ * policy_mgr_are_2_freq_on_same_mac may not match MCC/SCC state
+ * after the link is activated by target later. So to check frequency match
+ * or not to decide SAP do force SCC or not if MLO STA 2 links are present.
+ *
+ * Return: true if SAP is required to force SCC with MLO STA
+ */
+static bool
+policy_mgr_is_restart_sap_required_with_mlo_sta(struct wlan_objmgr_psoc *psoc,
+						uint8_t sap_vdev_id,
+						qdf_freq_t sap_ch_freq)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i;
+	bool same_freq_with_mlo_sta = false;
+	bool restart_required = false;
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_ml_active_sta = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst,
+				   NULL, NULL, NULL);
+	if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		policy_mgr_debug("unexpected num_ml_sta %d ", num_ml_sta);
+		return false;
+	}
+
+	num_ml_active_sta = num_ml_sta;
+	if (num_ml_sta >= num_disabled_ml_sta)
+		num_ml_active_sta = num_ml_sta - num_disabled_ml_sta;
+	for (i = 0; i < num_ml_active_sta; i++) {
+		if (ml_freq_lst[i] == sap_ch_freq) {
+			same_freq_with_mlo_sta = true;
+			break;
+		}
+	}
+
+	if (num_ml_active_sta >= 2 && !same_freq_with_mlo_sta) {
+		policy_mgr_debug("SAP is not SCC with any of active MLO STA link, restart SAP");
+		restart_required = true;
+	}
+
+	return restart_required;
+}
+
+/**
+ * policy_mgr_is_new_force_allowed() - Check if the new force command is allowed
+ * @psoc: PSOC object information
+ * @vdev: ml sta vdev object
+ * @active_link_bitmap: Active link bitmap from user request
+ *
+ * If ML STA associates in 3-link (2.4 GHz + 5 GHz + 6 GHz), Host sends force
+ * inactive num command between 5 GHz and 6 GHz links to firmware as it's a DBS
+ * RD. This force has to be in effect at all times but any new force active num
+ * command request from the userspace (except for 5 GHz + 6 GHz links) should be
+ * honored. This API checks if the new force command can be allowed.
+ *
+ * Return: True if the new force command is allowed, else False
+ */
+static bool
+policy_mgr_is_new_force_allowed(struct wlan_objmgr_psoc *psoc,
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t active_link_bitmap)
+{
+	uint32_t link_bitmap = 0;
+	uint8_t link_num = 0;
+	struct set_link_req conc_link_req;
+
+	qdf_mem_zero(&conc_link_req, sizeof(conc_link_req));
+	ml_nlink_get_force_link_request(psoc, vdev, &conc_link_req,
+					SET_LINK_FROM_CONCURRENCY);
+	/* If force inactive num is present due to MCC link(DBS RD) or
+	 * concurrency with legacy intf, don't allow force active if
+	 * left inactive link number doesn't meet concurrency
+	 * requirement.
+	 */
+	if (conc_link_req.force_inactive_num_bitmap ||
+	    conc_link_req.force_inactive_num) {
+		link_bitmap = ~active_link_bitmap &
+		conc_link_req.force_inactive_num_bitmap;
+		if (!link_bitmap) {
+			policy_mgr_err("New force bitmap 0x%x not allowed due to force_inactive_num_bitmap 0x%x",
+				       active_link_bitmap,
+				       conc_link_req.
+				       force_inactive_num_bitmap);
+			return false;
+		}
+		link_num = convert_link_bitmap_to_link_ids(link_bitmap,
+							   0, NULL);
+		if (link_num < conc_link_req.force_inactive_num) {
+			policy_mgr_debug("force inact num exists with %d don't allow act bitmap 0x%x",
+					 conc_link_req.force_active_num,
+					 active_link_bitmap);
+			return false;
+		}
+	}
+	/* If force inactive bitmap is present due to link removal or
+	 * concurrency with legacy intf, don't allow force active if
+	 * it is conflict with existing concurrency requirement.
+	 */
+	if (conc_link_req.force_inactive_bitmap) {
+		link_bitmap = active_link_bitmap &
+			conc_link_req.force_inactive_bitmap;
+		if (link_bitmap) {
+			policy_mgr_err("New force act bitmap 0x%x not allowed due to conc force inact bitmap 0x%x",
+				       active_link_bitmap,
+				       conc_link_req.force_inactive_bitmap);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+void policy_mgr_activate_mlo_links_nlink(struct wlan_objmgr_psoc *psoc,
+					 uint8_t session_id, uint8_t num_links,
+					 struct qdf_mac_addr active_link_addr[2])
+{
+	uint8_t *link_mac_addr;
+	uint32_t link_ctrl_flags;
+	enum mlo_link_force_reason reason;
+	enum mlo_link_force_mode mode;
+	struct wlan_objmgr_vdev *vdev;
+	struct mlo_link_info *link_info;
+	bool active_link_present = false;
+	uint8_t iter, link, active_link_cnt = 0, inactive_link_cnt = 0;
+	uint32_t active_link_bitmap = 0;
+	uint32_t inactive_link_bitmap = 0;
+	struct ml_link_force_state curr = {0};
+	bool update_inactive_link = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev_id: %d vdev not found", session_id);
+		return;
+	}
+
+	if (!wlan_cm_is_vdev_connected(vdev)) {
+		policy_mgr_err("vdev is not in connected state");
+		goto done;
+	}
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		policy_mgr_err("vdev is not mlo vdev");
+		goto done;
+	}
+
+	policy_mgr_debug("Num active links: %d", num_links);
+	link_info = &vdev->mlo_dev_ctx->link_ctx->links_info[0];
+	for (iter = 0; iter < WLAN_MAX_ML_BSS_LINKS; iter++) {
+		if (link_info->link_id == WLAN_INVALID_LINK_ID) {
+			link_info++;
+			continue;
+		}
+
+		link_mac_addr = &link_info->link_addr.bytes[0];
+		policy_mgr_debug("link addr: " QDF_MAC_ADDR_FMT,
+				 QDF_MAC_ADDR_REF(link_mac_addr));
+
+		for (link = 0; link < num_links; link++) {
+			policy_mgr_debug("active addr: " QDF_MAC_ADDR_FMT,
+			   QDF_MAC_ADDR_REF(&active_link_addr[link].bytes[0]));
+			if (!qdf_mem_cmp(link_mac_addr,
+					 &active_link_addr[link].bytes[0],
+					 QDF_MAC_ADDR_SIZE)) {
+				active_link_bitmap |= 1 << link_info->link_id;
+				active_link_cnt++;
+				active_link_present = true;
+				policy_mgr_debug("Link address match");
+			}
+		}
+		if (!active_link_present) {
+			inactive_link_bitmap |= 1 << link_info->link_id;
+			inactive_link_cnt++;
+			policy_mgr_err("No link address match");
+		}
+		active_link_present = false;
+		link_info++;
+	}
+
+	policy_mgr_debug("active link cnt: %d, inactive link cnt: %d",
+			 active_link_cnt, inactive_link_cnt);
+
+	if (!active_link_cnt) {
+		goto done;
+	} else if (policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
+		policy_mgr_debug("Concurrency exists, cannot enter EMLSR mode");
+		goto done;
+	} else {
+		if (!policy_mgr_is_new_force_allowed(
+			psoc, vdev, active_link_bitmap))
+			goto done;
+
+		/* If current force inactive bitmap exists, we have to remove
+		 * the new active bitmap from the existing inactive bitmap,
+		 * e.g. a link id can't be present in active bitmap and
+		 * inactive bitmap at same time, so update inactive bitmap
+		 * as well.
+		 */
+		ml_nlink_get_curr_force_state(psoc, vdev, &curr);
+		if (curr.force_inactive_bitmap && !inactive_link_cnt) {
+			inactive_link_bitmap = curr.force_inactive_bitmap &
+						~active_link_bitmap;
+			update_inactive_link = true;
+		}
+	}
+
+	/*
+	 * If there are both active and inactive vdev count, then issue a
+	 * single WMI with force mode MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+	 * else if there is only active vdev count, send single WMI for
+	 * all active vdevs with force mode MLO_LINK_FORCE_MODE_ACTIVE.
+	 */
+	if (inactive_link_cnt || update_inactive_link) {
+		reason = MLO_LINK_FORCE_REASON_CONNECT;
+		mode = MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE;
+		link_ctrl_flags = link_ctrl_f_overwrite_active_bitmap |
+					link_ctrl_f_overwrite_inactive_bitmap;
+	} else {
+		reason = MLO_LINK_FORCE_REASON_DISCONNECT;
+		mode = MLO_LINK_FORCE_MODE_ACTIVE;
+		link_ctrl_flags = link_ctrl_f_overwrite_active_bitmap;
+	}
+
+	policy_mgr_mlo_sta_set_nlink(psoc, wlan_vdev_get_id(vdev),
+				     reason, mode, 0,
+				     active_link_bitmap, inactive_link_bitmap,
+				     link_ctrl_flags);
+	if (active_link_bitmap)
+		ml_nlink_vendor_command_set_link(
+			psoc, session_id,
+			LINK_CONTROL_MODE_USER,
+			MLO_LINK_FORCE_REASON_CONNECT,
+			MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+			0, active_link_bitmap,
+			inactive_link_bitmap);
+
+done:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
+void policy_mgr_activate_mlo_links(struct wlan_objmgr_psoc *psoc,
+				   uint8_t session_id, uint8_t num_links,
+				   struct qdf_mac_addr *active_link_addr)
+{
+	uint8_t idx, link, active_vdev_cnt = 0, inactive_vdev_cnt = 0;
+	uint16_t ml_vdev_cnt = 0;
+	struct wlan_objmgr_vdev *tmp_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
+	uint8_t active_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
+	uint8_t inactive_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t *link_mac_addr;
+	bool active_vdev_present = false;
+	uint16_t active_link_bitmap = 0;
+	uint16_t inactive_link_bitmap = 0;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev_id: %d vdev not found", session_id);
+		return;
+	}
+
+	if (!wlan_cm_is_vdev_connected(vdev)) {
+		policy_mgr_err("vdev is not in connected state");
+		goto done;
+	}
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		policy_mgr_err("vdev is not mlo vdev");
+		goto done;
+	}
+
+	mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, tmp_vdev_lst);
+	policy_mgr_debug("Num active links: %d, ML vdev cnt: %d", num_links,
+			 ml_vdev_cnt);
+	for (idx = 0; idx < ml_vdev_cnt; idx++) {
+		link_mac_addr = wlan_vdev_mlme_get_macaddr(tmp_vdev_lst[idx]);
+		policy_mgr_debug("link addr: " QDF_MAC_ADDR_FMT,
+				 QDF_MAC_ADDR_REF(link_mac_addr));
+		for (link = 0; link < num_links; link++) {
+			policy_mgr_debug("active addr: " QDF_MAC_ADDR_FMT,
+			   QDF_MAC_ADDR_REF(&active_link_addr[link].bytes[0]));
+			if (!qdf_mem_cmp(link_mac_addr,
+					 &active_link_addr[link].bytes[0],
+					 QDF_MAC_ADDR_SIZE)) {
+				active_vdev_lst[active_vdev_cnt] =
+					wlan_vdev_get_id(tmp_vdev_lst[idx]);
+				active_link_bitmap |=
+				1 << wlan_vdev_get_link_id(tmp_vdev_lst[idx]);
+				active_vdev_cnt++;
+				active_vdev_present = true;
+				policy_mgr_debug("Link address match");
+			}
+		}
+		if (!active_vdev_present) {
+			inactive_vdev_lst[inactive_vdev_cnt] =
+					wlan_vdev_get_id(tmp_vdev_lst[idx]);
+			inactive_link_bitmap |=
+			1 << wlan_vdev_get_link_id(tmp_vdev_lst[idx]);
+
+			inactive_vdev_cnt++;
+			policy_mgr_err("No link address match");
+		}
+		active_vdev_present = false;
+	}
+
+	policy_mgr_debug("active vdev cnt: %d, inactive vdev cnt: %d",
+			 active_vdev_cnt, inactive_vdev_cnt);
+
+	if (active_vdev_cnt &&
+	    policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
+		policy_mgr_debug("Concurrency exists, cannot enter EMLSR mode");
+		goto ref_release;
+	}
+
+	/*
+	 * If there are both active and inactive vdev count, then issue a
+	 * single WMI with force mode MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+	 * else if there is only active vdev count, send single WMI for
+	 * all active vdevs with force mode MLO_LINK_FORCE_MODE_ACTIVE.
+	 */
+	if (active_vdev_cnt && inactive_vdev_cnt)
+		policy_mgr_mlo_sta_set_link_ext(
+					psoc, MLO_LINK_FORCE_REASON_CONNECT,
+					MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+					active_vdev_cnt, active_vdev_lst,
+					inactive_vdev_cnt, inactive_vdev_lst);
+	else if (active_vdev_cnt && !inactive_vdev_cnt)
+		policy_mgr_mlo_sta_set_link(psoc,
+					    MLO_LINK_FORCE_REASON_DISCONNECT,
+					    MLO_LINK_FORCE_MODE_ACTIVE,
+					    active_vdev_cnt, active_vdev_lst);
+	if (active_link_bitmap)
+		ml_nlink_vendor_command_set_link(
+			psoc, session_id,
+			LINK_CONTROL_MODE_USER,
+			MLO_LINK_FORCE_REASON_CONNECT,
+			MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+			0, active_link_bitmap,
+			inactive_link_bitmap);
+
+ref_release:
+	for (idx = 0; idx < ml_vdev_cnt; idx++)
+		mlo_release_vdev_ref(tmp_vdev_lst[idx]);
+done:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
+QDF_STATUS
+policy_mgr_update_mlo_links_based_on_linkid(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id,
+					    uint8_t num_links,
+					    uint8_t *link_id_list,
+					    uint32_t *config_state_list)
+{
+	uint8_t idx, link, active_vdev_cnt = 0, inactive_vdev_cnt = 0;
+	uint16_t ml_vdev_cnt = 0;
+	struct wlan_objmgr_vdev *vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
+	uint8_t active_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
+	uint8_t inactive_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t link_id, num_links_to_disable = 0, num_matched_linkid = 0;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t active_link_bitmap = 0;
+	uint32_t inactive_link_bitmap = 0;
+	bool update_vendor_cmd = false;
+
+	for (idx = 0; idx < num_links; idx++) {
+		if (config_state_list[idx] == 0)
+			num_links_to_disable++;
+	}
+
+	if (num_links_to_disable == num_links) {
+		policy_mgr_debug("vdev: %d num_links_to_disable: %d", vdev_id,
+				 num_links_to_disable);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev: %d vdev not found", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wlan_cm_is_vdev_connected(vdev)) {
+		policy_mgr_err("vdev: %d is not in connected state", vdev_id);
+		goto release_vdev_ref;
+	}
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		policy_mgr_err("vdev:%d is not mlo vdev", vdev_id);
+		goto release_vdev_ref;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		goto release_vdev_ref;
+	}
+
+	mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, vdev_lst);
+	for (idx = 0; idx < ml_vdev_cnt; idx++) {
+		link_id = wlan_vdev_get_link_id(vdev_lst[idx]);
+		for (link = 0; link < num_links; link++) {
+			if (link_id_list[link] == link_id) {
+				num_matched_linkid++;
+				policy_mgr_debug("link id:%d match", link_id);
+				if (config_state_list[link]) {
+					active_vdev_lst[active_vdev_cnt] =
+						wlan_vdev_get_id(vdev_lst[idx]);
+					active_link_bitmap |= 1 << link_id;
+					active_vdev_cnt++;
+				} else {
+					inactive_vdev_lst[inactive_vdev_cnt] =
+						wlan_vdev_get_id(vdev_lst[idx]);
+					inactive_link_bitmap |= 1 << link_id;
+					inactive_vdev_cnt++;
+				}
+			}
+		}
+	}
+
+	policy_mgr_debug("vdev: %d, active links: %d, ml count: %d, active count: %d, inactive count: %d",
+			 vdev_id, num_links, ml_vdev_cnt, active_vdev_cnt,
+			 inactive_vdev_cnt);
+
+	if (num_links != num_matched_linkid) {
+		policy_mgr_debug("invalid link id(s), num_matched_linkid: %d",
+				 num_matched_linkid);
+		goto release_ml_vdev_ref;
+	}
+
+	if (active_vdev_cnt &&
+	    policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
+		policy_mgr_debug("vdev: %d emlsr sta conn present", vdev_id);
+		if (active_vdev_cnt == 1)
+			status = QDF_STATUS_SUCCESS;
+		goto release_ml_vdev_ref;
+	}
+
+	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
+				   NULL, NULL);
+	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml);
+
+	/*
+	 * No ML STA is present or sinle link ML is present or
+	 * more no.of links are active than supported concurrent connections
+	 */
+	if (!num_ml_sta || num_ml_sta < 2 ||
+	    num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS)
+		goto release_ml_vdev_ref;
+
+	if (!num_disabled_ml_sta) {
+		/*
+		 * both link are already enabled and received set link req to
+		 * enable both again
+		 */
+		if (active_vdev_cnt && !inactive_vdev_cnt) {
+			status = QDF_STATUS_SUCCESS;
+			goto release_ml_vdev_ref;
+		}
+
+		/*
+		 * both link are already enabled and received set link req
+		 * disable one link, disable any
+		 */
+		if (active_vdev_cnt && inactive_vdev_cnt) {
+			status = policy_mgr_mlo_sta_set_link_ext(psoc,
+					MLO_LINK_FORCE_REASON_CONNECT,
+					MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+					active_vdev_cnt, active_vdev_lst,
+					inactive_vdev_cnt, inactive_vdev_lst);
+			if (status == QDF_STATUS_E_PENDING ||
+			    status == QDF_STATUS_SUCCESS)
+				update_vendor_cmd = true;
+
+			goto release_ml_vdev_ref;
+		}
+	} else {
+		/*
+		 * one link is enable and one link is disabled, If disabled
+		 * link can not be allowed to enable then send status failure
+		 * to upper layer.
+		 */
+		if (active_vdev_cnt &&
+		    !policy_mgr_sta_ml_link_enable_allowed(psoc,
+							   num_disabled_ml_sta,
+							   num_ml_sta,
+							   ml_freq_lst,
+							   ml_sta_vdev_lst)) {
+			policy_mgr_debug("vdev %d: link enable not allowed",
+					 vdev_id);
+			goto release_ml_vdev_ref;
+		}
+
+		/*
+		 * If there are both active and inactive vdev count, then
+		 * issue a single WMI with force mode
+		 * MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE, else if there is only
+		 * active vdev count, send single WMI for all active vdevs
+		 * with force mode MLO_LINK_FORCE_MODE_ACTIVE.
+		 */
+		if (active_vdev_cnt && inactive_vdev_cnt) {
+			status = policy_mgr_mlo_sta_set_link_ext(psoc,
+					MLO_LINK_FORCE_REASON_CONNECT,
+					MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+					active_vdev_cnt, active_vdev_lst,
+					inactive_vdev_cnt, inactive_vdev_lst);
+			if (status == QDF_STATUS_E_PENDING ||
+			    status == QDF_STATUS_SUCCESS)
+				update_vendor_cmd = true;
+		} else if (active_vdev_cnt && !inactive_vdev_cnt) {
+			status = policy_mgr_mlo_sta_set_link(psoc,
+					MLO_LINK_FORCE_REASON_DISCONNECT,
+					MLO_LINK_FORCE_MODE_ACTIVE,
+					active_vdev_cnt, active_vdev_lst);
+			if (status == QDF_STATUS_E_PENDING ||
+			    status == QDF_STATUS_SUCCESS)
+				update_vendor_cmd = true;
+		}
+	}
+	if (update_vendor_cmd)
+		ml_nlink_vendor_command_set_link(
+			psoc, vdev_id,
+			LINK_CONTROL_MODE_USER,
+			MLO_LINK_FORCE_REASON_CONNECT,
+			MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
+			0, active_link_bitmap,
+			inactive_link_bitmap);
+
+release_ml_vdev_ref:
+	for (idx = 0; idx < ml_vdev_cnt; idx++)
+		mlo_release_vdev_ref(vdev_lst[idx]);
+release_vdev_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	return status;
+}
+
+/**
+ * policy_mgr_process_mlo_sta_dynamic_force_num_link() - Set links for MLO STA
+ * @psoc: psoc object
+ * @reason: Reason for which link is forced
+ * @mode: Force reason
+ * @num_mlo_vdev: number of mlo vdev
+ * @mlo_vdev_lst: MLO STA vdev list
+ * @force_active_cnt: number of MLO links to operate in active state as per
+ * user req
+ *
+ * User space provides the desired number of MLO links to operate in active
+ * state at any given time. Host validate request as per current concurrency
+ * and send SET LINK requests to FW. FW will choose which MLO links should
+ * operate in the active state.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+policy_mgr_process_mlo_sta_dynamic_force_num_link(struct wlan_objmgr_psoc *psoc,
+				enum mlo_link_force_reason reason,
+				enum mlo_link_force_mode mode,
+				uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst,
+				uint8_t force_active_cnt)
+{
+	struct mlo_link_set_active_req *req;
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!num_mlo_vdev) {
+		policy_mgr_err("invalid 0 num_mlo_vdev");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, mlo_vdev_lst[0],
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d: invalid vdev", mlo_vdev_lst[0]);
+		qdf_mem_free(req);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_debug("vdev %d: mode %d num_mlo_vdev %d reason %d",
+			 wlan_vdev_get_id(vdev), mode, num_mlo_vdev, reason);
+
+	/*
+	 * TODO: this API has to be merged with policy_mgr_mlo_sta_set_link_ext
+	 * as part of 3 link FR change as in caller only we have to decide how
+	 * many links to disable/enable for MLO_LINK_FORCE_MODE_ACTIVE_NUM or
+	 * MLO_LINK_FORCE_MODE_INACTIVE_NUM scenario
+	 */
+	req->ctx.vdev = vdev;
+	req->param.reason = reason;
+	req->param.force_mode = mode;
+	req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp;
+	req->ctx.validate_set_mlo_link_cb =
+		policy_mgr_validate_set_mlo_link_cb;
+	req->ctx.cb_arg = req;
+
+	/* set MLO vdev bit mask */
+	policy_mgr_fill_ml_active_link_vdev_bitmap(req, mlo_vdev_lst,
+						   num_mlo_vdev);
+
+	pm_ctx->active_vdev_bitmap = req->param.vdev_bitmap[0];
+	pm_ctx->inactive_vdev_bitmap = req->param.vdev_bitmap[1];
+
+	req->param.num_link_entry = 1;
+	req->param.link_num[0].num_of_link = force_active_cnt;
+	req->param.control_flags.dynamic_force_link_num = 1;
+
+	if (ml_is_nlink_service_supported(psoc)) {
+		status =
+		policy_mgr_mlo_sta_set_link_by_linkid(psoc, vdev, reason,
+						      mode,
+						      req->param.link_num[0].
+						      num_of_link,
+						      num_mlo_vdev,
+						      mlo_vdev_lst,
+						      0,
+						      NULL);
+		qdf_mem_free(req);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+		if (status != QDF_STATUS_E_PENDING) {
+			policy_mgr_err("set_link_by_linkid status %d", status);
+			return status;
+		}
+		return QDF_STATUS_SUCCESS;
+	}
+
+	policy_mgr_set_link_in_progress(pm_ctx, true);
+
+	status = mlo_ser_set_link_req(req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d force_active_cnt: %d, reason %d",
+			       wlan_vdev_get_id(vdev), mode, num_mlo_vdev,
+			       force_active_cnt,
+			       reason);
+		qdf_mem_free(req);
+		policy_mgr_set_link_in_progress(pm_ctx, false);
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	return status;
+}
+
+QDF_STATUS policy_mgr_update_active_mlo_num_links(struct wlan_objmgr_psoc *psoc,
+						  uint8_t vdev_id,
+						  uint8_t force_active_cnt)
+{
+	struct wlan_objmgr_vdev *vdev, *tmp_vdev;
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
+	uint8_t num_enabled_ml_sta = 0, conn_count;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint16_t link_bitmap = 0;
+	uint8_t i;
+
+	if (policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
+		policy_mgr_debug("Concurrency exists, cannot enter EMLSR mode");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev_id: %d vdev not found", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		goto release_vdev_ref;
+
+	if (!wlan_cm_is_vdev_connected(vdev)) {
+		policy_mgr_err("vdev is not in connected state");
+		goto release_vdev_ref;
+	}
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		policy_mgr_err("vdev is not mlo vdev");
+		goto release_vdev_ref;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		goto release_vdev_ref;
+	}
+
+	conn_count = policy_mgr_get_connection_count(psoc);
+	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
+				   NULL, NULL);
+	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d conn cout %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml,
+			 conn_count);
+
+	/*
+	 * No ML STA is present or more no.of links are active than supported
+	 * concurrent connections
+	 */
+	if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS)
+		goto release_vdev_ref;
+
+	/*
+	 * DUT connected with MLO AP, one link is always active, So if
+	 * request comes to make one link is active, host sends set link command
+	 * with mode MLO_LINK_FORCE_MODE_ACTIVE_NUM, so that FW should restrict
+	 * to only one link and avoid switch from MLSR to MLMR.
+	 */
+	if (force_active_cnt == 1)
+		goto set_link;
+
+	/*
+	 * num_disabled_ml_sta == 0, means 2 link is already active,
+	 * In this case send set link command with num link 2 and mode
+	 * MLO_LINK_FORCE_MODE_ACTIVE_NUM, so that FW should restrict to only
+	 * in MLMR mode (2 link should be active).
+	 * If current enabled links are < 2, and there are concurrent
+	 * connection present, force active 2 links, which may be
+	 * conflict with concurrent rules, reject it.
+	 * If the two enabled links are MCC, don't not force active 2 links.
+	 */
+	num_enabled_ml_sta = num_ml_sta;
+	if (num_ml_sta >= num_disabled_ml_sta)
+		num_enabled_ml_sta = num_ml_sta - num_disabled_ml_sta;
+
+	if (force_active_cnt >= 2) {
+		if (num_ml_sta < 2) {
+			policy_mgr_debug("num_ml_sta %d < 2, can't force active cnt %d",
+					 num_ml_sta,
+					 force_active_cnt);
+			goto release_vdev_ref;
+		}
+		if (num_enabled_ml_sta < 2 &&
+		    conn_count > num_enabled_ml_sta) {
+			policy_mgr_debug("enabled link num %d < 2, concurrent conn present %d",
+					 num_enabled_ml_sta,
+					 conn_count);
+			goto release_vdev_ref;
+		}
+		if (policy_mgr_is_ml_sta_links_in_mcc(
+					psoc, ml_freq_lst,
+					ml_sta_vdev_lst,
+					NULL, num_ml_sta,
+					NULL)) {
+			policy_mgr_debug("enabled links are mcc, concurrency disallow");
+			goto release_vdev_ref;
+		}
+	}
+	if (force_active_cnt == 2 && num_disabled_ml_sta == 0)
+		goto set_link;
+
+	/* Link can not be allowed to enable then skip checking further */
+	if (!policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
+						   num_ml_sta, ml_freq_lst,
+						   ml_sta_vdev_lst)) {
+		policy_mgr_debug("vdev %d: link enable not allowed", vdev_id);
+		goto release_vdev_ref;
+	}
+
+set_link:
+	/*
+	 * TODO: In all scenarios wherever host sends
+	 * MLO_LINK_FORCE_MODE_ACTIVE_NUM/MLO_LINK_FORCE_MODE_INACTIVE_NUM to
+	 * FW, Host need to send MLO_LINK_FORCE_MODE_NO_FORCE to FW.
+	 * So instead of two commands for serialization, take care of this in
+	 * single serialization active command.
+	 */
+
+	/*
+	 * send MLO_LINK_FORCE_MODE_NO_FORCE to FW to clear user mode setting
+	 * configured via QCA_WLAN_VENDOR_ATTR_LINK_STATE_CONTROL_MODE in FW
+	 */
+	status = policy_mgr_mlo_sta_set_link(psoc,
+				    MLO_LINK_FORCE_REASON_CONNECT,
+				    MLO_LINK_FORCE_MODE_NO_FORCE,
+				    num_ml_sta, ml_sta_vdev_lst);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_debug("fail to send no force cmd for num_links:%d",
+				 num_ml_sta);
+		goto release_vdev_ref;
+	} else {
+		policy_mgr_debug("clear force mode setting for num_links:%d",
+				 num_ml_sta);
+	}
+
+	status = policy_mgr_process_mlo_sta_dynamic_force_num_link(psoc,
+					     MLO_LINK_FORCE_REASON_CONNECT,
+					     MLO_LINK_FORCE_MODE_ACTIVE_NUM,
+					     num_ml_sta, ml_sta_vdev_lst,
+					     force_active_cnt);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_debug("vdev %d: link enable allowed", vdev_id);
+		for (i = 0; i < num_ml_sta; i++) {
+			if (i >= force_active_cnt)
+				break;
+			tmp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+				psoc, ml_sta_vdev_lst[i],
+				WLAN_POLICY_MGR_ID);
+			if (!tmp_vdev) {
+				policy_mgr_err("vdev not found for vdev_id %d ",
+					       ml_sta_vdev_lst[i]);
+				continue;
+			}
+
+			link_bitmap |= 1 << wlan_vdev_get_link_id(tmp_vdev);
+			wlan_objmgr_vdev_release_ref(tmp_vdev,
+						     WLAN_POLICY_MGR_ID);
+		}
+		ml_nlink_vendor_command_set_link(
+			psoc, vdev_id,
+			LINK_CONTROL_MODE_MIXED,
+			MLO_LINK_FORCE_REASON_CONNECT,
+			MLO_LINK_FORCE_MODE_ACTIVE_NUM,
+			force_active_cnt,
+			link_bitmap,
+			0);
+	}
+
+release_vdev_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	return status;
+}
+
+QDF_STATUS
+policy_mgr_clear_ml_links_settings_in_fw(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t num_link_to_no_force = 0, num_active_ml_sta = 0;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev: %d vdev not found", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		goto release_vdev_ref;
+
+	if (!wlan_cm_is_vdev_connected(vdev)) {
+		policy_mgr_err("vdev: %d is not in connected state", vdev_id);
+		goto release_vdev_ref;
+	}
+
+	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
+		policy_mgr_err("vdev: %d is not mlo vdev", vdev_id);
+		goto release_vdev_ref;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("vdev: %d Invalid Context", vdev_id);
+		goto release_vdev_ref;
+	}
+	/* Clear all user vendor command setting for switching to "default" */
+	ml_nlink_vendor_command_set_link(psoc, vdev_id,
+					 LINK_CONTROL_MODE_DEFAULT,
+					 0, 0, 0, 0, 0);
+
+	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
+				   NULL, NULL);
+	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d",
+			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml);
+
+	if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	    num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS)
+		goto release_vdev_ref;
+
+	num_active_ml_sta = num_ml_sta;
+	if (num_ml_sta >= num_disabled_ml_sta)
+		num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
+
+	num_link_to_no_force += num_active_ml_sta;
+
+	/* Link can not be allowed to enable then skip checking further */
+	if (policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
+						  num_ml_sta, ml_freq_lst,
+						  ml_sta_vdev_lst)) {
+		num_link_to_no_force += num_disabled_ml_sta;
+		policy_mgr_debug("Link enable allowed, total num_links: %d",
+				 num_link_to_no_force);
+	}
+
+	if (num_link_to_no_force < 1 ||
+	    num_link_to_no_force > MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		policy_mgr_debug("vdev %d: invalid num_link_to_no_force: %d",
+				 vdev_id, num_link_to_no_force);
+		goto release_vdev_ref;
+	}
+
+	/*
+	 * send WMI_MLO_LINK_SET_ACTIVE_CMDID to clear user mode setting
+	 * configured via QCA_WLAN_VENDOR_ATTR_LINK_STATE_CONTROL_MODE in FW
+	 */
+	status = policy_mgr_mlo_sta_set_link(psoc,
+					MLO_LINK_FORCE_REASON_CONNECT,
+					MLO_LINK_FORCE_MODE_NO_FORCE,
+					num_link_to_no_force,
+					ml_sta_vdev_lst);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto release_vdev_ref;
+	else
+		policy_mgr_debug("clear user mode setting for num_links:%d",
+				 num_link_to_no_force);
+
+	/*
+	 * send WMI_MLO_LINK_SET_ACTIVE_CMDID with value of
+	 * num_link as 0 to clear dynamic mode setting configured
+	 * via vendor attr LINK_STATE_MIXED_MODE_ACTIVE_NUM_LINKS in FW
+	 */
+	status = policy_mgr_process_mlo_sta_dynamic_force_num_link(psoc,
+				MLO_LINK_FORCE_REASON_CONNECT,
+				MLO_LINK_FORCE_MODE_ACTIVE_NUM,
+				num_link_to_no_force, ml_sta_vdev_lst, 0);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		policy_mgr_debug("clear mixed mode setting for num_links:%d",
+				 num_link_to_no_force);
+release_vdev_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	return status;
+}
+
+#else
+static bool
+policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc,
+				 qdf_freq_t freq,
+				 uint32_t ext_flags)
+{
+	uint32_t count;
+
+	count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
+							  NULL);
+	if (!count)
+		return true;
+
+	if (count >= 2) {
+		policy_mgr_rl_debug("Disallow 3rd STA");
+		return false;
+	}
+
+	if (!policy_mgr_allow_multiple_sta_connections(psoc)) {
+		policy_mgr_rl_debug("Multiple STA connections is not allowed");
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+policy_mgr_is_restart_sap_required_with_mlo_sta(struct wlan_objmgr_psoc *psoc,
+						uint8_t sap_vdev_id,
+						qdf_freq_t sap_ch_freq)
+{
+	return false;
+}
+#endif
+
+#ifdef WLAN_FEATURE_P2P_P2P_STA
+bool policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_mlme_get_p2p_p2p_conc_support(psoc);
+}
+#endif
+
+/**
+ * policy_mgr_is_third_conn_sta_p2p_p2p_valid: This API checks the firmware
+ * capability and allows STA + P2P + P2P combination. It can be in SCC/MCC/DBS
+ * @psoc: psoc pointer
+ * @new_conn_mode: third connection mode
+ *
+ * Return: true if support else false
+ */
+static bool policy_mgr_is_third_conn_sta_p2p_p2p_valid(
+					struct wlan_objmgr_psoc *psoc,
+					enum policy_mgr_con_mode new_conn_mode)
+{
+	int num_sta, num_go, num_cli;
+
+	num_sta = policy_mgr_mode_specific_connection_count(psoc,
+							    PM_STA_MODE,
+							    NULL);
+
+	num_go = policy_mgr_mode_specific_connection_count(psoc,
+							   PM_P2P_GO_MODE,
+							   NULL);
+
+	num_cli = policy_mgr_mode_specific_connection_count(psoc,
+							    PM_P2P_CLIENT_MODE,
+							    NULL);
+
+	if (num_sta + num_go + num_cli != 2)
+		return true;
+
+	/* If STA + P2P + another STA comes up then return true
+	 * as this API is only for two port P2P + single STA combo
+	 * checks
+	 */
+	if (num_sta == 1 && new_conn_mode == PM_STA_MODE)
+		return true;
+
+	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))
+	      ||
+	      (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode &&
+	       PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)
+	      ||
+	      ((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))
+	      ||
+	      (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode &&
+	       PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)
+	      ||
+	      ((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))) &&
+	      num_sta <= 1) {
+		if ((new_conn_mode == PM_STA_MODE ||
+		     new_conn_mode == PM_P2P_CLIENT_MODE ||
+		     new_conn_mode == PM_P2P_GO_MODE) &&
+		    !policy_mgr_is_p2p_p2p_conc_supported(psoc))
+			return false;
+	}
+
+	return true;
+}
+
+static bool policy_mgr_is_sap_go_allowed_with_ll_sap(
+					struct wlan_objmgr_psoc *psoc,
+					qdf_freq_t freq,
+					enum policy_mgr_con_mode mode)
+{
+	/**
+	 * Scenario: When ll SAP(whose profile is set as gaming or
+	 * lossless audio) is present on 5GHz channel and SAP/GO
+	 * is trying to come up.
+	 * Validate the ch_freq of SAP/GO for both DBS and SBS case
+	 */
+	if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) &&
+	    !policy_mgr_is_ll_sap_concurrency_valid(psoc, freq, mode))
+		return false;
+
+	return true;
+}
+
+bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
+				       enum policy_mgr_con_mode mode,
+				       uint32_t ch_freq,
+				       enum hw_mode_bandwidth bw,
+				       uint32_t ext_flags,
+				       struct policy_mgr_pcl_list *pcl)
+{
+	uint32_t num_connections = 0, count = 0, index = 0, i;
+	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;
+	bool go_force_scc;
+	enum channel_state chan_state;
+	bool is_dfs_ch = false;
+	struct ch_params ch_params;
+
+	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_rl_debug("dont allow concurrency if Sub 20 MHz is enabled");
+		return status;
+	}
+
+	if (policy_mgr_max_concurrent_connections_reached(psoc)) {
+		policy_mgr_rl_debug("Reached max concurrent connections: %d",
+				    pm_ctx->cfg.max_conc_cxns);
+		policy_mgr_validate_conn_info(psoc);
+		return status;
+	}
+
+	if (ch_freq) {
+		if (wlan_reg_is_5ghz_ch_freq(ch_freq)) {
+			qdf_mem_zero(&ch_params, sizeof(ch_params));
+			ch_params.ch_width = policy_mgr_get_ch_width(bw);
+			chan_state =
+			wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
+					pm_ctx->pdev, ch_freq,
+					&ch_params, REG_CURRENT_PWR_MODE);
+			if (chan_state == CHANNEL_STATE_DFS)
+				is_dfs_ch = true;
+		}
+		/* don't allow 3rd home channel on same MAC
+		 * also check for single mac target which doesn't
+		 * support interbad MCC as well
+		 */
+		if (!policy_mgr_allow_new_home_channel(psoc, mode, ch_freq,
+						       num_connections,
+						       is_dfs_ch,
+						       ext_flags))
+			return status;
+
+		/*
+		 * 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.
+		 * 4) On a single MAC device, if a SAP/P2PGO is already on a DFS
+		 *    channel, don't allow a 2 channel as it will result
+		 *    in MCC which is not allowed.
+		 */
+		if (!policy_mgr_is_5g_channel_allowed(psoc,
+			ch_freq, list, PM_P2P_GO_MODE))
+			return status;
+		if (!policy_mgr_is_5g_channel_allowed(psoc,
+			ch_freq, list, PM_SAP_MODE))
+			return status;
+		if (!policy_mgr_is_6g_channel_allowed(psoc, mode,
+						      ch_freq))
+			return status;
+
+		sta_sap_scc_on_dfs_chan =
+			policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+		go_force_scc = policy_mgr_go_scc_enforced(psoc);
+		if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) &&
+		    (!sta_sap_scc_on_dfs_chan ||
+		     !policy_mgr_is_sta_sap_scc(psoc, ch_freq) ||
+		     (!go_force_scc && mode == PM_P2P_GO_MODE))) {
+			if (is_dfs_ch)
+				match = policy_mgr_disallow_mcc(psoc,
+								ch_freq);
+		}
+		if (true == match) {
+			policy_mgr_rl_debug("No MCC, SAP/GO about to come up on DFS channel");
+			return status;
+		}
+		if ((policy_mgr_is_hw_dbs_capable(psoc) != true) &&
+		    num_connections) {
+			if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
+				if (policy_mgr_is_sap_p2pgo_on_dfs(psoc)) {
+					policy_mgr_rl_debug("MCC not allowed: SAP/P2PGO on DFS");
+					return status;
+				}
+			}
+		}
+	}
+
+	if (mode == PM_STA_MODE &&
+	    !policy_mgr_allow_sta_concurrency(psoc, ch_freq, ext_flags))
+		return status;
+
+	if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, ch_freq,
+						 WLAN_INVALID_VDEV_ID)) {
+		policy_mgr_rl_debug("This concurrency combination is not allowed");
+		return status;
+	}
+
+	/*
+	 * don't allow two P2P GO on same band, if fw doesn't
+	 * support p2p +p2p concurrency
+	 */
+	if (ch_freq && mode == PM_P2P_GO_MODE && num_connections &&
+	    !policy_mgr_is_p2p_p2p_conc_supported(psoc)) {
+		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_FREQS(
+			    ch_freq,
+			    pm_conc_connection_list[list[index]].freq)) {
+				policy_mgr_rl_debug("Don't allow P2P GO on same band");
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				return status;
+			}
+			index++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	}
+
+	if (!policy_mgr_allow_wapi_concurrency(pm_ctx)) {
+		policy_mgr_rl_debug("Don't allow new conn when wapi security conn existing");
+		return status;
+	}
+
+	/* Allow sta+p2p+p2p only if firmware supports the capability */
+	if (!policy_mgr_is_third_conn_sta_p2p_p2p_valid(psoc, mode)) {
+		policy_mgr_err("Don't allow third connection as GO or GC or STA with old fw");
+		return status;
+	}
+
+	/* Validate ll sap + sap/go concurrency */
+	if (!policy_mgr_is_sap_go_allowed_with_ll_sap(psoc, ch_freq, mode)) {
+		policy_mgr_err("LL SAP concurrency is not valid");
+		return status;
+	}
+
+	/*
+	 * Don't allow DFS SAP on non-SCC channels if an ML-STA is already
+	 * present. PCL list returns the SCC channels and all channels from
+	 * other MAC in case of non-ML/single link STA.
+	 */
+	if (mode == PM_SAP_MODE && pcl &&
+	    wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq)) {
+		for (i = 0; i < pcl->pcl_len; i++)
+			if (pcl->pcl_list[i] == ch_freq) {
+				status = true;
+				break;
+			}
+		if (!status) {
+			policy_mgr_err("SAP channel %d Not present in PCL",
+				       ch_freq);
+			return status;
+		}
+	}
+	status = true;
+
+	return status;
+}
+
+bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
+				  enum policy_mgr_con_mode mode,
+				  uint32_t ch_freq,
+				  enum hw_mode_bandwidth bw,
+				  uint32_t ext_flags, uint8_t vdev_id)
+{
+	QDF_STATUS status;
+	struct policy_mgr_pcl_list pcl;
+	bool allowed;
+
+	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), vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("disallow connection:%d", status);
+		return false;
+	}
+
+	allowed = policy_mgr_is_concurrency_allowed(psoc, mode, ch_freq,
+						    bw, ext_flags, &pcl);
+
+	/* Fourth connection concurrency check */
+	if (allowed && policy_mgr_get_connection_count(psoc) == 3)
+		allowed = policy_mgr_is_concurrency_allowed_4_port(
+				psoc,
+				mode,
+				ch_freq,
+				pcl);
+	return allowed;
+}
+
+bool
+policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
+				 enum policy_mgr_con_mode mode,
+				 uint32_t ch_freq, enum hw_mode_bandwidth bw,
+				 uint32_t vdev_id, bool forced,
+				 enum sap_csa_reason_code reason)
+{
+	bool allow = false;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t num_cxn_del = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t old_ch_freq, conc_ext_flags;
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return allow;
+	}
+	policy_mgr_debug("check concurrency_csa vdev:%d ch %d bw %d, forced %d, reason %d",
+			 vdev_id, ch_freq, bw, forced, reason);
+
+	status = policy_mgr_get_chan_by_session_id(psoc, vdev_id,
+						   &old_ch_freq);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Failed to get channel for vdev:%d",
+			       vdev_id);
+		return allow;
+	}
+	qdf_mem_zero(info, sizeof(info));
+
+	/*
+	 * 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.
+	 *
+	 * In SAP+SAP SCC case, when LTE unsafe event processing,
+	 * we should remove the all SAP conn entry on the same ch before
+	 * do the concurrency check. Otherwise the left SAP on old channel
+	 * will cause the concurrency check failure because of dual beacon
+	 * MCC not supported. for the CSA request reason code,
+	 * PM_CSA_REASON_UNSAFE_CHANNEL, we remove all the SAP
+	 * entry on old channel before do concurrency check.
+	 *
+	 * The assumption is both SAP should move to the new channel later for
+	 * the reason code.
+	 */
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+
+	if (forced && (reason == CSA_REASON_UNSAFE_CHANNEL ||
+		       reason == CSA_REASON_DCS))
+		policy_mgr_store_and_del_conn_info_by_chan_and_mode(
+			psoc, old_ch_freq, mode, info, &num_cxn_del);
+	else
+		policy_mgr_store_and_del_conn_info_by_vdev_id(
+			psoc, vdev_id, info, &num_cxn_del);
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false);
+	allow = policy_mgr_allow_concurrency(psoc, mode, ch_freq,
+					     bw, conc_ext_flags, vdev_id);
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	/* Restore the connection entry */
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (!allow)
+		policy_mgr_err("CSA concurrency check failed");
+
+	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_debug("concurrency_mode: 0x%x",
+			 pm_ctx->concurrency_mode);
+
+	return pm_ctx->concurrency_mode;
+}
+
+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 (!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;
+}
+
+bool policy_mgr_will_freq_lead_to_mcc(struct wlan_objmgr_psoc *psoc,
+				      qdf_freq_t freq)
+{
+	bool is_mcc = false;
+	uint32_t conn_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 is_mcc;
+	}
+
+	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 &&
+		    policy_mgr_2_freq_always_on_same_mac(psoc, freq,
+		     pm_conc_connection_list[conn_index].freq)) {
+			is_mcc = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return is_mcc;
+}
+
+/**
+ * policy_mgr_is_two_connection_mcc() - Check if MCC scenario
+ * when there are two connections
+ * @psoc: PSOC object information
+ *
+ * If if MCC scenario when there are two connections
+ *
+ * Return: true or false
+ */
+static bool policy_mgr_is_two_connection_mcc(struct wlan_objmgr_psoc *psoc)
+{
+	return ((pm_conc_connection_list[0].freq !=
+		 pm_conc_connection_list[1].freq) &&
+		(policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[0].freq,
+			pm_conc_connection_list[1].freq)) &&
+		(pm_conc_connection_list[0].freq <=
+		 WLAN_REG_MAX_24GHZ_CHAN_FREQ) &&
+		(pm_conc_connection_list[1].freq <=
+		 WLAN_REG_MAX_24GHZ_CHAN_FREQ)) ? 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].freq !=
+		  pm_conc_connection_list[1].freq) ||
+		 (pm_conc_connection_list[0].freq !=
+		  pm_conc_connection_list[2].freq) ||
+		 (pm_conc_connection_list[1].freq !=
+		  pm_conc_connection_list[2].freq)) &&
+		(pm_conc_connection_list[0].freq <=
+		 WLAN_REG_MAX_24GHZ_CHAN_FREQ) &&
+		(pm_conc_connection_list[1].freq <=
+		 WLAN_REG_MAX_24GHZ_CHAN_FREQ) &&
+		(pm_conc_connection_list[2].freq <=
+		 WLAN_REG_MAX_24GHZ_CHAN_FREQ)) ? true : false;
+}
+
+uint32_t policy_mgr_get_conc_vdev_on_same_mac(struct wlan_objmgr_psoc *psoc,
+					      uint32_t vdev_id, uint8_t mac_id)
+{
+	uint32_t id = WLAN_INVALID_VDEV_ID;
+	uint32_t conn_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 id;
+	}
+
+	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].vdev_id != vdev_id) &&
+		    (pm_conc_connection_list[conn_index].mac == mac_id)) {
+			id = pm_conc_connection_list[conn_index].vdev_id;
+			break;
+		}
+	}
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return id;
+}
+
+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(psoc))
+			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 vdev_id, uint32_t ch_freq)
+{
+	enum policy_mgr_con_mode mode;
+	bool ret;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	uint32_t conc_ext_flags;
+
+	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, vdev_id);
+		if (PM_MAX_NUM_OF_MODE == mode) {
+			policy_mgr_err("Invalid mode");
+			return false;
+		}
+	} else
+		return false;
+
+	if (ch_freq == 0) {
+		policy_mgr_err("Invalid channel number 0");
+		return false;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+
+	/* Take care of 160MHz and 80+80Mhz later */
+	conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false);
+	ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, HW_MODE_20_MHZ,
+					   conc_ext_flags, vdev_id);
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	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_debug("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_qdf_opmode_to_pm_con_mode(struct wlan_objmgr_psoc *psoc,
+				     enum QDF_OPMODE device_mode,
+				     uint8_t vdev_id)
+{
+	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:
+#ifdef WLAN_FEATURE_LL_LT_SAP
+		if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id))
+			mode = PM_LL_LT_SAP_MODE;
+		else
+#endif
+			mode = PM_SAP_MODE;
+		break;
+	case QDF_NAN_DISC_MODE:
+		mode = PM_NAN_DISC_MODE;
+		break;
+	case QDF_NDI_MODE:
+		mode = PM_NDI_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:
+	case PM_LL_LT_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_NAN_DISC_MODE:
+		mode = QDF_NAN_DISC_MODE;
+		break;
+	case PM_NDI_MODE:
+		mode = QDF_NDI_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
+ * 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]
+		> 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 (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;
+}
+
+bool policy_mgr_is_sta_present_on_dfs_channel(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *vdev_id,
+					      qdf_freq_t *ch_freq,
+					      enum hw_mode_bandwidth *ch_width)
+{
+	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 &&
+		    (conn_info->mode == PM_STA_MODE ||
+		     conn_info->mode == PM_P2P_CLIENT_MODE) &&
+		    (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, conn_info->freq) ||
+		     (wlan_reg_is_5ghz_ch_freq(conn_info->freq) &&
+		      conn_info->bw == HW_MODE_160_MHZ))) {
+			*vdev_id = conn_info->vdev_id;
+			*ch_freq = pm_conc_connection_list[conn_index].freq;
+			*ch_width = conn_info->bw;
+			status = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+bool policy_mgr_is_sta_present_on_freq(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *vdev_id,
+				       qdf_freq_t ch_freq,
+				       enum hw_mode_bandwidth *ch_width)
+{
+	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 &&
+		    (conn_info->mode == PM_STA_MODE ||
+		     conn_info->mode == PM_P2P_CLIENT_MODE) &&
+		    ch_freq == conn_info->freq) {
+			*vdev_id = conn_info->vdev_id;
+			*ch_width = conn_info->bw;
+			status = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+bool policy_mgr_is_sta_gc_active_on_mac(struct wlan_objmgr_psoc *psoc,
+					uint8_t mac_id)
+{
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t index, count;
+	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, PM_STA_MODE, list);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (index = 0; index < count; index++) {
+		if (mac_id == pm_conc_connection_list[list[index]].mac) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return true;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	count = policy_mgr_mode_specific_connection_count(
+		psoc, PM_P2P_CLIENT_MODE, list);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (index = 0; index < count; index++) {
+		if (mac_id == pm_conc_connection_list[list[index]].mac) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return true;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return false;
+}
+
+/**
+ * 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,
+					   uint32_t *ch_freq)
+{
+	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_for_freq(pm_ctx->pdev,
+		    pm_conc_connection_list[conn_index].freq)) {
+			*ch_freq = pm_conc_connection_list[conn_index].freq;
+			status = true;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+uint32_t policy_mgr_get_dfs_beaconing_session_id(
+		struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX;
+	struct policy_mgr_conc_connection_info *conn_info;
+	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 session_id;
+	}
+	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_5GHZ_CH_FREQ(conn_info->freq) &&
+		    (conn_info->ch_flagext & (IEEE80211_CHAN_DFS |
+					      IEEE80211_CHAN_DFS_CFREQ2)) &&
+		    (conn_info->mode == PM_SAP_MODE ||
+		     conn_info->mode == PM_P2P_GO_MODE)) {
+			session_id =
+				pm_conc_connection_list[conn_index].vdev_id;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return session_id;
+}
+
+bool policy_mgr_is_any_dfs_beaconing_session_present(
+		struct wlan_objmgr_psoc *psoc, qdf_freq_t *ch_freq,
+		enum hw_mode_bandwidth *ch_width)
+{
+	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 &&
+		    (conn_info->mode == PM_SAP_MODE ||
+		     conn_info->mode == PM_P2P_GO_MODE) &&
+		     (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, conn_info->freq) ||
+		      (wlan_reg_is_5ghz_ch_freq(conn_info->freq) &&
+		      conn_info->bw == HW_MODE_160_MHZ))) {
+			*ch_freq = pm_conc_connection_list[conn_index].freq;
+			*ch_width = conn_info->bw;
+			status = true;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc,
+					      qdf_freq_t *freq)
+{
+	qdf_freq_t dfs_ch_frq = 0;
+	qdf_freq_t dfs_sta_frq = 0;
+	uint8_t vdev_id;
+	enum hw_mode_bandwidth ch_width;
+	enum hw_mode_bandwidth ch_sta_width;
+	QDF_STATUS status;
+	uint8_t  sta_sap_scc_on_dfs_chnl;
+
+	policy_mgr_is_any_dfs_beaconing_session_present(psoc, &dfs_ch_frq,
+							&ch_width);
+	if (!dfs_ch_frq)
+		return false;
+
+	*freq = dfs_ch_frq;
+
+	status = policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc,
+						&sta_sap_scc_on_dfs_chnl);
+	if (QDF_IS_STATUS_ERROR(status))
+		return false;
+
+	if (policy_mgr_is_sta_present_on_dfs_channel(psoc, &vdev_id,
+						     &dfs_sta_frq,
+						     &ch_sta_width) &&
+	    !policy_mgr_is_hw_dbs_capable(psoc) &&
+	    sta_sap_scc_on_dfs_chnl != PM_STA_SAP_ON_DFS_DEFAULT) {
+		policymgr_nofl_err("DFS STA present vdev_id %d ch_feq %d ch_width %d",
+				   vdev_id, dfs_sta_frq, ch_sta_width);
+		return false;
+	}
+
+	/*
+	 * 1) if agile & DFS scans are supported
+	 * 2) if hardware is DBS capable
+	 * 3) if current hw mode is non-dbs
+	 * if all above 3 conditions are true then don't skip any
+	 * channel from scan list
+	 */
+	if (policy_mgr_is_hw_dbs_capable(psoc) &&
+	    !policy_mgr_is_current_hwmode_dbs(psoc) &&
+	    policy_mgr_get_dbs_plus_agile_scan_config(psoc) &&
+	    policy_mgr_get_single_mac_scan_with_dfs_config(psoc))
+		return false;
+
+	policy_mgr_debug("scan skip 5g chan due to dfs ap(ch %d / ch_width %d) present",
+			 dfs_ch_frq, ch_width);
+
+	return true;
+}
+
+static void
+policy_mgr_fill_trim_chan(struct wlan_objmgr_pdev *pdev,
+			  void *object, void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = object;
+	struct trim_chan_info *trim_info = arg;
+	uint16_t sap_peer_count = 0;
+	qdf_freq_t chan_freq;
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE)
+		return;
+
+	if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS)
+		return;
+
+	sap_peer_count = wlan_vdev_get_peer_count(vdev);
+	policy_mgr_debug("vdev %d - peer count %d",
+			 wlan_vdev_get_id(vdev), sap_peer_count);
+	if (sap_peer_count <= 1)
+		return;
+
+	chan_freq = wlan_get_operation_chan_freq(vdev);
+	if (!chan_freq)
+		return;
+
+	if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) {
+		trim_info->trim |= TRIM_CHANNEL_LIST_5G;
+	} else if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
+		if (trim_info->sap_count != 1)
+			return;
+
+		if ((trim_info->band_capability & BIT(REG_BAND_5G)) ==
+		     BIT(REG_BAND_5G))
+			return;
+
+		trim_info->trim |= TRIM_CHANNEL_LIST_24G;
+	}
+}
+
+uint16_t
+policy_mgr_scan_trim_chnls_for_connected_ap(struct wlan_objmgr_pdev *pdev)
+{
+	struct trim_chan_info trim_info;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return TRIM_CHANNEL_LIST_NONE;
+
+	status = wlan_mlme_get_band_capability(psoc,
+					       &trim_info.band_capability);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Could not get band capability");
+		return TRIM_CHANNEL_LIST_NONE;
+	}
+
+	trim_info.sap_count = policy_mgr_mode_specific_connection_count(psoc,
+							PM_SAP_MODE, NULL);
+	if (!trim_info.sap_count)
+		return TRIM_CHANNEL_LIST_NONE;
+
+	trim_info.trim = TRIM_CHANNEL_LIST_NONE;
+
+	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
+					  policy_mgr_fill_trim_chan, &trim_info,
+					  0, WLAN_POLICY_MGR_ID);
+	policy_mgr_debug("band_capability %d, sap_count %d, trim %d",
+			 trim_info.band_capability, trim_info.sap_count,
+			 trim_info.trim);
+
+	return trim_info.trim;
+}
+
+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++) {
+		if (!pm_conc_connection_list[i].in_use)
+			continue;
+		policy_mgr_debug("%d: use:%d vdev:%d mode:%d mac:%d freq:%d orig chainmask:%d orig nss:%d bw:%d, ch_flags %0X",
+				 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].freq,
+				 pm_conc_connection_list[i].chain_mask,
+				 pm_conc_connection_list[i].original_nss,
+				 pm_conc_connection_list[i].bw,
+				 pm_conc_connection_list[i].ch_flagext);
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	policy_mgr_dump_curr_freq_range(pm_ctx);
+	policy_mgr_validate_conn_info(psoc);
+}
+
+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_FREQ(
+			pm_conc_connection_list[i].freq))) {
+				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_FREQ(
+			pm_conc_connection_list[i].freq))) {
+				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;
+}
+
+enum phy_ch_width
+policy_mgr_get_bw_by_session_id(struct wlan_objmgr_psoc *psoc,
+				uint8_t session_id)
+{
+	uint32_t i;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum hw_mode_bandwidth bw = HW_MODE_BW_NONE;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return CH_WIDTH_INVALID;
+	}
+
+	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) {
+			bw = pm_conc_connection_list[i].bw;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	return policy_mgr_get_ch_width(bw);
+}
+
+QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc,
+					     uint8_t session_id,
+					     uint32_t *ch_freq)
+{
+	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)) {
+			*ch_freq = pm_conc_connection_list[i].freq;
+			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;
+}
+
+uint32_t policy_mgr_get_sap_go_count_on_mac(struct wlan_objmgr_psoc *psoc,
+					    uint32_t *list, uint8_t mac_id)
+{
+	uint32_t conn_index;
+	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 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].mac == mac_id &&
+		    pm_conc_connection_list[conn_index].in_use &&
+		    policy_mgr_is_beaconing_mode(
+				pm_conc_connection_list[conn_index].mode)) {
+			if (list)
+				list[count] =
+				    pm_conc_connection_list[conn_index].vdev_id;
+			count++;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+uint32_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc,
+					      uint8_t vdev_id)
+{
+	uint8_t mcc_vdev_id;
+	QDF_STATUS status;
+	uint32_t ch_freq;
+
+	if (!policy_mgr_is_mcc_with_this_vdev_id(psoc, vdev_id, &mcc_vdev_id)) {
+		policy_mgr_debug("No concurrent MCC vdev for id:%d", vdev_id);
+		return INVALID_CHANNEL_ID;
+	}
+
+	status = policy_mgr_get_chan_by_session_id(psoc, mcc_vdev_id, &ch_freq);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Failed to get channel for MCC vdev:%d",
+			       mcc_vdev_id);
+		return INVALID_CHANNEL_ID;
+	}
+
+	return ch_freq;
+}
+
+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);
+
+	if (roffchan)
+		policy_mgr_debug("Restrict offchannel is set");
+
+	return roffchan;
+}
+
+QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc,
+					  uint32_t ch_freq, bool *ok)
+{
+	uint32_t cc_count = 0, i;
+	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!ok) {
+		policy_mgr_err("Invalid parameter");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cc_count = policy_mgr_get_sap_mode_info(psoc,
+						&op_ch_freq_list[cc_count],
+						&vdev_id[cc_count]);
+
+	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
+		cc_count = cc_count +
+			   policy_mgr_get_mode_specific_conn_info(
+					psoc, &op_ch_freq_list[cc_count],
+					&vdev_id[cc_count], PM_P2P_GO_MODE);
+
+	if (!cc_count) {
+		*ok = true;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (!ch_freq) {
+		policy_mgr_err("channel is 0, cc count %d", cc_count);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		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, 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.
+			 */
+			if (policy_mgr_is_dnsc_set(vdev)) {
+				if (op_ch_freq_list[i] == ch_freq) {
+					*ok = true;
+					wlan_objmgr_vdev_release_ref(
+							vdev,
+							WLAN_POLICY_MGR_ID);
+					break;
+				} else if (policy_mgr_2_freq_always_on_same_mac(
+					   psoc,
+					   op_ch_freq_list[i], ch_freq)) {
+					*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);
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_get_hw_dbs_max_bw(struct wlan_objmgr_psoc *psoc,
+				  struct dbs_bw *bw_dbs)
+{
+	uint32_t dbs, sbs, 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];
+		dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param);
+		sbs = POLICY_MGR_HW_MODE_SBS_MODE_GET(param);
+
+		if (!dbs && !sbs)
+			bw_dbs->mac0_bw =
+				POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param);
+
+		if (dbs) {
+			bw_dbs->mac0_bw =
+				POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param);
+			bw_dbs->mac1_bw =
+				POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param);
+		} else {
+			continue;
+		}
+	}
+}
+
+uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc,
+				   struct dbs_nss *nss_dbs)
+{
+	int i, param;
+	uint32_t dbs, sbs, 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;
+	}
+
+	nss_dbs->single_mac0_band_cap = 0;
+	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);
+		sbs = POLICY_MGR_HW_MODE_SBS_MODE_GET(param);
+
+		if (!dbs && !sbs && !nss_dbs->single_mac0_band_cap)
+			nss_dbs->single_mac0_band_cap =
+				POLICY_MGR_HW_MODE_MAC0_BAND_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)
+{
+	uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
+
+	policy_mgr_get_dual_mac_feature(psoc, &dual_mac_feature);
+	if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
+	    (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN) ||
+	    (dual_mac_feature ==
+	     ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN) ||
+	     !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("dual_mac_disable_ini:%d ",
+				 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_sap_allowed_on_dfs_freq(struct wlan_objmgr_pdev *pdev,
+					   uint8_t vdev_id, qdf_freq_t ch_freq)
+{
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t sta_sap_scc_on_dfs_chan;
+	uint32_t sta_cnt, gc_cnt, idx;
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	struct wlan_objmgr_vdev *vdev;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return false;
+
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+	sta_cnt = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							 vdev_id_list,
+							 PM_STA_MODE);
+
+	if (sta_cnt >= MAX_NUMBER_OF_CONC_CONNECTIONS)
+		return false;
+
+	gc_cnt = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							&vdev_id_list[sta_cnt],
+							PM_P2P_CLIENT_MODE);
+
+	policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_cnt %u, gc_cnt %u",
+			 sta_sap_scc_on_dfs_chan, sta_cnt, gc_cnt);
+
+	/* if sta_sap_scc_on_dfs_chan ini is set, DFS master capability is
+	 * assumed disabled in the driver.
+	 */
+	if ((wlan_reg_get_channel_state_for_pwrmode(
+		pdev, ch_freq, REG_CURRENT_PWR_MODE) == CHANNEL_STATE_DFS) &&
+	    !sta_cnt && !gc_cnt && sta_sap_scc_on_dfs_chan &&
+	    !policy_mgr_get_dfs_master_dynamic_enabled(psoc, vdev_id)) {
+		policy_mgr_err("SAP not allowed on DFS channel if no dfs master capability!!");
+		return false;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+						    vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("Invalid vdev");
+		return false;
+	}
+	/* Allow the current CSA to continue if it's already started. This is
+	 * possible when SAP CSA started to move to STA channel but STA got
+	 * disconnected.
+	 */
+	if (!wlan_vdev_mlme_is_init_state(vdev) &&
+	    !wlan_vdev_is_up_active_state(vdev)) {
+		policy_mgr_debug("SAP is not yet UP: vdev %d", vdev_id);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return true;
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	/*
+	 * Check if any of the concurrent STA/ML-STA link/P2P client are in
+	 * disconnecting state and disallow current SAP CSA. Concurrencies
+	 * would be re-evaluated upon disconnect completion and SAP would be
+	 * moved to right channel.
+	 */
+	for (idx = 0; idx < sta_cnt + gc_cnt; idx++) {
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+							    vdev_id_list[idx],
+							    WLAN_POLICY_MGR_ID);
+		if (!vdev) {
+			policy_mgr_err("Invalid vdev");
+			return false;
+		}
+		if (wlan_cm_is_vdev_disconnecting(vdev) ||
+		    mlo_is_any_link_disconnecting(vdev)) {
+			policy_mgr_err("SAP is not allowed to move to DFS channel at this time, vdev %d",
+				       vdev_id_list[idx]);
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+			return false;
+		}
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	}
+
+	return true;
+}
+
+bool
+policy_mgr_is_sap_go_interface_allowed_on_indoor(struct wlan_objmgr_pdev *pdev,
+						 uint8_t vdev_id,
+						 qdf_freq_t ch_freq)
+{
+	struct wlan_objmgr_psoc *psoc;
+	bool is_scc = false, indoor_support = false;
+	enum QDF_OPMODE mode;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return true;
+
+	if (!wlan_reg_is_freq_indoor(pdev, ch_freq))
+		return true;
+
+	is_scc = policy_mgr_is_sta_sap_scc(psoc, ch_freq);
+	mode = wlan_get_opmode_from_vdev_id(pdev, vdev_id);
+	ucfg_mlme_get_indoor_channel_support(psoc, &indoor_support);
+
+	/*
+	 * Rules for indoor operation:
+	 * If gindoor_channel_support is enabled - Allow SAP/GO
+	 * If gindoor_channel_support is disabled
+	 *      a) Restrict 6 GHz SAP
+	 *      b) Restrict standalone 5 GHz SAP
+	 *
+	 * If p2p_go_on_5ghz_indoor_chan is enabled - Allow GO
+	 * with or without concurrency
+	 *
+	 * If sta_sap_scc_on_indoor_chan is enabled - Allow
+	 * SAP/GO with concurrent STA in indoor SCC
+	 *
+	 * Restrict all other operations on indoor
+	 */
+
+	if (indoor_support)
+		return true;
+
+	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) {
+		policy_mgr_rl_debug("SAP operation is not allowed on 6 GHz indoor channel");
+		return false;
+	}
+
+	if (mode == QDF_SAP_MODE) {
+		if (is_scc &&
+		    policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc))
+			return true;
+		policy_mgr_rl_debug("SAP operation is not allowed on indoor channel");
+		return false;
+	}
+
+	if (mode == QDF_P2P_GO_MODE) {
+		if (ucfg_p2p_get_indoor_ch_support(psoc) ||
+		    (is_scc &&
+		    policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc)))
+			return true;
+		policy_mgr_rl_debug("GO operation is not allowed on indoor channel");
+		return false;
+	}
+
+	policy_mgr_rl_debug("SAP operation is not allowed on indoor channel");
+	return false;
+}
+
+bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
+		struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t sta_sap_scc_on_dfs_chnl = 0;
+	bool status = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc,
+					       &sta_sap_scc_on_dfs_chnl);
+	if (policy_mgr_is_force_scc(psoc) && sta_sap_scc_on_dfs_chnl)
+		status = true;
+
+	return status;
+}
+
+bool policy_mgr_is_multi_sap_allowed_on_same_band(
+					struct wlan_objmgr_pdev *pdev,
+					enum policy_mgr_con_mode mode,
+					qdf_freq_t ch_freq)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool multi_sap_allowed_on_same_band;
+	QDF_STATUS status;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	if (!ch_freq || !policy_mgr_is_sap_mode(mode))
+		return true;
+
+	status = policy_mgr_get_multi_sap_allowed_on_same_band(psoc,
+					&multi_sap_allowed_on_same_band);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		policy_mgr_err("Failed to get multi_sap_allowed_on_same_band");
+		/* Allow multi SAPs started on same band by default. */
+		multi_sap_allowed_on_same_band = true;
+	}
+	if (!multi_sap_allowed_on_same_band) {
+		uint32_t ap_cnt, index = 0;
+		uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+		struct policy_mgr_conc_connection_info *ap_info;
+
+		ap_cnt = policy_mgr_get_sap_mode_count(psoc, list);
+		if (!ap_cnt)
+			return true;
+
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		while (index < ap_cnt) {
+			ap_info = &pm_conc_connection_list[list[index]];
+			if (WLAN_REG_IS_SAME_BAND_FREQS(ch_freq,
+							ap_info->freq)) {
+				policy_mgr_rl_debug("Don't allow SAP on same band");
+				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+				return false;
+			}
+			index++;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	}
+
+	return true;
+}
+
+bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc,
+					  enum policy_mgr_con_mode mode)
+{
+	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 == mode &&
+		    pm_conc_connection_list[conn_index].freq >=
+					WLAN_REG_MIN_5GHZ_CHAN_FREQ &&
+		    pm_conc_connection_list[conn_index].in_use)
+			ret = true;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return ret;
+}
+
+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].freq <=
+				WLAN_REG_MAX_24GHZ_CHAN_FREQ &&
+		    pm_conc_connection_list[conn_index].in_use)
+			ret = true;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return ret;
+}
+
+bool
+policy_mgr_is_connected_sta_5g(struct wlan_objmgr_psoc *psoc, qdf_freq_t *freq)
+{
+	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++) {
+		*freq = pm_conc_connection_list[conn_index].freq;
+		if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(*freq) &&
+		    pm_conc_connection_list[conn_index].in_use) {
+			ret = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return ret;
+}
+
+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;
+	}
+	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_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 = wlan_reg_freq_to_chan(
+				pm_ctx->pdev,
+				pm_conc_connection_list[conn_index].freq);
+			info[count].ch_freq =
+				pm_conc_connection_list[conn_index].freq;
+			count++;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return count;
+}
+
+bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc,
+					 enum policy_mgr_con_mode mode,
+					 uint32_t ch_freq,
+					 uint32_t vdev_id)
+{
+	enum policy_mgr_con_mode con_mode;
+	int id;
+	uint32_t vdev, con_freq;
+	bool dbs;
+
+	if (mode != PM_SAP_MODE && mode != PM_P2P_GO_MODE)
+		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_freq = pm_conc_connection_list[id].freq;
+
+		if (policy_mgr_is_p2p_p2p_conc_supported(psoc) &&
+		    (mode == PM_P2P_GO_MODE) && (con_mode == PM_P2P_GO_MODE)) {
+			policy_mgr_debug("GO+GO scc is allowed freq = %d ",
+					 ch_freq);
+			return true;
+		}
+
+		if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc) &&
+		    (mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) &&
+		    (con_mode == PM_SAP_MODE || con_mode == PM_P2P_GO_MODE))
+			return true;
+
+		if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc) &&
+		    (ch_freq == con_freq)) {
+			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 (policy_mgr_are_2_freq_on_same_mac(psoc, ch_freq,
+						      con_freq)) {
+			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;
+	uint8_t scc_lte_coex = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+	policy_mgr_get_sta_sap_scc_lte_coex_chnl(psoc, &scc_lte_coex);
+
+	return scc_lte_coex;
+}
+
+#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)
+void policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id,
+				     enum conn_6ghz_flag ap_6ghz_capable)
+{
+	struct policy_mgr_conc_connection_info *conn_info;
+	uint32_t conn_index;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum conn_6ghz_flag conn_6ghz_flag = 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++) {
+		conn_info = &pm_conc_connection_list[conn_index];
+		if (conn_info->in_use &&
+		    policy_mgr_is_sap_mode(conn_info->mode) &&
+		    vdev_id == conn_info->vdev_id) {
+			conn_info->conn_6ghz_flag = ap_6ghz_capable;
+			conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID;
+			conn_6ghz_flag = conn_info->conn_6ghz_flag;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_debug("vdev %d init conn_6ghz_flag %x new %x",
+			 vdev_id, ap_6ghz_capable, conn_6ghz_flag);
+}
+
+void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id,
+				    bool set,
+				    enum conn_6ghz_flag ap_6ghz_capable)
+{
+	struct policy_mgr_conc_connection_info *conn_info;
+	uint32_t conn_index;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum conn_6ghz_flag conn_6ghz_flag = 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++) {
+		conn_info = &pm_conc_connection_list[conn_index];
+		if (conn_info->in_use &&
+		    policy_mgr_is_beaconing_mode(conn_info->mode) &&
+		    policy_mgr_is_6ghz_conc_mode_supported(
+						psoc, conn_info->mode) &&
+		    vdev_id == conn_info->vdev_id) {
+			if (set)
+				conn_info->conn_6ghz_flag |= ap_6ghz_capable;
+			else
+				conn_info->conn_6ghz_flag &= ~ap_6ghz_capable;
+			conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID;
+			conn_6ghz_flag = conn_info->conn_6ghz_flag;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_debug("vdev %d %s conn_6ghz_flag %x new %x",
+			 vdev_id, set ? "set" : "clr",
+			 ap_6ghz_capable, conn_6ghz_flag);
+}
+
+bool policy_mgr_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id,
+				    uint32_t *conn_flag)
+{
+	struct policy_mgr_conc_connection_info *conn_info;
+	uint32_t conn_index;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum conn_6ghz_flag conn_6ghz_flag = 0;
+	bool is_6g_allowed = false;
+
+	if (conn_flag)
+		*conn_flag = 0;
+	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 &&
+		    policy_mgr_is_beaconing_mode(conn_info->mode) &&
+		    policy_mgr_is_6ghz_conc_mode_supported(
+						psoc, conn_info->mode) &&
+		    vdev_id == conn_info->vdev_id) {
+			conn_6ghz_flag = conn_info->conn_6ghz_flag;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	/* If the vdev connection is not active, policy mgr will query legacy
+	 * hdd to get sap acs and security information.
+	 * The assumption is no legacy client connected for non active
+	 * connection.
+	 */
+	if (!(conn_6ghz_flag & CONN_6GHZ_FLAG_VALID) &&
+	    pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable)
+		conn_6ghz_flag = pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable(
+					psoc, vdev_id) |
+					CONN_6GHZ_FLAG_NO_LEGACY_CLIENT;
+
+	if ((conn_6ghz_flag & CONN_6GHZ_CAPABLE) == CONN_6GHZ_CAPABLE)
+		is_6g_allowed = true;
+	policy_mgr_debug("vdev %d conn_6ghz_flag %x 6ghz %s", vdev_id,
+			 conn_6ghz_flag, is_6g_allowed ? "allowed" : "deny");
+	if (conn_flag)
+		*conn_flag = conn_6ghz_flag;
+
+	return is_6g_allowed;
+}
+#endif
+
+bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc,
+			       uint32_t sap_freq)
+{
+	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;
+	}
+
+	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 ||
+				pm_conc_connection_list[conn_index].mode ==
+				PM_P2P_CLIENT_MODE) && (sap_freq ==
+				pm_conc_connection_list[conn_index].freq)) {
+			is_scc = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return is_scc;
+}
+
+bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t mcc_to_scc_switch;
+	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;
+	}
+	mcc_to_scc_switch = policy_mgr_get_mcc_to_scc_switch_mode(psoc);
+	if (mcc_to_scc_switch ==
+	    QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)
+		return true;
+
+	if (pm_ctx->cfg.go_force_scc && policy_mgr_is_force_scc(psoc))
+		return true;
+
+	return false;
+}
+
+uint8_t
+policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id, uint32_t freq,
+				   enum policy_mgr_con_mode *mode,
+				   uint32_t *existing_con_freq,
+				   enum phy_ch_width *existing_ch_width)
+{
+	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 WLAN_UMAC_VDEV_ID_MAX;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		if ((policy_mgr_is_beaconing_mode(
+				pm_conc_connection_list[conn_index].mode) ||
+		    pm_conc_connection_list[conn_index].mode ==
+		    PM_P2P_CLIENT_MODE ||
+		    pm_conc_connection_list[conn_index].mode ==
+		    PM_STA_MODE) &&
+		    pm_conc_connection_list[conn_index].in_use &&
+		    policy_mgr_are_2_freq_on_same_mac(
+			psoc, freq, pm_conc_connection_list[conn_index].freq) &&
+		    freq != pm_conc_connection_list[conn_index].freq &&
+		    vdev_id != pm_conc_connection_list[conn_index].vdev_id) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			policy_mgr_debug(
+				"Existing vdev_id for mode %d is %d",
+				pm_conc_connection_list[conn_index].mode,
+				pm_conc_connection_list[conn_index].vdev_id);
+			*mode = pm_conc_connection_list[conn_index].mode;
+			*existing_con_freq =
+				pm_conc_connection_list[conn_index].freq;
+			*existing_ch_width = policy_mgr_get_ch_width(
+					pm_conc_connection_list[conn_index].bw);
+			return pm_conc_connection_list[conn_index].vdev_id;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return WLAN_UMAC_VDEV_ID_MAX;
+}
+
+#ifdef WLAN_FEATURE_P2P_P2P_STA
+bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool ret = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		ret = false;
+		goto return_val;
+	}
+	if (pm_ctx->cfg.go_force_scc & GO_FORCE_SCC_STRICT) {
+		ret = true;
+		goto return_val;
+	}
+	ret = false;
+return_val:
+	policy_mgr_debug("ret val is %d", ret);
+	return ret;
+}
+#endif
+
+QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc,
+					       uint8_t nan_vdev_id,
+					       uint8_t mac_id)
+{
+	struct policy_mgr_hw_mode_params hw_mode = {0};
+	struct policy_mgr_vdev_mac_map vdev_mac_map = {0};
+	QDF_STATUS status;
+
+	vdev_mac_map.vdev_id = nan_vdev_id;
+	vdev_mac_map.mac_id = mac_id;
+
+	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
+
+	if (QDF_IS_STATUS_SUCCESS(status))
+		policy_mgr_update_hw_mode_conn_info(psoc, 1, &vdev_mac_map,
+						    hw_mode, 0, NULL);
+
+	return status;
+}
+
+bool policy_mgr_is_sap_go_on_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_SAP_MODE ||
+		     pm_conc_connection_list[conn_index].mode == PM_P2P_GO_MODE) &&
+			 pm_conc_connection_list[conn_index].freq <=
+				WLAN_REG_MAX_24GHZ_CHAN_FREQ &&
+			 pm_conc_connection_list[conn_index].in_use)
+			ret = true;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return ret;
+}
+
+static inline bool
+policy_mgr_is_chan_eligible_for_sap(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				    uint8_t vdev_id, qdf_freq_t freq)
+{
+	struct wlan_objmgr_vdev *vdev;
+	enum channel_state ch_state;
+	enum reg_6g_ap_type sta_connected_pwr_type;
+	uint32_t ap_power_type_6g = 0;
+	bool is_eligible = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev)
+		return false;
+
+	ch_state = wlan_reg_get_channel_state_for_pwrmode(pm_ctx->pdev,
+							  freq,
+							  REG_CURRENT_PWR_MODE);
+	sta_connected_pwr_type = mlme_get_best_6g_power_type(vdev);
+	wlan_reg_get_cur_6g_ap_pwr_type(pm_ctx->pdev, &ap_power_type_6g);
+
+	/*
+	 * If the SAP user configured frequency is 6 GHz,
+	 * move the SAP to STA SCC in 6 GHz only if:
+	 * a) The channel is PSC
+	 * b) The channel supports AP in VLP power type
+	 * c) The DUT is configured to operate SAP in VLP only
+	 * d) The STA is connected to the 6 GHz AP in
+	 *    either VLP or LPI.
+	 *    - If the STA is in LPI, then lim_update_tx_power()
+	 *	would move the STA to VLP.
+	 */
+	if (WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(freq) &&
+	    ap_power_type_6g == REG_VERY_LOW_POWER_AP &&
+	    ch_state == CHANNEL_STATE_ENABLE &&
+	    (sta_connected_pwr_type == REG_VERY_LOW_POWER_AP ||
+	     sta_connected_pwr_type == REG_INDOOR_AP))
+		is_eligible = true;
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	return is_eligible;
+}
+
+bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id,
+					qdf_freq_t freq,
+					tQDF_MCC_TO_SCC_SWITCH_MODE scc_mode)
+{
+	uint8_t i;
+	bool restart_required = false;
+	bool is_sta_p2p_cli;
+	bool sap_on_dfs = false;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_conc_connection_info *connection;
+	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_allowed_on_indoor_ch;
+	qdf_freq_t user_config_freq;
+	bool sap_found = false;
+	uint8_t num_mcc_conn = 0;
+	uint8_t num_scc_conn = 0;
+	uint8_t num_5_or_6_conn = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid psoc");
+		return false;
+	}
+
+	if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) {
+		if (policy_mgr_is_ll_lt_sap_restart_required(psoc))
+			return true;
+		return false;
+	}
+
+	if (scc_mode == QDF_MCC_TO_SCC_SWITCH_DISABLE) {
+		policy_mgr_debug("No scc required");
+		return false;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	connection = pm_conc_connection_list;
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if (!connection[i].in_use)
+			continue;
+		if (connection[i].vdev_id == vdev_id) {
+			if (WLAN_REG_IS_5GHZ_CH_FREQ(connection[i].freq) &&
+			    (connection[i].ch_flagext & (IEEE80211_CHAN_DFS |
+					      IEEE80211_CHAN_DFS_CFREQ2)))
+				sap_on_dfs = true;
+			sap_found = true;
+		} else {
+			if (connection[i].freq == freq)
+				num_scc_conn++;
+			else
+				num_mcc_conn++;
+
+			if (!WLAN_REG_IS_24GHZ_CH_FREQ(connection[i].freq))
+				num_5_or_6_conn++;
+		}
+	}
+	if (!sap_found) {
+		policy_mgr_err("Invalid vdev id: %d", vdev_id);
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		return false;
+	}
+	/* Current hw mode is SBS low share. STA 5180, SAP 1 2412,
+	 * SAP 2 5745, but SAP 1 is 2G only, can't move to STA 5180,
+	 * SAP 2 is SBS with STA, policy_mgr_are_2_freq_on_same_mac
+	 * return false for 5745 and 5180 and finally this function
+	 * return false, no force SCC on SAP2.
+	 * Add mcc conntion count check for SAP2, if SAP 2 channel
+	 * is different from all of exsting 2 or more connections, then
+	 * try to force SCC on SAP 2.
+	 */
+	if (num_mcc_conn > 1 && !num_scc_conn) {
+		policy_mgr_debug("sap vdev %d has chan %d diff with %d exsting conn",
+				 vdev_id, freq, num_mcc_conn);
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		return true;
+	}
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+
+	sta_sap_scc_allowed_on_indoor_ch =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if (!connection[i].in_use)
+			continue;
+
+		if (scc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL &&
+		    connection[i].mode == PM_P2P_GO_MODE &&
+		    connection[i].vdev_id != vdev_id &&
+		    policy_mgr_2_freq_always_on_same_mac(psoc, freq,
+							 connection[i].freq)) {
+			policy_mgr_debug("SAP:%d and GO:%d on same mac. Restart SAP ",
+					 freq, connection[i].freq);
+			restart_required = true;
+			break;
+		}
+
+		is_sta_p2p_cli =
+			(connection[i].mode == PM_STA_MODE ||
+			 connection[i].mode == PM_P2P_CLIENT_MODE);
+		if (!is_sta_p2p_cli)
+			continue;
+
+		if (connection[i].freq != freq &&
+		    policy_mgr_are_2_freq_on_same_mac(psoc, freq,
+						      connection[i].freq)) {
+			policy_mgr_debug("SAP:%d and STA:%d on same mac. Restart SAP ",
+					 freq, connection[i].freq);
+			restart_required = true;
+			break;
+		}
+		if (connection[i].freq == freq &&
+		    !sta_sap_scc_on_dfs_chan && sap_on_dfs) {
+			policy_mgr_debug("Move SAP out of DFS ch:%d", freq);
+			restart_required = true;
+			break;
+		}
+
+		if (connection[i].freq == freq &&
+		    !sta_sap_scc_allowed_on_indoor_ch &&
+		    wlan_reg_is_freq_indoor(pm_ctx->pdev, connection[i].freq)) {
+			policy_mgr_debug("Move SAP out of indoor ch:%d", freq);
+			restart_required = true;
+			break;
+		}
+
+		/*
+		 * Existing connection:
+		 * 1. "STA in DFS ch and SoftAP in 2.4 GHz channel, and then
+		 * STA moves to 5 GHz non-DFS channel
+		 *
+		 * 2. "STA in indoor channel and sta_sap_scc_on_indoor_ch
+		 * ini is false & SAP has moved to 2.4 GHz channel"
+		 * STA moves back to 5 GHZ non indoor/non DFS channel
+		 *
+		 * Now SAP has to move to STA 5 GHz channel if SAP
+		 * was started on 5 GHz channel initially.
+		 */
+		user_config_freq =
+			policy_mgr_get_user_config_sap_freq(psoc, vdev_id);
+
+		if (connection[i].freq != freq &&
+		    WLAN_REG_IS_24GHZ_CH_FREQ(freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(connection[i].freq) &&
+		    !wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
+					      connection[i].freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(user_config_freq)) {
+			policy_mgr_debug("Move SAP from:%d to STA ch:%d  (sap start freq:%d)",
+					 freq, connection[i].freq,
+					 user_config_freq);
+			restart_required = true;
+
+			if (wlan_reg_is_freq_indoor(pm_ctx->pdev,
+						    connection[i].freq) &&
+			    !sta_sap_scc_allowed_on_indoor_ch)
+				restart_required = false;
+			break;
+		}
+
+		/*
+		 * SAP has to move away from indoor only channel
+		 * when STA moves out of indoor only channel and
+		 * SAP standalone support on indoor only
+		 * channel ini is disabled
+		 **/
+		if (connection[i].freq != freq &&
+		    WLAN_REG_IS_24GHZ_CH_FREQ(connection[i].freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(freq) &&
+		    !policy_mgr_is_sap_go_interface_allowed_on_indoor(
+							pm_ctx->pdev,
+							vdev_id, freq)) {
+			policy_mgr_debug("SAP in indoor freq: sta:%d sap:%d",
+					 connection[i].freq, freq);
+			restart_required = true;
+		}
+
+		if (scc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL &&
+		    WLAN_REG_IS_24GHZ_CH_FREQ(freq) && user_config_freq) {
+			if (connection[i].freq == freq && !num_5_or_6_conn &&
+			    !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq)) {
+				policy_mgr_debug("SAP move to user configure %d from %d",
+						 user_config_freq, freq);
+				restart_required = true;
+			} else if (connection[i].freq != freq &&
+				   WLAN_REG_IS_6GHZ_CHAN_FREQ(user_config_freq) &&
+				   policy_mgr_is_chan_eligible_for_sap(pm_ctx,
+								       connection[i].vdev_id,
+								       connection[i].freq)) {
+				policy_mgr_debug("Move SAP to STA 6 GHz channel");
+				restart_required = true;
+			}
+		}
+	}
+
+	if (!restart_required &&
+	    policy_mgr_is_restart_sap_required_with_mlo_sta(
+					psoc, vdev_id, freq))
+		restart_required = true;
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return restart_required;
+}
+
+uint8_t policy_mgr_get_roam_enabled_sta_session_id(
+					struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id)
+{
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t index, count;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_vdev *vdev, *assoc_vdev;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return WLAN_UMAC_VDEV_ID_MAX;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("Invalid vdev");
+		return WLAN_UMAC_VDEV_ID_MAX;
+	}
+
+	if (wlan_vdev_mlme_is_link_sta_vdev(vdev)) {
+		assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
+		if (assoc_vdev && ucfg_cm_is_vdev_active(assoc_vdev)) {
+			policy_mgr_debug("replace link vdev %d with assoc vdev %d",
+					 vdev_id, wlan_vdev_get_id(assoc_vdev));
+			vdev_id = wlan_vdev_get_id(assoc_vdev);
+		}
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	count = policy_mgr_mode_specific_connection_count(
+		psoc, PM_STA_MODE, list);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+
+	for (index = 0; index < count; index++) {
+		if (vdev_id == pm_conc_connection_list[list[index]].vdev_id)
+			continue;
+		if (MLME_IS_ROAM_INITIALIZED(
+			psoc, pm_conc_connection_list[list[index]].vdev_id)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return pm_conc_connection_list[list[index]].vdev_id;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return WLAN_UMAC_VDEV_ID_MAX;
+}
+
+bool policy_mgr_is_sta_mon_concurrency(struct wlan_objmgr_psoc *psoc)
+{
+	uint32_t conc_mode;
+
+	if (wlan_mlme_is_sta_mon_conc_supported(psoc)) {
+		conc_mode = policy_mgr_get_concurrency_mode(psoc);
+		if (conc_mode & QDF_STA_MASK &&
+		    conc_mode & QDF_MONITOR_MASK) {
+			policy_mgr_err("STA + MON mode is UP");
+			return true;
+		}
+	}
+	return false;
+}
+
+QDF_STATUS policy_mgr_check_mon_concurrency(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t num_open_session = 0;
+
+	if (policy_mgr_mode_specific_num_open_sessions(
+				psoc,
+				QDF_MONITOR_MODE,
+				&num_open_session) != QDF_STATUS_SUCCESS)
+		return QDF_STATUS_E_INVAL;
+
+	if (num_open_session) {
+		policy_mgr_err("monitor mode already exists, only one is possible");
+		return QDF_STATUS_E_BUSY;
+	}
+
+	num_open_session = policy_mgr_get_sap_mode_count(psoc, NULL);
+
+	if (num_open_session) {
+		policy_mgr_err("cannot add monitor mode, due to SAP concurrency");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	num_open_session = policy_mgr_mode_specific_connection_count(
+					psoc,
+					PM_P2P_CLIENT_MODE,
+					NULL);
+
+	if (num_open_session) {
+		policy_mgr_err("cannot add monitor mode, due to P2P CLIENT concurrency");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	num_open_session = policy_mgr_mode_specific_connection_count(
+					psoc,
+					PM_P2P_GO_MODE,
+					NULL);
+
+	if (num_open_session) {
+		policy_mgr_err("cannot add monitor mode, due to P2P GO concurrency");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	num_open_session = policy_mgr_mode_specific_connection_count(
+					psoc,
+					PM_NAN_DISC_MODE,
+					NULL);
+
+	if (num_open_session) {
+		policy_mgr_err("cannot add monitor mode, due to NAN concurrency");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_is_hwmode_offload_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct wmi_unified *wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		policy_mgr_err("Invalid WMI handle");
+		return false;
+	}
+
+	return wmi_service_enabled(wmi_handle,
+				   wmi_service_hw_mode_policy_offload_support);
+}
+
+bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
+				   struct wlan_objmgr_pdev *pdev,
+				   struct wlan_objmgr_vdev *vdev,
+				   uint32_t ch_freq,
+				   enum phy_ch_width ch_width,
+				   uint8_t *con_vdev_id,
+				   uint32_t *con_freq)
+{
+	enum QDF_OPMODE mode;
+	enum policy_mgr_con_mode con_mode;
+	union conc_ext_flag conc_ext_flags;
+	uint32_t cc_count, i, j, ap_index;
+	uint32_t op_freq[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
+	QDF_STATUS status;
+	struct policy_mgr_pcl_list pcl;
+
+	if (!psoc || !vdev || !pdev) {
+		policy_mgr_debug("psoc or vdev or pdev is NULL");
+		return false;
+	}
+
+	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
+							  &op_freq[0],
+							  &vdev_id[0],
+							  PM_SAP_MODE);
+	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
+		cc_count = cc_count +
+				policy_mgr_get_mode_specific_conn_info(
+					psoc,
+					&op_freq[cc_count],
+					&vdev_id[cc_count],
+					PM_P2P_GO_MODE);
+	if (!cc_count)
+		return true;
+
+	mode = wlan_vdev_mlme_get_opmode(vdev);
+	con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(
+				psoc, mode, wlan_vdev_get_id(vdev));
+	qdf_mem_zero(&pcl, sizeof(pcl));
+	status = policy_mgr_get_pcl(psoc, con_mode, pcl.pcl_list, &pcl.pcl_len,
+				    pcl.weight_list,
+				    QDF_ARRAY_SIZE(pcl.weight_list),
+				    wlan_vdev_get_id(vdev));
+	if (!pcl.pcl_len)
+		return true;
+	ap_index = cc_count;
+	for (i = 0 ; i < pcl.pcl_len; i++) {
+		for (j = 0; j < cc_count; j++) {
+			if (op_freq[j] == pcl.pcl_list[i])
+				break;
+		}
+		if (j >= cc_count)
+			continue;
+		if (ch_freq == op_freq[j]) {
+			ap_index = j;
+			break;
+		}
+		if (!policy_mgr_is_hw_dbs_capable(psoc)) {
+			ap_index = j;
+			break;
+		}
+		if (wlan_reg_is_same_band_freqs(ch_freq, op_freq[j]) &&
+		    !policy_mgr_are_sbs_chan(psoc, ch_freq, op_freq[j])) {
+			ap_index = j;
+			break;
+		}
+		if (wlan_reg_is_same_band_freqs(ch_freq, op_freq[j]) &&
+		    policy_mgr_get_connection_count(psoc) > 2) {
+			ap_index = j;
+			break;
+		}
+	}
+	/* If same band MCC SAP/GO not present, return true,
+	 * no AP to AP channel override
+	 */
+	if (ap_index >= cc_count)
+		return true;
+
+	*con_freq = op_freq[ap_index];
+	*con_vdev_id = vdev_id[ap_index];
+	/*
+	 * For 3Vif concurrency we only support SCC in same MAC
+	 * in below combination:
+	 * 2 beaconing entities with STA in SCC.
+	 * 3 beaconing entities in SCC.
+	 */
+	conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
+	if (!policy_mgr_allow_concurrency(
+			psoc, con_mode, ch_freq,
+			policy_mgr_get_bw(ch_width),
+			conc_ext_flags.value,
+			wlan_vdev_get_id(vdev))) {
+		policy_mgr_debug("AP AP mcc not allowed, try to override 2nd SAP/GO chan");
+		return false;
+	}
+	/* For SCC case & bandwdith > 20, the center frequency have to be
+	 * same to avoid target MCC on different center frequency even though
+	 * primary channel are same.
+	 */
+	if (*con_freq == ch_freq && wlan_reg_get_bw_value(ch_width) > 20)
+		return false;
+
+	return true;
+}
+
+bool policy_mgr_any_other_vdev_on_same_mac_as_freq(
+				struct wlan_objmgr_psoc *psoc,
+				uint32_t freq, uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_index = 0;
+	bool same_mac = false;
+
+	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)
+			continue;
+
+		if (pm_conc_connection_list[conn_index].vdev_id == vdev_id)
+			continue;
+
+		if (policy_mgr_are_2_freq_on_same_mac(
+				psoc,
+				pm_conc_connection_list[conn_index].freq,
+				freq)) {
+			same_mac = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return same_mac;
+}
+
+QDF_STATUS policy_mgr_get_sbs_cfg(struct wlan_objmgr_psoc *psoc, bool *sbs)
+{
+	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;
+	}
+	*sbs = pm_ctx->cfg.sbs_enable;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_SR
+bool policy_mgr_sr_same_mac_conc_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct wmi_unified *wmi_handle;
+	bool sr_conc_enabled;
+
+	if (!psoc) {
+		mlme_err("PSOC is NULL");
+		return false;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		mlme_err("wmi_handle is null");
+		return false;
+	}
+
+	sr_conc_enabled = policy_mgr_get_same_mac_conc_sr_status(psoc);
+
+	return (sr_conc_enabled &&
+		wmi_service_enabled(wmi_handle,
+				    wmi_service_obss_per_packet_sr_support));
+}
+#endif
+
+/**
+ * _policy_mgr_get_ll_sap_freq()- Function to get LL sap freq if it's present
+ * for provided type
+ * @psoc: PSOC object
+ * @ap_type: low latency ap type
+ *
+ * Return: freq if LL SAP otherwise return 0
+ *
+ */
+static qdf_freq_t _policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc *psoc,
+					      enum ll_ap_type ap_type)
+{
+	struct wlan_objmgr_vdev *sap_vdev;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_idx = 0, vdev_id;
+	bool is_ll_sap_present = false;
+	qdf_freq_t freq = 0;
+	enum host_concurrent_ap_policy profile =
+					HOST_CONCURRENT_AP_POLICY_UNSPECIFIED;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return 0;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_idx++) {
+		if (!(policy_mgr_is_sap_mode(
+				pm_conc_connection_list[conn_idx].mode) &&
+		      pm_conc_connection_list[conn_idx].in_use))
+			continue;
+
+		vdev_id = pm_conc_connection_list[conn_idx].vdev_id;
+		freq = pm_conc_connection_list[conn_idx].freq;
+
+		sap_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+				psoc,
+				vdev_id,
+				WLAN_POLICY_MGR_ID);
+
+		if (!sap_vdev) {
+			policy_mgr_err("vdev %d: not a sap vdev", vdev_id);
+			continue;
+		}
+
+		profile = wlan_mlme_get_ap_policy(sap_vdev);
+		wlan_objmgr_vdev_release_ref(sap_vdev,
+					     WLAN_POLICY_MGR_ID);
+		switch (ap_type) {
+		case LL_AP_TYPE_HT:
+			if (profile == HOST_CONCURRENT_AP_POLICY_XR)
+				is_ll_sap_present = true;
+		break;
+		case LL_AP_TYPE_LT:
+			if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO ||
+			    profile ==
+			    HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING)
+				is_ll_sap_present = true;
+		break;
+		case LL_AP_TYPE_ANY:
+			if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO ||
+			    profile == HOST_CONCURRENT_AP_POLICY_XR ||
+			    profile ==
+			    HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING)
+				is_ll_sap_present = true;
+		break;
+		default:
+		break;
+		}
+		if (!is_ll_sap_present)
+			continue;
+
+	       policy_mgr_debug("LL SAP %d present with vdev_id %d and freq %d",
+				ap_type, vdev_id, freq);
+
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+		return freq;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	return 0;
+}
+
+qdf_freq_t policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc *psoc)
+{
+	return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_ANY);
+}
+
+qdf_freq_t policy_mgr_get_ll_ht_sap_freq(struct wlan_objmgr_psoc *psoc)
+{
+	return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_HT);
+}
+
+qdf_freq_t policy_mgr_get_ll_lt_sap_freq(struct wlan_objmgr_psoc *psoc)
+{
+	return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_LT);
+}
+
+#ifndef WLAN_FEATURE_LL_LT_SAP
+bool policy_mgr_is_ll_sap_concurrency_valid(struct wlan_objmgr_psoc *psoc,
+					    qdf_freq_t freq,
+					    enum policy_mgr_con_mode mode)
+{
+	qdf_freq_t ll_sap_freq;
+
+	ll_sap_freq = policy_mgr_get_ll_sap_freq(psoc);
+	if (!ll_sap_freq)
+		return true;
+
+	/*
+	 * Scenario: When low latency SAP with 5GHz channel(whose
+	 * profile is set as gaming or lossless audio or XR) is present
+	 * on SBS/DBS hardware and the other interface like
+	 * STA/SAP/GC/GO trying to form connection.
+	 * Allow connection on those freq which are mutually exclusive
+	 * to LL SAP mac
+	 */
+
+	if (policy_mgr_2_freq_always_on_same_mac(psoc, ll_sap_freq,
+						 freq)) {
+		policy_mgr_debug("Invalid LL-SAP concurrency for SBS/DBS hw, ll-sap freq %d, conc_freq %d, conc_mode %d",
+				 ll_sap_freq, freq, mode);
+		return false;
+	}
+
+	return true;
+}
+#endif
+
+bool
+policy_mgr_update_indoor_concurrency(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id,
+				     uint32_t discon_freq,
+				     enum indoor_conc_update_type type)
+{
+	uint32_t ch_freq;
+	enum QDF_OPMODE mode;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum phy_ch_width ch_width = CH_WIDTH_INVALID;
+	bool indoor_support = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return false;
+	}
+
+	ucfg_mlme_get_indoor_channel_support(psoc, &indoor_support);
+	if (indoor_support ||
+	    !policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc))
+		return false;
+
+	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+
+	/**
+	 * DISCONNECT_WITH_CONCURRENCY update comes after SAP/GO CSA.
+	 * Whereas, all other updates come from STA/GC operation.
+	 */
+	if (type != DISCONNECT_WITH_CONCURRENCY &&
+	    (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)) {
+		return false;
+	} else if (type == DISCONNECT_WITH_CONCURRENCY &&
+		 (mode != QDF_SAP_MODE && mode != QDF_P2P_GO_MODE)) {
+		return false;
+	}
+
+	switch (type) {
+	case CONNECT:
+	case SWITCH_WITHOUT_CONCURRENCY:
+	case SWITCH_WITH_CONCURRENCY:
+		policy_mgr_get_chan_by_session_id(psoc, vdev_id, &ch_freq);
+		ch_width = policy_mgr_get_bw_by_session_id(psoc, vdev_id);
+		break;
+	case DISCONNECT_WITHOUT_CONCURRENCY:
+	case DISCONNECT_WITH_CONCURRENCY:
+		ch_freq = discon_freq;
+		break;
+	default:
+		return false;
+	}
+
+	if (type != SWITCH_WITHOUT_CONCURRENCY &&
+	    !(WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
+	    wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq))) {
+		return false;
+	} else if (type == SWITCH_WITHOUT_CONCURRENCY) {
+		/* Either the previous frequency or the current
+		 * frequency can be indoor. Or both can be indoor.
+		 * Therefore, atleast one of the frequency must be
+		 * indoor in order to proceed for the update.
+		 */
+		if (!((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
+		       wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq)) ||
+		      (WLAN_REG_IS_5GHZ_CH_FREQ(discon_freq) &&
+		       wlan_reg_is_freq_indoor(pm_ctx->pdev, discon_freq))))
+			return false;
+	}
+
+	switch (type) {
+	case CONNECT:
+		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id,
+						   ch_freq, ch_width, true);
+		break;
+	case DISCONNECT_WITHOUT_CONCURRENCY:
+		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id,
+						   0, CH_WIDTH_INVALID, false);
+		break;
+	case SWITCH_WITHOUT_CONCURRENCY:
+		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id, 0,
+						   CH_WIDTH_INVALID, false);
+		if (wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq))
+			wlan_reg_modify_indoor_concurrency(pm_ctx->pdev,
+							   vdev_id, ch_freq,
+							   ch_width, true);
+		break;
+	case DISCONNECT_WITH_CONCURRENCY:
+		/*If there are other sessions, do not change current chan list*/
+		if (policy_mgr_get_connection_count_with_ch_freq(ch_freq) > 1)
+			return false;
+		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev,
+						   INVALID_VDEV_ID, ch_freq,
+						   CH_WIDTH_INVALID, false);
+		break;
+	case SWITCH_WITH_CONCURRENCY:
+		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id,
+						   ch_freq, ch_width, true);
+		/*
+		 * The previous frequency removal and current channel list
+		 * recomputation will happen after SAP CSA
+		 */
+		return false;
+	}
+	return true;
+}
+
+bool policy_mgr_is_conc_sap_present_on_sta_freq(struct wlan_objmgr_psoc *psoc,
+						enum policy_mgr_con_mode mode,
+						uint32_t ch_freq)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t i;
+	bool sap_go_exists = false;
+	enum policy_mgr_con_mode cmode;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return false;
+	}
+
+	if (mode != PM_STA_MODE && mode != PM_P2P_CLIENT_MODE)
+		return false;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		cmode = pm_conc_connection_list[i].mode;
+		if (pm_conc_connection_list[i].in_use &&
+		    ch_freq == pm_conc_connection_list[i].freq &&
+		    (cmode == PM_SAP_MODE || cmode == PM_P2P_GO_MODE)) {
+			sap_go_exists = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return sap_go_exists;
+}
+
+bool policy_mgr_is_sap_mode(enum policy_mgr_con_mode mode)
+{
+	if (mode == PM_SAP_MODE || mode == PM_LL_LT_SAP_MODE)
+		return true;
+
+	return false;
+}
+
+bool policy_mgr_is_beaconing_mode(enum policy_mgr_con_mode mode)
+{
+	if (mode == PM_SAP_MODE || mode == PM_LL_LT_SAP_MODE ||
+	    mode == PM_P2P_GO_MODE)
+		return true;
+
+	return false;
+}
+
+bool policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(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 0;
+	}
+	return pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl;
+}
+
+QDF_STATUS
+policy_mgr_reset_sap_mandatory_channels(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->sap_mandatory_channels_len = 0;
+	qdf_mem_zero(pm_ctx->sap_mandatory_channels,
+		     QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels) *
+		     sizeof(*pm_ctx->sap_mandatory_channels));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_is_freq_on_mac_id(struct policy_mgr_freq_range *freq_range,
+				  qdf_freq_t freq, uint8_t mac_id)
+{
+	return IS_FREQ_ON_MAC_ID(freq_range, freq, mac_id);
+}
+
+bool policy_mgr_get_vdev_same_freq_new_conn(struct wlan_objmgr_psoc *psoc,
+					    uint32_t new_freq,
+					    uint8_t *vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool match = false;
+	uint32_t i;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (qdf_unlikely(!pm_ctx)) {
+		policy_mgr_err("Invalid pm_ctx");
+		return false;
+	}
+
+	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 &&
+		    pm_conc_connection_list[i].freq == new_freq) {
+			match = true;
+			*vdev_id = pm_conc_connection_list[i].vdev_id;
+			policy_mgr_debug("new_freq %d matched with vdev_id %d",
+					 new_freq, *vdev_id);
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return match;
+}
+
+bool policy_mgr_get_vdev_diff_freq_new_conn(struct wlan_objmgr_psoc *psoc,
+					    uint32_t new_freq,
+					    uint8_t *vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool match = false;
+	uint32_t i;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (qdf_unlikely(!pm_ctx)) {
+		policy_mgr_err("Invalid pm_ctx");
+		return false;
+	}
+
+	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 &&
+		    pm_conc_connection_list[i].freq != new_freq) {
+			match = true;
+			*vdev_id = pm_conc_connection_list[i].vdev_id;
+			policy_mgr_debug("new_freq %d matched with vdev_id %d",
+					 new_freq, *vdev_id);
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return match;
+}
+
+enum hw_mode_bandwidth
+policy_mgr_get_connection_max_channel_width(struct wlan_objmgr_psoc *psoc)
+{
+	enum hw_mode_bandwidth bw = HW_MODE_20_MHZ;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_index = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return HW_MODE_20_MHZ;
+	}
+
+	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].bw > bw)
+			bw = pm_conc_connection_list[conn_index].bw;
+	}
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return bw;
+}
+
+bool policy_mgr_is_given_freq_5g_low(struct wlan_objmgr_psoc *psoc,
+				     qdf_freq_t given_freq)
+{
+	qdf_freq_t sbs_cut_off_freq;
+
+	sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc);
+	if (!sbs_cut_off_freq)
+		return false;
+
+	if (given_freq < sbs_cut_off_freq &&
+	    WLAN_REG_IS_5GHZ_CH_FREQ(given_freq))
+		return true;
+
+	return false;
+}

+ 1214 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -0,0 +1,1214 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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"
+#include "cds_ieee80211_common_i.h"
+#include "qdf_delayed_work.h"
+#define DBS_OPPORTUNISTIC_TIME   5
+
+#define POLICY_MGR_SER_CMD_TIMEOUT 4000
+
+#ifdef QCA_WIFI_3_0_EMU
+#define CONNECTION_UPDATE_TIMEOUT (POLICY_MGR_SER_CMD_TIMEOUT + 3000)
+#else
+#define CONNECTION_UPDATE_TIMEOUT (POLICY_MGR_SER_CMD_TIMEOUT + 2000)
+#endif
+
+#define PM_24_GHZ_CH_FREQ_6   (2437)
+#define PM_5_GHZ_CH_FREQ_36   (5180)
+#define CHANNEL_SWITCH_COMPLETE_TIMEOUT   (2000)
+#define MAX_NOA_TIME (3000)
+
+/* Defer SAP force SCC check by 2000ms due to another SAP/GO start AP in
+ * progress
+ */
+#define SAP_CONC_CHECK_DEFER_TIMEOUT_MS (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_EMLSR_MODE_BITPOS       (32)
+#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_EMLSR_MODE_MASK         \
+	(0x1 << POLICY_MGR_HW_MODE_EMLSR_MODE_BITPOS)
+#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_EMLSR_MODE_SET(hw_mode, tmp, value) \
+	QDF_SET_BITS64(hw_mode, tmp, POLICY_MGR_HW_MODE_EMLSR_MODE_BITPOS,\
+	1, value)
+#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_EMLSR_MODE_GET(hw_mode)                     \
+		QDF_GET_BITS64(hw_mode, POLICY_MGR_HW_MODE_EMLSR_MODE_BITPOS,\
+		1)
+#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 policy_mgr_rl_debug(params...) \
+	QDF_TRACE_DEBUG_RL(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];
+
+#ifdef WLAN_FEATURE_11BE_MLO
+extern struct policy_mgr_disabled_ml_link_info
+	pm_disabled_ml_links[MAX_NUMBER_OF_DISABLE_LINK];
+#endif
+
+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 enum policy_mgr_pcl_type const
+	(*second_connection_pcl_non_dbs_table)[PM_MAX_ONE_CONNECTION_MODE]
+			[PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE];
+extern pm_dbs_pcl_third_connection_table_type
+		*third_connection_pcl_dbs_table;
+extern enum policy_mgr_pcl_type const
+	(*third_connection_pcl_non_dbs_table)[PM_MAX_TWO_CONNECTION_MODE]
+			[PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE];
+
+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;
+
+#ifdef FEATURE_FOURTH_CONNECTION
+extern const enum policy_mgr_pcl_type
+	fourth_connection_pcl_dbs_sbs_table
+	[PM_MAX_THREE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE]
+	[PM_MAX_CONC_PRIORITY_MODE];
+#endif
+
+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 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
+ * @allow_mcc_go_diff_bi: Allow GO and STA diff beacon interval in MCC
+ * @dual_mac_feature: To enable/disable dual mac features
+ * @is_force_1x1_enable: Is 1x1 forced for connection
+ * @sta_sap_scc_on_dfs_chnl: STA-SAP SCC on DFS channel
+ * @sta_sap_scc_on_lte_coex_chnl: STA-SAP SCC on LTE Co-ex channel
+ * @sta_sap_scc_on_indoor_channel: Allow STA-SAP scc on indoor only
+ * channels
+ * @nan_sap_scc_on_lte_coex_chnl: NAN-SAP SCC on LTE Co-ex channel
+ * @sap_mandatory_chnl_enable: To enable/disable SAP mandatory channels
+ * @mark_indoor_chnl_disable: Mark indoor channel as disable or enable
+ * @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
+ * @go_force_scc: Enable/Disable P2P GO force SCC
+ * @pcl_band_priority: PCL channel order between 5G and 6G.
+ * @sbs_enable: To enable/disable SBS
+ * @multi_sap_allowed_on_same_band: Enable/Disable multi sap started
+ *                                  on same band
+ * @sr_in_same_mac_conc: Enable/Disable SR in same MAC concurrency
+ * @use_sap_original_bw: Enable/Disable sap original BW as default
+ *                       BW when do restart
+ * @move_sap_go_1st_on_dfs_sta_csa: Enable/Disable SAP / GO's movement
+ *				    to non-DFS channel before STA
+ */
+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;
+	bool enable_mcc_adaptive_sch;
+	uint8_t allow_mcc_go_diff_bi;
+	uint8_t dual_mac_feature;
+	enum force_1x1_type is_force_1x1_enable;
+	uint8_t sta_sap_scc_on_dfs_chnl;
+	uint8_t sta_sap_scc_on_lte_coex_chnl;
+	bool sta_sap_scc_on_indoor_channel;
+	uint8_t nan_sap_scc_on_lte_coex_chnl;
+	uint8_t sap_mandatory_chnl_enable;
+	uint8_t mark_indoor_chnl_disable;
+	uint8_t enable_sta_cxn_5g_band;
+	uint32_t dbs_selection_plcy;
+	uint32_t vdev_priority_list;
+	uint32_t chnl_select_plcy;
+	uint8_t go_force_scc;
+	enum policy_mgr_pcl_band_priority pcl_band_priority;
+	bool sbs_enable;
+	bool multi_sap_allowed_on_same_band;
+#ifdef WLAN_FEATURE_SR
+	bool sr_in_same_mac_conc;
+#endif
+	bool use_sap_original_bw;
+	bool move_sap_go_1st_on_dfs_sta_csa;
+};
+
+/**
+ * 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
+ * @hdd_cbacks: callbacks to be registered by HDD for
+ *            interaction with Policy Manager
+ * @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
+ * @dp_cbacks: callbacks to be registered by Datapath for
+ * interaction with Policy Manager
+ * @conc_cbacks: callbacks to be registered by lim for
+ * interaction with Policy Manager
+ * @sap_mandatory_channels: The user preferred master list on
+ *                        which SAP can be brought up. This
+ *                        mandatory channel freq 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_sap_unsafe_ch_check: whether need check sap unsafe channel
+ * @last_disconn_sta_freq: last disconnected sta channel freq
+ * @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
+ * @work_fail_count: sta_ap work schedule fail count
+ * @nan_sap_conc_work: Info related to nan sap conc 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 currently used by FW for
+ *              scan & connections
+ * @radio_comb_num: radio combination number
+ * @radio_combinations: radio combination list
+ * @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
+ * @user_cfg:
+ * @unsafe_channel_list: LTE coex channel freq 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
+ * @cur_conc_system_pref:
+ * @opportunistic_update_done_evt: qdf event to synchronize host
+ *                               & FW HW mode
+ * @channel_switch_complete_evt: qdf event for channel switch completion check
+ * @mode_change_cb: Mode change callback
+ * @cfg: Policy manager config data
+ * @valid_ch_freq_list: valid frequencies
+ * @valid_ch_freq_list_count: number of valid frequencies
+ * @dynamic_mcc_adaptive_sched: disable/enable mcc adaptive scheduler feature
+ * @dynamic_dfs_master_disabled: current state of dynamic dfs master
+ * @link_in_progress: To track if set link is in progress
+ * @set_link_update_done_evt: qdf event to synchronize set link
+ * @active_vdev_bitmap: Active vdev id bitmap
+ * @inactive_vdev_bitmap: Inactive vdev id bitmap
+ * @restriction_mask:
+ */
+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;
+	struct policy_mgr_conc_cbacks conc_cbacks;
+	uint32_t sap_mandatory_channels[NUM_CHANNELS];
+	uint32_t sap_mandatory_channels_len;
+	qdf_freq_t last_disconn_sta_freq;
+	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];
+	struct qdf_delayed_work sta_ap_intf_check_work;
+	uint8_t work_fail_count;
+	qdf_work_t nan_sap_conc_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 radio_comb_num;
+	struct radio_combination radio_combinations[MAX_RADIO_COMBINATION];
+	uint32_t hw_mode_change_in_progress;
+	struct policy_mgr_user_cfg user_cfg;
+	uint32_t unsafe_channel_list[NUM_CHANNELS];
+	uint16_t unsafe_channel_count;
+	struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info;
+	uint8_t cur_conc_system_pref;
+	qdf_event_t opportunistic_update_done_evt;
+	qdf_event_t channel_switch_complete_evt;
+	send_mode_change_event_cb mode_change_cb;
+	struct policy_mgr_cfg cfg;
+	uint32_t valid_ch_freq_list[NUM_CHANNELS];
+	uint32_t valid_ch_freq_list_count;
+	bool dynamic_mcc_adaptive_sched;
+	bool dynamic_dfs_master_disabled;
+#ifdef WLAN_FEATURE_11BE_MLO
+	qdf_atomic_t link_in_progress;
+	qdf_event_t set_link_update_done_evt;
+#endif
+	uint32_t active_vdev_bitmap;
+	uint32_t inactive_vdev_bitmap;
+#ifdef FEATURE_WLAN_CH_AVOID_EXT
+	uint32_t restriction_mask;
+#endif
+};
+
+/**
+ * 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)
+ * @support_6ghz_band: support 6 GHz band
+ */
+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;
+	bool support_6ghz_band;
+};
+
+#ifdef WLAN_FEATURE_SR
+/**
+ * policy_mgr_get_same_mac_conc_sr_status() - Function returns value of INI
+ * g_enable_sr_in_same_mac_conc
+ *
+ * @psoc: Pointer to PSOC
+ *
+ * Return: Returns True / False
+ */
+bool policy_mgr_get_same_mac_conc_sr_status(struct wlan_objmgr_psoc *psoc);
+
+#else
+static inline
+bool policy_mgr_get_same_mac_conc_sr_status(struct wlan_objmgr_psoc *psoc)
+{
+	return true;
+}
+#endif
+
+struct policy_mgr_psoc_priv_obj *policy_mgr_get_context(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_get_updated_scan_config() - Get the updated scan configuration
+ * @psoc: psoc handle
+ * @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);
+
+/**
+ * policy_mgr_get_updated_fw_mode_config() - Get the updated fw
+ * mode configuration
+ * @psoc: psoc handle
+ * @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);
+
+/**
+ * policy_mgr_is_dual_mac_disabled_in_ini() - Check if dual mac
+ * is disabled in INI
+ * @psoc: psoc handle
+ *
+ * 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);
+
+/**
+ * policy_mgr_find_if_hwlist_has_dbs() - Find if hw list has DBS modes or not
+ * @psoc: PSOC object information
+ *
+ * Find if hw list has DBS modes or not
+ *
+ * Return: true or false
+ */
+bool policy_mgr_find_if_hwlist_has_dbs(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);
+
+/**
+ * policy_mgr_get_dbs_config() - Get DBS bit
+ * @psoc: psoc handle
+ *
+ * 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);
+
+/**
+ * policy_mgr_get_agile_dfs_config() - Get Agile DFS bit
+ * @psoc: psoc handle
+ *
+ * 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);
+
+/**
+ * policy_mgr_get_dbs_scan_config() - Get DBS scan bit
+ * @psoc: psoc handle
+ *
+ * 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);
+
+/**
+ * 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);
+
+/**
+ * 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);
+
+/**
+ * policy_mgr_get_hw_mode_idx_from_dbs_hw_list() - Get hw_mode index
+ * @psoc: psoc handle
+ * @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);
+
+/**
+ * policy_mgr_get_old_and_new_hw_index() - Get the old and new HW index
+ * @psoc: psoc handle
+ * @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);
+
+/**
+ * policy_mgr_update_conc_list() - Update the concurrent connection list
+ * @psoc: PSOC object information
+ * @conn_index: Connection index
+ * @mode: Mode
+ * @freq: channel frequency
+ * @bw: Bandwidth
+ * @mac: Mac id
+ * @chain_mask: Chain mask
+ * @original_nss: Original number of spatial streams
+ * @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
+ * @ch_flagext: channel state flags
+ *
+ * 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,
+		uint32_t freq,
+		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,
+		uint16_t ch_flagext);
+
+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: structure 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);
+
+/**
+ * policy_mgr_store_and_del_conn_info_by_chan_and_mode() - Store and del a
+ * connection info by chan number and conn mode
+ * @psoc: PSOC object information
+ * @ch_freq: channel frequency value
+ * @mode: conn mode
+ * @info: structure array pointer where the connection info will be saved
+ * @num_cxn_del: number of connection which are going to be deleted
+ *
+ * Saves and deletes the entries if the active connection entry chan and mode
+ * matches the provided chan & mode from the function parameters.
+ *
+ * Return: None
+ */
+void policy_mgr_store_and_del_conn_info_by_chan_and_mode(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t ch_freq,
+			enum policy_mgr_con_mode mode,
+			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,
+				uint32_t num_mac_freq,
+				struct policy_mgr_pdev_mac_freq_map *freq_info);
+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,
+				uint32_t request_id);
+
+#ifdef WLAN_FEATURE_11BE_MLO
+void
+policy_mgr_dump_disabled_ml_links(struct policy_mgr_psoc_priv_obj *pm_ctx);
+
+/**
+ * policy_mgr_link_switch_notifier_cb() - link switch notifier callback
+ * @vdev: vdev object
+ * @req: link switch request
+ * @notify_reason: Reason for notification
+ *
+ * This API will be registered to mlo link switch, to be invoked before
+ * do link switch process.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_link_switch_notifier_cb(struct wlan_objmgr_vdev *vdev,
+				   struct wlan_mlo_link_switch_req *req,
+				   enum wlan_mlo_link_switch_notify_reason notify_reason);
+#else
+static inline void
+policy_mgr_dump_disabled_ml_links(struct policy_mgr_psoc_priv_obj *pm_ctx) {}
+#endif
+
+/**
+ * policy_mgr_dump_current_concurrency() - To dump the current
+ * concurrency combination
+ * @psoc: psoc handle
+ *
+ * This routine is called to dump the concurrency info
+ *
+ * Return: None
+ */
+void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc);
+
+void pm_dbs_opportunistic_timer_handler(void *data);
+
+/**
+ * policy_mgr_get_channel_list() - Get channel list based on PCL and mode
+ * @psoc: psoc object
+ * @pcl: pcl type
+ * @mode: interface mode
+ * @pcl_channels: pcl channel list buffer
+ * @pcl_weights: pcl weight buffer
+ * @pcl_sz: pcl channel list buffer size
+ * @len: pcl channel number returned from API
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc,
+				       enum policy_mgr_pcl_type pcl,
+				       enum policy_mgr_con_mode mode,
+				       uint32_t *pcl_channels,
+				       uint8_t *pcl_weights,
+				       uint32_t pcl_sz, uint32_t *len);
+
+/**
+ * policy_mgr_allow_new_home_channel() - Check for allowed number of
+ * home channels
+ * @psoc: PSOC Pointer
+ * @mode: Connection mode
+ * @ch_freq: channel frequency on which new connection is coming up
+ * @num_connections: number of current connections
+ * @is_dfs_ch: DFS channel or not
+ * @ext_flags: extended flags for concurrency check
+ *
+ * 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, enum policy_mgr_con_mode mode,
+	uint32_t ch_freq, uint32_t num_connections, bool is_dfs_ch,
+	uint32_t ext_flags);
+
+/**
+ * policy_mgr_is_5g_channel_allowed() - check if 5g channel is allowed
+ * @psoc: PSOC object information
+ * @ch_freq: channel frequency which needs to be validated
+ * @list: list of existing connections.
+ * @mode: mode against which channel needs to be validated
+ *
+ * This API takes the channel frequency 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,
+				uint32_t ch_freq, uint32_t *list,
+				enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_complete_action() - initiates actions needed on
+ * current connections once channel has been decided for the new
+ * connection
+ * @psoc: PSOC object information
+ * @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
+ * @request_id: connection manager req id
+ *
+ * This function 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, uint32_t request_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);
+
+/**
+ * policy_mgr_get_current_pref_hw_mode_dbs_2x2() - Get the
+ * current preferred hw mode
+ * @psoc: psoc handle
+ *
+ * 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);
+
+/**
+ * policy_mgr_get_current_pref_hw_mode_dbs_1x1() - Get the
+ * current preferred hw mode
+ * @psoc: psoc handle
+ *
+ * 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);
+
+/**
+ * policy_mgr_get_current_pref_hw_mode_dual_dbs() - Get the
+ * current preferred hw mode
+ * @psoc: PSOC object information
+ *
+ * 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);
+
+void
+policy_mgr_dump_freq_range_per_mac(struct policy_mgr_freq_range *freq_range,
+				   enum policy_mgr_mode hw_mode);
+
+/**
+ * policy_mgr_fill_curr_mac_freq_by_hwmode() - Fill Current Mac frequency with
+ * the frequency range of the given Hw Mode
+ *
+ * @pm_ctx: Policy Mgr context
+ * @mode_hw: Policy Mgr Hw mode
+ *
+ * Fill Current Mac frequency with the frequency range of the given Hw Mode
+ *
+ * Return: None
+ */
+void
+policy_mgr_fill_curr_mac_freq_by_hwmode(struct policy_mgr_psoc_priv_obj *pm_ctx,
+					enum policy_mgr_mode mode_hw);
+
+/**
+ * policy_mgr_dump_freq_range() - Function to print every frequency range
+ * for both MAC 0 and MAC1 for every Hw mode
+ *
+ * @pm_ctx: Policy Mgr context
+ *
+ * This function will print every frequency range
+ * for both MAC 0 and MAC1 for every Hw mode
+ *
+ * Return: void
+ *
+ */
+void
+policy_mgr_dump_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx);
+
+/**
+ * policy_mgr_dump_sbs_freq_range() - Function to print SBS frequency range
+ * for both MAC 0 and MAC1
+ *
+ * @pm_ctx: Policy Mgr context
+ *
+ * Return: void
+ */
+void
+policy_mgr_dump_sbs_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx);
+
+/**
+ * policy_mgr_dump_curr_freq_range() - Function to print current frequency range
+ * for both MAC 0 and MAC1
+ *
+ * @pm_ctx: Policy Mgr context
+ *
+ * This function will print current frequency range
+ * for both MAC 0 and MAC1 for every Hw mode
+ *
+ * Return: void
+ *
+ */
+void
+policy_mgr_dump_curr_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx);
+
+/**
+ * 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_update_nss_req() - wrapper API to update nss
+ * @psoc: psoc object
+ * @vdev_id: vdev id
+ * @tx_nss: Tx nss to set
+ * @rx_nss: Rx nss to set
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS policy_mgr_update_nss_req(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id, uint8_t tx_nss,
+				     uint8_t rx_nss);
+
+/**
+ * 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
+ * @request_id: request 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, uint32_t request_id);
+
+/**
+ * policy_mgr_is_concurrency_allowed() - Check for allowed
+ * concurrency combination
+ * @psoc: PSOC object information
+ * @mode: new connection mode
+ * @ch_freq: channel frequency on which new connection is coming up
+ * @bw: Bandwidth requested by the connection (optional)
+ * @ext_flags: extended flags for concurrency check (union conc_ext_flag)
+ * @pcl: Optional PCL for new connection
+ *
+ * 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,
+				       uint32_t ch_freq,
+				       enum hw_mode_bandwidth bw,
+				       uint32_t ext_flags,
+				       struct policy_mgr_pcl_list *pcl);
+
+/**
+ * policy_mgr_can_2ghz_share_low_high_5ghz_sbs() - if SBS mode is dynamic where
+ * 2.4 GHZ can be shared by any of high 5 GHZ or low 5GHZ at a time.
+ * @pm_ctx: policy mgr psoc priv object
+ *
+ * Return: true is sbs is dynamic else false.
+ */
+bool policy_mgr_can_2ghz_share_low_high_5ghz_sbs(
+				struct policy_mgr_psoc_priv_obj *pm_ctx);
+
+/**
+ * policy_mgr_sbs_24_shared_with_high_5() - if 2.4 GHZ
+ * can be shared by high 5 GHZ
+ *
+ * @pm_ctx: policy mgr psoc priv object
+ *
+ * Return: true if 2.4 GHz is shared by high 5 GHZ
+ */
+bool
+policy_mgr_sbs_24_shared_with_high_5(struct policy_mgr_psoc_priv_obj *pm_ctx);
+
+/**
+ * policy_mgr_sbs_24_shared_with_low_5() - if 2.4 GHZ
+ * can be shared by low 5 GHZ
+ *
+ * @pm_ctx: policy mgr psoc priv object
+ *
+ * Return: true if 2.4 GHz is shared by low 5 GHZ
+ */
+bool
+policy_mgr_sbs_24_shared_with_low_5(struct policy_mgr_psoc_priv_obj *pm_ctx);
+
+/**
+ * policy_mgr_2_freq_same_mac_in_dbs() - to check provided frequencies are
+ * in dbs freq range or not
+ *
+ * @pm_ctx: policy mgr psoc priv object
+ * @freq_1: first frequency
+ * @freq_2: second frequency
+ *
+ * This API is used to check provided frequencies are in dbs freq range or not
+ *
+ * Return: true/false.
+ */
+bool
+policy_mgr_2_freq_same_mac_in_dbs(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				  qdf_freq_t freq_1, qdf_freq_t freq_2);
+
+/**
+ * policy_mgr_2_freq_same_mac_in_sbs() - to check provided frequencies are
+ * in sbs freq range or not
+ *
+ * @pm_ctx: policy mgr psoc priv object
+ * @freq_1: first frequency
+ * @freq_2: second frequency
+ *
+ * This API is used to check provided frequencies are in sbs freq range or not
+ *
+ * Return: true/false.
+ */
+bool policy_mgr_2_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				       qdf_freq_t freq_1, qdf_freq_t freq_2);
+
+/**
+ * policy_mgr_get_connection_for_vdev_id() - provides the
+ * particular connection with the requested vdev id
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id of the connection
+ *
+ * This function provides the specific connection with the
+ * requested vdev id
+ *
+ * Return: index in the connection table
+ */
+uint32_t policy_mgr_get_connection_for_vdev_id(struct wlan_objmgr_psoc *psoc,
+					       uint32_t vdev_id);
+
+#ifdef FEATURE_WLAN_CH_AVOID_EXT
+/**
+ * policy_mgr_set_freq_restriction_mask() - fill the restriction_mask
+ * in pm_ctx
+ *
+ * @pm_ctx: policy mgr psoc priv object
+ * @freq_list: avoid freq indication carries freq/mask/freq count
+ *
+ * Return: None
+ */
+void
+policy_mgr_set_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				     struct ch_avoid_ind_type *freq_list);
+
+/**
+ * policy_mgr_get_freq_restriction_mask() - get restriction_mask from
+ * pm_ctx
+ *
+ * @pm_ctx: policy mgr psoc priv object
+ *
+ * Return: Restriction mask
+ */
+uint32_t
+policy_mgr_get_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx);
+#else
+static inline void
+policy_mgr_set_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				     struct ch_avoid_ind_type *freq_list)
+{
+}
+#endif
+
+/**
+ * policy_mgr_get_connection_max_channel_width() - Get max channel width
+ * among vdevs in use
+ * @psoc: PSOC object pointer
+ *
+ * This function returns max channel width among in-use vdevs
+ *
+ * Return: enum hw_mode_bandwidth
+ */
+enum hw_mode_bandwidth
+policy_mgr_get_connection_max_channel_width(struct wlan_objmgr_psoc *psoc);
+
+#endif

+ 989 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -0,0 +1,989 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_no_dbs_i.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_tables_2x2_dbs_sbs_i.h"
+#include "wlan_policy_mgr_i.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_objmgr_global_obj.h"
+#include "target_if.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)
+		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;
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+static QDF_STATUS policy_mgr_register_link_switch_notifier(void)
+{
+	QDF_STATUS status;
+
+	status = mlo_mgr_register_link_switch_notifier(
+			WLAN_UMAC_COMP_POLICY_MGR,
+			policy_mgr_link_switch_notifier_cb);
+	if (status == QDF_STATUS_E_NOSUPPORT) {
+		status = QDF_STATUS_SUCCESS;
+		policy_mgr_debug("Link switch not supported");
+	} else if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register link switch notifier for policy mgr!");
+	}
+
+	return status;
+}
+
+static QDF_STATUS policy_mgr_unregister_link_switch_notifier(void)
+{
+	QDF_STATUS status;
+
+	status = mlo_mgr_unregister_link_switch_notifier(
+			WLAN_UMAC_COMP_POLICY_MGR);
+	if (status == QDF_STATUS_E_NOSUPPORT)
+		status = QDF_STATUS_SUCCESS;
+	else if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to unregister link switch notifier for policy mgr!");
+
+	return status;
+}
+#else
+static QDF_STATUS policy_mgr_register_link_switch_notifier(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_unregister_link_switch_notifier(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+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;
+	}
+
+	status = policy_mgr_register_link_switch_notifier();
+	if (status != QDF_STATUS_SUCCESS) {
+		policy_mgr_err("Failed to register link switch cback");
+		goto err_link_switch;
+	}
+
+	policy_mgr_notice("Callbacks registered with obj mgr");
+
+	return QDF_STATUS_SUCCESS;
+err_link_switch:
+	wlan_objmgr_unregister_vdev_status_handler(
+				WLAN_UMAC_COMP_POLICY_MGR,
+				policy_mgr_vdev_obj_status_cb,
+				NULL);
+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 = policy_mgr_unregister_link_switch_notifier();
+	if (status != QDF_STATUS_SUCCESS)
+		policy_mgr_err("Failed to deregister link switch cback");
+
+	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;
+	}
+
+	pm_ctx->sta_ap_intf_check_work_info = qdf_mem_malloc(
+		sizeof(struct sta_ap_intf_check_work_ctx));
+	if (!pm_ctx->sta_ap_intf_check_work_info) {
+		qdf_mutex_destroy(&pm_ctx->qdf_conc_list_lock);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pm_ctx->sta_ap_intf_check_work_info->psoc = psoc;
+	pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id =
+						WLAN_UMAC_VDEV_ID_MAX;
+	pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason =
+						CSA_REASON_UNKNOWN;
+	if (QDF_IS_STATUS_ERROR(qdf_delayed_work_create(
+				&pm_ctx->sta_ap_intf_check_work,
+				policy_mgr_check_sta_ap_concurrent_ch_intf,
+				pm_ctx))) {
+		policy_mgr_err("Failed to create dealyed work queue");
+		qdf_mutex_destroy(&pm_ctx->qdf_conc_list_lock);
+		qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info);
+		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_debug("HW list is freed");
+	}
+
+	if (pm_ctx->sta_ap_intf_check_work_info) {
+		qdf_delayed_work_destroy(&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;
+}
+
+#ifdef FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT
+static void policy_mgr_init_non_dbs_pcl(struct wlan_objmgr_psoc *psoc)
+{
+	struct wmi_unified *wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+
+	if (!wmi_handle) {
+		policy_mgr_debug("Invalid WMI handle");
+		return;
+	}
+
+	if (wmi_service_enabled(wmi_handle,
+				wmi_service_no_interband_mcc_support) &&
+	    !wmi_service_enabled(wmi_handle,
+				wmi_service_dual_band_simultaneous_support)) {
+		second_connection_pcl_non_dbs_table =
+		&second_connection_pcl_nodbs_no_interband_mcc_table;
+		third_connection_pcl_non_dbs_table =
+		&third_connection_pcl_nodbs_no_interband_mcc_table;
+	} else {
+		second_connection_pcl_non_dbs_table =
+		&second_connection_pcl_nodbs_table;
+		third_connection_pcl_non_dbs_table =
+		&third_connection_pcl_nodbs_table;
+	}
+}
+#else
+static void policy_mgr_init_non_dbs_pcl(struct wlan_objmgr_psoc *psoc)
+{
+	second_connection_pcl_non_dbs_table =
+	&second_connection_pcl_nodbs_table;
+	third_connection_pcl_non_dbs_table =
+	&third_connection_pcl_nodbs_table;
+}
+#endif
+
+#ifdef WLAN_FEATURE_11BE_MLO
+static inline void policy_mgr_memzero_disabled_ml_list(void)
+{
+	qdf_mem_zero(pm_disabled_ml_links, sizeof(pm_disabled_ml_links));
+}
+
+static QDF_STATUS
+policy_mgr_init_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	QDF_STATUS qdf_status;
+
+	qdf_atomic_init(&pm_ctx->link_in_progress);
+	qdf_status = qdf_event_create(&pm_ctx->set_link_update_done_evt);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		policy_mgr_err("init event failed for for set_link_update_done_evt");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+policy_mgr_deinit_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	QDF_STATUS qdf_status;
+
+	qdf_atomic_set(&pm_ctx->link_in_progress, 0);
+	qdf_status = qdf_event_destroy(&pm_ctx->set_link_update_done_evt);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		policy_mgr_err("deinit event failed for set_link_update_done_evt");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#else
+static inline void policy_mgr_memzero_disabled_ml_list(void) {}
+
+static inline QDF_STATUS
+policy_mgr_init_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+policy_mgr_deinit_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool enable_mcc_adaptive_sch = false;
+
+	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));
+	policy_mgr_memzero_disabled_ml_list();
+	policy_mgr_clear_concurrent_session_count(psoc);
+	/* 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;
+	}
+
+	status = policy_mgr_init_ml_link_update(pm_ctx);
+	if (QDF_IS_STATUS_ERROR(status))
+		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;
+	}
+	policy_mgr_get_mcc_adaptive_sch(psoc, &enable_mcc_adaptive_sch);
+	policy_mgr_set_dynamic_mcc_adaptive_sch(psoc, enable_mcc_adaptive_sch);
+	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(psoc);
+	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_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G))
+		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_hw_sbs_capable(psoc))
+		second_connection_pcl_dbs_table =
+		&pm_second_connection_pcl_dbs_sbs_2x2_table;
+	else if (policy_mgr_is_hw_dbs_2x2_capable(psoc) ||
+	    policy_mgr_is_hw_dbs_required_for_band(psoc,
+						   HW_MODE_MAC_BAND_2G) ||
+	    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_hw_sbs_capable(psoc))
+		third_connection_pcl_dbs_table =
+		&pm_third_connection_pcl_dbs_sbs_2x2_table;
+	else if (policy_mgr_is_hw_dbs_2x2_capable(psoc) ||
+	    policy_mgr_is_hw_dbs_required_for_band(psoc,
+						   HW_MODE_MAC_BAND_2G) ||
+	    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;
+
+	/* Initialize non-DBS pcl table pointer to particular table*/
+	policy_mgr_init_non_dbs_pcl(psoc);
+
+	if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) {
+		if (policy_mgr_is_hw_dbs_required_for_band(psoc,
+							HW_MODE_MAC_BAND_2G)) {
+			next_action_two_connection_table =
+				&pm_next_action_two_connection_dbs_2x2_table;
+			policy_mgr_debug("using hst/hsp policy manager table");
+		} else {
+			next_action_two_connection_table =
+			      &pm_next_action_two_connection_dbs_2x2_table_v2;
+			policy_mgr_debug("using hmt policy manager 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) ||
+	    policy_mgr_is_hw_dbs_required_for_band(psoc,
+						   HW_MODE_MAC_BAND_2G)) {
+		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, 2g-on-dbs %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_hw_dbs_required_for_band(
+				psoc, HW_MODE_MAC_BAND_2G),
+			 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);
+	}
+
+	if (QDF_IS_STATUS_ERROR(policy_mgr_deinit_ml_link_update(pm_ctx))) {
+		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(psoc))) {
+		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));
+	policy_mgr_clear_concurrent_session_count(psoc);
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_register_conc_cb(struct wlan_objmgr_psoc *psoc,
+				struct policy_mgr_conc_cbacks *conc_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->conc_cbacks.connection_info_update =
+					conc_cbacks->connection_info_update;
+	return QDF_STATUS_SUCCESS;
+}
+
+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_nss_update_request =
+		sme_cbacks->sme_nss_update_request;
+	if (!policy_mgr_is_hwmode_offload_enabled(psoc))
+		pm_ctx->sme_cbacks.sme_pdev_set_hw_mode =
+			sme_cbacks->sme_pdev_set_hw_mode;
+	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_rso_start_cb =
+		sme_cbacks->sme_rso_start_cb;
+	pm_ctx->sme_cbacks.sme_rso_stop_cb =
+		sme_cbacks->sme_rso_stop_cb;
+	pm_ctx->sme_cbacks.sme_change_sap_csa_count =
+		sme_cbacks->sme_change_sap_csa_count;
+	pm_ctx->sme_cbacks.sme_sap_update_ch_width =
+		sme_cbacks->sme_sap_update_ch_width;
+
+	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_is_chan_switch_in_progress =
+		hdd_cbacks->hdd_is_chan_switch_in_progress;
+	pm_ctx->hdd_cbacks.hdd_is_cac_in_progress =
+		hdd_cbacks->hdd_is_cac_in_progress;
+	pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable =
+		hdd_cbacks->hdd_get_ap_6ghz_capable;
+	pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt =
+		hdd_cbacks->wlan_hdd_indicate_active_ndp_cnt;
+	pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params =
+		hdd_cbacks->wlan_get_ap_prefer_conc_ch_params;
+	pm_ctx->hdd_cbacks.wlan_get_sap_acs_band =
+		hdd_cbacks->wlan_get_sap_acs_band;
+	pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb =
+		hdd_cbacks->wlan_check_cc_intf_cb;
+	pm_ctx->hdd_cbacks.wlan_set_tx_rx_nss_cb =
+		hdd_cbacks->wlan_set_tx_rx_nss_cb;
+
+	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;
+	pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress = NULL;
+	pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = NULL;
+	pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = NULL;
+	pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = NULL;
+	pm_ctx->hdd_cbacks.wlan_get_sap_acs_band = NULL;
+	pm_ctx->hdd_cbacks.wlan_set_tx_rx_nss_cb = 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;
+	pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw =
+		dp_cbacks->hdd_ipa_set_perf_level_bw;
+
+	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;
+}

+ 327 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ll_sap.c

@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains policy manager ll_sap definitions specific to the ll_sap module
+ */
+
+#include "wlan_policy_mgr_ll_sap.h"
+#include "wlan_policy_mgr_public_struct.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_policy_mgr_i.h"
+#include "wlan_cmn.h"
+#include "wlan_ll_sap_api.h"
+
+void policy_mgr_ll_lt_sap_get_valid_freq(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_objmgr_pdev *pdev,
+					 uint8_t vdev_id,
+					 qdf_freq_t sap_ch_freq,
+					 uint8_t cc_switch_mode,
+					 qdf_freq_t *new_sap_freq,
+					 bool *is_ll_lt_sap_present)
+{
+	enum sap_csa_reason_code csa_reason;
+	enum policy_mgr_con_mode conn_mode;
+	qdf_freq_t ll_lt_sap_freq = 0;
+	*is_ll_lt_sap_present = false;
+
+	/* If Vdev is ll_lt_sap, check if the frequency on which it is
+	 * coming up is correct, else, get new frequency
+	 */
+	if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) {
+		*new_sap_freq = wlan_get_ll_lt_sap_restart_freq(pdev,
+								sap_ch_freq,
+								vdev_id,
+								&csa_reason);
+		*is_ll_lt_sap_present = true;
+	}
+
+	ll_lt_sap_freq = policy_mgr_get_ll_lt_sap_freq(psoc);
+	if (!ll_lt_sap_freq)
+		return;
+
+	conn_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
+
+	if (conn_mode == PM_SAP_MODE) {
+		/* If ll_lt_sap and concurrent SAP are on same MAC,
+		 * update the frequency of concurrent SAP, else return.
+		 */
+		if (!policy_mgr_are_2_freq_on_same_mac(psoc, sap_ch_freq,
+						       ll_lt_sap_freq))
+			return;
+		goto policy_mgr_check_scc;
+	} else if (conn_mode == PM_P2P_GO_MODE) {
+		/* If ll_lt_sap and P2P_GO are in SCC,
+		 * update the frequency of concurrent GO else, return.
+		 */
+		if (ll_lt_sap_freq != sap_ch_freq)
+			return;
+		goto policy_mgr_check_scc;
+	} else {
+		policy_mgr_debug("Invalid con mode %d vdev %d", conn_mode,
+				 vdev_id);
+		return;
+	}
+
+policy_mgr_check_scc:
+	policy_mgr_check_scc_channel(psoc, new_sap_freq, sap_ch_freq, vdev_id,
+				     cc_switch_mode);
+	policy_mgr_debug("vdev_id %d old_freq %d new_freq %d", vdev_id,
+			 sap_ch_freq, *new_sap_freq);
+}
+
+uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev_id(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t ll_lt_sap_cnt;
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+
+	ll_lt_sap_cnt = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							vdev_id_list,
+							PM_LL_LT_SAP_MODE);
+
+	/* Currently only 1 ll_lt_sap is supported */
+	if (!ll_lt_sap_cnt)
+		return WLAN_INVALID_VDEV_ID;
+
+	return vdev_id_list[0];
+}
+
+bool __policy_mgr_is_ll_lt_sap_restart_required(struct wlan_objmgr_psoc *psoc,
+						const char *func)
+{
+	qdf_freq_t ll_lt_sap_freq = 0;
+	uint8_t scc_vdev_id;
+	bool is_scc = false;
+	uint8_t conn_idx = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm ctx");
+		return false;
+	}
+
+	ll_lt_sap_freq = policy_mgr_get_ll_lt_sap_freq(psoc);
+
+	if (!ll_lt_sap_freq)
+		return false;
+
+	/*
+	 * Restart ll_lt_sap if any other interface is present in SCC
+	 * with LL_LT_SAP.
+	 */
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_idx++) {
+		if (pm_conc_connection_list[conn_idx].mode ==
+		      PM_LL_LT_SAP_MODE)
+			continue;
+
+		if (ll_lt_sap_freq == pm_conc_connection_list[conn_idx].freq) {
+			scc_vdev_id = pm_conc_connection_list[conn_idx].vdev_id;
+			is_scc = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (is_scc) {
+		uint8_t ll_lt_sap_vdev_id =
+				wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc);
+
+		policymgr_nofl_debug("%s ll_lt_sap vdev %d with freq %d is in scc with vdev %d",
+				     func, ll_lt_sap_vdev_id, ll_lt_sap_freq,
+				     scc_vdev_id);
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * policy_mgr_ll_lt_sap_get_restart_freq_for_concurent_sap() - Get restart frequency
+ * for concurrent SAP which is in concurrency with LL_LT_SAP
+ * @pm_ctx: Policy manager context
+ * @vdev_id: Vdev id of the SAP for which restart freq is required
+ * @curr_freq: Current frequency of the SAP for which restart freq is required
+ * @ll_lt_sap_enabled: Indicates if ll_lt_sap is getting enabled or disabled
+ *
+ * This API returns user configured frequency if ll_lt_sap is going down and
+ * if ll_lt_sap is coming up it returns frequency according to ll_lt_sap
+ * concurrency.
+ *
+ * Return: Restart frequency
+ */
+static qdf_freq_t
+policy_mgr_ll_lt_sap_get_restart_freq_for_concurent_sap(
+					struct policy_mgr_psoc_priv_obj *pm_ctx,
+					uint8_t vdev_id,
+					qdf_freq_t curr_freq,
+					bool ll_lt_sap_enabled)
+{
+	qdf_freq_t user_config_freq;
+	uint8_t i;
+	QDF_STATUS status;
+	uint32_t channel_list[NUM_CHANNELS];
+	uint32_t num_channels;
+	qdf_freq_t restart_freq = 0;
+
+	/*
+	 * If ll_lt_sap is getting disabled, return user configured frequency
+	 * for concurrent SAP restart, if user configured frequency is not valid
+	 * frequency, remain on the same frequency and do not restart the SAP
+	 */
+	if (!ll_lt_sap_enabled) {
+		user_config_freq = policy_mgr_get_user_config_sap_freq(
+								pm_ctx->psoc,
+								vdev_id);
+		if (wlan_reg_is_enable_in_secondary_list_for_freq(
+							pm_ctx->pdev,
+							user_config_freq) &&
+		    policy_mgr_is_safe_channel(pm_ctx->psoc, user_config_freq))
+			return user_config_freq;
+		return curr_freq;
+	}
+
+	status = policy_mgr_get_valid_chans(pm_ctx->psoc, channel_list,
+					    &num_channels);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Error in getting valid channels");
+		return curr_freq;
+	}
+
+	/* return first valid 2.4 GHz frequency */
+	for (i = 0; i < num_channels; i++) {
+		if (wlan_reg_is_24ghz_ch_freq(channel_list[i])) {
+			if (!restart_freq)
+				restart_freq = channel_list[i];
+			/* Prefer SCC frequency */
+			if (policy_mgr_get_connection_count_with_ch_freq(
+							channel_list[i])) {
+				restart_freq = channel_list[i];
+				break;
+			}
+		}
+	}
+	return restart_freq;
+}
+
+void policy_mgr_ll_lt_sap_restart_concurrent_sap(struct wlan_objmgr_psoc *psoc,
+						 bool is_ll_lt_sap_enabled)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_conc_connection_info sap_info = {0};
+	qdf_freq_t restart_freq;
+	struct ch_params ch_params = {0};
+	uint8_t i;
+	enum sap_csa_reason_code csa_reason;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm context");
+		return;
+	}
+
+	qdf_mem_zero(&sap_info, sizeof(sap_info));
+
+	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)
+			continue;
+		if (PM_SAP_MODE == pm_conc_connection_list[i].mode ||
+		    PM_LL_LT_SAP_MODE == pm_conc_connection_list[i].mode) {
+			qdf_mem_copy(&sap_info, &pm_conc_connection_list[i],
+				     sizeof(sap_info));
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	/* No concurrent SAP or ll_lt_sap present, return */
+	if (!sap_info.in_use)
+		return;
+
+	if (sap_info.mode == PM_SAP_MODE) {
+		/*
+		 * For SBS case, no need to restart concurrent SAP as LL_LT_SAP
+		 * and concurrent SAP can be on different MACs
+		 */
+		if (policy_mgr_is_hw_sbs_capable(psoc))
+			return;
+
+		/*
+		 * If concurrent SAP is 2.4 GHz and ll_lt_sap is getting enabled
+		 * then there is no need to restart the concurrent SAP
+		 */
+		if (is_ll_lt_sap_enabled &&
+		    wlan_reg_is_24ghz_ch_freq(sap_info.freq))
+			return;
+
+		/*
+		 * If concurrent SAP is 5 GHz/6 GHz and ll_lt_sap is getting
+		 * disabled then there is no need to restart the concurrent SAP
+		 */
+		else if (!is_ll_lt_sap_enabled &&
+			 (wlan_reg_is_5ghz_ch_freq(sap_info.freq) ||
+			 wlan_reg_is_6ghz_chan_freq(sap_info.freq)))
+			return;
+
+		restart_freq =
+		policy_mgr_ll_lt_sap_get_restart_freq_for_concurent_sap(
+							pm_ctx,
+							sap_info.vdev_id,
+							sap_info.freq,
+							is_ll_lt_sap_enabled);
+		csa_reason = CSA_REASON_CONCURRENT_LL_LT_SAP_EVENT;
+	} else {
+		restart_freq = wlan_get_ll_lt_sap_restart_freq(pm_ctx->pdev,
+							       sap_info.freq,
+							       sap_info.vdev_id,
+							       &csa_reason);
+	}
+
+	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
+	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
+		policy_mgr_debug("channel switch is already in progress");
+		return;
+	}
+
+	if (!restart_freq) {
+		policy_mgr_err("Restart freq not found for vdev %d",
+			       sap_info.vdev_id);
+		return;
+	}
+	if (restart_freq == sap_info.freq) {
+		policy_mgr_debug("vdev %d restart freq %d same as current freq",
+				 sap_info.vdev_id, restart_freq);
+		return;
+	}
+	ch_params.ch_width = policy_mgr_get_ch_width(sap_info.bw);
+	wlan_reg_set_channel_params_for_pwrmode(pm_ctx->pdev, restart_freq,
+						0, &ch_params,
+						REG_CURRENT_PWR_MODE);
+	policy_mgr_debug("Restart SAP vdev %d with %d freq width %d",
+			 sap_info.vdev_id, restart_freq, ch_params.ch_width);
+
+	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
+		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc,
+							       sap_info.vdev_id,
+							       csa_reason);
+
+	policy_mgr_change_sap_channel_with_csa(psoc, sap_info.vdev_id,
+					       restart_freq,
+					       ch_params.ch_width, true);
+}

+ 5135 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -0,0 +1,5135 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_i.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "qdf_str.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_utility.h"
+#include "wlan_mlme_ucfg_api.h"
+#ifdef WLAN_FEATURE_11BE_MLO
+#include "wlan_mlo_mgr_cmn.h"
+#endif
+#include "wlan_policy_mgr_ll_sap.h"
+#include "wlan_cm_ucfg_api.h"
+#include "wlan_cm_roam_api.h"
+#include "wlan_scan_api.h"
+#include "wlan_nan_api.h"
+#include "wlan_mlo_link_force.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_NAN_DISC_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+};
+
+pm_dbs_pcl_second_connection_table_type
+		*second_connection_pcl_dbs_table;
+
+enum policy_mgr_pcl_type const
+	(*second_connection_pcl_non_dbs_table)[PM_MAX_ONE_CONNECTION_MODE]
+			[PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE];
+pm_dbs_pcl_third_connection_table_type
+		*third_connection_pcl_dbs_table;
+enum policy_mgr_pcl_type const
+	(*third_connection_pcl_non_dbs_table)[PM_MAX_TWO_CONNECTION_MODE]
+			[PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE];
+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,
+		uint32_t *pcl_ch, uint32_t *len,
+		uint8_t *pcl_weight, uint32_t weight_len,
+		bool all_matching_cxn_to_del,
+		uint8_t vdev_id)
+{
+	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;
+	}
+
+	*len = 0;
+	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);
+		/* Get the PCL */
+		status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
+					    pcl_weight, weight_len, vdev_id);
+		policy_mgr_debug("Get PCL to FW for mode:%d", mode);
+		/* 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;
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * policy_mgr_get_pcl_concurrent_connetions() - Get concurrent connections
+ * those will affect PCL fetching for the given vdev id
+ * @psoc: PSOC object information
+ * @mode: Connection Mode
+ * @vdev_id: vdev id
+ * @vdev_ids: vdev id list of the concurrent connections
+ * @vdev_ids_size: size of the vdev id list
+ *
+ * Return: number of the concurrent connections
+ */
+static uint32_t
+policy_mgr_get_pcl_concurrent_connetions(struct wlan_objmgr_psoc *psoc,
+					 enum policy_mgr_con_mode mode,
+					 uint8_t vdev_id, uint8_t *vdev_ids,
+					 uint32_t vdev_ids_size)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t num_related = 0;
+	bool is_ml_sta, has_same_band = false;
+	uint8_t vdev_id_with_diff_band = WLAN_INVALID_VDEV_ID;
+	uint8_t num_ml = 0, num_non_ml = 0, ml_vdev_id;
+	uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t freq = 0, ml_freq;
+	int i;
+
+	if (!vdev_ids || !vdev_ids_size) {
+		policy_mgr_err("Invalid parameters");
+		return num_related;
+	}
+
+	if (mode != PM_STA_MODE) {
+		vdev_ids[0] = vdev_id;
+		return 1;
+	}
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d is not present", vdev_id);
+		goto out;
+	}
+
+	if (wlan_vdev_mlme_is_link_sta_vdev(vdev)) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		policy_mgr_debug("ignore ML STA link vdev %d", vdev_id);
+		goto out;
+	}
+
+	is_ml_sta = wlan_vdev_mlme_is_mlo_vdev(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+
+	policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx,
+					       &num_non_ml, non_ml_idx,
+					       freq_list, vdev_id_list);
+	for (i = 0;
+	     i < num_non_ml + num_ml && num_related < vdev_ids_size; i++) {
+		if (vdev_id_list[i] == vdev_id) {
+			vdev_ids[num_related++] = vdev_id;
+			freq = freq_list[i];
+			break;
+		}
+	}
+
+	/* No existing connection for the vdev id */
+	if (!freq)
+		goto out;
+
+	for (i = 0; i < num_ml && num_related < vdev_ids_size; i++) {
+		ml_vdev_id = vdev_id_list[ml_idx[i]];
+		if (ml_vdev_id == vdev_id)
+			continue;
+
+		/* If it's ML STA, return vdev ids for all links */
+		if (is_ml_sta) {
+			policy_mgr_debug("vdev_ids[%d]: %d",
+					 num_related, ml_vdev_id);
+			vdev_ids[num_related++] = ml_vdev_id;
+			continue;
+		}
+
+		ml_freq = freq_list[ml_idx[i]];
+		if (wlan_reg_is_24ghz_ch_freq(ml_freq) ==
+		    wlan_reg_is_24ghz_ch_freq(freq)) {
+			if (policy_mgr_are_sbs_chan(psoc, freq, ml_freq) &&
+			    wlan_cm_same_band_sta_allowed(psoc))
+				continue;
+
+			/*
+			 * If it's Non-ML STA, and its freq is within the same
+			 * band with one of the existing ML link, but can NOT
+			 * lead to SBS, return the original vdev id and vdev id
+			 * of the ML link within same band.
+			 */
+			policy_mgr_debug("vdev_ids[%d]: %d",
+					 num_related, ml_vdev_id);
+			vdev_ids[num_related++] = ml_vdev_id;
+			has_same_band = true;
+			break;
+		}
+
+		vdev_id_with_diff_band = ml_vdev_id;
+	}
+
+	/*
+	 * If it's Non-ML STA, and ML STA is present but the links are
+	 * within different band or (within same band but can lead to SBS and
+	 * same band STA is allowed), return original vdev id and vdev id of
+	 * any ML link within different band.
+	 */
+	if (!has_same_band && vdev_id_with_diff_band != WLAN_INVALID_VDEV_ID) {
+		policy_mgr_debug("vdev_ids[%d]: %d",
+				 num_related, vdev_id_with_diff_band);
+
+		if (num_related < vdev_ids_size)
+			vdev_ids[num_related++] = vdev_id_with_diff_band;
+	}
+
+out:
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	return num_related;
+}
+#else
+static inline uint32_t
+policy_mgr_get_pcl_concurrent_connetions(struct wlan_objmgr_psoc *psoc,
+					 enum policy_mgr_con_mode mode,
+					 uint8_t vdev_id, uint8_t *vdev_ids,
+					 uint32_t vdev_ids_size)
+{
+	if (!vdev_ids || !vdev_ids_size) {
+		policy_mgr_err("Invalid parameters");
+		return 0;
+	}
+
+	vdev_ids[0] = vdev_id;
+	return 1;
+}
+#endif
+
+QDF_STATUS policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc *psoc,
+					  enum policy_mgr_con_mode mode,
+					  uint32_t *pcl_ch, uint32_t *len,
+					  uint8_t *pcl_weight,
+					  uint32_t weight_len,
+					  uint8_t vdev_id)
+{
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t ids[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t num_del = 0, total_del = 0, id_num = 0;
+	int i;
+
+	policy_mgr_debug("get pcl for existing conn:%d vdev id %d",
+			 mode, vdev_id);
+	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);
+	id_num = policy_mgr_get_pcl_concurrent_connetions(psoc, mode,
+							  vdev_id, ids,
+							  QDF_ARRAY_SIZE(ids));
+	if (!id_num || id_num > MAX_NUMBER_OF_CONC_CONNECTIONS) {
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	*len = 0;
+
+	/* Check, store and temp delete the mode's parameter */
+	for (i = 0; i < id_num; i++) {
+		policy_mgr_store_and_del_conn_info_by_vdev_id(psoc,
+							      ids[i],
+							      &info[i],
+							      &num_del);
+		total_del += num_del;
+	}
+
+	/* Get the PCL */
+	status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
+				    pcl_weight, weight_len, vdev_id);
+	policy_mgr_debug("Get PCL to FW for mode:%d", mode);
+	/* Restore the connection info */
+	policy_mgr_restore_deleted_conn_info(psoc, info, total_del);
+
+out:
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+QDF_STATUS
+policy_mgr_get_pcl_for_scc_in_same_mode(struct wlan_objmgr_psoc *psoc,
+					enum policy_mgr_con_mode mode,
+					uint32_t *pcl_ch, uint32_t *len,
+					uint8_t *pcl_weight,
+					uint32_t weight_len,
+					uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	qdf_freq_t vdev_freq;
+	QDF_STATUS status;
+	uint8_t num_del = 0;
+
+	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, vdev_id, &vdev_freq);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Fail to get channel by vdev id %d", vdev_id);
+		return status;
+	}
+
+	policy_mgr_debug("get pcl for existing conn:%d vdev id %d",
+			 mode, vdev_id);
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_store_and_del_conn_info_by_chan_and_mode(psoc,
+							    vdev_freq,
+							    mode,
+							    info,
+							    &num_del);
+	status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
+				    pcl_weight, weight_len, vdev_id);
+	if (num_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, info, num_del);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+
+void
+polic_mgr_send_pcl_to_fw(struct wlan_objmgr_psoc *psoc,
+			 enum QDF_OPMODE mode)
+{
+	uint32_t conn_idx = 0;
+	mac_handle_t mac_handle = cds_get_context(QDF_MODULE_ID_SME);
+	uint8_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;
+	}
+
+	for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_idx++) {
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		if (!(pm_conc_connection_list[conn_idx].mode ==
+		      PM_STA_MODE &&
+		      pm_conc_connection_list[conn_idx].in_use)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			continue;
+		}
+
+		vdev_id = pm_conc_connection_list[conn_idx].vdev_id;
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+		/*
+		 * Avoid sending PCL when roaming is in progress. PCL
+		 * gets updated to firmware once roaming is done
+		 */
+		if (mode == QDF_SAP_MODE &&
+		    wlan_cm_roaming_in_progress(pm_ctx->pdev,
+						vdev_id)) {
+			policy_mgr_debug("Roaming is in progress, don't stop RSO for vdev_id: %d",
+					 vdev_id);
+			continue;
+		}
+
+		pm_ctx->sme_cbacks.sme_rso_stop_cb(
+				mac_handle, vdev_id,
+				REASON_DRIVER_DISABLED,
+				RSO_SET_PCL);
+
+		policy_mgr_set_pcl_for_existing_combo(pm_ctx->psoc, PM_STA_MODE,
+						      vdev_id);
+		pm_ctx->sme_cbacks.sme_rso_start_cb(
+				mac_handle, vdev_id,
+				REASON_DRIVER_ENABLED,
+				RSO_SET_PCL);
+	}
+}
+
+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.
+	 */
+
+	if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
+						       NULL) > 0) &&
+	    mode != QDF_STA_MODE)
+		polic_mgr_send_pcl_to_fw(psoc, mode);
+
+	/* do we need to change the HW mode */
+	if (!policy_mgr_is_hw_dbs_capable(psoc))
+		return;
+
+	policy_mgr_check_n_start_opportunistic_timer(psoc);
+	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
+		ml_nlink_conn_change_notify(
+			psoc, session_id, ml_nlink_ap_stopped_evt, NULL);
+}
+
+/**
+ * policy_mgr_update_valid_ch_freq_list() - Update policy manager valid ch list
+ * @pm_ctx: policy manager context data
+ * @reg_ch_list: Regulatory channel list
+ * @is_client: true if caller is a client, false if it is a beaconing entity
+ *
+ * When regulatory component channel list is updated this internal function is
+ * called to update policy manager copy of valid channel list.
+ *
+ * Return: QDF_STATUS_SUCCESS on success other qdf error status code
+ */
+static void
+policy_mgr_update_valid_ch_freq_list(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				     struct regulatory_channel *reg_ch_list,
+				     bool is_client)
+{
+	uint32_t i, j = 0, ch_freq;
+	enum channel_state state;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		ch_freq = reg_ch_list[i].center_freq;
+		if (is_client)
+			state = wlan_reg_get_channel_state_for_pwrmode(
+							pm_ctx->pdev, ch_freq,
+							REG_CURRENT_PWR_MODE);
+		else
+			state =
+			wlan_reg_get_channel_state_from_secondary_list_for_freq(
+							pm_ctx->pdev, ch_freq);
+
+		if (state != CHANNEL_STATE_DISABLE &&
+		    state != CHANNEL_STATE_INVALID) {
+			pm_ctx->valid_ch_freq_list[j] =
+				reg_ch_list[i].center_freq;
+			j++;
+		}
+	}
+	pm_ctx->valid_ch_freq_list_count = j;
+}
+
+#ifdef FEATURE_WLAN_CH_AVOID_EXT
+void
+policy_mgr_set_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx,
+				     struct ch_avoid_ind_type *freq_list)
+{
+	pm_ctx->restriction_mask = freq_list->restriction_mask;
+}
+
+uint32_t
+policy_mgr_get_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx)
+{
+	return pm_ctx->restriction_mask;
+}
+#endif
+
+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;
+	uint32_t i;
+	struct ch_avoid_ind_type *freq_list;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	policy_mgr_update_valid_ch_freq_list(pm_ctx, chan_list, false);
+
+	if (!avoid_freq_ind) {
+		policy_mgr_debug("avoid_freq_ind NULL");
+		return;
+	}
+
+	/*
+	 * The ch_list buffer can accommodate 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.chan_cnt >=
+			NUM_CHANNELS ?
+			NUM_CHANNELS : avoid_freq_ind->chan_list.chan_cnt;
+
+	freq_list = &avoid_freq_ind->freq_list;
+	policy_mgr_set_freq_restriction_mask(pm_ctx, freq_list);
+
+	for (i = 0; i < pm_ctx->unsafe_channel_count; i++)
+		pm_ctx->unsafe_channel_list[i] =
+			avoid_freq_ind->chan_list.chan_freq_list[i];
+
+	policy_mgr_debug("Channel list update, received %d avoided channels",
+			 pm_ctx->unsafe_channel_count);
+}
+
+QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc,
+					  qdf_freq_t *chan_freq_list,
+					  uint16_t chan_cnt)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t i;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->unsafe_channel_count = chan_cnt >= NUM_CHANNELS ?
+			NUM_CHANNELS : chan_cnt;
+
+	for (i = 0; i < pm_ctx->unsafe_channel_count; i++)
+		pm_ctx->unsafe_channel_list[i] = chan_freq_list[i];
+
+	policy_mgr_debug("Channel list init, received %d avoided channels",
+			 pm_ctx->unsafe_channel_count);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc,
+					      uint32_t *pcl_channels,
+					      uint32_t *len,
+					      uint8_t *weight_list,
+					      uint32_t weight_len)
+{
+	uint32_t current_channel_list[NUM_CHANNELS];
+	uint8_t org_weight_list[NUM_CHANNELS];
+	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;
+	uint8_t scc_on_lte_coex = 0;
+	uint32_t nan_2g_freq, nan_5g_freq;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (len) {
+		current_channel_count = QDF_MIN(*len, NUM_CHANNELS);
+	} else {
+		policy_mgr_err("invalid number of channel length");
+		return;
+	}
+
+	if (!pm_ctx->unsafe_channel_count)
+		return;
+
+	qdf_mem_copy(current_channel_list, pcl_channels,
+		     current_channel_count * sizeof(*current_channel_list));
+	qdf_mem_zero(pcl_channels,
+		     current_channel_count * sizeof(*pcl_channels));
+
+	qdf_mem_copy(org_weight_list, weight_list, NUM_CHANNELS);
+	qdf_mem_zero(weight_list, weight_len);
+
+	policy_mgr_get_sta_sap_scc_lte_coex_chnl(psoc, &scc_on_lte_coex);
+	nan_2g_freq =
+		policy_mgr_mode_specific_get_channel(pm_ctx->psoc,
+						     PM_NAN_DISC_MODE);
+	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc);
+
+	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 && scc_on_lte_coex &&
+		    policy_mgr_is_sta_sap_scc(psoc, current_channel_list[i])) {
+			policy_mgr_debug("CH %d unsafe ignored when STA present on it",
+					 current_channel_list[i]);
+			is_unsafe = 0;
+		} else if (is_unsafe &&
+			   (nan_2g_freq == current_channel_list[i] ||
+			    nan_5g_freq == current_channel_list[i]) &&
+			    policy_mgr_is_force_scc(pm_ctx->psoc) &&
+			 policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(pm_ctx->psoc)) {
+			is_unsafe = 0;
+		}
+
+		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 wlan_objmgr_psoc *psoc,
+					uint32_t *pcl_list_org,
+					uint8_t *weight_list_org,
+					uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+	bool allow_go_scc_on_dfs_chn = false;
+	bool dfs_master_capable = false;
+	uint8_t sta_sap_scc_on_dfs_chnl = 0;
+	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("context is NULL");
+		return status;
+	}
+
+	status = ucfg_mlme_get_dfs_master_capability(psoc, &dfs_master_capable);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get dfs master capable");
+		return status;
+	}
+
+	status = policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc,
+						&sta_sap_scc_on_dfs_chnl);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get sta_sap_scc_on_dfs_chnl");
+		return status;
+	}
+
+	if (dfs_master_capable && sta_sap_scc_on_dfs_chnl &&
+	    pm_ctx->cfg.go_force_scc == GO_FORCE_SCC_STRICT) {
+		allow_go_scc_on_dfs_chn = true;
+	}
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if ((!wlan_reg_is_passive_or_disable_for_pwrmode(
+			pm_ctx->pdev, pcl_list_org[i],
+			REG_CURRENT_PWR_MODE)) ||
+		    (allow_go_scc_on_dfs_chn &&
+		     wlan_reg_is_dfs_for_freq(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,
+						uint32_t *pcl_list_org,
+						uint8_t *weight_list_org,
+						uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+	uint32_t pcl_list[NUM_CHANNELS];
+	uint8_t weight_list[NUM_CHANNELS];
+	bool ok;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (*pcl_len_org > NUM_CHANNELS) {
+		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
+		return status;
+	}
+	for (i = 0; i < *pcl_len_org; i++) {
+		status = policy_mgr_is_chan_ok_for_dnbs(psoc, pcl_list_org[i],
+							&ok);
+
+		if (QDF_IS_STATUS_ERROR(status)) {
+			policy_mgr_err("Not able to check DNBS eligibility");
+			return status;
+		}
+		if (ok) {
+			pcl_list[pcl_len] = pcl_list_org[i];
+			weight_list[pcl_len++] = weight_list_org[i];
+		}
+	}
+
+	qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org));
+	qdf_mem_zero(weight_list_org, *pcl_len_org);
+	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
+	qdf_mem_copy(weight_list_org, weight_list, pcl_len);
+	*pcl_len_org = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint32_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc,
+				enum policy_mgr_con_mode mode,
+				uint32_t *vdev_id)
+{
+	uint32_t idx = 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 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) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return pm_conc_connection_list[idx].freq;
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	}
+
+	return 0;
+}
+
+QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc,
+				  bool *skip_dfs_channel)
+{
+	bool sta_sap_scc_on_dfs_chan;
+	bool dfs_master_capable;
+	QDF_STATUS status;
+
+	status = ucfg_mlme_get_dfs_master_capability(psoc,
+						     &dfs_master_capable);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get dfs master capable");
+		return status;
+	}
+
+	*skip_dfs_channel = false;
+	if (!dfs_master_capable) {
+		policy_mgr_debug("skip DFS ch for SAP/Go dfs master cap %d",
+				 dfs_master_capable);
+		*skip_dfs_channel = true;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+
+	if (policy_mgr_is_hw_dbs_capable(psoc)) {
+		if ((policy_mgr_is_special_mode_active_5g(psoc,
+							  PM_P2P_CLIENT_MODE) ||
+		     policy_mgr_is_special_mode_active_5g(psoc, PM_STA_MODE)) &&
+		    !sta_sap_scc_on_dfs_chan) {
+			policy_mgr_debug("skip DFS ch from pcl for DBS SAP/Go");
+			*skip_dfs_channel = true;
+		}
+	} else {
+		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 non-DBS SAP/Go");
+			*skip_dfs_channel = true;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_modify_sap_pcl_based_on_dfs() - filter out DFS channel if needed
+ * @psoc: pointer to soc
+ * @pcl_list_org: channel list to filter out
+ * @weight_list_org: weight of channel list
+ * @pcl_len_org: length of channel list
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_dfs(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *pcl_list_org,
+		uint8_t *weight_list_org,
+		uint32_t *pcl_len_org)
+{
+	size_t i, pcl_len = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool skip_dfs_channel = false;
+	QDF_STATUS status;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (*pcl_len_org > NUM_CHANNELS) {
+		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = policy_mgr_skip_dfs_ch(psoc, &skip_dfs_channel);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get dfs channel skip info");
+		return status;
+	}
+
+	if (!skip_dfs_channel)
+		return QDF_STATUS_SUCCESS;
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (!wlan_reg_is_dfs_in_secondary_list_for_freq(
+							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_sap_pcl_based_on_nol(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t *pcl_list_org,
+		uint8_t *weight_list_org,
+		uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+	uint32_t pcl_list[NUM_CHANNELS];
+	uint8_t weight_list[NUM_CHANNELS];
+	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 (*pcl_len_org > NUM_CHANNELS) {
+		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (!wlan_reg_is_disable_in_secondary_list_for_freq(
+		    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, *pcl_len_org * sizeof(*pcl_list_org));
+	qdf_mem_zero(weight_list_org, *pcl_len_org);
+	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
+	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_pcl_based_on_srd(struct wlan_objmgr_psoc *psoc,
+				   uint32_t *pcl_list_org,
+				   uint8_t *weight_list_org,
+				   uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+	uint32_t pcl_list[NUM_CHANNELS];
+	uint8_t weight_list[NUM_CHANNELS];
+	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 (*pcl_len_org > NUM_CHANNELS) {
+		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
+		return QDF_STATUS_E_FAILURE;
+	}
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (wlan_reg_is_etsi_srd_chan_for_freq(
+		    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, *pcl_len_org * sizeof(*pcl_list_org));
+	qdf_mem_zero(weight_list_org, *pcl_len_org);
+	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
+	qdf_mem_copy(weight_list_org, weight_list, pcl_len);
+	*pcl_len_org = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_modify_pcl_based_on_indoor() - filter out indoor channel if needed
+ * @psoc: pointer to soc
+ * @pcl_list_org: channel list to filter out
+ * @weight_list_org: weight of channel list
+ * @pcl_len_org: length of channel list
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+policy_mgr_modify_pcl_based_on_indoor(struct wlan_objmgr_psoc *psoc,
+				      uint32_t *pcl_list_org,
+				      uint8_t *weight_list_org,
+				      uint32_t *pcl_len_org)
+{
+	uint32_t i, pcl_len = 0;
+	uint32_t pcl_list[NUM_CHANNELS];
+	uint8_t weight_list[NUM_CHANNELS];
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool include_indoor_channel, sta_sap_scc_on_indoor_channel_allowed;
+	QDF_STATUS status;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (*pcl_len_org > NUM_CHANNELS) {
+		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = ucfg_mlme_get_indoor_channel_support(psoc,
+						      &include_indoor_channel);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get indoor channel skip info");
+		return status;
+	}
+
+	/*
+	 * If STA SAP scc is allowed on indoor channels, and if STA/P2P
+	 * client is present on 5 GHz channel, include indoor channels
+	 */
+	sta_sap_scc_on_indoor_channel_allowed =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+	if (!include_indoor_channel && sta_sap_scc_on_indoor_channel_allowed &&
+	    (policy_mgr_is_special_mode_active_5g(psoc, PM_P2P_CLIENT_MODE) ||
+	     policy_mgr_is_special_mode_active_5g(psoc, PM_STA_MODE)))
+		include_indoor_channel = true;
+
+	if (include_indoor_channel) {
+		policy_mgr_debug("Indoor channels allowed. PCL not modified for indoor channels");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (wlan_reg_is_freq_indoor_in_secondary_list(pm_ctx->pdev,
+							pcl_list_org[i])) {
+			policy_mgr_debug("Remove freq: %d from PCL as it's indoor",
+					 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, *pcl_len_org * sizeof(*pcl_list_org));
+	qdf_mem_zero(weight_list_org, *pcl_len_org);
+	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
+	qdf_mem_copy(weight_list_org, weight_list, pcl_len);
+	*pcl_len_org = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_modify_sap_pcl_for_6G_channels() - filter out the
+ * 6GHz channels where SCC is not supported.
+ * @psoc: pointer to soc
+ * @pcl_list_org: channel list to filter out
+ * @weight_list_org: weight of channel list
+ * @pcl_len_org: length of channel list
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+policy_mgr_modify_sap_pcl_for_6G_channels(struct wlan_objmgr_psoc *psoc,
+					  uint32_t *pcl_list_org,
+					  uint8_t *weight_list_org,
+					  uint32_t *pcl_len_org)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t pcl_list[NUM_CHANNELS];
+	uint8_t weight_list[NUM_CHANNELS];
+	uint32_t vdev_id = 0, pcl_len = 0, i;
+	struct wlan_objmgr_vdev *vdev;
+	qdf_freq_t sta_gc_6ghz_freq = 0;
+	uint32_t ap_pwr_type_6g = 0;
+	bool indoor_ch_support = false;
+	bool keep_6ghz_sta_cli_conn;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (*pcl_len_org > NUM_CHANNELS) {
+		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
+		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].mode == PM_STA_MODE ||
+		    pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE) &&
+		    pm_conc_connection_list[i].in_use) {
+			if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(pm_conc_connection_list[i].freq))
+				continue;
+			sta_gc_6ghz_freq = pm_conc_connection_list[i].freq;
+			vdev_id = pm_conc_connection_list[i].vdev_id;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (!sta_gc_6ghz_freq)
+		return QDF_STATUS_SUCCESS;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d is not present", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* If STA is present in 6GHz PSC, STA+SAP SCC is allowed
+	 * only for the following combinations:
+	 *
+	 * VLP STA + SAP - Allowed with VLP Power
+	 * LPI STA + SAP - Allowed with VLP power if channel supports VLP.
+	 * LPI STA + SAP - Allowed with LPI power if gindoor_channel_support=1
+	 */
+	ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(vdev);
+	policy_mgr_debug("STA power type : %d", ap_pwr_type_6g);
+
+	ucfg_mlme_get_indoor_channel_support(psoc, &indoor_ch_support);
+	keep_6ghz_sta_cli_conn = wlan_reg_get_keep_6ghz_sta_cli_connection(
+								pm_ctx->pdev);
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_list_org[i])) {
+			if (!WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(pcl_list_org[i]) ||
+			    keep_6ghz_sta_cli_conn)
+				continue;
+			if (ap_pwr_type_6g == REG_VERY_LOW_POWER_AP)
+				goto add_freq;
+			else if (ap_pwr_type_6g == REG_INDOOR_AP &&
+				 (!wlan_reg_is_freq_indoor(pm_ctx->pdev,
+							   pcl_list_org[i]) ||
+				  indoor_ch_support))
+				goto add_freq;
+			else
+				continue;
+		}
+add_freq:
+		pcl_list[pcl_len] = pcl_list_org[i];
+		weight_list[pcl_len++] = weight_list_org[i];
+	}
+
+	qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org));
+	qdf_mem_zero(weight_list_org, *pcl_len_org * sizeof(*weight_list_org));
+	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
+	qdf_mem_copy(weight_list_org, weight_list, pcl_len);
+	*pcl_len_org = pcl_len;
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_channel_mcc_with_non_sap() - Helper function to check if channel
+ * is MCC with exist non-movable connections.
+ * @psoc: pointer to SOC
+ * @chan_freq: channel frequency to check
+ *
+ * Return: true if is MCC with exist non-movable connections, otherwise false.
+ */
+static bool policy_mgr_channel_mcc_with_non_sap(struct wlan_objmgr_psoc *psoc,
+						qdf_freq_t chan_freq)
+{
+	uint32_t i, connection_of_2ghz = 0;
+	qdf_freq_t conc_freq;
+	bool is_mcc = false, check_only_dbs = 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 false;
+	}
+
+	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 &&
+		    WLAN_REG_IS_24GHZ_CH_FREQ(pm_conc_connection_list[i].freq))
+			connection_of_2ghz++;
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (connection_of_2ghz >= 2)
+		check_only_dbs = true;
+
+	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 &&
+		    (pm_conc_connection_list[i].mode == PM_STA_MODE ||
+		     pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE ||
+		     pm_conc_connection_list[i].mode == PM_P2P_GO_MODE)) {
+			conc_freq = pm_conc_connection_list[i].freq;
+			if (conc_freq != chan_freq &&
+			    ((check_only_dbs &&
+			      policy_mgr_2_freq_same_mac_in_dbs(pm_ctx,
+								chan_freq,
+								conc_freq)) ||
+			     policy_mgr_2_freq_always_on_same_mac(psoc,
+								  chan_freq,
+								  conc_freq))) {
+				is_mcc = true;
+				break;
+			}
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return is_mcc;
+}
+
+/**
+ * policy_mgr_modify_sap_pcl_filter_mcc() - API to filter out MCC channel with
+ * existing non-SAP connection frequency from SAP PCL list.
+ * @psoc: pointer to SOC
+ * @pcl_list_org: channel list to filter out
+ * @weight_list_org: weight of channel list
+ * @pcl_len_org: length of channel list
+ * @mode: Policy manager connection mode
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+policy_mgr_modify_sap_pcl_filter_mcc(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *pcl_list_org,
+				     uint8_t *weight_list_org,
+				     uint32_t *pcl_len_org,
+				     enum policy_mgr_con_mode mode)
+{
+	uint32_t i, pcl_len = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	if (mode == PM_LL_LT_SAP_MODE)
+		return QDF_STATUS_SUCCESS;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (*pcl_len_org > NUM_CHANNELS) {
+		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!policy_mgr_is_force_scc(psoc)) {
+		policy_mgr_debug("force SCC is not prefer, skip!");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (policy_mgr_channel_mcc_with_non_sap(psoc, pcl_list_org[i]))
+			continue;
+
+		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;
+}
+
+/**
+ * policy_mgr_modify_sap_go_4th_conc_disallow() - filter out channel that
+ * is not allowed for 4th sap/go connection
+ * @psoc: pointer to soc
+ * @mode: interface mode
+ * @pcl_list_org: channel list to filter out
+ * @weight_list_org: weight of channel list
+ * @pcl_len_org: length of channel list
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS policy_mgr_modify_sap_go_4th_conc_disallow(
+		struct wlan_objmgr_psoc *psoc,
+		enum policy_mgr_con_mode mode,
+		uint32_t *pcl_list_org,
+		uint8_t *weight_list_org,
+		uint32_t *pcl_len_org)
+{
+	size_t i, pcl_len = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t num_connections;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (*pcl_len_org > NUM_CHANNELS) {
+		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	num_connections = policy_mgr_get_connection_count(psoc);
+	if (num_connections < 3)
+		goto end;
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		if (policy_mgr_allow_4th_new_freq(psoc, pcl_list_org[i],
+						  mode, 0)) {
+			pcl_list_org[pcl_len] = pcl_list_org[i];
+			weight_list_org[pcl_len++] = weight_list_org[i];
+		}
+	}
+
+	*pcl_len_org = pcl_len;
+end:
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_pcl_modification_for_sap(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t *pcl_channels, uint8_t *pcl_weight,
+			uint32_t *len, uint32_t weight_len,
+			enum policy_mgr_con_mode mode)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool mandatory_modified_pcl = false;
+	bool nol_modified_pcl = false;
+	bool dfs_modified_pcl = false;
+	bool indoor_modified_pcl = false;
+	bool passive_modified_pcl = false;
+	bool band_6ghz_modified_pcl = false;
+	bool fourth_conc_modified_pcl = false;
+	bool modified_final_pcl = false;
+	bool srd_chan_enabled;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* check the channel avoidance list for beaconing entities */
+	policy_mgr_update_with_safe_channel_list(psoc, pcl_channels,
+						 len, pcl_weight, weight_len);
+
+	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 mandatory modified pcl for SAP");
+			return status;
+		}
+		mandatory_modified_pcl = true;
+	}
+
+	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 nol modified pcl for SAP");
+		return status;
+	}
+	nol_modified_pcl = true;
+
+	status = policy_mgr_modify_sap_pcl_based_on_dfs(
+			psoc, pcl_channels, pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get dfs modified pcl for SAP");
+		return status;
+	}
+	dfs_modified_pcl = true;
+
+	wlan_mlme_get_srd_master_mode_for_vdev(psoc, QDF_SAP_MODE,
+					       &srd_chan_enabled);
+
+	if (!srd_chan_enabled) {
+		status = policy_mgr_modify_pcl_based_on_srd
+				(psoc, pcl_channels, pcl_weight, len);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			policy_mgr_err("Failed to modify SRD in pcl for SAP");
+			return status;
+		}
+	}
+
+	status = policy_mgr_modify_pcl_based_on_indoor(psoc, pcl_channels,
+						       pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get indoor modified pcl for SAP");
+		return status;
+	}
+	indoor_modified_pcl = true;
+
+	status = policy_mgr_filter_passive_ch(pm_ctx->pdev,
+					      pcl_channels, len);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to filter passive channels");
+		return INVALID_CHANNEL_ID;
+	}
+	passive_modified_pcl = true;
+
+	status = policy_mgr_modify_sap_pcl_for_6G_channels(psoc,
+							   pcl_channels,
+							   pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to modify pcl for 6G channels");
+		return status;
+	}
+	band_6ghz_modified_pcl = true;
+
+	status = policy_mgr_modify_sap_go_4th_conc_disallow(psoc,
+							    PM_SAP_MODE,
+							    pcl_channels,
+							    pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to modify pcl for 4th sap channels");
+		return status;
+	}
+	fourth_conc_modified_pcl = true;
+
+	status = policy_mgr_modify_sap_pcl_filter_mcc(psoc,
+						      pcl_channels,
+						      pcl_weight, len,
+						      mode);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to modify pcl for filter mcc");
+		return status;
+	}
+
+	modified_final_pcl = true;
+	policy_mgr_debug("%d %d %d %d %d %d %d %d",
+			 mandatory_modified_pcl,
+			 nol_modified_pcl,
+			 dfs_modified_pcl,
+			 indoor_modified_pcl,
+			 passive_modified_pcl,
+			 band_6ghz_modified_pcl,
+			 fourth_conc_modified_pcl,
+			 modified_final_pcl);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS policy_mgr_pcl_modification_for_p2p_go(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t *pcl_channels, uint8_t *pcl_weight,
+			uint32_t *len, uint32_t weight_len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	bool srd_chan_enabled;
+
+	/* check the channel avoidance list for beaconing entities */
+	policy_mgr_update_with_safe_channel_list(psoc, pcl_channels,
+						 len, pcl_weight, weight_len);
+
+	status = policy_mgr_modify_pcl_based_on_enabled_channels(
+			psoc, pcl_channels, pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get modified pcl for GO");
+		return status;
+	}
+
+	status = policy_mgr_modify_sap_pcl_based_on_dfs(
+			psoc, pcl_channels, pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get dfs modified pcl for GO");
+		return status;
+	}
+
+	wlan_mlme_get_srd_master_mode_for_vdev(psoc, QDF_P2P_GO_MODE,
+					       &srd_chan_enabled);
+
+	if (!srd_chan_enabled) {
+		status = policy_mgr_modify_pcl_based_on_srd
+				(psoc, pcl_channels, pcl_weight, len);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			policy_mgr_err("Failed to modify SRD in pcl for GO");
+			return status;
+		}
+	}
+	status = policy_mgr_modify_sap_go_4th_conc_disallow(psoc,
+							    PM_P2P_GO_MODE,
+							    pcl_channels,
+							    pcl_weight, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to modify pcl for 4th go channels");
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_LL_LT_SAP
+#ifdef WLAN_FEATURE_LL_LT_SAP_6G_SUPPORT
+static bool policy_mgr_is_6G_chan_valid_for_ll_sap(qdf_freq_t freq)
+{
+	if (!wlan_reg_is_6ghz_chan_freq(freq))
+		return true;
+
+	if (wlan_reg_is_6ghz_psc_chan_freq(freq) &&
+	    wlan_reg_is_6ghz_unii5_chan_freq(freq))
+		return true;
+
+	return false;
+}
+#else
+static inline bool policy_mgr_is_6G_chan_valid_for_ll_sap(qdf_freq_t freq)
+{
+	if (!wlan_reg_is_6ghz_chan_freq(freq))
+		return true;
+
+	return false;
+}
+#endif
+
+static bool policy_mgr_is_dynamic_sbs_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return false;
+
+	return (policy_mgr_is_hw_sbs_capable(psoc) &&
+		policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx));
+}
+
+/**
+ * policy_mgr_is_sbs_mac0_freq() - Check if the given frequency is
+ * sbs frequency on mac0 for static sbs case.
+ * @psoc: psoc pointer
+ * @freq: Frequency which needs to be checked.
+ *
+ * Return: true/false.
+ */
+static bool policy_mgr_is_sbs_mac0_freq(struct wlan_objmgr_psoc *psoc,
+					qdf_freq_t freq)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct policy_mgr_freq_range *freq_range;
+
+	if (policy_mgr_is_dynamic_sbs_enabled(psoc))
+		return false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return false;
+
+	freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS];
+
+	if (policy_mgr_is_freq_on_mac_id(freq_range, freq, 0))
+		return true;
+
+	return false;
+}
+
+static QDF_STATUS policy_mgr_pcl_modification_for_ll_lt_sap(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t *pcl_channels, uint8_t *pcl_weight,
+			uint32_t *len, uint32_t weight_len)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t pcl_list[NUM_CHANNELS], orig_len = *len;
+	uint8_t weight_list[NUM_CHANNELS];
+	uint32_t i, pcl_len = 0;
+	bool sbs_mac0_modified_pcl = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_pcl_modification_for_sap(
+		psoc, pcl_channels, pcl_weight, len, weight_len,
+		PM_LL_LT_SAP_MODE);
+
+	for (i = 0; i < *len; i++) {
+		/* Remove passive/dfs/6G invalid channel for LL_LT_SAP */
+		if (wlan_reg_is_24ghz_ch_freq(pcl_channels[i]) ||
+		    wlan_reg_is_passive_for_freq(
+					pm_ctx->pdev,
+					pcl_channels[i]) ||
+		    wlan_reg_is_dfs_for_freq(
+					pm_ctx->pdev,
+					pcl_channels[i]) ||
+		    !policy_mgr_is_6G_chan_valid_for_ll_sap(pcl_channels[i]))
+			continue;
+
+		/* Remove mac0 frequencies for static SBS case */
+		if (policy_mgr_is_sbs_mac0_freq(psoc, pcl_channels[i])) {
+			sbs_mac0_modified_pcl = true;
+			continue;
+		}
+
+		pcl_list[pcl_len] = pcl_channels[i];
+		weight_list[pcl_len++] = pcl_weight[i];
+	}
+
+	if (orig_len == pcl_len)
+		return QDF_STATUS_SUCCESS;
+
+	qdf_mem_zero(pcl_channels, *len * sizeof(*pcl_channels));
+	qdf_mem_zero(pcl_weight, *len);
+	qdf_mem_copy(pcl_channels, pcl_list, pcl_len * sizeof(*pcl_channels));
+	qdf_mem_copy(pcl_weight, weight_list, pcl_len);
+	*len = pcl_len;
+
+	policy_mgr_debug("sbs_mac0_modified_pcl %d, PCL after ll sap modification",
+			 sbs_mac0_modified_pcl);
+	policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+policy_mgr_pcl_modification_for_ll_lt_sap(struct wlan_objmgr_psoc *psoc,
+					  uint32_t *pcl_channels,
+					  uint8_t *pcl_weight,
+					  uint32_t *len, uint32_t weight_len)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl(
+			struct wlan_objmgr_psoc *psoc,
+			uint32_t *pcl_channels, uint8_t *pcl_weight,
+			uint32_t *len, uint32_t weight_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, weight_len, mode);
+		break;
+	case PM_P2P_GO_MODE:
+		status = policy_mgr_pcl_modification_for_p2p_go(
+			psoc, pcl_channels, pcl_weight, len, weight_len);
+		break;
+	case PM_STA_MODE:
+	case PM_P2P_CLIENT_MODE:
+	case PM_NAN_DISC_MODE:
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case PM_LL_LT_SAP_MODE:
+		status = policy_mgr_pcl_modification_for_ll_lt_sap(
+			psoc, pcl_channels, pcl_weight, len, weight_len);
+		break;
+	default:
+		policy_mgr_err("unexpected mode %d", mode);
+		break;
+	}
+
+	return status;
+}
+
+#ifdef FEATURE_FOURTH_CONNECTION
+static enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port(
+				struct wlan_objmgr_psoc *psoc,
+				enum policy_mgr_con_mode mode,
+				enum policy_mgr_conc_priority_mode pref)
+{
+	enum policy_mgr_three_connection_mode fourth_index = 0;
+	enum policy_mgr_pcl_type pcl;
+
+	/* Will be enhanced for other types of 4 port conc (NaN etc.)
+	 * in future.
+	 */
+	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
+		policy_mgr_err("Can't find index for 4th port pcl table for non dbs capable");
+		return PM_MAX_PCL_TYPE;
+	}
+
+	/* SAP and P2P Go have same result in 4th port pcl table */
+	if (mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE)
+		mode = PM_SAP_MODE;
+	else if (mode == PM_P2P_CLIENT_MODE)
+		mode = PM_STA_MODE;
+
+	if (mode != PM_STA_MODE && mode != PM_SAP_MODE &&
+	    mode != PM_NDI_MODE) {
+		policy_mgr_err("Can't start 4th port if not STA, SAP, NDI");
+		return PM_MAX_PCL_TYPE;
+	}
+
+	fourth_index =
+		policy_mgr_get_fourth_connection_pcl_table_index(psoc);
+	if (PM_MAX_THREE_CONNECTION_MODE == fourth_index) {
+		policy_mgr_err("Can't find index for 4th port pcl table");
+		return PM_MAX_PCL_TYPE;
+	}
+	policy_mgr_debug("Index for 4th port pcl table: %d", fourth_index);
+
+	pcl = fourth_connection_pcl_dbs_sbs_table[fourth_index][mode][pref];
+
+	return pcl;
+}
+#else
+static inline enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port(
+				struct wlan_objmgr_psoc *psoc,
+				enum policy_mgr_con_mode mode,
+				enum policy_mgr_conc_priority_mode pref)
+{return PM_MAX_PCL_TYPE; }
+#endif
+
+QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
+			      enum policy_mgr_con_mode mode,
+			      uint32_t *pcl_channels, uint32_t *len,
+			      uint8_t *pcl_weight, uint32_t weight_len,
+			      uint8_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t num_connections = 0;
+	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;
+	uint32_t orig_pcl_len;
+
+	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 vdev_id:%d",
+			 num_connections, pm_ctx->cur_conc_system_pref, mode,
+			 vdev_id);
+
+	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_non_dbs_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_non_dbs_table)
+				[third_index][mode][conc_system_pref];
+		}
+		break;
+	case 3:
+		pcl = policy_mgr_get_pcl_4_port(psoc, mode, conc_system_pref);
+		break;
+	default:
+		policy_mgr_err("unexpected num_connections value %d",
+			num_connections);
+		break;
+	}
+
+	/* 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, mode, pcl_channels,
+					     pcl_weight, weight_len, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get channel list:%d", status);
+		return status;
+	}
+
+	if (!*len) {
+		policymgr_nofl_debug("Total PCL Chan %d", *len);
+		return QDF_STATUS_SUCCESS;
+	}
+	orig_pcl_len = *len;
+	policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
+	policy_mgr_mode_specific_modification_on_pcl(
+		psoc, pcl_channels, pcl_weight, len, 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;
+	}
+
+	if (orig_pcl_len != *len) {
+		policy_mgr_debug("PCL after modification");
+		policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
+	}
+
+	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_FREQ(
+		    pm_conc_connection_list[0].freq)) {
+			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_FREQ(
+		    pm_conc_connection_list[0].freq)) {
+			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_FREQ(
+		    pm_conc_connection_list[0].freq)) {
+			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_FREQ(
+		    pm_conc_connection_list[0].freq)) {
+			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_NAN_DISC_MODE == pm_conc_connection_list[0].mode) {
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_NAN_DISC_24_1x1;
+		else
+			index = PM_NAN_DISC_24_2x2;
+	} else if (PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) {
+		index = PM_LL_LT_SAP_5_2x2;
+	}
+
+	policy_mgr_debug("mode:%d freq:%d chain:%d index:%d",
+			 pm_conc_connection_list[0].mode,
+			 pm_conc_connection_list[0].freq,
+			 pm_conc_connection_list[0].chain_mask, index);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return index;
+}
+
+/*
+ * policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc() -
+ * This function checks connection mode is in scc or not and returns
+ * index value based on mode and prvided index inputs.
+ *
+ * @scc_2g_1x1: index of scc_2g_1x1 for provided concurrency
+ * @scc_2g_2x2: index of scc_2g_2x2 for provided concurrency
+ * @scc_5g_1x1: index of scc_5g_1x1 for provided concurrency
+ * @scc_5g_2x2: index of scc_5g_2x2 for provided concurrency
+ *
+ * Return: policy_mgr_two_connection_mode index
+ */
+static enum policy_mgr_two_connection_mode
+policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+			enum policy_mgr_two_connection_mode scc_2g_1x1,
+			enum policy_mgr_two_connection_mode scc_2g_2x2,
+			enum policy_mgr_two_connection_mode scc_5g_1x1,
+			enum policy_mgr_two_connection_mode scc_5g_2x2)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	if (pm_conc_connection_list[0].freq ==
+	    pm_conc_connection_list[1].freq) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(
+		    pm_conc_connection_list[0].freq)) {
+			if (POLICY_MGR_ONE_ONE ==
+					pm_conc_connection_list[0].chain_mask)
+				index = scc_2g_1x1;
+			else
+				index = scc_2g_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = scc_5g_1x1;
+			else
+				index = scc_5g_2x2;
+		}
+	}
+	return index;
+}
+
+/*
+ * policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc() -
+ * This function checks connection mode is in mcc or not and returns
+ * index value based on mode and prvided index inputs.
+ *
+ * @mcc_2g_1x1: index of mcc_2g_1x1 for provided concurrency
+ * @mcc_2g_2x2: index of mcc_2g_2x2 for provided concurrency
+ * @mcc_5g_1x1: index of mcc_5g_1x1 for provided concurrency
+ * @mcc_5g_2x2: index of mcc_5g_2x2 for provided concurrency
+ * @mcc_24_5_1x1: index of mcc_24_5_1x1 for provided concurrency
+ * @mcc_24_5_2x2: index of mcc_24_5_2x2 for provided concurrency
+ *
+ * Return: policy_mgr_two_connection_mode index
+ */
+static enum policy_mgr_two_connection_mode
+policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(
+			struct wlan_objmgr_psoc *psoc,
+			enum policy_mgr_two_connection_mode mcc_2g_1x1,
+			enum policy_mgr_two_connection_mode mcc_2g_2x2,
+			enum policy_mgr_two_connection_mode mcc_5g_1x1,
+			enum policy_mgr_two_connection_mode mcc_5g_2x2,
+			enum policy_mgr_two_connection_mode mcc_24_5_1x1,
+			enum policy_mgr_two_connection_mode mcc_24_5_2x2)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	if (policy_mgr_are_2_freq_on_same_mac(psoc,
+					      pm_conc_connection_list[0].freq,
+					      pm_conc_connection_list[1].freq)
+					     ) {
+		if ((WLAN_REG_IS_24GHZ_CH_FREQ(
+		    pm_conc_connection_list[0].freq)) &&
+		    (WLAN_REG_IS_24GHZ_CH_FREQ(
+		    pm_conc_connection_list[1].freq))) {
+			if (POLICY_MGR_ONE_ONE ==
+					pm_conc_connection_list[0].chain_mask)
+				index = mcc_2g_1x1;
+			else
+				index = mcc_2g_2x2;
+		} else if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
+			   pm_conc_connection_list[0].freq)) &&
+			   !(WLAN_REG_IS_24GHZ_CH_FREQ(
+			   pm_conc_connection_list[1].freq))) {
+			if (POLICY_MGR_ONE_ONE ==
+					pm_conc_connection_list[0].chain_mask)
+				index = mcc_5g_1x1;
+			else
+				index = mcc_5g_2x2;
+		} else {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = mcc_24_5_1x1;
+			else
+				index = mcc_24_5_2x2;
+		}
+	}
+	return index;
+}
+
+/*
+ * policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs() -
+ * This function checks connection mode is in dbs or sbs and returns index
+ * value based on mode and prvided index inputs.
+ *
+ * @sbs_5g_1x1: index of sbs_5g_1x1 for provided concurrency
+ * @sbs_5g_2x2: index of sbs_5g_2x2 for provided concurrency
+ * @dbs_1x1: index of dbs_1x1 for provided concurrency
+ * @dbs_2x2: index of dbs_2x2 for provided concurrency
+ *
+ * Return: policy_mgr_two_connection_mode index
+ */
+static enum policy_mgr_two_connection_mode
+policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
+			struct wlan_objmgr_psoc *psoc,
+			enum policy_mgr_two_connection_mode sbs_5g_1x1,
+			enum policy_mgr_two_connection_mode sbs_5g_2x2,
+			enum policy_mgr_two_connection_mode dbs_1x1,
+			enum policy_mgr_two_connection_mode dbs_2x2)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	if (!policy_mgr_are_2_freq_on_same_mac(psoc,
+					       pm_conc_connection_list[0].freq,
+					       pm_conc_connection_list[1].freq)
+					      ) {
+		/* SBS */
+		if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
+		    pm_conc_connection_list[0].freq)) &&
+		    !(WLAN_REG_IS_24GHZ_CH_FREQ(
+		    pm_conc_connection_list[1].freq))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = sbs_5g_1x1;
+			else
+				index = sbs_5g_2x2;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = dbs_1x1;
+			else
+				index = dbs_2x2;
+		}
+	}
+
+	return index;
+}
+
+/*
+ * policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta() -
+ * Get third connection pcl table index when ML STA is present
+ * @sbs_5g_1x1: index of sbs_5g_1x1 for provided concurrency
+ * @sbs_5g_2x2: index of sbs_5g_2x2 for provided concurrency
+ * @dbs_1x1: index of dbs_1x1 for provided concurrency
+ * @dbs_2x2: index of dbs_2x2 for provided concurrency
+ *
+ * This function checks connection mode is in dbs or sbs when two ML STA links
+ * are active and returns index value based on mode and provided index inputs.
+ *
+ * Return: policy_mgr_two_connection_mode index
+ */
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta(
+			struct wlan_objmgr_psoc *psoc,
+			enum policy_mgr_two_connection_mode sbs_5g_1x1,
+			enum policy_mgr_two_connection_mode sbs_5g_2x2,
+			enum policy_mgr_two_connection_mode dbs_1x1,
+			enum policy_mgr_two_connection_mode dbs_2x2)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	if (!policy_mgr_2_freq_always_on_same_mac(
+				psoc,
+				pm_conc_connection_list[0].freq,
+				pm_conc_connection_list[1].freq)) {
+		/* SBS */
+		if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
+		    pm_conc_connection_list[0].freq)) &&
+		    !(WLAN_REG_IS_24GHZ_CH_FREQ(
+		    pm_conc_connection_list[1].freq))) {
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = sbs_5g_1x1;
+			else
+				index = sbs_5g_2x2;
+		} else {
+		/* DBS */
+			if (POLICY_MGR_ONE_ONE ==
+				pm_conc_connection_list[0].chain_mask)
+				index = dbs_1x1;
+			else
+				index = dbs_2x2;
+		}
+	}
+
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_cli_sap(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_P2P_CLI_SAP_SCC_24_1x1,
+					PM_P2P_CLI_SAP_SCC_24_2x2,
+					PM_P2P_CLI_SAP_SCC_5_1x1,
+					PM_P2P_CLI_SAP_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_P2P_CLI_SAP_MCC_24_1x1,
+					PM_P2P_CLI_SAP_MCC_24_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);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_P2P_CLI_SAP_SBS_5_1x1,
+					PM_P2P_CLI_SAP_SBS_5_2x2,
+					PM_P2P_CLI_SAP_DBS_1x1,
+					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(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_STA_SAP_SCC_24_1x1,
+					PM_STA_SAP_SCC_24_2x2,
+					PM_STA_SAP_SCC_5_1x1,
+					PM_STA_SAP_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_STA_SAP_MCC_24_1x1,
+					PM_STA_SAP_MCC_24_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);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_STA_SAP_SBS_5_1x1,
+					PM_STA_SAP_SBS_5_2x2,
+					PM_STA_SAP_DBS_1x1,
+					PM_STA_SAP_DBS_2x2);
+
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_sap_sap(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_SAP_SAP_SCC_24_1x1,
+					PM_SAP_SAP_SCC_24_2x2,
+					PM_SAP_SAP_SCC_5_1x1,
+					PM_SAP_SAP_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_SAP_SAP_MCC_24_1x1,
+					PM_SAP_SAP_MCC_24_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);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_SAP_SAP_SBS_5_1x1,
+					PM_SAP_SAP_SBS_5_2x2,
+					PM_SAP_SAP_DBS_1x1,
+					PM_SAP_SAP_DBS_2x2);
+
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_sta_go(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_STA_P2P_GO_SCC_24_1x1,
+					PM_STA_P2P_GO_SCC_24_2x2,
+					PM_STA_P2P_GO_SCC_5_1x1,
+					PM_STA_P2P_GO_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_STA_P2P_GO_MCC_24_1x1,
+					PM_STA_P2P_GO_MCC_24_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);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_STA_P2P_GO_SBS_5_1x1,
+					PM_STA_P2P_GO_SBS_5_2x2,
+					PM_STA_P2P_GO_DBS_1x1,
+					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(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_STA_P2P_CLI_SCC_24_1x1,
+					PM_STA_P2P_CLI_SCC_24_2x2,
+					PM_STA_P2P_CLI_SCC_5_1x1,
+					PM_STA_P2P_CLI_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_STA_P2P_CLI_MCC_24_1x1,
+					PM_STA_P2P_CLI_MCC_24_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);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_STA_P2P_CLI_SBS_5_1x1,
+					PM_STA_P2P_CLI_SBS_5_2x2,
+					PM_STA_P2P_CLI_DBS_1x1,
+					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(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_P2P_GO_P2P_CLI_SCC_24_1x1,
+					PM_P2P_GO_P2P_CLI_SCC_24_2x2,
+					PM_P2P_GO_P2P_CLI_SCC_5_1x1,
+					PM_P2P_GO_P2P_CLI_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_P2P_GO_P2P_CLI_MCC_24_1x1,
+					PM_P2P_GO_P2P_CLI_MCC_24_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);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_P2P_GO_P2P_CLI_SBS_5_1x1,
+					PM_P2P_GO_P2P_CLI_SBS_5_2x2,
+					PM_P2P_GO_P2P_CLI_DBS_1x1,
+					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(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_P2P_GO_SAP_SCC_24_1x1,
+					PM_P2P_GO_SAP_SCC_24_2x2,
+					PM_P2P_GO_SAP_SCC_5_1x1,
+					PM_P2P_GO_SAP_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_P2P_GO_SAP_MCC_24_1x1,
+					PM_P2P_GO_SAP_MCC_24_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);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_P2P_GO_SAP_SBS_5_1x1,
+					PM_P2P_GO_SAP_SBS_5_2x2,
+					PM_P2P_GO_SAP_DBS_1x1,
+					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(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+
+	if (policy_mgr_is_ml_vdev_id(psoc,
+				     pm_conc_connection_list[0].vdev_id) &&
+	    policy_mgr_is_ml_vdev_id(psoc,
+				     pm_conc_connection_list[1].vdev_id)) {
+		index =
+		policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta(
+					psoc,
+					PM_STA_STA_SBS_5_1x1,
+					PM_STA_STA_SBS_5_2x2,
+					PM_STA_STA_DBS_1x1,
+					PM_STA_STA_DBS_2x2);
+		if (index != PM_MAX_TWO_CONNECTION_MODE)
+			return index;
+	}
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_STA_STA_SCC_24_1x1,
+					PM_STA_STA_SCC_24_2x2,
+					PM_STA_STA_SCC_5_1x1,
+					PM_STA_STA_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_STA_STA_MCC_24_1x1,
+					PM_STA_STA_MCC_24_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);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_STA_STA_SBS_5_1x1,
+					PM_STA_STA_SBS_5_2x2,
+					PM_STA_STA_DBS_1x1,
+					PM_STA_STA_DBS_2x2);
+
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_cli_cli(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_P2P_CLI_P2P_CLI_SCC_24_1x1,
+					PM_P2P_CLI_P2P_CLI_SCC_24_2x2,
+					PM_P2P_CLI_P2P_CLI_SCC_5_1x1,
+					PM_P2P_CLI_P2P_CLI_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_P2P_CLI_P2P_CLI_MCC_24_1x1,
+					PM_P2P_CLI_P2P_CLI_MCC_24_2x2,
+					PM_P2P_CLI_P2P_CLI_MCC_5_1x1,
+					PM_P2P_CLI_P2P_CLI_MCC_5_2x2,
+					PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1,
+					PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2);
+
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_P2P_CLI_P2P_CLI_SBS_5_1x1,
+					PM_P2P_CLI_P2P_CLI_SBS_5_2x2,
+					PM_P2P_CLI_P2P_CLI_DBS_1x1,
+					PM_P2P_CLI_P2P_CLI_DBS_2x2);
+
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_go_go(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
+					PM_P2P_GO_P2P_GO_SCC_24_1x1,
+					PM_P2P_GO_P2P_GO_SCC_24_2x2,
+					PM_P2P_GO_P2P_GO_SCC_5_1x1,
+					PM_P2P_GO_P2P_GO_SCC_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
+					PM_P2P_GO_P2P_GO_MCC_24_1x1,
+					PM_P2P_GO_P2P_GO_MCC_24_2x2,
+					PM_P2P_GO_P2P_GO_MCC_5_1x1,
+					PM_P2P_GO_P2P_GO_MCC_5_2x2,
+					PM_P2P_GO_P2P_GO_MCC_24_5_1x1,
+					PM_P2P_GO_P2P_GO_MCC_24_5_2x2);
+	if (index != PM_MAX_TWO_CONNECTION_MODE)
+		return index;
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
+					PM_P2P_GO_P2P_GO_SBS_5_1x1,
+					PM_P2P_GO_P2P_GO_SBS_5_2x2,
+					PM_P2P_GO_P2P_GO_DBS_1x1,
+					PM_P2P_GO_P2P_GO_DBS_2x2);
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_nan_ndi(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].freq ==
+		pm_conc_connection_list[1].freq) {
+		/* Policy mgr only considers NAN Disc ch in 2.4GHz */
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_NAN_DISC_NDI_SCC_24_1x1;
+		else
+			index = PM_NAN_DISC_NDI_SCC_24_2x2;
+	/* MCC */
+	} else if (policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[0].freq,
+			pm_conc_connection_list[1].freq)) {
+		/* Policy mgr only considers NAN Disc ch in 2.4GHz */
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_NAN_DISC_NDI_MCC_24_1x1;
+		else
+			index = PM_NAN_DISC_NDI_MCC_24_2x2;
+	/* DBS */
+	} else {
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_NAN_DISC_NDI_DBS_1x1;
+		else
+			index = PM_NAN_DISC_NDI_DBS_2x2;
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_sta_nan(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].freq ==
+		pm_conc_connection_list[1].freq) {
+		/* Policy mgr only considers NAN Disc ch in 2.4GHz */
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_STA_NAN_DISC_SCC_24_1x1;
+		else
+			index = PM_STA_NAN_DISC_SCC_24_2x2;
+	/* MCC */
+	} else if (policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[0].freq,
+			pm_conc_connection_list[1].freq)) {
+		/* Policy mgr only considers NAN Disc ch in 2.4 GHz */
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_STA_NAN_DISC_MCC_24_1x1;
+		else
+			index = PM_STA_NAN_DISC_MCC_24_2x2;
+	/* DBS */
+	} else {
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_STA_NAN_DISC_DBS_1x1;
+		else
+			index = PM_STA_NAN_DISC_DBS_2x2;
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_sap_nan(
+					struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
+	/* SCC */
+	if (pm_conc_connection_list[0].freq ==
+		pm_conc_connection_list[1].freq) {
+		/* Policy mgr only considers NAN Disc ch in 2.4 GHz */
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_SAP_NAN_DISC_SCC_24_1x1;
+		else
+			index = PM_SAP_NAN_DISC_SCC_24_2x2;
+	/* MCC */
+	} else if (policy_mgr_are_2_freq_on_same_mac(psoc,
+			pm_conc_connection_list[0].freq,
+			pm_conc_connection_list[1].freq)) {
+		/* Policy mgr only considers NAN Disc ch in 2.4GHz */
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_SAP_NAN_DISC_MCC_24_1x1;
+		else
+			index = PM_SAP_NAN_DISC_MCC_24_2x2;
+	/* DBS */
+	} else {
+		if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
+			index = PM_SAP_NAN_DISC_DBS_1x1;
+		else
+			index = PM_SAP_NAN_DISC_DBS_2x2;
+	}
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_sta_ll_lt_sap(
+						struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+	enum policy_mgr_two_connection_mode sbs_5g_1x1;
+	enum policy_mgr_two_connection_mode sbs_5g_2x2;
+	qdf_freq_t sta_freq, sbs_cut_off_freq;
+
+	/*
+	 * LL_LT_SAP can not be in SCC so there will not be any scc index.
+	 * With LL_LT_SAP, MCC is possible only on 5 GHz
+	 */
+	if (policy_mgr_are_2_freq_on_same_mac(
+					psoc,
+					pm_conc_connection_list[0].freq,
+					pm_conc_connection_list[1].freq)) {
+		if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
+			   pm_conc_connection_list[0].freq)) &&
+			   !(WLAN_REG_IS_24GHZ_CH_FREQ(
+			   pm_conc_connection_list[1].freq))) {
+			if (POLICY_MGR_ONE_ONE ==
+					pm_conc_connection_list[0].chain_mask)
+				index = PM_STA_5_LL_LT_SAP_MCC_1x1;
+			else
+				index = PM_STA_5_LL_LT_SAP_MCC_2x2;
+
+			return index;
+		}
+	}
+
+	if (pm_conc_connection_list[0].mode == PM_STA_MODE)
+		sta_freq = pm_conc_connection_list[0].freq;
+	else
+		sta_freq = pm_conc_connection_list[1].freq;
+
+	sbs_cut_off_freq =  policy_mgr_get_sbs_cut_off_freq(psoc);
+
+	if (sta_freq < sbs_cut_off_freq) {
+		sbs_5g_1x1 = PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1;
+		sbs_5g_2x2 = PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2;
+	} else {
+		sbs_5g_1x1 = PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1;
+		sbs_5g_2x2 = PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2;
+	}
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
+						psoc, sbs_5g_1x1, sbs_5g_2x2,
+						PM_STA_24_LL_LT_SAP_DBS_1x1,
+						PM_STA_24_LL_LT_SAP_DBS_2x2);
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_sap_ll_lt_sap(
+						struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+	enum policy_mgr_two_connection_mode sbs_5g_1x1;
+	enum policy_mgr_two_connection_mode sbs_5g_2x2;
+	qdf_freq_t sap_freq, sbs_cut_off_freq;
+
+	if (pm_conc_connection_list[0].mode == PM_SAP_MODE)
+		sap_freq = pm_conc_connection_list[0].freq;
+	else
+		sap_freq = pm_conc_connection_list[1].freq;
+
+	sbs_cut_off_freq =  policy_mgr_get_sbs_cut_off_freq(psoc);
+
+	if (sap_freq < sbs_cut_off_freq) {
+		sbs_5g_1x1 = PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1;
+		sbs_5g_2x2 = PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2;
+	} else {
+		sbs_5g_1x1 = PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1;
+		sbs_5g_2x2 = PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2;
+	}
+
+	/*
+	 * LL_LT_SAP can not be in SCC so there will not be any scc index.
+	 * For LL_LT_SAP + SAP, MCC is not possible, so there will be only
+	 * sbs or dbs index
+	 */
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
+						psoc, sbs_5g_1x1, sbs_5g_2x2,
+						PM_SAP_24_LL_LT_SAP_DBS_1x1,
+						PM_SAP_24_LL_LT_SAP_DBS_2x2);
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_go_ll_lt_sap(
+						struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+	enum policy_mgr_two_connection_mode sbs_5g_1x1;
+	enum policy_mgr_two_connection_mode sbs_5g_2x2;
+	qdf_freq_t go_freq, sbs_cut_off_freq;
+
+	/*
+	 * LL_LT_SAP can not be in SCC so there will not be any scc index.
+	 * With LL_LT_SAP, MCC is possible only on 5 GHz
+	 */
+	if (policy_mgr_are_2_freq_on_same_mac(
+					psoc,
+					pm_conc_connection_list[0].freq,
+					pm_conc_connection_list[1].freq)) {
+		if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
+			   pm_conc_connection_list[0].freq)) &&
+			   !(WLAN_REG_IS_24GHZ_CH_FREQ(
+			   pm_conc_connection_list[1].freq))) {
+			if (POLICY_MGR_ONE_ONE ==
+					pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_GO_5_LL_LT_SAP_MCC_1x1;
+			else
+				index = PM_P2P_GO_5_LL_LT_SAP_MCC_2x2;
+
+			return index;
+		}
+	}
+
+	if (pm_conc_connection_list[0].mode == PM_P2P_GO_MODE)
+		go_freq = pm_conc_connection_list[0].freq;
+	else
+		go_freq = pm_conc_connection_list[1].freq;
+
+	sbs_cut_off_freq =  policy_mgr_get_sbs_cut_off_freq(psoc);
+
+	if (go_freq < sbs_cut_off_freq) {
+		sbs_5g_1x1 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1;
+		sbs_5g_2x2 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2;
+	} else {
+		sbs_5g_1x1 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1;
+		sbs_5g_2x2 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2;
+	}
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
+						psoc, sbs_5g_1x1, sbs_5g_2x2,
+						PM_P2P_GO_24_LL_LT_SAP_DBS_1x1,
+						PM_P2P_GO_24_LL_LT_SAP_DBS_2x2);
+	return index;
+}
+
+static enum policy_mgr_two_connection_mode
+policy_mgr_get_third_connection_pcl_table_index_cli_ll_lt_sap(
+						struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_two_connection_mode index;
+	enum policy_mgr_two_connection_mode sbs_5g_1x1;
+	enum policy_mgr_two_connection_mode sbs_5g_2x2;
+	qdf_freq_t cli_freq, sbs_cut_off_freq;
+
+	/*
+	 * LL_LT_SAP can not be in SCC so there will not be any scc index.
+	 * With LL_LT_SAP, MCC is possible only on 5 GHz
+	 */
+	if (policy_mgr_are_2_freq_on_same_mac(
+					psoc,
+					pm_conc_connection_list[0].freq,
+					pm_conc_connection_list[1].freq)) {
+		if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
+			   pm_conc_connection_list[0].freq)) &&
+			   !(WLAN_REG_IS_24GHZ_CH_FREQ(
+			   pm_conc_connection_list[1].freq))) {
+			if (POLICY_MGR_ONE_ONE ==
+					pm_conc_connection_list[0].chain_mask)
+				index = PM_P2P_CLI_5_LL_LT_SAP_MCC_1x1;
+			else
+				index = PM_P2P_CLI_5_LL_LT_SAP_MCC_2x2;
+
+			return index;
+		}
+	}
+
+	if (pm_conc_connection_list[0].mode == PM_P2P_GO_MODE)
+		cli_freq = pm_conc_connection_list[0].freq;
+	else
+		cli_freq = pm_conc_connection_list[1].freq;
+
+	sbs_cut_off_freq =  policy_mgr_get_sbs_cut_off_freq(psoc);
+
+	if (cli_freq < sbs_cut_off_freq) {
+		sbs_5g_1x1 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1;
+		sbs_5g_2x2 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2;
+	} else {
+		sbs_5g_1x1 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1;
+		sbs_5g_2x2 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2;
+	}
+
+	index =
+	policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
+					psoc, sbs_5g_1x1, sbs_5g_2x2,
+					PM_P2P_CLI_24_LL_LT_SAP_DBS_1x1,
+					PM_P2P_CLI_24_LL_LT_SAP_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(psoc);
+	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(psoc);
+	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(psoc);
+	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(psoc);
+	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(psoc);
+	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(psoc);
+	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(psoc);
+	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(psoc);
+	else if (((PM_NAN_DISC_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_NAN_DISC_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_sta_nan(psoc);
+	else if (((PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_NDI_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_NDI_MODE == pm_conc_connection_list[0].mode) &&
+		(PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode)))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_nan_ndi(psoc);
+	else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
+		  (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_NAN_DISC_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_nan(psoc);
+	else if ((pm_conc_connection_list[0].mode == PM_P2P_GO_MODE) &&
+		 (pm_conc_connection_list[1].mode == PM_P2P_GO_MODE))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_go_go(psoc);
+
+	else if ((pm_conc_connection_list[0].mode == PM_P2P_CLIENT_MODE) &&
+		 (pm_conc_connection_list[1].mode == PM_P2P_CLIENT_MODE))
+		index =
+		policy_mgr_get_third_connection_pcl_table_index_cli_cli(psoc);
+
+	else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
+		  (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_LL_LT_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_ll_lt_sap(psoc);
+
+	else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
+		  (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_LL_LT_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_ll_lt_sap(psoc);
+
+	else if (((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) &&
+		  (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_LL_LT_SAP_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_ll_lt_sap(psoc);
+
+	else if (((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) &&
+		  (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) ||
+		((PM_LL_LT_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_ll_lt_sap(psoc);
+
+	policy_mgr_debug("mode0:%d mode1:%d freq0:%d freq1:%d chain:%d index:%d",
+			 pm_conc_connection_list[0].mode,
+			 pm_conc_connection_list[1].mode,
+			 pm_conc_connection_list[0].freq,
+			 pm_conc_connection_list[1].freq,
+			 pm_conc_connection_list[0].chain_mask, index);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return index;
+}
+
+#ifdef FEATURE_FOURTH_CONNECTION
+/**
+ * policy_mgr_get_index_for_3_given_freq_dbs() - Find the index for next
+ * connection for given 3 freq in DBS mode
+ * @pm_ctx: policy manager context
+ * @index: Index to return for next connection
+ * @freq1: freq of interface 1
+ * @freq2: freq of interface 2
+ * @freq3: freq of interface 3
+ *
+ * This function finds the index for next connection for 3 freq in DBS mode.
+ *
+ * Return: none
+ */
+static void
+policy_mgr_get_index_for_3_given_freq_dbs(
+	struct policy_mgr_psoc_priv_obj *pm_ctx,
+	enum policy_mgr_three_connection_mode *index,
+	qdf_freq_t freq1, qdf_freq_t freq2, qdf_freq_t freq3)
+{
+	/* If all freq are on same band */
+	if ((WLAN_REG_IS_24GHZ_CH_FREQ(freq1) ==
+	     WLAN_REG_IS_24GHZ_CH_FREQ(freq2) &&
+	    (WLAN_REG_IS_24GHZ_CH_FREQ(freq2) ==
+	     WLAN_REG_IS_24GHZ_CH_FREQ(freq3)))) {
+		policy_mgr_err("Invalid mode for all freq %d, %d and %d on same band",
+			       freq1, freq2, freq3);
+		return;
+	}
+
+	/*
+	 * If freq1 and freq2 are on same band and freq3 is on differet band and
+	 * is not sharing mac with any SAP. STA on same band is handled above,
+	 * so both SAP on same band mean STA cannot be on same band. This can
+	 * happen if SBS is not enabled.
+	 */
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1) ==
+	    WLAN_REG_IS_24GHZ_CH_FREQ(freq2)) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(freq3))
+			/*
+			 * As all 3 cannot be on same band, so if freq3 is
+			 * 2.4 GHZ mean both freq1 and freq2 are on 5 / 6 GHZ
+			 */
+			*index = PM_5_SCC_MCC_PLUS_24_DBS;
+		else
+			/*
+			 * As all 3 cannot be on same band, so if freq3 is
+			 * 5 / 6 GHZ, mean both freq1 and freq2 are on 2.4 GHZ.
+			 */
+			*index = PM_24_SCC_MCC_PLUS_5_DBS;
+		return;
+	}
+
+	/*
+	 * if freq1 and freq 2 are on different band (2 GHZ + 5 GHZ/6 GHZ DBS),
+	 * check with which freq the freq3 will share mac, and return index as
+	 * per it.
+	 */
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(freq3))
+		*index = PM_24_SCC_MCC_PLUS_5_DBS;
+	else
+		*index = PM_5_SCC_MCC_PLUS_24_DBS;
+}
+
+/**
+ * policy_mgr_get_index_for_3_given_freq_sbs() - Find the index for next
+ * connection for 3 given freq, in case current HW mode is SBS
+ * @pm_ctx: policy manager context
+ * @index: Index to return for next connection
+ * @freq1: freq of interface 1
+ * @freq2: freq of interface 2
+ * @freq3: freq of interface 3
+ *
+ * This function finds the index for next
+ * connection for 3 given freq, in case current HW mode is SBS
+ *
+ * Return: none
+ */
+static void policy_mgr_get_index_for_3_given_freq_sbs(
+	struct policy_mgr_psoc_priv_obj *pm_ctx,
+	enum policy_mgr_three_connection_mode *index,
+	qdf_freq_t freq1, qdf_freq_t freq2, qdf_freq_t freq3)
+{
+	qdf_freq_t sbs_cut_off_freq;
+	qdf_freq_t shared_5_ghz_freq = 0;
+
+	/*
+	 * Sanity check: At least 2 of the given freq needs to be creating SBS
+	 * separation for HW mode to be in SBS, if not it shouldn't have
+	 * entered this API.
+	 */
+	if (!policy_mgr_are_sbs_chan(pm_ctx->psoc, freq1, freq2) &&
+	    !policy_mgr_are_sbs_chan(pm_ctx->psoc, freq2, freq3) &&
+	    !policy_mgr_are_sbs_chan(pm_ctx->psoc, freq3, freq1)) {
+		policy_mgr_err("freq1 %d, freq2 %d and freq3 %d, none of the 2 connections/3 vdevs are leading to SBS",
+			       freq1, freq2, freq3);
+		return;
+	}
+
+	sbs_cut_off_freq =  policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
+	if (!sbs_cut_off_freq) {
+		policy_mgr_err("Invalid cutoff freq");
+		return;
+	}
+
+	/*
+	 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH
+	 * 5GHZ as well as LOW 5 GHZ, but one at a time) and one of the
+	 * freq is 2.4 GHZ, this mean that the new interface can come up on
+	 * 5 GHZ LOW or HIGH and HW mode will move the 2.4 GHZ link to
+	 * the other mac dynamically.
+	 */
+	if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx) &&
+	    (WLAN_REG_IS_24GHZ_CH_FREQ(freq1) ||
+	     WLAN_REG_IS_24GHZ_CH_FREQ(freq2) ||
+	     WLAN_REG_IS_24GHZ_CH_FREQ(freq3))) {
+		*index = PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS;
+		return;
+	}
+	/*
+	 * if freq1 on freq2 same mac, get the 5 / 6 GHZ freq from it check
+	 * and determine shared mac.
+	 */
+	if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq1, freq2)) {
+		/*
+		 * If freq1 is 2.4 GHZ that mean freq2 is 5 / 6 GHZ.
+		 * so take decision using freq2.
+		 */
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1))
+			shared_5_ghz_freq = freq2;
+		else
+			/* freq1 5 / 6 GHZ, use freq1 */
+			shared_5_ghz_freq = freq1;
+	} else if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq2, freq3)) {
+		/*
+		 * If freq2 is 2.4 GHZ that mean freq3 is 5 / 6 GHZ.
+		 * so take decision using freq3.
+		 */
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(freq2))
+			shared_5_ghz_freq = freq3;
+		else
+			/* freq2 5 / 6 GHZ, use freq1 */
+			shared_5_ghz_freq = freq2;
+	} else if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq3, freq1)) {
+		/*
+		 * If freq1 is 2.4 GHZ that mean freq3 is 5 / 6 GHZ.
+		 * so take decision using freq3.
+		 */
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1))
+			shared_5_ghz_freq = freq3;
+		else
+			/* freq1 5 / 6 GHZ, use freq1 */
+			shared_5_ghz_freq = freq1;
+	}
+
+	if (!shared_5_ghz_freq ||
+	    WLAN_REG_IS_24GHZ_CH_FREQ(shared_5_ghz_freq)) {
+		policy_mgr_err("shared_5_ghz_freq %d is not 5 / 6 GHZ",
+			       shared_5_ghz_freq);
+		return;
+	}
+
+	/* If shared 5 / 6 GHZ freq is low 5 GHZ, then return high 5 GHZ freq */
+	if (shared_5_ghz_freq < sbs_cut_off_freq)
+		*index = PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS;
+	else
+		*index = PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS;
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * policy_mgr_get_index_for_ml_sta_sap_dbs() - Find the index for next
+ * connection for ML STA + SAP, in case current HW mode is DBS and ML STA is
+ * 2.4 GHZ + 5 GHZ/6 GHZ OR if SBS is not supported.
+ * @pm_ctx: policy manager context
+ * @index: Index to return for next connection
+ * @sap_freq: SAP freq
+ * @sta_freq_list: STA freq list
+ * @ml_sta_idx: ML STA index in freq_list
+ *
+ * This function finds the index for next
+ * connection for ML STA + SAP, in case current HW mode is DBS and ML STA is
+ * 2.4 GHZ + 5 GHZ/6 GHZ OR if SBS is not supported.
+ *
+ * Return: none
+ */
+static void
+policy_mgr_get_index_for_ml_sta_sap_dbs(
+	struct policy_mgr_psoc_priv_obj *pm_ctx,
+	enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq,
+	qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx)
+{
+	/* If ML STA and SAP all are on same band */
+	if ((WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) ==
+	     WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) &&
+	    (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) ==
+	     WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq))) {
+		policy_mgr_err("Invalid mode for ML STA %d and %d are on same band as SAP %d",
+			       sta_freq_list[ml_sta_idx[0]],
+			       sta_freq_list[ml_sta_idx[1]], sap_freq);
+		return;
+	}
+
+	/*
+	 * If ML STA is MCC and SAP is on differet band and is not sharing mac
+	 * with any link. SAP on same band is handled above, so ML STA on same
+	 * band mean SAP cannot be on same band. This can happen if SBS is not
+	 * enabled.
+	 */
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) ==
+	    WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq))
+			/*
+			 * As all 3 cannot be on same band, so if SAP is 2.4 GHZ
+			 * mean both ML STA are on 5 / 6 GHZ
+			 */
+			*index = PM_STA_STA_5_SAP_24_DBS;
+		else
+			/*
+			 * As all 3 cannot be on same band, so if SAP is
+			 *  5 / 6 GHZ, mean both ML STA are on 2.4 GHZ.
+			 */
+			policy_mgr_err("Invalid mode for ML STA %d and %d are on 2.4 GHZ, sap freq %d",
+				       sta_freq_list[ml_sta_idx[0]],
+				       sta_freq_list[ml_sta_idx[1]], sap_freq);
+
+		return;
+	}
+
+	/*
+	 * if ML STA is 2 GHZ + 5 GHZ/6 GHZ DBS, check with which freq the SAP
+	 * will share mac, and return index as per it.
+	 */
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq))
+		*index = PM_STA_SAP_24_STA_5_DBS;
+	else
+		*index = PM_STA_SAP_5_STA_24_DBS;
+}
+
+/**
+ * policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs() - Find the index for next
+ * connection for ML STA + SAP, in case current HW mode is SBS but ML STA is
+ * with 2 GHz + 5/6 GHz.
+ * @pm_ctx: policy manager context
+ * @index: Index to return for next connection
+ * @sap_freq: SAP freq
+ * @sta_freq_list: STA freq list
+ * @ml_sta_idx: ML STA index in freq_list
+ *
+ * This function finds the index for next connection for ML STA + SAP,
+ * in case current HW mode is SBS but ML STA is with 2 GHz + 5/6 GHz.
+ *
+ * Return: none
+ */
+static void policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs(
+	struct policy_mgr_psoc_priv_obj *pm_ctx,
+	enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq,
+	qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx)
+{
+	bool sbs_24_shared_high_support =
+		policy_mgr_sbs_24_shared_with_high_5(pm_ctx);
+	bool sbs_24_shared_low_support =
+		policy_mgr_sbs_24_shared_with_low_5(pm_ctx);
+	qdf_freq_t sbs_cut_off_freq, ml_sta_5g_freq;
+	bool ml_sta_5g_low;
+
+	/* HW supports sbs but ml sta 2 home channels are not in sbs frequency
+	 * separation by check policy_mgr_are_sbs_chan.
+	 * It means one ml sta is 2.4 GHz, the other is 5/6 GHz.
+	 * The combinations handled by this API:
+	 * 2.4 GHz band    |  5 GHz low band  | 5/6 GHz high band |   PCL list
+	 * ----------------------------------------------------------------------
+	 * ML STA          |  ML STA+SAP      |               |   5 GHz High + 2.4 GHz
+	 * ML STA          |  ML STA+SAP      |               |   2.4 GHz(nhss)
+	 * ML STA          |  ML STA          | SAP           |   5 GHz Low + 2.4 GHz
+	 * ML STA          |  ML STA          | SAP           |   2.4 GHz (nhss)
+	 * ML STA          |  SAP             | ML STA        |   5 GHz High+ 2.4 GHz
+	 * ML STA          |  SAP             | ML STA        |   2.4 GHz (nlss)
+	 * ML STA          |                  | ML STA+SAP    |   5 GHz Low + 2.4 GHz
+	 * ML STA          |                  | ML STA+SAP    |   2.4 GHz (nlss)
+	 * ML STA+SAP      |  ML STA          |               |   5 GHz Low+5 GHz High
+	 * ML STA+SAP      |                  | ML STA        |   5 GHz Low+5 GHz High
+	 *
+	 * nhss: no high share supported
+	 * nlss: no low share supported
+	 */
+
+	if (!WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) &&
+	    !WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) {
+		policy_mgr_err("unexpected ml sta home freq to handle (%d %d)",
+			       sta_freq_list[ml_sta_idx[0]],
+			       sta_freq_list[ml_sta_idx[1]]);
+		return;
+	}
+	if (!sbs_24_shared_low_support && !sbs_24_shared_high_support) {
+		policy_mgr_err("unexpected sbs mode: low share %d high share %d",
+			       sbs_24_shared_low_support,
+			       sbs_24_shared_high_support);
+		return;
+	}
+	sbs_cut_off_freq =  policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
+	if (!sbs_cut_off_freq) {
+		policy_mgr_err("Invalid cutoff freq");
+		return;
+	}
+
+	if (!WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]))
+		ml_sta_5g_freq = sta_freq_list[ml_sta_idx[0]];
+	else
+		ml_sta_5g_freq = sta_freq_list[ml_sta_idx[1]];
+	if (ml_sta_5g_freq < sbs_cut_off_freq)
+		ml_sta_5g_low = true;
+	else
+		ml_sta_5g_low = false;
+
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq)) {
+		/* pcl 5 GHz Low+5 GHz High - PM_SCC_ON_5_CH_5G */
+		*index = PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS;
+	} else if (sap_freq < sbs_cut_off_freq) {
+		if ((ml_sta_5g_low && sbs_24_shared_high_support) ||
+		    (!ml_sta_5g_low && sbs_24_shared_low_support))
+			/* pcl 5 GHz High + 2.4 GHz -
+			 * PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G
+			 */
+			*index = PM_STA_24_STA_5_MCC_SAP_5_LOW_SBS;
+		else
+			*index = PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS;
+	} else {
+		if ((ml_sta_5g_low && sbs_24_shared_high_support) ||
+		    (!ml_sta_5g_low && sbs_24_shared_low_support))
+			/* pcl 5 GHz Low + 2.4 GHz -
+			 * PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G
+			 */
+			*index = PM_STA_24_STA_5_MCC_SAP_5_HIGH_SBS;
+		else
+			*index = PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS;
+	}
+	policy_mgr_debug("4th index %d sap freq %d ml sta 5g %d sbs_cut_off_freq %d support high share %d low share %d",
+			 *index, sap_freq, ml_sta_5g_freq, sbs_cut_off_freq,
+			 sbs_24_shared_high_support,
+			 sbs_24_shared_low_support);
+}
+
+/**
+ * policy_mgr_get_index_for_ml_sta_sap_sbs() - Find the index for next
+ * connection for ML STA + SAP, in case current HW mode is SBS or ML STA is
+ * with 5 GHZ + 5 GHZ/6 GHZ SBS separation.
+ * @pm_ctx: policy manager context
+ * @index: Index to return for next connection
+ * @sap_freq: SAP freq
+ * @sta_freq_list: STA freq list
+ * @ml_sta_idx: ML STA index in freq_list
+ *
+ * This function finds the index for next
+ * connection for ML STA + SAP, in case current HW mode is SBS or ML STA is
+ * with 5 GHZ + 5 GHZ/6 GHZ SBS separation.
+ *
+ * Return: none
+ */
+static void policy_mgr_get_index_for_ml_sta_sap_sbs(
+	struct policy_mgr_psoc_priv_obj *pm_ctx,
+	enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq,
+	qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx)
+{
+	qdf_freq_t sbs_cut_off_freq;
+	bool can_2ghz_share_low_high_5ghz =
+			policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx);
+
+	/*
+	 * Sanity check: At least one of the 3 combo (ML STA OR SAP + one of
+	 * ML STA link) needs to be creating SBS separation for
+	 * HW mode to be in SBS, if not it shouldn't have entered this API.
+	 */
+	if (!policy_mgr_are_sbs_chan(pm_ctx->psoc, sta_freq_list[ml_sta_idx[0]],
+				     sta_freq_list[ml_sta_idx[1]]) &&
+	    !policy_mgr_are_sbs_chan(pm_ctx->psoc, sap_freq,
+				     sta_freq_list[ml_sta_idx[0]]) &&
+	    !policy_mgr_are_sbs_chan(pm_ctx->psoc, sap_freq,
+				     sta_freq_list[ml_sta_idx[1]])) {
+		if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc)) {
+			policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs(
+				pm_ctx, index, sap_freq, sta_freq_list,
+				ml_sta_idx);
+			return;
+		}
+		policy_mgr_err("SAP freq (%d) and ML STA freq %d and %d, none of the 2 connections/3 vdevs are leading to SBS",
+			       sap_freq,
+			       sta_freq_list[ml_sta_idx[0]],
+			       sta_freq_list[ml_sta_idx[1]]);
+		return;
+	}
+
+	sbs_cut_off_freq =  policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
+	if (!sbs_cut_off_freq) {
+		policy_mgr_err("Invalid cutoff freq");
+		return;
+	}
+
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq)) {
+		/*
+		 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH
+		 * 5GHZ as well as LOW 5 GHZ, but one at a time) and SAP is
+		 * 2.4 GHZ, this mean that the new SAP can come up on 5 GHZ LOW
+		 * or HIGH and HW mode will move the 2.4 GHZ SAP to the other
+		 * mac dynamically.
+		 */
+		if (can_2ghz_share_low_high_5ghz) {
+			*index = PM_SAP_24_STA_5_STA_5_LOW_N_HIGH_SHARE_SBS;
+			return;
+		}
+		/*
+		 * if SAP is 2.4 GHZ that means both ML STA needs to
+		 * be with 5 GHZ + 5 GHZ/6 GHZ SBS separation. If not, it would
+		 * have failed the sanity check. So Get STA link with
+		 * which SAP freq is sharing mac and select index accordingly
+		 */
+		if (policy_mgr_2_freq_same_mac_in_sbs(
+						pm_ctx, sap_freq,
+						sta_freq_list[ml_sta_idx[0]])) {
+			/*
+			 * SAP is sharig mac with link ml_sta_idx[0], so check
+			 * if ml_sta_idx[0] is lower 5 GHZ or high 5 GHZ and
+			 * select index
+			 */
+			if (sta_freq_list[ml_sta_idx[0]] < sbs_cut_off_freq)
+				*index = PM_STA_5_LOW_SAP_24_MCC_STA_5_HIGH_SBS;
+			else
+				*index = PM_STA_5_HIGH_SAP_24_MCC_STA_5_LOW_SBS;
+		} else {
+			/*
+			 * SAP is sharig mac with link ml_sta_idx[1], so check
+			 * if ml_sta_idx[1] is lower 5 GHZ or high 5 GHZ and
+			 * select index
+			 */
+			if (sta_freq_list[ml_sta_idx[1]] < sbs_cut_off_freq)
+				*index = PM_STA_5_LOW_SAP_24_MCC_STA_5_HIGH_SBS;
+			else
+				*index = PM_STA_5_HIGH_SAP_24_MCC_STA_5_LOW_SBS;
+		}
+
+		return;
+	}
+
+	/* SAP freq is 5 GHZ or 6 GHZ and one ML sta is on 2.4 GHZ */
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) ||
+	    WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) {
+		/*
+		 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH
+		 * 5GHZ as well as LOW 5 GHZ, but one at a time) and one STA
+		 * link is 2.4 GHZ, this mean that the new SAP can come up on
+		 * 5 GHZ LOW or HIGH and HW mode will move the 2.4 GHZ link to
+		 * the other mac dynamically.
+		 */
+		if (can_2ghz_share_low_high_5ghz) {
+			*index = PM_STA_24_SAP_5_STA_5_LOW_N_HIGH_SHARE_SBS;
+			return;
+		}
+		/*
+		 * If (2 GHZ + 5 GHZ/6 GHZ) ML is MCC i.e Both sta links are on
+		 * same mac and SAP is on separate mac. This can happen if SBS
+		 * is not dynamic and is low 5 GHZ shared, with ML STA on 5 GHZ
+		 * low along with SAP 5Ghz high and vice versa. As both links
+		 * of ML STA and sap are on different mac, so set index based
+		 * on sap frequency whether it is in 5 GHZ low band or 5 GHZ
+		 * high Band.
+		 */
+		if (policy_mgr_2_freq_same_mac_in_sbs(
+					pm_ctx, sta_freq_list[ml_sta_idx[0]],
+					sta_freq_list[ml_sta_idx[1]])) {
+			if (sap_freq < sbs_cut_off_freq)
+				*index = PM_STA_24_STA_5_HIGH_MCC_SAP_5_LOW_SBS;
+			else
+				*index = PM_STA_24_STA_5_LOW_MCC_SAP_5_HIGH_SBS;
+		} else {
+			/*
+			 * STA ML is (2 GHZ + 5 GHZ/6 GHZ) select as per the SAP
+			 * freq, as for current mode to be in SBS, SAP will
+			 * share mac with STA 2.4 GHZ Link or will not share
+			 * mac at all (2 GHZ + 5 GHZ/6 GHZ MCC). Other case i.e
+			 * 2 links on 5 GHZ and one STA link on 2 GHZ is DBS and
+			 * sanity check already taken care this at start of the
+			 * func.
+			 */
+			if (sap_freq < sbs_cut_off_freq)
+				*index = PM_STA_24_SAP_5_LOW_MCC_STA_5_HIGH_SBS;
+			else
+				*index = PM_STA_24_SAP_5_HIGH_MCC_STA_5_LOW_SBS;
+		}
+		return;
+	}
+	/*
+	 * If (5 GHZ + 5 GHZ/6 GHZ) ML is MCC i.e SAP is not sharing mac
+	 * with any link. This can happen if SBS is not dynamic and is
+	 * low 5 GHZ shared, with ML STA on 5 GHZ low along with SAP 5 GHZ
+	 * high and vice versa. As both ML sta link are on same mac and
+	 * sap is on different mac, so decide whether ML links are sharing
+	 * low 5 GHZ frequency or high 5 GHZ frequency based on sap frequency
+	 */
+	if (policy_mgr_2_freq_same_mac_in_sbs(
+				pm_ctx, sta_freq_list[ml_sta_idx[0]],
+				sta_freq_list[ml_sta_idx[1]])) {
+		if (sap_freq < sbs_cut_off_freq)
+			*index = PM_STA_STA_5_HIGH_MCC_SAP_5_LOW_SBS;
+		else
+			*index = PM_STA_STA_5_LOW_MCC_SAP_5_HIGH_SBS;
+	} else {
+		/*
+		 * STA ML is (5 GHZ + 5 GHZ/6 GHZ SBS/MCC), select as per the
+		 * SAP freq, as for current mode to be in SBS, SAP will share
+		 * mac with the corresponding low/high 5 GHZ
+		 * (5 GHZ + 5 GHZ/6 GHZ SBS) or will not share mac at all
+		 * (5 GHZ +5 GHZ/6 GHZ MCC). Other case sanity already
+		 * taken care at start of the func.
+		 */
+		if (sap_freq < sbs_cut_off_freq)
+			*index = PM_STA_SAP_5_LOW_STA_5_HIGH_SBS;
+		else
+			*index = PM_STA_SAP_5_HIGH_STA_5_LOW_SBS;
+	}
+}
+
+static void
+policy_mgr_get_index_for_ml_sta_sap(
+			struct policy_mgr_psoc_priv_obj *pm_ctx,
+			enum policy_mgr_three_connection_mode *index,
+			qdf_freq_t sap_freq, qdf_freq_t *sta_freq_list,
+			uint8_t *ml_sta_idx)
+{
+	/*
+	 * P2P GO/P2P CLI are treated as SAP to optimize as pcl
+	 * table is same for all three.
+	 */
+	policy_mgr_debug("channel: sap0: %d, ML STA link0: %d, ML STA link1: %d",
+			 sap_freq, sta_freq_list[ml_sta_idx[0]],
+			 sta_freq_list[ml_sta_idx[1]]);
+	if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc) ||
+	    policy_mgr_are_sbs_chan(pm_ctx->psoc, sta_freq_list[ml_sta_idx[0]],
+				    sta_freq_list[ml_sta_idx[1]])) {
+		/* if current mode is SBS or the ML STA is 5+5/6Ghz SBS */
+		policy_mgr_get_index_for_ml_sta_sap_sbs(pm_ctx, index,
+							sap_freq,
+							sta_freq_list,
+							ml_sta_idx);
+		return;
+	}
+	/*
+	 * current HW mode is DBS and ML STA is 2.4 GHZ + 5 GHZ or SBS
+	 * is not enabled
+	 */
+	policy_mgr_get_index_for_ml_sta_sap_dbs(pm_ctx, index, sap_freq,
+						sta_freq_list, ml_sta_idx);
+}
+
+static void
+policy_mgr_get_index_for_ml_sta_sap_sap(
+			struct policy_mgr_psoc_priv_obj *pm_ctx,
+			enum policy_mgr_three_connection_mode *index,
+			qdf_freq_t ml_sta_freq, qdf_freq_t sap_freq_1,
+			qdf_freq_t sap_freq_2)
+{
+	/*
+	 * P2P GO/P2P CLI are treated as SAP to optimize as pcl
+	 * table is same for all three.
+	 */
+	policy_mgr_debug("channel: ML sta0: %d, SAP0: %d, SAP1: %d",
+			 ml_sta_freq, sap_freq_1, sap_freq_2);
+	if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc))
+		/* if current mode is SBS */
+		return policy_mgr_get_index_for_3_given_freq_sbs(pm_ctx, index,
+							ml_sta_freq, sap_freq_1,
+							sap_freq_2);
+
+	/* current HW mode is DBS */
+	policy_mgr_get_index_for_3_given_freq_dbs(pm_ctx, index, ml_sta_freq,
+						  sap_freq_1, sap_freq_2);
+}
+
+#else /* WLAN_FEATURE_11BE_MLO */
+
+static inline void
+policy_mgr_get_index_for_ml_sta_sap(
+			struct policy_mgr_psoc_priv_obj *pm_ctx,
+			enum policy_mgr_three_connection_mode *index,
+			qdf_freq_t sap_freq, qdf_freq_t *sta_freq_list,
+			uint8_t *ml_sta_idx) {}
+
+static inline void
+policy_mgr_get_index_for_ml_sta_sap_sap(
+			struct policy_mgr_psoc_priv_obj *pm_ctx,
+			enum policy_mgr_three_connection_mode *index,
+			qdf_freq_t ml_sta_freq, qdf_freq_t sap_freq_1,
+			qdf_freq_t sap_freq_2) {}
+#endif /* WLAN_FEATURE_11BE_MLO */
+
+enum policy_mgr_three_connection_mode
+		policy_mgr_get_fourth_connection_pcl_table_index(
+		struct wlan_objmgr_psoc *psoc)
+{
+	enum policy_mgr_three_connection_mode index =
+			PM_MAX_THREE_CONNECTION_MODE;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t count_sap = 0;
+	uint32_t count_sta = 0;
+	uint32_t count_ndi = 0;
+	uint32_t count_nan_disc = 0;
+	uint8_t num_ml_sta = 0, num_non_ml_sta = 0;
+	uint32_t list_sap[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t list_sta[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t list_ndi[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t list_nan_disc[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t ml_sta_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t non_ml_sta_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	qdf_freq_t sap_freq = 0;
+
+	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);
+
+	/* For 4 port concurrency case,
+	 * 1st step: (SAP+STA)(2.4G MAC SCC) + (SAP+STA)(5G MAC SCC)
+	 * 2nd step: (AGO+STA)(2.4G MAC SCC) + (AGO+STA)(5G MAC SCC)
+	 */
+	count_sap += policy_mgr_mode_specific_connection_count(
+				psoc, PM_SAP_MODE, &list_sap[count_sap]);
+	count_sap += policy_mgr_mode_specific_connection_count(
+				psoc, PM_P2P_GO_MODE, &list_sap[count_sap]);
+	count_sap += policy_mgr_mode_specific_connection_count(
+				psoc, PM_P2P_CLIENT_MODE, &list_sap[count_sap]);
+	count_sta = policy_mgr_mode_specific_connection_count(
+				psoc, PM_STA_MODE, list_sta);
+	policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml_sta, ml_sta_idx,
+					       &num_non_ml_sta, non_ml_sta_idx,
+					       freq_list, vdev_id_list);
+
+	count_ndi = policy_mgr_mode_specific_connection_count(
+				psoc, PM_NDI_MODE, list_ndi);
+	count_nan_disc = policy_mgr_mode_specific_connection_count(
+				psoc, PM_NAN_DISC_MODE, list_nan_disc);
+	policy_mgr_debug("sap/go/cli:%d sta:%d ndi:%d nan disc:%d ml_sta:%d",
+			 count_sap, count_sta, count_ndi, count_nan_disc,
+			 num_ml_sta);
+
+	if (count_sap == 2 && num_ml_sta == 1) {
+		policy_mgr_get_index_for_ml_sta_sap_sap(
+				pm_ctx, &index,
+				freq_list[ml_sta_idx[0]],
+				pm_conc_connection_list[list_sap[0]].freq,
+				pm_conc_connection_list[list_sap[1]].freq);
+	} else if (count_sap == 2 && count_sta == 1 && !num_ml_sta) {
+		policy_mgr_debug(
+			"channel: sap0: %d, sap1: %d, sta0: %d",
+			pm_conc_connection_list[list_sap[0]].freq,
+			pm_conc_connection_list[list_sap[1]].freq,
+			pm_conc_connection_list[list_sta[0]].freq);
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+		     WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[1]].freq)) {
+			index = PM_STA_SAP_SCC_24_SAP_5_DBS;
+		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[1]].freq) &&
+		     WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq)) {
+			index = PM_STA_SAP_SCC_24_SAP_5_DBS;
+		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[1]].freq)) {
+			index = PM_STA_SAP_SCC_5_SAP_24_DBS;
+		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[1]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq)) {
+			index = PM_STA_SAP_SCC_5_SAP_24_DBS;
+		} else {
+			index =  PM_MAX_THREE_CONNECTION_MODE;
+		}
+	} else if (num_ml_sta == 2 && count_sap == 1) {
+		sap_freq = pm_conc_connection_list[list_sap[0]].freq;
+		policy_mgr_get_index_for_ml_sta_sap(pm_ctx, &index, sap_freq,
+						    freq_list, ml_sta_idx);
+	} else if (count_sap == 1 && count_sta == 2 && !num_ml_sta) {
+		policy_mgr_debug(
+			"channel: sap0: %d, sta0: %d, sta1: %d",
+			pm_conc_connection_list[list_sap[0]].freq,
+			pm_conc_connection_list[list_sta[0]].freq,
+			pm_conc_connection_list[list_sta[1]].freq);
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+		     WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[1]].freq)) {
+			index = PM_STA_SAP_24_STA_5_DBS;
+		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[1]].freq) &&
+		     WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq)) {
+			index = PM_STA_SAP_24_STA_5_DBS;
+		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[1]].freq)) {
+			index = PM_STA_SAP_5_STA_24_DBS;
+		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[1]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+		     WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq)) {
+			index = PM_STA_SAP_5_STA_24_DBS;
+		} else {
+			index =  PM_MAX_THREE_CONNECTION_MODE;
+		}
+	} else if (count_nan_disc == 1 && count_ndi == 1 && count_sap == 1) {
+		/* Policy mgr only considers NAN Disc ch in 2.4GHz */
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS;
+		} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+			   WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS;
+		} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sap[0]].freq) &&
+			  WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS;
+		} else {
+			index = PM_MAX_THREE_CONNECTION_MODE;
+		}
+	} else if (count_nan_disc == 1 && count_ndi == 1 && count_sta == 1) {
+		/* Policy mgr only considers NAN Disc ch in 2.4GHz */
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_NAN_DISC_STA_24_NDI_5_DBS;
+		} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+			   WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_NAN_DISC_NDI_24_STA_5_DBS;
+		} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+			  WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_STA_NDI_5_NAN_DISC_24_DBS;
+		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_sta[0]].freq) &&
+			  WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_STA_NDI_NAN_DISC_24_SMM;
+		}
+	} else if (count_nan_disc == 1 && count_ndi == 2) {
+		/* Policy mgr only considers NAN Disc ch in 2.4GHz */
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[1]].freq)) {
+			index = PM_NAN_DISC_NDI_24_NDI_5_DBS;
+		} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq) &&
+			   WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_NAN_DISC_NDI_24_NDI_5_DBS;
+		} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq) &&
+			  WLAN_REG_IS_5GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_NDI_NDI_5_NAN_DISC_24_DBS;
+		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq) &&
+			  WLAN_REG_IS_24GHZ_CH_FREQ(
+			pm_conc_connection_list[list_ndi[0]].freq)) {
+			index = PM_NDI_NDI_NAN_DISC_24_SMM;
+		}
+	} else if (count_sap == 3) {
+		if (policy_mgr_is_current_hwmode_sbs(psoc))
+			policy_mgr_get_index_for_3_given_freq_sbs(pm_ctx,
+								  &index,
+								  pm_conc_connection_list[list_sap[0]].freq,
+								  pm_conc_connection_list[list_sap[1]].freq,
+								  pm_conc_connection_list[list_sap[2]].freq);
+		else if (policy_mgr_is_current_hwmode_dbs(psoc))
+			policy_mgr_get_index_for_3_given_freq_dbs(pm_ctx,
+								  &index,
+								  pm_conc_connection_list[list_sap[0]].freq,
+								  pm_conc_connection_list[list_sap[1]].freq,
+								  pm_conc_connection_list[list_sap[2]].freq);
+	}
+
+	policy_mgr_debug(
+		"mode0:%d mode1:%d mode2:%d chan0:%d chan1:%d chan2:%d chain:%d index:%d",
+		pm_conc_connection_list[0].mode,
+		pm_conc_connection_list[1].mode,
+		pm_conc_connection_list[2].mode,
+		pm_conc_connection_list[0].freq,
+		pm_conc_connection_list[1].freq,
+		pm_conc_connection_list[2].freq,
+		pm_conc_connection_list[0].chain_mask, index);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return index;
+}
+#endif
+
+uint32_t
+policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc,
+					enum policy_mgr_con_mode mode,
+					bool for_existing_conn,
+					uint8_t vdev_id)
+{
+	uint32_t pcl_channels[NUM_CHANNELS];
+	uint8_t pcl_weight[NUM_CHANNELS];
+	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
+	 */
+	uint32_t i, pcl_len = 0, non_dfs_freq, freq;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return PM_24_GHZ_CH_FREQ_6;
+	}
+
+	freq = PM_24_GHZ_CH_FREQ_6;
+	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, &non_dfs_freq))
+			return non_dfs_freq;
+
+		if (QDF_STATUS_SUCCESS !=
+				policy_mgr_get_pcl_for_existing_conn(
+					psoc, mode,
+					pcl_channels, &pcl_len,
+					pcl_weight, QDF_ARRAY_SIZE(pcl_weight),
+					false, vdev_id))
+			return freq;
+	} else {
+		if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl(
+		    psoc, mode, pcl_channels, &pcl_len, pcl_weight,
+		    QDF_ARRAY_SIZE(pcl_weight), vdev_id))
+			return freq;
+	}
+
+	for (i = 0; i < pcl_len; i++) {
+		if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i]) ||
+		    !policy_mgr_is_safe_channel(psoc, pcl_channels[i])) {
+			continue;
+		} else {
+			freq = pcl_channels[i];
+			break;
+		}
+	}
+
+	return freq;
+}
+
+static void policy_mgr_remove_dsrc_channels(uint32_t *ch_freq_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_freq(ch_freq_list[i])) {
+			ch_freq_list[num_chan_temp] = ch_freq_list[i];
+			num_chan_temp++;
+		}
+	}
+
+	*num_channels = num_chan_temp;
+}
+
+QDF_STATUS policy_mgr_get_valid_chans_from_range(
+		struct wlan_objmgr_psoc *psoc, uint32_t *ch_freq_list,
+		uint32_t *ch_cnt, enum policy_mgr_con_mode mode)
+{
+	uint8_t ch_weight_list[NUM_CHANNELS] = {0};
+	uint32_t ch_weight_len;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	size_t chan_index = 0;
+
+	if (!ch_freq_list || !ch_cnt) {
+		policy_mgr_err("NULL parameters");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (chan_index = 0; chan_index < *ch_cnt; chan_index++)
+		ch_weight_list[chan_index] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
+
+	ch_weight_len = *ch_cnt;
+
+	/* check the channel avoidance list for beaconing entities */
+	if (policy_mgr_is_beaconing_mode(mode))
+		policy_mgr_update_with_safe_channel_list(
+			psoc, ch_freq_list, ch_cnt, ch_weight_list,
+			ch_weight_len);
+
+	status = policy_mgr_mode_specific_modification_on_pcl(
+			psoc, ch_freq_list, ch_weight_list, ch_cnt,
+			ch_weight_len, mode);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get modified pcl for mode %d", mode);
+		return status;
+	}
+
+	status = policy_mgr_modify_pcl_based_on_dnbs(psoc, ch_freq_list,
+						     ch_weight_list, ch_cnt);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("failed to get modified pcl based on DNBS");
+		return status;
+	}
+	policy_mgr_dump_channel_list(*ch_cnt, ch_freq_list, ch_weight_list);
+
+	return status;
+}
+
+QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc,
+				      uint32_t *ch_freq_list,
+				      uint32_t *list_len)
+{
+	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->valid_ch_freq_list_count) {
+		policy_mgr_err("Invalid PM valid channel list");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*list_len = pm_ctx->valid_ch_freq_list_count;
+	qdf_mem_copy(ch_freq_list, pm_ctx->valid_ch_freq_list,
+		     pm_ctx->valid_ch_freq_list_count *
+		     sizeof(pm_ctx->valid_ch_freq_list[0]));
+
+	policy_mgr_remove_dsrc_channels(ch_freq_list, list_len, pm_ctx->pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_list_has_24GHz_channel(uint32_t *ch_freq_list,
+				       uint32_t list_len)
+{
+	uint32_t i;
+
+	for (i = 0; i < list_len; i++) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i]))
+			return true;
+	}
+
+	return false;
+}
+
+QDF_STATUS
+policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc,
+				      uint32_t *ch_freq_list, 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(ch_freq_list, 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] = ch_freq_list[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;
+}
+
+static inline
+uint32_t policy_mgr_is_sta_on_indoor_channel(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_index;
+	uint32_t freq = INVALID_CHANNEL_ID;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return freq;
+	}
+	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 &&
+		    wlan_reg_is_freq_indoor(pm_ctx->pdev,
+				pm_conc_connection_list[conn_index].freq) &&
+				pm_conc_connection_list[conn_index].in_use) {
+			freq = pm_conc_connection_list[conn_index].freq;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return freq;
+}
+
+QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel(
+		struct wlan_objmgr_psoc *psoc, uint32_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;
+	qdf_freq_t dfs_sta_freq = INVALID_CHANNEL_ID;
+	qdf_freq_t indoor_sta_freq = INVALID_CHANNEL_ID;
+	qdf_freq_t sta_5GHz_freq = INVALID_CHANNEL_ID;
+	enum hw_mode_bandwidth sta_ch_width;
+	uint8_t sta_vdev_id = 0, scc_on_dfs_channel = 0;
+	bool sta_sap_scc_on_5ghz_channel;
+	bool scc_on_indoor =
+		 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+	uint8_t go_count;
+	uint32_t go_op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t go_vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t go_op_ch_freq_5g = 0;
+
+	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]);
+
+	if (scc_on_indoor)
+		indoor_sta_freq = policy_mgr_is_sta_on_indoor_channel(psoc);
+
+	policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &scc_on_dfs_channel);
+	if (scc_on_dfs_channel)
+		policy_mgr_is_sta_present_on_dfs_channel(psoc,
+							 &sta_vdev_id,
+							 &dfs_sta_freq,
+							 &sta_ch_width);
+	sta_sap_scc_on_5ghz_channel =
+		policy_mgr_is_connected_sta_5g(psoc, &sta_5GHz_freq);
+
+	go_count = policy_mgr_get_mode_specific_conn_info(
+				psoc, go_op_ch_freq_list,
+				go_vdev_id_list, PM_P2P_GO_MODE);
+	if (go_count && !WLAN_REG_IS_24GHZ_CH_FREQ(go_op_ch_freq_list[0])) {
+		go_op_ch_freq_5g = go_op_ch_freq_list[0];
+		policy_mgr_debug("go 5/6G present, SAP exclude 5/6G channels");
+	}
+
+	for (i = 0; i < *pcl_len_org; i++) {
+		found = false;
+		if (i >= NUM_CHANNELS) {
+			policy_mgr_debug("index is exceeding NUM_CHANNELS");
+			break;
+		}
+
+		if (go_op_ch_freq_5g &&
+		    !WLAN_REG_IS_24GHZ_CH_FREQ(pcl_list_org[i]))
+			continue;
+
+		if (scc_on_indoor && policy_mgr_is_force_scc(psoc) &&
+		    pcl_list_org[i] == indoor_sta_freq) {
+			policy_mgr_debug("indoor chan:%d", pcl_list_org[i]);
+			found = true;
+			goto update_pcl;
+		}
+
+		if (scc_on_dfs_channel && policy_mgr_is_force_scc(psoc) &&
+		    pcl_list_org[i] == dfs_sta_freq) {
+			policy_mgr_debug("dfs chan:%d", pcl_list_org[i]);
+			found = true;
+			goto update_pcl;
+		}
+
+		if (sta_sap_scc_on_5ghz_channel &&
+		    policy_mgr_is_force_scc(psoc) &&
+		    pcl_list_org[i] == sta_5GHz_freq) {
+			policy_mgr_debug("scc chan:%d", pcl_list_org[i]);
+			found = true;
+			goto update_pcl;
+		}
+
+		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;
+			}
+		}
+
+update_pcl:
+		if (found && (pcl_len < NUM_CHANNELS)) {
+			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;
+}
+
+void
+policy_mgr_sap_on_non_psc_channel(struct wlan_objmgr_psoc *psoc,
+				  qdf_freq_t *intf_ch_freq, uint8_t vdev_id)
+{
+	struct policy_mgr_pcl_list pcl;
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+	uint32_t i;
+	uint32_t ap_pwr_type_6g = 0;
+
+	if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(*intf_ch_freq))
+		return;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+
+	if (!vdev) {
+		policy_mgr_err("vdev %d is not present", vdev_id);
+		return;
+	}
+
+	ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(vdev);
+	qdf_mem_zero(&pcl, sizeof(pcl));
+
+	/* PCL list is filtered with Non-PSC channels during
+	 * policy_mgr_pcl_modification_for_sap, Reuse same list to check
+	 * if STA is in PSC channel for STA + SAP concurrency during SAP restart
+	 */
+	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, vdev_id);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("Unable to get PCL for SAP");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+		return;
+	}
+
+	for (i = 0; i < pcl.pcl_len; i++) {
+		if ((WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl.pcl_list[i])) &&
+		    pcl.pcl_list[i] == *intf_ch_freq &&
+		    ap_pwr_type_6g == REG_VERY_LOW_POWER_AP) {
+			policy_mgr_debug("STA is in PSC channel %d in VLP mode, Hence SAP + STA allowed in PSC",
+					 *intf_ch_freq);
+			*intf_ch_freq = 0;
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+			return;
+		}
+	}
+
+	/* if STA is in Non-PSC Channel + VLP or in non-VLP mode then move
+	 * SAP to 2 GHz from PCL list channels
+	 */
+	*intf_ch_freq = pcl.pcl_list[0];
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+}
+
+QDF_STATUS
+policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
+				     uint32_t sap_ch_freq,
+				     uint32_t *intf_ch_freq,
+				     uint8_t vdev_id)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	QDF_STATUS status;
+	struct policy_mgr_pcl_list pcl;
+	uint32_t i;
+	uint32_t sap_new_freq;
+	uint8_t mcc_to_scc_switch;
+	uint8_t sta_count;
+	qdf_freq_t user_config_freq = 0;
+	bool sta_sap_scc_on_indoor_channel =
+		 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+
+	mcc_to_scc_switch =
+		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
+
+	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
+							      NULL);
+
+	if (!sta_count || mcc_to_scc_switch !=
+			QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)
+		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;
+	}
+
+	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, vdev_id);
+	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), vdev_id);
+		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;
+	}
+
+	/*
+	 * If both freq leads to SBS, and sap_ch_freq is a mandatory freq,
+	 * allow it as they are not interfering.
+	 */
+	if (policy_mgr_are_sbs_chan(psoc, sap_ch_freq, *intf_ch_freq)) {
+		for (i = 0; i < pcl.pcl_len; i++) {
+			if (pcl.pcl_list[i] == sap_ch_freq) {
+				policy_mgr_debug("As both freq, %d and %d are SBS, allow sap on mandatory freq %d",
+						 sap_ch_freq, *intf_ch_freq,
+						 sap_ch_freq);
+				*intf_ch_freq = 0;
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+
+	/*
+	 * If intf_ch_freq is non-2.4Ghz, First try to get a mandatory freq
+	 * which can cause SBS with intf_ch_freq. i.e if STA is in lower 5Ghz,
+	 * allow higher 5Ghz mandatory freq.
+	 */
+	if (!WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq)) {
+		for (i = 0; i < pcl.pcl_len; i++) {
+			if (policy_mgr_are_sbs_chan(psoc, pcl.pcl_list[i],
+						    *intf_ch_freq)) {
+				sap_new_freq = pcl.pcl_list[i];
+				goto update_freq;
+			}
+		}
+	}
+
+	sap_new_freq = pcl.pcl_list[0];
+	/*
+	 * pcl_list carries multiple channel in ML-STA case depending on
+	 * the no.of links connected. Check if intf_ch_freq is carrying
+	 * any frequency from the list and pick it. If intf_ch_freq is not
+	 * present in the list, the frequency present at pcl_list[0] can
+	 * be picked as caller doesn't have any preferred/chosen channel
+	 * as such.
+	 */
+	for (i = 0; i < pcl.pcl_len; i++) {
+		if (pcl.pcl_list[i] == *intf_ch_freq) {
+			sap_new_freq = pcl.pcl_list[i];
+			break;
+		}
+	}
+
+	user_config_freq = policy_mgr_get_user_config_sap_freq(psoc, vdev_id);
+
+	for (i = 0; i < pcl.pcl_len; i++) {
+		/* When sta_sap_scc_on_indoor_channel is enabled,
+		 * and if pcl contains SCC channel, then STA must
+		 * exist on the concurrent session. Therefore, choose
+		 * Indoor channel to restart SAP in SCC.
+		 */
+		if (wlan_reg_is_freq_indoor(pm_ctx->pdev, pcl.pcl_list[i]) &&
+		    !WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl.pcl_list[i]) &&
+		    sta_sap_scc_on_indoor_channel) {
+			sap_new_freq = pcl.pcl_list[i];
+			policy_mgr_debug("Choose Indoor channel from PCL list %d sap_new_freq %d",
+					 *intf_ch_freq, sap_new_freq);
+			goto update_freq;
+		}
+
+		if (user_config_freq && (pcl.pcl_list[i] == user_config_freq)) {
+			sap_new_freq = pcl.pcl_list[i];
+			policy_mgr_debug("Prefer starting SAP on user configured channel:%d",
+					 sap_new_freq);
+			goto update_freq;
+		}
+	}
+
+	/* If no SBS Try get SCC freq */
+	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) ||
+	    (WLAN_REG_IS_5GHZ_CH_FREQ(sap_ch_freq) &&
+	     WLAN_REG_IS_5GHZ_CH_FREQ(*intf_ch_freq))) {
+		for (i = 0; i < pcl.pcl_len; i++) {
+			if (pcl.pcl_list[i] == *intf_ch_freq) {
+				sap_new_freq = pcl.pcl_list[i];
+				break;
+			}
+		}
+	}
+
+update_freq:
+	*intf_ch_freq = sap_new_freq;
+	policy_mgr_debug("Mandatory channel:%d org sap ch %d", *intf_ch_freq,
+			 sap_ch_freq);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
+		struct policy_mgr_pcl_chan_weights *weight,
+		enum policy_mgr_con_mode mode, struct wlan_objmgr_vdev *vdev)
+{
+	uint32_t i, j;
+	struct policy_mgr_conc_connection_info
+			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
+	uint8_t num_del = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool strict_follow_pcl = false;
+
+	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, NUM_CHANNELS,
+		    WEIGHT_OF_DISALLOWED_CHANNELS);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	if ((mode == PM_P2P_GO_MODE || mode == PM_P2P_CLIENT_MODE) ||
+	    (mode == PM_STA_MODE &&
+	     policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
+						       NULL))) {
+		/*
+		 * 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.
+		 */
+		if (mode == PM_STA_MODE) {
+			if (policy_mgr_concurrent_sta_on_different_mac(psoc) &&
+			    !wlan_cm_same_band_sta_allowed(psoc) &&
+			    weight->pcl_len) {
+				policy_mgr_debug("sta follow pcl strictly");
+				strict_follow_pcl = true;
+			}
+			if (vdev)
+				policy_mgr_store_and_del_conn_info_by_vdev_id(
+					psoc, wlan_vdev_get_id(vdev),
+					info, &num_del);
+			else
+				policy_mgr_store_and_del_conn_info(psoc,
+								   mode, true,
+								   info,
+								   &num_del);
+		}
+		/*
+		 * For two port/three port connection strictly follow
+		 * PCL weight if coming intf is p2p GO/GC and existing
+		 * vdev is SAP/P2PGO/P2PGC.
+		 */
+		if ((mode == PM_P2P_GO_MODE || mode == PM_P2P_CLIENT_MODE) &&
+		    ((policy_mgr_get_beaconing_mode_count(psoc, NULL)) ||
+		     policy_mgr_mode_specific_connection_count(
+					psoc, PM_P2P_CLIENT_MODE, NULL)))
+			strict_follow_pcl = true;
+
+		/*
+		 * This is a temporary check and will be removed once ll_lt_sap
+		 * CSA support is added.
+		 */
+		if (wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc) !=
+							WLAN_INVALID_VDEV_ID) {
+			policy_mgr_debug("LL_LT_SAP present, strict follow PCL");
+			strict_follow_pcl = true;
+		}
+
+		/*
+		 * 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 channel is not allowed for concurrency, keep pcl
+			 * weight as 0 (WEIGHT_OF_DISALLOWED_CHANNELS)
+			 */
+			if (!policy_mgr_is_concurrency_allowed
+			    (psoc, mode, weight->saved_chan_list[i],
+			     HW_MODE_20_MHZ,
+			     policy_mgr_get_conc_ext_flags(vdev, false), NULL))
+				continue;
+			/*
+			 * Keep weight 0 (WEIGHT_OF_DISALLOWED_CHANNELS) not
+			 * changed for scenarios which require to follow PCL.
+			 */
+			if (strict_follow_pcl)
+				continue;
+			weight->weighed_valid_list[i] =
+				WEIGHT_OF_NON_PCL_CHANNELS;
+		}
+		/* Restore the connection info */
+		if (mode == PM_STA_MODE)
+			policy_mgr_restore_deleted_conn_info(psoc, info,
+							     num_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;
+}
+
+uint32_t policy_mgr_mode_specific_get_channel(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
+{
+	uint32_t conn_index;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t freq = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+	/* 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) {
+			freq = pm_conc_connection_list[conn_index].freq;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return freq;
+}
+
+uint32_t policy_mgr_get_connection_count_with_ch_freq(uint32_t ch_freq)
+{
+	uint32_t i;
+	uint32_t count = 0;
+
+	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
+		if (pm_conc_connection_list[i].in_use &&
+		    ch_freq == pm_conc_connection_list[i].freq)
+			count++;
+	}
+
+	return count;
+}
+
+uint32_t policy_mgr_get_alternate_channel_for_sap(
+	struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id,
+	uint32_t sap_ch_freq,
+	enum reg_wifi_band pref_band)
+{
+	uint32_t pcl_channels[NUM_CHANNELS];
+	uint8_t pcl_weight[NUM_CHANNELS];
+	uint32_t ch_freq = 0;
+	uint32_t pcl_len = 0;
+	uint32_t first_valid_dfs_5g_freq = 0;
+	uint32_t first_valid_non_dfs_5g_freq = 0;
+	uint32_t first_valid_6g_freq = 0;
+	struct policy_mgr_conc_connection_info info;
+	uint8_t num_cxn_del = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t i;
+	enum policy_mgr_con_mode con_mode;
+	bool is_6ghz_cap;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+	con_mode = policy_mgr_con_mode_by_vdev_id(psoc, sap_vdev_id);
+	is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL);
+	/*
+	 * Store the connection's parameter and temporarily delete it
+	 * from the concurrency table. This way the get pcl can be used as a
+	 * new connection is coming up, after check, restore the connection to
+	 * concurrency table.
+	 */
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id,
+						      &info, &num_cxn_del);
+	if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(
+	    psoc, con_mode, pcl_channels, &pcl_len,
+	    pcl_weight, QDF_ARRAY_SIZE(pcl_weight), sap_vdev_id)) {
+		for (i = 0; i < pcl_len; i++) {
+			/*
+			 * The API is expected to select the channel on the
+			 * other band which is not same as sap's home and
+			 * concurrent interference channel (if present),
+			 * so skip the sap home channel in PCL.
+			 */
+			if (pcl_channels[i] == sap_ch_freq)
+				continue;
+			if (!is_6ghz_cap &&
+			    WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_channels[i]))
+				continue;
+			if (policy_mgr_get_connection_count(psoc) &&
+			    policy_mgr_are_2_freq_on_same_mac(psoc,
+							      sap_ch_freq,
+							      pcl_channels[i]))
+				continue;
+			if (policy_mgr_get_connection_count_with_ch_freq(
+							pcl_channels[i])) {
+				ch_freq = pcl_channels[i];
+				break;
+			} else if (!ch_freq) {
+				ch_freq = pcl_channels[i];
+			}
+			if (!first_valid_non_dfs_5g_freq &&
+			    wlan_reg_is_5ghz_ch_freq(pcl_channels[i])) {
+				if (!wlan_reg_is_dfs_in_secondary_list_for_freq(
+					pm_ctx->pdev,
+					pcl_channels[i])) {
+					first_valid_non_dfs_5g_freq = pcl_channels[i];
+					if (pref_band == REG_BAND_5G)
+						break;
+					} else if (!first_valid_dfs_5g_freq) {
+						first_valid_dfs_5g_freq = pcl_channels[i];
+					}
+			}
+			if (!first_valid_6g_freq &&
+			    wlan_reg_is_6ghz_chan_freq(pcl_channels[i])) {
+				first_valid_6g_freq = pcl_channels[i];
+				if (pref_band == REG_BAND_6G)
+					break;
+			}
+		}
+	}
+
+	/* Restore the connection entry */
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	if (pref_band == REG_BAND_6G) {
+		if (first_valid_6g_freq)
+			ch_freq = first_valid_6g_freq;
+		else if (first_valid_non_dfs_5g_freq)
+			ch_freq = first_valid_non_dfs_5g_freq;
+		else if (first_valid_dfs_5g_freq)
+			ch_freq = first_valid_dfs_5g_freq;
+	} else if (pref_band == REG_BAND_5G) {
+		if (first_valid_non_dfs_5g_freq)
+			ch_freq = first_valid_non_dfs_5g_freq;
+		else if (first_valid_dfs_5g_freq)
+			ch_freq = first_valid_dfs_5g_freq;
+	}
+
+	return ch_freq;
+}
+
+/*
+ * Buffer len size to consider the 4 char freq, 3 char weight, 2 char
+ * for open close brackets and space and a space, Total 10
+ */
+#define CHAN_WEIGHT_CHAR_LEN 10
+#define MAX_CHAN_TO_PRINT 39
+
+bool policy_mgr_dump_channel_list(uint32_t len, uint32_t *pcl_channels,
+				  uint8_t *pcl_weight)
+{
+	uint32_t idx, buff_len, num = 0, count = 0;
+	char *chan_buff = NULL;
+
+	buff_len = (QDF_MIN(len, MAX_CHAN_TO_PRINT) * CHAN_WEIGHT_CHAR_LEN) + 1;
+	chan_buff = qdf_mem_malloc(buff_len);
+	if (!chan_buff)
+		return false;
+
+	policymgr_nofl_debug("Total PCL Chan Freq %d", len);
+	for (idx = 0; (idx < len) && (idx < NUM_CHANNELS); idx++) {
+		num += qdf_scnprintf(chan_buff + num, buff_len - num,
+				     " %d[%d]", pcl_channels[idx],
+				     pcl_weight[idx]);
+		count++;
+		if (count >= MAX_CHAN_TO_PRINT) {
+			/* Print the MAX_CHAN_TO_PRINT channels */
+			policymgr_nofl_debug("Freq[weight]:%s",
+					     chan_buff);
+			count = 0;
+			num = 0;
+		}
+	}
+	/* Print any pending channels */
+	if (num)
+		policymgr_nofl_debug("Freq[weight]:%s", chan_buff);
+
+	qdf_mem_free(chan_buff);
+
+	return true;
+}
+
+QDF_STATUS policy_mgr_filter_passive_ch(struct wlan_objmgr_pdev *pdev,
+					uint32_t *ch_freq_list,
+					uint32_t *ch_cnt)
+{
+	size_t ch_index;
+	size_t target_ch_cnt = 0;
+
+	if (!pdev || !ch_freq_list || !ch_cnt) {
+		policy_mgr_err("NULL parameters");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	for (ch_index = 0; ch_index < *ch_cnt; ch_index++) {
+		if (wlan_reg_is_passive_for_freq(pdev,
+						 ch_freq_list[ch_index])) {
+			policy_mgr_debug("Remove freq: %d from list as it's passive",
+					 ch_freq_list[ch_index]);
+			continue;
+		}
+		ch_freq_list[target_ch_cnt++] = ch_freq_list[ch_index];
+	}
+
+	*ch_cnt = target_ch_cnt;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool policy_mgr_is_3rd_conn_on_same_band_allowed(struct wlan_objmgr_psoc *psoc,
+						 enum policy_mgr_con_mode mode,
+						 qdf_freq_t ch_freq)
+{
+	enum policy_mgr_pcl_type pcl = PM_NONE;
+	enum policy_mgr_conc_priority_mode conc_system_pref = 0;
+	enum policy_mgr_two_connection_mode third_index = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	bool ret = false;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("context is NULL");
+			return false;
+	}
+
+	if (pm_conc_connection_list[0].freq != ch_freq ||
+	    pm_conc_connection_list[0].freq !=
+				pm_conc_connection_list[1].freq) {
+		policy_mgr_debug("No MCC support in 3vif in same mac: %d %d %d",
+				 pm_conc_connection_list[0].freq,
+				 pm_conc_connection_list[1].freq,
+				 ch_freq);
+		return false;
+	}
+
+	policy_mgr_debug("pref:%d requested mode:%d",
+			 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;
+	}
+
+	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 false;
+	}
+	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_non_dbs_table)
+			[third_index][mode][conc_system_pref];
+	}
+
+	policy_mgr_debug("pcl for third connection mode %s is %d %s",
+			 device_mode_to_string(mode), pcl,
+			 pcl_type_to_string(pcl));
+	switch (pcl) {
+	case PM_SCC_CH:
+	case PM_SCC_CH_24G:
+	case PM_SCC_CH_5G:
+	case PM_24G_SCC_CH:
+	case PM_5G_SCC_CH:
+	case PM_SCC_ON_5_CH_5G:
+	case PM_SCC_ON_5_SCC_ON_24_24G:
+	case PM_SCC_ON_5_SCC_ON_24_5G:
+	case PM_SCC_ON_5_5G_24G:
+	case PM_SCC_ON_5_5G_SCC_ON_24G:
+	case PM_SCC_ON_24_SCC_ON_5_24G:
+	case PM_SCC_ON_24_SCC_ON_5_5G:
+	case PM_SCC_ON_24_CH_24G:
+	case PM_SCC_ON_5_SCC_ON_24:
+	case PM_SCC_ON_24_SCC_ON_5:
+	case PM_24G_SCC_CH_SBS_CH:
+	case PM_24G_SCC_CH_SBS_CH_5G:
+	case PM_SBS_CH_24G_SCC_CH:
+	case PM_SBS_CH_SCC_CH_24G:
+	case PM_SCC_CH_SBS_CH_24G:
+	case PM_SBS_CH_SCC_CH_5G_24G:
+	case PM_SCC_CH_MCC_CH_SBS_CH_24G:
+	case PM_MCC_CH:
+	case PM_MCC_CH_24G:
+	case PM_MCC_CH_5G:
+	case PM_24G_MCC_CH:
+	case PM_5G_MCC_CH:
+	case PM_24G_SBS_CH_MCC_CH:
+		ret = true;
+		break;
+	default:
+		policy_mgr_debug("Not in SCC case");
+		ret = false;
+		break;
+	}
+	return ret;
+}
+
+bool policy_mgr_is_sta_chan_valid_for_connect_and_roam(
+				struct wlan_objmgr_pdev *pdev,
+				qdf_freq_t freq)
+{
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t sap_count;
+	bool skip_6g_and_indoor_freq;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return true;
+
+	skip_6g_and_indoor_freq =
+		wlan_scan_cfg_skip_6g_and_indoor_freq(psoc);
+	sap_count =
+		policy_mgr_get_sap_mode_count(psoc, NULL);
+	/*
+	 * Do not allow STA to connect/roam on 6Ghz or indoor channel for
+	 * non-dbs hardware if SAP is present and skip_6g_and_indoor_freq_scan
+	 * ini is enabled
+	 */
+	if (skip_6g_and_indoor_freq && sap_count &&
+	    !policy_mgr_is_hw_dbs_capable(psoc) &&
+	    (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq) ||
+	     wlan_reg_is_freq_indoor(pdev, freq)))
+		return false;
+
+	return true;
+}
+
+/**
+ * _policy_mgr_is_vdev_ll_sap() - Check whether any LL SAP is present or not
+ * for provided ap policy
+ * @psoc: psoc object
+ * @vdev_id: vdev id
+ * @ap_type: LL SAP type
+ *
+ * Return: true if it's present otherwise false
+ */
+static bool
+_policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc *psoc,
+			   uint32_t vdev_id, enum ll_ap_type ap_type)
+{
+	struct wlan_objmgr_vdev *vdev;
+	bool is_ll_sap = false;
+	enum QDF_OPMODE mode;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	enum host_concurrent_ap_policy profile =
+					HOST_CONCURRENT_AP_POLICY_UNSPECIFIED;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm_ctx");
+		return is_ll_sap;
+	}
+
+	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
+
+	if (mode != QDF_SAP_MODE)
+		return is_ll_sap;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_POLICY_MGR_ID);
+	if (!vdev) {
+		policy_mgr_err("vdev %d: invalid vdev", vdev_id);
+		return is_ll_sap;
+	}
+
+	profile = wlan_mlme_get_ap_policy(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
+	switch (ap_type) {
+	case LL_AP_TYPE_HT:
+		if (profile == HOST_CONCURRENT_AP_POLICY_XR)
+			is_ll_sap = true;
+	break;
+	case LL_AP_TYPE_LT:
+		if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO ||
+		    profile ==
+		    HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING)
+			is_ll_sap = true;
+	break;
+	case LL_AP_TYPE_ANY:
+		if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO ||
+		    profile ==
+		    HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING ||
+		    profile == HOST_CONCURRENT_AP_POLICY_XR)
+			is_ll_sap = true;
+	break;
+	default:
+		policy_mgr_err("invalid ap type %d", ap_type);
+	}
+	return is_ll_sap;
+}
+
+bool
+policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc *psoc,
+			  uint32_t vdev_id)
+{
+	return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_ANY);
+}
+
+bool
+policy_mgr_is_vdev_ll_ht_sap(struct wlan_objmgr_psoc *psoc,
+			     uint32_t vdev_id)
+{
+	return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_HT);
+}
+
+bool
+policy_mgr_is_vdev_ll_lt_sap(struct wlan_objmgr_psoc *psoc,
+			     uint32_t vdev_id)
+{
+	return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_LT);
+}
+
+#ifndef WLAN_FEATURE_LL_LT_SAP
+QDF_STATUS
+policy_mgr_get_pcl_chlist_for_ll_sap(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *len, uint32_t *pcl_channels,
+				     uint8_t *pcl_weight)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t pcl_len = 0, i, conn_idx = 0;
+	uint32_t pcl_list[NUM_CHANNELS], total_connection = 0;
+	uint8_t weight_list[NUM_CHANNELS];
+	qdf_freq_t freq;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	total_connection = policy_mgr_get_connection_count(psoc);
+	if (!total_connection) {
+		for (i = 0; i < *len; i++) {
+			if (WLAN_REG_IS_24GHZ_CH_FREQ(pcl_channels[i]))
+				continue;
+
+			pcl_list[pcl_len] = pcl_channels[i];
+			weight_list[pcl_len++] = pcl_weight[i];
+		}
+		qdf_mem_zero(pcl_channels, *len * sizeof(*pcl_channels));
+		qdf_mem_copy(pcl_channels, pcl_list,
+			     pcl_len * sizeof(*pcl_channels));
+	} else {
+		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+		for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
+		     conn_idx++) {
+			if (!pm_conc_connection_list[conn_idx].in_use)
+				continue;
+
+			freq = pm_conc_connection_list[conn_idx].freq;
+
+			for (i = 0; i < *len; i++) {
+				if (policy_mgr_2_freq_always_on_same_mac(
+								psoc,
+								pcl_channels[i],
+								freq) ||
+				    WLAN_REG_IS_24GHZ_CH_FREQ(pcl_channels[i]))
+					continue;
+				pcl_list[pcl_len] = pcl_channels[i];
+				weight_list[pcl_len++] = pcl_weight[i];
+			}
+			*len = pcl_len;
+			qdf_mem_zero(pcl_channels,
+				     *len * sizeof(*pcl_channels));
+			qdf_mem_copy(pcl_channels, pcl_list,
+				     pcl_len * sizeof(*pcl_channels));
+		}
+		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+	}
+
+	qdf_mem_zero(pcl_weight, *len * sizeof(*pcl_weight));
+	qdf_mem_copy(pcl_weight, weight_list, pcl_len);
+	*len = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present(
+					struct wlan_objmgr_psoc *psoc,
+					uint32_t *len, uint32_t *pcl_channels,
+					uint8_t *pcl_weight)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t pcl_len = 0, i, conn_idx = 0;
+	uint32_t pcl_list[NUM_CHANNELS];
+	uint8_t weight_list[NUM_CHANNELS];
+	qdf_freq_t freq;
+	uint32_t vdev_id;
+	bool is_ll_sap = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_idx++) {
+		if (!pm_conc_connection_list[conn_idx].in_use)
+			continue;
+
+		freq = pm_conc_connection_list[conn_idx].freq;
+		vdev_id = pm_conc_connection_list[conn_idx].vdev_id;
+		if (!policy_mgr_is_vdev_ll_sap(psoc, vdev_id))
+			continue;
+
+		is_ll_sap = 1;
+		for (i = 0; i < *len; i++) {
+			if (policy_mgr_2_freq_always_on_same_mac(
+								psoc,
+								pcl_channels[i],
+								freq))
+				continue;
+			pcl_list[pcl_len] = pcl_channels[i];
+			weight_list[pcl_len++] = pcl_weight[i];
+		}
+		*len = pcl_len;
+		qdf_mem_zero(pcl_channels,
+			     *len * sizeof(*pcl_channels));
+		qdf_mem_copy(pcl_channels, pcl_list,
+			     pcl_len * sizeof(*pcl_channels));
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (!is_ll_sap)
+		return QDF_STATUS_SUCCESS;
+
+	qdf_mem_zero(pcl_weight, *len * sizeof(*pcl_weight));
+	qdf_mem_copy(pcl_weight, weight_list, pcl_len);
+	*len = pcl_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+policy_mgr_get_pcl_channel_for_ll_sap_concurrency(
+					struct wlan_objmgr_psoc *psoc,
+					uint32_t vdev_id,
+					uint32_t *pcl_channels,
+					uint8_t *pcl_weight, uint32_t *len)
+{
+	uint32_t orig_len = *len;
+
+	if (policy_mgr_is_vdev_ll_sap(psoc, vdev_id)) {
+		/* Scenario: If there is some existing interface present and
+		 * LL SAP is coming up.
+		 * Filter pcl channel for LL SAP
+		 */
+		policy_mgr_get_pcl_chlist_for_ll_sap(psoc, len, pcl_channels,
+						     pcl_weight);
+	} else {
+		/* Scenario: If there is LL SAP and GO/SAP is coming up.
+		 * Filter pcl channel for GO/SAP
+		 */
+		policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present(
+								psoc,
+								len,
+								pcl_channels,
+								pcl_weight);
+	}
+
+	if (orig_len != *len) {
+		policy_mgr_debug("PCL after ll sap modification");
+		policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_FEATURE_LL_LT_SAP
+QDF_STATUS policy_mgr_get_pcl_ch_list_for_ll_sap(
+					struct wlan_objmgr_psoc *psoc,
+					struct policy_mgr_pcl_list *pcl,
+					uint8_t vdev_id,
+					struct connection_info *info,
+					uint8_t *connection_count)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t num_cxn_del = 0;
+	struct policy_mgr_conc_connection_info pm_info = {0};
+	QDF_STATUS status;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+
+	/*
+	 * Scenario: Standalone XPAN is present and CSA happens on
+	 * LL_LT_SAP interface.
+	 * During CSA, it will check the PCL list to get the new freq.
+	 * Since there is already LL_LT_SAP interface entry in PCL index.
+	 * It will lead to LL_LT_SAP + LL_LT_SAP concurrencies. To avoid
+	 * that, delete the existing connection entry from PCL index,
+	 * get the PCL list and restore it back.
+	 */
+	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
+						      &pm_info, &num_cxn_del);
+
+	status = policy_mgr_get_pcl(psoc, PM_LL_LT_SAP_MODE, pcl->pcl_list,
+				    &pcl->pcl_len, pcl->weight_list,
+				    QDF_ARRAY_SIZE(pcl->weight_list),
+				    vdev_id);
+
+	/*
+	 * Get existing connection info before updating LL_LT_SAP freq list
+	 * This will help to avoid updation of SCC channel in LL_LT_SAP
+	 * freq list.
+	 */
+	*connection_count = policy_mgr_get_connection_info(psoc, info);
+
+	/* Restore the connection entry */
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, &pm_info,
+						     num_cxn_del);
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return status;
+}
+#endif

+ 2283 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h

@@ -0,0 +1,2283 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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} },
+};
+
+/*
+ * 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). For helium that is NON-DBS,
+ * DBS 1x1, three port concurrency would be disabled, so for every
+ * combination MAX_PCL_TYPE would be the return value, if in future
+ * the requirement for 3 port concurrency comes, refer to below table
+ * for details.
+ * 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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} },
+ *
+ * };
+ */
+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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_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_NAN_DISC_NDI_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_NAN_DISC_NDI_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_NAN_DISC_NDI_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_NAN_DISC_NDI_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_NAN_DISC_NDI_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}
+	},
+};
+
+/*
+ * 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},
+};
+
+/*
+ * 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

+ 151 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h

@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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},
+};
+
+/*
+ * 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

+ 151 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h

@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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},
+};
+
+/*
+ * 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

+ 2580 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h

@@ -0,0 +1,2580 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_NAN_DISC_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_SCC_CH_24G,
+		PM_SCC_CH_24G, PM_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH_24G,
+		PM_SCC_CH_24G, PM_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G,
+		PM_SCC_CH_24G, PM_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_SCC_CH_24G,
+		PM_SCC_CH_24G, PM_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SCC_CH_24G,
+		PM_SCC_CH_24G, PM_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G,
+		PM_SCC_CH_24G, PM_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_5G, PM_SBS_CH_5G, PM_SBS_CH_5G} },
+
+	[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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_5G, PM_SBS_CH_5G, PM_SBS_CH_5G} },
+
+	[PM_NAN_DISC_24_1x1] = {
+	[PM_STA_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_NDI_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_24_2x2] = {
+	[PM_STA_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_NDI_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_LL_LT_SAP_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+				PM_SBS_5G_MCC_24G},
+	[PM_P2P_GO_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			    PM_SBS_5G_MCC_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			      PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_P2P_GO_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_SAP_SAP_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_SAP_SAP_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G, PM_5G, PM_5G},
+	[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_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_SAP_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_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_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_SAP_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_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_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_SAP_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_MCC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_MCC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_GO_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_SAP_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5_SCC_ON_24, 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_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5_SCC_ON_24, 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_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_GO_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_GO_MCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_GO_MCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G,
+		PM_SCC_ON_5_SCC_ON_24_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_P2P_GO_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_P2P_CLI_SCC_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_P2P_CLI_SCC_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_P2P_CLI_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_P2P_CLI_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_P2P_CLI_SCC_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_CLI_P2P_CLI_SCC_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_CLI_P2P_CLI_MCC_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_CLI_P2P_CLI_MCC_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_P2P_CLI_DBS_1x1] = {
+		[PM_STA_MODE] = {
+			PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G,
+			PM_SCC_ON_5_SCC_ON_24_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+				       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_P2P_CLI_DBS_2x2] = {
+		[PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G,
+				  PM_SCC_ON_5_SCC_ON_24_5G,
+				  PM_SCC_ON_5_SCC_ON_24_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+				       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+		[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+				 PM_MAX_PCL_TYPE},
+		[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_24G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_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_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_P2P_CLI_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_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_GO_MODE] =  {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_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_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_STA_STA_SBS_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_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_NAN_DISC_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_MCC_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_NDI_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_MCC_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_NDI_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_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_NDI_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_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_NDI_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_SCC_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_24_LL_LT_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24G, PM_SCC_ON_24G, PM_SCC_ON_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G},
+	[PM_P2P_GO_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			    PM_SBS_5G_MCC_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_LL_LT_SAP_MCC_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH, PM_SCC_ON_5G_HIGH,
+			 PM_SCC_ON_5G_HIGH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_LL_LT_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+			 PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+			 PM_SBS_CH_MCC_CH_SCC_ON_24_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24G, PM_SCC_ON_24G, PM_SCC_ON_24G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+				PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+				PM_SBS_CH_MCC_CH_SCC_ON_24_24G},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH_SCC_ON_24G, PM_MCC_CH_SCC_ON_24G,
+			    PM_MCC_CH_SCC_ON_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH,
+			    PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH,
+			    PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH, PM_SCC_ON_5G_HIGH,
+			 PM_SCC_ON_5G_HIGH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW,
+			    PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW,
+			    PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_LL_LT_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24G, PM_SCC_ON_24G, PM_SCC_ON_24G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+				PM_SBS_5G_MCC_24G},
+	[PM_P2P_GO_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			    PM_SBS_5G_MCC_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_LL_LT_SAP_MCC_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH, PM_SCC_ON_5G_HIGH,
+			 PM_SCC_ON_5G_HIGH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_24_LL_LT_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24G, PM_SCC_ON_24G, PM_SCC_ON_24G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+				PM_SBS_5G_MCC_24G},
+	[PM_P2P_GO_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			    PM_SBS_5G_MCC_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_LL_LT_SAP_MCC_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH, PM_SCC_ON_5G_HIGH,
+			 PM_SCC_ON_5G_HIGH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+};
+
+#ifdef FEATURE_FOURTH_CONNECTION
+/*
+ * fourth_connection_pcl_dbs_sbs_table - table which provides PCL for
+ * the 4th connection, when we have 3 connections already in
+ * the system (with DBS & SBS supported by HW), this table is for auto products.
+ */
+#ifdef FOURTH_CONNECTION_AUTO
+const enum policy_mgr_pcl_type
+fourth_connection_pcl_dbs_sbs_table
+	[PM_MAX_THREE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE]
+	[PM_MAX_CONC_PRIORITY_MODE] = {
+	[PM_STA_SAP_SCC_24_SAP_5_DBS] = {
+	[PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_SAP_SCC_5_SAP_24_DBS] = {
+	[PM_STA_MODE] = { PM_24G, PM_24G, PM_24G } },
+	[PM_STA_SAP_24_STA_5_DBS] = {
+	[PM_SAP_MODE] = { PM_SCC_ON_5_CH_5G, PM_SCC_ON_5_CH_5G,
+			 PM_SCC_ON_5_CH_5G} },
+	[PM_STA_SAP_5_STA_24_DBS] = {
+	[PM_SAP_MODE] = { PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G } },
+	[PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS] = {
+	[PM_SAP_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS] = {
+	[PM_SAP_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS] = {
+	[PM_SAP_MODE] = { PM_24G, PM_24G, PM_24G } }
+};
+#else
+/*
+ * fourth_connection_pcl_dbs_sbs_table - table which provides PCL for
+ * the 4th connection, when we have 3 connections already in
+ * the system (with DBS & SBS supported by HW), this table is for mobile
+ * products If you want to support any 4 port other than the below in MCL add
+ * below as other concurrencies supported by auto may not be PORed for mobile
+ * products and vice-versa.
+ */
+const enum policy_mgr_pcl_type
+fourth_connection_pcl_dbs_sbs_table
+	[PM_MAX_THREE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE]
+	[PM_MAX_CONC_PRIORITY_MODE] = {
+#if !defined(MDM_PLATFORM)
+	[PM_NAN_DISC_STA_24_NDI_5_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_NDI_24_STA_5_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_NDI_5_NAN_DISC_24_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_NDI_NAN_DISC_24_SMM] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_NDI_24_NDI_5_DBS] = {
+	[PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NDI_NDI_5_NAN_DISC_24_DBS] = {
+	[PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NDI_NDI_NAN_DISC_24_SMM] = {
+	[PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_STA_5_NAN_DISC_24_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_24_STA_STA_5_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_STA_24_NAN_DISC_24_SMM] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_24_STA_STA_24_SMM] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_24_STA_5_NAN_DISC_24_SMM] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_24_STA_5_NAN_DISC_24_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_5_STA_24_NAN_DISC_24_SMM] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_STA_5_STA_24_NAN_DISC_24_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_24_STA_5_STA_24_SMM] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_24_STA_5_STA_24_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_24_STA_24_STA_5_SMM] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+	[PM_NAN_DISC_24_STA_24_STA_5_DBS] = {
+	[PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } },
+#endif
+	[PM_24_SCC_MCC_PLUS_5_DBS] = {
+	[PM_STA_MODE] = { PM_SCC_ON_5_CH_5G, PM_SCC_ON_5_CH_5G,
+			 PM_SCC_ON_5_CH_5G},
+	[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_5_SCC_MCC_PLUS_24_DBS] = {
+	[PM_STA_MODE] = { PM_SBS_CH_2G, PM_SBS_CH_2G,
+			  PM_SBS_CH_2G },
+	[PM_SAP_MODE] = { PM_SCC_ON_24_SCC_ON_5, PM_SCC_ON_24_SCC_ON_5,
+			  PM_SCC_ON_24_SCC_ON_5 } },
+	[PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G,
+			 PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G,
+			 PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G,
+			 PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G,
+			 PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G} },
+	[PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G,
+			 PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G,
+			 PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH_5G_HIGH_SCC_ON_5G_LOW_PLUS_SHARED_2G,
+			 PM_SCC_ON_5G_HIGH_5G_HIGH_SCC_ON_5G_LOW_PLUS_SHARED_2G,
+			 PM_SCC_ON_5G_HIGH_5G_HIGH_SCC_ON_5G_LOW_PLUS_SHARED_2G} },
+	[PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5_CH_5G, PM_SCC_ON_5_CH_5G,
+			 PM_SCC_ON_5_CH_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_5G_SCC_ON_24G,
+			 PM_SCC_ON_5_5G_SCC_ON_24G} },
+	[PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_CH_24G, PM_SCC_ON_24_CH_24G,
+			PM_SCC_ON_24_CH_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_24G, PM_SCC_ON_24_SCC_ON_5_24G,
+			PM_SCC_ON_24_SCC_ON_5_24G} },
+};
+#endif
+#endif
+
+/*
+ * 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},
+};
+
+/*
+ * 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_P2P_CLI_SAP_SCC_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_P2P_CLI_SAP_SCC_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_24_1x1] = {PM_NOP,		PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_24_2x2] = {PM_NOP,		PM_NOP},
+	[PM_P2P_CLI_SAP_SCC_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_P2P_CLI_SAP_SCC_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_P2P_CLI_SAP_MCC_5_1x1] = {PM_DBS,		PM_SBS},
+	[PM_P2P_CLI_SAP_MCC_5_2x2] = {PM_DBS,		PM_SBS_DOWNGRADE},
+	[PM_P2P_CLI_SAP_MCC_24_5_1x1] = {PM_NOP,	PM_NOP},
+	[PM_P2P_CLI_SAP_MCC_24_5_2x2] = {PM_NOP,	PM_NOP},
+	[PM_P2P_CLI_SAP_DBS_1x1] = {PM_NOP,		PM_NOP},
+	[PM_P2P_CLI_SAP_DBS_2x2] = {PM_NOP,		PM_NOP},
+	[PM_P2P_CLI_SAP_SBS_5_1x1] = {PM_DBS_UPGRADE,	PM_NOP},
+
+	[PM_P2P_CLI_P2P_CLI_SCC_5_1x1] = {PM_DBS, PM_SBS},
+	[PM_P2P_CLI_P2P_CLI_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE},
+	[PM_P2P_CLI_P2P_CLI_MCC_5_1x1] = {PM_DBS, PM_SBS},
+	[PM_P2P_CLI_P2P_CLI_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE},
+	[PM_P2P_CLI_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},
+
+	[PM_P2P_GO_P2P_GO_SCC_5_1x1] = {PM_DBS, PM_SBS},
+	[PM_P2P_GO_P2P_GO_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE},
+	[PM_P2P_GO_P2P_GO_MCC_5_1x1] = {PM_DBS, PM_SBS},
+	[PM_P2P_GO_P2P_GO_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE},
+	[PM_P2P_GO_P2P_GO_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP},
+
+	[PM_P2P_GO_SAP_SCC_5_1x1] = {PM_DBS, PM_SBS},
+	[PM_P2P_GO_SAP_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE},
+	[PM_P2P_GO_SAP_MCC_5_1x1] = {PM_DBS, PM_SBS},
+	[PM_P2P_GO_SAP_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE},
+	[PM_P2P_GO_SAP_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP},
+};
+
+/*
+ * next_action_two_connection_table_v2 - 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_v2 = {
+	[PM_STA_24_1x1]     = {PM_NOP, PM_DBS},
+	[PM_STA_24_2x2]     = {PM_NOP, PM_DBS},
+	[PM_STA_5_1x1]      = {PM_DBS, PM_NOP},
+	[PM_STA_5_2x2]      = {PM_DBS, PM_NOP},
+	[PM_P2P_CLI_24_1x1] = {PM_NOP, PM_DBS},
+	[PM_P2P_CLI_24_2x2] = {PM_NOP, PM_DBS},
+	[PM_P2P_CLI_5_1x1]  = {PM_DBS, PM_NOP},
+	[PM_P2P_CLI_5_2x2]  = {PM_DBS, PM_NOP},
+	[PM_P2P_GO_24_1x1]  = {PM_NOP, PM_DBS},
+	[PM_P2P_GO_24_2x2]  = {PM_NOP, PM_DBS},
+	[PM_P2P_GO_5_1x1]   = {PM_DBS, PM_NOP},
+	[PM_P2P_GO_5_2x2]   = {PM_DBS, PM_NOP},
+	[PM_SAP_24_1x1]     = {PM_NOP, PM_DBS},
+	[PM_SAP_24_2x2]     = {PM_NOP, PM_DBS},
+	[PM_SAP_5_1x1]      = {PM_DBS, PM_NOP},
+	[PM_SAP_5_2x2]      = {PM_DBS, PM_NOP},
+};
+#endif

+ 2208 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_sbs_i.h

@@ -0,0 +1,2208 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_SBS_H
+#define __WLAN_POLICY_MGR_TABLES_2X2_DBS_SBS_H
+
+#include "wlan_policy_mgr_api.h"
+
+/*
+ * pm_second_connection_pcl_dbs_sbs_2x2_table - table which provides PCL
+ * for the 2nd connection, when we have a connection already in
+ * the system (with DBS-SBS 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_sbs_2x2_table = {
+	[PM_STA_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_STA_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_STA_5_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SBS_CH_SCC_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] =	{PM_SBS_CH_SCC_CH_5G_24G,
+		PM_SCC_CH_MCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_STA_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SBS_CH_SCC_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] =	{PM_SBS_CH_SCC_CH_5G_24G,
+		PM_SCC_CH_MCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_5_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_5G_24G,
+		PM_SCC_CH_MCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] =	{PM_SBS_CH_SCC_CH_5G_24G,
+		PM_SCC_CH_MCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_5G_24G,
+		PM_SCC_CH_MCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] =	{PM_SBS_CH_SCC_CH_5G_24G,
+		PM_SCC_CH_MCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_5_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] =	{PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] =	{ PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+
+	[PM_SAP_24_1x1] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_SAP_24_2x2] = {
+	[PM_STA_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_SAP_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH_5G, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_SAP_5_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] =	{PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_5G, PM_SBS_CH_5G, PM_SBS_CH_5G} },
+
+	[PM_SAP_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] =	{PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_SCC_CH_24G,
+		PM_SCC_CH_SBS_CH_24G, PM_SBS_CH_24G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_5G, PM_SBS_CH_5G, PM_SBS_CH_5G} },
+
+	[PM_NAN_DISC_24_1x1] = {
+	[PM_STA_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_NDI_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_24_2x2] = {
+	[PM_STA_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_NDI_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_LL_LT_SAP_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+				PM_SBS_5G_MCC_24G},
+	[PM_P2P_GO_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+				PM_SBS_5G_MCC_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			      PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_sbs_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_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_24G_SCC_CH, PM_SBS_CH_24G_SCC_CH,
+			    PM_SBS_CH_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_24G_SCC_CH, PM_SBS_CH_24G_SCC_CH,
+			    PM_SBS_CH_24G_SCC_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	{PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_GO_MODE] = { PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_GO_MODE] = { PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_STA_SAP_SBS_5_2x2] = {
+	[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_SBS_CH_SCC_CH_5G_24G, PM_SBS_CH, PM_SBS_CH},
+	[PM_P2P_GO_MODE] = {
+		PM_SBS_CH_SCC_CH_5G_24G, PM_SBS_CH, PM_SBS_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_SBS_CH_MCC_CH, PM_24G, PM_24G_SBS_CH_MCC_CH},
+	[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_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_SBS_CH_MCC_CH, PM_24G, PM_24G_SBS_CH_MCC_CH},
+	[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_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_SAP_SAP_SBS_5_2x2] = {
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_SAP_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_MCC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_MCC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_5G, PM_5G},
+	[PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_SBS_CH_24G_SCC_CH, PM_SBS_CH_24G_SCC_CH,
+		PM_SBS_CH_24G_SCC_CH},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_SBS_CH_24G_SCC_CH, PM_SBS_CH_24G_SCC_CH,
+			 PM_SBS_CH_24G_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_SBS_CH_2G, 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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_SBS_CH_2G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_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_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_24G, PM_24G, PM_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G_SCC_ON_24G, 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_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_GO_MODE] = {
+		PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_STA_P2P_GO_SBS_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH, PM_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SCC_ON_5_5G_24G, PM_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {
+		PM_SCC_ON_5_5G_24G, PM_SCC_CH, PM_SCC_CH_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_24G_SCC_CH, PM_SBS_CH_24G_SCC_CH,
+		PM_SBS_CH_24G_SCC_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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_24G_SCC_CH, PM_SBS_CH_24G_SCC_CH,
+		PM_SBS_CH_24G_SCC_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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G_SCC_ON_24G, 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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_SAP_DBS_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_5G_SCC_ON_24G, 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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_SAP_SBS_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_SCC_CH_5G_24G, 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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_P2P_CLI_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_P2P_CLI_DBS_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_P2P_CLI_SBS_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_5G_24G, PM_SCC_CH, PM_SCC_CH_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_SAP_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_SAP_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_CLI_SAP_SCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, 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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_SCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, 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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_MCC_5_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, 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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_MCC_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, 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_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5_5G_SCC_ON_24G, 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_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5_5G_SCC_ON_24G, 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_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_CLI_SAP_SBS_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_CH_SCC_CH_5G_24G, 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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_GO_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_GO_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_GO_MCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_GO_MCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G,
+		PM_SCC_ON_5_SCC_ON_24_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_P2P_GO_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_P2P_GO_SBS_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_5G_24G, PM_SCC_CH, PM_SCC_CH_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_STA_P2P_CLI_SCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, 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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_STA_P2P_CLI_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_STA_P2P_CLI_MCC_5_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, 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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_STA_P2P_CLI_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_24G, PM_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_SCC_ON_5_5G_SCC_ON_24G, 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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[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_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_GO_MODE] = {
+		PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_STA_P2P_CLI_SBS_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SBS_CH_SCC_CH_5G_24G, PM_SBS_CH, PM_SBS_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SCC_ON_5_5G_24G, PM_SCC_CH, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {
+		PM_SCC_ON_5_5G_24G, PM_SCC_CH, PM_SCC_CH_24G},
+	[PM_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_P2P_CLI_DBS_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_5G_SCC_ON_24G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_P2P_GO_P2P_CLI_SBS_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_5G_24G, PM_SCC_CH, PM_SCC_CH_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
+		PM_24G_SCC_CH_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH, PM_SBS_CH, PM_SBS_CH} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G,
+		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_SCC_ON_5_SCC_ON_24_5G,
+				PM_SCC_ON_5_SCC_ON_24_5G,
+				PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_STA_STA_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G,
+		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_SCC_ON_5_SCC_ON_24_5G,
+				PM_SCC_ON_5_SCC_ON_24_5G,
+				PM_SCC_ON_5_SCC_ON_24},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NAN_DISC_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G,
+		PM_SCC_ON_5_SCC_ON_24},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_SBS_CH_MCC_CH, PM_SBS_CH_MCC_CH,
+			       PM_SBS_CH_MCC_CH} },
+
+	[PM_STA_STA_SBS_5_2x2] = {
+	[PM_STA_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH_5G, PM_SBS_CH},
+	[PM_SAP_MODE] = {
+		PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH_5G, PM_SBS_CH},
+	[PM_P2P_GO_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH_5G, PM_SBS_CH},
+	[PM_NAN_DISC_MODE] = {
+		PM_SBS_CH_5G, PM_SBS_CH_5G, PM_SBS_CH},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_MCC_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_NDI_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_MCC_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_NDI_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_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_NDI_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+			 PM_SCC_ON_24_SCC_ON_5_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_NDI_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_SCC_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_5G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G,
+		PM_SCC_ON_24_SCC_ON_5_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_24_LL_LT_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24G, PM_SCC_ON_24G, PM_SCC_ON_24G},
+	[PM_P2P_CLIENT_MODE] = {
+		PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G},
+	[PM_P2P_GO_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			    PM_SBS_5G_MCC_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_LL_LT_SAP_MCC_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH, PM_SCC_ON_5G_HIGH,
+			 PM_SCC_ON_5G_HIGH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_LL_LT_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+			 PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+			 PM_SBS_CH_MCC_CH_SCC_ON_24_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24G, PM_SCC_ON_24G, PM_SCC_ON_24G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+				PM_SBS_CH_MCC_CH_SCC_ON_24_24G,
+				PM_SBS_CH_MCC_CH_SCC_ON_24_24G},
+	[PM_P2P_GO_MODE] = {PM_MCC_CH_SCC_ON_24G, PM_MCC_CH_SCC_ON_24G,
+			    PM_MCC_CH_SCC_ON_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH,
+			    PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH,
+			    PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH, PM_SCC_ON_5G_HIGH,
+			 PM_SCC_ON_5G_HIGH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW,
+			    PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW,
+			    PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_LL_LT_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24G, PM_SCC_ON_24G, PM_SCC_ON_24G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+				PM_SBS_5G_MCC_24G},
+	[PM_P2P_GO_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			    PM_SBS_5G_MCC_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_LL_LT_SAP_MCC_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH, PM_SCC_ON_5G_HIGH,
+			 PM_SCC_ON_5G_HIGH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_24_LL_LT_SAP_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_24G, PM_SCC_ON_24G, PM_SCC_ON_24G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+				PM_SBS_5G_MCC_24G},
+	[PM_P2P_GO_MODE] = {PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_24G,
+			    PM_SBS_5G_MCC_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_LL_LT_SAP_MCC_1x1] = {
+	[PM_STA_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_SAP_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_CLIENT_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_P2P_GO_MODE] = {PM_SBS_CH_2G, PM_SBS_CH_2G, PM_SBS_CH_2G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW, PM_SCC_ON_5G_LOW},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1] = {
+	[PM_STA_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_SAP_MODE] = {PM_SCC_ON_5G_HIGH, PM_SCC_ON_5G_HIGH,
+			 PM_SCC_ON_5G_HIGH},
+	[PM_P2P_CLIENT_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_P2P_GO_MODE] = {PM_5G_24G, PM_5G_24G, PM_5G_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+};
+#endif

+ 3692 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_no_dbs_i.h

@@ -0,0 +1,3692 @@
+/*
+ * Copyright (c) 2012-2017, 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_NAN_DISC_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_5G, PM_SCC_CH, PM_SCC_CH_5G},
+	[PM_NAN_DISC_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G} },
+
+	[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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_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_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_NDI_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_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_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_NDI_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_LL_LT_SAP_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			      PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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). For helium that is NON-DBS,
+ * DBS 1x1, three port concurrency would be disabled, so for every
+ * combination MAX_PCL_TYPE would be the return value, if in future
+ * the requirement for 3 port concurrency comes, refer to below table
+ * for details.
+ * 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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},
+ * };
+ */
+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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_NONE, PM_NONE, PM_NONE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+};
+
+#ifdef FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT
+
+/*
+ * second_connection_pcl_nodbs_no_interband_mcc_table - table
+ * which provides PCL for the 2nd connection, when we have a
+ * connection already in the system (when DBS and interband mcc
+ * are not 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 const enum policy_mgr_pcl_type
+second_connection_pcl_nodbs_no_interband_mcc_table[PM_MAX_ONE_CONNECTION_MODE]
+	[PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE] = {
+	[PM_STA_24_1x1] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+				PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_24_2x2] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH},
+	[PM_P2P_CLIENT_MODE] = {
+				PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_1x1] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_5G},
+	[PM_P2P_CLIENT_MODE] = {
+				PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_5G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_5G},
+	[PM_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_5_2x2] = {
+	[PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_5G},
+	[PM_P2P_CLIENT_MODE] = {
+				PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_5G},
+	[PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_5G},
+	[PM_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_24_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_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_24_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_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G, PM_SCC_CH_5G},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G, PM_SCC_CH_5G},
+	[PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_24_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_24_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_5G, PM_SCC_CH_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_NAN_DISC_MODE] = {
+			PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_24_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_NDI_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_24_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_NDI_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+	[PM_LL_LT_SAP_5_2x2] = {
+	[PM_STA_MODE] = {PM_SBS_5G_MCC_24G,
+			 PM_SBS_5G_MCC_24G, PM_SBS_5G_MCC_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_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			      PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+};
+
+/*
+ * third_connection_pcl_nodbs_no_interband_mcc_table - table which provides
+ * PCL for the 3rd connection, when we have two connections already in
+ * the system (when DBS and interband mcc are not supported by HW)
+ */
+static const enum policy_mgr_pcl_type
+third_connection_pcl_nodbs_no_interband_mcc_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_SAP_NAN_DISC_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_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_NAN_DISC_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+		PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_CLI_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_DBS_1x1] = {
+	[PM_STA_MODE] = {
+		PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G,
+		PM_SCC_ON_5_SCC_ON_24_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_P2P_GO_P2P_GO_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_STA_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_NAN_DISC_MODE] = {
+		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_STA_NAN_DISC_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_NDI_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_5G},
+	[PM_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_SCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_SCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_MCC_24_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_MCC_24_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_DBS_1x1] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+
+	[PM_NAN_DISC_NDI_DBS_2x2] = {
+	[PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH_5G, PM_SCC_CH_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_LL_LT_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE,
+			       PM_MAX_PCL_TYPE} },
+};
+#endif /* FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT */
+#endif

+ 381 - 0
qcom/opensource/wlan/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c

@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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"
+#include "wlan_nan_api.h"
+
+#ifdef WLAN_FEATURE_SR
+/**
+ * policy_mgr_init_same_mac_conc_sr_status() - Function initializes default
+ * value to sr_in_same_mac_conc based on INI g_enable_sr_in_same_mac_conc
+ *
+ * @psoc: Pointer to PSOC
+ *
+ * Return: void
+ */
+static void
+policy_mgr_init_same_mac_conc_sr_status(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->cfg.sr_in_same_mac_conc =
+		cfg_get(psoc, CFG_ENABLE_SR_IN_SAME_MAC_CONC);
+}
+#else
+static void
+policy_mgr_init_same_mac_conc_sr_status(struct wlan_objmgr_psoc *psoc)
+{}
+#endif
+
+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);
+	if (cfg->mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE &&
+	    cfg->mcc_to_scc_switch <
+			QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) {
+		policy_mgr_info("User configured mcc_to_scc_switch: %d, overwrite it to: %d",
+			cfg->mcc_to_scc_switch,
+			QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION);
+		cfg->mcc_to_scc_switch =
+			QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION;
+	}
+
+	cfg->sys_pref = cfg_get(psoc, CFG_CONC_SYS_PREF);
+
+	if (wlan_is_mlo_sta_nan_ndi_allowed(psoc)) {
+		cfg->max_conc_cxns = cfg_get(psoc, CFG_MAX_CONC_CXNS) + 1;
+		 policy_mgr_err("max_conc_cxns %d nan", cfg->max_conc_cxns);
+	} else {
+		cfg->max_conc_cxns = cfg_get(psoc, CFG_MAX_CONC_CXNS);
+		policy_mgr_err("max_conc_cxns %d non-nan", cfg->max_conc_cxns);
+	}
+	cfg->max_conc_cxns = QDF_MIN(cfg->max_conc_cxns,
+				     MAX_NUMBER_OF_CONC_CONNECTIONS);
+	cfg->conc_rule1 = cfg_get(psoc, CFG_ENABLE_CONC_RULE1);
+	cfg->conc_rule2 = cfg_get(psoc, CFG_ENABLE_CONC_RULE2);
+	cfg->pcl_band_priority = cfg_get(psoc, CFG_PCL_BAND_PRIORITY);
+	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_ADAPTIVE_SCH_ENABLED_NAME);
+	cfg->enable_sta_cxn_5g_band =
+		cfg_get(psoc, CFG_ENABLE_STA_CONNECTION_IN_5GHZ);
+	cfg->allow_mcc_go_diff_bi =
+		cfg_get(psoc, CFG_ALLOW_MCC_GO_DIFF_BI);
+	cfg->dual_mac_feature =
+		cfg_get(psoc, CFG_DUAL_MAC_FEATURE_DISABLE);
+	cfg->sbs_enable =
+		cfg_get(psoc, CFG_ENABLE_SBS);
+	cfg->is_force_1x1_enable =
+		cfg_get(psoc, CFG_FORCE_1X1_FEATURE);
+	cfg->sta_sap_scc_on_dfs_chnl =
+		cfg_get(psoc, CFG_STA_SAP_SCC_ON_DFS_CHAN);
+
+	/*
+	 * Override concurrency sta+sap indoor flag to true if global indoor
+	 * flag is true
+	 */
+	cfg->sta_sap_scc_on_indoor_channel =
+		cfg_get(psoc, CFG_STA_SAP_SCC_ON_INDOOR_CHAN);
+	if (cfg_get(psoc, CFG_INDOOR_CHANNEL_SUPPORT))
+		cfg->sta_sap_scc_on_indoor_channel = true;
+
+	/*
+	 * Force set sta_sap_scc_on_dfs_chnl on Non-DBS HW so that standalone
+	 * SAP is not allowed on DFS channel on non-DBS HW, Also, force SCC in
+	 * case of STA+SAP
+	 */
+	if (cfg->sta_sap_scc_on_dfs_chnl == 2 &&
+	    !cfg_get(psoc, CFG_ENABLE_DFS_MASTER_CAPABILITY))
+		cfg->sta_sap_scc_on_dfs_chnl = 0;
+	cfg->nan_sap_scc_on_lte_coex_chnl =
+		cfg_get(psoc, CFG_NAN_SAP_SCC_ON_LTE_COEX_CHAN);
+	cfg->sta_sap_scc_on_lte_coex_chnl =
+		cfg_get(psoc, CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN);
+	cfg->sap_mandatory_chnl_enable =
+		cfg_get(psoc, CFG_ENABLE_SAP_MANDATORY_CHAN_LIST);
+	cfg->mark_indoor_chnl_disable =
+		cfg_get(psoc, CFG_MARK_INDOOR_AS_DISABLE_FEATURE);
+	cfg->go_force_scc = cfg_get(psoc, CFG_P2P_GO_ENABLE_FORCE_SCC);
+	cfg->multi_sap_allowed_on_same_band =
+		cfg_get(psoc, CFG_MULTI_SAP_ALLOWED_ON_SAME_BAND);
+	policy_mgr_init_same_mac_conc_sr_status(psoc);
+	cfg->use_sap_original_bw =
+		cfg_get(psoc, CFG_SAP_DEFAULT_BW_FOR_RESTART);
+	cfg->move_sap_go_1st_on_dfs_sta_csa =
+		cfg_get(psoc, CFG_MOVE_SAP_GO_1ST_ON_DFS_STA_CSA);
+
+	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 (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("pm_ctx is NULL");
+		return status;
+	}
+
+	status = policy_mgr_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("psoc open fail");
+		policy_mgr_psoc_close(psoc);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void ucfg_policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	policy_mgr_psoc_close(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_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_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_set_dynamic_mcc_adaptive_sch(
+					struct wlan_objmgr_psoc *psoc,
+					bool dynamic_mcc_adaptive_sch)
+{
+	return policy_mgr_set_dynamic_mcc_adaptive_sch(
+					psoc, dynamic_mcc_adaptive_sch);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_dynamic_mcc_adaptive_sch(
+					struct wlan_objmgr_psoc *psoc,
+					bool *dynamic_mcc_adaptive_sch)
+{
+	return policy_mgr_get_dynamic_mcc_adaptive_sch(
+					psoc, dynamic_mcc_adaptive_sch);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
+						bool *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);
+}
+
+QDF_STATUS
+ucfg_policy_mgr_get_allow_mcc_go_diff_bi(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *allow_mcc_go_diff_bi)
+{
+	return policy_mgr_get_allow_mcc_go_diff_bi(psoc, allow_mcc_go_diff_bi);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_dual_mac_feature(struct wlan_objmgr_psoc *psoc,
+						uint8_t *dual_mac_feature)
+{
+	return policy_mgr_get_dual_mac_feature(psoc, dual_mac_feature);
+}
+
+bool ucfg_policy_mgr_get_dual_sta_feature(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_allow_multiple_sta_connections(psoc);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_force_1x1(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *force_1x1)
+{
+	return policy_mgr_get_force_1x1(psoc, force_1x1);
+}
+
+uint32_t ucfg_policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_get_max_conc_cxns(psoc);
+}
+
+QDF_STATUS ucfg_policy_mgr_set_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
+					     uint32_t max_conc_cxns)
+{
+	return policy_mgr_set_max_conc_cxns(psoc, max_conc_cxns);
+}
+
+QDF_STATUS
+ucfg_policy_mgr_get_radio_combinations(struct wlan_objmgr_psoc *psoc,
+				       struct radio_combination *comb,
+				       uint32_t comb_max,
+				       uint32_t *comb_num)
+{
+	return policy_mgr_get_radio_combinations(psoc, comb,
+						 comb_max, comb_num);
+}
+
+QDF_STATUS
+ucfg_policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *sta_sap_scc_on_dfs_chnl)
+{
+	return policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc,
+						      sta_sap_scc_on_dfs_chnl);
+}
+
+bool
+ucfg_policy_mgr_get_dfs_master_dynamic_enabled(struct wlan_objmgr_psoc *psoc,
+					       uint8_t vdev_id)
+{
+	return policy_mgr_get_dfs_master_dynamic_enabled(psoc, vdev_id);
+}
+
+QDF_STATUS
+ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *sta_sap_scc_lte_coex)
+{
+	return policy_mgr_get_sta_sap_scc_lte_coex_chnl(psoc,
+							sta_sap_scc_lte_coex);
+}
+
+QDF_STATUS
+ucfg_policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc,
+				    qdf_freq_t *chan_freq_list,
+				    uint16_t chan_cnt)
+{
+	return policy_mgr_init_chan_avoidance(psoc, chan_freq_list, chan_cnt);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *sap_mandt_chnl)
+{
+	return policy_mgr_get_sap_mandt_chnl(psoc, sap_mandt_chnl);
+}
+
+QDF_STATUS
+ucfg_policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc *psoc,
+					uint8_t *indoor_chnl_marking)
+{
+	return policy_mgr_get_indoor_chnl_marking(psoc, indoor_chnl_marking);
+}
+
+bool
+ucfg_policy_mgr_get_sta_sap_scc_on_indoor_chnl(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc) ?
+								true : false;
+}
+
+bool ucfg_policy_mgr_is_fw_supports_dbs(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_find_if_fw_supports_dbs(psoc);
+}
+
+uint32_t ucfg_policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_get_connection_count(psoc);
+}
+
+bool ucfg_policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_is_hw_dbs_capable(psoc);
+}
+
+bool ucfg_policy_mgr_get_vdev_same_freq_new_conn(struct wlan_objmgr_psoc *psoc,
+						 uint32_t new_freq,
+						 uint8_t *vdev_id)
+{
+	return policy_mgr_get_vdev_same_freq_new_conn(psoc, new_freq, vdev_id);
+}
+
+bool ucfg_policy_mgr_get_vdev_diff_freq_new_conn(struct wlan_objmgr_psoc *psoc,
+						 uint32_t new_freq,
+						 uint8_t *vdev_id)
+{
+	return policy_mgr_get_vdev_diff_freq_new_conn(psoc, new_freq, vdev_id);
+}
+
+QDF_STATUS ucfg_policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc,
+					    bool *one_by_one_dbs,
+					    bool *two_by_two_dbs)
+{
+	return policy_mgr_get_dbs_hw_modes(psoc, one_by_one_dbs,
+					   two_by_two_dbs);
+}

+ 152 - 0
qcom/opensource/wlan/qcacld-3.0/components/coap/core/inc/wlan_coap_main.h

@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains declarations for CoAP core functions
+ */
+
+#ifndef _WLAN_COAP_MAIN_H_
+#define _WLAN_COAP_MAIN_H_
+
+#ifdef WLAN_FEATURE_COAP
+#include "wlan_objmgr_vdev_obj.h"
+
+#define coap_err(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_COAP, params)
+#define coap_info(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_COAP, params)
+#define coap_debug(params...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_COAP, params)
+
+/**
+ * struct wlan_coap_comp_priv - CoAP component private structure
+ * @req_id: cache get request id
+ * @cache_get_cbk: Callback function to be called with the cache get result
+ * @cache_get_context: context to be used by the caller to associate the get
+ * cache request with the response
+ */
+struct wlan_coap_comp_priv {
+	uint32_t req_id;
+	coap_cache_get_callback cache_get_cbk;
+	void *cache_get_context;
+};
+
+static inline struct wlan_coap_comp_priv *
+wlan_get_vdev_coap_obj(struct wlan_objmgr_vdev *vdev)
+{
+	return wlan_objmgr_vdev_get_comp_private_obj(vdev,
+						     WLAN_UMAC_COMP_COAP);
+}
+
+/*
+ * wlan_coap_init() - CoAP module initialization API
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_coap_init(void);
+
+/*
+ * wlan_coap_init() - CoAP module deinitialization API
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_coap_deinit(void);
+
+/**
+ * wlan_coap_enable(): API to enable CoAP component
+ * @psoc: pointer to psoc
+ *
+ * This API is invoked from dispatcher psoc enable.
+ * This API will register CoAP related WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_coap_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_coap_disable(): API to disable CoAP component
+ * @psoc: pointer to psoc
+ *
+ * This API is invoked from dispatcher psoc disable.
+ * This API will unregister CoAP related WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_coap_disable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_coap_offload_reply_enable() - private API to enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP offload reply
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+			       struct coap_offload_reply_param *param);
+
+/**
+ * wlan_coap_offload_reply_disable() - private API to disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache info
+ * @context: context to be used by the caller to associate the disable request
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+				coap_cache_get_callback cbk, void *context);
+
+/**
+ * wlan_coap_offload_periodic_tx_enable() - private API to enable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP periodic transmit
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+			struct coap_offload_periodic_tx_param *param);
+
+/**
+ * wlan_coap_offload_periodic_tx_disable() - private API to disable CoAP
+ * offload periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+				      uint32_t req_id);
+
+/**
+ * wlan_coap_offload_cache_get() - private API to get CoAP offload cache
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache get result
+ * @context: context to be used by the caller to associate the get
+ * cache request with the response
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+			    coap_cache_get_callback cbk, void *context);
+#endif
+#endif

+ 163 - 0
qcom/opensource/wlan/qcacld-3.0/components/coap/core/src/wlan_coap_main.c

@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains definitions for CoAP core functions
+ */
+
+#include <wlan_coap_tgt_api.h>
+#include <wlan_coap_main.h>
+#include <wlan_objmgr_global_obj.h>
+
+QDF_STATUS wlan_coap_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return tgt_coap_attach(psoc);
+}
+
+QDF_STATUS wlan_coap_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return tgt_coap_detach(psoc);
+}
+
+static QDF_STATUS
+wlan_coap_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg)
+{
+	struct wlan_coap_comp_priv *coap_priv;
+	QDF_STATUS status;
+
+	if (!vdev)
+		return QDF_STATUS_E_INVAL;
+
+	coap_priv = qdf_mem_malloc(sizeof(struct wlan_coap_comp_priv));
+	if (!coap_priv)
+		return QDF_STATUS_E_NOMEM;
+
+	status = wlan_objmgr_vdev_component_obj_attach(vdev,
+						       WLAN_UMAC_COMP_COAP,
+						       (void *)coap_priv,
+						       QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status))
+		qdf_mem_free(coap_priv);
+
+	return status;
+}
+
+static QDF_STATUS
+wlan_coap_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, void *arg)
+{
+	void *coap_priv;
+
+	if (!vdev) {
+		coap_err("Vdev NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	coap_priv = wlan_get_vdev_coap_obj(vdev);
+	if (!coap_priv) {
+		coap_err("coap_priv NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_COAP,
+					      coap_priv);
+	qdf_mem_free(coap_priv);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_coap_init(void)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_COAP,
+				wlan_coap_vdev_obj_create_handler, NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		return status;
+
+	status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_COAP,
+				wlan_coap_vdev_obj_destroy_handler, NULL);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_COAP,
+				wlan_coap_vdev_obj_create_handler, NULL);
+	return status;
+}
+
+QDF_STATUS wlan_coap_deinit(void)
+{
+	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_COAP,
+				wlan_coap_vdev_obj_create_handler, NULL);
+	wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_COAP,
+				wlan_coap_vdev_obj_destroy_handler, NULL);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+			       struct coap_offload_reply_param *params)
+{
+	return tgt_send_coap_offload_reply_enable(vdev, params);
+}
+
+QDF_STATUS
+wlan_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+				coap_cache_get_callback cbk, void *context)
+{
+	struct wlan_coap_comp_priv *coap_priv;
+
+	if (!vdev) {
+		coap_err("Vdev NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	coap_priv = wlan_get_vdev_coap_obj(vdev);
+	coap_priv->req_id = req_id;
+	coap_priv->cache_get_context = context;
+	coap_priv->cache_get_cbk = cbk;
+	return tgt_send_coap_offload_reply_disable(vdev, req_id);
+}
+
+QDF_STATUS
+wlan_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+			struct coap_offload_periodic_tx_param *params)
+{
+	return tgt_send_coap_offload_periodic_tx_enable(vdev, params);
+}
+
+QDF_STATUS
+wlan_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+				      uint32_t req_id)
+{
+	return tgt_send_coap_offload_periodic_tx_disable(vdev, req_id);
+}
+
+QDF_STATUS
+wlan_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+			    coap_cache_get_callback cbk, void *context)
+{
+	struct wlan_coap_comp_priv *coap_priv;
+
+	if (!vdev) {
+		coap_err("Vdev NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	coap_priv = wlan_get_vdev_coap_obj(vdev);
+	coap_priv->req_id = req_id;
+	coap_priv->cache_get_context = context;
+	coap_priv->cache_get_cbk = cbk;
+	return tgt_send_coap_offload_cache_get(vdev, req_id);
+}

+ 123 - 0
qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/inc/wlan_coap_public_structs.h

@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains CoAP structure definitions
+ */
+
+#ifndef _WLAN_COAP_PUBLIC_STRUCTS_H_
+#define _WLAN_COAP_PUBLIC_STRUCTS_H_
+#include <qdf_types.h>
+
+/**
+ * struct coap_offload_reply_param - parameters to enable CoAP offload reply
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ * @cache_timeout: the cached packet expire timeout in ms
+ * @src_ip_v4: source IPv4 address for sending reply message
+ * @src_udp_port: source udp port for sending reply message
+ * @dest_ip_v4: destination IPv4 address to match received CoAP message
+ * @dest_ip_v4_is_bc: indicate whether the destination address is broadcast
+ * address or not
+ * @dest_udp_port: destination UDP port to match received CoAP message
+ * @verify_offset: UDP payload offset to match received CoAP message
+ * @verify_len: UDP payload length to match received CoAP message
+ * @verify: pointer to binary data to match received CoAP message
+ * @coapmsg_len: CoAP reply message length
+ * @coapmsg: pointer to CoAP reply message
+ */
+struct coap_offload_reply_param {
+	uint32_t vdev_id;
+	uint32_t pattern_id;
+	uint32_t cache_timeout;
+	uint32_t src_ip_v4;
+	uint16_t src_udp_port;
+	uint32_t dest_ip_v4;
+	bool dest_ip_v4_is_bc;
+	uint16_t dest_udp_port;
+	uint32_t verify_offset;
+	uint32_t verify_len;
+	uint8_t *verify;
+	uint32_t coapmsg_len;
+	uint8_t *coapmsg;
+};
+
+/**
+ * struct coap_offload_periodic_tx_param - parameters to enable CoAP offload
+ * periodic transmitting
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ * @src_ip_v4: IPv4 address for sending CoAP message
+ * @src_udp_port: source udp port for sending CoAP message
+ * @dest_ip_v4: destination IPv4 address for sending CoAP message
+ * @dest_ip_v4_is_bc: indicate whether the destination address is broadcast
+ * address or not
+ * @dest_udp_port: destination UDP port for sending CoAP message
+ * @timeout: the periorid to send keepalive message in ms
+ * @coapmsg_len: keeplive CoAP message length
+ * @coapmsg: pointer to keeplive CoAP message
+ */
+struct coap_offload_periodic_tx_param {
+	uint32_t vdev_id;
+	uint32_t pattern_id;
+	uint32_t src_ip_v4;
+	uint16_t src_udp_port;
+	uint32_t dest_ip_v4;
+	bool dest_ip_v4_is_bc;
+	uint16_t dest_udp_port;
+	uint32_t timeout;
+	uint32_t coapmsg_len;
+	uint8_t *coapmsg;
+};
+
+/**
+ * struct coap_buf_node - CoAP message info entry
+ * @node: List entry element
+ * @tsf: TSF of the CoAP meesage
+ * @src_ip: source IPv4 address of the CoAP message
+ * @len: length of the payload
+ * @payload: pointer to buffer holding UDP payload of the CoAP message
+ */
+struct coap_buf_node {
+	qdf_list_node_t node;
+	uint64_t tsf;
+	uint32_t src_ip;
+	uint32_t len;
+	uint8_t *payload;
+};
+
+/**
+ * struct coap_buf_info - info of the cached CoAP messages
+ * @vdev_id: vdev id
+ * @req_id: request id
+ * @more_info: flag to indicate whether there are more cached messages
+ * @info_list: list to hold cached CoAP messages
+ */
+struct coap_buf_info {
+	uint8_t vdev_id;
+	uint32_t req_id;
+	bool more_info;
+	qdf_list_t info_list;
+};
+
+/**
+ * typedef coap_cache_get_callback() - callback for getting cached CoAP messages
+ * @context: context for getting cached CoAP messages
+ * @info: pointer to info of the cached CoAP messages
+ */
+typedef void (*coap_cache_get_callback)(void *context,
+					struct coap_buf_info *info);
+#endif

+ 106 - 0
qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/inc/wlan_coap_tgt_api.h

@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains CoAP south bound interface definitions
+ */
+
+#ifndef _WLAN_COAP_TGT_API_H_
+#define _WLAN_COAP_TGT_API_H_
+
+#ifdef WLAN_FEATURE_COAP
+#include <qdf_types.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+
+/**
+ * tgt_coap_attach(): attach CoAP component
+ * @psoc: pointer to psoc
+ *
+ * This API will register CoAP related WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS tgt_coap_attach(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_coap_detach(): detach CoAP component
+ * @psoc: pointer to psoc
+ *
+ * This API will unregister CoAP related WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS tgt_coap_detach(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_send_coap_offload_reply_enable() - enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters for CoAP offload reply
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+				   struct coap_offload_reply_param *param);
+
+/**
+ * tgt_send_coap_offload_reply_disable() - disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev,
+				    uint32_t req_id);
+
+/**
+ * tgt_send_coap_offload_periodic_tx_enable() - enable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @param: parameters for CoAP periodic transmitting
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+			struct coap_offload_periodic_tx_param *param);
+
+/**
+ * tgt_send_coap_offload_periodic_tx_disable() - disable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+					  uint32_t req_id);
+
+/**
+ * tgt_send_coap_offload_cache_get() - get cached CoAP messages
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev,
+				uint32_t req_id);
+#endif
+#endif

+ 91 - 0
qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/inc/wlan_coap_ucfg_api.h

@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains CoAP north bound interface declarations
+ */
+
+#ifndef _WLAN_COAP_UCFG_API_H_
+#define _WLAN_COAP_UCFG_API_H_
+
+#include "qdf_status.h"
+#include <wlan_objmgr_vdev_obj.h>
+#include "wlan_coap_public_structs.h"
+
+#ifdef WLAN_FEATURE_COAP
+/**
+ * ucfg_coap_offload_reply_enable() - API to enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP offload reply
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+			       struct coap_offload_reply_param *param);
+
+/**
+ * ucfg_coap_offload_reply_disable() - API to disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to invoke with cached data
+ * @context: caller-supplied context
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+				coap_cache_get_callback cbk, void *context);
+
+/**
+ * ucfg_coap_offload_periodic_tx_enable() - API to enable CoAP offload
+ * periodic transmit
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP periodic transmit
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+			struct coap_offload_periodic_tx_param *param);
+
+/**
+ * ucfg_coap_offload_periodic_tx_disable() - API to disable CoAP offload
+ * periodic transmit
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+				      uint32_t req_id);
+
+/**
+ * ucfg_coap_offload_cache_get() - API to get CoAP offload cache
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache get result
+ * @context: context to be used by the caller to associate the get
+ * cache request with the response
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+			    coap_cache_get_callback cbk, void *context);
+#endif
+#endif

+ 187 - 0
qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/src/wlan_coap_tgt_api.c

@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains CoAP south bound interface definitions
+ */
+
+#include <wlan_coap_main.h>
+#include <wlan_coap_tgt_api.h>
+#include <wlan_lmac_if_def.h>
+#include "wlan_objmgr_pdev_obj.h"
+
+static inline struct wlan_lmac_if_coap_tx_ops *
+wlan_psoc_get_coap_txops(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_tx_ops *tx_ops;
+
+	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
+	if (!tx_ops) {
+		coap_err("tx_ops is NULL");
+		return NULL;
+	}
+
+	return &tx_ops->coap_ops;
+}
+
+static inline struct wlan_lmac_if_coap_tx_ops *
+wlan_vdev_get_coap_txops(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		coap_err("NULL psoc");
+		return NULL;
+	}
+
+	return wlan_psoc_get_coap_txops(psoc);
+}
+
+QDF_STATUS tgt_coap_attach(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_coap_tx_ops *coap_tx_ops;
+
+	if (!psoc) {
+		coap_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coap_tx_ops = wlan_psoc_get_coap_txops(psoc);
+	if (!coap_tx_ops) {
+		coap_err("tx_ops is null!");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!coap_tx_ops->attach) {
+		coap_err("attach function is null!");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return coap_tx_ops->attach(psoc);
+}
+
+QDF_STATUS tgt_coap_detach(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_coap_tx_ops *coap_tx_ops;
+
+	if (!psoc) {
+		coap_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coap_tx_ops = wlan_psoc_get_coap_txops(psoc);
+	if (!coap_tx_ops) {
+		coap_err("tx_ops is null!");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!coap_tx_ops->detach) {
+		coap_err("coap_detach function is null!");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return coap_tx_ops->detach(psoc);
+}
+
+QDF_STATUS
+tgt_send_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+				   struct coap_offload_reply_param *param)
+{
+	struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+	if (!vdev) {
+		coap_err("NULL vdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coap_ops = wlan_vdev_get_coap_txops(vdev);
+	if (coap_ops && coap_ops->offload_reply_enable)
+		return coap_ops->offload_reply_enable(vdev, param);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev,
+				    uint32_t req_id)
+{
+	struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+	if (!vdev) {
+		coap_err("NULL vdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coap_ops = wlan_vdev_get_coap_txops(vdev);
+	if (coap_ops && coap_ops->offload_reply_disable)
+		return coap_ops->offload_reply_disable(vdev, req_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+			struct coap_offload_periodic_tx_param *param)
+{
+	struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+	if (!vdev) {
+		coap_err("NULL vdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coap_ops = wlan_vdev_get_coap_txops(vdev);
+	if (coap_ops && coap_ops->offload_periodic_tx_enable)
+		return coap_ops->offload_periodic_tx_enable(vdev, param);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+					  uint32_t req_id)
+{
+	struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+	if (!vdev) {
+		coap_err("NULL vdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coap_ops = wlan_vdev_get_coap_txops(vdev);
+	if (coap_ops && coap_ops->offload_periodic_tx_disable)
+		return coap_ops->offload_periodic_tx_disable(vdev, req_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id)
+{
+	struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+	if (!vdev) {
+		coap_err("NULL vdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coap_ops = wlan_vdev_get_coap_txops(vdev);
+	if (coap_ops && coap_ops->offload_cache_get)
+		return coap_ops->offload_cache_get(vdev, req_id);
+
+	return QDF_STATUS_SUCCESS;
+}

+ 99 - 0
qcom/opensource/wlan/qcacld-3.0/components/coap/dispatcher/src/wlan_coap_ucfg_api.c

@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains CoAP north bound interface definitions
+ */
+
+#include <wlan_coap_main.h>
+#include <wlan_coap_ucfg_api.h>
+
+/**
+ * ucfg_coap_offload_reply_enable() - API to enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP offload reply
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+			       struct coap_offload_reply_param *param)
+{
+	return wlan_coap_offload_reply_enable(vdev, param);
+}
+
+/**
+ * ucfg_coap_offload_reply_disable() - API to disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache info
+ * @context: context to be used by the caller to associate the disable request
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+				coap_cache_get_callback cbk, void *context)
+{
+	return wlan_coap_offload_reply_disable(vdev, req_id, cbk, context);
+}
+
+/**
+ * ucfg_coap_offload_periodic_tx_enable() - API to enable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @param: parameters for CoAP periodic transmit
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+			struct coap_offload_periodic_tx_param *param)
+{
+	return wlan_coap_offload_periodic_tx_enable(vdev, param);
+}
+
+/**
+ * ucfg_coap_offload_periodic_tx_disable() - private API to disable CoAP
+ * offload periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+				      uint32_t req_id)
+{
+	return wlan_coap_offload_periodic_tx_disable(vdev, req_id);
+}
+
+/**
+ * ucfg_coap_offload_cache_get() - API to get CoAP offload cache
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache get result
+ * @context: context to be used by the caller to associate the get
+ * cache request with the response
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+			    coap_cache_get_callback cbk, void *context)
+{
+	return wlan_coap_offload_cache_get(vdev, req_id, cbk, context);
+}

+ 249 - 0
qcom/opensource/wlan/qcacld-3.0/components/coex/core/inc/wlan_coex_main.h

@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains declarations for coex core functions
+ */
+
+#ifndef _WLAN_COEX_MAIN_API_H_
+#define _WLAN_COEX_MAIN_API_H_
+
+#ifdef FEATURE_COEX
+#include "wlan_coex_ucfg_api.h"
+#include "wmi_unified_param.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+
+#define coex_err(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_COEX, params)
+#define coex_info(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_COEX, params)
+#define coex_debug(params...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_COEX, params)
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+/**
+ * struct wlan_coex_callback - coex dbam callback structure
+ * @set_dbam_config_cb: callback for set_dbam_config
+ * @set_dbam_config_ctx: context for set_dbam_config callback
+ */
+struct wlan_coex_callback {
+	void (*set_dbam_config_cb)(void *ctx, enum coex_dbam_comp_status *rsp);
+	void *set_dbam_config_ctx;
+};
+#endif
+
+/**
+ * struct coex_psoc_obj - coex object definition
+ * @btc_chain_mode: BT Coex chain mode.
+ * @coex_config_updated: callback functions for each config type, which will
+ *  be called when config is updated.
+ * @cb: structure to dbam callback
+ */
+struct coex_psoc_obj {
+	enum coex_btc_chain_mode btc_chain_mode;
+	update_coex_cb coex_config_updated[COEX_CONFIG_TYPE_MAX];
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+	struct wlan_coex_callback cb;
+#endif
+};
+
+/**
+ * wlan_psoc_get_coex_obj() - private API to get coex object from psoc
+ * @psoc: psoc object
+ *
+ * Return: coex object
+ */
+#define wlan_psoc_get_coex_obj(psoc) \
+	wlan_psoc_get_coex_obj_fl(psoc, __func__, __LINE__)
+
+static inline struct coex_psoc_obj *
+wlan_psoc_get_coex_obj_fl(struct wlan_objmgr_psoc *psoc,
+			  const char *func, uint32_t line)
+{
+	struct coex_psoc_obj *psoc_obj;
+
+	psoc_obj = (struct coex_psoc_obj *)
+		wlan_objmgr_psoc_get_comp_private_obj(psoc,
+						      WLAN_UMAC_COMP_COEX);
+	if (!psoc_obj) {
+		coex_err("%s:%u, Failed to get coex psoc object", func, line);
+		return NULL;
+	}
+	return psoc_obj;
+}
+
+/**
+ * wlan_coex_psoc_init() - API to initialize coex component
+ * @psoc: soc context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_coex_psoc_init(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_coex_psoc_deinit() - API to deinitialize coex component
+ * @psoc: soc context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_coex_psoc_deinit(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_coex_config_send() - private API to send coex config
+ * @vdev: pointer to vdev object
+ * @param: parameters of coex config
+ *
+ * Return: status of operation
+ */
+QDF_STATUS wlan_coex_config_send(struct wlan_objmgr_vdev *vdev,
+				 struct coex_config_params *param);
+
+/**
+ * wlan_coex_multi_config_send() - API to send coex multiple configure
+ * @vdev: pointer to vdev object
+ * @param: parameters of coex multiple config
+ *
+ * QDF_STATUS
+ */
+QDF_STATUS wlan_coex_multi_config_send(struct wlan_objmgr_vdev *vdev,
+				       struct coex_multi_config *param);
+
+/**
+ * wlan_coex_config_updated() - private API to notify that coex config
+ * is updated.
+ * @vdev: pointer to vdev object
+ * @type: type of coex config
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coex_config_updated(struct wlan_objmgr_vdev *vdev, uint8_t type);
+
+/**
+ * wlan_coex_psoc_created_notification() - PSOC obj create callback
+ * @psoc: PSOC object
+ * @arg_list: Variable argument list
+ *
+ * This callback is registered with object manager during initialization to
+ * get notified when the object is created.
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS wlan_coex_psoc_created_notification(struct wlan_objmgr_psoc *psoc,
+					       void *arg_list);
+
+/**
+ * wlan_coex_psoc_destroyed_notification() - PSOC obj delete callback
+ * @psoc: PSOC object
+ * @arg_list: Variable argument list
+ *
+ * This callback is registered with object manager during initialization to
+ * get notified when the object is deleted.
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS wlan_coex_psoc_destroyed_notification(struct wlan_objmgr_psoc *psoc,
+						 void *arg_list);
+
+/**
+ * wlan_coex_psoc_set_btc_chain_mode() - private API to set BT coex chain mode
+ * for psoc
+ * @psoc: pointer to psoc object
+ * @val: BT coex chain mode
+ *
+ * Return : status of operation
+ */
+QDF_STATUS
+wlan_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode val);
+
+/**
+ * wlan_coex_psoc_get_btc_chain_mode() - private API to get BT coex chain mode
+ * from psoc
+ * @psoc: pointer to psoc object
+ * @val: pointer to BT coex chain mode
+ *
+ * Return : status of operation
+ */
+QDF_STATUS
+wlan_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode *val);
+#endif
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+/**
+ * wlan_dbam_config_send() - private API to send dbam config
+ * @vdev: pointer to vdev object
+ * @param: parameters of dbam config
+ *
+ * Return: QDF_STATUS of operation
+ */
+QDF_STATUS wlan_dbam_config_send(struct wlan_objmgr_vdev *vdev,
+				 struct coex_dbam_config_params *param);
+
+static inline struct wlan_lmac_if_dbam_rx_ops *
+wlan_psoc_get_dbam_rx_ops(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_rx_ops *rx_ops;
+
+	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
+	if (!rx_ops) {
+		coex_err("rx_ops is NULL");
+		return NULL;
+	}
+
+	return &rx_ops->dbam_rx_ops;
+}
+
+static inline struct wlan_lmac_if_dbam_tx_ops *
+wlan_psoc_get_dbam_tx_ops(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_tx_ops *tx_ops;
+
+	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
+	if (!tx_ops) {
+		coex_err("tx_ops is NULL");
+		return NULL;
+	}
+
+	return &tx_ops->dbam_tx_ops;
+}
+
+/**
+ * wlan_dbam_attach() - Attach dbam handler
+ * @psoc: psoc pointer
+ *
+ * This function gets called to register dbam FW events handler
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_dbam_attach(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_dbam_detach() - Detach dbam handler
+ * @psoc: psoc pointer
+ *
+ * This function gets called to unregister dbam FW events handler
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_dbam_detach(struct wlan_objmgr_psoc *psoc);
+#endif /* WLAN_FEATURE_DBAM_CONFIG */
+#endif

+ 264 - 0
qcom/opensource/wlan/qcacld-3.0/components/coex/core/src/wlan_coex_main.c

@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains definitions for coex core functions
+ */
+
+#include <wlan_coex_ucfg_api.h>
+#include <wlan_coex_tgt_api.h>
+#include <wlan_coex_main.h>
+
+QDF_STATUS wlan_coex_psoc_created_notification(struct wlan_objmgr_psoc *psoc,
+					       void *arg_list)
+{
+	struct coex_psoc_obj *psoc_obj;
+	QDF_STATUS status;
+
+	psoc_obj = qdf_mem_malloc(sizeof(*psoc_obj));
+	if (!psoc_obj)
+		return QDF_STATUS_E_NOMEM;
+
+	psoc_obj->btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED;
+
+	/* Attach scan private date to psoc */
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+						       WLAN_UMAC_COMP_COEX,
+						       psoc_obj,
+						       QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		coex_err("Failed to attach psoc coex component");
+		qdf_mem_free(psoc_obj);
+	} else {
+		coex_debug("Coex object attach to psoc successful");
+	}
+
+	return status;
+}
+
+QDF_STATUS wlan_coex_psoc_destroyed_notification(struct wlan_objmgr_psoc *psoc,
+						 void *arg_list)
+{
+	void *psoc_obj;
+	QDF_STATUS status;
+
+	psoc_obj = wlan_psoc_get_coex_obj(psoc);
+	if (!psoc_obj)
+		return QDF_STATUS_E_FAILURE;
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+						       WLAN_UMAC_COMP_COEX,
+						       psoc_obj);
+	if (QDF_IS_STATUS_ERROR(status))
+		coex_err("Failed to detach psoc coex component");
+
+	qdf_mem_free(psoc_obj);
+
+	return status;
+}
+
+QDF_STATUS
+wlan_coex_psoc_init(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_coex_psoc_deinit(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_coex_config_send(struct wlan_objmgr_vdev *vdev,
+				 struct coex_config_params *param)
+{
+	QDF_STATUS status;
+
+	status = tgt_send_coex_config(vdev, param);
+	if (QDF_IS_STATUS_ERROR(status))
+		coex_err("failed to send coex config");
+
+	return status;
+}
+
+QDF_STATUS wlan_coex_multi_config_send(struct wlan_objmgr_vdev *vdev,
+				       struct coex_multi_config *param)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct coex_config_params one_param;
+	QDF_STATUS status, ret = QDF_STATUS_SUCCESS;
+	uint32_t i;
+
+	if (!vdev) {
+		coex_err("Null vdev");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		coex_err("failed to get coex_obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (tgt_get_coex_multi_config_support(psoc))
+		return tgt_send_coex_multi_config(vdev, param);
+
+	for (i = 0; i < param->num_configs; i++) {
+		one_param.vdev_id = param->vdev_id;
+		one_param.config_type = param->cfg_items[i].config_type;
+		one_param.config_arg1 = param->cfg_items[i].config_arg1;
+		one_param.config_arg2 = param->cfg_items[i].config_arg2;
+		one_param.config_arg3 = param->cfg_items[i].config_arg3;
+		one_param.config_arg4 = param->cfg_items[i].config_arg4;
+		one_param.config_arg5 = param->cfg_items[i].config_arg5;
+		one_param.config_arg6 = param->cfg_items[i].config_arg6;
+		status = tgt_send_coex_config(vdev, &one_param);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			coex_err("fail to send one coex config");
+			ret = status;
+		}
+	}
+
+	return ret;
+}
+
+QDF_STATUS
+wlan_coex_config_updated(struct wlan_objmgr_vdev *vdev, uint8_t type)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct coex_psoc_obj *coex_obj;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!vdev) {
+		coex_err("NULL vdev");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (type >= COEX_CONFIG_TYPE_MAX) {
+		coex_err("config type out of range: %d", type);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		coex_err("NULL psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	coex_obj = wlan_psoc_get_coex_obj(psoc);
+	if (!coex_obj)
+		return QDF_STATUS_E_INVAL;
+
+	if (coex_obj->coex_config_updated[type])
+		status = coex_obj->coex_config_updated[type](vdev);
+
+	return status;
+}
+
+QDF_STATUS
+wlan_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode val)
+{
+	struct coex_psoc_obj *coex_obj;
+
+	coex_obj = wlan_psoc_get_coex_obj(psoc);
+	if (!coex_obj)
+		return QDF_STATUS_E_INVAL;
+
+	coex_obj->btc_chain_mode = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode *val)
+{
+	struct coex_psoc_obj *coex_obj;
+
+	if (!val) {
+		coex_err("invalid param for getting btc chain mode");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	coex_obj = wlan_psoc_get_coex_obj(psoc);
+	if (!coex_obj)
+		return QDF_STATUS_E_INVAL;
+
+	*val = coex_obj->btc_chain_mode;
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+QDF_STATUS wlan_dbam_config_send(struct wlan_objmgr_vdev *vdev,
+				 struct coex_dbam_config_params *param)
+{
+	QDF_STATUS status;
+
+	status = tgt_send_dbam_config(vdev, param);
+	if (QDF_IS_STATUS_ERROR(status))
+		coex_err("failed to send dbam config");
+
+	return status;
+}
+
+QDF_STATUS wlan_dbam_attach(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_dbam_tx_ops *dbam_tx_ops;
+
+	if (!psoc) {
+		coex_err("psoc is Null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	dbam_tx_ops = wlan_psoc_get_dbam_tx_ops(psoc);
+	if (!dbam_tx_ops) {
+		coex_err("dbam_tx_ops is Null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!dbam_tx_ops->dbam_event_attach) {
+		coex_err("dbam_event_attach function is Null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return dbam_tx_ops->dbam_event_attach(psoc);
+}
+
+QDF_STATUS wlan_dbam_detach(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_dbam_tx_ops *dbam_tx_ops;
+
+	if (!psoc) {
+		coex_err("psoc is Null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	dbam_tx_ops = wlan_psoc_get_dbam_tx_ops(psoc);
+	if (!dbam_tx_ops) {
+		coex_err("dbam_tx_ops is Null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!dbam_tx_ops->dbam_event_detach) {
+		coex_err("dbam_event_detach function is Null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return dbam_tx_ops->dbam_event_detach(psoc);
+}
+#endif

+ 78 - 0
qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/inc/wlan_coex_tgt_api.h

@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains coex south bound interface definitions
+ */
+
+#ifndef _WLAN_COEX_TGT_API_H_
+#define _WLAN_COEX_TGT_API_H_
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+#include "wlan_coex_public_structs.h"
+#endif
+
+#ifdef FEATURE_COEX
+struct coex_config_params;
+struct coex_multi_config;
+
+/**
+ * tgt_send_coex_config() - invoke target_if send coex config
+ * @vdev: vdev object
+ * @param: coex config parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+tgt_send_coex_config(struct wlan_objmgr_vdev *vdev,
+		     struct coex_config_params *param);
+
+/**
+ * tgt_send_coex_multi_config() - invoke target_if send coex multiple config
+ * @vdev: vdev object
+ * @param: coex multiple config parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+tgt_send_coex_multi_config(struct wlan_objmgr_vdev *vdev,
+			   struct coex_multi_config *param);
+
+/**
+ * tgt_get_coex_multi_config_support() - invoke target_if get coex multiple
+ * configure support
+ * @psoc: PSOC object
+ *
+ * Return: true if target support coex multiple config command
+ */
+bool
+tgt_get_coex_multi_config_support(struct wlan_objmgr_psoc *psoc);
+#endif
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+/**
+ * tgt_send_dbam_config() - invoke target_if send dbam config
+ * @vdev: vdev object
+ * @param: dbam config parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+tgt_send_dbam_config(struct wlan_objmgr_vdev *vdev,
+		     struct coex_dbam_config_params *param);
+#endif
+#endif

+ 198 - 0
qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/inc/wlan_coex_ucfg_api.h

@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains coex north bound interface declarations
+ */
+
+#ifndef _WLAN_COEX_UCFG_API_H_
+#define _WLAN_COEX_UCFG_API_H_
+
+#include "qdf_status.h"
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include "wlan_coex_public_structs.h"
+
+/**
+ * enum coex_btc_chain_mode - btc chain mode definitions
+ * @WLAN_COEX_BTC_CHAIN_MODE_SHARED: chains of BT and WLAN 2.4 GHz are shared.
+ * @WLAN_COEX_BTC_CHAIN_MODE_FDD: chains of BT and WLAN 2.4 GHz are
+ * separated, FDD mode.
+ * @WLAN_COEX_BTC_CHAIN_MODE_HYBRID: chains of BT and WLAN 2.4 GHz are
+ * separated, hybrid mode.
+ * @WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED: chain mode is not set.
+ */
+enum coex_btc_chain_mode {
+	WLAN_COEX_BTC_CHAIN_MODE_SHARED = 0,
+	WLAN_COEX_BTC_CHAIN_MODE_FDD,
+	WLAN_COEX_BTC_CHAIN_MODE_HYBRID,
+	WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED = 0xFF,
+};
+
+/**
+ * enum coex_config_type - coex config type definitions
+ * @COEX_CONFIG_BTC_CHAIN_MODE: config BT coex chain mode
+ * @COEX_CONFIG_TYPE_MAX: max value
+ */
+enum coex_config_type {
+	COEX_CONFIG_BTC_CHAIN_MODE,
+	/* keep last */
+	COEX_CONFIG_TYPE_MAX,
+};
+
+/**
+ * typedef update_coex_cb() - cb to inform coex config
+ * @vdev: vdev pointer
+ *
+ * Return: void
+ */
+typedef QDF_STATUS (*update_coex_cb)(struct wlan_objmgr_vdev *vdev);
+
+#ifdef FEATURE_COEX
+/**
+ * ucfg_coex_register_cfg_updated_handler() - API to register coex config
+ * updated handler.
+ * @psoc: pointer to psoc object
+ * @type: type of coex config
+ * @handler: handler to be registered
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coex_register_cfg_updated_handler(struct wlan_objmgr_psoc *psoc,
+				       enum coex_config_type type,
+				       update_coex_cb handler);
+
+/**
+ * ucfg_coex_psoc_set_btc_chain_mode() - API to set BT coex chain mode for psoc
+ * @psoc: pointer to psoc object
+ * @val: BT coex chain mode
+ *
+ * Return : status of operation
+ */
+QDF_STATUS
+ucfg_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode val);
+
+/**
+ * ucfg_coex_psoc_get_btc_chain_mode() - API to get BT coex chain mode from psoc
+ * @psoc: pointer to psoc object
+ * @val: pointer to BT coex chain mode
+ *
+ * Return : status of operation
+ */
+QDF_STATUS
+ucfg_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode *val);
+
+/**
+ * ucfg_coex_send_btc_chain_mode() - API to send BT coex config to target if
+ * @vdev: pointer to vdev object
+ * @mode: BT coex chain mode
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coex_send_btc_chain_mode(struct wlan_objmgr_vdev *vdev,
+			      enum coex_btc_chain_mode mode);
+
+/**
+ * ucfg_coex_send_multi_config() - API to send coex multiple config to target
+ * @vdev: pointer to vdev object
+ * @param: pointer to coex multiple config parameters
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coex_send_multi_config(struct wlan_objmgr_vdev *vdev,
+			    struct coex_multi_config *param);
+
+/**
+ * ucfg_coex_send_logging_config() - API to send BT coex logging config to
+ * target if
+ * @psoc: pointer to psoc object
+ * @apps_args: pointer to argument
+ *
+ * Return : status of operation
+ */
+QDF_STATUS
+ucfg_coex_send_logging_config(struct wlan_objmgr_psoc *psoc,
+			      uint32_t *apps_args);
+#else
+static inline QDF_STATUS
+ucfg_coex_register_cfg_updated_handler(struct wlan_objmgr_psoc *psoc,
+				       enum coex_config_type type,
+				       update_coex_cb handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode *val)
+{
+	if (val)
+		*val = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_coex_send_btc_chain_mode(struct wlan_objmgr_vdev *vdev,
+			      enum coex_btc_chain_mode mode)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_coex_send_multi_config(struct wlan_objmgr_vdev *vdev,
+			    struct coex_multi_config *param)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_coex_send_logging_config(struct wlan_objmgr_psoc *psoc,
+			      uint32_t *apps_args)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+/**
+ * ucfg_coex_send_dbam_config() - API to send dbam config to target if
+ * @vdev: pointer to vdev object
+ * @param: DBAM config mode params
+ * @clbk: dbam config response callback
+ * @context: request manager context
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS
+ucfg_coex_send_dbam_config(struct wlan_objmgr_vdev *vdev,
+			   struct coex_dbam_config_params *param,
+			   void (*clbk)(void *ctx,
+			   enum coex_dbam_comp_status *rsp),
+			   void *context);
+#else
+static inline QDF_STATUS
+ucfg_coex_send_dbam_config(void)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+#endif

+ 88 - 0
qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/inc/wlan_coex_utils_api.h

@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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_coex_utils_api.h
+ *
+ * This header file provides declaration of public APIs exposed to other UMAC
+ * components.
+ */
+
+#ifndef _WLAN_COEX_UTILS_API_H_
+#define _WLAN_COEX_UTILS_API_H_
+#include <wlan_objmgr_psoc_obj.h>
+
+/*
+ * wlan_coex_init() - Coex module initialization API
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_coex_init(void);
+
+/*
+ * wlan_coex_deinit() - Coex module deinitialization API
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_coex_deinit(void);
+
+/**
+ * wlan_coex_psoc_open() - Open coex component
+ * @psoc: soc context
+ *
+ * This function gets called when dispatcher opening.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+wlan_coex_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_coex_psoc_close() - Close coex component
+ * @psoc: soc context
+ *
+ * This function gets called when dispatcher closing.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+wlan_coex_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+/**
+ * wlan_dbam_psoc_enable() - API to enable coex dbam psoc component
+ * @psoc: pointer to psoc
+ *
+ * This API is invoked from dispatcher psoc enable.
+ * This API will register dbam WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_dbam_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_dbam_psoc_disable() - API to disable coex dbam psoc component
+ * @psoc: pointer to psoc
+ *
+ * This API is invoked from dispatcher psoc disable.
+ * This API will unregister dbam WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_dbam_psoc_disable(struct wlan_objmgr_psoc *psoc);
+#endif /* WLAN_FEATURE_DBAM_CONFIG */
+#endif

+ 151 - 0
qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/src/wlan_coex_tgt_api.c

@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains coex south bound interface definitions
+ */
+
+#include <wlan_coex_main.h>
+#include <wlan_coex_tgt_api.h>
+#include <wlan_lmac_if_def.h>
+#include "wlan_objmgr_pdev_obj.h"
+
+static inline struct wlan_lmac_if_coex_tx_ops *
+wlan_psoc_get_coex_txops(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_tx_ops *tx_ops;
+
+	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
+	if (!tx_ops) {
+		coex_err("tx_ops is NULL");
+		return NULL;
+	}
+
+	return &tx_ops->coex_ops;
+}
+
+static inline struct wlan_lmac_if_coex_tx_ops *
+wlan_vdev_get_coex_txops(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		coex_err("NULL psoc");
+		return NULL;
+	}
+
+	return wlan_psoc_get_coex_txops(psoc);
+}
+
+QDF_STATUS
+tgt_send_coex_config(struct wlan_objmgr_vdev *vdev,
+		     struct coex_config_params *param)
+{
+	struct wlan_lmac_if_coex_tx_ops *coex_ops;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+
+	if (!vdev) {
+		coex_err("NULL vdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		coex_err("NULL psoc");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		coex_err("NULL pdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coex_ops = wlan_psoc_get_coex_txops(psoc);
+	if (coex_ops && coex_ops->coex_config_send)
+		return coex_ops->coex_config_send(pdev, param);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coex_multi_config(struct wlan_objmgr_vdev *vdev,
+			   struct coex_multi_config *param)
+{
+	struct wlan_lmac_if_coex_tx_ops *coex_ops;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+
+	if (!vdev) {
+		coex_err("NULL vdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		coex_err("NULL psoc");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		coex_err("NULL pdev");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	coex_ops = wlan_psoc_get_coex_txops(psoc);
+	if (coex_ops && coex_ops->coex_multi_config_send)
+		return coex_ops->coex_multi_config_send(pdev, param);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool
+tgt_get_coex_multi_config_support(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_coex_tx_ops *coex_ops;
+
+	coex_ops = wlan_psoc_get_coex_txops(psoc);
+	if (coex_ops && coex_ops->coex_get_multi_config_support)
+		return coex_ops->coex_get_multi_config_support(psoc);
+
+	return false;
+}
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+QDF_STATUS
+tgt_send_dbam_config(struct wlan_objmgr_vdev *vdev,
+		     struct coex_dbam_config_params *param)
+{
+	struct wlan_lmac_if_dbam_tx_ops *dbam_tx_ops;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		coex_err("NULL psoc");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	dbam_tx_ops = wlan_psoc_get_dbam_tx_ops(psoc);
+	if (dbam_tx_ops && dbam_tx_ops->set_dbam_config)
+		return dbam_tx_ops->set_dbam_config(psoc, param);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif

+ 167 - 0
qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/src/wlan_coex_ucfg_api.c

@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: contains coex north bound interface definitions
+ */
+
+#include <wlan_coex_main.h>
+#include <wlan_coex_ucfg_api.h>
+#include "wmi_unified.h"
+#include "wlan_coex_public_structs.h"
+#include "wlan_coex_tgt_api.h"
+
+QDF_STATUS
+ucfg_coex_register_cfg_updated_handler(struct wlan_objmgr_psoc *psoc,
+				       enum coex_config_type type,
+				       update_coex_cb handler)
+{
+	struct coex_psoc_obj *coex_obj;
+
+	if (type >= COEX_CONFIG_TYPE_MAX) {
+		coex_err("invalid coex type: %d", type);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	coex_obj = wlan_psoc_get_coex_obj(psoc);
+	if (!coex_obj)
+		return QDF_STATUS_E_INVAL;
+
+	coex_obj->coex_config_updated[type] = handler;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode val)
+{
+	return wlan_coex_psoc_set_btc_chain_mode(psoc, val);
+}
+
+QDF_STATUS
+ucfg_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc,
+				  enum coex_btc_chain_mode *val)
+{
+	return wlan_coex_psoc_get_btc_chain_mode(psoc, val);
+}
+
+QDF_STATUS
+ucfg_coex_send_btc_chain_mode(struct wlan_objmgr_vdev *vdev,
+			      enum coex_btc_chain_mode mode)
+{
+	struct coex_config_params param = {0};
+
+	if (mode > WLAN_COEX_BTC_CHAIN_MODE_HYBRID)
+		return QDF_STATUS_E_INVAL;
+
+	param.vdev_id = wlan_vdev_get_id(vdev);
+	param.config_type = WMI_COEX_CONFIG_BTCOEX_SEPARATE_CHAIN_MODE;
+	param.config_arg1 = mode;
+
+	coex_debug("send btc chain mode %d for vdev %d", mode, param.vdev_id);
+
+	return wlan_coex_config_send(vdev, &param);
+}
+
+QDF_STATUS
+ucfg_coex_send_multi_config(struct wlan_objmgr_vdev *vdev,
+			    struct coex_multi_config *param)
+{
+	return wlan_coex_multi_config_send(vdev, param);
+}
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+QDF_STATUS
+ucfg_coex_send_dbam_config(struct wlan_objmgr_vdev *vdev,
+			   struct coex_dbam_config_params *param,
+			   void (*clbk)(void *ctx,
+			   enum coex_dbam_comp_status *rsp),
+			   void *context)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct coex_psoc_obj *coex_obj;
+	struct wlan_coex_callback *cbk;
+
+	if (!vdev) {
+		coex_err("Null vdev");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		coex_err("psoc is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	coex_obj = wlan_psoc_get_coex_obj(psoc);
+	if (!coex_obj) {
+		coex_err("failed to get coex_obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cbk = &coex_obj->cb;
+	cbk->set_dbam_config_cb = clbk;
+	cbk->set_dbam_config_ctx = context;
+
+	coex_debug("send dbam config mode %d for vdev_id %d",
+		   param->dbam_mode, param->vdev_id);
+
+	return wlan_dbam_config_send(vdev, param);
+}
+#endif
+
+#define COEX_CONFIG_ENABLE_CONT_INFO 12
+
+QDF_STATUS
+ucfg_coex_send_logging_config(struct wlan_objmgr_psoc *psoc,
+			      uint32_t *apps_args)
+{
+	struct coex_config_params param = {0};
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+
+	if (apps_args[0] != COEX_CONFIG_ENABLE_CONT_INFO) {
+		coex_err("invalid cmd %d", apps_args[0]);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_STA_MODE,
+							WLAN_COEX_ID);
+
+	if (!vdev) {
+		coex_err("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param.vdev_id = wlan_vdev_get_id(vdev);
+	param.config_type = WMI_COEX_CONFIG_ENABLE_CONT_INFO;
+	param.config_arg1 = apps_args[1];
+	param.config_arg2 = apps_args[2];
+	param.config_arg3 = apps_args[3];
+	param.config_arg4 = apps_args[4];
+	param.config_arg5 = apps_args[5];
+	param.config_arg6 = apps_args[6];
+
+	coex_debug("send logging_config arg: %u for vdev %d", *apps_args,
+		   param.vdev_id);
+
+	status = wlan_coex_config_send(vdev, &param);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_COEX_ID);
+
+	return status;
+}

+ 147 - 0
qcom/opensource/wlan/qcacld-3.0/components/coex/dispatcher/src/wlan_coex_utils_api.c

@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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_coex_utils_api.c
+ *
+ * This file provides definitions of public APIs exposed to other UMAC
+ * components.
+ */
+
+#include <wlan_coex_main.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_coex_utils_api.h>
+#include "cfg_ucfg_api.h"
+
+QDF_STATUS wlan_coex_init(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_COEX,
+			wlan_coex_psoc_created_notification, NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		coex_err("Failed to register psoc create handler");
+		goto fail_create_psoc;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_COEX,
+			wlan_coex_psoc_destroyed_notification, NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		coex_err("Failed to create psoc delete handler");
+		goto fail_psoc_destroy;
+	}
+
+	coex_debug("coex psoc create and delete handler registered");
+	return status;
+
+fail_psoc_destroy:
+	wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_COEX,
+			wlan_coex_psoc_created_notification, NULL);
+fail_create_psoc:
+	return status;
+}
+
+QDF_STATUS wlan_coex_deinit(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_COEX,
+			wlan_coex_psoc_destroyed_notification, NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		coex_err("Failed to unregister psoc delete handler");
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_COEX,
+			wlan_coex_psoc_created_notification, NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		coex_err("Failed to unregister psoc create handler");
+
+	return status;
+}
+
+#ifdef FEATURE_BTC_CHAIN_MODE
+/**
+ * wlan_coex_set_btc_chain_mode_with_ini() - set BTC init chain mode
+ * with ini
+ * @psoc: pointer to psoc object
+ *
+ * This function is used to set BTC init chain mode with ini
+ *
+ * Return: None
+ */
+static void
+wlan_coex_set_btc_chain_mode_with_ini(struct wlan_objmgr_psoc *psoc)
+{
+	enum coex_btc_chain_mode btc_chain_mode;
+	QDF_STATUS status;
+
+	status = wlan_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		coex_err("error for getting btc chain mode");
+		return;
+	}
+
+	if (btc_chain_mode == WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED) {
+		btc_chain_mode = cfg_get(psoc, CFG_SET_INIT_CHAIN_MODE_FOR_BTC);
+		if (btc_chain_mode > WLAN_COEX_BTC_CHAIN_MODE_HYBRID &&
+		    btc_chain_mode != WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED) {
+			coex_err("invalid ini config %d for btc chain mode",
+				 btc_chain_mode);
+			return;
+		}
+
+		status = wlan_coex_psoc_set_btc_chain_mode(psoc,
+							   btc_chain_mode);
+		if (QDF_IS_STATUS_ERROR(status))
+			coex_err("error for setting btc init chain mode from ini");
+	}
+}
+#else
+static void
+wlan_coex_set_btc_chain_mode_with_ini(struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+QDF_STATUS
+wlan_coex_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	wlan_coex_set_btc_chain_mode_with_ini(psoc);
+	return wlan_coex_psoc_init(psoc);
+}
+
+QDF_STATUS
+wlan_coex_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_coex_psoc_deinit(psoc);
+}
+
+#ifdef WLAN_FEATURE_DBAM_CONFIG
+QDF_STATUS wlan_dbam_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_dbam_attach(psoc);
+}
+
+QDF_STATUS wlan_dbam_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_dbam_detach(psoc);
+}
+#endif

+ 63 - 0
qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_ext_type.h

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019 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_ext_cp_stats_types.h
+ *
+ * This header file is included by the converged control path statistics
+ * component to map legacy statistic structures to the external
+ * (ext)typedefs used by the converged code. This mechanism allows the
+ * legacy structs to be included as part of the global objmgr objects.
+ */
+
+#ifndef __WLAN_EXT_CP_STATS_TYPE_H__
+#define __WLAN_EXT_CP_STATS_TYPE_H__
+
+/**
+ * typedef psoc_ext_cp_stats_t  - Definition of psoc cp stats pointer
+ * Define obj_stats from external umac/cp_stats component point to this type
+ */
+typedef struct psoc_mc_cp_stats psoc_ext_cp_stats_t;
+
+/**
+ * typedef pdev_ext_cp_stats_t  - Definition of pdev cp stats pointer
+ * Define pdev_stats from external umac/cp_stats component point to this type
+ */
+typedef struct pdev_mc_cp_stats pdev_ext_cp_stats_t;
+
+/**
+ * typedef vdev_ext_cp_stats_t  - Definition of vdev cp stats pointer
+ * Define vdev_stats from external umac/cp_stats component point to this type
+ */
+typedef struct vdev_mc_cp_stats vdev_ext_cp_stats_t;
+
+/**
+ * typedef peer_ext_cp_stats_t  - Definition of peer cp stats pointer
+ * Define peer_stats from external umac/cp_stats component point to this type
+ */
+typedef struct peer_mc_cp_stats peer_ext_cp_stats_t;
+
+/**
+ * typedef peer_ext_adv_cp_stats_t  - Definition of peer adv cp stats pointer
+ * Define peer_adv_stats from external umac/cp_stats component point to this
+ * type
+ */
+typedef struct peer_adv_mc_cp_stats peer_ext_adv_cp_stats_t;
+
+#endif /* __WLAN_EXT_CP_STATS_TYPE_H__ */
+

+ 875 - 0
qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h

@@ -0,0 +1,875 @@
+/*
+ * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_cp_stats_mc_defs.h
+ *
+ * This file provide definition for structure/enums/defines related to control
+ * path stats component
+ */
+
+#ifndef __WLAN_CP_STATS_MC_DEFS_H__
+#define __WLAN_CP_STATS_MC_DEFS_H__
+
+#include "wlan_cmn.h"
+#include "qdf_event.h"
+/* For WMI_MAX_CHAINS */
+#include "wmi_unified.h"
+#include "wlan_mlo_mgr_cmn.h"
+
+#ifdef QCA_SUPPORT_MC_CP_STATS
+#include "wlan_cp_stats_public_structs.h"
+#endif
+
+#ifdef WLAN_SUPPORT_TWT
+
+#include <wmi_unified_twt_param.h>
+/* Max TWT sessions per peer (supported by fw) */
+#define TWT_PEER_MAX_SESSIONS 1
+
+#endif /* WLAN_SUPPORT_TWT */
+
+#define MAX_NUM_CHAINS              2
+
+#define MAX_MIB_STATS               1
+
+#define IS_MSB_SET(__num) ((__num) & BIT(31))
+#define IS_LSB_SET(__num) ((__num) & BIT(0))
+
+#define VDEV_ALL                    0xFF
+
+/**
+ * enum stats_req_type - enum indicating bit position of various stats type in
+ * request map
+ * @TYPE_CONNECTION_TX_POWER: tx power was requested
+ * @TYPE_STATION_STATS: station stats was requested
+ * @TYPE_PEER_STATS: peer stats was requested
+ * @TYPE_MIB_STATS: MIB stats was requested
+ * @TYPE_PEER_STATS_INFO_EXT: peer stats info ext was requested
+ * @TYPE_CONGESTION_STATS: congestion stats was requested
+ * @TYPE_BIG_DATA_STATS: big data stats was requested
+ * @TYPE_MAX: maximum value
+ */
+enum stats_req_type {
+	TYPE_CONNECTION_TX_POWER = 0,
+	TYPE_STATION_STATS,
+	TYPE_PEER_STATS,
+	TYPE_MIB_STATS,
+	TYPE_PEER_STATS_INFO_EXT,
+	TYPE_CONGESTION_STATS,
+	TYPE_BIG_DATA_STATS,
+	TYPE_MAX,
+};
+
+/**
+ * enum tx_rate_info - tx rate flags
+ * @TX_RATE_LEGACY: Legacy rates
+ * @TX_RATE_HT20: HT20 rates
+ * @TX_RATE_HT40: HT40 rates
+ * @TX_RATE_SGI: Rate with Short guard interval
+ * @TX_RATE_LGI: Rate with Long guard interval
+ * @TX_RATE_VHT20: VHT 20 rates
+ * @TX_RATE_VHT40: VHT 40 rates
+ * @TX_RATE_VHT80: VHT 80 rates
+ * @TX_RATE_HE20: HE 20 rates
+ * @TX_RATE_HE40: HE 40 rates
+ * @TX_RATE_HE80: HE 80 rates
+ * @TX_RATE_HE160: HE 160 rates
+ * @TX_RATE_VHT160: VHT 160 rates
+ * @TX_RATE_EHT20: EHT 20 rates
+ * @TX_RATE_EHT40: EHT 40 rates
+ * @TX_RATE_EHT80: EHT 80 rates
+ * @TX_RATE_EHT160: EHT 160 rates
+ * @TX_RATE_EHT320: EHT 320 rates
+ */
+enum tx_rate_info {
+	TX_RATE_LEGACY = 0x1,
+	TX_RATE_HT20 = 0x2,
+	TX_RATE_HT40 = 0x4,
+	TX_RATE_SGI = 0x8,
+	TX_RATE_LGI = 0x10,
+	TX_RATE_VHT20 = 0x20,
+	TX_RATE_VHT40 = 0x40,
+	TX_RATE_VHT80 = 0x80,
+	TX_RATE_HE20 = 0x100,
+	TX_RATE_HE40 = 0x200,
+	TX_RATE_HE80 = 0x400,
+	TX_RATE_HE160 = 0x800,
+	TX_RATE_VHT160 = 0x1000,
+	TX_RATE_EHT20 = 0x2000,
+	TX_RATE_EHT40 = 0x4000,
+	TX_RATE_EHT80 = 0x8000,
+	TX_RATE_EHT160 = 0x10000,
+	TX_RATE_EHT320 = 0x20000,
+};
+
+/**
+ * enum txrate_gi - Guard Intervals
+ * @TXRATE_GI_0_8_US: guard interval 0.8 us
+ * @TXRATE_GI_0_4_US: guard interval 0.4 us for legacy
+ * @TXRATE_GI_1_6_US: guard interval 1.6 us
+ * @TXRATE_GI_3_2_US: guard interval 3.2 us
+ */
+enum txrate_gi {
+	TXRATE_GI_0_8_US = 0,
+	TXRATE_GI_0_4_US,
+	TXRATE_GI_1_6_US,
+	TXRATE_GI_3_2_US,
+};
+
+/**
+ * struct wake_lock_stats - wake lock stats structure
+ * @ucast_wake_up_count:        Unicast wakeup count
+ * @bcast_wake_up_count:        Broadcast wakeup count
+ * @ipv4_mcast_wake_up_count:   ipv4 multicast wakeup count
+ * @ipv6_mcast_wake_up_count:   ipv6 multicast wakeup count
+ * @ipv6_mcast_ra_stats:        ipv6 multicast ra stats
+ * @ipv6_mcast_ns_stats:        ipv6 multicast ns stats
+ * @ipv6_mcast_na_stats:        ipv6 multicast na stats
+ * @icmpv4_count:               ipv4 icmp packet count
+ * @icmpv6_count:               ipv6 icmp packet count
+ * @rssi_breach_wake_up_count:  rssi breach wakeup count
+ * @low_rssi_wake_up_count:     low rssi wakeup count
+ * @gscan_wake_up_count:        gscan wakeup count
+ * @pno_complete_wake_up_count: pno complete wakeup count
+ * @pno_match_wake_up_count:    pno match wakeup count
+ * @oem_response_wake_up_count: oem response wakeup count
+ * @uc_drop_wake_up_count:      local data uc drop wakeup count
+ * @fatal_event_wake_up_count:  fatal event wakeup count
+ * @pwr_save_fail_detected:     pwr save fail detected wakeup count
+ * @scan_11d:                   11d scan wakeup count
+ * @mgmt_assoc: association request management frame
+ * @mgmt_disassoc: disassociation management frame
+ * @mgmt_assoc_resp: association response management frame
+ * @mgmt_reassoc: reassociate request management frame
+ * @mgmt_reassoc_resp: reassociate response management frame
+ * @mgmt_auth: authentication management frame
+ * @mgmt_deauth: deauthentication management frame
+ * @mgmt_action: action management frame
+ */
+struct wake_lock_stats {
+	uint32_t ucast_wake_up_count;
+	uint32_t bcast_wake_up_count;
+	uint32_t ipv4_mcast_wake_up_count;
+	uint32_t ipv6_mcast_wake_up_count;
+	uint32_t ipv6_mcast_ra_stats;
+	uint32_t ipv6_mcast_ns_stats;
+	uint32_t ipv6_mcast_na_stats;
+	uint32_t icmpv4_count;
+	uint32_t icmpv6_count;
+	uint32_t rssi_breach_wake_up_count;
+	uint32_t low_rssi_wake_up_count;
+	uint32_t gscan_wake_up_count;
+	uint32_t pno_complete_wake_up_count;
+	uint32_t pno_match_wake_up_count;
+	uint32_t oem_response_wake_up_count;
+	uint32_t uc_drop_wake_up_count;
+	uint32_t fatal_event_wake_up_count;
+	uint32_t pwr_save_fail_detected;
+	uint32_t scan_11d;
+	uint32_t mgmt_assoc;
+	uint32_t mgmt_disassoc;
+	uint32_t mgmt_assoc_resp;
+	uint32_t mgmt_reassoc;
+	uint32_t mgmt_reassoc_resp;
+	uint32_t mgmt_auth;
+	uint32_t mgmt_deauth;
+	uint32_t mgmt_action;
+};
+
+struct stats_event;
+
+/**
+ * struct big_data_stats_event - big data stats event param
+ * @vdev_id:               vdev id
+ * @tsf_out_of_sync:       tsf out of sync
+ * @ani_level:             ani level
+ * @last_data_tx_pwr:  tx pwr last data frm
+ * @target_power_dsss:  tx power dsss
+ * @target_power_ofdm:  target power ofdm
+ * @last_tx_data_rix:     rx lateset data frame
+ * @last_tx_data_rate_kbps: tx latest data frame
+ */
+struct big_data_stats_event {
+	uint32_t vdev_id;
+	uint32_t tsf_out_of_sync;
+	int32_t ani_level;
+	uint32_t last_data_tx_pwr;
+	uint32_t target_power_dsss;
+	uint32_t target_power_ofdm;
+	uint32_t last_tx_data_rix;
+	uint32_t last_tx_data_rate_kbps;
+};
+
+/**
+ * struct medium_assess_data - medium assess data from firmware
+ * @part1_valid: the flag for part1 data, include cycle_count,
+ *    rx_clear_count and tx_frame_count
+ * @cycle_count: accumulative cycle count (total time)
+ * @rx_clear_count: accumulative rx clear count (busy time)
+ * @tx_frame_count: accumulative tx frame count (total time)
+ * @part2_valid: the flag for part2 data, include my_rx_count
+ * @my_rx_count: my RX count
+ */
+struct medium_assess_data {
+	bool part1_valid;
+	uint32_t cycle_count;
+	uint32_t rx_clear_count;
+	uint32_t tx_frame_count;
+	bool part2_valid;
+	uint32_t my_rx_count;
+};
+
+/**
+ * struct request_info: details of each request
+ * @cookie: identifier for os_if request
+ * @u: unified data type for callback to process tx power/peer rssi/
+ *     station stats/mib stats/peer stats request when response comes and
+ *     congestion notification callback.
+ * @vdev_id: vdev_id of request
+ * @pdev_id: pdev_id of request
+ * @peer_mac_addr: peer mac address
+ * @ml_vdev_info: mlo_stats_vdev_params structure
+ * @ml_peer_mac_addr: Array of ml peer mac addresses
+ */
+struct request_info {
+	void *cookie;
+	union {
+		void (*get_tx_power_cb)(int tx_power, void *cookie);
+		void (*get_peer_rssi_cb)(struct stats_event *ev, void *cookie);
+		void (*get_station_stats_cb)(struct stats_event *ev,
+					     void *cookie);
+		void (*get_mib_stats_cb)(struct stats_event *ev,
+					 void *cookie);
+		void (*get_peer_stats_cb)(struct stats_event *ev,
+					  void *cookie);
+		void (*congestion_notif_cb)(uint8_t vdev_id,
+					  struct medium_assess_data *data,
+					  bool last);
+#ifdef WLAN_FEATURE_BIG_DATA_STATS
+		void (*get_big_data_stats_cb)(struct big_data_stats_event *ev,
+					      void *cookie);
+#endif
+	} u;
+	uint32_t vdev_id;
+	uint32_t pdev_id;
+	uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE];
+#ifdef WLAN_FEATURE_11BE_MLO
+	struct mlo_stats_vdev_params ml_vdev_info;
+	uint8_t ml_peer_mac_addr[WLAN_UMAC_MLO_MAX_VDEVS][QDF_MAC_ADDR_SIZE];
+#endif
+};
+
+/**
+ * struct pending_stats_requests: details of pending requests
+ * @type_map: map indicating type of outstanding requests
+ * @req: array of info for outstanding request of each type
+ */
+struct pending_stats_requests {
+	uint32_t type_map;
+	struct request_info req[TYPE_MAX];
+};
+
+/**
+ * struct cca_stats - cca stats
+ * @congestion: the congestion percentage = (busy_time/total_time)*100
+ *    for the interval from when the vdev was started to the current time
+ *    (or the time at which the vdev was stopped).
+ */
+struct cca_stats {
+	uint32_t congestion;
+};
+
+/**
+ * struct psoc_mc_cp_stats: psoc specific stats
+ * @is_cp_stats_suspended: is cp stats suspended or not
+ * @pending: details of pending requests
+ * @wow_unspecified_wake_up_count: number of non-wow related wake ups
+ * @wow_stats: wake_lock stats for vdev
+ * @big_data_fw_support_enable: big data feature supported by fw or not
+ */
+struct psoc_mc_cp_stats {
+	bool is_cp_stats_suspended;
+	struct pending_stats_requests pending;
+	uint32_t wow_unspecified_wake_up_count;
+	struct wake_lock_stats wow_stats;
+#ifdef WLAN_FEATURE_BIG_DATA_STATS
+	bool big_data_fw_support_enable;
+#endif
+};
+
+/**
+ * struct pdev_mc_cp_extd_stats - pdev extd stats
+ * @pdev_id: pdev id
+ * @my_rx_count: What portion of time, as measured by the MAC HW clock was
+ *               occupied, by receiving PPDUs addressed to one of the vdevs
+ *               within this pdev.
+ * @rx_matched_11ax_msdu_cnt: number of Rx 11ax MSDUs with matching BSS color
+ *                            counter updated at EOP (end of packet)
+ * @rx_other_11ax_msdu_cnt: number of Rx 11ax MSDUs with other BSS color counter
+ *                          updated at EOP (end of packet)
+ */
+struct pdev_mc_cp_extd_stats {
+	uint32_t pdev_id;
+	uint32_t my_rx_count;
+	uint32_t rx_matched_11ax_msdu_cnt;
+	uint32_t rx_other_11ax_msdu_cnt;
+};
+
+/* Max supported bandwidth is 320Mhz, so max 16 subbands for 20Mhz */
+#define MAX_WIDE_BAND_SCAN_CHAN 16
+
+/**
+ * struct wide_band_scan_chan_info - wide band scan channel info
+ * @vdev_id: vdev id
+ * @num_chan: number of channels (for each subbands fo 20Mhz)
+ * @is_wide_band_scan: wide band scan or not
+ * @cca_busy_subband_info: CCA busy for each possible 20Mhz subbands
+ * of the wideband scan channel
+ */
+struct wide_band_scan_chan_info {
+	uint32_t vdev_id;
+	uint8_t num_chan;
+	bool is_wide_band_scan;
+	uint32_t cca_busy_subband_info[MAX_WIDE_BAND_SCAN_CHAN];
+};
+
+/**
+ * struct channel_status
+ * @channel_freq: Channel freq
+ * @noise_floor: Noise Floor value
+ * @rx_clear_count: rx clear count
+ * @cycle_count: cycle count
+ * @chan_tx_pwr_range: channel tx power per range in 0.5dBm steps
+ * @chan_tx_pwr_throughput: channel tx power per throughput
+ * @rx_frame_count: rx frame count (cumulative)
+ * @bss_rx_cycle_count: BSS rx cycle count
+ * @rx_11b_mode_data_duration: b-mode data rx time (units are microseconds)
+ * @tx_frame_count: BSS tx cycle count
+ * @mac_clk_mhz: sample frequency
+ * @channel_id: channel index
+ * @cmd_flags: indicate which stat event is this status coming from
+ * @subband_info: wide band scan channel info
+ */
+struct channel_status {
+	uint32_t    channel_freq;
+	uint32_t    noise_floor;
+	uint32_t    rx_clear_count;
+	uint32_t    cycle_count;
+	uint32_t    chan_tx_pwr_range;
+	uint32_t    chan_tx_pwr_throughput;
+	uint32_t    rx_frame_count;
+	uint32_t    bss_rx_cycle_count;
+	uint32_t    rx_11b_mode_data_duration;
+	uint32_t    tx_frame_count;
+	uint32_t    mac_clk_mhz;
+	uint32_t    channel_id;
+	uint32_t    cmd_flags;
+	struct wide_band_scan_chan_info subband_info;
+};
+
+/**
+ * struct per_channel_stats
+ * @total_channel: total number of be scanned channel
+ * @channel_status_list: channel status info store in this array
+ */
+struct per_channel_stats {
+	uint8_t total_channel;
+	struct channel_status
+		 channel_status_list[NUM_CHANNELS];
+};
+
+/**
+ * struct pdev_mc_cp_stats: pdev specific stats
+ * @max_pwr: max tx power for pdev
+ * @pdev_id: pdev id
+ * @rx_clear_count: accumulative rx clear count (busy time) of pdev
+ * @cycle_count: accumulative cycle count (total time) of pdev
+ * @tx_frame_count: accumulative tx frame count (total time) of pdev
+ * @chan_stats: per channel info stats
+ */
+struct pdev_mc_cp_stats {
+	int32_t max_pwr;
+	uint32_t pdev_id;
+	uint32_t rx_clear_count;
+	uint32_t cycle_count;
+	uint32_t tx_frame_count;
+	struct per_channel_stats chan_stats;
+};
+
+/**
+ * struct summary_stats - summary stats
+ * @snr: snr of vdev
+ * @rssi: rssi of vdev
+ * @retry_cnt: retry count
+ * @multiple_retry_cnt: multiple_retry_cnt
+ * @tx_frm_cnt: num of tx frames
+ * @rx_frm_cnt: num of rx frames
+ * @frm_dup_cnt: duplicate frame count
+ * @fail_cnt: fail count
+ * @rts_fail_cnt: rts fail count
+ * @ack_fail_cnt: ack fail count
+ * @rts_succ_cnt: rts success count
+ * @rx_discard_cnt: rx frames discarded
+ * @rx_error_cnt: rx frames with error
+ */
+struct summary_stats {
+	uint32_t snr;
+	int8_t rssi;
+	uint32_t retry_cnt[4];
+	uint32_t multiple_retry_cnt[4];
+	uint32_t tx_frm_cnt[4];
+	uint32_t rx_frm_cnt;
+	uint32_t frm_dup_cnt;
+	uint32_t fail_cnt[4];
+	uint32_t rts_fail_cnt;
+	uint32_t ack_fail_cnt;
+	uint32_t rts_succ_cnt;
+	uint32_t rx_discard_cnt;
+	uint32_t rx_error_cnt;
+};
+
+/**
+ * struct pmf_bcn_protect_stats - pmf bcn protect stats param
+ * @pmf_bcn_stats_valid: bcn protect stats received from fw are valid or not
+ * @igtk_mic_fail_cnt: MIC failure count of management packets using IGTK
+ * @igtk_replay_cnt: Replay detection count of management packets using IGTK
+ * @bcn_mic_fail_cnt: MIC failure count of beacon packets using BIGTK
+ * @bcn_replay_cnt: Replay detection count of beacon packets using BIGTK
+ */
+struct pmf_bcn_protect_stats {
+	bool pmf_bcn_stats_valid;
+	uint32_t igtk_mic_fail_cnt;
+	uint32_t igtk_replay_cnt;
+	uint32_t bcn_mic_fail_cnt;
+	uint32_t bcn_replay_cnt;
+};
+
+/**
+ * struct vdev_summary_extd_stats - vdev summary extended stats
+ * @vdev_id: vdev_id of the event
+ * @is_mlo_vdev_active: is the mlo vdev currently active
+ * @vdev_tx_power: vdev tx power
+ */
+struct vdev_summary_extd_stats {
+	uint8_t vdev_id;
+	bool is_mlo_vdev_active;
+	uint32_t vdev_tx_power;
+};
+
+/**
+ * struct vdev_mc_cp_stats - vdev specific stats
+ * @cca: cca stats
+ * @tx_rate_flags: tx rate flags (enum tx_rate_info)
+ * @chain_rssi: chain rssi
+ * @vdev_summary_stats: vdev's summary stats
+ * @pmf_bcn_stats: pmf beacon protect stats
+ * @vdev_extd_stats: vdev summary extended stats
+ */
+struct vdev_mc_cp_stats {
+	struct cca_stats cca;
+	uint32_t tx_rate_flags;
+	int8_t chain_rssi[MAX_NUM_CHAINS];
+	struct summary_stats vdev_summary_stats;
+	struct pmf_bcn_protect_stats pmf_bcn_stats;
+	struct vdev_summary_extd_stats vdev_extd_stats;
+};
+
+/**
+ * struct peer_extd_stats - Peer extension statistics
+ * @peer_macaddr: peer MAC address
+ * @rx_duration: lower 32 bits of rx duration in microseconds
+ * @peer_tx_bytes: Total TX bytes (including dot11 header) sent to peer
+ * @peer_rx_bytes: Total RX bytes (including dot11 header) received from peer
+ * @last_tx_rate_code: last TX ratecode
+ * @last_tx_power: TX power used by peer - units are 0.5 dBm
+ * @rx_mc_bc_cnt: Total number of received multicast & broadcast data frames
+ * corresponding to this peer, 1 in the MSB of rx_mc_bc_cnt represents a
+ * valid data
+ */
+struct peer_extd_stats {
+	uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE];
+	uint32_t rx_duration;
+	uint32_t peer_tx_bytes;
+	uint32_t peer_rx_bytes;
+	uint32_t last_tx_rate_code;
+	int32_t last_tx_power;
+	uint32_t rx_mc_bc_cnt;
+};
+
+/**
+ * struct peer_mc_cp_stats - peer specific stats
+ * @tx_rate: tx rate
+ * @rx_rate: rx rate
+ * @peer_rssi: rssi
+ * @peer_macaddr: mac address
+ * @extd_stats: Pointer to peer extended stats
+ * @adv_stats: Pointer to peer adv (extd2) stats
+ * @twt_param: Pointer to peer twt session parameters
+ */
+struct peer_mc_cp_stats {
+	uint32_t tx_rate;
+	uint32_t rx_rate;
+	int8_t peer_rssi;
+	uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE];
+	struct peer_extd_stats *extd_stats;
+	struct peer_adv_mc_cp_stats *adv_stats;
+#ifdef WLAN_SUPPORT_TWT
+	struct wmi_host_twt_session_stats_info twt_param[TWT_PEER_MAX_SESSIONS];
+#endif
+};
+
+/**
+ * struct peer_adv_mc_cp_stats - peer specific adv stats
+ * @peer_macaddr: mac address
+ * @fcs_count: fcs count
+ * @rx_bytes: rx bytes
+ * @rx_count: rx count
+ */
+struct peer_adv_mc_cp_stats {
+	uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE];
+	uint32_t fcs_count;
+	uint32_t rx_count;
+	uint64_t rx_bytes;
+};
+
+#ifdef WLAN_FEATURE_MIB_STATS
+/**
+ * struct dot11_counters - mib group containing attributes that are MAC counters
+ * @tx_frags: successfully transmitted fragments
+ * @group_tx_frames: transmitted group addressed frames
+ * @failed_cnt: MSDUs not transmitted successfully
+ * @rx_frags: fragments successfully received
+ * @group_rx_frames: group addressed frames received
+ * @fcs_error_cnt: FCS errors detected
+ * @tx_frames: frames successfully transmitted
+ */
+struct dot11_counters {
+	uint32_t tx_frags;
+	uint32_t group_tx_frames;
+	uint32_t failed_cnt;
+	uint32_t rx_frags;
+	uint32_t group_rx_frames;
+	uint32_t fcs_error_cnt;
+	uint32_t tx_frames;
+};
+
+/**
+ * struct dot11_mac_statistics - mib stats information on the operation of MAC
+ * @retry_cnt: retries done by mac for successful transmission
+ * @multi_retry_cnt: multiple retries done before successful transmission
+ * @frame_dup_cnt: duplicate no of frames
+ * @rts_success_cnt: number of CTS received (in response to RTS)
+ * @rts_fail_cnt: number of CTS not received (in response to RTS)
+ * @tx_ack_fail_cnt: number of ACK not received
+ */
+struct dot11_mac_statistics {
+	uint32_t retry_cnt;
+	uint32_t multi_retry_cnt;
+	uint32_t frame_dup_cnt;
+	uint32_t rts_success_cnt;
+	uint32_t rts_fail_cnt;
+	uint32_t tx_ack_fail_cnt;
+};
+
+/**
+ * struct dot11_qos_counters - qos mac counters
+ * @qos_tx_frag_cnt: transmitted QoS fragments
+ * @qos_failed_cnt: failed Qos fragments
+ * @qos_retry_cnt: Qos frames transmitted after retransmissions
+ * @qos_multi_retry_cnt: Qos frames transmitted after more than
+ *                       one retransmissions
+ * @qos_frame_dup_cnt: duplicate frames
+ * @qos_rts_success_cnt: number of CTS received (in response to RTS)
+ * @qos_rts_fail_cnt: number of CTS not received (in response to RTS)
+ * @tx_qos_ack_fail_cnt_up: number of ACK not received
+ *                          (in response to Qos frame)
+ * @qos_rx_frag_cnt: number of received MPDU of type Data
+ * @qos_tx_frame_cnt: number of transmitted MPDU of type Data
+ * @qos_discarded_frame_cnt: total Discarded MSDUs
+ * @qos_mpdu_rx_cnt: total received MPDU
+ * @qos_retries_rx_cnt: received MPDU with retry bit equal to 1
+ */
+struct dot11_qos_counters {
+	uint32_t qos_tx_frag_cnt;
+	uint32_t qos_failed_cnt;
+	uint32_t qos_retry_cnt;
+	uint32_t qos_multi_retry_cnt;
+	uint32_t qos_frame_dup_cnt;
+	uint32_t qos_rts_success_cnt;
+	uint32_t qos_rts_fail_cnt;
+	uint32_t tx_qos_ack_fail_cnt_up;
+	uint32_t qos_rx_frag_cnt;
+	uint32_t qos_tx_frame_cnt;
+	uint32_t qos_discarded_frame_cnt;
+	uint32_t qos_mpdu_rx_cnt;
+	uint32_t qos_retries_rx_cnt;
+};
+
+/**
+ * struct dot11_rsna_stats - mib rsn stats
+ * @rm_ccmp_replays: received robust management CCMP MPDUs discarded
+ *                   by the replay mechanism
+ * @tkip_icv_err: TKIP ICV errors encountered
+ * @tkip_replays: TKIP replay errors detected
+ * @ccmp_decrypt_err: MPDUs discarded by the CCMP decryption algorithm
+ * @ccmp_replays: received CCMP MPDUs discarded by the replay mechanism
+ * @cmac_icv_err: MPDUs discarded by the CMAC integrity check algorithm
+ * @cmac_replays: MPDUs discarded by the CMAC replay errors
+ */
+struct dot11_rsna_stats {
+	uint32_t rm_ccmp_replays;
+	uint32_t tkip_icv_err;
+	uint32_t tkip_replays;
+	uint32_t ccmp_decrypt_err;
+	uint32_t ccmp_replays;
+	uint32_t cmac_icv_err;
+	uint32_t cmac_replays;
+};
+
+/**
+ * struct dot11_counters_group3 - dot11 group3 stats
+ * @tx_ampdu_cnt: transmitted AMPDUs
+ * @tx_mpdus_in_ampdu_cnt: number of MPDUs in the A-MPDU in transmitted AMPDUs
+ * @tx_octets_in_ampdu_cnt: octets in the transmitted A-MPDUs
+ * @ampdu_rx_cnt: received A-MPDU
+ * @mpdu_in_rx_ampdu_cnt: MPDUs received in the A-MPDU
+ * @rx_octets_in_ampdu_cnt: octets in the received A-MPDU
+ * @rx_ampdu_deli_crc_err_cnt: number of MPDUs delimiter with CRC error
+ */
+struct dot11_counters_group3 {
+	uint32_t tx_ampdu_cnt;
+	uint32_t tx_mpdus_in_ampdu_cnt;
+	uint64_t tx_octets_in_ampdu_cnt;
+	uint32_t ampdu_rx_cnt;
+	uint32_t mpdu_in_rx_ampdu_cnt;
+	uint64_t rx_octets_in_ampdu_cnt;
+	uint32_t rx_ampdu_deli_crc_err_cnt;
+};
+
+/**
+ * struct mib_stats_metrics - mib stats counters
+ * @mib_counters: dot11Counters group
+ * @mib_mac_statistics: dot11MACStatistics group
+ * @mib_qos_counters: dot11QoSCounters group
+ * @mib_rsna_stats: dot11RSNAStats group
+ * @mib_counters_group3: dot11CountersGroup3 group
+ */
+struct mib_stats_metrics {
+	struct dot11_counters mib_counters;
+	struct dot11_mac_statistics mib_mac_statistics;
+	struct dot11_qos_counters mib_qos_counters;
+	struct dot11_rsna_stats mib_rsna_stats;
+	struct dot11_counters_group3 mib_counters_group3;
+};
+#endif
+
+/**
+ * struct congestion_stats_event: congestion stats event param
+ * @vdev_id: vdev_id of the event
+ * @congestion: the congestion percentage
+ */
+struct congestion_stats_event {
+	uint8_t vdev_id;
+	uint32_t congestion;
+};
+
+/**
+ * struct summary_stats_event - summary_stats event param
+ * @vdev_id: vdev_id of the event
+ * @stats: summary stats
+ */
+struct summary_stats_event {
+	uint8_t vdev_id;
+	struct summary_stats stats;
+};
+
+/**
+ * struct chain_rssi_event - chain_rssi event param
+ * @vdev_id: vdev_id of the event
+ * @chain_rssi: chain_rssi
+ */
+struct chain_rssi_event {
+	uint8_t vdev_id;
+	int8_t chain_rssi[MAX_NUM_CHAINS];
+};
+
+/**
+ * struct peer_stats_info_ext_event - peer extended stats info
+ * @peer_macaddr: MAC address
+ * @tx_packets: packets transmitted to this station
+ * @tx_bytes: bytes transmitted to this station
+ * @rx_packets: packets received from this station
+ * @rx_bytes: bytes received from this station
+ * @tx_retries: cumulative retry counts
+ * @tx_failed: the number of failed frames
+ * @tx_succeed: the number of succeed frames
+ * @rssi: the signal strength
+ * @tx_rate: last used tx bitrate (kbps)
+ * @tx_rate_code: last tx rate code (last_tx_rate_code of wmi_peer_stats_info)
+ * @rx_rate: last used rx bitrate (kbps)
+ * @rx_rate_code: last rx rate code (last_rx_rate_code of wmi_peer_stats_info)
+ * @peer_rssi_per_chain: the average value of RSSI (dbm) per chain
+ * @num_tx_rate_counts: Num tx rate count for current peer
+ * @num_rx_rate_counts: Num rx rate count for current peer
+ * @tx_pkt_per_mcs: Number of tx packets for each MCS
+ * @rx_pkt_per_mcs: Number of rx packets for each MCS
+ */
+struct peer_stats_info_ext_event {
+	struct qdf_mac_addr peer_macaddr;
+	uint32_t tx_packets;
+	uint64_t tx_bytes;
+	uint32_t rx_packets;
+	uint64_t rx_bytes;
+	uint32_t tx_retries;
+	uint32_t tx_failed;
+	uint32_t tx_succeed;
+	int32_t rssi;
+	uint32_t tx_rate;
+	uint32_t tx_rate_code;
+	uint32_t rx_rate;
+	uint32_t rx_rate_code;
+	int32_t peer_rssi_per_chain[WMI_MAX_CHAINS];
+	uint32_t num_tx_rate_counts;
+	uint32_t num_rx_rate_counts;
+	uint32_t *tx_pkt_per_mcs;
+	uint32_t *rx_pkt_per_mcs;
+};
+
+/**
+ * struct stats_event - parameters populated by stats event
+ * @num_pdev_stats: num pdev stats
+ * @pdev_stats: if populated array indicating pdev stats (index = pdev_id)
+ * @num_pdev_extd_stats: num pdev extended stats
+ * @pdev_extd_stats: if populated array indicating pdev extended stats
+ *                   (index = pdev_id)
+ * @num_peer_stats: num peer stats
+ * @peer_stats: if populated array indicating peer stats
+ * @peer_adv_stats: if populated, indicates peer adv (extd2) stats
+ * @num_peer_adv_stats: number of peer adv (extd2) stats
+ * @num_peer_extd_stats: Num peer extended stats
+ * @peer_extended_stats: Peer extended stats
+ * @cca_stats: if populated indicates congestion stats
+ * @num_summary_stats: number of summary stats
+ * @vdev_summary_stats: if populated indicates array of summary stats per vdev
+ * @num_mib_stats: number of mib stats
+ * @mib_stats: if populated indicates array of mib stats per vdev
+ * @num_chain_rssi_stats: number of chain rssi stats
+ * @vdev_chain_rssi: if populated indicates array of chain rssi per vdev
+ * @tx_rate: tx rate (kbps)
+ * @rx_rate: rx rate (kbps)
+ * @tx_rate_flags: tx rate flags, (enum tx_rate_info)
+ * @last_event: The LSB indicates if the event is the last event or not and the
+ *              MSB indicates if this feature is supported by FW or not.
+ * @mac_seq_num: sequence number of event when fw update to host
+ * @num_peer_stats_info_ext: number of peer extended stats info
+ * @peer_stats_info_ext: peer extended stats info
+ * @bcn_protect_stats: pmf bcn protect stats
+ * @num_vdev_extd_stats: number of vdev extended stats
+ * @vdev_extd_stats: if populated indicates array of ext summary stats per vdev
+ */
+struct stats_event {
+	uint32_t num_pdev_stats;
+	struct pdev_mc_cp_stats *pdev_stats;
+	uint32_t num_pdev_extd_stats;
+	struct pdev_mc_cp_extd_stats *pdev_extd_stats;
+	uint32_t num_peer_stats;
+	struct peer_mc_cp_stats *peer_stats;
+	uint32_t num_peer_adv_stats;
+	struct peer_adv_mc_cp_stats *peer_adv_stats;
+	uint32_t num_peer_extd_stats;
+	struct peer_extd_stats *peer_extended_stats;
+	struct congestion_stats_event *cca_stats;
+	uint32_t num_summary_stats;
+	struct summary_stats_event *vdev_summary_stats;
+#ifdef WLAN_FEATURE_MIB_STATS
+	uint32_t num_mib_stats;
+	struct mib_stats_metrics *mib_stats;
+#endif
+	uint32_t num_chain_rssi_stats;
+	struct chain_rssi_event *vdev_chain_rssi;
+	uint32_t tx_rate;
+	uint32_t rx_rate;
+	enum tx_rate_info tx_rate_flags;
+	uint32_t last_event;
+	uint8_t mac_seq_num;
+	uint32_t num_peer_stats_info_ext;
+	struct peer_stats_info_ext_event *peer_stats_info_ext;
+	struct pmf_bcn_protect_stats bcn_protect_stats;
+	uint32_t num_vdev_extd_stats;
+	struct vdev_summary_extd_stats *vdev_extd_stats;
+};
+
+/**
+ * struct peer_stats_request_params - peer stats request parameter
+ * @request_type: request type, one peer or all peers of the vdev
+ * @vdev_id: vdev id
+ * @peer_mac_addr: peer mac address, omitted if request type is all peers
+ * @reset_after_request: whether reset stats after request
+ */
+struct peer_stats_request_params {
+	uint32_t request_type;
+	uint32_t vdev_id;
+	uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE];
+	uint32_t reset_after_request;
+};
+
+/**
+ * struct wmi_host_peer_stats_info - WMI peer stats info
+ * @peer_macaddr: peer mac address
+ * @tx_bytes: tx_bytes
+ * @tx_packets: tx packets
+ * @rx_bytes: rx_bytes
+ * @rx_packets: rx packets
+ * @tx_retries: tx retries of MPDU
+ * @tx_failed: tx failed MPDU
+ * @last_tx_rate_code: rate code of the last tx
+ * @last_rx_rate_code: rate code of the last rx
+ * @last_tx_bitrate_kbps: bitrate in bps of the last tx
+ * @last_rx_bitrate_kbps: bitrate in bps of the last rx
+ * @peer_rssi: peer rssi
+ * @tx_succeed: tx succeed MPDU
+ * @peer_rssi_per_chain: peer rssi per chain
+ * @num_tx_rate_counts: Num tx rate count for current peer
+ * @num_rx_rate_counts: Num rx rate count for current peer
+ * @tx_pkt_per_mcs: Number of tx rate counts for each MCS
+ * @rx_pkt_per_mcs: Number of rx rate counts for each MCS
+ */
+typedef struct {
+	struct qdf_mac_addr peer_macaddr;
+	uint64_t tx_bytes;
+	uint32_t tx_packets;
+	uint64_t rx_bytes;
+	uint32_t rx_packets;
+	uint32_t tx_retries;
+	uint32_t tx_failed;
+	uint32_t last_tx_rate_code;
+	uint32_t last_rx_rate_code;
+	uint32_t last_tx_bitrate_kbps;
+	uint32_t last_rx_bitrate_kbps;
+	int32_t peer_rssi;
+	uint32_t tx_succeed;
+	int32_t peer_rssi_per_chain[WMI_MAX_CHAINS];
+	uint32_t num_tx_rate_counts;
+	uint32_t num_rx_rate_counts;
+	uint32_t *tx_pkt_per_mcs;
+	uint32_t *rx_pkt_per_mcs;
+} wmi_host_peer_stats_info;
+
+#endif /* __WLAN_CP_STATS_MC_DEFS_H__ */

+ 129 - 0
qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_tgt_api.h

@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2018, 2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_cp_stats_mc_tgt_api.h
+ *
+ * This header file provide with API declarations to interface with Southbound
+ */
+#ifndef __WLAN_CP_STATS_MC_TGT_API_H__
+#define __WLAN_CP_STATS_MC_TGT_API_H__
+
+#ifdef QCA_SUPPORT_CP_STATS
+#include "wlan_cp_stats_mc_defs.h"
+
+//TODO -  Check if this is true for hamilton
+#ifdef QCA_WIFI_QCA6490
+#define TGT_MAC_ID_24G 2
+#define TGT_MAC_ID_5G 1
+#else
+#define TGT_MAC_ID_24G 0
+#define TGT_MAC_ID_5G 0
+#endif
+
+/**
+ * target_if_mc_cp_get_mac_id(): API to get mac id
+ * @vdev_mlme: vdev mlme pointer
+ *
+ * Return: mac id
+ */
+uint8_t target_if_mc_cp_get_mac_id(struct vdev_mlme_obj *vdev_mlme);
+
+/**
+ * tgt_mc_cp_stats_process_stats_event(): API to process stats event
+ * @psoc: pointer to psoc object
+ * @ev: event parameters
+ *
+ * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
+ * failure
+ */
+QDF_STATUS
+tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc,
+				    struct stats_event *ev);
+
+#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
+/**
+ * tgt_mc_cp_stats_process_infra_stats_event(): API to process event from
+ * cp stats infrastructure
+ * @psoc: pointer to psoc object
+ * @infra_event: infra cp stats event parameters
+ *
+ * Return: status of operation
+ */
+QDF_STATUS tgt_mc_cp_stats_process_infra_stats_event(
+				struct wlan_objmgr_psoc *psoc,
+				struct infra_cp_stats_event *infra_event);
+
+#endif
+
+#ifdef WLAN_FEATURE_BIG_DATA_STATS
+/**
+ * tgt_mc_cp_stats_process_big_data_stats_event(): API to process big data
+ * stats event
+ * @psoc: pointer to psoc object
+ * @event: big data stats event parameters
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_mc_cp_stats_process_big_data_stats_event(
+				struct wlan_objmgr_psoc *psoc,
+				struct big_data_stats_event *event);
+#endif
+
+/**
+ * tgt_send_mc_cp_stats_req(): API to send stats request to lmac
+ * @psoc: pointer to psoc object
+ * @type: specific type of stats requested
+ * @req: pointer to stats request
+ *
+ * Return: status of operation
+ */
+QDF_STATUS tgt_send_mc_cp_stats_req(struct wlan_objmgr_psoc *psoc,
+				    enum stats_req_type type,
+				    struct request_info *req);
+
+/**
+ * tgt_set_pdev_stats_update_period(): API to set pdev stats update
+ * period to FW
+ * @psoc: pointer to psoc object
+ * @pdev_id: pdev id
+ * @val: pdev stats update period, 0: disabled periodical stats report.
+ *
+ * Return: status of operation
+ */
+QDF_STATUS tgt_set_pdev_stats_update_period(struct wlan_objmgr_psoc *psoc,
+					    uint8_t pdev_id, uint32_t val);
+
+/**
+ * tgt_mc_cp_stats_inc_wake_lock_stats() : API to increment wake lock stats
+ * given the wake reason code
+ * @psoc: pointer to psoc object
+ * @reason: wake reason
+ * @stats: vdev wow stats to update
+ * @unspecified_wake_count: unspecified wake count to update
+ *
+ * Return : status of operation
+ */
+QDF_STATUS tgt_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc,
+				uint32_t reason, struct wake_lock_stats *stats,
+				uint32_t *unspecified_wake_count);
+
+#endif /* QCA_SUPPORT_CP_STATS */
+#endif /* __WLAN_CP_STATS_MC_TGT_API_H__ */

+ 538 - 0
qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h

@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_cp_stats_mc_ucfg_api.h
+ *
+ * This header file maintain API declaration required for northbound interaction
+ */
+
+#ifndef __WLAN_CP_STATS_MC_UCFG_API_H__
+#define __WLAN_CP_STATS_MC_UCFG_API_H__
+
+#ifdef QCA_SUPPORT_CP_STATS
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_cp_stats_mc_defs.h>
+
+#ifdef WLAN_SUPPORT_TWT
+
+#include <wlan_objmgr_peer_obj.h>
+#include "../../core/src/wlan_cp_stats_defs.h"
+#include <qdf_event.h>
+
+/* Max TWT sessions supported */
+#define TWT_PSOC_MAX_SESSIONS TWT_PEER_MAX_SESSIONS
+
+/**
+ * ucfg_twt_get_peer_session_params() - Retrieves peer twt session parameters
+ * corresponding to a peer by using mac_addr and dialog id
+ * If dialog_id is TWT_GET_ALL_PEER_PARAMS_DIALOG_ID retrieves twt session
+ * parameters of all peers with valid twt session
+ * @psoc_obj: psoc object
+ * @param: array pointer to store peer twt session parameters, should contain
+ * mac_addr and dialog id of a peer for which twt session stats to be retrieved
+ *
+ * Return: total number of valid twt session
+ */
+int
+ucfg_twt_get_peer_session_params(struct wlan_objmgr_psoc *psoc_obj,
+				 struct wmi_host_twt_session_stats_info *param);
+#endif /* WLAN_SUPPORT_TWT */
+
+struct psoc_cp_stats;
+struct vdev_cp_stats;
+
+/**
+ * ucfg_mc_cp_stats_get_psoc_wake_lock_stats() : API to get wake lock stats from
+ * psoc
+ * @psoc: pointer to psoc object
+ * @stats: stats object to populate
+ *
+ * Return : status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_get_psoc_wake_lock_stats(
+						struct wlan_objmgr_psoc *psoc,
+						struct wake_lock_stats *stats);
+
+/**
+ * ucfg_mc_cp_stats_get_vdev_wake_lock_stats() : API to get wake lock stats from
+ * vdev
+ * @vdev: pointer to vdev object
+ * @stats: stats object to populate
+ *
+ * Return : status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_get_vdev_wake_lock_stats(
+						struct wlan_objmgr_vdev *vdev,
+						struct wake_lock_stats *stats);
+
+/**
+ * ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol() : API to increment wake
+ * lock stats given the protocol of the packet that was received.
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev_id for which the packet was received
+ * @protocol: protocol of the packet that was received
+ *
+ * Return : status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol(
+					struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id,
+					enum qdf_proto_subtype protocol);
+
+/**
+ * ucfg_mc_cp_stats_inc_wake_lock_stats_by_dst_addr() : API to increment wake
+ * lock stats given destination of packet that was received.
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev_id for which the packet was received
+ * @dest_mac: destination mac address of packet that was received
+ *
+ * Return : status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_dst_addr(
+					struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id, uint8_t *dest_mac);
+
+/**
+ * ucfg_mc_cp_stats_inc_wake_lock_stats() : API to increment wake lock stats
+ * given wake reason.
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev_id on with WOW was received
+ * @reason: reason of WOW
+ *
+ * Return : status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id,
+						uint32_t reason);
+
+/**
+ * ucfg_mc_cp_stats_write_wow_stats() - Writes WOW stats to buffer
+ * @psoc: pointer to psoc object
+ * @buffer: The char buffer to write to
+ * @max_len: The maximum number of chars to write
+ * @ret: number of bytes written
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_write_wow_stats(
+				struct wlan_objmgr_psoc *psoc,
+				char *buffer, uint16_t max_len, int *ret);
+
+/**
+ * ucfg_mc_cp_stats_send_stats_request() - API to send stats request to lmac
+ * @vdev: pointer to vdev object
+ * @type: request type
+ * @info: specific request information
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_send_stats_request(struct wlan_objmgr_vdev *vdev,
+					       enum stats_req_type type,
+					       struct request_info *info);
+
+/**
+ * wlan_cfg80211_mc_twt_clear_infra_cp_stats() - send request to reset
+ * control path statistics
+ * @vdev: pointer to vdev object
+ * @dialog_id: dialod id of the twt session
+ * @twt_peer_mac: mac address of the peer
+ *
+ * Return: 0 for success or error code for failure
+ */
+int
+wlan_cfg80211_mc_twt_clear_infra_cp_stats(
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t dialog_id,
+				uint8_t twt_peer_mac[QDF_MAC_ADDR_SIZE]);
+
+/**
+ * wlan_cfg80211_mc_twt_get_infra_cp_stats() - send twt get statistic request
+ * @vdev: pointer to vdev object
+ * @dialog_id: TWT session dialog id
+ * @twt_peer_mac: mac address of the peer
+ * @errno: error code
+ *
+ * Return: pointer to infra cp stats event for success or NULL for failure
+ */
+struct infra_cp_stats_event *
+wlan_cfg80211_mc_twt_get_infra_cp_stats(struct wlan_objmgr_vdev *vdev,
+					uint32_t dialog_id,
+					uint8_t twt_peer_mac[QDF_MAC_ADDR_SIZE],
+					int *errno);
+/**
+ * ucfg_mc_cp_stats_get_tx_power() - API to fetch tx_power
+ * @vdev: pointer to vdev object
+ * @dbm: pointer to tx power in dbm
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev,
+					 int *dbm);
+
+/**
+ * ucfg_mc_cp_stats_is_req_pending() - API to tell if given request is pending
+ * @psoc: pointer to psoc object
+ * @type: request type to check
+ *
+ * Return: true of request is pending, false otherwise
+ */
+bool ucfg_mc_cp_stats_is_req_pending(struct wlan_objmgr_psoc *psoc,
+				     enum stats_req_type type);
+
+/**
+ * ucfg_mc_cp_stats_set_pending_req() - API to set pending request
+ * @psoc: pointer to psoc object
+ * @type: request to update
+ * @req: value to update
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_set_pending_req(struct wlan_objmgr_psoc *psoc,
+					    enum stats_req_type type,
+					    struct request_info *req);
+/**
+ * ucfg_mc_cp_stats_reset_pending_req() - API to reset pending request
+ * @psoc: pointer to psoc object
+ * @type: request to update
+ * @last_req: last request
+ * @pending: pending request present
+ *
+ * The function is an atomic operation of "reset" and "get" last request.
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_reset_pending_req(struct wlan_objmgr_psoc *psoc,
+					      enum stats_req_type type,
+					      struct request_info *last_req,
+					      bool *pending);
+
+/**
+ * ucfg_mc_cp_stats_get_pending_req() - API to get pending request
+ * @psoc: pointer to psoc object
+ * @type: request to update
+ * @info: buffer to populate
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_get_pending_req(struct wlan_objmgr_psoc *psoc,
+					    enum stats_req_type type,
+					    struct request_info *info);
+
+/**
+ * ucfg_mc_infra_cp_stats_free_stats_resources() - API to free buffers within
+ * infra cp stats_event structure
+ * @ev: structure whose buffer are to freed
+ *
+ * Return: none
+ */
+void
+ucfg_mc_infra_cp_stats_free_stats_resources(struct infra_cp_stats_event *ev);
+
+/**
+ * ucfg_mc_cp_stats_free_stats_resources() - API to free buffers within stats_event
+ * structure
+ * @ev: structure whose buffer are to freed
+ *
+ * Return: none
+ */
+void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev);
+
+/**
+ * ucfg_mc_cp_stats_cca_stats_get() - API to fetch cca stats
+ * @vdev: pointer to vdev object
+ * @cca_stats: pointer to cca info
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_cca_stats_get(struct wlan_objmgr_vdev *vdev,
+					  struct cca_stats *cca_stats);
+
+/**
+ * ucfg_mc_cp_stats_set_rate_flags() - API to set rate flags
+ * @vdev: pointer to vdev object
+ * @flags: value to set
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_mc_cp_stats_set_rate_flags(struct wlan_objmgr_vdev *vdev,
+					   uint32_t flags);
+
+/**
+ * ucfg_mc_cp_stats_register_lost_link_info_cb() - API to register lost link
+ * info callback
+ * @psoc: pointer to psoc object
+ * @lost_link_cp_stats_info_cb: Lost link info callback to be registered
+ *
+ */
+void ucfg_mc_cp_stats_register_lost_link_info_cb(
+		struct wlan_objmgr_psoc *psoc,
+		void (*lost_link_cp_stats_info_cb)(void *stats_ev));
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+/**
+ * ucfg_mc_cp_stats_register_pmo_handler() - API to register pmo handler
+ *
+ * Return: none
+ */
+void ucfg_mc_cp_stats_register_pmo_handler(void);
+#else
+void static inline ucfg_mc_cp_stats_register_pmo_handler(void) { };
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#ifdef WLAN_FEATURE_BIG_DATA_STATS
+/**
+ * ucfg_send_big_data_stats_request() - API to send big data stats
+ * request
+ * @vdev: pointer to vdev object
+ * @type: request type
+ * @info: request info
+ *
+ * Return: status of operation
+ */
+QDF_STATUS ucfg_send_big_data_stats_request(struct wlan_objmgr_vdev *vdev,
+					    enum stats_req_type type,
+					    struct request_info *info);
+
+/**
+ * ucfg_mc_cp_set_big_data_fw_support() - set big data fw support
+ * @psoc: PSOC object
+ * @enable: Set true if firmware supports big data, otherwise false
+ *
+ * API to set fw supports big data feature or not
+ *
+ * Return: void
+ */
+void
+ucfg_mc_cp_set_big_data_fw_support(struct wlan_objmgr_psoc *psoc,
+				   bool enable);
+
+/**
+ * ucfg_mc_cp_get_big_data_fw_support() - get big data fw support
+ * @psoc: PSOC object
+ * @enable: Set true if firmware supports big data, otherwise false
+ *
+ * API to get fw supports big data feature or not
+ *
+ * Return: void
+ */
+void
+ucfg_mc_cp_get_big_data_fw_support(struct wlan_objmgr_psoc *psoc,
+				   bool *enable);
+#else
+static inline
+QDF_STATUS ucfg_send_big_data_stats_request(struct wlan_objmgr_vdev *vdev,
+					    enum stats_req_type type,
+					    struct request_info *info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+ucfg_mc_cp_set_big_data_fw_support(struct wlan_objmgr_psoc *psoc,
+				   bool enable)
+{}
+
+static inline void
+ucfg_mc_cp_get_big_data_fw_support(struct wlan_objmgr_psoc *psoc,
+				   bool *enable)
+{}
+#endif
+
+#ifdef CONFIG_WLAN_BMISS
+/**
+ * wlan_cfg80211_mc_bmiss_get_infra_cp_stats() - API to get bmiss stats
+ * @vdev: pointer to vdev object
+ * @bmiss_peer_mac: mac address of the peer
+ * @errno: error code
+ *
+ * Return: pointer to infra cp stats event for success or NULL for failure
+ */
+struct infra_cp_stats_event*
+wlan_cfg80211_mc_bmiss_get_infra_cp_stats(
+				struct wlan_objmgr_vdev *vdev,
+				uint8_t bmiss_peer_mac[QDF_MAC_ADDR_SIZE],
+				int *errno);
+#else /* CONFIG_WLAN_BMISS */
+static inline struct infra_cp_stats_event*
+wlan_cfg80211_mc_bmiss_get_infra_cp_stats(
+				struct wlan_objmgr_vdev *vdev,
+				uint8_t bmiss_peer_mac[QDF_MAC_ADDR_SIZE],
+				int *errno)
+{
+	return NULL;
+}
+#endif /* CONFIG_WLAN_BMISS */
+
+/**
+ * wlan_cp_stats_update_chan_info() - API to update chan stats
+ * @psoc: pointer to psoc
+ * @chan_stat: channel stats
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
+				    struct channel_status *chan_stat,
+				    uint8_t vdev_id);
+
+/**
+ * wlan_cp_stats_get_rx_clear_count() - API to get rx clear count for a channel
+ * @psoc: pointer to psoc
+ * @vdev_id: vdev id
+ * @req_freq: freq for which rx clear count require
+ *
+ * Return: channel load
+ */
+uint8_t wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id, qdf_freq_t req_freq);
+
+/**
+ * ucfg_mc_cp_stats_clear_channel_status() - API to clear chan stats
+ * @pdev: pointer to pdev object
+ *
+ * Return: None
+ */
+void ucfg_mc_cp_stats_clear_channel_status(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_mc_cp_stats_get_channel_status() - API to get chan stats
+ * @pdev: pointer to pdev object
+ * @chan_freq: channel freq of which stats are needed
+ *
+ * Return: channel status
+ */
+struct channel_status *
+ucfg_mc_cp_stats_get_channel_status(struct wlan_objmgr_pdev *pdev,
+				    uint32_t chan_freq);
+#else /* QCA_SUPPORT_CP_STATS */
+
+void static inline ucfg_mc_cp_stats_register_pmo_handler(void) { };
+static inline QDF_STATUS ucfg_mc_cp_stats_send_stats_request(
+				struct wlan_objmgr_vdev *vdev,
+				enum stats_req_type type,
+				struct request_info *info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS ucfg_mc_cp_stats_set_rate_flags(
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t flags)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS ucfg_mc_cp_stats_get_psoc_wake_lock_stats(
+						struct wlan_objmgr_psoc *psoc,
+						struct wake_lock_stats *stats)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol(
+					struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id,
+					enum qdf_proto_subtype protocol)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id,
+				uint32_t reason)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_dst_addr(
+					struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id, uint8_t *dest_mac)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS ucfg_mc_cp_stats_get_vdev_wake_lock_stats(
+						struct wlan_objmgr_vdev *vdev,
+						struct wake_lock_stats *stats)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_send_big_data_stats_request(struct wlan_objmgr_vdev *vdev,
+					    enum stats_req_type type,
+					    struct request_info *info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+ucfg_mc_cp_set_big_data_fw_support(struct wlan_objmgr_psoc *psoc,
+				   bool enable)
+{}
+
+static inline void
+ucfg_mc_cp_big_data_fw_support(struct wlan_objmgr_psoc *psoc,
+			       bool *enable)
+{}
+
+static inline struct infra_cp_stats_event*
+wlan_cfg80211_mc_bmiss_get_infra_cp_stats(
+				struct wlan_objmgr_vdev *vdev,
+				uint8_t bmiss_peer_mac[QDF_MAC_ADDR_SIZE],
+				int *errno)
+{
+	return NULL;
+}
+
+static inline void
+ucfg_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev,
+			      int *dbm)
+{}
+
+static inline
+void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
+				    struct channel_status *chan_stat,
+				    uint8_t vdev_id)
+{
+}
+
+static inline
+uint8_t wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id, qdf_freq_t req_freq)
+{
+}
+
+static inline
+void ucfg_mc_cp_stats_clear_channel_status(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline struct channel_status *
+ucfg_mc_cp_stats_get_channel_status(struct wlan_objmgr_pdev *pdev,
+				    uint32_t chan_freq)
+{
+	return NULL;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+#endif /* __WLAN_CP_STATS_MC_UCFG_API_H__ */

+ 1564 - 0
qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c

@@ -0,0 +1,1564 @@
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_cp_stats_mc_tgt_api.c
+ *
+ * This file provide API definitions to update control plane statistics received
+ * from southbound interface
+ */
+
+#include "wlan_cp_stats_mc_defs.h"
+#include "target_if_cp_stats.h"
+#include "wlan_cp_stats_tgt_api.h"
+#include "wlan_cp_stats_ucfg_api.h"
+#include "wlan_cp_stats_mc_tgt_api.h"
+#include <wlan_cp_stats_mc_ucfg_api.h>
+#include <wlan_cp_stats_utils_api.h>
+#include "../../core/src/wlan_cp_stats_defs.h"
+#include "../../core/src/wlan_cp_stats_obj_mgr_handler.h"
+#include "son_api.h"
+#include "wlan_policy_mgr_api.h"
+
+static bool tgt_mc_cp_stats_is_last_event(struct stats_event *ev,
+					  enum stats_req_type stats_type)
+{
+	bool is_last_event;
+
+	if (IS_MSB_SET(ev->last_event)) {
+		is_last_event = IS_LSB_SET(ev->last_event);
+	} else {
+		if (stats_type == TYPE_CONNECTION_TX_POWER)
+			is_last_event = true;
+		else
+			is_last_event = !!ev->peer_stats;
+	}
+
+	if (is_last_event)
+		cp_stats_debug("Last stats event");
+
+	return is_last_event;
+}
+
+#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
+static void
+tgt_cp_stats_register_infra_cp_stats_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+	rx_ops->cp_stats_rx_ops.process_infra_stats_event =
+				tgt_mc_cp_stats_process_infra_stats_event;
+}
+#else
+static void
+tgt_cp_stats_register_infra_cp_stats_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_BIG_DATA_STATS
+static void
+tgt_cp_stats_register_big_data_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+	rx_ops->cp_stats_rx_ops.process_big_data_stats_event =
+			tgt_mc_cp_stats_process_big_data_stats_event;
+}
+
+static QDF_STATUS
+send_big_data_stats_req(struct wlan_lmac_if_cp_stats_tx_ops *tx_ops,
+			struct wlan_objmgr_psoc *psoc,
+			struct request_info *req)
+{
+	if (!tx_ops->send_req_big_data_stats) {
+		cp_stats_err("could not get send_req_big_data_stats");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return tx_ops->send_req_big_data_stats(psoc, req);
+}
+#else
+static void
+tgt_cp_stats_register_big_data_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
+{}
+
+static QDF_STATUS
+send_big_data_stats_req(struct wlan_lmac_if_cp_stats_tx_ops *tx_ops,
+			struct wlan_objmgr_psoc *psoc,
+			struct request_info *req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+void tgt_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+	rx_ops->cp_stats_rx_ops.process_stats_event =
+					tgt_mc_cp_stats_process_stats_event;
+	tgt_cp_stats_register_infra_cp_stats_rx_ops(rx_ops);
+	tgt_cp_stats_register_big_data_rx_ops(rx_ops);
+}
+
+static void tgt_mc_cp_stats_extract_tx_power(struct wlan_objmgr_psoc *psoc,
+					struct stats_event *ev,
+					bool is_station_stats)
+{
+	int32_t max_pwr = 0;
+	uint8_t pdev_id;
+	uint8_t mac_id = 0;
+	QDF_STATUS status;
+	struct wlan_objmgr_pdev *pdev;
+	struct request_info last_req = {0};
+	struct wlan_objmgr_vdev *vdev = NULL;
+	struct pdev_mc_cp_stats *pdev_mc_stats;
+	struct pdev_cp_stats *pdev_cp_stats_priv;
+
+	if (!ev->pdev_stats)
+		return;
+
+	if (is_station_stats)
+		status = ucfg_mc_cp_stats_get_pending_req(psoc,
+					TYPE_STATION_STATS, &last_req);
+	else
+		status = ucfg_mc_cp_stats_get_pending_req(psoc,
+					TYPE_CONNECTION_TX_POWER, &last_req);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		goto end;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req.vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev) {
+		cp_stats_err("vdev is null");
+		goto end;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		cp_stats_err("pdev is null");
+		goto end;
+	}
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
+	if (pdev_id >= ev->num_pdev_stats) {
+		cp_stats_err("pdev_id: %d invalid", pdev_id);
+		goto end;
+	}
+
+	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
+	if (!pdev_cp_stats_priv) {
+		cp_stats_err("pdev_cp_stats_priv is null");
+		goto end;
+	}
+
+	mac_id = policy_mgr_mode_get_macid_by_vdev_id(psoc, last_req.vdev_id);
+
+	wlan_cp_stats_pdev_obj_lock(pdev_cp_stats_priv);
+	pdev_mc_stats = pdev_cp_stats_priv->pdev_stats;
+	if (!is_station_stats &&
+	    pdev_mc_stats->max_pwr != ev->pdev_stats[pdev_id].max_pwr)
+		wlan_son_deliver_tx_power(vdev,
+					  ev->pdev_stats[pdev_id].max_pwr);
+	if (mac_id == ev->mac_seq_num)
+		max_pwr = pdev_mc_stats->max_pwr =
+			ev->pdev_stats[pdev_id].max_pwr;
+
+	wlan_cp_stats_pdev_obj_unlock(pdev_cp_stats_priv);
+
+end:
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+}
+
+static void peer_rssi_iterator(struct wlan_objmgr_pdev *pdev,
+			       void *peer, void *arg)
+{
+	struct stats_event *ev;
+	struct peer_mc_cp_stats *peer_mc_stats;
+	struct peer_cp_stats *peer_cp_stats_priv;
+	struct peer_extd_stats *peer_extd_mc_stats;
+
+	if (WLAN_PEER_SELF == wlan_peer_get_peer_type(peer)) {
+		cp_stats_debug("ignore self peer: "QDF_MAC_ADDR_FMT,
+			       QDF_MAC_ADDR_REF(wlan_peer_get_macaddr(peer)));
+		return;
+	}
+
+	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+	if (!peer_cp_stats_priv) {
+		cp_stats_err("peer cp stats object is null");
+		return;
+	}
+
+	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+	peer_mc_stats = peer_cp_stats_priv->peer_stats;
+	ev = arg;
+	ev->peer_stats[ev->num_peer_stats] = *peer_mc_stats;
+	ev->num_peer_stats++;
+
+	peer_extd_mc_stats = peer_mc_stats->extd_stats;
+	ev->peer_extended_stats[ev->num_peer_extd_stats] = *peer_extd_mc_stats;
+	ev->num_peer_extd_stats++;
+	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+}
+
+static void
+tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc,
+				      struct request_info *last_req)
+{
+	uint8_t *mac_addr;
+	uint16_t peer_count;
+	struct stats_event ev = {0};
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_peer *peer = NULL;
+	struct peer_mc_cp_stats *peer_mc_stats;
+	struct peer_extd_stats *peer_mc_extd_stats;
+	struct peer_cp_stats *peer_cp_stats_priv;
+	void (*get_peer_rssi_cb)(struct stats_event *ev, void *cookie);
+
+	get_peer_rssi_cb = last_req->u.get_peer_rssi_cb;
+	if (!get_peer_rssi_cb) {
+		cp_stats_debug("get_peer_rssi_cb is null");
+		return;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req->vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev) {
+		cp_stats_err("vdev is null");
+		goto end;
+	}
+
+	mac_addr = last_req->peer_mac_addr;
+	if (QDF_IS_ADDR_BROADCAST(mac_addr)) {
+		pdev = wlan_vdev_get_pdev(vdev);
+		peer_count = wlan_pdev_get_peer_count(pdev);
+		ev.peer_stats = qdf_mem_malloc(sizeof(*ev.peer_stats) *
+								peer_count);
+		if (!ev.peer_stats)
+			goto end;
+
+		ev.peer_extended_stats =
+			qdf_mem_malloc(sizeof(*ev.peer_extended_stats) *
+				       peer_count);
+		if (!ev.peer_extended_stats)
+			goto end;
+
+		wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_PEER_OP,
+						  peer_rssi_iterator, &ev,
+						  true, WLAN_CP_STATS_ID);
+	} else {
+		peer = wlan_objmgr_get_peer(psoc, last_req->pdev_id,
+					    mac_addr, WLAN_CP_STATS_ID);
+		if (!peer) {
+			cp_stats_debug("peer[" QDF_MAC_ADDR_FMT "] is null",
+				       QDF_MAC_ADDR_REF(mac_addr));
+			goto end;
+		}
+
+		peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+		if (!peer_cp_stats_priv) {
+			cp_stats_err("peer cp stats object is null");
+			goto end;
+		}
+
+		ev.peer_stats = qdf_mem_malloc(sizeof(*ev.peer_stats));
+		if (!ev.peer_stats)
+			goto end;
+
+		ev.num_peer_stats = 1;
+
+		ev.peer_extended_stats =
+			qdf_mem_malloc(sizeof(*ev.peer_extended_stats));
+		if (!ev.peer_extended_stats)
+			goto end;
+
+		ev.num_peer_extd_stats = 1;
+
+		wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+		peer_mc_stats = peer_cp_stats_priv->peer_stats;
+		*ev.peer_stats = *peer_mc_stats;
+
+		peer_mc_extd_stats = peer_mc_stats->extd_stats;
+		*ev.peer_extended_stats = *peer_mc_extd_stats;
+		wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+	}
+
+end:
+	get_peer_rssi_cb(&ev, last_req->cookie);
+
+	ucfg_mc_cp_stats_free_stats_resources(&ev);
+
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+	if (peer)
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+}
+
+static QDF_STATUS
+tgt_mc_cp_stats_update_peer_adv_stats(struct wlan_objmgr_psoc *psoc,
+				      struct peer_adv_mc_cp_stats
+				      *peer_adv_stats, uint32_t size)
+{
+	uint8_t *peer_mac_addr;
+	struct wlan_objmgr_peer *peer;
+	struct peer_mc_cp_stats *peer_mc_stats;
+	struct peer_adv_mc_cp_stats *peer_adv_mc_stats;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct peer_cp_stats *peer_cp_stats_priv;
+
+	if (!peer_adv_stats)
+		return QDF_STATUS_E_INVAL;
+
+	peer_mac_addr = peer_adv_stats->peer_macaddr;
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
+					   WLAN_CP_STATS_ID);
+	if (!peer) {
+		cp_stats_debug("peer is null");
+		return QDF_STATUS_E_EXISTS;
+	}
+	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+	if (!peer_cp_stats_priv) {
+		cp_stats_err("peer_cp_stats_priv is null");
+		status = QDF_STATUS_E_EXISTS;
+		goto end;
+	}
+	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+	peer_mc_stats = peer_cp_stats_priv->peer_stats;
+	peer_adv_mc_stats = peer_mc_stats->adv_stats;
+
+	qdf_mem_copy(peer_adv_mc_stats->peer_macaddr,
+		     peer_adv_stats->peer_macaddr,
+		     QDF_MAC_ADDR_SIZE);
+	if (peer_adv_stats->fcs_count)
+		peer_adv_mc_stats->fcs_count = peer_adv_stats->fcs_count;
+	if (peer_adv_stats->rx_bytes)
+		peer_adv_mc_stats->rx_bytes = peer_adv_stats->rx_bytes;
+	if (peer_adv_stats->rx_count)
+		peer_adv_mc_stats->rx_count = peer_adv_stats->rx_count;
+	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+
+end:
+	if (peer)
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+
+	return status;
+}
+
+static QDF_STATUS
+tgt_mc_cp_stats_update_peer_stats(struct wlan_objmgr_psoc *psoc,
+				  struct peer_mc_cp_stats *peer_stats)
+{
+	uint8_t *peer_mac_addr;
+	struct wlan_objmgr_peer *peer;
+	struct peer_mc_cp_stats *peer_mc_stats;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct peer_cp_stats *peer_cp_stats_priv;
+
+	if (!peer_stats)
+		return QDF_STATUS_E_INVAL;
+
+	peer_mac_addr = peer_stats->peer_macaddr;
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
+				    WLAN_CP_STATS_ID);
+	if (!peer) {
+		cp_stats_debug("peer is null");
+		return QDF_STATUS_E_EXISTS;
+	}
+
+	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+	if (!peer_cp_stats_priv) {
+		cp_stats_err("peer_cp_stats_priv is null");
+		status = QDF_STATUS_E_EXISTS;
+		goto end;
+	}
+
+	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+	peer_mc_stats = peer_cp_stats_priv->peer_stats;
+	qdf_mem_copy(peer_mc_stats->peer_macaddr,
+		     peer_stats->peer_macaddr,
+		     QDF_MAC_ADDR_SIZE);
+	if (peer_stats->tx_rate)
+		peer_mc_stats->tx_rate = peer_stats->tx_rate;
+	if (peer_stats->rx_rate)
+		peer_mc_stats->rx_rate = peer_stats->rx_rate;
+	if (peer_stats->peer_rssi)
+		peer_mc_stats->peer_rssi = peer_stats->peer_rssi;
+	cp_stats_nofl_debug("PEER STATS: peer_mac="QDF_MAC_ADDR_FMT", tx_rate=%u, rx_rate=%u, peer_rssi=%d",
+			    QDF_MAC_ADDR_REF(peer_mc_stats->peer_macaddr),
+			    peer_mc_stats->tx_rate,
+			    peer_mc_stats->rx_rate, peer_mc_stats->peer_rssi);
+	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+
+end:
+	if (peer)
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+
+	return status;
+}
+
+static QDF_STATUS
+tgt_mc_cp_stats_update_peer_extd_stats(
+				struct wlan_objmgr_psoc *psoc,
+				struct peer_extd_stats *peer_extended_stats)
+{
+	uint8_t *peer_mac_addr;
+	struct wlan_objmgr_peer *peer;
+	struct peer_mc_cp_stats *peer_mc_stats;
+	struct peer_extd_stats *peer_extd_mc_stats;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct peer_cp_stats *peer_cp_stats_priv;
+
+	if (!peer_extended_stats)
+		return QDF_STATUS_E_INVAL;
+
+	peer_mac_addr = peer_extended_stats->peer_macaddr;
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
+					   WLAN_CP_STATS_ID);
+	if (!peer) {
+		cp_stats_debug("peer is null");
+		return QDF_STATUS_E_EXISTS;
+	}
+
+	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+	if (!peer_cp_stats_priv) {
+		cp_stats_err("peer_cp_stats_priv is null");
+		status = QDF_STATUS_E_EXISTS;
+		goto end;
+	}
+
+	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+	peer_mc_stats = peer_cp_stats_priv->peer_stats;
+	peer_extd_mc_stats = peer_mc_stats->extd_stats;
+	if (!peer_extd_mc_stats) {
+		wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+		cp_stats_err("No peer_extd_mc_stats");
+		status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+	qdf_mem_copy(peer_extd_mc_stats->peer_macaddr,
+		     peer_extended_stats->peer_macaddr,
+		     QDF_MAC_ADDR_SIZE);
+	if (peer_extended_stats->rx_mc_bc_cnt)
+		peer_extd_mc_stats->rx_mc_bc_cnt =
+					peer_extended_stats->rx_mc_bc_cnt;
+	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+
+	cp_stats_debug("peer_mac="QDF_MAC_ADDR_FMT", rx_mc_bc_cnt=%u",
+		       QDF_MAC_ADDR_REF(peer_extended_stats->peer_macaddr),
+		       peer_extended_stats->rx_mc_bc_cnt);
+
+end:
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+
+	return status;
+}
+
+static void tgt_mc_cp_stats_extract_peer_extd_stats(
+						struct wlan_objmgr_psoc *psoc,
+						struct stats_event *ev)
+{
+	uint32_t i, selected;
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_PEER_STATS,
+						  &last_req);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	selected = ev->num_peer_extd_stats;
+	for (i = 0; i < ev->num_peer_extd_stats; i++) {
+		status = tgt_mc_cp_stats_update_peer_extd_stats(
+						psoc,
+						&ev->peer_extended_stats[i]);
+
+		if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
+		    !qdf_mem_cmp(ev->peer_extended_stats[i].peer_macaddr,
+				 last_req.peer_mac_addr,
+				 QDF_MAC_ADDR_SIZE)) {
+			/* mac is specified, but failed to update the peer */
+			if (QDF_IS_STATUS_ERROR(status))
+				return;
+
+			selected = i;
+		}
+	}
+
+	/* no matched peer */
+	if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
+	    selected == ev->num_peer_extd_stats) {
+		cp_stats_rl_err("peer not found stats");
+		return;
+	}
+}
+
+static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc,
+					       struct stats_event *ev,
+					       bool is_station_stats)
+{
+	uint32_t i;
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	bool pending = false;
+	uint32_t selected;
+
+	if (is_station_stats)
+		status = ucfg_mc_cp_stats_get_pending_req(psoc,
+							  TYPE_STATION_STATS,
+							  &last_req);
+	else
+		status = ucfg_mc_cp_stats_get_pending_req(psoc,
+							  TYPE_PEER_STATS,
+							  &last_req);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	if (!ev->peer_stats)
+		goto extd2_stats;
+
+	selected = ev->num_peer_stats;
+	for (i = 0; i < ev->num_peer_stats; i++) {
+		status = tgt_mc_cp_stats_update_peer_stats(psoc,
+							   &ev->peer_stats[i]);
+		if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
+		    !qdf_mem_cmp(ev->peer_stats[i].peer_macaddr,
+				 last_req.peer_mac_addr,
+				 QDF_MAC_ADDR_SIZE)) {
+			/* mac is specified, but failed to update the peer */
+			if (QDF_IS_STATUS_ERROR(status))
+				return;
+
+			selected = i;
+		}
+	}
+
+	/* no matched peer */
+	if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
+	    selected == ev->num_peer_stats)
+		cp_stats_debug("peer not found for stats");
+
+extd2_stats:
+
+	if (!ev->peer_adv_stats)
+		goto complete;
+
+	selected = ev->num_peer_adv_stats;
+	for (i = 0; i < ev->num_peer_adv_stats; i++) {
+		status = tgt_mc_cp_stats_update_peer_adv_stats(
+						psoc, &ev->peer_adv_stats[i],
+						ev->num_peer_adv_stats);
+		if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
+		    !qdf_mem_cmp(ev->peer_adv_stats[i].peer_macaddr,
+				 last_req.peer_mac_addr,
+				 QDF_MAC_ADDR_SIZE)) {
+			/* mac is specified, but failed to update the peer */
+			if (QDF_IS_STATUS_ERROR(status))
+				return;
+
+			selected = i;
+		}
+	}
+
+	/* no matched peer */
+	if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
+	    selected == ev->num_peer_adv_stats)
+		cp_stats_debug("peer not found for extd stats");
+
+complete:
+	if (is_station_stats)
+		return;
+
+	tgt_mc_cp_stats_extract_peer_extd_stats(psoc, ev);
+	if (tgt_mc_cp_stats_is_last_event(ev, TYPE_PEER_STATS)) {
+		ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS,
+						   &last_req, &pending);
+		if (pending && last_req.u.get_peer_rssi_cb)
+			tgt_mc_cp_stats_prepare_raw_peer_rssi(psoc, &last_req);
+	}
+}
+
+#ifdef WLAN_FEATURE_MIB_STATS
+static void tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc *psoc,
+					      struct stats_event *ev)
+{
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	bool pending = false;
+
+	if (!ev->mib_stats) {
+		cp_stats_debug("no mib stats");
+		return;
+	}
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_MIB_STATS, &last_req);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	if (tgt_mc_cp_stats_is_last_event(ev, TYPE_MIB_STATS)) {
+		ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_MIB_STATS,
+						   &last_req, &pending);
+		if (last_req.u.get_mib_stats_cb && pending)
+			last_req.u.get_mib_stats_cb(ev, last_req.cookie);
+	}
+}
+#else
+static void tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc *psoc,
+					      struct stats_event *ev)
+{
+}
+#endif
+
+static void
+tgt_mc_cp_stats_extract_peer_stats_info_ext(struct wlan_objmgr_psoc *psoc,
+					    struct stats_event *ev)
+{
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	bool pending = false;
+
+	if (!ev->peer_stats_info_ext || ev->num_peer_stats_info_ext == 0) {
+		cp_stats_debug("no peer_stats_info_ext");
+		return;
+	}
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_PEER_STATS_INFO_EXT,
+						  &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS_INFO_EXT,
+					   &last_req, &pending);
+	if (last_req.u.get_peer_stats_cb && pending) {
+		last_req.u.get_peer_stats_cb(ev, last_req.cookie);
+		last_req.u.get_peer_stats_cb = NULL;
+	}
+}
+
+#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
+#ifdef WLAN_SUPPORT_TWT
+static void
+tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc *psoc,
+					struct infra_cp_stats_event *ev)
+{
+	QDF_STATUS status;
+	get_infra_cp_stats_cb resp_cb = NULL;
+	void *context = NULL;
+
+	status = wlan_cp_stats_infra_cp_get_context(psoc, &resp_cb, &context);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_get_infra_cp_stats_context failed");
+		return;
+	}
+
+	cp_stats_debug("num_twt_infra_cp_stats = %d action %d",
+		       ev->num_twt_infra_cp_stats, ev->action);
+
+	if (resp_cb)
+		resp_cb(ev, context);
+}
+#else
+static void
+tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc *psoc,
+					struct infra_cp_stats_event *ev)
+{
+}
+#endif
+#endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
+
+#ifdef WLAN_FEATURE_MEDIUM_ASSESS
+static void
+tgt_mc_cp_stats_extract_congestion_stats(struct wlan_objmgr_psoc *psoc,
+					 struct stats_event *ev)
+{
+	QDF_STATUS status;
+	uint8_t i, index;
+	struct request_info last_req = {0};
+	struct medium_assess_data data[WLAN_UMAC_MAX_RP_PID] = { {0} };
+	bool is_last_event = tgt_mc_cp_stats_is_last_event(ev,
+					TYPE_CONGESTION_STATS);
+
+	if (!(ev->num_pdev_stats || ev->num_pdev_extd_stats)) {
+		cp_stats_err("no congestion sta for pdev");
+		return;
+	}
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_CONGESTION_STATS,
+						  &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	for (i = 0; (i < ev->num_pdev_stats) && (i < WLAN_UMAC_MAX_RP_PID);
+	     i++){
+		index = ev->pdev_stats[i].pdev_id;
+		if (index >= WLAN_UMAC_MAX_RP_PID) {
+			cp_stats_err("part1 pdev id error");
+			continue;
+		}
+		data[index].part1_valid = true;
+		data[index].cycle_count = ev->pdev_stats[i].cycle_count;
+		data[index].rx_clear_count = ev->pdev_stats[i].rx_clear_count;
+		data[index].tx_frame_count = ev->pdev_stats[i].tx_frame_count;
+	}
+
+	for (i = 0; (i < ev->num_pdev_extd_stats) && (i < WLAN_UMAC_MAX_RP_PID);
+	     i++){
+		index = ev->pdev_extd_stats[i].pdev_id;
+		if (index >= WLAN_UMAC_MAX_RP_PID) {
+			cp_stats_err("part2 pdev id error");
+			continue;
+		}
+		data[index].part2_valid = true;
+		data[index].my_rx_count = ev->pdev_extd_stats[i].my_rx_count;
+	}
+
+	if (last_req.u.congestion_notif_cb)
+		last_req.u.congestion_notif_cb(last_req.vdev_id, data,
+						is_last_event);
+
+}
+#else
+static void
+tgt_mc_cp_stats_extract_congestion_stats(struct wlan_objmgr_psoc *psoc,
+					 struct stats_event *ev)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_11BE_MLO
+static void
+update_ml_vdev_id_from_stats_event(struct request_info *req,
+				   uint8_t *vdev_id)
+{
+	if (!req->ml_vdev_info.ml_vdev_count) {
+		*vdev_id = req->vdev_id;
+		return;
+	}
+
+	if (*vdev_id == WLAN_UMAC_VDEV_ID_MAX ||
+	    *vdev_id >= WLAN_MAX_VDEVS) {
+		cp_stats_err("Invalid vdev[%u] sent by firmware", *vdev_id);
+		*vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+	}
+}
+#else
+static inline void
+update_ml_vdev_id_from_stats_event(struct request_info *req,
+				   uint8_t *vdev_id)
+{
+	*vdev_id = req->vdev_id;
+}
+#endif
+
+static void tgt_mc_cp_stats_extract_cca_stats(struct wlan_objmgr_psoc *psoc,
+						  struct stats_event *ev)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct vdev_cp_stats *vdev_cp_stats_priv;
+
+	if (!ev->cca_stats)
+		return;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+						    ev->cca_stats->vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev) {
+		cp_stats_err("vdev is null");
+		return;
+	}
+
+	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
+	if (!vdev_cp_stats_priv) {
+		cp_stats_err("vdev cp stats object is null");
+		goto end;
+	}
+
+	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
+	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
+	vdev_mc_stats->cca.congestion =  ev->cca_stats->congestion;
+	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
+
+end:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+}
+
+static void
+tgt_mc_cp_stats_extract_pmf_bcn_stats(struct wlan_objmgr_psoc *psoc,
+				      struct stats_event *ev)
+{
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct vdev_cp_stats *vdev_cp_stats_priv;
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_STATION_STATS,
+						  &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req.vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev) {
+		cp_stats_err("vdev is null");
+		return;
+	}
+
+	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
+	if (!vdev_cp_stats_priv) {
+		cp_stats_err("vdev cp stats object is null");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+		return;
+	}
+
+	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
+	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
+
+	if (ev->bcn_protect_stats.pmf_bcn_stats_valid)
+		vdev_mc_stats->pmf_bcn_stats = ev->bcn_protect_stats;
+
+	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+}
+
+static void tgt_mc_cp_stats_extract_vdev_summary_stats(
+					struct wlan_objmgr_psoc *psoc,
+					struct stats_event *ev)
+{
+	uint8_t i, vdev_id = WLAN_INVALID_VDEV_ID;
+	QDF_STATUS status;
+	struct wlan_objmgr_peer *peer = NULL;
+	struct request_info last_req = {0};
+	struct wlan_objmgr_vdev *vdev;
+	struct peer_mc_cp_stats *peer_mc_stats;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct peer_cp_stats *peer_cp_stats_priv;
+	struct vdev_cp_stats *vdev_cp_stats_priv;
+
+	if (!ev->vdev_summary_stats)
+		return;
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						 TYPE_STATION_STATS,
+						 &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	for (i = 0; i < ev->num_summary_stats; i++) {
+		vdev_id = ev->vdev_summary_stats[i].vdev_id;
+		update_ml_vdev_id_from_stats_event(&last_req, &vdev_id);
+		if (ev->vdev_summary_stats[i].vdev_id == vdev_id)
+			break;
+	}
+
+	if (i == ev->num_summary_stats) {
+		cp_stats_debug("vdev_id %d not found", vdev_id);
+		return;
+	}
+
+	if (vdev_id == WLAN_INVALID_VDEV_ID)
+		return;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev) {
+		cp_stats_err("vdev is null");
+		return;
+	}
+
+	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
+	if (!vdev_cp_stats_priv) {
+		cp_stats_err("vdev cp stats object is null");
+		goto end;
+	}
+
+	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
+	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
+	qdf_mem_copy(&vdev_mc_stats->vdev_summary_stats,
+		     &ev->vdev_summary_stats[i].stats,
+		     sizeof(vdev_mc_stats->vdev_summary_stats));
+
+	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
+
+	peer = wlan_objmgr_get_peer(psoc, last_req.pdev_id,
+				    last_req.peer_mac_addr, WLAN_CP_STATS_ID);
+	if (!peer) {
+		cp_stats_debug("peer is null "QDF_MAC_ADDR_FMT,
+				QDF_MAC_ADDR_REF(last_req.peer_mac_addr));
+		goto end;
+	}
+
+	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+	if (!peer_cp_stats_priv) {
+		cp_stats_err("peer cp stats object is null");
+		goto end;
+	}
+
+	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+	peer_mc_stats = peer_cp_stats_priv->peer_stats;
+	peer_mc_stats->peer_rssi = ev->vdev_summary_stats[i].stats.rssi;
+	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+
+end:
+	if (peer)
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+}
+
+static void tgt_mc_cp_stats_extract_vdev_chain_rssi_stats(
+					struct wlan_objmgr_psoc *psoc,
+					struct stats_event *ev)
+{
+	uint8_t i, j, vdev_id;
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct vdev_cp_stats *vdev_cp_stats_priv;
+
+	if (!ev->vdev_chain_rssi)
+		return;
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_STATION_STATS,
+						  &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	for (i = 0; i < ev->num_chain_rssi_stats; i++) {
+		vdev_id = ev->vdev_chain_rssi[i].vdev_id;
+		update_ml_vdev_id_from_stats_event(&last_req, &vdev_id);
+		if (ev->vdev_chain_rssi[i].vdev_id != vdev_id)
+			continue;
+
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+							    WLAN_CP_STATS_ID);
+		if (!vdev) {
+			cp_stats_err("vdev is null");
+			return;
+		}
+
+		vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
+		if (!vdev_cp_stats_priv) {
+			cp_stats_err("vdev cp stats object is null");
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+			return;
+		}
+
+		wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
+		vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
+		for (j = 0; j < MAX_NUM_CHAINS; j++) {
+			vdev_mc_stats->chain_rssi[j] =
+					ev->vdev_chain_rssi[i].chain_rssi[j];
+		}
+		wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
+
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+	}
+}
+
+static void
+tgt_mc_cp_stats_extract_vdev_extd_stats(struct wlan_objmgr_psoc *psoc,
+					struct stats_event *ev)
+{
+	uint8_t i, vdev_id;
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct vdev_cp_stats *vdev_cp_stats_priv;
+
+	if (!ev->vdev_extd_stats)
+		return;
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc, TYPE_STATION_STATS,
+						  &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	for (i = 0; i < ev->num_vdev_extd_stats; i++) {
+		vdev_id = ev->vdev_extd_stats[i].vdev_id;
+
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+							    WLAN_CP_STATS_ID);
+		if (!vdev) {
+			cp_stats_err("vdev is null");
+			return;
+		}
+
+		vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
+		if (!vdev_cp_stats_priv) {
+			cp_stats_err("vdev cp stats object is null");
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+			return;
+		}
+
+		wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
+		vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
+		qdf_mem_copy(&vdev_mc_stats->vdev_extd_stats,
+			     &ev->vdev_extd_stats[i],
+			     sizeof(vdev_mc_stats->vdev_extd_stats));
+
+		wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+	}
+}
+
+static QDF_STATUS
+tgt_send_vdev_mc_cp_stats(struct wlan_objmgr_psoc *psoc,
+			  struct stats_event *ev,
+			  struct request_info *last_req)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct vdev_cp_stats *vdev_cp_stats_priv;
+
+	if (!ev || !last_req)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req->vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev) {
+		cp_stats_err("vdev object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
+	if (!vdev_cp_stats_priv) {
+		cp_stats_err("vdev cp stats object is null");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
+	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
+	ev->vdev_summary_stats[0].vdev_id = last_req->vdev_id;
+	ev->vdev_summary_stats[0].stats = vdev_mc_stats->vdev_summary_stats;
+	ev->vdev_chain_rssi[0].vdev_id = last_req->vdev_id;
+	qdf_mem_copy(ev->vdev_chain_rssi[0].chain_rssi,
+		     vdev_mc_stats->chain_rssi,
+		     sizeof(vdev_mc_stats->chain_rssi));
+	ev->tx_rate_flags = vdev_mc_stats->tx_rate_flags;
+
+	ev->bcn_protect_stats = vdev_mc_stats->pmf_bcn_stats;
+
+	qdf_mem_copy(&ev->vdev_extd_stats[0],
+		     &vdev_mc_stats->vdev_extd_stats,
+		     sizeof(vdev_mc_stats->vdev_extd_stats));
+
+	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+tgt_send_peer_mc_cp_stats(struct wlan_objmgr_psoc *psoc,
+			  struct stats_event *ev,
+			  struct request_info *last_req)
+{
+	struct wlan_objmgr_peer *peer;
+	struct peer_mc_cp_stats *peer_mc_stats;
+	struct peer_cp_stats *peer_cp_stats_priv;
+
+	if (!ev || !last_req)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	peer = wlan_objmgr_get_peer(psoc, last_req->pdev_id,
+				    last_req->peer_mac_addr, WLAN_CP_STATS_ID);
+	if (!peer) {
+		cp_stats_debug("peer object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+	if (!peer_cp_stats_priv) {
+		cp_stats_err("peer cp stats object is null");
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+	peer_mc_stats = peer_cp_stats_priv->peer_stats;
+	/*
+	 * The linkspeed returned by fw is in kbps so convert
+	 * it in units of 100kbps which is expected by UMAC
+	 */
+	ev->tx_rate = peer_mc_stats->tx_rate / 100;
+	ev->rx_rate = peer_mc_stats->rx_rate / 100;
+
+	if (peer_mc_stats->adv_stats) {
+		ev->num_peer_adv_stats = 1;
+		qdf_mem_copy(ev->peer_adv_stats,
+			     peer_mc_stats->adv_stats,
+			     sizeof(*peer_mc_stats->adv_stats));
+	}
+
+	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+	wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+tgt_send_pdev_mc_cp_stats(struct wlan_objmgr_psoc *psoc,
+			  struct stats_event *ev,
+			  struct request_info *last_req)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_vdev *vdev = NULL;
+	struct pdev_mc_cp_stats *pdev_mc_stats;
+	struct pdev_cp_stats *pdev_cp_stats_priv;
+	int pdev_id;
+
+	if (!ev || !last_req)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req->vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev) {
+		cp_stats_err("vdev is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		cp_stats_err("pdev is null");
+		goto end;
+	}
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
+	if (pdev_id != last_req->pdev_id) {
+		cp_stats_err("pdev_id: %d invalid", pdev_id);
+		goto end;
+	}
+
+	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
+	if (!pdev_cp_stats_priv) {
+		cp_stats_err("pdev_cp_stats_priv is null");
+		goto end;
+	}
+
+	wlan_cp_stats_pdev_obj_lock(pdev_cp_stats_priv);
+	pdev_mc_stats = pdev_cp_stats_priv->pdev_stats;
+	qdf_mem_copy(ev->pdev_stats,
+		     pdev_mc_stats,
+		     sizeof(*pdev_mc_stats));
+	wlan_cp_stats_pdev_obj_unlock(pdev_cp_stats_priv);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+
+	return QDF_STATUS_SUCCESS;
+
+end:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+	return QDF_STATUS_E_NULL_VALUE;
+}
+
+static QDF_STATUS
+tgt_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev, int *dbm)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct pdev_mc_cp_stats *pdev_mc_stats;
+	struct pdev_cp_stats *pdev_cp_stats_priv;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct vdev_cp_stats *vdev_cp_stat;
+	uint32_t vdev_power = 0;
+
+	vdev_cp_stat = wlan_cp_stats_get_vdev_stats_obj(vdev);
+	if (vdev_cp_stat) {
+		wlan_cp_stats_vdev_obj_lock(vdev_cp_stat);
+		vdev_mc_stats = vdev_cp_stat->vdev_stats;
+		vdev_power = vdev_mc_stats->vdev_extd_stats.vdev_tx_power;
+		wlan_cp_stats_vdev_obj_unlock(vdev_cp_stat);
+		if (vdev_power) {
+			*dbm = vdev_power;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
+	if (!pdev_cp_stats_priv) {
+		cp_stats_err("pdev cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_pdev_obj_lock(pdev_cp_stats_priv);
+	pdev_mc_stats = pdev_cp_stats_priv->pdev_stats;
+	*dbm = pdev_mc_stats->max_pwr;
+	wlan_cp_stats_pdev_obj_unlock(pdev_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void
+tgt_mc_cp_stats_extract_vdev_and_extd_stats(struct wlan_objmgr_psoc *psoc,
+					    struct stats_event *ev)
+{
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	bool pending = false;
+	int32_t max_pwr = 0;
+	struct wlan_objmgr_vdev *vdev = NULL;
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_CONNECTION_TX_POWER,
+						  &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	if (ev->pdev_stats)
+		tgt_mc_cp_stats_extract_tx_power(psoc, ev, false);
+	else if (ev->vdev_extd_stats)
+		tgt_mc_cp_stats_extract_vdev_extd_stats(psoc, ev);
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req.vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev) {
+		cp_stats_err("vdev is null");
+		return;
+	}
+	tgt_mc_cp_stats_get_tx_power(vdev, &max_pwr);
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+
+	if (tgt_mc_cp_stats_is_last_event(ev, TYPE_CONNECTION_TX_POWER)) {
+		ucfg_mc_cp_stats_reset_pending_req(psoc,
+						   TYPE_CONNECTION_TX_POWER,
+						   &last_req,
+						   &pending);
+		if (last_req.u.get_tx_power_cb && pending)
+			last_req.u.get_tx_power_cb(max_pwr, last_req.cookie);
+	}
+}
+
+static void
+tgt_mc_cp_stats_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
+				       struct request_info *last_req)
+{
+	/* station_stats to be given to userspace thread */
+	struct stats_event info = {0};
+	void (*get_station_stats_cb)(struct stats_event *info, void *cookie);
+	QDF_STATUS status;
+
+	get_station_stats_cb = last_req->u.get_station_stats_cb;
+	if (!get_station_stats_cb) {
+		cp_stats_err("callback is null");
+		return;
+	}
+
+	info.num_summary_stats = 1;
+	info.num_chain_rssi_stats = 1;
+	info.num_vdev_extd_stats = 1;
+	info.vdev_summary_stats = qdf_mem_malloc(
+					sizeof(*info.vdev_summary_stats));
+	info.vdev_chain_rssi = qdf_mem_malloc(sizeof(*info.vdev_chain_rssi));
+
+	info.vdev_extd_stats = qdf_mem_malloc(sizeof(*info.vdev_extd_stats));
+
+	if (!info.vdev_summary_stats || !info.vdev_chain_rssi ||
+	    !info.vdev_extd_stats)
+		goto end;
+
+	status = tgt_send_vdev_mc_cp_stats(psoc, &info, last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("tgt_send_vdev_mc_cp_stats failed");
+		goto end;
+	}
+
+	info.peer_adv_stats = qdf_mem_malloc(sizeof(*info.peer_adv_stats));
+	if (!info.peer_adv_stats)
+		goto end;
+
+	status = tgt_send_peer_mc_cp_stats(psoc, &info, last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("tgt_send_peer_mc_cp_stats failed");
+		goto end;
+	}
+
+	info.num_pdev_stats = 1;
+	info.pdev_stats = qdf_mem_malloc(sizeof(*info.pdev_stats));
+	if (!info.pdev_stats)
+		goto end;
+
+	status = tgt_send_pdev_mc_cp_stats(psoc, &info, last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("tgt_send_pdev_mc_cp_stats failed");
+		goto end;
+	}
+end:
+	get_station_stats_cb(&info, last_req->cookie);
+
+	ucfg_mc_cp_stats_free_stats_resources(&info);
+}
+
+#ifdef WLAN_FEATURE_11BE_MLO
+static void
+tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
+						 struct request_info *last_req)
+{
+	uint8_t i;
+
+	if (!last_req->ml_vdev_info.ml_vdev_count) {
+		cp_stats_nofl_debug("Invoking get_station_cb for vdev_id[%d]",
+				    last_req->vdev_id);
+		tgt_mc_cp_stats_send_raw_station_stats(psoc, last_req);
+		return;
+	}
+
+	for (i = 0; i < last_req->ml_vdev_info.ml_vdev_count; i++) {
+		last_req->vdev_id = last_req->ml_vdev_info.ml_vdev_id[i];
+		qdf_mem_copy(last_req->peer_mac_addr,
+			     &(last_req->ml_peer_mac_addr[i][0]),
+			     QDF_MAC_ADDR_SIZE);
+		cp_stats_nofl_debug("Invoking get_station_cb for ml vdev_id[%d]",
+				    last_req->vdev_id);
+		tgt_mc_cp_stats_send_raw_station_stats(psoc, last_req);
+	}
+}
+#else
+static void
+tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
+						 struct request_info *last_req)
+{
+	tgt_mc_cp_stats_send_raw_station_stats(psoc, last_req);
+}
+#endif
+
+static void tgt_mc_cp_stats_extract_station_stats(
+				struct wlan_objmgr_psoc *psoc,
+				struct stats_event *ev)
+{
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	bool pending = false;
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_STATION_STATS,
+						  &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	tgt_mc_cp_stats_extract_tx_power(psoc, ev, true);
+	tgt_mc_cp_stats_extract_peer_stats(psoc, ev, true);
+	tgt_mc_cp_stats_extract_vdev_summary_stats(psoc, ev);
+	tgt_mc_cp_stats_extract_vdev_chain_rssi_stats(psoc, ev);
+	tgt_mc_cp_stats_extract_pmf_bcn_stats(psoc, ev);
+	tgt_mc_cp_stats_extract_vdev_extd_stats(psoc, ev);
+
+	/*
+	 * PEER stats are the last stats sent for get_station statistics.
+	 * reset type_map bit for station stats .
+	 */
+	if (tgt_mc_cp_stats_is_last_event(ev, TYPE_STATION_STATS)) {
+		ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_STATION_STATS,
+						   &last_req,
+						   &pending);
+		if (pending && last_req.u.get_station_stats_cb)
+			tgt_mc_cp_stats_prepare_n_send_raw_station_stats(
+							psoc, &last_req);
+	}
+}
+
+static void tgt_mc_cp_send_lost_link_stats(struct wlan_objmgr_psoc *psoc,
+					   struct stats_event *ev)
+{
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (psoc_cp_stats_priv && psoc_cp_stats_priv->legacy_stats_cb)
+		psoc_cp_stats_priv->legacy_stats_cb(ev);
+}
+
+#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
+QDF_STATUS tgt_mc_cp_stats_process_infra_stats_event(
+				struct wlan_objmgr_psoc *psoc,
+				struct infra_cp_stats_event *infra_event)
+{
+	if (!infra_event)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	tgt_mc_infra_cp_stats_extract_twt_stats(psoc, infra_event);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+QDF_STATUS tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc,
+					       struct stats_event *ev)
+{
+	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_CONNECTION_TX_POWER))
+		tgt_mc_cp_stats_extract_vdev_and_extd_stats(psoc, ev);
+
+	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_PEER_STATS))
+		tgt_mc_cp_stats_extract_peer_stats(psoc, ev, false);
+
+	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_STATION_STATS))
+		tgt_mc_cp_stats_extract_station_stats(psoc, ev);
+
+	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_MIB_STATS))
+		tgt_mc_cp_stats_extract_mib_stats(psoc, ev);
+
+	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_PEER_STATS_INFO_EXT))
+		tgt_mc_cp_stats_extract_peer_stats_info_ext(psoc, ev);
+
+	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_CONGESTION_STATS))
+		tgt_mc_cp_stats_extract_congestion_stats(psoc, ev);
+
+	tgt_mc_cp_stats_extract_cca_stats(psoc, ev);
+
+	tgt_mc_cp_send_lost_link_stats(psoc, ev);
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_BIG_DATA_STATS
+QDF_STATUS
+tgt_mc_cp_stats_process_big_data_stats_event(struct wlan_objmgr_psoc *psoc,
+					     struct big_data_stats_event *ev)
+{
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+	bool pending = false;
+
+	if (!ev) {
+		cp_stats_err("invalid data");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_BIG_DATA_STATS,
+						  &last_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_BIG_DATA_STATS,
+					   &last_req, &pending);
+
+	if (last_req.u.get_big_data_stats_cb && pending) {
+		last_req.u.get_big_data_stats_cb(ev, last_req.cookie);
+		last_req.u.get_big_data_stats_cb = NULL;
+	} else {
+		cp_stats_err("callback to send big data stats not found");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+QDF_STATUS tgt_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc,
+					       uint32_t reason,
+					       struct wake_lock_stats *stats,
+					       uint32_t *unspecified_wake_count)
+{
+	struct wlan_lmac_if_cp_stats_tx_ops *tx_ops;
+
+	tx_ops = target_if_cp_stats_get_tx_ops(psoc);
+	if (!tx_ops || !tx_ops->inc_wake_lock_stats)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	tx_ops->inc_wake_lock_stats(reason, stats, unspecified_wake_count);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS tgt_send_mc_cp_stats_req(struct wlan_objmgr_psoc *psoc,
+				    enum stats_req_type type,
+				    struct request_info *req)
+{
+	struct wlan_lmac_if_cp_stats_tx_ops *tx_ops;
+	QDF_STATUS status;
+
+	tx_ops = target_if_cp_stats_get_tx_ops(psoc);
+	if (!tx_ops) {
+		cp_stats_err("could not get tx_ops");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	switch (type) {
+	case TYPE_PEER_STATS_INFO_EXT:
+		if (!tx_ops->send_req_peer_stats) {
+			cp_stats_err("could not get send_req_peer_stats");
+			return QDF_STATUS_E_NULL_VALUE;
+		}
+		status = tx_ops->send_req_peer_stats(psoc, req);
+		break;
+	case TYPE_BIG_DATA_STATS:
+		status = send_big_data_stats_req(tx_ops, psoc, req);
+		break;
+	default:
+		if (!tx_ops->send_req_stats) {
+			cp_stats_err("could not get send_req_stats");
+			return QDF_STATUS_E_NULL_VALUE;
+		}
+		status = tx_ops->send_req_stats(psoc, type, req);
+	}
+
+	return status;
+}
+
+QDF_STATUS tgt_set_pdev_stats_update_period(struct wlan_objmgr_psoc *psoc,
+					    uint8_t pdev_id, uint32_t val)
+{
+	struct wlan_lmac_if_cp_stats_tx_ops *tx_ops;
+	QDF_STATUS status;
+
+	tx_ops = target_if_cp_stats_get_tx_ops(psoc);
+	if (!tx_ops || !tx_ops->set_pdev_stats_update_period) {
+		cp_stats_err("could not get tx_ops");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+	status = tx_ops->set_pdev_stats_update_period(psoc, pdev_id, val);
+
+	return status;
+}
+

+ 1460 - 0
qcom/opensource/wlan/qcacld-3.0/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c

@@ -0,0 +1,1460 @@
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_cp_stats_mc_ucfg_api.c
+ *
+ * This file provide API definitions required for northbound interaction
+ */
+
+#include <wlan_objmgr_psoc_obj.h>
+#include "wlan_cp_stats_mc_defs.h"
+#include <wlan_cp_stats_mc_ucfg_api.h>
+#include <wlan_cp_stats_mc_tgt_api.h>
+#include <wlan_cp_stats_utils_api.h>
+#include "../../core/src/wlan_cp_stats_defs.h"
+#include "../../core/src/wlan_cp_stats_cmn_api_i.h"
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+#include <wlan_pmo_obj_mgmt_api.h>
+#endif
+#ifdef WLAN_SUPPORT_TWT
+#include <wlan_mlme_twt_public_struct.h>
+#endif
+#include <wlan_mlme_api.h>
+
+#ifdef WLAN_SUPPORT_TWT
+
+/**
+ * ucfg_twt_get_peer_session_param_by_dlg_id() - Finds a Peer twt session with
+ * dialog id matching with input dialog id. If a match is found copies
+ * the twt session parameters
+ * @mc_stats: pointer to peer specific stats
+ * @input_dialog_id: input dialog id
+ * @dest_param: Pointer to copy twt session parameters when a peer with
+ * given dialog id is found
+ * @num_twt_session: Pointer holding total number of valid twt session
+ *
+ * Return: Success if stats are copied for a peer with given dialog,
+ * else failure
+ */
+static QDF_STATUS
+ucfg_twt_get_peer_session_param_by_dlg_id(struct peer_mc_cp_stats *mc_stats,
+					  uint32_t input_dialog_id,
+					  struct wmi_host_twt_session_stats_info
+					  *dest_param, int *num_twt_session)
+{
+	struct wmi_host_twt_session_stats_info *src_param;
+	uint32_t event_type;
+	int i = 0;
+	QDF_STATUS qdf_status = QDF_STATUS_E_INVAL;
+
+	if (!mc_stats || !dest_param)
+		return qdf_status;
+
+	for (i = 0; i < TWT_PEER_MAX_SESSIONS; i++) {
+		event_type = mc_stats->twt_param[i].event_type;
+
+		src_param = &mc_stats->twt_param[i];
+		if (!event_type ||
+		    (src_param->dialog_id != input_dialog_id &&
+		     input_dialog_id != TWT_ALL_SESSIONS_DIALOG_ID))
+			continue;
+
+		if ((event_type == HOST_TWT_SESSION_SETUP) ||
+		    (event_type == HOST_TWT_SESSION_UPDATE)) {
+			qdf_mem_copy(&dest_param[*num_twt_session], src_param,
+				     sizeof(*src_param));
+			qdf_status = QDF_STATUS_SUCCESS;
+			*num_twt_session += 1;
+			if (*num_twt_session >= TWT_PEER_MAX_SESSIONS)
+				break;
+		}
+	}
+
+	return qdf_status;
+}
+
+/**
+ * ucfg_twt_get_single_peer_session_params()- Extracts twt session parameters
+ * corresponding to a peer given by dialog_id
+ * @psoc_obj: psoc object
+ * @mac_addr: mac addr of peer
+ * @dialog_id: dialog id of peer for which twt session params to be retrieved
+ * @params: pointer to store peer twt session parameters
+ *
+ * Return: total number of valid twt session
+ */
+static int
+ucfg_twt_get_single_peer_session_params(struct wlan_objmgr_psoc *psoc_obj,
+					uint8_t *mac_addr, uint32_t dialog_id,
+					struct wmi_host_twt_session_stats_info
+					*params)
+{
+	struct wlan_objmgr_peer *peer;
+	struct peer_cp_stats *peer_cp_stats_priv;
+	struct peer_mc_cp_stats *peer_mc_stats;
+	QDF_STATUS qdf_status = QDF_STATUS_E_INVAL;
+	int num_twt_session = 0;
+
+	if (!psoc_obj || !params)
+		return num_twt_session;
+
+	peer = wlan_objmgr_get_peer_by_mac(psoc_obj, mac_addr,
+					   WLAN_CP_STATS_ID);
+	if (!peer)
+		return num_twt_session;
+
+	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+	if (!peer_cp_stats_priv) {
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+		return num_twt_session;
+	}
+
+	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+	peer_mc_stats = peer_cp_stats_priv->peer_stats;
+
+	qdf_status = ucfg_twt_get_peer_session_param_by_dlg_id(
+							peer_mc_stats,
+							dialog_id,
+							params,
+							&num_twt_session);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		qdf_err("No TWT session for " QDF_MAC_ADDR_FMT " dialog_id %d",
+			QDF_MAC_ADDR_REF(mac_addr), dialog_id);
+	}
+
+	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+	wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+
+	return num_twt_session;
+}
+
+/**
+ * ucfg_twt_get_peer_session_param() - Obtains twt session parameters of
+ * a peer if twt session is valid
+ * @mc_cp_stats: pointer to peer specific stats
+ * @params: Pointer to copy twt session parameters
+ * @num_twt_session: Pointer holding total number of valid twt sessions
+ *
+ * Return: QDF_STATUS success if valid twt session parameters are obtained
+ * else other qdf error values
+ */
+static QDF_STATUS
+ucfg_twt_get_peer_session_param(struct peer_mc_cp_stats *mc_cp_stats,
+				struct wmi_host_twt_session_stats_info *params,
+				int *num_twt_session)
+{
+	struct wmi_host_twt_session_stats_info *twt_params;
+	QDF_STATUS qdf_status = QDF_STATUS_E_INVAL;
+	uint32_t event_type;
+	int i;
+
+	if (!mc_cp_stats || !params)
+		return qdf_status;
+
+	for (i = 0; i < TWT_PEER_MAX_SESSIONS; i++) {
+		twt_params = &mc_cp_stats->twt_param[i];
+		event_type = mc_cp_stats->twt_param[i].event_type;
+
+		/* Check twt session is established */
+		if ((event_type == HOST_TWT_SESSION_SETUP) ||
+		    (event_type == HOST_TWT_SESSION_UPDATE)) {
+			qdf_mem_copy(&params[*num_twt_session], twt_params,
+				     sizeof(*twt_params));
+			qdf_status = QDF_STATUS_SUCCESS;
+			*num_twt_session += 1;
+		}
+	}
+	return qdf_status;
+}
+
+/**
+ * ucfg_twt_get_all_peer_session_params()- Retrieves twt session parameters
+ * of all peers with valid twt session
+ * @psoc_obj: psoc object
+ * @vdev_id: vdev_id
+ * @params: array of pointer to store peer twt session parameters
+ *
+ * Return: total number of valid twt sessions
+ */
+static int
+ucfg_twt_get_all_peer_session_params(struct wlan_objmgr_psoc *psoc_obj,
+				     uint8_t vdev_id,
+				     struct wmi_host_twt_session_stats_info
+				     *params)
+{
+	qdf_list_t *peer_list;
+	struct wlan_objmgr_peer *peer, *peer_next;
+	struct wlan_objmgr_vdev *vdev;
+	struct peer_cp_stats *cp_stats_peer_obj, *peer_cp_stat_prv;
+	struct peer_mc_cp_stats *mc_cp_stats;
+	int num_twt_session = 0;
+	enum QDF_OPMODE opmode;
+	int sap_max_peer = 0;
+
+	if (!psoc_obj) {
+		cp_stats_err("psoc is NULL");
+		return num_twt_session;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc_obj, vdev_id,
+						    WLAN_CP_STATS_ID);
+
+	if (!vdev) {
+		cp_stats_err("vdev is NULL, vdev_id: %d", vdev_id);
+		return num_twt_session;
+	}
+
+	wlan_mlme_get_sap_max_peers(psoc_obj, &sap_max_peer);
+	opmode = wlan_vdev_mlme_get_opmode(vdev);
+
+	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
+	if (!peer_list) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+		cp_stats_err("Peer list for vdev obj is NULL");
+		return num_twt_session;
+	}
+
+	peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
+						    WLAN_CP_STATS_ID);
+
+	while (peer) {
+		cp_stats_peer_obj = wlan_objmgr_peer_get_comp_private_obj(
+						peer, WLAN_UMAC_COMP_CP_STATS);
+
+		mc_cp_stats = NULL;
+		if (cp_stats_peer_obj)
+			mc_cp_stats = cp_stats_peer_obj->peer_stats;
+
+		peer_cp_stat_prv =
+			wlan_cp_stats_get_peer_stats_obj(peer);
+
+		if (peer_cp_stat_prv && mc_cp_stats) {
+			wlan_cp_stats_peer_obj_lock(peer_cp_stat_prv);
+			ucfg_twt_get_peer_session_param(mc_cp_stats,
+							params,
+							&num_twt_session);
+			wlan_cp_stats_peer_obj_unlock(peer_cp_stat_prv);
+		}
+
+		if (opmode == QDF_STA_MODE &&
+		    num_twt_session >= TWT_PEER_MAX_SESSIONS) {
+			wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+			goto done;
+		}
+
+		if (opmode == QDF_SAP_MODE &&
+		    num_twt_session >= (sap_max_peer * TWT_PEER_MAX_SESSIONS)) {
+			wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+			goto done;
+		}
+
+		peer_next = wlan_peer_get_next_active_peer_of_vdev(
+							vdev, peer_list, peer,
+							WLAN_CP_STATS_ID);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+		peer = peer_next;
+	}
+
+done:
+	if (!num_twt_session)
+		cp_stats_err("Unable to find a peer with twt session established");
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+	return num_twt_session;
+}
+
+int
+ucfg_twt_get_peer_session_params(struct wlan_objmgr_psoc *psoc_obj,
+				 struct wmi_host_twt_session_stats_info *params)
+{
+	uint8_t *mac_addr;
+	uint32_t dialog_id;
+	uint8_t vdev_id;
+	int num_twt_session = 0;
+
+	if (!psoc_obj || !params)
+		return num_twt_session;
+
+	mac_addr = params[0].peer_mac;
+	dialog_id = params[0].dialog_id;
+	vdev_id = params[0].vdev_id;
+
+	/*
+	 * Currently for STA case, twt_get_params nl is sending only dialog_id
+	 * and mac_addr is being filled by driver in STA peer case.
+	 * For SAP case, twt_get_params nl is sending dialog_id and
+	 * peer mac_addr. When twt_get_params add mac_addr and dialog_id of
+	 * STA/SAP, we need handle unicast/multicast macaddr in
+	 * ucfg_twt_get_peer_session_params.
+	 */
+	if (!QDF_IS_ADDR_BROADCAST(mac_addr))
+		num_twt_session = ucfg_twt_get_single_peer_session_params(
+								psoc_obj,
+								mac_addr,
+								dialog_id,
+								params);
+	else
+		num_twt_session = ucfg_twt_get_all_peer_session_params(
+								psoc_obj,
+								vdev_id,
+								params);
+
+	return num_twt_session;
+}
+#endif /* WLAN_SUPPORT_TWT */
+
+QDF_STATUS wlan_cp_stats_psoc_cs_init(struct psoc_cp_stats *psoc_cs)
+{
+	psoc_cs->obj_stats = qdf_mem_malloc(sizeof(struct psoc_mc_cp_stats));
+	if (!psoc_cs->obj_stats)
+		return QDF_STATUS_E_NOMEM;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cp_stats_psoc_cs_deinit(struct psoc_cp_stats *psoc_cs)
+{
+	qdf_mem_free(psoc_cs->obj_stats);
+	psoc_cs->obj_stats = NULL;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cp_stats_vdev_cs_init(struct vdev_cp_stats *vdev_cs)
+{
+	vdev_cs->vdev_stats = qdf_mem_malloc(sizeof(struct vdev_mc_cp_stats));
+	if (!vdev_cs->vdev_stats)
+		return QDF_STATUS_E_NOMEM;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cp_stats_vdev_cs_deinit(struct vdev_cp_stats *vdev_cs)
+{
+	qdf_mem_free(vdev_cs->vdev_stats);
+	vdev_cs->vdev_stats = NULL;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cp_stats_pdev_cs_init(struct pdev_cp_stats *pdev_cs)
+{
+	pdev_cs->pdev_stats = qdf_mem_malloc(sizeof(struct pdev_mc_cp_stats));
+	if (!pdev_cs->pdev_stats)
+		return QDF_STATUS_E_NOMEM;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cp_stats_pdev_cs_deinit(struct pdev_cp_stats *pdev_cs)
+{
+	qdf_mem_free(pdev_cs->pdev_stats);
+	pdev_cs->pdev_stats = NULL;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cp_stats_peer_cs_init(struct peer_cp_stats *peer_cs)
+{
+	struct peer_mc_cp_stats *peer_mc_stats;
+
+	peer_mc_stats = qdf_mem_malloc(sizeof(struct peer_mc_cp_stats));
+	if (!peer_mc_stats)
+		return QDF_STATUS_E_NOMEM;
+
+	peer_mc_stats->adv_stats =
+			qdf_mem_malloc(sizeof(struct peer_adv_mc_cp_stats));
+
+	if (!peer_mc_stats->adv_stats) {
+		qdf_mem_free(peer_mc_stats);
+		peer_mc_stats = NULL;
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	peer_mc_stats->extd_stats =
+			qdf_mem_malloc(sizeof(struct peer_extd_stats));
+
+	if (!peer_mc_stats->extd_stats) {
+		qdf_mem_free(peer_mc_stats->adv_stats);
+		peer_mc_stats->adv_stats = NULL;
+		qdf_mem_free(peer_mc_stats);
+		peer_mc_stats = NULL;
+		return QDF_STATUS_E_NOMEM;
+	}
+	peer_cs->peer_stats = peer_mc_stats;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cp_stats_peer_cs_deinit(struct peer_cp_stats *peer_cs)
+{
+	struct peer_mc_cp_stats *peer_mc_stats = peer_cs->peer_stats;
+
+	qdf_mem_free(peer_mc_stats->adv_stats);
+	peer_mc_stats->adv_stats = NULL;
+	qdf_mem_free(peer_mc_stats->extd_stats);
+	peer_mc_stats->extd_stats = NULL;
+	qdf_mem_free(peer_cs->peer_stats);
+	peer_cs->peer_stats = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol(
+					struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id,
+					enum qdf_proto_subtype protocol)
+{
+	struct wake_lock_stats *stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+
+	if (!psoc_mc_stats) {
+		cp_stats_err("psoc mc stats is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	stats = &psoc_mc_stats->wow_stats;
+	switch (protocol) {
+	case QDF_PROTO_ICMP_REQ:
+	case QDF_PROTO_ICMP_RES:
+		stats->icmpv4_count++;
+		break;
+	case QDF_PROTO_ICMPV6_REQ:
+	case QDF_PROTO_ICMPV6_RES:
+	case QDF_PROTO_ICMPV6_RS:
+		stats->icmpv6_count++;
+		break;
+	case QDF_PROTO_ICMPV6_RA:
+		stats->icmpv6_count++;
+		stats->ipv6_mcast_ra_stats++;
+		break;
+	case QDF_PROTO_ICMPV6_NS:
+		stats->icmpv6_count++;
+		stats->ipv6_mcast_ns_stats++;
+		break;
+	case QDF_PROTO_ICMPV6_NA:
+		stats->icmpv6_count++;
+		stats->ipv6_mcast_na_stats++;
+		break;
+	default:
+		break;
+	}
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats_by_dst_addr(
+					struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id, uint8_t *dest_mac)
+{
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct wake_lock_stats *stats;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	if (!psoc_mc_stats) {
+		cp_stats_err("psoc mc stats is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	stats = &psoc_mc_stats->wow_stats;
+
+	switch (*dest_mac) {
+	case QDF_BCAST_MAC_ADDR:
+		stats->bcast_wake_up_count++;
+		break;
+	case QDF_MCAST_IPV4_MAC_ADDR:
+		stats->ipv4_mcast_wake_up_count++;
+		break;
+	case QDF_MCAST_IPV6_MAC_ADDR:
+		stats->ipv6_mcast_wake_up_count++;
+		break;
+	default:
+		stats->ucast_wake_up_count++;
+		break;
+	}
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id,
+						uint32_t reason)
+{
+	struct wake_lock_stats *stats;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+
+	if (!psoc_mc_stats) {
+		cp_stats_err("psoc mc stats is null");
+		wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	stats = &psoc_mc_stats->wow_stats;
+
+	status = tgt_mc_cp_stats_inc_wake_lock_stats(psoc, reason, stats,
+				&psoc_mc_stats->wow_unspecified_wake_up_count);
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return status;
+}
+
+/**
+ * vdev_iterator() - iterator function to collect wake_lock_stats from all vdev
+ * @psoc: pointer to psoc object
+ * @vdev: pointer to vdev object
+ * @arg: stats object pointer passed as arg
+ *
+ * Return - none
+ */
+static void vdev_iterator(struct wlan_objmgr_psoc *psoc, void *vdev, void *arg)
+{
+	struct wake_lock_stats *vdev_stats;
+	struct wake_lock_stats *stats = arg;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return;
+	}
+
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	if (!psoc_mc_stats) {
+		cp_stats_err("psoc mc stats is null");
+		return;
+	}
+
+	vdev_stats = &psoc_mc_stats->wow_stats;
+
+	stats->ucast_wake_up_count += vdev_stats->ucast_wake_up_count;
+	stats->bcast_wake_up_count += vdev_stats->bcast_wake_up_count;
+	stats->ipv4_mcast_wake_up_count += vdev_stats->ipv4_mcast_wake_up_count;
+	stats->ipv6_mcast_wake_up_count += vdev_stats->ipv6_mcast_wake_up_count;
+	stats->ipv6_mcast_ra_stats += vdev_stats->ipv6_mcast_ra_stats;
+	stats->ipv6_mcast_ns_stats += vdev_stats->ipv6_mcast_ns_stats;
+	stats->ipv6_mcast_na_stats += vdev_stats->ipv6_mcast_na_stats;
+	stats->icmpv4_count += vdev_stats->icmpv4_count;
+	stats->icmpv6_count += vdev_stats->icmpv6_count;
+	stats->rssi_breach_wake_up_count +=
+			vdev_stats->rssi_breach_wake_up_count;
+	stats->low_rssi_wake_up_count += vdev_stats->low_rssi_wake_up_count;
+	stats->gscan_wake_up_count += vdev_stats->gscan_wake_up_count;
+	stats->pno_complete_wake_up_count +=
+			vdev_stats->pno_complete_wake_up_count;
+	stats->pno_match_wake_up_count += vdev_stats->pno_match_wake_up_count;
+	stats->oem_response_wake_up_count +=
+			vdev_stats->oem_response_wake_up_count;
+	stats->uc_drop_wake_up_count += vdev_stats->uc_drop_wake_up_count;
+	stats->fatal_event_wake_up_count +=
+			vdev_stats->fatal_event_wake_up_count;
+	stats->pwr_save_fail_detected += vdev_stats->pwr_save_fail_detected;
+	stats->scan_11d += vdev_stats->scan_11d;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_get_psoc_wake_lock_stats(
+						struct wlan_objmgr_psoc *psoc,
+						struct wake_lock_stats *stats)
+{
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	/* iterate through all vdevs, and get wow stats from vdev_cs object */
+	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, vdev_iterator,
+				     stats, true, WLAN_CP_STATS_ID);
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_get_vdev_wake_lock_stats(
+						struct wlan_objmgr_vdev *vdev,
+						struct wake_lock_stats *stats)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+
+	wlan_vdev_obj_lock(vdev);
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		wlan_vdev_obj_unlock(vdev);
+		cp_stats_err("psoc NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	wlan_vdev_obj_unlock(vdev);
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+
+	if (!psoc_mc_stats) {
+		cp_stats_err("psoc mc stats is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	qdf_mem_copy(stats, &psoc_mc_stats->wow_stats, sizeof(*stats));
+
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_write_wow_stats(
+				struct wlan_objmgr_psoc *psoc,
+				char *buffer, uint16_t max_len, int *ret)
+{
+	QDF_STATUS status;
+	uint32_t unspecified_wake_count;
+	struct wake_lock_stats wow_stats = {0};
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	/* get stats from psoc */
+	status = ucfg_mc_cp_stats_get_psoc_wake_lock_stats(psoc, &wow_stats);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("Failed to get WoW stats");
+		return status;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	unspecified_wake_count = psoc_mc_stats->wow_unspecified_wake_up_count;
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	*ret = qdf_scnprintf(buffer, max_len,
+			     "WoW Wake Reasons\n"
+			     "\tunspecified wake count: %u\n"
+			     "\tunicast: %u\n"
+			     "\tbroadcast: %u\n"
+			     "\tIPv4 multicast: %u\n"
+			     "\tIPv6 multicast: %u\n"
+			     "\tIPv6 multicast RA: %u\n"
+			     "\tIPv6 multicast NS: %u\n"
+			     "\tIPv6 multicast NA: %u\n"
+			     "\tICMPv4: %u\n"
+			     "\tICMPv6: %u\n"
+			     "\tRSSI Breach: %u\n"
+			     "\tLow RSSI: %u\n"
+			     "\tG-Scan: %u\n"
+			     "\tPNO Complete: %u\n"
+			     "\tPNO Match: %u\n"
+			     "\tUC Drop wake_count: %u\n"
+			     "\twake count due to fatal event: %u\n"
+			     "\tOEM rsp wake_count: %u\n"
+			     "\twake count due to pwr_save_fail_detected: %u\n"
+			     "\twake count due to 11d scan: %u\n",
+			     unspecified_wake_count,
+			     wow_stats.ucast_wake_up_count,
+			     wow_stats.bcast_wake_up_count,
+			     wow_stats.ipv4_mcast_wake_up_count,
+			     wow_stats.ipv6_mcast_wake_up_count,
+			     wow_stats.ipv6_mcast_ra_stats,
+			     wow_stats.ipv6_mcast_ns_stats,
+			     wow_stats.ipv6_mcast_na_stats,
+			     wow_stats.icmpv4_count,
+			     wow_stats.icmpv6_count,
+			     wow_stats.rssi_breach_wake_up_count,
+			     wow_stats.low_rssi_wake_up_count,
+			     wow_stats.gscan_wake_up_count,
+			     wow_stats.pno_complete_wake_up_count,
+			     wow_stats.pno_match_wake_up_count,
+			     wow_stats.uc_drop_wake_up_count,
+			     wow_stats.fatal_event_wake_up_count,
+			     wow_stats.oem_response_wake_up_count,
+			     wow_stats.pwr_save_fail_detected,
+			     wow_stats.scan_11d);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_send_stats_request(struct wlan_objmgr_vdev *vdev,
+					       enum stats_req_type type,
+					       struct request_info *info)
+{
+	QDF_STATUS status;
+
+	status = ucfg_mc_cp_stats_set_pending_req(wlan_vdev_get_psoc(vdev),
+						  type, info);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_set_pending_req pdev failed: %d",
+			     status);
+		return status;
+	}
+
+	return tgt_send_mc_cp_stats_req(wlan_vdev_get_psoc(vdev), type, info);
+}
+
+#ifdef WLAN_FEATURE_BIG_DATA_STATS
+QDF_STATUS ucfg_send_big_data_stats_request(struct wlan_objmgr_vdev *vdev,
+					    enum stats_req_type type,
+					    struct request_info *info)
+{
+	QDF_STATUS status;
+
+	status = ucfg_mc_cp_stats_set_pending_req(wlan_vdev_get_psoc(vdev),
+						  type, info);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_set_pending_req pdev failed: %d",
+			     status);
+		return status;
+	}
+	return tgt_send_mc_cp_stats_req(wlan_vdev_get_psoc(vdev), type, info);
+}
+
+void ucfg_mc_cp_set_big_data_fw_support(struct wlan_objmgr_psoc *psoc,
+					bool enable)
+{
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	psoc_mc_stats->big_data_fw_support_enable = enable;
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+}
+
+void ucfg_mc_cp_get_big_data_fw_support(struct wlan_objmgr_psoc *psoc,
+					bool *enable)
+{
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	*enable = psoc_mc_stats->big_data_fw_support_enable;
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+}
+#endif
+
+QDF_STATUS ucfg_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev,
+					 int *dbm)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct pdev_mc_cp_stats *pdev_mc_stats;
+	struct pdev_cp_stats *pdev_cp_stats_priv;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct vdev_cp_stats *vdev_cp_stat;
+	uint32_t vdev_power = 0;
+
+	vdev_cp_stat = wlan_cp_stats_get_vdev_stats_obj(vdev);
+	if (vdev_cp_stat) {
+		wlan_cp_stats_vdev_obj_lock(vdev_cp_stat);
+		vdev_mc_stats = vdev_cp_stat->vdev_stats;
+		vdev_power = vdev_mc_stats->vdev_extd_stats.vdev_tx_power;
+		wlan_cp_stats_vdev_obj_unlock(vdev_cp_stat);
+		if (vdev_power) {
+			*dbm = vdev_power;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
+	if (!pdev_cp_stats_priv) {
+		cp_stats_err("pdev cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_pdev_obj_lock(pdev_cp_stats_priv);
+	pdev_mc_stats = pdev_cp_stats_priv->pdev_stats;
+	*dbm = pdev_mc_stats->max_pwr;
+	wlan_cp_stats_pdev_obj_unlock(pdev_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool ucfg_mc_cp_stats_is_req_pending(struct wlan_objmgr_psoc *psoc,
+				     enum stats_req_type type)
+{
+	uint32_t pending_req_map;
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return false;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	pending_req_map = psoc_mc_stats->pending.type_map;
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return (pending_req_map & (1 << type));
+}
+
+QDF_STATUS ucfg_mc_cp_stats_set_pending_req(struct wlan_objmgr_psoc *psoc,
+					    enum stats_req_type type,
+					    struct request_info *req)
+{
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (type >= TYPE_MAX) {
+		cp_stats_err("Invalid type index: %d", type);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	if (psoc_mc_stats->is_cp_stats_suspended) {
+		cp_stats_debug("cp stats is suspended try again after resume");
+		wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+		return QDF_STATUS_E_AGAIN;
+	}
+	psoc_mc_stats->pending.type_map |= (1 << type);
+	psoc_mc_stats->pending.req[type] = *req;
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_reset_pending_req(struct wlan_objmgr_psoc *psoc,
+					      enum stats_req_type type,
+					      struct request_info *last_req,
+					      bool *pending)
+{
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (type >= TYPE_MAX) {
+		cp_stats_err("Invalid type index: %d", type);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	if (psoc_mc_stats->pending.type_map & (1 << type)) {
+		*last_req = psoc_mc_stats->pending.req[type];
+		*pending = true;
+	} else {
+		*pending = false;
+	}
+	psoc_mc_stats->pending.type_map &= ~(1 << type);
+	qdf_mem_zero(&psoc_mc_stats->pending.req[type],
+		     sizeof(psoc_mc_stats->pending.req[type]));
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_get_pending_req(struct wlan_objmgr_psoc *psoc,
+					    enum stats_req_type type,
+					    struct request_info *info)
+{
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (type >= TYPE_MAX) {
+		cp_stats_err("Invalid type index: %d", type);
+		return QDF_STATUS_E_INVAL;
+	}
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	*info = psoc_mc_stats->pending.req[type];
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_mc_cp_stats_free_peer_stats_info_ext() - API to free peer stats info ext
+ * structure
+ * @ev: structure from where peer stats info ext needs to be freed
+ *
+ * Return: none
+ */
+static void ucfg_mc_cp_stats_free_peer_stats_info_ext(struct stats_event *ev)
+{
+	struct peer_stats_info_ext_event *peer_stats_info =
+							ev->peer_stats_info_ext;
+	uint16_t i;
+
+	for (i = 0; i < ev->num_peer_stats_info_ext; i++) {
+		qdf_mem_free(peer_stats_info->tx_pkt_per_mcs);
+		qdf_mem_free(peer_stats_info->rx_pkt_per_mcs);
+		peer_stats_info++;
+	}
+
+	qdf_mem_free(ev->peer_stats_info_ext);
+}
+
+void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev)
+{
+	if (!ev)
+		return;
+
+	qdf_mem_free(ev->pdev_stats);
+	qdf_mem_free(ev->pdev_extd_stats);
+	qdf_mem_free(ev->peer_adv_stats);
+	qdf_mem_free(ev->peer_stats);
+	qdf_mem_free(ev->cca_stats);
+	qdf_mem_free(ev->vdev_summary_stats);
+	qdf_mem_free(ev->vdev_chain_rssi);
+	qdf_mem_free(ev->peer_extended_stats);
+	ucfg_mc_cp_stats_free_peer_stats_info_ext(ev);
+	qdf_mem_free(ev->vdev_extd_stats);
+	qdf_mem_zero(ev, sizeof(*ev));
+}
+
+QDF_STATUS ucfg_mc_cp_stats_cca_stats_get(struct wlan_objmgr_vdev *vdev,
+					  struct cca_stats *cca_stats)
+{
+	struct vdev_cp_stats *vdev_cp_stats_priv;
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+
+	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
+	if (!vdev_cp_stats_priv) {
+		cp_stats_err("vdev cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
+	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
+	cca_stats->congestion = vdev_mc_stats->cca.congestion;
+	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mc_cp_stats_set_rate_flags(struct wlan_objmgr_vdev *vdev,
+					   uint32_t flags)
+{
+	struct vdev_mc_cp_stats *vdev_mc_stats;
+	struct vdev_cp_stats *vdev_cp_stats_priv;
+
+	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
+	if (!vdev_cp_stats_priv) {
+		cp_stats_err("vdev cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
+	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
+	vdev_mc_stats->tx_rate_flags = flags;
+	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void ucfg_mc_cp_stats_register_lost_link_info_cb(
+			struct wlan_objmgr_psoc *psoc,
+			void (*lost_link_cp_stats_info_cb)(void *stats_ev))
+{
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return;
+	}
+
+	psoc_cp_stats_priv->legacy_stats_cb = lost_link_cp_stats_info_cb;
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+uint8_t wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id, qdf_freq_t req_freq)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_vdev *vdev;
+	struct pdev_cp_stats *pdev_cp_stats_priv;
+	struct per_channel_stats *channel_stats;
+	struct channel_status *channel_status_list;
+	uint8_t total_channel, chan_load = 0;
+	uint8_t i;
+	uint32_t rx_clear_count = 0, cycle_count = 0;
+	bool found = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev)
+		return 0;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		cp_stats_err("pdev object is null");
+		goto release_ref;
+	}
+
+	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
+	if (!pdev_cp_stats_priv) {
+		cp_stats_err("pdev cp stats object is null");
+		goto release_ref;
+	}
+
+	channel_stats = &pdev_cp_stats_priv->pdev_stats->chan_stats;
+	channel_status_list = channel_stats->channel_status_list;
+	total_channel = channel_stats->total_channel;
+
+	for (i = 0; i < total_channel; i++) {
+		if (channel_status_list[i].channel_freq == req_freq) {
+			rx_clear_count = channel_status_list[i].rx_clear_count;
+			cycle_count = channel_status_list[i].cycle_count;
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		cp_stats_debug("no channel found for freq:%d", req_freq);
+		goto release_ref;
+	}
+
+	if (cycle_count == 0) {
+		cp_stats_debug("cycle_count is zero");
+		goto release_ref;
+	}
+
+	chan_load = ((rx_clear_count * 255) / cycle_count);
+
+	cp_stats_debug("t_chan:%d, freq:%d, rcc:%u, cc:%u, chan_load:%d",
+		       total_channel, req_freq, rx_clear_count, cycle_count,
+		       chan_load);
+
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+	return chan_load;
+}
+#endif
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+static QDF_STATUS
+ucfg_mc_cp_stats_suspend_req_handler(struct wlan_objmgr_psoc *psoc)
+{
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	psoc_mc_stats->is_cp_stats_suspended = true;
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+ucfg_mc_cp_stats_resume_req_handler(struct wlan_objmgr_psoc *psoc)
+{
+	struct psoc_mc_cp_stats *psoc_mc_stats;
+	struct psoc_cp_stats *psoc_cp_stats_priv;
+
+	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
+	if (!psoc_cp_stats_priv) {
+		cp_stats_err("psoc cp stats object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
+	psoc_mc_stats = psoc_cp_stats_priv->obj_stats;
+	psoc_mc_stats->is_cp_stats_suspended = false;
+	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+ucfg_mc_cp_stats_resume_handler(struct wlan_objmgr_psoc *psoc,
+				void *arg)
+{
+	return ucfg_mc_cp_stats_resume_req_handler(psoc);
+}
+
+static QDF_STATUS
+ucfg_mc_cp_stats_suspend_handler(struct wlan_objmgr_psoc *psoc,
+				 void *arg)
+{
+	return ucfg_mc_cp_stats_suspend_req_handler(psoc);
+}
+
+void ucfg_mc_cp_stats_register_pmo_handler(void)
+{
+	pmo_register_suspend_handler(WLAN_UMAC_COMP_CP_STATS,
+				     ucfg_mc_cp_stats_suspend_handler, NULL);
+	pmo_register_resume_handler(WLAN_UMAC_COMP_CP_STATS,
+				    ucfg_mc_cp_stats_resume_handler, NULL);
+}
+
+/**
+ * wlan_cp_stats_get_ch_width_from_chan_info - get ch_width as per num channel
+ * present in scan event
+ * @channel_stat: struct scan_chan_info
+ *
+ * Return: phy_ch_width.
+ */
+static enum phy_ch_width
+wlan_cp_stats_get_ch_width_from_chan_info(struct channel_status *channel_stat)
+{
+	enum phy_ch_width scanned_ch_width;
+
+	switch (channel_stat->subband_info.num_chan) {
+	case 1:
+		scanned_ch_width = CH_WIDTH_20MHZ;
+		break;
+	case 2:
+		scanned_ch_width = CH_WIDTH_40MHZ;
+		break;
+	case 4:
+		scanned_ch_width = CH_WIDTH_80MHZ;
+		break;
+	case 8:
+		scanned_ch_width = CH_WIDTH_160MHZ;
+		break;
+	default:
+		scanned_ch_width = CH_WIDTH_INVALID;
+		break;
+	}
+
+	return scanned_ch_width;
+}
+
+/**
+ * wlan_cp_stats_update_per_channel_stats - update per channel stats as per
+ * data present in scan event
+ * @channel_stats: per channel stats
+ * @ev_channel_stat: channel stats per scan event
+ * @freq: freq to update channel stats
+ * @rx_clear_count: rx clear count for a freq
+ *
+ * Return: none.
+ */
+static void
+wlan_cp_stats_update_per_channel_stats(struct per_channel_stats *channel_stats,
+				       struct channel_status *ev_channel_stat,
+				       uint32_t freq, uint32_t rx_clear_count)
+{
+	struct channel_status *channel_status_list;
+	uint8_t total_channel, i;
+	bool found = false;
+
+	channel_status_list = channel_stats->channel_status_list;
+	total_channel = channel_stats->total_channel;
+
+	for (i = 0; i < total_channel; i++) {
+		if (channel_status_list[i].channel_freq == freq) {
+			cp_stats_debug("update rcc: %d, cc:%d at index: %d, freq: %d",
+				       ev_channel_stat->rx_clear_count,
+				       ev_channel_stat->cycle_count, i, freq);
+
+			channel_status_list[i].rx_clear_count = rx_clear_count;
+			channel_status_list[i].cycle_count =
+					ev_channel_stat->cycle_count;
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		if (total_channel < NUM_CHANNELS) {
+			ev_channel_stat->rx_clear_count = rx_clear_count;
+			ev_channel_stat->channel_freq = freq;
+
+			cp_stats_debug("Add rcc: %d cc: %d, at index: %d, freq: %d",
+				       ev_channel_stat->rx_clear_count,
+				       ev_channel_stat->rx_clear_count,
+				       total_channel, freq);
+
+			qdf_mem_copy(&channel_status_list[total_channel++],
+				     ev_channel_stat,
+				     sizeof(*channel_status_list));
+			channel_stats->total_channel = total_channel;
+		} else {
+			cp_stats_debug("Chan cnt exceed, channel_id: %d",
+				       ev_channel_stat->channel_id);
+		}
+	}
+}
+
+/**
+ * wlan_cp_stats_update_channel_stats - wrapper api to update per channel stats
+ * as per data present in scan event
+ * @channel_stats: per channel stats
+ * @ev_channel_stat: channel stats per scan event
+ *
+ * Return: none.
+ */
+static void
+wlan_cp_stats_update_channel_stats(struct per_channel_stats *channel_stats,
+				   struct channel_status *ev_channel_stat)
+{
+	uint8_t index, freq_info_num;
+	enum phy_ch_width scanned_ch_width;
+	const struct bonded_channel_freq *range = NULL;
+	uint16_t start_freq, end_freq;
+	uint32_t rx_clear_count;
+
+	scanned_ch_width =
+		wlan_cp_stats_get_ch_width_from_chan_info(ev_channel_stat);
+	if (scanned_ch_width == CH_WIDTH_INVALID) {
+		cp_stats_debug("Invalid scanned_ch_width");
+		return;
+	}
+
+	if (scanned_ch_width == CH_WIDTH_20MHZ) {
+		start_freq = ev_channel_stat->channel_freq;
+		end_freq = ev_channel_stat->channel_freq;
+	} else {
+		range =
+		   wlan_reg_get_bonded_chan_entry(ev_channel_stat->channel_freq,
+						  scanned_ch_width, 0);
+		if (!range) {
+			cp_stats_debug("range is NULL for freq %d, ch_width %d",
+				       ev_channel_stat->channel_freq,
+				       scanned_ch_width);
+			return;
+		}
+		start_freq = range->start_freq;
+		end_freq = range->end_freq;
+	}
+
+	freq_info_num = ev_channel_stat->subband_info.num_chan;
+	index = 0;
+
+	cp_stats_debug("freq :%d bw %d, range [%d-%d], num_freq:%d",
+		       ev_channel_stat->channel_freq, scanned_ch_width,
+		       start_freq, end_freq, freq_info_num);
+
+	for (; start_freq <= end_freq;) {
+		if (index >= freq_info_num || index >= MAX_WIDE_BAND_SCAN_CHAN)
+			break;
+		rx_clear_count =
+		    ev_channel_stat->subband_info.cca_busy_subband_info[index];
+		wlan_cp_stats_update_per_channel_stats(channel_stats,
+						       ev_channel_stat,
+						       start_freq,
+						       rx_clear_count);
+
+		start_freq += BW_20_MHZ;
+		index++;
+	}
+}
+
+void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
+				    struct channel_status *ev_channel_stat,
+				    uint8_t vdev_id)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_vdev *vdev;
+	struct pdev_cp_stats *pdev_cp_stats_priv;
+	struct per_channel_stats *channel_stats;
+	struct channel_status *channel_status_list;
+	uint8_t total_channel;
+	uint8_t i;
+	bool found = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_CP_STATS_ID);
+	if (!vdev)
+		return;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+		cp_stats_err("pdev object is null");
+		return;
+	}
+
+	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
+	if (!pdev_cp_stats_priv) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+		cp_stats_err("pdev cp stats object is null");
+		return;
+	}
+
+	channel_stats = &pdev_cp_stats_priv->pdev_stats->chan_stats;
+	channel_status_list = channel_stats->channel_status_list;
+	total_channel = channel_stats->total_channel;
+
+	if (ev_channel_stat->subband_info.is_wide_band_scan) {
+		wlan_cp_stats_update_channel_stats(channel_stats,
+						   ev_channel_stat);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+		return;
+	}
+
+	for (i = 0; i < total_channel; i++) {
+		if (channel_status_list[i].channel_id ==
+		    ev_channel_stat->channel_id) {
+			if (ev_channel_stat->cmd_flags ==
+			    WMI_CHAN_InFO_END_RESP &&
+			    channel_status_list[i].cmd_flags ==
+			    WMI_CHAN_InFO_START_RESP) {
+				/* adjust to delta value for counts */
+				ev_channel_stat->rx_clear_count -=
+				    channel_status_list[i].rx_clear_count;
+				ev_channel_stat->cycle_count -=
+				    channel_status_list[i].cycle_count;
+				ev_channel_stat->rx_frame_count -=
+				    channel_status_list[i].rx_frame_count;
+				ev_channel_stat->tx_frame_count -=
+				    channel_status_list[i].tx_frame_count;
+				ev_channel_stat->bss_rx_cycle_count -=
+				    channel_status_list[i].bss_rx_cycle_count;
+			}
+			qdf_mem_copy(&channel_status_list[i], ev_channel_stat,
+				     sizeof(*channel_status_list));
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		if (total_channel < NUM_CHANNELS) {
+			qdf_mem_copy(&channel_status_list[total_channel++],
+				     ev_channel_stat,
+				     sizeof(*channel_status_list));
+			channel_stats->total_channel = total_channel;
+		} else {
+			cp_stats_err("Chan cnt exceed, channel_id=%d",
+				     ev_channel_stat->channel_id);
+		}
+	}
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+}
+
+struct channel_status *
+ucfg_mc_cp_stats_get_channel_status(struct wlan_objmgr_pdev *pdev,
+				    uint32_t chan_freq)
+{
+	struct pdev_cp_stats *pdev_cp_stats_priv;
+	struct per_channel_stats *channel_stats;
+	struct channel_status *entry;
+	uint8_t i;
+
+	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
+	if (!pdev_cp_stats_priv) {
+		cp_stats_err("pdev cp stats object is null");
+		return NULL;
+	}
+
+	channel_stats = &pdev_cp_stats_priv->pdev_stats->chan_stats;
+
+	for (i = 0; i < channel_stats->total_channel; i++) {
+		entry = &channel_stats->channel_status_list[i];
+		if (entry->channel_freq == chan_freq)
+			return entry;
+	}
+	cp_stats_err("Channel %d status info not exist", chan_freq);
+
+	return NULL;
+}
+
+void ucfg_mc_cp_stats_clear_channel_status(struct wlan_objmgr_pdev *pdev)
+{
+	struct pdev_cp_stats *pdev_cp_stats_priv;
+	struct per_channel_stats *channel_stats;
+
+	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
+	if (!pdev_cp_stats_priv) {
+		cp_stats_err("pdev cp stats object is null");
+		return;
+	}
+
+	channel_stats = &pdev_cp_stats_priv->pdev_stats->chan_stats;
+	channel_stats->total_channel = 0;
+}
+
+#endif

+ 333 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/core/inc/wlan_dlm_core.h

@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: declare internal APIs related to the denylist component
+ */
+
+#ifndef _WLAN_DLM_CORE_H_
+#define _WLAN_DLM_CORE_H_
+
+#include <wlan_dlm_main.h>
+
+#define DLM_IS_AP_AVOIDED_BY_USERSPACE(cur_node) \
+			(cur_node)->userspace_avoidlist
+
+#define DLM_IS_AP_AVOIDED_BY_DRIVER(cur_node) \
+		(cur_node)->driver_avoidlist
+
+#define DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node) \
+		(cur_node)->userspace_denylist
+
+#define DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node) \
+		(cur_node)->driver_denylist
+
+#define DLM_IS_AP_IN_MONITOR_LIST(cur_node) \
+		(cur_node)->driver_monitorlist
+
+#define DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node) \
+		(cur_node)->rssi_reject_list
+
+#define DLM_IS_AP_IN_DENYLIST(cur_node) \
+		(DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node) | \
+		 DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node) | \
+		 DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node))
+
+#define DLM_IS_AP_IN_AVOIDLIST(cur_node) \
+		(DLM_IS_AP_AVOIDED_BY_USERSPACE(cur_node) | \
+		 DLM_IS_AP_AVOIDED_BY_DRIVER(cur_node))
+
+#define IS_AP_IN_USERSPACE_DENYLIST_ONLY(cur_node) \
+		(DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node) & \
+		!(DLM_IS_AP_IN_AVOIDLIST(cur_node) | \
+		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
+		 DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node) | \
+		 DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node)))
+
+#define IS_AP_IN_MONITOR_LIST_ONLY(cur_node) \
+		(DLM_IS_AP_IN_MONITOR_LIST(cur_node) & \
+		!(DLM_IS_AP_IN_AVOIDLIST(cur_node) | \
+		 DLM_IS_AP_IN_DENYLIST(cur_node)))
+
+#define IS_AP_IN_AVOID_LIST_ONLY(cur_node) \
+		(DLM_IS_AP_IN_AVOIDLIST(cur_node) & \
+		!(DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
+		 DLM_IS_AP_IN_DENYLIST(cur_node)))
+
+#define IS_AP_IN_DRIVER_DENYLIST_ONLY(cur_node) \
+		(DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node) & \
+		!(DLM_IS_AP_IN_AVOIDLIST(cur_node) | \
+		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
+		 DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node) | \
+		 DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node)))
+
+#define IS_AP_IN_RSSI_REJECT_LIST_ONLY(cur_node) \
+		(DLM_IS_AP_IN_RSSI_REJECT_LIST(cur_node) & \
+		!(DLM_IS_AP_IN_AVOIDLIST(cur_node) | \
+		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
+		 DLM_IS_AP_DENYLISTED_BY_DRIVER(cur_node) | \
+		 DLM_IS_AP_DENYLISTED_BY_USERSPACE(cur_node)))
+
+#define IS_AP_IN_USERSPACE_AVOID_LIST_ONLY(cur_node) \
+		(DLM_IS_AP_AVOIDED_BY_USERSPACE(cur_node) & \
+		!(DLM_IS_AP_AVOIDED_BY_DRIVER(cur_node) | \
+		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
+		 DLM_IS_AP_IN_DENYLIST(cur_node)))
+
+#define IS_AP_IN_DRIVER_AVOID_LIST_ONLY(cur_node) \
+		(DLM_IS_AP_AVOIDED_BY_DRIVER(cur_node) & \
+		!(DLM_IS_AP_AVOIDED_BY_USERSPACE(cur_node) | \
+		 DLM_IS_AP_IN_MONITOR_LIST(cur_node) | \
+		 DLM_IS_AP_IN_DENYLIST(cur_node)))
+
+/**
+ * struct dlm_reject_ap_timestamp - Structure to store the reject list BSSIDs
+ * entry time stamp.
+ * @userspace_avoid_timestamp: Time when userspace adds BSSID to avoid list.
+ * @driver_avoid_timestamp: Time when driver adds BSSID to avoid list.
+ * @userspace_denylist_timestamp: Time when userspace adds BSSID to deny list.
+ * @driver_denylist_timestamp: Time when driver adds BSSID to deny list.
+ * @rssi_reject_timestamp: Time when driver adds BSSID to rssi reject list.
+ * @driver_monitor_timestamp: Time when driver adds BSSID to monitor list.
+ */
+struct dlm_reject_ap_timestamp {
+	qdf_time_t userspace_avoid_timestamp;
+	qdf_time_t driver_avoid_timestamp;
+	qdf_time_t userspace_denylist_timestamp;
+	qdf_time_t driver_denylist_timestamp;
+	qdf_time_t rssi_reject_timestamp;
+	qdf_time_t driver_monitor_timestamp;
+};
+
+/**
+ * struct dlm_reject_ap - Structure of a node added to denylist manager
+ * @node: Node of the entry
+ * @bssid: Bssid of the AP entry.
+ * @rssi_reject_params: Rssi reject params of the AP entry.
+ * @bad_bssid_counter: It represent how many times data stall happened.
+ * @ap_timestamp: AP timestamp.
+ * @reject_ap_type: consolidated bitmap of rejection types for the AP
+ * @userspace_denylist: AP in userspace denylist
+ * @driver_denylist: AP in driver denylist
+ * @userspace_avoidlist: AP in userspace avoidlist
+ * @driver_avoidlist: AP in driver avoidlist
+ * @rssi_reject_list: AP has bad RSSI
+ * @driver_monitorlist: AP is monitored
+ * @reject_ap_reason: consolidated bitmap of rejection reasons for the AP
+ * @nud_fail: NUD fail reason
+ * @sta_kickout: STA kickout reason
+ * @ho_fail: Handoff failure reason
+ * @poor_rssi: Poor RSSI reason
+ * @oce_assoc_reject: OCE association rejected reason
+ * @denylist_userspace: Userspace denylist reason
+ * @avoid_userspace: Userspace avoidlist reason
+ * @btm_disassoc_imminent: BTM disassociation imminent reason
+ * @btm_bss_termination: BTM BSS termination reason
+ * @btm_mbo_retry: BTM MBO retry reason
+ * @reassoc_rssi_reject: Reassociation RSSI rejection reason
+ * @no_more_stas: AP reached STA capacity reason
+ * @source: source of the rejection
+ * @connect_timestamp: Timestamp when the STA got connected with this BSSID
+ */
+struct dlm_reject_ap {
+	qdf_list_node_t node;
+	struct qdf_mac_addr bssid;
+	struct dlm_rssi_disallow_params rssi_reject_params;
+	uint8_t bad_bssid_counter;
+	struct dlm_reject_ap_timestamp ap_timestamp;
+	union {
+		struct {
+			uint8_t userspace_denylist:1,
+				driver_denylist:1,
+				userspace_avoidlist:1,
+				driver_avoidlist:1,
+				rssi_reject_list:1,
+				driver_monitorlist:1;
+		};
+		uint8_t reject_ap_type;
+	};
+	union {
+		struct {
+			uint32_t nud_fail:1,
+				 sta_kickout:1,
+				 ho_fail:1,
+				 poor_rssi:1,
+				 oce_assoc_reject:1,
+				 denylist_userspace:1,
+				 avoid_userspace:1,
+				 btm_disassoc_imminent:1,
+				 btm_bss_termination:1,
+				 btm_mbo_retry:1,
+				 reassoc_rssi_reject:1,
+				 no_more_stas:1;
+		};
+		uint32_t reject_ap_reason;
+	};
+	enum dlm_reject_ap_source source;
+	qdf_time_t connect_timestamp;
+};
+
+/**
+ * dlm_add_bssid_to_reject_list() - Add BSSID to the specific reject list.
+ * @pdev: Pdev object
+ * @ap_info: Ap info params such as BSSID, and the type of rejection to be done
+ *
+ * This API will add the BSSID to the reject AP list maintained by the denylist
+ * manager.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
+			     struct reject_ap_info *ap_info);
+
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * dlm_send_reject_ap_list_to_fw() - Send the denylist BSSIDs to FW
+ * @pdev: Pdev object
+ * @reject_db_list: List of denylist BSSIDs
+ * @cfg: Denylist manager cfg
+ *
+ * This API will send the denylist BSSIDs to FW for avoiding or denylisting
+ * in roaming scenarios.
+ *
+ * Return: None
+ */
+void
+dlm_send_reject_ap_list_to_fw(struct wlan_objmgr_pdev *pdev,
+			      qdf_list_t *reject_db_list,
+			      struct dlm_config *cfg);
+
+/**
+ * dlm_update_reject_ap_list_to_fw() - Send the denylist BSSIDs to FW
+ * @psoc: psoc object
+ *
+ * This API will send the denylist BSSIDs to FW.
+ *
+ * Return: None
+ */
+void dlm_update_reject_ap_list_to_fw(struct wlan_objmgr_psoc *psoc);
+#else
+static inline void dlm_send_reject_ap_list_to_fw(struct wlan_objmgr_pdev *pdev,
+						 qdf_list_t *reject_db_list,
+						 struct dlm_config *cfg)
+{
+}
+
+static inline void
+dlm_update_reject_ap_list_to_fw(struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+/**
+ * dlm_add_userspace_deny_list() - Clear already existing userspace BSSID, and
+ * add the new ones to denylist manager.
+ * @pdev: pdev object
+ * @bssid_deny_list: BSSIDs to be denylisted by userspace.
+ * @num_of_bssid: num of bssids to be denylisted.
+ *
+ * This API will Clear already existing userspace BSSID, and add the new ones
+ * to denylist manager's reject list.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+dlm_add_userspace_deny_list(struct wlan_objmgr_pdev *pdev,
+			    struct qdf_mac_addr *bssid_deny_list,
+			    uint8_t num_of_bssid);
+
+/**
+ * dlm_update_bssid_connect_params() - Inform the DLM about connect/disconnect
+ * with the current AP.
+ * @pdev: pdev object
+ * @bssid: BSSID of the AP
+ * @con_state: Connection state (connected/disconnected)
+ *
+ * This API will inform the DLM about the state with the AP so that if the AP
+ * is selected, and the connection went through, and the connection did not
+ * face any data stall till the bad bssid reset timer, DLM can remove the
+ * AP from the reject ap list maintained by it.
+ *
+ * Return: None
+ */
+void
+dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
+				struct qdf_mac_addr bssid,
+				enum dlm_connection_state con_state);
+
+/**
+ * dlm_flush_reject_ap_list() - Clear away BSSID and destroy the reject ap list
+ * @dlm_ctx: denylist manager pdev priv object
+ *
+ * This API will clear the BSSID info in the reject AP list maintained by the
+ * denylist manager, and will destroy the list as well.
+ *
+ * Return: None
+ */
+void
+dlm_flush_reject_ap_list(struct dlm_pdev_priv_obj *dlm_ctx);
+
+/**
+ * dlm_get_bssid_reject_list() - Get the BSSIDs in reject list from DLM
+ * @pdev: pdev object
+ * @reject_list: reject list to be filled (passed by caller)
+ * @max_bssid_to_be_filled: num of bssids filled in reject list by DLM
+ * @reject_ap_type: reject ap type of the BSSIDs to be filled.
+ *
+ * This API will fill the reject ap list requested by caller of type given as
+ * argument reject_ap_type, and will return the number of BSSIDs filled.
+ *
+ * Return: Unsigned integer (number of BSSIDs filled by the denylist manager)
+ */
+uint8_t
+dlm_get_bssid_reject_list(struct wlan_objmgr_pdev *pdev,
+			  struct reject_ap_config_params *reject_list,
+			  uint8_t max_bssid_to_be_filled,
+			  enum dlm_reject_ap_type reject_ap_type);
+
+/**
+ * dlm_dump_denylist_bssid - Dump denylisted bssids
+ * @pdev: pdev object
+ *
+ * Return: None
+ */
+void dlm_dump_denylist_bssid(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * dlm_is_bssid_in_reject_list - Check whether a BSSID is present in
+ * reject list or not.
+ * @pdev: pdev object
+ * @bssid: bssid to check
+ *
+ * Return: true if BSSID is present in reject list
+ */
+bool dlm_is_bssid_in_reject_list(struct wlan_objmgr_pdev *pdev,
+				 struct qdf_mac_addr *bssid);
+
+/**
+ * dlm_get_rssi_denylist_threshold() - Get rssi denylist threshold value
+ * @pdev: pdev object
+ *
+ * This API will get the RSSI denylist threshold info.
+ *
+ * Return: rssi threshold value
+ */
+int32_t
+dlm_get_rssi_denylist_threshold(struct wlan_objmgr_pdev *pdev);
+#endif

+ 178 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/core/inc/wlan_dlm_main.h

@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: declare internal APIs related to the denylist manager component
+ */
+
+#ifndef _WLAN_DLM_MAIN_H_
+#define _WLAN_DLM_MAIN_H_
+
+#include <qdf_time.h>
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_dlm_ucfg_api.h>
+
+#define dlm_fatal(params...)\
+		QDF_TRACE_FATAL(QDF_MODULE_ID_DENYLIST_MGR, params)
+#define dlm_err(params...)\
+		QDF_TRACE_ERROR(QDF_MODULE_ID_DENYLIST_MGR, params)
+#define dlm_warn(params...)\
+		QDF_TRACE_WARN(QDF_MODULE_ID_DENYLIST_MGR, params)
+#define dlm_info(params...)\
+		QDF_TRACE_INFO(QDF_MODULE_ID_DENYLIST_MGR, params)
+#define dlm_debug(params...)\
+		QDF_TRACE_DEBUG(QDF_MODULE_ID_DENYLIST_MGR, params)
+#define dlm_nofl_debug(params...)\
+		QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_DENYLIST_MGR, params)
+
+/**
+ * struct dlm_pdev_priv_obj - Pdev priv struct to store list of denylist mgr.
+ * @reject_ap_list_lock: Mutex needed to restrict two threads updating the list.
+ * @reject_ap_list: The reject Ap list which would contain the list of bad APs.
+ * @dlm_tx_ops: tx ops to send reject ap list to FW
+ */
+struct dlm_pdev_priv_obj {
+	qdf_mutex_t reject_ap_list_lock;
+	qdf_list_t reject_ap_list;
+	struct wlan_dlm_tx_ops dlm_tx_ops;
+};
+
+/**
+ * struct dlm_config - Structure to define the config params for denylist mgr.
+ * @avoid_list_exipry_time: Timer after which transition from avoid->monitor
+ * would happen for the BSSID which is in avoid list.
+ * @deny_list_exipry_time: Timer after which transition from deny->monitor
+ * would happen for the BSSID which is in deny list.
+ * @bad_bssid_counter_reset_time: Timer after which the bssid would be removed
+ * from the reject list when connected, and data stall is not seen with the AP.
+ * @bad_bssid_counter_thresh: This is the threshold count which is incremented
+ * after every NUD fail, and after this much count, the BSSID would be moved to
+ * denylist.
+ * @delta_rssi: This is the rssi threshold, only when rssi
+ * improves by this value the entry for BSSID should be removed from deny
+ * list manager list.
+ */
+struct dlm_config {
+	qdf_time_t avoid_list_exipry_time;
+	qdf_time_t deny_list_exipry_time;
+	qdf_time_t bad_bssid_counter_reset_time;
+	uint8_t bad_bssid_counter_thresh;
+	uint32_t delta_rssi;
+};
+
+/**
+ * struct dlm_psoc_priv_obj - Psoc priv structure of the denylist manager.
+ * @pdev_id: pdev id
+ * @is_suspended: is deny list manager state suspended
+ * @dlm_cfg: These are the config ini params that the user can configure.
+ */
+struct dlm_psoc_priv_obj {
+	uint8_t pdev_id;
+	bool is_suspended;
+	struct dlm_config dlm_cfg;
+};
+
+/**
+ * dlm_pdev_object_created_notification() - denylist mgr pdev create
+ * handler
+ * @pdev: pdev which is going to be created by objmgr
+ * @arg: argument for pdev create handler
+ *
+ * Register this api with objmgr to detect if pdev is created.
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+dlm_pdev_object_created_notification(struct wlan_objmgr_pdev *pdev,
+				     void *arg);
+
+/**
+ * dlm_pdev_object_destroyed_notification() - denylist mgr pdev delete handler
+ * @pdev: pdev which is going to be deleted by objmgr
+ * @arg: argument for pdev delete handler
+ *
+ * Register this api with objmgr to detect if pdev is deleted.
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+dlm_pdev_object_destroyed_notification(struct wlan_objmgr_pdev *pdev,
+				       void *arg);
+
+/**
+ * dlm_psoc_object_created_notification() - denylist mgr psoc create handler
+ * @psoc: psoc which is going to be created by objmgr
+ * @arg: argument for psoc create handler
+ *
+ * Register this api with objmgr to detect if psoc is created.
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+dlm_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc,
+				     void *arg);
+
+/**
+ * dlm_psoc_object_destroyed_notification() - denylist mgr psoc delete handler
+ * @psoc: psoc which is going to be deleted by objmgr
+ * @arg: argument for psoc delete handler.
+ *
+ * Register this api with objmgr to detect if psoc is deleted.
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+dlm_psoc_object_destroyed_notification(struct wlan_objmgr_psoc *psoc,
+				       void *arg);
+
+/**
+ * dlm_cfg_psoc_open() - denylist mgr psoc open handler
+ * @psoc: psoc which is initialized by objmgr
+ *
+ * This API will initialize the config file, and store the config while in the
+ * psoc priv object of the denylist manager.
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+dlm_cfg_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dlm_get_pdev_obj() - Get the pdev priv object of the denylist manager
+ * @pdev: pdev object
+ *
+ * Get the pdev priv object of the denylist manager
+ *
+ * Return: Pdev priv object if present, else NULL.
+ */
+struct dlm_pdev_priv_obj *
+dlm_get_pdev_obj(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * dlm_get_psoc_obj() - Get the psoc priv object of the denylist manager
+ * @psoc: psoc object
+ *
+ * Get the psoc priv object of the denylist manager
+ *
+ * Return: Psoc priv object if present, else NULL.
+ */
+struct dlm_psoc_priv_obj *
+dlm_get_psoc_obj(struct wlan_objmgr_psoc *psoc);
+
+#endif

+ 1486 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/core/src/wlan_dlm_core.c

@@ -0,0 +1,1486 @@
+/*
+ * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: declare internal APIs related to the denylist component
+ */
+
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_dlm_core.h>
+#include <qdf_mc_timer.h>
+#include <wlan_scan_public_structs.h>
+#include <wlan_scan_utils_api.h>
+#include "wlan_dlm_tgt_api.h"
+#include <wlan_cm_bss_score_param.h>
+#include <wlan_dlm_public_struct.h>
+
+#define SECONDS_TO_MS(params)       ((params) * 1000)
+#define MINUTES_TO_MS(params)       (SECONDS_TO_MS(params) * 60)
+#define RSSI_TIMEOUT_VALUE          60
+
+static void
+dlm_update_ap_info(struct dlm_reject_ap *dlm_entry, struct dlm_config *cfg,
+		   struct scan_cache_entry *scan_entry)
+{
+	qdf_time_t cur_timestamp = qdf_mc_timer_get_system_time();
+	qdf_time_t entry_add_time = 0;
+	bool update_done = false;
+	uint8_t old_reject_ap_type;
+
+	old_reject_ap_type = dlm_entry->reject_ap_type;
+
+	if (DLM_IS_AP_AVOIDED_BY_USERSPACE(dlm_entry)) {
+		entry_add_time =
+			dlm_entry->ap_timestamp.userspace_avoid_timestamp;
+
+		if ((cur_timestamp - entry_add_time) >=
+		     MINUTES_TO_MS(cfg->avoid_list_exipry_time)) {
+			/* Move AP to monitor list as avoid list time is over */
+			dlm_entry->userspace_avoidlist = false;
+			dlm_entry->avoid_userspace = false;
+			dlm_entry->driver_monitorlist = true;
+
+			dlm_entry->ap_timestamp.driver_monitor_timestamp =
+								cur_timestamp;
+			dlm_debug("Userspace avoid list timer expired, moved to monitor list");
+			update_done = true;
+		}
+	}
+
+	if (DLM_IS_AP_AVOIDED_BY_DRIVER(dlm_entry)) {
+		entry_add_time = dlm_entry->ap_timestamp.driver_avoid_timestamp;
+
+		if ((cur_timestamp - entry_add_time) >=
+		     MINUTES_TO_MS(cfg->avoid_list_exipry_time)) {
+			/* Move AP to monitor list as avoid list time is over */
+			dlm_entry->driver_avoidlist = false;
+			dlm_entry->nud_fail = false;
+			dlm_entry->sta_kickout = false;
+			dlm_entry->ho_fail = false;
+			dlm_entry->driver_monitorlist = true;
+
+			dlm_entry->ap_timestamp.driver_monitor_timestamp =
+								cur_timestamp;
+			dlm_debug("Driver avoid list timer expired, moved to monitor list");
+			update_done = true;
+		}
+	}
+
+	if (DLM_IS_AP_DENYLISTED_BY_DRIVER(dlm_entry)) {
+		entry_add_time =
+			dlm_entry->ap_timestamp.driver_denylist_timestamp;
+
+		if ((cur_timestamp - entry_add_time) >=
+		     MINUTES_TO_MS(cfg->deny_list_exipry_time)) {
+			/* Move AP to monitor list as deny list time is over */
+			dlm_entry->driver_denylist = false;
+			dlm_entry->driver_monitorlist = true;
+			dlm_entry->nud_fail = false;
+			dlm_entry->sta_kickout = false;
+			dlm_entry->ho_fail = false;
+			dlm_entry->ap_timestamp.driver_monitor_timestamp =
+								cur_timestamp;
+			dlm_debug("Driver denylist timer expired, moved to monitor list");
+			update_done = true;
+		}
+	}
+
+	if (DLM_IS_AP_IN_RSSI_REJECT_LIST(dlm_entry)) {
+		qdf_time_t entry_age = cur_timestamp -
+			    dlm_entry->ap_timestamp.rssi_reject_timestamp;
+
+		if ((dlm_entry->rssi_reject_params.retry_delay &&
+		     entry_age >= dlm_entry->rssi_reject_params.retry_delay) ||
+		    (scan_entry && scan_entry->rssi_raw >=
+		      dlm_entry->rssi_reject_params.expected_rssi)) {
+			/*
+			 * Remove from the rssi reject list as:-
+			 * 1. In case of OCE reject, both the time, and RSSI
+			 *    param are present, and one of them have improved
+			 *    now, so the STA can now connect to the AP.
+			 *
+			 * 2. In case of BTM message received from the FW,
+			 *    the STA just needs to wait for a certain time,
+			 *    hence RSSI is not a restriction (MIN RSSI needed
+			 *    in that case is filled as 0).
+			 *    Hence the above check will still pass, if BTM
+			 *    delay is over, and will fail is not. RSSI check
+			 *    for BTM message will fail (expected), as BTM does
+			 *    not care about the same.
+			 */
+			dlm_entry->poor_rssi = false;
+			dlm_entry->oce_assoc_reject = false;
+			dlm_entry->btm_bss_termination = false;
+			dlm_entry->btm_disassoc_imminent = false;
+			dlm_entry->btm_mbo_retry = false;
+			dlm_entry->no_more_stas = false;
+			dlm_entry->reassoc_rssi_reject = false;
+			dlm_entry->rssi_reject_list = false;
+			dlm_debug("Remove BSSID from rssi reject expected RSSI = %d, current RSSI = %d, retry delay required = %d ms, delay = %lu ms",
+				  dlm_entry->rssi_reject_params.expected_rssi,
+				  scan_entry ? scan_entry->rssi_raw : 0,
+				  dlm_entry->rssi_reject_params.retry_delay,
+				  entry_age);
+			update_done = true;
+		}
+	}
+
+	if (!update_done)
+		return;
+
+	dlm_debug(QDF_MAC_ADDR_FMT " Old %d Updated reject ap type = %x",
+		  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes),
+		  old_reject_ap_type,
+		  dlm_entry->reject_ap_type);
+}
+
+#define MAX_BL_TIME 255000
+
+static enum cm_denylist_action
+dlm_prune_old_entries_and_get_action(struct dlm_reject_ap *dlm_entry,
+				     struct dlm_config *cfg,
+				     struct scan_cache_entry *entry,
+				     qdf_list_t *reject_ap_list)
+{
+	dlm_update_ap_info(dlm_entry, cfg, entry);
+
+	/*
+	 * If all entities have cleared the bits of reject ap type, then
+	 * the AP is not needed in the database,(reject_ap_type should be 0),
+	 * then remove the entry from the reject ap list.
+	 */
+	if (!dlm_entry->reject_ap_type) {
+		dlm_debug(QDF_MAC_ADDR_FMT " cleared from list",
+			  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+		qdf_list_remove_node(reject_ap_list, &dlm_entry->node);
+		qdf_mem_free(dlm_entry);
+		return CM_DLM_NO_ACTION;
+	}
+
+	if (DLM_IS_AP_IN_RSSI_REJECT_LIST(dlm_entry) &&
+	    !dlm_entry->userspace_denylist && !dlm_entry->driver_denylist &&
+	    dlm_entry->rssi_reject_params.original_timeout > MAX_BL_TIME) {
+		dlm_info("Allow BSSID " QDF_MAC_ADDR_FMT " as the retry delay is greater than %u ms, expected RSSI = %d, current RSSI = %d, retry delay = %u ms original timeout %u time added %lu source %d reason %d",
+			 QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes), MAX_BL_TIME,
+			 dlm_entry->rssi_reject_params.expected_rssi,
+			 entry ? entry->rssi_raw : 0,
+			 dlm_entry->rssi_reject_params.retry_delay,
+			 dlm_entry->rssi_reject_params.original_timeout,
+			 dlm_entry->rssi_reject_params.received_time,
+			 dlm_entry->source, dlm_entry->reject_ap_reason);
+
+		if (DLM_IS_AP_IN_AVOIDLIST(dlm_entry)) {
+			dlm_debug(QDF_MAC_ADDR_FMT " in avoid list, deprioritize it",
+				  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+			return CM_DLM_AVOID;
+		}
+
+		return CM_DLM_NO_ACTION;
+	}
+	if (DLM_IS_AP_IN_DENYLIST(dlm_entry)) {
+		dlm_debug(QDF_MAC_ADDR_FMT " in denylist list, reject ap type %d removing from candidate list",
+			  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes),
+			  dlm_entry->reject_ap_type);
+
+		if (DLM_IS_AP_DENYLISTED_BY_USERSPACE(dlm_entry) ||
+		    DLM_IS_AP_IN_RSSI_REJECT_LIST(dlm_entry)) {
+			if (dlm_entry->reject_ap_reason == REASON_UNKNOWN ||
+			    dlm_entry->reject_ap_reason == REASON_NUD_FAILURE ||
+			    dlm_entry->reject_ap_reason == REASON_STA_KICKOUT ||
+			    dlm_entry->reject_ap_reason == REASON_ROAM_HO_FAILURE)
+				return CM_DLM_REMOVE;
+			else
+				return CM_DLM_FORCE_REMOVE;
+		}
+
+		return CM_DLM_REMOVE;
+	}
+
+	if (DLM_IS_AP_IN_AVOIDLIST(dlm_entry)) {
+		dlm_debug(QDF_MAC_ADDR_FMT " in avoid list, deprioritize it",
+			  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+		return CM_DLM_AVOID;
+	}
+
+	return CM_DLM_NO_ACTION;
+}
+
+static enum cm_denylist_action
+dlm_action_on_bssid(struct wlan_objmgr_pdev *pdev,
+		    struct scan_cache_entry *entry)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	struct dlm_config *cfg;
+	struct dlm_reject_ap *dlm_entry = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	QDF_STATUS status;
+	enum cm_denylist_action action = CM_DLM_NO_ACTION;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+	if (!dlm_ctx || !dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return CM_DLM_NO_ACTION;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return CM_DLM_NO_ACTION;
+	}
+
+	cfg = &dlm_psoc_obj->dlm_cfg;
+
+	qdf_list_peek_front(&dlm_ctx->reject_ap_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(&dlm_ctx->reject_ap_list, cur_node,
+				   &next_node);
+
+		dlm_entry = qdf_container_of(cur_node, struct dlm_reject_ap,
+					     node);
+
+		if (qdf_is_macaddr_equal(&dlm_entry->bssid, &entry->bssid)) {
+			action = dlm_prune_old_entries_and_get_action(dlm_entry,
+					cfg, entry, &dlm_ctx->reject_ap_list);
+			qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+			return action;
+		}
+		cur_node = next_node;
+		next_node = NULL;
+	}
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+
+	return CM_DLM_NO_ACTION;
+}
+
+enum cm_denylist_action
+wlan_denylist_action_on_bssid(struct wlan_objmgr_pdev *pdev,
+			      struct scan_cache_entry *entry)
+{
+	return dlm_action_on_bssid(pdev, entry);
+}
+
+static void
+dlm_update_avoidlist_reject_reason(struct dlm_reject_ap *entry,
+				   enum dlm_reject_ap_reason reject_reason)
+{
+	entry->nud_fail = false;
+	entry->sta_kickout = false;
+	entry->ho_fail = false;
+
+	switch (reject_reason) {
+	case REASON_NUD_FAILURE:
+		entry->nud_fail = true;
+		break;
+	case REASON_STA_KICKOUT:
+		entry->sta_kickout = true;
+		break;
+	case REASON_ROAM_HO_FAILURE:
+		entry->ho_fail = true;
+		break;
+	default:
+		dlm_err("Invalid reason passed %d", reject_reason);
+	}
+}
+
+static void
+dlm_handle_avoid_list(struct dlm_reject_ap *entry,
+		      struct dlm_config *cfg,
+		      struct reject_ap_info *ap_info)
+{
+	qdf_time_t cur_timestamp = qdf_mc_timer_get_system_time();
+
+	if (ap_info->reject_ap_type == USERSPACE_AVOID_TYPE) {
+		entry->userspace_avoidlist = true;
+		entry->avoid_userspace = true;
+		entry->ap_timestamp.userspace_avoid_timestamp = cur_timestamp;
+	} else if (ap_info->reject_ap_type == DRIVER_AVOID_TYPE) {
+		entry->driver_avoidlist = true;
+		dlm_update_avoidlist_reject_reason(entry,
+						   ap_info->reject_reason);
+		entry->ap_timestamp.driver_avoid_timestamp = cur_timestamp;
+	} else {
+		return;
+	}
+	entry->source = ap_info->source;
+	/* Update bssid info for new entry */
+	entry->bssid = ap_info->bssid;
+
+	/* Clear the monitor list bit if the AP was present in monitor list */
+	entry->driver_monitorlist = false;
+
+	/* Increment bad bssid counter as NUD failure happenend with this ap */
+	entry->bad_bssid_counter++;
+
+	/* If bad bssid counter has reached threshold, move it to denylist */
+	if (entry->bad_bssid_counter >= cfg->bad_bssid_counter_thresh) {
+		if (ap_info->reject_ap_type == USERSPACE_AVOID_TYPE)
+			entry->userspace_avoidlist = false;
+		else if (ap_info->reject_ap_type == DRIVER_AVOID_TYPE)
+			entry->driver_avoidlist = false;
+
+		/* Move AP to denylist list */
+		entry->driver_denylist = true;
+		entry->ap_timestamp.driver_denylist_timestamp = cur_timestamp;
+
+		dlm_debug(QDF_MAC_ADDR_FMT " moved to deny list with counter %d",
+			  QDF_MAC_ADDR_REF(entry->bssid.bytes),
+			  entry->bad_bssid_counter);
+		return;
+	}
+	dlm_debug("Added " QDF_MAC_ADDR_FMT " to avoid list type %d, counter %d reason %d updated reject reason %d source %d",
+		  QDF_MAC_ADDR_REF(entry->bssid.bytes), ap_info->reject_ap_type,
+		  entry->bad_bssid_counter, ap_info->reject_reason,
+		  entry->reject_ap_reason, entry->source);
+
+	entry->connect_timestamp = qdf_mc_timer_get_system_time();
+}
+
+static void
+dlm_handle_denylist(struct dlm_reject_ap *entry,
+		    struct reject_ap_info *ap_info)
+{
+	/*
+	 * No entity will denylist an AP internal to driver, so only
+	 * userspace denylist is the case to be taken care. Driver denylist
+	 * will only happen when the bad bssid counter has reached the max
+	 * threshold.
+	 */
+	entry->bssid = ap_info->bssid;
+	entry->userspace_denylist = true;
+	entry->ap_timestamp.userspace_denylist_timestamp =
+						qdf_mc_timer_get_system_time();
+
+	entry->source = ADDED_BY_DRIVER;
+	entry->denylist_userspace = true;
+	dlm_debug(QDF_MAC_ADDR_FMT " added to userspace denylist",
+		  QDF_MAC_ADDR_REF(entry->bssid.bytes));
+}
+
+static void
+dlm_update_rssi_reject_reason(struct dlm_reject_ap *entry,
+			      enum dlm_reject_ap_reason reject_reason)
+{
+	entry->poor_rssi = false;
+	entry->oce_assoc_reject = false;
+	entry->btm_bss_termination = false;
+	entry->btm_disassoc_imminent = false;
+	entry->btm_mbo_retry = false;
+	entry->no_more_stas = false;
+	entry->reassoc_rssi_reject = false;
+
+	switch (reject_reason) {
+	case REASON_ASSOC_REJECT_POOR_RSSI:
+		entry->poor_rssi = true;
+		break;
+	case REASON_ASSOC_REJECT_OCE:
+		entry->oce_assoc_reject = true;
+		break;
+	case REASON_BTM_DISASSOC_IMMINENT:
+		entry->btm_disassoc_imminent = true;
+		break;
+	case REASON_BTM_BSS_TERMINATION:
+		entry->btm_bss_termination = true;
+		break;
+	case REASON_BTM_MBO_RETRY:
+		entry->btm_mbo_retry = true;
+		break;
+	case REASON_REASSOC_RSSI_REJECT:
+		entry->reassoc_rssi_reject = true;
+		break;
+	case REASON_REASSOC_NO_MORE_STAS:
+		entry->no_more_stas = true;
+		break;
+	default:
+		dlm_err("Invalid reason passed %d", reject_reason);
+	}
+}
+
+static void
+dlm_handle_rssi_reject_list(struct dlm_reject_ap *entry,
+			    struct reject_ap_info *ap_info)
+{
+	bool bssid_newly_added;
+
+	if (entry->rssi_reject_list) {
+		bssid_newly_added = false;
+	} else {
+		entry->rssi_reject_params.source = ap_info->source;
+		entry->bssid = ap_info->bssid;
+		entry->rssi_reject_list = true;
+		bssid_newly_added = true;
+	}
+
+	entry->ap_timestamp.rssi_reject_timestamp =
+					qdf_mc_timer_get_system_time();
+	entry->rssi_reject_params = ap_info->rssi_reject_params;
+	dlm_update_rssi_reject_reason(entry, ap_info->reject_reason);
+	dlm_info(QDF_MAC_ADDR_FMT " %s to rssi reject list, expected RSSI %d retry delay %u source %d original timeout %u received time %lu reject reason %d updated reason %d",
+		 QDF_MAC_ADDR_REF(entry->bssid.bytes),
+		 bssid_newly_added ? "ADDED" : "UPDATED",
+		 entry->rssi_reject_params.expected_rssi,
+		 entry->rssi_reject_params.retry_delay,
+		 entry->rssi_reject_params.source,
+		 entry->rssi_reject_params.original_timeout,
+		 entry->rssi_reject_params.received_time,
+		 ap_info->reject_reason, entry->reject_ap_reason);
+}
+
+static void
+dlm_modify_entry(struct dlm_reject_ap *entry, struct dlm_config *cfg,
+		 struct reject_ap_info *ap_info)
+{
+	/* Modify the entry according to the ap_info */
+	switch (ap_info->reject_ap_type) {
+	case USERSPACE_AVOID_TYPE:
+	case DRIVER_AVOID_TYPE:
+		dlm_handle_avoid_list(entry, cfg, ap_info);
+		break;
+	case USERSPACE_DENYLIST_TYPE:
+		dlm_handle_denylist(entry, ap_info);
+		break;
+	case DRIVER_RSSI_REJECT_TYPE:
+		dlm_handle_rssi_reject_list(entry, ap_info);
+		break;
+	default:
+		dlm_debug("Invalid input of ap type %d",
+			  ap_info->reject_ap_type);
+	}
+}
+
+static bool
+dlm_is_bssid_present_only_in_list_type(enum dlm_reject_ap_type list_type,
+				       struct dlm_reject_ap *dlm_entry)
+{
+	switch (list_type) {
+	case USERSPACE_AVOID_TYPE:
+		return IS_AP_IN_USERSPACE_AVOID_LIST_ONLY(dlm_entry);
+	case USERSPACE_DENYLIST_TYPE:
+		return IS_AP_IN_USERSPACE_DENYLIST_ONLY(dlm_entry);
+	case DRIVER_AVOID_TYPE:
+		return IS_AP_IN_DRIVER_AVOID_LIST_ONLY(dlm_entry);
+	case DRIVER_DENYLIST_TYPE:
+		return IS_AP_IN_DRIVER_DENYLIST_ONLY(dlm_entry);
+	case DRIVER_RSSI_REJECT_TYPE:
+		return IS_AP_IN_RSSI_REJECT_LIST_ONLY(dlm_entry);
+	case DRIVER_MONITOR_TYPE:
+		return IS_AP_IN_MONITOR_LIST_ONLY(dlm_entry);
+	default:
+		dlm_debug("Wrong list type %d passed", list_type);
+		return false;
+	}
+}
+
+static bool
+dlm_is_bssid_of_type(enum dlm_reject_ap_type reject_ap_type,
+		     struct dlm_reject_ap *dlm_entry)
+{
+	switch (reject_ap_type) {
+	case USERSPACE_AVOID_TYPE:
+		return DLM_IS_AP_AVOIDED_BY_USERSPACE(dlm_entry);
+	case USERSPACE_DENYLIST_TYPE:
+		return DLM_IS_AP_DENYLISTED_BY_USERSPACE(dlm_entry);
+	case DRIVER_AVOID_TYPE:
+		return DLM_IS_AP_AVOIDED_BY_DRIVER(dlm_entry);
+	case DRIVER_DENYLIST_TYPE:
+		return DLM_IS_AP_DENYLISTED_BY_DRIVER(dlm_entry);
+	case DRIVER_RSSI_REJECT_TYPE:
+		return DLM_IS_AP_IN_RSSI_REJECT_LIST(dlm_entry);
+	case DRIVER_MONITOR_TYPE:
+		return DLM_IS_AP_IN_MONITOR_LIST(dlm_entry);
+	default:
+		dlm_err("Wrong list type %d passed", reject_ap_type);
+		return false;
+	}
+}
+
+static qdf_time_t
+dlm_get_delta_of_bssid(enum dlm_reject_ap_type list_type,
+		       struct dlm_reject_ap *dlm_entry,
+		       struct dlm_config *cfg)
+{
+	qdf_time_t cur_timestamp = qdf_mc_timer_get_system_time();
+	int32_t disallowed_time;
+	/*
+	 * For all the list types, delta would be the entry age only. Hence the
+	 * oldest entry would be removed first in case of list is full, and the
+	 * driver needs to make space for newer entries.
+	 */
+
+	switch (list_type) {
+	case USERSPACE_AVOID_TYPE:
+		return MINUTES_TO_MS(cfg->avoid_list_exipry_time) -
+			(cur_timestamp -
+			 dlm_entry->ap_timestamp.userspace_avoid_timestamp);
+	case USERSPACE_DENYLIST_TYPE:
+		return cur_timestamp -
+			  dlm_entry->ap_timestamp.userspace_denylist_timestamp;
+	case DRIVER_AVOID_TYPE:
+		return MINUTES_TO_MS(cfg->avoid_list_exipry_time) -
+			(cur_timestamp -
+			 dlm_entry->ap_timestamp.driver_avoid_timestamp);
+	case DRIVER_DENYLIST_TYPE:
+		return MINUTES_TO_MS(cfg->deny_list_exipry_time) -
+			(cur_timestamp -
+			 dlm_entry->ap_timestamp.driver_denylist_timestamp);
+
+	/*
+	 * For RSSI reject lowest delta would be the BSSID whose retry delay
+	 * is about to expire, hence the delta would be remaining duration for
+	 * de-denylisting the AP from rssi reject list.
+	 */
+	case DRIVER_RSSI_REJECT_TYPE:
+		if (dlm_entry->rssi_reject_params.retry_delay)
+			disallowed_time =
+				dlm_entry->rssi_reject_params.retry_delay -
+				(cur_timestamp -
+				dlm_entry->ap_timestamp.rssi_reject_timestamp);
+		else
+			disallowed_time =
+				(int32_t)(MINUTES_TO_MS(RSSI_TIMEOUT_VALUE) -
+				(cur_timestamp -
+				 dlm_entry->ap_timestamp.rssi_reject_timestamp)
+				 );
+		return ((disallowed_time < 0) ? 0 : disallowed_time);
+	case DRIVER_MONITOR_TYPE:
+		return cur_timestamp -
+			       dlm_entry->ap_timestamp.driver_monitor_timestamp;
+	default:
+		dlm_debug("Wrong list type %d passed", list_type);
+		return 0;
+	}
+}
+
+static bool
+dlm_is_oldest_entry(enum dlm_reject_ap_type list_type,
+		    qdf_time_t cur_node_delta,
+		    qdf_time_t oldest_node_delta)
+{
+	switch (list_type) {
+	/*
+	 * For RSSI reject, userspace avoid, driver avoid/denylist type the
+	 * lowest retry delay has to be found out hence if oldest_node_delta is
+	 * 0, mean this is the first entry and thus return true, If
+	 * oldest_node_delta is non zero, compare the delta and return true if
+	 * the cur entry has lower retry delta.
+	 */
+	case DRIVER_RSSI_REJECT_TYPE:
+	case USERSPACE_AVOID_TYPE:
+	case DRIVER_AVOID_TYPE:
+	case DRIVER_DENYLIST_TYPE:
+		if (!oldest_node_delta || cur_node_delta < oldest_node_delta)
+			return true;
+		break;
+	case USERSPACE_DENYLIST_TYPE:
+	case DRIVER_MONITOR_TYPE:
+		if (cur_node_delta > oldest_node_delta)
+			return true;
+		break;
+	default:
+		dlm_debug("Wrong list type passed %d", list_type);
+		return false;
+	}
+
+	return false;
+}
+
+static QDF_STATUS
+dlm_try_delete_bssid_in_list(qdf_list_t *reject_ap_list,
+			     enum dlm_reject_ap_type list_type,
+			     struct dlm_config *cfg)
+{
+	struct dlm_reject_ap *dlm_entry = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	struct dlm_reject_ap *oldest_dlm_entry = NULL;
+	qdf_time_t oldest_node_delta = 0;
+	qdf_time_t cur_node_delta = 0;
+
+	qdf_list_peek_front(reject_ap_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(reject_ap_list, cur_node, &next_node);
+
+		dlm_entry = qdf_container_of(cur_node, struct dlm_reject_ap,
+					     node);
+
+		if (dlm_is_bssid_present_only_in_list_type(list_type,
+							   dlm_entry)) {
+			cur_node_delta = dlm_get_delta_of_bssid(list_type,
+								dlm_entry, cfg);
+
+			if (dlm_is_oldest_entry(list_type, cur_node_delta,
+						oldest_node_delta)) {
+				/* now this is the oldest entry*/
+				oldest_dlm_entry = dlm_entry;
+				oldest_node_delta = cur_node_delta;
+			}
+		}
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	if (oldest_dlm_entry) {
+		/* Remove this entry to make space for the next entry */
+		dlm_debug("Removed " QDF_MAC_ADDR_FMT ", type = %d",
+			  QDF_MAC_ADDR_REF(oldest_dlm_entry->bssid.bytes),
+			  list_type);
+		qdf_list_remove_node(reject_ap_list, &oldest_dlm_entry->node);
+		qdf_mem_free(oldest_dlm_entry);
+		return QDF_STATUS_SUCCESS;
+	}
+	/* If the flow has reached here, that means no entry could be removed */
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+static QDF_STATUS
+dlm_remove_lowest_delta_entry(qdf_list_t *reject_ap_list,
+			      struct dlm_config *cfg)
+{
+	QDF_STATUS status;
+
+	/*
+	 * According to the Priority, the driver will try to remove the entries,
+	 * as the least priority list, that is monitor list would not penalize
+	 * the BSSIDs for connection. The priority order for the removal is:-
+	 * 1. Monitor list
+	 * 2. Driver avoid list
+	 * 3. Userspace avoid list.
+	 * 4. RSSI reject list.
+	 * 5. Driver Denylist.
+	 * 6. Userspace Denylist.
+	 */
+
+	status = dlm_try_delete_bssid_in_list(reject_ap_list,
+					      DRIVER_MONITOR_TYPE, cfg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	status = dlm_try_delete_bssid_in_list(reject_ap_list,
+					      DRIVER_AVOID_TYPE, cfg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	status = dlm_try_delete_bssid_in_list(reject_ap_list,
+					      USERSPACE_AVOID_TYPE, cfg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	status = dlm_try_delete_bssid_in_list(reject_ap_list,
+					      DRIVER_RSSI_REJECT_TYPE, cfg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	status = dlm_try_delete_bssid_in_list(reject_ap_list,
+					      DRIVER_DENYLIST_TYPE, cfg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	status = dlm_try_delete_bssid_in_list(reject_ap_list,
+					      USERSPACE_DENYLIST_TYPE, cfg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	dlm_debug("Failed to remove AP from denylist manager");
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+static enum dlm_reject_ap_reason
+dlm_get_rssi_reject_reason(struct dlm_reject_ap *dlm_entry)
+{
+	if (dlm_entry->poor_rssi)
+		return REASON_ASSOC_REJECT_POOR_RSSI;
+	else if (dlm_entry->oce_assoc_reject)
+		return REASON_ASSOC_REJECT_OCE;
+	else if (dlm_entry->btm_bss_termination)
+		return REASON_BTM_BSS_TERMINATION;
+	else if (dlm_entry->btm_disassoc_imminent)
+		return REASON_BTM_DISASSOC_IMMINENT;
+	else if (dlm_entry->btm_mbo_retry)
+		return REASON_BTM_MBO_RETRY;
+	else if (dlm_entry->no_more_stas)
+		return REASON_REASSOC_NO_MORE_STAS;
+	else if (dlm_entry->reassoc_rssi_reject)
+		return REASON_REASSOC_RSSI_REJECT;
+
+	return REASON_UNKNOWN;
+}
+
+static void
+dlm_fill_rssi_reject_params(struct dlm_reject_ap *dlm_entry,
+			    enum dlm_reject_ap_type reject_ap_type,
+			    struct reject_ap_config_params *dlm_reject_list)
+{
+	if (reject_ap_type != DRIVER_RSSI_REJECT_TYPE)
+		return;
+
+	dlm_reject_list->source = dlm_entry->rssi_reject_params.source;
+	dlm_reject_list->original_timeout =
+			dlm_entry->rssi_reject_params.original_timeout;
+	dlm_reject_list->received_time =
+			dlm_entry->rssi_reject_params.received_time;
+	dlm_reject_list->reject_reason = dlm_get_rssi_reject_reason(dlm_entry);
+	dlm_debug(QDF_MAC_ADDR_FMT " source %d original timeout %u received time %lu reject reason %d",
+		  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes),
+		  dlm_reject_list->source,
+		  dlm_reject_list->original_timeout,
+		  dlm_reject_list->received_time,
+		  dlm_reject_list->reject_reason);
+}
+
+/**
+ * dlm_find_reject_type_string() - Function to convert int to string
+ * @reject_ap_type:   dlm_reject_ap_type
+ *
+ * This function is used to convert int value of enum dlm_reject_ap_type
+ * to string format.
+ *
+ * Return: String
+ *
+ */
+static const char *
+dlm_find_reject_type_string(enum dlm_reject_ap_type reject_ap_type)
+{
+	switch (reject_ap_type) {
+	CASE_RETURN_STRING(USERSPACE_AVOID_TYPE);
+	CASE_RETURN_STRING(USERSPACE_DENYLIST_TYPE);
+	CASE_RETURN_STRING(DRIVER_AVOID_TYPE);
+	CASE_RETURN_STRING(DRIVER_DENYLIST_TYPE);
+	CASE_RETURN_STRING(DRIVER_RSSI_REJECT_TYPE);
+	CASE_RETURN_STRING(DRIVER_MONITOR_TYPE);
+	default:
+		return "REJECT_REASON_UNKNOWN";
+	}
+}
+
+/**
+ * dlm_get_reject_ap_type() - Function to find reject ap type
+ * @dlm_entry:   dlm_reject_ap
+ *
+ * This function is used to get reject ap type.
+ *
+ * Return: dlm_reject_ap_type
+ *
+ */
+static enum dlm_reject_ap_type
+dlm_get_reject_ap_type(struct dlm_reject_ap *dlm_entry)
+{
+	if (DLM_IS_AP_AVOIDED_BY_USERSPACE(dlm_entry))
+		return USERSPACE_AVOID_TYPE;
+	if (DLM_IS_AP_DENYLISTED_BY_USERSPACE(dlm_entry))
+		return USERSPACE_DENYLIST_TYPE;
+	if (DLM_IS_AP_AVOIDED_BY_DRIVER(dlm_entry))
+		return DRIVER_AVOID_TYPE;
+	if (DLM_IS_AP_DENYLISTED_BY_DRIVER(dlm_entry))
+		return DRIVER_DENYLIST_TYPE;
+	if (DLM_IS_AP_IN_RSSI_REJECT_LIST(dlm_entry))
+		return DRIVER_RSSI_REJECT_TYPE;
+	if (DLM_IS_AP_IN_MONITOR_LIST(dlm_entry))
+		return DRIVER_MONITOR_TYPE;
+
+	return REJECT_REASON_UNKNOWN;
+}
+
+bool dlm_is_bssid_in_reject_list(struct wlan_objmgr_pdev *pdev,
+				 struct qdf_mac_addr *bssid)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	struct dlm_reject_ap *dlm_entry = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	QDF_STATUS status;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	if (!dlm_ctx) {
+		dlm_err("dlm_ctx is NULL");
+		return false;
+	}
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+	if (!dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return false;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return false;
+	}
+
+	qdf_list_peek_front(&dlm_ctx->reject_ap_list, &cur_node);
+	while (cur_node) {
+		qdf_list_peek_next(&dlm_ctx->reject_ap_list, cur_node,
+				   &next_node);
+		dlm_entry =
+			qdf_container_of(cur_node, struct dlm_reject_ap, node);
+		/* Update the AP info to the latest list first */
+		dlm_update_ap_info(dlm_entry, &dlm_psoc_obj->dlm_cfg, NULL);
+		if (!dlm_entry->reject_ap_type) {
+			dlm_debug(QDF_MAC_ADDR_FMT " cleared from list",
+				  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+			qdf_list_remove_node(&dlm_ctx->reject_ap_list,
+					     &dlm_entry->node);
+			qdf_mem_free(dlm_entry);
+			cur_node = next_node;
+			next_node = NULL;
+			continue;
+		}
+
+		if (qdf_is_macaddr_equal(&dlm_entry->bssid, bssid)) {
+			dlm_debug("BSSID reject_ap_type 0x%x",
+				  dlm_entry->reject_ap_type);
+			if (DLM_IS_AP_IN_DENYLIST(dlm_entry)) {
+				dlm_debug("BSSID is present in deny list");
+				qdf_mutex_release(
+					&dlm_ctx->reject_ap_list_lock);
+				return true;
+			}
+			qdf_mutex_release(
+				&dlm_ctx->reject_ap_list_lock);
+			return false;
+		}
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+
+	return false;
+}
+
+/**
+ * dlm_dump_denylist_bssid() - Function to dump denylisted bssid
+ * @pdev:  pdev object
+ *
+ * This function is used to dump denylisted bssid along with reject
+ * ap type, source, delay and required rssi
+ *
+ * Return: None
+ *
+ */
+void dlm_dump_denylist_bssid(struct wlan_objmgr_pdev *pdev)
+{
+	struct dlm_reject_ap *dlm_entry = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	uint32_t reject_duration;
+	enum dlm_reject_ap_type reject_ap_type;
+	qdf_list_t *reject_db_list;
+	QDF_STATUS status;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+
+	if (!dlm_ctx || !dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return;
+	}
+
+	reject_db_list = &dlm_ctx->reject_ap_list;
+	qdf_list_peek_front(reject_db_list, &cur_node);
+	while (cur_node) {
+		qdf_list_peek_next(reject_db_list, cur_node, &next_node);
+
+		dlm_entry = qdf_container_of(cur_node, struct dlm_reject_ap,
+					     node);
+
+		reject_ap_type = dlm_get_reject_ap_type(dlm_entry);
+
+		reject_duration = dlm_get_delta_of_bssid(reject_ap_type,
+							 dlm_entry,
+							 &dlm_psoc_obj->dlm_cfg);
+
+		dlm_nofl_debug("DENYLIST BSSID " QDF_MAC_ADDR_FMT " type %s retry delay %dms expected RSSI %d reject reason %d rejection source %d",
+			       QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes),
+			       dlm_find_reject_type_string(reject_ap_type),
+			       reject_duration,
+			       dlm_entry->rssi_reject_params.expected_rssi,
+			       dlm_entry->reject_ap_reason,
+			       dlm_entry->rssi_reject_params.source);
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+}
+
+static void dlm_fill_reject_list(qdf_list_t *reject_db_list,
+				 struct reject_ap_config_params *reject_list,
+				 uint8_t *num_of_reject_bssid,
+				 enum dlm_reject_ap_type reject_ap_type,
+				 uint8_t max_bssid_to_be_filled,
+				 struct dlm_config *cfg)
+{
+	struct dlm_reject_ap *dlm_entry = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+
+	qdf_list_peek_front(reject_db_list, &cur_node);
+	while (cur_node) {
+		if (*num_of_reject_bssid == max_bssid_to_be_filled) {
+			dlm_debug("Max size reached in list, reject_ap_type %d",
+				  reject_ap_type);
+			return;
+		}
+		qdf_list_peek_next(reject_db_list, cur_node, &next_node);
+
+		dlm_entry = qdf_container_of(cur_node, struct dlm_reject_ap,
+					     node);
+
+		dlm_update_ap_info(dlm_entry, cfg, NULL);
+		if (!dlm_entry->reject_ap_type) {
+			dlm_debug(QDF_MAC_ADDR_FMT " cleared from list",
+				  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+			qdf_list_remove_node(reject_db_list, &dlm_entry->node);
+			qdf_mem_free(dlm_entry);
+			cur_node = next_node;
+			next_node = NULL;
+			continue;
+		}
+
+		if (dlm_is_bssid_of_type(reject_ap_type, dlm_entry)) {
+			struct reject_ap_config_params *dlm_reject_list;
+
+			dlm_reject_list = &reject_list[*num_of_reject_bssid];
+			dlm_reject_list->expected_rssi =
+				    dlm_entry->rssi_reject_params.expected_rssi;
+			dlm_reject_list->reject_duration =
+			       dlm_get_delta_of_bssid(reject_ap_type, dlm_entry,
+						      cfg);
+
+			dlm_fill_rssi_reject_params(dlm_entry, reject_ap_type,
+						    dlm_reject_list);
+			dlm_reject_list->reject_ap_type = reject_ap_type;
+			dlm_reject_list->bssid = dlm_entry->bssid;
+			(*num_of_reject_bssid)++;
+			dlm_debug("Adding BSSID " QDF_MAC_ADDR_FMT " of type %d retry delay %d expected RSSI %d, entries added = %d reject reason %d",
+				  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes),
+				  reject_ap_type,
+				  reject_list[*num_of_reject_bssid - 1].reject_duration,
+				  dlm_entry->rssi_reject_params.expected_rssi,
+				  *num_of_reject_bssid,
+				  dlm_entry->reject_ap_reason);
+		}
+		cur_node = next_node;
+		next_node = NULL;
+	}
+}
+
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD)
+void dlm_update_reject_ap_list_to_fw(struct wlan_objmgr_psoc *psoc)
+{
+	struct dlm_config *cfg;
+	struct wlan_objmgr_pdev *pdev;
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	QDF_STATUS status;
+
+	dlm_psoc_obj = dlm_get_psoc_obj(psoc);
+	if (!dlm_psoc_obj) {
+		dlm_err("DLM psoc obj NULL");
+		return;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, dlm_psoc_obj->pdev_id,
+					  WLAN_MLME_CM_ID);
+	if (!pdev) {
+		dlm_err("pdev obj NULL");
+		return;
+	}
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	if (!dlm_ctx) {
+		dlm_err("DLM pdev obj NULL");
+		goto end;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		goto end;
+	}
+
+	cfg = &dlm_psoc_obj->dlm_cfg;
+	dlm_send_reject_ap_list_to_fw(pdev, &dlm_ctx->reject_ap_list, cfg);
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+
+end:
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_MLME_CM_ID);
+}
+
+static void dlm_store_pdevid_in_dlm_psocpriv(struct wlan_objmgr_pdev *pdev)
+{
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+
+	if (!dlm_psoc_obj) {
+		dlm_err("DLM psoc obj NULL");
+		return;
+	}
+
+	dlm_psoc_obj->pdev_id = pdev->pdev_objmgr.wlan_pdev_id;
+}
+
+void
+dlm_send_reject_ap_list_to_fw(struct wlan_objmgr_pdev *pdev,
+			      qdf_list_t *reject_db_list,
+			      struct dlm_config *cfg)
+{
+	QDF_STATUS status;
+	bool is_dlm_suspended;
+	struct reject_ap_params reject_params = {0};
+
+	ucfg_dlm_psoc_get_suspended(wlan_pdev_get_psoc(pdev),
+				    &is_dlm_suspended);
+	if (is_dlm_suspended) {
+		dlm_store_pdevid_in_dlm_psocpriv(pdev);
+		dlm_debug("Failed to send reject AP list to FW as DLM is suspended");
+		return;
+	}
+
+	reject_params.bssid_list =
+			qdf_mem_malloc(sizeof(*reject_params.bssid_list) *
+				       PDEV_MAX_NUM_BSSID_DISALLOW_LIST);
+	if (!reject_params.bssid_list)
+		return;
+
+	/* The priority for filling is as below */
+	dlm_fill_reject_list(reject_db_list, reject_params.bssid_list,
+			     &reject_params.num_of_reject_bssid,
+			     USERSPACE_DENYLIST_TYPE,
+			     PDEV_MAX_NUM_BSSID_DISALLOW_LIST, cfg);
+	dlm_fill_reject_list(reject_db_list, reject_params.bssid_list,
+			     &reject_params.num_of_reject_bssid,
+			     DRIVER_DENYLIST_TYPE,
+			     PDEV_MAX_NUM_BSSID_DISALLOW_LIST, cfg);
+	dlm_fill_reject_list(reject_db_list, reject_params.bssid_list,
+			     &reject_params.num_of_reject_bssid,
+			     DRIVER_RSSI_REJECT_TYPE,
+			     PDEV_MAX_NUM_BSSID_DISALLOW_LIST, cfg);
+	dlm_fill_reject_list(reject_db_list, reject_params.bssid_list,
+			     &reject_params.num_of_reject_bssid,
+			     USERSPACE_AVOID_TYPE,
+			     PDEV_MAX_NUM_BSSID_DISALLOW_LIST, cfg);
+	dlm_fill_reject_list(reject_db_list, reject_params.bssid_list,
+			     &reject_params.num_of_reject_bssid,
+			     DRIVER_AVOID_TYPE,
+			     PDEV_MAX_NUM_BSSID_DISALLOW_LIST, cfg);
+
+	status = tgt_dlm_send_reject_list_to_fw(pdev, &reject_params);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		dlm_err("failed to send the reject Ap list to FW");
+
+	qdf_mem_free(reject_params.bssid_list);
+}
+#endif
+
+QDF_STATUS
+dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
+			     struct reject_ap_info *ap_info)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	struct dlm_config *cfg;
+	struct dlm_reject_ap *dlm_entry;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	QDF_STATUS status;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+
+	if (!dlm_ctx || !dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (qdf_is_macaddr_zero(&ap_info->bssid) ||
+	    qdf_is_macaddr_group(&ap_info->bssid)) {
+		dlm_err("Zero/Broadcast BSSID received, entry not added");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return status;
+	}
+
+	cfg = &dlm_psoc_obj->dlm_cfg;
+
+	qdf_list_peek_front(&dlm_ctx->reject_ap_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(&dlm_ctx->reject_ap_list,
+				   cur_node, &next_node);
+
+		dlm_entry = qdf_container_of(cur_node, struct dlm_reject_ap,
+					     node);
+
+		/* Update the AP info to the latest list first */
+		dlm_update_ap_info(dlm_entry, cfg, NULL);
+		if (!dlm_entry->reject_ap_type) {
+			dlm_debug(QDF_MAC_ADDR_FMT " cleared from list",
+				  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+			qdf_list_remove_node(&dlm_ctx->reject_ap_list,
+					     &dlm_entry->node);
+			qdf_mem_free(dlm_entry);
+			cur_node = next_node;
+			next_node = NULL;
+			continue;
+		}
+
+		if (qdf_is_macaddr_equal(&dlm_entry->bssid, &ap_info->bssid)) {
+			dlm_modify_entry(dlm_entry, cfg, ap_info);
+			goto end;
+		}
+
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	if (qdf_list_size(&dlm_ctx->reject_ap_list) == MAX_BAD_AP_LIST_SIZE) {
+		/* List is FULL, need to delete entries */
+		status =
+			dlm_remove_lowest_delta_entry(&dlm_ctx->reject_ap_list,
+						      cfg);
+
+		if (QDF_IS_STATUS_ERROR(status)) {
+			qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+			return status;
+		}
+	}
+
+	dlm_entry = qdf_mem_malloc(sizeof(*dlm_entry));
+	if (!dlm_entry) {
+		qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_list_insert_back(&dlm_ctx->reject_ap_list, &dlm_entry->node);
+	dlm_modify_entry(dlm_entry, cfg, ap_info);
+
+end:
+	dlm_send_reject_ap_list_to_fw(pdev, &dlm_ctx->reject_ap_list, cfg);
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+dlm_clear_userspace_denylist_info(struct wlan_objmgr_pdev *pdev)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_reject_ap *dlm_entry;
+	QDF_STATUS status;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	if (!dlm_ctx) {
+		dlm_err("dlm_ctx is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	qdf_list_peek_front(&dlm_ctx->reject_ap_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(&dlm_ctx->reject_ap_list, cur_node,
+				   &next_node);
+		dlm_entry = qdf_container_of(cur_node, struct dlm_reject_ap,
+					     node);
+
+		if (IS_AP_IN_USERSPACE_DENYLIST_ONLY(dlm_entry)) {
+			dlm_debug("removing bssid: " QDF_MAC_ADDR_FMT,
+				  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+			qdf_list_remove_node(&dlm_ctx->reject_ap_list,
+					     &dlm_entry->node);
+			qdf_mem_free(dlm_entry);
+		} else if (DLM_IS_AP_DENYLISTED_BY_USERSPACE(dlm_entry)) {
+			dlm_debug("Clearing userspace denylist bit for "
+				   QDF_MAC_ADDR_FMT,
+				   QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+			dlm_entry->userspace_denylist = false;
+			dlm_entry->denylist_userspace = false;
+		}
+		cur_node = next_node;
+		next_node = NULL;
+	}
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+dlm_add_userspace_deny_list(struct wlan_objmgr_pdev *pdev,
+			    struct qdf_mac_addr *bssid_deny_list,
+			    uint8_t num_of_bssid)
+{
+	uint8_t i = 0;
+	struct reject_ap_info ap_info;
+	QDF_STATUS status;
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	struct dlm_config *cfg;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+
+	if (!dlm_ctx || !dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Clear all the info of APs already existing in DLM first */
+	dlm_clear_userspace_denylist_info(pdev);
+	cfg = &dlm_psoc_obj->dlm_cfg;
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return status;
+	}
+
+	dlm_send_reject_ap_list_to_fw(pdev, &dlm_ctx->reject_ap_list, cfg);
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+
+	if (!bssid_deny_list || !num_of_bssid) {
+		dlm_debug("Userspace denylist/num of denylist NULL");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	for (i = 0; i < num_of_bssid; i++) {
+		qdf_mem_zero(&ap_info, sizeof(struct reject_ap_info));
+		ap_info.bssid = bssid_deny_list[i];
+		ap_info.reject_ap_type = USERSPACE_DENYLIST_TYPE;
+		ap_info.source = ADDED_BY_DRIVER;
+		ap_info.reject_reason = REASON_USERSPACE_BL;
+		status = dlm_add_bssid_to_reject_list(pdev, &ap_info);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			dlm_err("Failed to add bssid to userspace denylist");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void
+dlm_flush_reject_ap_list(struct dlm_pdev_priv_obj *dlm_ctx)
+{
+	struct dlm_reject_ap *dlm_entry = NULL;
+	QDF_STATUS status;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return;
+	}
+
+	qdf_list_peek_front(&dlm_ctx->reject_ap_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(&dlm_ctx->reject_ap_list, cur_node,
+				   &next_node);
+		dlm_entry = qdf_container_of(cur_node, struct dlm_reject_ap,
+					     node);
+		qdf_list_remove_node(&dlm_ctx->reject_ap_list,
+				     &dlm_entry->node);
+		qdf_mem_free(dlm_entry);
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	dlm_debug("DLM reject ap list flushed");
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+}
+
+uint8_t
+dlm_get_bssid_reject_list(struct wlan_objmgr_pdev *pdev,
+			  struct reject_ap_config_params *reject_list,
+			  uint8_t max_bssid_to_be_filled,
+			  enum dlm_reject_ap_type reject_ap_type)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	uint8_t num_of_reject_bssid = 0;
+	QDF_STATUS status;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+
+	if (!dlm_ctx || !dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return 0;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return 0;
+	}
+
+	dlm_fill_reject_list(&dlm_ctx->reject_ap_list, reject_list,
+			     &num_of_reject_bssid, reject_ap_type,
+			     max_bssid_to_be_filled, &dlm_psoc_obj->dlm_cfg);
+
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+
+	return num_of_reject_bssid;
+}
+
+void
+dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
+				struct qdf_mac_addr bssid,
+				enum dlm_connection_state con_state)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	QDF_STATUS status;
+	struct dlm_reject_ap *dlm_entry = NULL;
+	qdf_time_t connection_age = 0;
+	bool entry_found = false;
+	qdf_time_t max_entry_time;
+	qdf_time_t bad_bssid_reset_time;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+
+	if (!dlm_ctx || !dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return;
+	}
+
+	qdf_list_peek_front(&dlm_ctx->reject_ap_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(&dlm_ctx->reject_ap_list, cur_node,
+				   &next_node);
+		dlm_entry = qdf_container_of(cur_node, struct dlm_reject_ap,
+					     node);
+		if (!dlm_entry && next_node) {
+			cur_node = next_node;
+			next_node = NULL;
+			continue;
+		}
+
+		if (!qdf_mem_cmp(dlm_entry->bssid.bytes, bssid.bytes,
+				 QDF_MAC_ADDR_SIZE)) {
+			dlm_debug(QDF_MAC_ADDR_FMT " present in DLM reject list, updating connect info con_state = %d",
+				  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes),
+				  con_state);
+			entry_found = true;
+			break;
+		}
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	/* This means that the BSSID was not added in the reject list of DLM */
+	if (!entry_found || !dlm_entry) {
+		qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+		return;
+	}
+	switch (con_state) {
+	case DLM_AP_CONNECTED:
+		dlm_entry->connect_timestamp = qdf_mc_timer_get_system_time();
+		break;
+	case DLM_AP_DISCONNECTED:
+		/* Update the dlm info first */
+		dlm_update_ap_info(dlm_entry, &dlm_psoc_obj->dlm_cfg, NULL);
+
+		max_entry_time = dlm_entry->connect_timestamp;
+		if (dlm_entry->driver_denylist) {
+			max_entry_time =
+			   dlm_entry->ap_timestamp.driver_denylist_timestamp;
+		} else if (dlm_entry->driver_avoidlist) {
+			max_entry_time =
+			 QDF_MAX(dlm_entry->ap_timestamp.driver_avoid_timestamp,
+				 dlm_entry->connect_timestamp);
+		}
+		connection_age = qdf_mc_timer_get_system_time() -
+							max_entry_time;
+		bad_bssid_reset_time =
+			dlm_psoc_obj->dlm_cfg.bad_bssid_counter_reset_time;
+		if (connection_age > SECONDS_TO_MS(bad_bssid_reset_time)) {
+			dlm_entry->driver_avoidlist = false;
+			dlm_entry->driver_denylist = false;
+			dlm_entry->driver_monitorlist = false;
+			dlm_entry->userspace_avoidlist = false;
+			dlm_debug("updated reject ap type %d ",
+				  dlm_entry->reject_ap_type);
+			if (!dlm_entry->reject_ap_type) {
+				dlm_debug("Bad Bssid timer expired/AP cleared from all denylisting, removed " QDF_MAC_ADDR_FMT " from list",
+					  QDF_MAC_ADDR_REF(dlm_entry->bssid.bytes));
+				qdf_list_remove_node(&dlm_ctx->reject_ap_list,
+						     &dlm_entry->node);
+				qdf_mem_free(dlm_entry);
+				dlm_send_reject_ap_list_to_fw(pdev,
+					&dlm_ctx->reject_ap_list,
+					&dlm_psoc_obj->dlm_cfg);
+			}
+		}
+		break;
+	default:
+		dlm_debug("Invalid AP connection state received %d", con_state);
+	};
+
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+}
+
+int32_t dlm_get_rssi_denylist_threshold(struct wlan_objmgr_pdev *pdev)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	struct dlm_config *cfg;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+
+	if (!dlm_ctx || !dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return 0;
+	}
+
+	cfg = &dlm_psoc_obj->dlm_cfg;
+	return cfg->delta_rssi;
+}
+

+ 190 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/core/src/wlan_dlm_main.c

@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_dlm_main.c
+ *
+ * WLAN Denylist Mgr related APIs
+ *
+ */
+
+/* Include files */
+
+#include "target_if_dlm.h"
+#include <wlan_dlm_ucfg_api.h>
+#include "cfg_ucfg_api.h"
+#include <wlan_dlm_core.h>
+
+struct dlm_pdev_priv_obj *
+dlm_get_pdev_obj(struct wlan_objmgr_pdev *pdev)
+{
+	struct dlm_pdev_priv_obj *dlm_pdev_obj;
+
+	dlm_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
+						  WLAN_UMAC_COMP_DENYLIST_MGR);
+
+	return dlm_pdev_obj;
+}
+
+struct dlm_psoc_priv_obj *
+dlm_get_psoc_obj(struct wlan_objmgr_psoc *psoc)
+{
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+
+	dlm_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+						  WLAN_UMAC_COMP_DENYLIST_MGR);
+
+	return dlm_psoc_obj;
+}
+
+QDF_STATUS
+dlm_pdev_object_created_notification(struct wlan_objmgr_pdev *pdev,
+				     void *arg)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	QDF_STATUS status;
+
+	dlm_ctx = qdf_mem_malloc(sizeof(*dlm_ctx));
+
+	if (!dlm_ctx)
+		return QDF_STATUS_E_FAILURE;
+
+	status = qdf_mutex_create(&dlm_ctx->reject_ap_list_lock);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("Failed to create mutex");
+		qdf_mem_free(dlm_ctx);
+		return status;
+	}
+	qdf_list_create(&dlm_ctx->reject_ap_list, MAX_BAD_AP_LIST_SIZE);
+
+	target_if_dlm_register_tx_ops(&dlm_ctx->dlm_tx_ops);
+	status = wlan_objmgr_pdev_component_obj_attach(pdev,
+						   WLAN_UMAC_COMP_DENYLIST_MGR,
+						   dlm_ctx,
+						   QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("Failed to attach pdev_ctx with pdev");
+		qdf_list_destroy(&dlm_ctx->reject_ap_list);
+		qdf_mutex_destroy(&dlm_ctx->reject_ap_list_lock);
+		qdf_mem_free(dlm_ctx);
+	}
+
+	return status;
+}
+
+QDF_STATUS
+dlm_pdev_object_destroyed_notification(struct wlan_objmgr_pdev *pdev,
+				       void *arg)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+
+	if (!dlm_ctx) {
+		dlm_err("DLM Pdev obj is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Clear away the memory allocated for the bad BSSIDs */
+	dlm_flush_reject_ap_list(dlm_ctx);
+	qdf_list_destroy(&dlm_ctx->reject_ap_list);
+	qdf_mutex_destroy(&dlm_ctx->reject_ap_list_lock);
+
+	wlan_objmgr_pdev_component_obj_detach(pdev,
+					      WLAN_UMAC_COMP_DENYLIST_MGR,
+					      dlm_ctx);
+	qdf_mem_free(dlm_ctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+dlm_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc,
+				     void *arg)
+{
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	QDF_STATUS status;
+
+	dlm_psoc_obj = qdf_mem_malloc(sizeof(*dlm_psoc_obj));
+
+	if (!dlm_psoc_obj)
+		return QDF_STATUS_E_FAILURE;
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+						   WLAN_UMAC_COMP_DENYLIST_MGR,
+						   dlm_psoc_obj,
+						   QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("Failed to attach psoc_ctx with psoc");
+		qdf_mem_free(dlm_psoc_obj);
+	}
+
+	return status;
+}
+
+QDF_STATUS
+dlm_psoc_object_destroyed_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+
+	dlm_psoc_obj = dlm_get_psoc_obj(psoc);
+
+	if (!dlm_psoc_obj) {
+		dlm_err("DLM psoc obj NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	wlan_objmgr_psoc_component_obj_detach(psoc,
+					      WLAN_UMAC_COMP_DENYLIST_MGR,
+					      dlm_psoc_obj);
+	qdf_mem_free(dlm_psoc_obj);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void
+dlm_init_cfg(struct wlan_objmgr_psoc *psoc, struct dlm_config *dlm_cfg)
+{
+	dlm_cfg->avoid_list_exipry_time =
+				cfg_get(psoc, CFG_AVOID_LIST_EXPIRY_TIME);
+	dlm_cfg->deny_list_exipry_time =
+				cfg_get(psoc, CFG_DENY_LIST_EXPIRY_TIME);
+	dlm_cfg->bad_bssid_counter_reset_time =
+				cfg_get(psoc, CFG_BAD_BSSID_RESET_TIME);
+	dlm_cfg->bad_bssid_counter_thresh =
+				cfg_get(psoc, CFG_BAD_BSSID_COUNTER_THRESHOLD);
+	dlm_cfg->delta_rssi =
+				cfg_get(psoc, CFG_DENYLIST_RSSI_THRESHOLD);
+}
+
+QDF_STATUS
+dlm_cfg_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+
+	dlm_psoc_obj = dlm_get_psoc_obj(psoc);
+
+	if (!dlm_psoc_obj) {
+		dlm_err("DLM psoc obj NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dlm_init_cfg(psoc, &dlm_psoc_obj->dlm_cfg);
+
+	return QDF_STATUS_SUCCESS;
+}

+ 176 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/cfg_dlm.h

@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: This file contains ini params for denylist mgr component
+ */
+
+#ifndef __CFG_DLM_H_
+#define __CFG_DLM_H_
+
+#ifdef FEATURE_DENYLIST_MGR
+
+/*
+ * <ini>
+ * avoid_list_expiry_time - Config Param to move AP from avoid to monitor list.
+ * @Min: 1 minutes
+ * @Max: 300 minutes
+ * @Default: 5 minutes
+ *
+ * This ini is used to specify the time after which the BSSID which is in the
+ * avoid list should be moved to monitor list, assuming that the AP or the
+ * gateway with which the data stall happenend might have recovered, and now
+ * the STA can give another chance to connect to the AP.
+ *
+ * Supported Feature: Data Stall Recovery
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_AVOID_LIST_EXPIRY_TIME CFG_INI_UINT( \
+				"avoid_list_expiry_time", \
+				1, \
+				300, \
+				5, \
+				CFG_VALUE_OR_DEFAULT, \
+				"avoid list expiry")
+
+/*
+ * <ini>
+ * bad_bssid_counter_thresh - Threshold to move the Ap from avoid to denylist.
+ * @Min: 2
+ * @Max: 100
+ * @Default: 3
+ *
+ * This ini is used to specify the threshld after which the BSSID which is in
+ * the avoid list should be moved to deny list, assuming that the AP or the
+ * gateway with which the data stall happenend has no recovered, and now
+ * the STA got the NUD failure again with the BSSID
+ *
+ * Supported Feature: Data Stall Recovery
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BAD_BSSID_COUNTER_THRESHOLD CFG_INI_UINT( \
+				"bad_bssid_counter_thresh", \
+				2, \
+				100, \
+				3, \
+				CFG_VALUE_OR_DEFAULT, \
+				"bad bssid counter thresh")
+
+/*
+ * <ini>
+ * deny_list_expiry_time - Config Param to move AP from denylist to monitor
+ * list.
+ * @Min: 1 minutes
+ * @Max: 600 minutes
+ * @Default: 10 minutes
+ *
+ * This ini is used to specify the time after which the BSSID which is in the
+ * deny list should be moved to monitor list, assuming that the AP or the
+ * gateway with which the data stall happenend might have recovered, and now
+ * the STA can give another chance to connect to the AP.
+ *
+ * Supported Feature: Data Stall Recovery
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DENY_LIST_EXPIRY_TIME CFG_INI_UINT( \
+				"black_list_expiry_time", \
+				1, \
+				600, \
+				10, \
+				CFG_VALUE_OR_DEFAULT, \
+				"deny list expiry")
+
+/*
+ * <ini>
+ * bad_bssid_reset_time - Config Param to specify time after which AP would be
+ * removed from monitor/avoid when connected.
+ * @Min: 30 seconds
+ * @Max: 1 minute
+ * @Default: 30 seconds
+ *
+ * This ini is used to specify the time after which the BSSID which is in the
+ * avoid or monitor list should be removed from the respective list, if the
+ * data stall has not happened till the mentioned time after connection to the
+ * AP. That means that the AP has recovered from the previous state where
+ * data stall was observed with it, and was moved to avoid list.
+ *
+ * Supported Feature: Data Stall Recovery
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BAD_BSSID_RESET_TIME CFG_INI_UINT( \
+				"bad_bssid_reset_time", \
+				30, \
+				60, \
+				30, \
+				CFG_VALUE_OR_DEFAULT, \
+				"bad bssid reset time")
+
+/*
+ * <ini>
+ * delta_rssi - RSSI threshold value, only when AP rssi improves
+ * by threshold value entry would be removed from denylist manager and assoc
+ * req would be sent by FW.
+ * @Min: 0
+ * @Max: 10
+ * @Default: 5
+ *
+ * This ini is used to specify the rssi threshold value, after rssi improves
+ * by threshold the BSSID which is in the denylist manager list should be
+ * removed from the respective list.
+ *
+ * Supported Feature: Customer requirement
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_DENYLIST_RSSI_THRESHOLD CFG_INI_INT( \
+			"delta_rssi", \
+			0, \
+			10, \
+			5, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Configure delta RSSI")
+
+#define CFG_DENYLIST_MGR_ALL \
+	CFG(CFG_AVOID_LIST_EXPIRY_TIME) \
+	CFG(CFG_BAD_BSSID_COUNTER_THRESHOLD) \
+	CFG(CFG_DENY_LIST_EXPIRY_TIME) \
+	CFG(CFG_BAD_BSSID_RESET_TIME) \
+	CFG(CFG_DENYLIST_RSSI_THRESHOLD)
+
+#else
+
+#define CFG_DENYLIST_MGR_ALL
+
+#endif /* FEATURE_DENYLIST_MGR */
+
+#endif /* __CFG_DENYLIST_MGR */

+ 173 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/wlan_dlm_api.h

@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: declare public APIs exposed by the denylist manager component
+ */
+
+#ifndef _WLAN_DLM_API_H_
+#define _WLAN_DLM_API_H_
+
+#include "qdf_types.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include <wlan_dlm_public_struct.h>
+
+#ifdef FEATURE_DENYLIST_MGR
+#include "wlan_dlm_core.h"
+
+/**
+ * wlan_dlm_add_bssid_to_reject_list() - Add BSSID to the specific reject list.
+ * @pdev: Pdev object
+ * @ap_info: Ap info params such as BSSID, and the type of rejection to be done
+ *
+ * This API will add the BSSID to the reject AP list maintained by the denylist
+ * manager.
+ */
+static inline QDF_STATUS
+wlan_dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
+				  struct reject_ap_info *ap_info)
+{
+	return dlm_add_bssid_to_reject_list(pdev, ap_info);
+}
+
+/**
+ * wlan_dlm_update_bssid_connect_params() - Inform the DLM about connect or
+ * disconnect with the current AP.
+ * @pdev: pdev object
+ * @bssid: BSSID of the AP
+ * @con_state: Connection state (connected/disconnected)
+ *
+ * This API will inform the DLM about the state with the AP so that if the AP
+ * is selected, and the connection went through, and the connection did not
+ * face any data stall till the bad bssid reset timer, DLM can remove the
+ * AP from the reject ap list maintained by it.
+ *
+ * Return: None
+ */
+static inline void
+wlan_dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
+				     struct qdf_mac_addr bssid,
+				     enum dlm_connection_state con_state)
+{
+	return dlm_update_bssid_connect_params(pdev, bssid, con_state);
+}
+
+/**
+ * wlan_dlm_get_bssid_reject_list() - Get the BSSIDs in reject list from DLM
+ * @pdev: pdev object
+ * @reject_list: reject list to be filled (passed by caller)
+ * @max_bssid_to_be_filled: num of bssids filled in reject list by DLM
+ * @reject_ap_type: reject ap type of the BSSIDs to be filled.
+ *
+ * This API is a wrapper to an API of denylist manager which will fill the
+ * reject ap list requested by caller of type given as argument reject_ap_type,
+ * and will return the number of BSSIDs filled.
+ *
+ * Return: Unsigned integer (number of BSSIDs filled by the denylist manager)
+ */
+static inline uint8_t
+wlan_dlm_get_bssid_reject_list(struct wlan_objmgr_pdev *pdev,
+			       struct reject_ap_config_params *reject_list,
+			       uint8_t max_bssid_to_be_filled,
+			       enum dlm_reject_ap_type reject_ap_type)
+{
+	return dlm_get_bssid_reject_list(pdev, reject_list,
+					 max_bssid_to_be_filled,
+					 reject_ap_type);
+}
+
+/**
+ * wlan_dlm_is_bssid_in_reject_list() - Check whether a BSSID is present in
+ * reject list or not
+ * @pdev: pdev object
+ * @bssid: bssid to check
+ *
+ * Return: true if BSSID is present in reject list
+ */
+static inline bool
+wlan_dlm_is_bssid_in_reject_list(struct wlan_objmgr_pdev *pdev,
+				 struct qdf_mac_addr *bssid)
+{
+	return dlm_is_bssid_in_reject_list(pdev, bssid);
+}
+
+/**
+ * wlan_dlm_dump_denylist_bssid() - dump the denylisted BSSIDs from DLM
+ * @pdev: pdev object
+ *
+ * Return: None
+ */
+static inline void
+wlan_dlm_dump_denylist_bssid(struct wlan_objmgr_pdev *pdev)
+{
+	return dlm_dump_denylist_bssid(pdev);
+}
+
+/**
+ * wlan_dlm_get_rssi_denylist_threshold() - Get the RSSI denylist threshold
+ * @pdev: pdev object
+ *
+ * This API will get the rssi denylist threshold value configured via
+ * CFG_DENYLIST_RSSI_THRESHOLD.
+ *
+ * Return: int32_t (threshold value)
+ */
+static inline int32_t
+wlan_dlm_get_rssi_denylist_threshold(struct wlan_objmgr_pdev *pdev)
+{
+	return dlm_get_rssi_denylist_threshold(pdev);
+}
+
+#else
+static inline bool
+wlan_dlm_is_bssid_in_reject_list(struct wlan_objmgr_pdev *pdev,
+				 struct qdf_mac_addr *bssid)
+{
+	return false;
+}
+
+static inline QDF_STATUS
+wlan_dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
+				  struct reject_ap_info *ap_info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline uint8_t
+wlan_dlm_get_bssid_reject_list(struct wlan_objmgr_pdev *pdev,
+			       struct reject_ap_config_params *reject_list,
+			       uint8_t max_bssid_to_be_filled,
+			       enum dlm_reject_ap_type reject_ap_type)
+{
+	return 0;
+}
+
+static inline void
+wlan_dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
+				     struct qdf_mac_addr bssid,
+				     enum dlm_connection_state con_state)
+{
+}
+
+static inline int32_t
+wlan_dlm_get_rssi_denylist_threshold(struct wlan_objmgr_pdev *pdev)
+{
+	return 0;
+}
+#endif
+#endif

+ 186 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/wlan_dlm_public_struct.h

@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: define public structures of denylist mgr.
+ */
+
+#ifndef _WLAN_DLM_PUBLIC_STRUCT_H
+#define _WLAN_DLM_PUBLIC_STRUCT_H
+
+#include <qdf_types.h>
+#include "wlan_objmgr_pdev_obj.h"
+
+#define MAX_BAD_AP_LIST_SIZE               28
+#define MAX_RSSI_AVOID_BSSID_LIST          10
+#define PDEV_MAX_NUM_BSSID_DISALLOW_LIST   28
+
+/**
+ * enum dlm_reject_ap_source - Source of adding BSSID to DLM
+ * @ADDED_BY_DRIVER: Source adding this BSSID is driver
+ * @ADDED_BY_TARGET: Source adding this BSSID is target
+ */
+enum dlm_reject_ap_source {
+	ADDED_BY_DRIVER = 1,
+	ADDED_BY_TARGET,
+};
+
+/**
+ * struct dlm_rssi_disallow_params - structure to specify params for RSSI
+ * reject
+ * @retry_delay: Time before which the AP doesn't expect a connection.
+ * @expected_rssi: RSSI less than which only the STA should try association
+ * @received_time: Time at which the AP was added to denylist.
+ * @original_timeout: Original timeout which the AP sent while denylisting.
+ * @source: Source of adding this BSSID to RSSI reject list
+ */
+struct dlm_rssi_disallow_params {
+	uint32_t retry_delay;
+	int8_t expected_rssi;
+	qdf_time_t received_time;
+	uint32_t original_timeout;
+	enum dlm_reject_ap_source source;
+};
+
+/**
+ * enum dlm_reject_ap_type - Rejection type of the AP
+ * @USERSPACE_AVOID_TYPE: userspace wants the AP to be avoided.
+ * @USERSPACE_DENYLIST_TYPE: userspace wants the AP to be denylisted.
+ * @DRIVER_AVOID_TYPE: driver wants the AP to be avoided.
+ * @DRIVER_DENYLIST_TYPE: driver wants the AP to be denylisted.
+ * @DRIVER_RSSI_REJECT_TYPE: driver wants the AP to be in driver rssi
+ * reject.
+ * @DRIVER_MONITOR_TYPE: driver wants the AP to be in monitor list.
+ * @REJECT_REASON_UNKNOWN: Rejection reason unknown
+ */
+enum dlm_reject_ap_type {
+	USERSPACE_AVOID_TYPE     = 0,
+	USERSPACE_DENYLIST_TYPE  = 1,
+	DRIVER_AVOID_TYPE        = 2,
+	DRIVER_DENYLIST_TYPE     = 3,
+	DRIVER_RSSI_REJECT_TYPE  = 4,
+	DRIVER_MONITOR_TYPE      = 5,
+	REJECT_REASON_UNKNOWN    = 6,
+};
+
+/**
+ * enum dlm_reject_ap_reason - Rejection reason for adding BSSID to DLM
+ * @REASON_UNKNOWN: Unknown reason
+ * @REASON_NUD_FAILURE: NUD failure happened with this BSSID
+ * @REASON_STA_KICKOUT: STA kickout happened with this BSSID
+ * @REASON_ROAM_HO_FAILURE: HO failure happenend with this BSSID
+ * @REASON_ASSOC_REJECT_POOR_RSSI: assoc rsp with reason 71 received from
+ * AP.
+ * @REASON_ASSOC_REJECT_OCE: OCE assoc reject received from the AP.
+ * @REASON_USERSPACE_BL: Userspace wants to denylist this AP.
+ * @REASON_USERSPACE_AVOID_LIST: Userspace wants to avoid this AP.
+ * @REASON_BTM_DISASSOC_IMMINENT: BTM IE received with disassoc imminent
+ * set.
+ * @REASON_BTM_BSS_TERMINATION: BTM IE received with BSS termination set.
+ * @REASON_BTM_MBO_RETRY: BTM IE received from AP with MBO retry set.
+ * @REASON_REASSOC_RSSI_REJECT: Re-Assoc resp received with reason code 34
+ * @REASON_REASSOC_NO_MORE_STAS: Re-assoc reject received with reason code
+ * 17
+ */
+enum dlm_reject_ap_reason {
+	REASON_UNKNOWN = 0,
+	REASON_NUD_FAILURE,
+	REASON_STA_KICKOUT,
+	REASON_ROAM_HO_FAILURE,
+	REASON_ASSOC_REJECT_POOR_RSSI,
+	REASON_ASSOC_REJECT_OCE,
+	REASON_USERSPACE_BL,
+	REASON_USERSPACE_AVOID_LIST,
+	REASON_BTM_DISASSOC_IMMINENT,
+	REASON_BTM_BSS_TERMINATION,
+	REASON_BTM_MBO_RETRY,
+	REASON_REASSOC_RSSI_REJECT,
+	REASON_REASSOC_NO_MORE_STAS,
+};
+
+/**
+ * enum dlm_connection_state - State with AP (Connected, Disconnected)
+ * @DLM_AP_CONNECTED: Connected with the AP
+ * @DLM_AP_DISCONNECTED: Disconnected with the AP
+ */
+enum dlm_connection_state {
+	DLM_AP_CONNECTED,
+	DLM_AP_DISCONNECTED,
+};
+
+/**
+ * struct reject_ap_config_params - Structure to send reject ap list to FW
+ * @bssid: BSSID of the AP
+ * @reject_ap_type: Type of the rejection done with the BSSID
+ * @reject_duration: time left till the AP is in the reject list.
+ * @expected_rssi: expected RSSI when the AP expects the connection to be
+ * made.
+ * @reject_reason: reason to add the BSSID to DLM
+ * @source: Source of adding the BSSID to DLM
+ * @received_time: Time at which the AP was added to denylist.
+ * @original_timeout: Original timeout which the AP sent while denylisting.
+ */
+struct reject_ap_config_params {
+	struct qdf_mac_addr bssid;
+	enum dlm_reject_ap_type reject_ap_type;
+	uint32_t reject_duration;
+	int32_t expected_rssi;
+	enum dlm_reject_ap_reason reject_reason;
+	enum dlm_reject_ap_source source;
+	qdf_time_t received_time;
+	uint32_t original_timeout;
+};
+
+/**
+ * struct reject_ap_params - Struct to send bssid list and there num to FW
+ * @num_of_reject_bssid: num of bssid params there in bssid config.
+ * @bssid_list: Pointer to the bad bssid list
+ */
+struct reject_ap_params {
+	uint8_t num_of_reject_bssid;
+	struct reject_ap_config_params *bssid_list;
+};
+
+/**
+ * struct wlan_dlm_tx_ops - structure of tx operation function
+ * pointers for denylist manager component
+ * @dlm_send_reject_ap_list: send reject ap list to fw
+ */
+struct wlan_dlm_tx_ops {
+	QDF_STATUS (*dlm_send_reject_ap_list)(struct wlan_objmgr_pdev *pdev,
+					struct reject_ap_params *reject_params);
+};
+
+/**
+ * struct reject_ap_info - structure to specify the reject ap info.
+ * @bssid: BSSID of the AP.
+ * @rssi_reject_params: RSSI reject params of the AP is of type RSSI reject
+ * @reject_ap_type: Reject type of AP (eg. avoid, denylist, rssi reject
+ * etc.)
+ * @reject_reason: reason to add the BSSID to DLM
+ * @source: Source of adding the BSSID to DLM
+ */
+struct reject_ap_info {
+	struct qdf_mac_addr bssid;
+	struct dlm_rssi_disallow_params rssi_reject_params;
+	enum dlm_reject_ap_type reject_ap_type;
+	enum dlm_reject_ap_reason reject_reason;
+	enum dlm_reject_ap_source source;
+};
+
+#endif

+ 42 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/wlan_dlm_tgt_api.h

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Declare public API for denylist manager to interact with target/WMI
+ */
+
+#ifndef _WLAN_DLM_TGT_API_H
+#define _WLAN_DLM_TGT_API_H
+
+#include "wlan_dlm_main.h"
+
+/**
+ * tgt_dlm_send_reject_list_to_fw() - API to send the reject ap list to FW.
+ * @pdev: pdev object
+ * @reject_params: Reject params contains the bssid list, and num of bssids
+ *
+ * This API will send the reject AP list maintained by the denylist manager
+ * to the target.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+tgt_dlm_send_reject_list_to_fw(struct wlan_objmgr_pdev *pdev,
+			       struct reject_ap_params *reject_params);
+
+#endif

+ 222 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/inc/wlan_dlm_ucfg_api.h

@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: declare UCFG APIs exposed by the denylist manager component
+ */
+
+#ifndef _WLAN_DLM_UCFG_H_
+#define _WLAN_DLM_UCFG_H_
+
+#include "qdf_types.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include <wlan_dlm_public_struct.h>
+
+#ifdef FEATURE_DENYLIST_MGR
+
+/**
+ * ucfg_dlm_init() - initialize denylist mgr context
+ *
+ * This function initializes the denylist mgr context
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_dlm_init(void);
+
+/**
+ * ucfg_dlm_deinit() - De initialize denylist mgr context
+ *
+ * This function De initializes denylist mgr context
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_dlm_deinit(void);
+
+/**
+ * ucfg_dlm_psoc_set_suspended() - API to set denylist mgr state suspended
+ * @psoc: pointer to psoc object
+ * @state: state to be set
+ *
+ * This function sets denylist mgr state to suspended
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_dlm_psoc_set_suspended(struct wlan_objmgr_psoc *psoc,
+				       bool state);
+
+/**
+ * ucfg_dlm_psoc_get_suspended() - API to get denylist mgr state suspended
+ * @psoc: pointer to psoc object
+ * @state: pointer to get suspend state of denylist manager
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_dlm_psoc_get_suspended(struct wlan_objmgr_psoc *psoc,
+				       bool *state);
+
+/**
+ * ucfg_dlm_psoc_open() - API to initialize the cfg when psoc is initialized.
+ * @psoc: psoc object
+ *
+ * This function initializes the config of denylist mgr.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_dlm_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_dlm_psoc_close() - API to deinit the dlm when psoc is deinitialized.
+ * @psoc: psoc object
+ *
+ * This function deinits the dlm psoc object.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_dlm_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_dlm_add_userspace_deny_list() - Clear already existing userspace BSSID,
+ * and add the new ones to denylist manager.
+ * @pdev: pdev object
+ * @bssid_deny_list: BSSIDs to be denylisted by userspace.
+ * @num_of_bssid: num of bssids to be denylisted.
+ *
+ * This API clear already existing userspace BSSID, and add the new ones to
+ * denylist manager
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error.
+ */
+QDF_STATUS
+ucfg_dlm_add_userspace_deny_list(struct wlan_objmgr_pdev *pdev,
+				 struct qdf_mac_addr *bssid_deny_list,
+				 uint8_t num_of_bssid);
+
+/**
+ * ucfg_dlm_dump_deny_list_ap() - get denylisted bssid.
+ * @pdev: pdev object
+ *
+ * This API dumps denylist ap
+ *
+ * Return: None
+ */
+void ucfg_dlm_dump_deny_list_ap(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_dlm_update_bssid_connect_params() - Inform the DLM about connect or
+ * disconnect with the current AP.
+ * @pdev: pdev object
+ * @bssid: BSSID of the AP
+ * @con_state: Connection state (connected/disconnected)
+ *
+ * This API will inform the DLM about the state with the AP so that if the AP
+ * is selected, and the connection went through, and the connection did not
+ * face any data stall till the bad bssid reset timer, DLM can remove the
+ * AP from the reject ap list maintained by it.
+ *
+ * Return: None
+ */
+void
+ucfg_dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
+				     struct qdf_mac_addr bssid,
+				     enum dlm_connection_state con_state);
+
+/**
+ * ucfg_dlm_add_bssid_to_reject_list() - Add BSSID to the specific reject list.
+ * @pdev: Pdev object
+ * @ap_info: Ap info params such as BSSID, and the type of rejection to be done
+ *
+ * This API will add the BSSID to the reject AP list maintained by the denylist
+ * manager.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error.
+ */
+QDF_STATUS
+ucfg_dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
+				  struct reject_ap_info *ap_info);
+
+/**
+ * ucfg_dlm_wifi_off() - Inform the denylist manager about wifi off
+ * @pdev: Pdev object
+ *
+ * This API will inform the denylist manager that the user has turned wifi off
+ * from the UI, and the denylist manager can take action based upon this.
+ *
+ * Return: None
+ */
+void
+ucfg_dlm_wifi_off(struct wlan_objmgr_pdev *pdev);
+
+#else
+static inline
+QDF_STATUS ucfg_dlm_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_dlm_deinit(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_dlm_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_dlm_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+void ucfg_dlm_dump_deny_list_ap(struct wlan_objmgr_pdev *pdev)
+{}
+
+static inline
+QDF_STATUS
+ucfg_dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
+				  struct reject_ap_info *ap_info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_dlm_add_userspace_deny_list(struct wlan_objmgr_pdev *pdev,
+				 struct qdf_mac_addr *bssid_deny_list,
+				 uint8_t num_of_bssid)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+ucfg_dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
+				     struct qdf_mac_addr bssid,
+				     enum dlm_connection_state con_state)
+{
+}
+
+static inline
+void ucfg_dlm_wifi_off(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+#endif
+#endif /* _WLAN_DLM_UCFG_H_ */

+ 51 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/src/wlan_dlm_tgt_api.c

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Implements public API for denylist manager to interact with target/WMI
+ */
+
+#include "wlan_dlm_tgt_api.h"
+
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD)
+QDF_STATUS
+tgt_dlm_send_reject_list_to_fw(struct wlan_objmgr_pdev *pdev,
+			       struct reject_ap_params *reject_params)
+{
+	struct wlan_dlm_tx_ops *dlm_tx_ops;
+	struct dlm_pdev_priv_obj *dlm_priv;
+
+	dlm_priv = dlm_get_pdev_obj(pdev);
+
+	if (!dlm_priv) {
+		dlm_err("dlm_priv is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	dlm_tx_ops = &dlm_priv->dlm_tx_ops;
+	if (!dlm_tx_ops) {
+		dlm_err("dlm_tx_ops is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (dlm_tx_ops->dlm_send_reject_ap_list)
+		return dlm_tx_ops->dlm_send_reject_ap_list(pdev, reject_params);
+	dlm_err("Tx ops not registered, failed to send reject list to FW");
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif

+ 253 - 0
qcom/opensource/wlan/qcacld-3.0/components/denylist_mgr/dispatcher/src/wlan_dlm_ucfg_api.c

@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: define UCFG APIs exposed by the denylist mgr component
+ */
+
+#include <wlan_dlm_ucfg_api.h>
+#include <wlan_dlm_core.h>
+#include <wlan_dlm_api.h>
+#include "wlan_pmo_obj_mgmt_api.h"
+
+QDF_STATUS ucfg_dlm_init(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_register_pdev_create_handler(
+			WLAN_UMAC_COMP_DENYLIST_MGR,
+			dlm_pdev_object_created_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("pdev create register notification failed");
+		goto fail_create_pdev;
+	}
+
+	status = wlan_objmgr_register_pdev_destroy_handler(
+			WLAN_UMAC_COMP_DENYLIST_MGR,
+			dlm_pdev_object_destroyed_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("pdev destroy register notification failed");
+		goto fail_destroy_pdev;
+	}
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_DENYLIST_MGR,
+			dlm_psoc_object_created_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("psoc create register notification failed");
+		goto fail_create_psoc;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_DENYLIST_MGR,
+			dlm_psoc_object_destroyed_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("psoc destroy register notification failed");
+		goto fail_destroy_psoc;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+fail_destroy_psoc:
+	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
+				   dlm_psoc_object_created_notification, NULL);
+fail_create_psoc:
+	wlan_objmgr_unregister_pdev_destroy_handler(
+				 WLAN_UMAC_COMP_DENYLIST_MGR,
+				 dlm_pdev_object_destroyed_notification, NULL);
+fail_destroy_pdev:
+	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
+				   dlm_pdev_object_created_notification, NULL);
+fail_create_pdev:
+	return status;
+}
+
+QDF_STATUS ucfg_dlm_deinit(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_DENYLIST_MGR,
+			dlm_psoc_object_destroyed_notification,
+			NULL);
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_DENYLIST_MGR,
+			dlm_psoc_object_created_notification,
+			NULL);
+
+	status = wlan_objmgr_unregister_pdev_destroy_handler(
+			WLAN_UMAC_COMP_DENYLIST_MGR,
+			dlm_pdev_object_destroyed_notification,
+			NULL);
+
+	status = wlan_objmgr_unregister_pdev_create_handler(
+			WLAN_UMAC_COMP_DENYLIST_MGR,
+			dlm_pdev_object_created_notification,
+			NULL);
+
+	return status;
+}
+
+QDF_STATUS ucfg_dlm_psoc_set_suspended(struct wlan_objmgr_psoc *psoc,
+				       bool state)
+{
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+
+	dlm_psoc_obj = dlm_get_psoc_obj(psoc);
+
+	if (!dlm_psoc_obj) {
+		dlm_err("DLM psoc obj NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dlm_psoc_obj->is_suspended = state;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_dlm_psoc_get_suspended(struct wlan_objmgr_psoc *psoc,
+				       bool *state)
+{
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+
+	dlm_psoc_obj = dlm_get_psoc_obj(psoc);
+
+	if (!dlm_psoc_obj) {
+		dlm_err("DLM psoc obj NULL");
+		*state = true;
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*state = dlm_psoc_obj->is_suspended;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+ucfg_dlm_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	ucfg_dlm_psoc_set_suspended(psoc, true);
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+ucfg_dlm_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	ucfg_dlm_psoc_set_suspended(psoc, false);
+	dlm_update_reject_ap_list_to_fw(psoc);
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+ucfg_dlm_register_pmo_handler(void)
+{
+	pmo_register_suspend_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
+				     ucfg_dlm_suspend_handler, NULL);
+	pmo_register_resume_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
+				    ucfg_dlm_resume_handler, NULL);
+}
+
+static inline void
+ucfg_dlm_unregister_pmo_handler(void)
+{
+	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
+				       ucfg_dlm_suspend_handler);
+	pmo_unregister_resume_handler(WLAN_UMAC_COMP_DENYLIST_MGR,
+				      ucfg_dlm_resume_handler);
+}
+
+QDF_STATUS ucfg_dlm_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	ucfg_dlm_register_pmo_handler();
+	return dlm_cfg_psoc_open(psoc);
+}
+
+QDF_STATUS ucfg_dlm_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	ucfg_dlm_unregister_pmo_handler();
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_dlm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
+				  struct reject_ap_info *ap_info)
+{
+	return dlm_add_bssid_to_reject_list(pdev, ap_info);
+}
+
+QDF_STATUS
+ucfg_dlm_add_userspace_deny_list(struct wlan_objmgr_pdev *pdev,
+				 struct qdf_mac_addr *bssid_deny_list,
+				 uint8_t num_of_bssid)
+{
+	return dlm_add_userspace_deny_list(pdev, bssid_deny_list,
+					    num_of_bssid);
+}
+
+void
+ucfg_dlm_dump_deny_list_ap(struct wlan_objmgr_pdev *pdev)
+{
+	return wlan_dlm_dump_denylist_bssid(pdev);
+}
+
+void
+ucfg_dlm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
+				     struct qdf_mac_addr bssid,
+				     enum dlm_connection_state con_state)
+{
+	wlan_dlm_update_bssid_connect_params(pdev, bssid, con_state);
+}
+
+void
+ucfg_dlm_wifi_off(struct wlan_objmgr_pdev *pdev)
+{
+	struct dlm_pdev_priv_obj *dlm_ctx;
+	struct dlm_psoc_priv_obj *dlm_psoc_obj;
+	struct dlm_config *cfg;
+	QDF_STATUS status;
+
+	if (!pdev) {
+		dlm_err("pdev is NULL");
+		return;
+	}
+
+	dlm_ctx = dlm_get_pdev_obj(pdev);
+	dlm_psoc_obj = dlm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
+
+	if (!dlm_ctx || !dlm_psoc_obj) {
+		dlm_err("dlm_ctx or dlm_psoc_obj is NULL");
+		return;
+	}
+
+	status = qdf_mutex_acquire(&dlm_ctx->reject_ap_list_lock);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dlm_err("failed to acquire reject_ap_list_lock");
+		return;
+	}
+
+	cfg = &dlm_psoc_obj->dlm_cfg;
+
+	dlm_flush_reject_ap_list(dlm_ctx);
+	dlm_send_reject_ap_list_to_fw(pdev, &dlm_ctx->reject_ap_list, cfg);
+	qdf_mutex_release(&dlm_ctx->reject_ap_list_lock);
+}

+ 100 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/core/inc/wlan_disa_main.h

@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: declare various api which shall be used by
+ * DISA user configuration and target interface
+ */
+
+#ifndef _WLAN_DISA_MAIN_H_
+#define _WLAN_DISA_MAIN_H_
+
+#include "wlan_disa_public_struct.h"
+#include "wlan_disa_obj_mgmt_public_struct.h"
+#include "wlan_disa_priv.h"
+#include "wlan_disa_objmgr.h"
+
+#define disa_fatal(params...) \
+	QDF_TRACE_FATAL(QDF_MODULE_ID_DISA, params)
+#define disa_err(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_DISA, params)
+#define disa_warn(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_DISA, params)
+#define disa_info(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_DISA, params)
+#define disa_debug(params...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_DISA, params)
+
+#define disa_nofl_fatal(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_DISA, params)
+#define disa_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_DISA, params)
+#define disa_nofl_warn(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_DISA, params)
+#define disa_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_DISA, params)
+#define disa_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_DISA, params)
+
+#define DISA_ENTER() \
+	QDF_TRACE_ENTER(QDF_MODULE_ID_DISA, "enter")
+#define DISA_EXIT() \
+	QDF_TRACE_EXIT(QDF_MODULE_ID_DISA, "exit")
+
+/**
+ * disa_allocate_ctx() - Api to allocate disa ctx
+ *
+ * Helper function to allocate disa ctx
+ *
+ * Return: Success or failure.
+ */
+QDF_STATUS disa_allocate_ctx(void);
+
+/**
+ * disa_free_ctx() - to free disa context
+ *
+ * Helper function to free disa context
+ *
+ * Return: None.
+ */
+void disa_free_ctx(void);
+
+/**
+ * disa_get_context() - to get disa context
+ *
+ * Helper function to get disa context
+ *
+ * Return: disa context.
+ */
+struct wlan_disa_ctx *disa_get_context(void);
+
+/**
+ * disa_core_encrypt_decrypt_req() - Form encrypt/decrypt request
+ * @psoc: objmgr psoc object
+ * @req: DISA encrypt/decrypt request parameters
+ * @cb: Response callback for the encrypt/decrypt request
+ * @cookie: Cookie to pass to the response callback
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS disa_core_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req,
+		encrypt_decrypt_resp_callback cb,
+		void *cookie);
+
+#endif /* end  of _WLAN_DISA_MAIN_H_ */

+ 193 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/core/inc/wlan_disa_objmgr.h

@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: This file contains various object manager related wrappers and helpers
+ */
+
+#ifndef _WLAN_DISA_OBJMGR_H
+#define _WLAN_DISA_OBJMGR_H
+
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_disa_obj_mgmt_public_struct.h"
+
+/* Get/Put Ref */
+
+/**
+ * disa_psoc_get_ref() - DISA wrapper to increment ref count, if allowed
+ * @psoc: PSOC object
+ *
+ * DISA wrapper to increment ref count after checking valid object state
+ *
+ * Return: SUCCESS/FAILURE
+ */
+static inline QDF_STATUS disa_psoc_get_ref(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_try_get_ref(psoc, WLAN_DISA_ID);
+}
+
+/**
+ * disa_psoc_put_ref() - DISA wrapper to decrement ref count
+ * @psoc: PSOC object
+ *
+ * DISA wrapper to decrement ref count of psoc
+ *
+ * Return: SUCCESS/FAILURE
+ */
+static inline void disa_psoc_put_ref(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_release_ref(psoc, WLAN_DISA_ID);
+}
+
+/* Private Data */
+
+/**
+ * disa_psoc_get_priv_nolock(): DISA wrapper to retrieve component object
+ * @psoc: Psoc pointer
+ *
+ * DISA wrapper used to get the component private object pointer
+ *
+ * Return: Component private object
+ */
+static inline void *disa_psoc_get_priv_nolock(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_DISA);
+}
+
+/* Ids */
+static inline uint8_t
+disa_vdev_get_id(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t vdev_id;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+	QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
+
+	return vdev_id;
+}
+
+/* Tree Navigation */
+
+/*
+ * !PLEASE READ!
+ *
+ * The following are objmgr navigation helpers for traversing objmgr object
+ * trees.
+ *
+ * Objmgr ensures parents of an objmgr object cannot be freed while a valid
+ * reference to one of its children is held. Based on this fact, all of these
+ * navigation helpers make the following assumptions to ensure safe usage:
+ *
+ * 1) The caller must hold a valid reference to the input objmgr object!
+ *	E.g. Use disa_[peer|vdev|pdev|psoc]_get_ref() on the input objmgr
+ *	object before using these APIs
+ * 2) Given assumption #1, the caller does not need to hold a reference to the
+ *	parents of the input objmgr object
+ * 3) Given assumption #1, parents of the input objmgr object cannot be null
+ * 4) Given assumption #1, private contexts of any parent of the input objmgr
+ *	object cannot be null
+ *
+ * These characteristics remove the need for most sanity checks when dealing
+ * with objmgr objects. However, please note that if you ever walk the tree
+ * from parent to child, references must be acquired all the way down!
+ *
+ * Example #1:
+ *
+ *	psoc = disa_vdev_get_psoc(vdev);
+ *	if (!psoc)
+ *		// this is dead code
+ *
+ * Example #2:
+ *
+ *	psoc_priv = disa_psoc_get_priv(psoc);
+ *	if (!psoc_priv)
+ *		// this is dead code
+ *
+ * Example #3:
+ *
+ *	status = disa_psoc_get_ref(psoc);
+ *
+ *	...
+ *
+ *	psoc = disa_vdev_get_psoc(vdev);
+ *
+ *	// the next line is redundant, don't do it!
+ *	status = disa_psoc_get_ref(psoc);
+ */
+
+/* Tree Navigation: psoc */
+static inline struct disa_psoc_priv_obj *
+disa_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
+{
+	struct disa_psoc_priv_obj *psoc_priv;
+
+	psoc_priv = disa_psoc_get_priv_nolock(psoc);
+	QDF_BUG(psoc_priv);
+
+	return psoc_priv;
+}
+
+static inline struct wlan_objmgr_vdev *
+disa_psoc_get_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
+	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS)
+		return NULL;
+
+	wlan_psoc_obj_lock(psoc);
+	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
+	wlan_psoc_obj_unlock(psoc);
+
+	return vdev;
+}
+
+/* Tree Navigation: pdev */
+static inline struct wlan_objmgr_psoc *
+disa_pdev_get_psoc(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	QDF_BUG(psoc);
+
+	return psoc;
+}
+
+/* Tree Navigation: vdev */
+static inline struct wlan_objmgr_pdev *
+disa_vdev_get_pdev(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	QDF_BUG(pdev);
+
+	return pdev;
+}
+
+static inline struct wlan_objmgr_psoc *
+disa_vdev_get_psoc(struct wlan_objmgr_vdev *vdev)
+{
+	return disa_pdev_get_psoc(disa_vdev_get_pdev(vdev));
+}
+
+#endif /* _WLAN_DISA_OBJMGR_H */

+ 61 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/core/inc/wlan_disa_priv.h

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Declare various struct, macros which are used privately in DISA
+  * component.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_DISA_PRIV_STRUCT_H_
+#define _WLAN_DISA_PRIV_STRUCT_H_
+
+#include <qdf_lock.h>
+#include "wlan_disa_public_struct.h"
+
+/**
+ * struct disa_psoc_priv_obj -psoc specific user configuration required for disa
+ *
+ * @disa_rx_ops: rx operations for disa
+ * @disa_tx_ops: tx operations for disa
+ * @lock: spin lock for disa psoc priv ctx
+ */
+struct disa_psoc_priv_obj {
+	struct wlan_disa_rx_ops disa_rx_ops;
+	struct wlan_disa_tx_ops disa_tx_ops;
+	qdf_spinlock_t lock;
+};
+
+/**
+ * struct wlan_disa_ctx - disa context for single command
+ *
+ * @callback: hdd callback for disa encrypt/decrypt resp
+ * @callback_context: context for the callback
+ * @request_active: true if a request is active
+ * @lock: spin lock for disa context
+ */
+struct wlan_disa_ctx {
+	encrypt_decrypt_resp_callback callback;
+	void *callback_context;
+	bool request_active;
+	qdf_spinlock_t lock;
+};
+
+#endif /* end  of _WLAN_DISA_PRIV_STRUCT_H_ */

+ 105 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/core/src/wlan_disa_main.c

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2018-2020 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: Implement various api / helper function which shall be used for
+ * DISA user and target interface.
+ */
+
+#include "wlan_disa_main.h"
+#include "wlan_disa_obj_mgmt_public_struct.h"
+#include "wlan_disa_tgt_api.h"
+
+static struct wlan_disa_ctx *gp_disa_ctx;
+
+QDF_STATUS disa_allocate_ctx(void)
+{
+	/* If it is already created, ignore */
+	if (gp_disa_ctx) {
+		disa_debug("already allocated disa_ctx");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* allocate DISA ctx */
+	gp_disa_ctx = qdf_mem_malloc(sizeof(*gp_disa_ctx));
+	if (!gp_disa_ctx)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_spinlock_create(&gp_disa_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void disa_free_ctx(void)
+{
+	if (!gp_disa_ctx) {
+		disa_err("disa ctx is already freed");
+		QDF_ASSERT(0);
+		return;
+	}
+	qdf_spinlock_destroy(&gp_disa_ctx->lock);
+	qdf_mem_free(gp_disa_ctx);
+	gp_disa_ctx = NULL;
+}
+
+struct wlan_disa_ctx *disa_get_context(void)
+{
+	return gp_disa_ctx;
+}
+
+QDF_STATUS disa_core_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req,
+		encrypt_decrypt_resp_callback cb,
+		void *cookie)
+{
+	struct wlan_disa_ctx *disa_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	DISA_ENTER();
+	disa_ctx = disa_get_context();
+	if (!disa_ctx) {
+		disa_err("DISA context is NULL!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_spin_lock_bh(&disa_ctx->lock);
+	if (!disa_ctx->request_active) {
+		disa_ctx->callback = cb;
+		disa_ctx->callback_context = cookie;
+		disa_ctx->request_active = true;
+	} else {
+		status = QDF_STATUS_E_INVAL;
+	}
+	qdf_spin_unlock_bh(&disa_ctx->lock);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("A request is already active!");
+		return status;
+	}
+
+	status = disa_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("DISA cannot get the reference out of psoc");
+		return status;
+	}
+
+	status = tgt_disa_encrypt_decrypt_req(psoc, req);
+	disa_psoc_put_ref(psoc);
+
+	DISA_EXIT();
+	return status;
+}

+ 116 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_api.h

@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+/**
+ * DOC: declare utility API related to the disa component
+ * called by other components
+ */
+
+#ifndef _WLAN_DISA_OBJ_MGMT_API_H_
+#define _WLAN_DISA_OBJ_MGMT_API_H_
+
+#include <qdf_types.h>
+
+struct wlan_objmgr_psoc;
+
+/**
+ * disa_init() - register disa notification handlers.
+ *
+ * This function registers disa related notification handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS disa_init(void);
+#else
+static inline QDF_STATUS disa_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * disa_deinit() - unregister disa notification handlers.
+ *
+ * This function unregisters disa related notification handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS disa_deinit(void);
+#else
+static inline QDF_STATUS disa_deinit(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * disa_psoc_enable() - Trigger psoc enable for DISA
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS disa_psoc_enable(struct wlan_objmgr_psoc *psoc);
+#else
+static inline QDF_STATUS disa_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * disa_psoc_disable() - Trigger psoc disable for DISA
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS disa_psoc_disable(struct wlan_objmgr_psoc *psoc);
+#else
+static inline QDF_STATUS disa_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * disa_psoc_object_created_notification(): disa psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for psoc create handler
+ *
+ * Attach psoc private object, register rx/tx ops and event handlers
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS disa_psoc_object_created_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * disa_psoc_object_destroyed_notification(): disa psoc destroy handler
+ * @psoc: objmgr object corresponding to psoc which is going to be destroyed
+ * @arg: argument for psoc destroy handler
+ *
+ * Detach and free psoc private object, unregister event handlers
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS disa_psoc_object_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg);
+
+#endif /* end  of _WLAN_DISA_OBJ_MGMT_API_H_ */

+ 56 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_public_struct.h

@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+/**
+ * DOC: Declare various struct, macros which are used for object mgmt in disa.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_DISA_OBJ_MGMT_PUBLIC_STRUCT_H_
+#define _WLAN_DISA_OBJ_MGMT_PUBLIC_STRUCT_H_
+
+struct wlan_objmgr_psoc;
+struct disa_encrypt_decrypt_req_params;
+struct disa_encrypt_decrypt_resp_params;
+
+/**
+ * struct wlan_disa_tx_ops - structure of tx operation function
+ *	pointers for disa component
+ * @disa_encrypt_decrypt_req: send encrypt/decrypt request
+ * @disa_register_ev_handlers: register disa event handlers
+ * @disa_unregister_ev_handlers: unregister disa event handlers
+ */
+struct wlan_disa_tx_ops {
+	QDF_STATUS (*disa_encrypt_decrypt_req)(struct wlan_objmgr_psoc *psoc,
+			struct disa_encrypt_decrypt_req_params *req);
+	QDF_STATUS (*disa_register_ev_handlers)(struct wlan_objmgr_psoc *psoc);
+	QDF_STATUS (*disa_unregister_ev_handlers)
+			(struct wlan_objmgr_psoc *psoc);
+};
+
+/**
+ * struct wlan_disa_rx_ops - structure of rx operation function
+ *	pointers for disa component
+ * @encrypt_decrypt_msg_resp: send response of encrypt/decrypt request
+ */
+struct wlan_disa_rx_ops {
+	QDF_STATUS (*encrypt_decrypt_msg_resp)(struct wlan_objmgr_psoc *psoc,
+			struct disa_encrypt_decrypt_resp_params *resp);
+};
+#endif /* end  of _WLAN_DISA_OBJ_MGMT_PUBLIC_STRUCT_H_ */

+ 91 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_public_struct.h

@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Declare various struct, macros which shall be used in the DISA
+ * component.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_DISA_PUBLIC_STRUCT_H_
+#define _WLAN_DISA_PUBLIC_STRUCT_H_
+
+#include <qdf_types.h>
+
+#define MAC_MAX_KEY_LENGTH 32
+#define MAC_PN_LENGTH 8
+#define MAX_MAC_HEADER_LEN 32
+#define MIN_MAC_HEADER_LEN 24
+
+/**
+ * struct disa_encrypt_decrypt_req_params - disa encrypt request
+ * @vdev_id: virtual device id
+ * @key_flag: This indicates firmware to encrypt/decrypt payload
+ *    see ENCRYPT_DECRYPT_FLAG
+ * @key_idx: Index used in storing key
+ * @key_cipher: cipher used for encryption/decryption
+ *    Eg: see WMI_CIPHER_AES_CCM for CCMP
+ * @key_len: length of key data
+ * @key_txmic_len: length of Tx MIC
+ * @key_rxmic_len: length of Rx MIC
+ * @key_data: Key
+ * @pn: packet number
+ * @mac_header: MAC header
+ * @data_len: length of data
+ * @data: pointer to payload
+ */
+struct disa_encrypt_decrypt_req_params {
+	uint32_t vdev_id;
+	uint8_t key_flag;
+	uint32_t key_idx;
+	uint32_t key_cipher;
+	uint32_t key_len;
+	uint32_t key_txmic_len;
+	uint32_t key_rxmic_len;
+	uint8_t key_data[MAC_MAX_KEY_LENGTH];
+	uint8_t pn[MAC_PN_LENGTH];
+	uint8_t mac_header[MAX_MAC_HEADER_LEN];
+	uint32_t data_len;
+	uint8_t *data;
+};
+
+/**
+ * struct disa_encrypt_decrypt_resp_params - disa encrypt response
+ * @vdev_id: vdev id
+ * @status: status
+ * @data_len: data length
+ * @data: data pointer
+ */
+struct disa_encrypt_decrypt_resp_params {
+	uint32_t vdev_id;
+	int32_t status;
+	uint32_t data_len;
+	uint8_t *data;
+};
+
+/**
+ * typedef encrypt_decrypt_resp_callback() - DISA callback function
+ * @cookie: cookie passed in the DISA request
+ * @resp: the DISA response
+ */
+typedef void (*encrypt_decrypt_resp_callback)(void *cookie,
+	struct disa_encrypt_decrypt_resp_params *resp);
+#endif /* end  of _WLAN_DISA_PUBLIC_STRUCT_H_ */
+

+ 71 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_tgt_api.h

@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+/**
+ * DOC: Declare public API for disa to interact with target/WMI
+ */
+
+#ifndef _WLAN_DISA_TGT_API_H_
+#define _WLAN_DISA_TGT_API_H_
+
+#include <qdf_types.h>
+
+struct wlan_objmgr_psoc;
+struct disa_encrypt_decrypt_req_params;
+struct disa_encrypt_decrypt_resp_params;
+
+#define GET_DISA_TX_OPS_FROM_PSOC(psoc) \
+	(&disa_psoc_get_priv(psoc)->disa_tx_ops)
+
+/**
+ * tgt_disa_encrypt_decrypt_req() - send encrypt/decrypt request to target if
+ * @psoc: objmgr psoc object
+ * @req: encrypt/decrypt parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req);
+
+/**
+ * tgt_disa_encrypt_decrypt_resp() - receive encrypt/decrypt response
+ *	from target if
+ * @psoc: objmgr psoc object
+ * @resp: encrypt/decrypt response containing results
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_disa_encrypt_decrypt_resp(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_resp_params *resp);
+
+/**
+ * tgt_disa_register_ev_handlers() - API to register disa event handlers
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS tgt_disa_register_ev_handlers(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_disa_unregister_ev_handlers() - API to unregister disa event handlers
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS tgt_disa_unregister_ev_handlers(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end  of _WLAN_DISA_TGT_API_H_ */

+ 46 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/inc/wlan_disa_ucfg_api.h

@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+/**
+ * DOC: Declare public API related to the disa called by north bound HDD/OSIF
+ */
+
+#ifndef _WLAN_DISA_UCFG_API_H_
+#define _WLAN_DISA_UCFG_API_H_
+
+#include "wlan_disa_public_struct.h"
+struct wlan_objmgr_psoc;
+struct disa_encrypt_decrypt_req_params;
+
+
+/**
+ * ucfg_disa_encrypt_decrypt_req() - Send encrypt/decrypt request to the DISA
+ * core
+ * @psoc: objmgr psoc object
+ * @req: DISA encrypt/decrypt request parameters
+ * @cb: Response callback for the encrypt/decrypt request
+ * @cookie: Cookie to pass to the response callback
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS ucfg_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req,
+		encrypt_decrypt_resp_callback cb,
+		void *cookie);
+
+
+#endif /* end  of _WLAN_DISA_UCFG_API_H_ */

+ 209 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/src/wlan_disa_obj_mgmt_api.c

@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2018-2020 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: define utility API related to the DISA component
+ * called by other components
+ */
+
+#include "wlan_disa_obj_mgmt_api.h"
+#include "wlan_disa_main.h"
+#include "target_if_disa.h"
+#include "wlan_disa_tgt_api.h"
+#include "wlan_objmgr_global_obj.h"
+
+/**
+ * disa_init() - register disa notification handlers.
+ *
+ * This function registers disa related notification handlers and
+ * allocates disa context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS disa_init(void)
+{
+	QDF_STATUS status;
+
+	DISA_ENTER();
+
+	if (disa_allocate_ctx() != QDF_STATUS_SUCCESS) {
+		disa_err("unable to allocate disa ctx");
+		status = QDF_STATUS_E_FAULT;
+		goto out;
+	}
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_DISA,
+			disa_psoc_object_created_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("unable to register psoc create handler");
+		goto err_free_ctx;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_DISA,
+			disa_psoc_object_destroyed_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("unable to register psoc destroy handler");
+		wlan_objmgr_unregister_psoc_create_handler(
+				WLAN_UMAC_COMP_DISA,
+				disa_psoc_object_created_notification,
+				NULL);
+	} else {
+		goto out;
+	}
+
+err_free_ctx:
+	disa_free_ctx();
+out:
+	DISA_EXIT();
+
+	return status;
+}
+
+/**
+ * disa_deinit() - unregister disa notification handlers.
+ *
+ * This function unregisters disa related notification handlers and
+ * frees disa context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS disa_deinit(void)
+{
+	QDF_STATUS status;
+
+	DISA_ENTER();
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_DISA,
+			disa_psoc_object_destroyed_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		disa_err("unable to unregister psoc create handle");
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_DISA,
+			disa_psoc_object_created_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		disa_err("unable to unregister psoc create handle");
+
+	disa_free_ctx();
+	DISA_EXIT();
+
+	return status;
+}
+
+/**
+ * disa_psoc_object_created_notification(): disa psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for psoc create handler
+ *
+ * Attach psoc private object, register rx/tx ops and event handlers
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS disa_psoc_object_created_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct disa_psoc_priv_obj *disa_priv;
+	QDF_STATUS status;
+
+	DISA_ENTER();
+
+	disa_priv = qdf_mem_malloc(sizeof(*disa_priv));
+	if (!disa_priv) {
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+			 WLAN_UMAC_COMP_DISA,
+			(void *)disa_priv, QDF_STATUS_SUCCESS);
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("Failed to attach disa_priv with psoc");
+		qdf_mem_free(disa_priv);
+		goto out;
+	}
+
+	qdf_spinlock_create(&disa_priv->lock);
+	target_if_disa_register_tx_ops(&disa_priv->disa_tx_ops);
+
+out:
+	DISA_EXIT();
+
+	return status;
+}
+
+/**
+ * disa_psoc_object_destroyed_notification(): disa psoc destroy handler
+ * @psoc: objmgr object corresponding to psoc which is going to be destroyed
+ * @arg: argument for psoc destroy handler
+ *
+ * Detach and free psoc private object, unregister event handlers
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS disa_psoc_object_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct disa_psoc_priv_obj *disa_priv = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	DISA_ENTER();
+
+	disa_priv = disa_psoc_get_priv(psoc);
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+			 WLAN_UMAC_COMP_DISA,
+			(void *)disa_priv);
+
+	if (status != QDF_STATUS_SUCCESS)
+		disa_err("Failed to detach disa_priv with psoc");
+
+	qdf_spinlock_destroy(&disa_priv->lock);
+	qdf_mem_free(disa_priv);
+	DISA_EXIT();
+
+	return status;
+}
+
+/**
+ * disa_psoc_enable() - Trigger psoc enable for DISA
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS disa_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return tgt_disa_register_ev_handlers(psoc);
+}
+
+/**
+ * disa_psoc_disable() - Trigger psoc disable for DISA
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS disa_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return tgt_disa_unregister_ev_handlers(psoc);
+
+}
+

+ 133 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/src/wlan_disa_tgt_api.c

@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+/**
+ * DOC: Implements public API for disa to interact with target/WMI
+ */
+
+#include "wlan_disa_tgt_api.h"
+#include "wlan_disa_main.h"
+#include "wlan_disa_public_struct.h"
+
+/**
+ * tgt_disa_encrypt_decrypt_req() - send encrypt/decrypt request to target if
+ * @psoc: objmgr psoc object
+ * @req: encrypt/decrypt parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req)
+{
+	struct wlan_disa_tx_ops *disa_tx_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	DISA_ENTER();
+
+	disa_tx_ops = GET_DISA_TX_OPS_FROM_PSOC(psoc);
+	QDF_ASSERT(disa_tx_ops->disa_encrypt_decrypt_req);
+
+	if (disa_tx_ops->disa_encrypt_decrypt_req)
+		status = disa_tx_ops->disa_encrypt_decrypt_req(psoc, req);
+
+	DISA_EXIT();
+	return status;
+}
+
+/**
+ * tgt_disa_encrypt_decrypt_resp() - receive encrypt/decrypt response
+ *	from target if
+ * @psoc: objmgr psoc object
+ * @resp: encrypt/decrypt response containing results
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_disa_encrypt_decrypt_resp(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_resp_params *resp)
+{
+	struct wlan_disa_ctx *disa_ctx;
+	encrypt_decrypt_resp_callback cb;
+	void *cookie;
+
+	DISA_ENTER();
+
+	if (!resp) {
+		disa_err("encrypt/decrypt resp is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	disa_ctx = disa_get_context();
+	if (!disa_ctx) {
+		disa_err("DISA context is NULL!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_spin_lock_bh(&disa_ctx->lock);
+	cb = disa_ctx->callback;
+	disa_ctx->callback = NULL;
+	cookie = disa_ctx->callback_context;
+	disa_ctx->callback_context = NULL;
+	disa_ctx->request_active = false;
+	qdf_spin_unlock_bh(&disa_ctx->lock);
+
+	if (cb)
+		cb(cookie, resp);
+
+	DISA_EXIT();
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * tgt_disa_register_ev_handlers() - API to register disa event handlers
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS tgt_disa_register_ev_handlers(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_disa_tx_ops *disa_tx_ops;
+
+	disa_tx_ops = GET_DISA_TX_OPS_FROM_PSOC(psoc);
+
+	QDF_ASSERT(disa_tx_ops->disa_register_ev_handlers);
+
+	if (disa_tx_ops->disa_register_ev_handlers)
+		return disa_tx_ops->disa_register_ev_handlers(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * tgt_disa_unregister_ev_handlers() - API to unregister disa event handlers
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS tgt_disa_unregister_ev_handlers(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_disa_tx_ops *disa_tx_ops;
+
+	disa_tx_ops = GET_DISA_TX_OPS_FROM_PSOC(psoc);
+
+	QDF_ASSERT(disa_tx_ops->disa_unregister_ev_handlers);
+
+	if (disa_tx_ops->disa_unregister_ev_handlers)
+		return disa_tx_ops->disa_unregister_ev_handlers(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+

+ 34 - 0
qcom/opensource/wlan/qcacld-3.0/components/disa/dispatcher/src/wlan_disa_ucfg_api.c

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: public API related to the disa called by north bound HDD/OSIF
+ */
+
+#include "wlan_disa_ucfg_api.h"
+#include "wlan_disa_main.h"
+
+QDF_STATUS ucfg_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req,
+		encrypt_decrypt_resp_callback cb,
+		void *cookie)
+{
+	return disa_core_encrypt_decrypt_req(psoc, req, cb, cookie);
+}
+
+

+ 1030 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_main.h

@@ -0,0 +1,1030 @@
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_dp_main.h
+  *
+  *
+  */
+#ifndef __WLAN_DP_MAIN_H__
+#define __WLAN_DP_MAIN_H__
+
+#include "wlan_dp_public_struct.h"
+#include "wlan_dp_priv.h"
+#include "wlan_dp_objmgr.h"
+
+#define NUM_RX_QUEUES 5
+
+#define dp_enter() QDF_TRACE_ENTER(QDF_MODULE_ID_DP, "enter")
+#define dp_exit() QDF_TRACE_EXIT(QDF_MODULE_ID_DP, "exit")
+
+/**
+ * dp_allocate_ctx() - Allocate DP context
+ *
+ */
+QDF_STATUS dp_allocate_ctx(void);
+
+/**
+ * dp_free_ctx() - Free DP context
+ *
+ */
+void dp_free_ctx(void);
+
+/**
+ * dp_get_front_intf_no_lock() - Get the first interface from the intf list
+ * This API does not use any lock in it's implementation. It is the caller's
+ * directive to ensure concurrency safety.
+ * @dp_ctx: pointer to the DP context
+ * @out_intf: double pointer to pass the next interface
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+dp_get_front_intf_no_lock(struct wlan_dp_psoc_context *dp_ctx,
+			  struct wlan_dp_intf **out_intf);
+
+/**
+ * dp_get_next_intf_no_lock() - Get the next intf from the intf list
+ * This API does not use any lock in it's implementation. It is the caller's
+ * directive to ensure concurrency safety.
+ * @dp_ctx: pointer to the DP context
+ * @cur_intf: pointer to the current intf
+ * @out_intf: double pointer to pass the next intf
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+dp_get_next_intf_no_lock(struct wlan_dp_psoc_context *dp_ctx,
+			 struct wlan_dp_intf *cur_intf,
+			 struct wlan_dp_intf **out_intf);
+
+/**
+ * __dp_take_ref_and_fetch_front_intf_safe - Helper macro to lock, fetch
+ * front and next intf, take ref and unlock.
+ * @dp_ctx: the global DP context
+ * @dp_intf: an dp_intf pointer to use as a cursor
+ * @dp_intf_next: dp_intf pointer to next intf
+ *
+ */
+#define __dp_take_ref_and_fetch_front_intf_safe(dp_ctx, dp_intf, \
+						dp_intf_next) \
+	qdf_spin_lock_bh(&dp_ctx->intf_list_lock), \
+	dp_get_front_intf_no_lock(dp_ctx, &dp_intf), \
+	dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf_next), \
+	qdf_spin_unlock_bh(&dp_ctx->intf_list_lock)
+
+/**
+ * __dp_take_ref_and_fetch_next_intf_safe - Helper macro to lock, fetch next
+ * interface, take ref and unlock.
+ * @dp_ctx: the global DP context
+ * @dp_intf: dp_intf pointer to use as a cursor
+ * @dp_intf_next: dp_intf pointer to next interface
+ *
+ */
+#define __dp_take_ref_and_fetch_next_intf_safe(dp_ctx, dp_intf, \
+					       dp_intf_next) \
+	qdf_spin_lock_bh(&dp_ctx->intf_list_lock), \
+	dp_intf = dp_intf_next, \
+	dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf_next), \
+	qdf_spin_unlock_bh(&dp_ctx->intf_list_lock)
+
+/**
+ * __dp_is_intf_valid - Helper macro to return true/false for valid interface.
+ * @_dp_intf: an dp_intf pointer to use as a cursor
+ */
+#define __dp_is_intf_valid(_dp_intf) !!(_dp_intf)
+
+/**
+ * dp_for_each_intf_held_safe - Interface iterator called
+ *                                      in a delete safe manner
+ * @dp_ctx: the global DP context
+ * @dp_intf: an dp_intf pointer to use as a cursor
+ * @dp_intf_next: dp_intf pointer to the next interface
+ *
+ */
+#define dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) \
+	for (__dp_take_ref_and_fetch_front_intf_safe(dp_ctx, dp_intf, \
+						     dp_intf_next); \
+	     __dp_is_intf_valid(dp_intf); \
+	     __dp_take_ref_and_fetch_next_intf_safe(dp_ctx, dp_intf, \
+						    dp_intf_next))
+
+/**
+ * dp_get_intf_by_macaddr() - Api to Get interface from MAC address
+ * @dp_ctx: DP context
+ * @addr: MAC address
+ *
+ * Return: Pointer to DP interface.
+ */
+struct wlan_dp_intf*
+dp_get_intf_by_macaddr(struct wlan_dp_psoc_context *dp_ctx,
+		       struct qdf_mac_addr *addr);
+
+/**
+ * dp_get_intf_by_netdev() - Api to Get interface from netdev
+ * @dp_ctx: DP context
+ * @dev: Pointer to network device
+ *
+ * Return: Pointer to DP interface.
+ */
+struct wlan_dp_intf*
+dp_get_intf_by_netdev(struct wlan_dp_psoc_context *dp_ctx, qdf_netdev_t dev);
+
+/**
+ * dp_get_front_link_no_lock() - Get the first link from the dp links list
+ * This API does not use any lock in it's implementation. It is the caller's
+ * directive to ensure concurrency safety.
+ * @dp_intf: DP interface handle
+ * @out_link: double pointer to pass the next link
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+dp_get_front_link_no_lock(struct wlan_dp_intf *dp_intf,
+			  struct wlan_dp_link **out_link);
+
+/**
+ * dp_get_next_link_no_lock() - Get the next link from the link list
+ * This API does not use any lock in it's implementation. It is the caller's
+ * directive to ensure concurrency safety.
+ * @dp_intf: DP interface handle
+ * @cur_link: pointer to the currentlink
+ * @out_link: double pointer to pass the nextlink
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+dp_get_next_link_no_lock(struct wlan_dp_intf *dp_intf,
+			 struct wlan_dp_link *cur_link,
+			 struct wlan_dp_link **out_link);
+
+/**
+ * __dp_take_ref_and_fetch_front_link_safe - Helper macro to lock, fetch
+ * front and next link, take ref and unlock.
+ * @dp_intf: DP interface handle
+ * @dp_link: an dp_link pointer to use as a cursor
+ * @dp_link_next: dp_link pointer to nextlink
+ */
+#define __dp_take_ref_and_fetch_front_link_safe(dp_intf, dp_link, \
+						dp_link_next) \
+	qdf_spin_lock_bh(&(dp_intf)->dp_link_list_lock), \
+	dp_get_front_link_no_lock(dp_intf, &(dp_link)), \
+	dp_get_next_link_no_lock(dp_intf, dp_link, &(dp_link_next)), \
+	qdf_spin_unlock_bh(&(dp_intf)->dp_link_list_lock)
+
+/**
+ * __dp_take_ref_and_fetch_next_link_safe - Helper macro to lock, fetch next
+ * interface, take ref and unlock.
+ * @dp_intf: DP interface handle
+ * @dp_link: dp_link pointer to use as a cursor
+ * @dp_link_next: dp_link pointer to next link
+ */
+#define __dp_take_ref_and_fetch_next_link_safe(dp_intf, dp_link, \
+					       dp_link_next) \
+	qdf_spin_lock_bh(&(dp_intf)->dp_link_list_lock), \
+	dp_link = dp_link_next, \
+	dp_get_next_link_no_lock(dp_intf, dp_link, &(dp_link_next)), \
+	qdf_spin_unlock_bh(&(dp_intf)->dp_link_list_lock)
+
+/**
+ * __dp_is_link_valid - Helper macro to return true/false for valid interface.
+ * @_dp_link: an dp_link pointer to use as a cursor
+ */
+#define __dp_is_link_valid(_dp_link) !!(_dp_link)
+
+/**
+ * dp_for_each_link_held_safe - Interface iterator called
+ *                                      in a delete safe manner
+ * @dp_intf: DP interface handle
+ * @dp_link: an dp_link pointer to use as a cursor
+ * @dp_link_next: dp_link pointer to the next interface
+ *
+ */
+#define dp_for_each_link_held_safe(dp_intf, dp_link, dp_link_next) \
+	for (__dp_take_ref_and_fetch_front_link_safe(dp_intf, dp_link, \
+						     dp_link_next); \
+	     __dp_is_link_valid(dp_link); \
+	     __dp_take_ref_and_fetch_next_link_safe(dp_intf, dp_link, \
+						    dp_link_next))
+
+/* MAX iteration count to wait for dp packet process to complete */
+#define DP_TASK_MAX_WAIT_CNT  100
+/* Milli seconds to wait when packet is getting processed */
+#define DP_TASK_WAIT_TIME 200
+
+#define DP_TX_FN_CLR (1 << 0)
+#define DP_TX_SAP_STOP (1 << 1)
+#define DP_TX_DFS_CAC_BLOCK (1 << 2)
+#define WLAN_DP_SUSPEND (1 << 3)
+
+/**
+ * dp_wait_complete_tasks: Wait for DP tasks to complete
+ * @dp_ctx: DP context pointer
+ *
+ * This function waits for dp tasks like TX to be completed
+ *
+ * Return: None
+ */
+void dp_wait_complete_tasks(struct wlan_dp_psoc_context *dp_ctx);
+
+#define NUM_RX_QUEUES 5
+
+#define dp_enter() QDF_TRACE_ENTER(QDF_MODULE_ID_DP, "enter")
+#define dp_exit() QDF_TRACE_EXIT(QDF_MODULE_ID_DP, "exit")
+
+/**
+ * __wlan_dp_runtime_suspend() - Runtime suspend DP handler
+ * @soc: CDP SoC handle
+ * @pdev_id: DP PDEV ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS __wlan_dp_runtime_suspend(ol_txrx_soc_handle soc, uint8_t pdev_id);
+
+/**
+ * __wlan_dp_runtime_resume() - Runtime suspend DP handler
+ * @soc: CDP SoC handle
+ * @pdev_id: DP PDEV ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS __wlan_dp_runtime_resume(ol_txrx_soc_handle soc, uint8_t pdev_id);
+
+/**
+ * __wlan_dp_bus_suspend() - BUS suspend DP handler
+ * @soc: CDP SoC handle
+ * @pdev_id: DP PDEV ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS __wlan_dp_bus_suspend(ol_txrx_soc_handle soc, uint8_t pdev_id);
+
+/**
+ * __wlan_dp_bus_resume() - BUS resume DP handler
+ * @soc: CDP SoC handle
+ * @pdev_id: DP PDEV ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS __wlan_dp_bus_resume(ol_txrx_soc_handle soc, uint8_t pdev_id);
+
+/**
+ * wlan_dp_txrx_soc_attach() - Datapath soc attach
+ * @params: SoC attach params
+ * @is_wifi3_0_target: [OUT] Pointer to update if the target is wifi3.0
+ *
+ * Return: SoC handle
+ */
+void *wlan_dp_txrx_soc_attach(struct dp_txrx_soc_attach_params *params,
+			      bool *is_wifi3_0_target);
+
+/**
+ * wlan_dp_txrx_soc_detach() - Datapath SoC detach
+ * @soc: DP SoC handle
+ *
+ * Return: None
+ */
+void wlan_dp_txrx_soc_detach(ol_txrx_soc_handle soc);
+
+/**
+ * wlan_dp_txrx_attach_target() - DP target attach
+ * @soc: DP SoC handle
+ * @pdev_id: DP pdev id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_dp_txrx_attach_target(ol_txrx_soc_handle soc, uint8_t pdev_id);
+
+/**
+ * wlan_dp_txrx_pdev_attach() - DP pdev attach
+ * @soc: DP SoC handle
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_dp_txrx_pdev_attach(ol_txrx_soc_handle soc);
+
+/**
+ * wlan_dp_txrx_pdev_detach() - DP pdev detach
+ * @soc: DP SoC handle
+ * @pdev_id: DP pdev id
+ * @force: indicates if force detach is to be done or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_dp_txrx_pdev_detach(ol_txrx_soc_handle soc, uint8_t pdev_id,
+				    int force);
+
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * dp_link_switch_notification() - DP notifier for MLO link switch
+ * @vdev: Objmgr vdev handle
+ * @lswitch_req: Link switch request params
+ * @notify_reason: Reason of notification
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+dp_link_switch_notification(struct wlan_objmgr_vdev *vdev,
+			    struct wlan_mlo_link_switch_req *lswitch_req,
+			    enum wlan_mlo_link_switch_notify_reason notify_reason);
+#endif
+
+/**
+ * dp_peer_obj_create_notification(): dp peer create handler
+ * @peer: peer which is going to created by objmgr
+ * @arg: argument for vdev create handler
+ *
+ * Register this api with objmgr to detect peer is created
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+dp_peer_obj_create_notification(struct wlan_objmgr_peer *peer, void *arg);
+
+/**
+ * dp_peer_obj_destroy_notification(): dp peer delete handler
+ * @peer: peer which is going to delete by objmgr
+ * @arg: argument for vdev delete handler
+ *
+ * Register this api with objmgr to detect peer is deleted
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+dp_peer_obj_destroy_notification(struct wlan_objmgr_peer *peer, void *arg);
+
+/**
+ * dp_vdev_obj_destroy_notification() - Free per DP vdev object
+ * @vdev: vdev context
+ * @arg: Pointer to arguments
+ *
+ * This function gets called from object manager when vdev is being
+ * deleted and delete DP vdev context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+dp_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg);
+
+/**
+ * dp_vdev_obj_create_notification() - Allocate per DP vdev object
+ * @vdev: vdev context
+ * @arg: Pointer to arguments
+ *
+ * This function gets called from object manager when vdev is being
+ * created and creates DP vdev context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+dp_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, void *arg);
+
+/**
+ * dp_pdev_obj_create_notification() - Allocate per DP pdev object
+ * @pdev: pdev context
+ * @arg: Pointer to arguments
+ *
+ * This function gets called from object manager when pdev is being
+ * created and creates DP pdev context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+dp_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev, void *arg);
+
+/**
+ * dp_pdev_obj_destroy_notification() - Free per DP pdev object
+ * @pdev: pdev context
+ * @arg: Pointer to arguments
+ *
+ * This function gets called from object manager when pdev is being
+ * deleted and delete DP pdev context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+dp_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, void *arg);
+
+/**
+ * dp_psoc_obj_create_notification() - Function to allocate per DP
+ * psoc private object
+ * @psoc: psoc context
+ * @arg: Pointer to arguments
+ *
+ * This function gets called from object manager when psoc is being
+ * created and creates DP soc context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+dp_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * dp_psoc_obj_destroy_notification() - Free psoc private object
+ * @psoc: psoc context
+ * @arg: Pointer to arguments
+ *
+ * This function gets called from object manager when psoc is being
+ * deleted and delete DP soc context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+dp_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * dp_attach_ctx() - Api to attach dp ctx
+ * @dp_ctx : DP Context
+ *
+ * Helper function to attach dp ctx
+ *
+ * Return: None.
+ */
+void dp_attach_ctx(struct wlan_dp_psoc_context *dp_ctx);
+
+/**
+ * dp_detach_ctx() - to detach dp context
+ *
+ * Helper function to detach dp context
+ *
+ * Return: None.
+ */
+void dp_detach_ctx(void);
+
+/**
+ * dp_get_context() - to get dp context
+ *
+ * Helper function to get dp context
+ *
+ * Return: dp context.
+ */
+struct wlan_dp_psoc_context *dp_get_context(void);
+
+/**
+ * dp_add_latency_critical_client() - Add latency critical client
+ * @vdev: pointer to vdev object (Should not be NULL)
+ * @phymode: the phymode of the connected adapter
+ *
+ * This function checks if the present connection is latency critical
+ * and adds to the latency critical clients count and informs the
+ * datapath about this connection being latency critical.
+ *
+ * Returns: None
+ */
+static inline void
+dp_add_latency_critical_client(struct wlan_objmgr_vdev *vdev,
+			       enum qca_wlan_802_11_mode phymode)
+{
+	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
+	struct wlan_dp_intf *dp_intf;
+
+	if (!dp_link) {
+		dp_err("No dp_link for objmgr vdev %pK", vdev);
+		return;
+	}
+
+	dp_intf = dp_link->dp_intf;
+	if (!dp_intf) {
+		dp_err("Invalid dp_intf for dp_link %pK (" QDF_MAC_ADDR_FMT ")",
+		       dp_link, QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
+		return;
+	}
+
+	switch (phymode) {
+	case QCA_WLAN_802_11_MODE_11A:
+	case QCA_WLAN_802_11_MODE_11G:
+		qdf_atomic_inc(&dp_intf->dp_ctx->num_latency_critical_clients);
+
+		dp_debug("Adding latency critical connection for vdev %d",
+			 dp_link->link_id);
+		cdp_vdev_inform_ll_conn(cds_get_context(QDF_MODULE_ID_SOC),
+					dp_link->link_id,
+					CDP_VDEV_LL_CONN_ADD);
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * dp_del_latency_critical_client() - Add tlatency critical client
+ * @vdev: pointer to vdev object (Should not be NULL)
+ * @phymode: the phymode of the connected adapter
+ *
+ * This function checks if the present connection was latency critical
+ * and removes from the latency critical clients count and informs the
+ * datapath about the removed connection being latency critical.
+ *
+ * Returns: None
+ */
+static inline void
+dp_del_latency_critical_client(struct wlan_objmgr_vdev *vdev,
+			       enum qca_wlan_802_11_mode phymode)
+{
+	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
+	struct wlan_dp_intf *dp_intf;
+
+	if (!dp_link) {
+		dp_err("No dp_link for objmgr vdev %pK", vdev);
+		return;
+	}
+
+	dp_intf = dp_link->dp_intf;
+	if (!dp_intf) {
+		dp_err("Invalid dp_intf for dp_link %pK (" QDF_MAC_ADDR_FMT ")",
+		       dp_link, QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
+		return;
+	}
+
+	switch (phymode) {
+	case QCA_WLAN_802_11_MODE_11A:
+	case QCA_WLAN_802_11_MODE_11G:
+		qdf_atomic_dec(&dp_intf->dp_ctx->num_latency_critical_clients);
+
+		dp_info("Removing latency critical connection for vdev %d",
+			dp_link->link_id);
+		cdp_vdev_inform_ll_conn(cds_get_context(QDF_MODULE_ID_SOC),
+					dp_link->link_id,
+					CDP_VDEV_LL_CONN_DEL);
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * is_dp_intf_valid() - to check DP interface valid
+ * @dp_intf: DP interface pointer
+ *
+ * API to check whether DP interface is valid
+ *
+ * Return: non zero value on interface valid
+ */
+int is_dp_intf_valid(struct wlan_dp_intf *dp_intf);
+
+/**
+ * is_dp_link_valid() - check if DP link is valid
+ * @dp_link: DP link handle
+ *
+ * API to check whether DP link is valid
+ *
+ * Return: true if dp_link is valid, else false.
+ */
+bool is_dp_link_valid(struct wlan_dp_link *dp_link);
+
+/**
+ * dp_send_rps_ind() - send rps indication to daemon
+ * @dp_intf: DP interface
+ *
+ * If RPS feature enabled by INI, send RPS enable indication to daemon
+ * Indication contents is the name of interface to find correct sysfs node
+ * Should send all available interfaces
+ *
+ * Return: none
+ */
+void dp_send_rps_ind(struct wlan_dp_intf *dp_intf);
+
+/**
+ * dp_try_send_rps_ind() - try to send rps indication to daemon.
+ * @vdev: vdev handle
+ *
+ * If RPS flag is set in DP context then send rsp indication.
+ *
+ * Return: none
+ */
+void dp_try_send_rps_ind(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * dp_send_rps_disable_ind() - send rps disable indication to daemon
+ * @dp_intf: DP interface
+ *
+ * Return: none
+ */
+void dp_send_rps_disable_ind(struct wlan_dp_intf *dp_intf);
+
+#ifdef QCA_CONFIG_RPS
+/**
+ * dp_set_rps() - Enable/disable RPS for mode specified
+ * @vdev_id: vdev id which RPS needs to be enabled
+ * @enable: Set true to enable RPS in SAP mode
+ *
+ * Callback function registered with ipa
+ *
+ * Return: none
+ */
+void dp_set_rps(uint8_t vdev_id, bool enable);
+#else
+static inline void dp_set_rps(uint8_t vdev_id, bool enable)
+{
+}
+#endif
+
+/**
+ * dp_set_rx_mode_rps() - Enable/disable RPS in SAP mode
+ * @enable: Set true to enable RPS in SAP mode
+ *
+ * Callback function registered with core datapath
+ *
+ * Return: none
+ */
+void dp_set_rx_mode_rps(bool enable);
+
+/**
+ * dp_set_rps_cpu_mask - set RPS CPU mask for interfaces
+ * @dp_ctx: pointer to struct dp_context
+ *
+ * Return: none
+ */
+void dp_set_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx);
+
+/**
+ * dp_try_set_rps_cpu_mask() - try to set RPS CPU mask
+ * @psoc: psoc handle
+ *
+ * If RPS flag is set in DP context then set RPS CPU mask.
+ *
+ * Return: none
+ */
+void dp_try_set_rps_cpu_mask(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_clear_rps_cpu_mask - clear RPS CPU mask for interfaces
+ * @dp_ctx: pointer to struct dp_context
+ *
+ * Return: none
+ */
+void dp_clear_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx);
+
+/**
+ * dp_mic_init_work() - init mic error work
+ * @dp_intf: Pointer to dp interface
+ *
+ * Return: None
+ */
+void dp_mic_init_work(struct wlan_dp_intf *dp_intf);
+
+/**
+ * dp_mic_deinit_work() - deinitialize mic error work
+ * @dp_intf: Pointer to dp interface
+ *
+ * Return: None
+ */
+void dp_mic_deinit_work(struct wlan_dp_intf *dp_intf);
+
+/**
+ * dp_rx_mic_error_ind() - MIC error indication handler
+ * @psoc: opaque handle for UMAC psoc object
+ * @pdev_id: physical device instance id
+ * @mic_failure_info: mic failure information
+ *
+ * This function indicates the Mic failure to the supplicant
+ *
+ * Return: None
+ */
+void
+dp_rx_mic_error_ind(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id,
+		    struct cdp_rx_mic_err_info *mic_failure_info);
+/**
+ * dp_intf_get_tx_ops: get TX ops from the DP interface
+ * @psoc: pointer to psoc object
+ *
+ * Return: pointer to TX op callback
+ */
+static inline
+struct wlan_dp_psoc_sb_ops *dp_intf_get_tx_ops(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+
+	if (!psoc) {
+		dp_err("psoc is null");
+		return NULL;
+	}
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("psoc private object is null");
+		return NULL;
+	}
+
+	return &dp_ctx->sb_ops;
+}
+
+/**
+ * dp_intf_get_rx_ops: get RX ops from the DP interface
+ * @psoc: pointer to psoc object
+ *
+ * Return: pointer to RX op callback
+ */
+static inline
+struct wlan_dp_psoc_nb_ops *dp_intf_get_rx_ops(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+
+	if (!psoc) {
+		dp_err("psoc is null");
+		return NULL;
+	}
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("psoc private object is null");
+		return NULL;
+	}
+
+	return &dp_ctx->nb_ops;
+}
+
+/**
+ * dp_get_arp_request_ctx: get ARP req context from the DP context
+ * @psoc: pointer to psoc object
+ *
+ * Return: pointer to ARP request ctx.
+ */
+static inline
+void *dp_get_arp_request_ctx(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("psoc private object is null");
+		return NULL;
+	}
+	return dp_ctx->sb_ops.arp_request_ctx;
+}
+
+/**
+ * dp_get_arp_stats_event_handler() - callback api to update the
+ * stats received from FW
+ * @psoc : psoc handle
+ * @rsp: pointer to data received from FW.
+ *
+ * This is called when wlan driver received response event for
+ * get arp stats to firmware.
+ *
+ * Return: None
+ */
+QDF_STATUS dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc,
+					  struct dp_rsp_stats *rsp);
+
+/**
+ * dp_trace_init() - Initialize DP trace
+ * @psoc: psoc handle
+ *
+ * Return: None
+ */
+
+void dp_trace_init(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_set_dump_dp_trace() - set DP trace dump level
+ * @cmd_type : command type
+ * @count: count
+ *
+ * Return: None
+ */
+void dp_set_dump_dp_trace(uint16_t cmd_type, uint16_t count);
+
+#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
+#define DP_BUS_BW_CFG(bus_bw_cfg)	bus_bw_cfg
+#define DP_BUS_BW_GET_RX_LVL(dp_ctx)	(dp_ctx)->cur_rx_level
+static inline bool
+dp_is_low_tput_gro_enable(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return (qdf_atomic_read(&dp_ctx->low_tput_gro_enable)) ? true : false;
+}
+#else
+#define DP_BUS_BW_CFG(bus_bw_cfg)	0
+#define DP_BUS_BW_GET_RX_LVL(dp_ctx)	0
+static inline bool
+dp_is_low_tput_gro_enable(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return false;
+}
+#endif
+
+#define DP_DATA_STALL_ENABLE      BIT(0)
+#define DP_HOST_STA_TX_TIMEOUT    BIT(16)
+#define DP_HOST_SAP_TX_TIMEOUT    BIT(17)
+#define DP_HOST_NUD_FAILURE       BIT(18)
+#define DP_TIMEOUT_WLM_MODE       BIT(31)
+#define FW_DATA_STALL_EVT_MASK     0x8000FFFF
+
+/**
+ * dp_is_data_stall_event_enabled() - Check if data stall detection is enabled
+ * @evt: Data stall event to be checked
+ *
+ * Return: True if the data stall event is enabled
+ */
+bool dp_is_data_stall_event_enabled(uint32_t evt);
+
+/*
+ * dp_get_net_dev_stats(): Get netdev stats
+ * @dp_intf: DP interface handle
+ * @stats: To hold netdev stats
+ *
+ * Return: None
+ */
+static inline void
+dp_get_net_dev_stats(struct wlan_dp_intf *dp_intf, qdf_net_dev_stats *stats)
+{
+	qdf_mem_copy(stats, &dp_intf->stats, sizeof(dp_intf->stats));
+}
+
+/*
+ * dp_clear_net_dev_stats(): Clear netdev stats
+ * @dp_intf: DP interface handle
+ *
+ * Return: None
+ */
+static inline
+void dp_clear_net_dev_stats(struct wlan_dp_intf *dp_intf)
+{
+	qdf_mem_set(&dp_intf->stats, sizeof(dp_intf->stats), 0);
+}
+
+#ifdef FEATURE_DIRECT_LINK
+/**
+ * dp_direct_link_init() - Initializes Direct Link datapath
+ * @dp_ctx: DP private context
+ *
+ * Return: QDF status
+ */
+QDF_STATUS dp_direct_link_init(struct wlan_dp_psoc_context *dp_ctx);
+
+/**
+ * dp_direct_link_deinit() - De-initializes Direct Link datapath
+ * @dp_ctx: DP private context
+ * @is_ssr: true if SSR is in progress else false
+ *
+ * Return: None
+ */
+void dp_direct_link_deinit(struct wlan_dp_psoc_context *dp_ctx, bool is_ssr);
+
+/**
+ * dp_config_direct_link: Set direct link config of vdev
+ * @dp_intf: DP interface handle
+ * @config_direct_link: Flag to enable direct link path
+ * @enable_low_latency: Flag to enable low link latency
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS dp_config_direct_link(struct wlan_dp_intf *dp_intf,
+				 bool config_direct_link,
+				 bool enable_low_latency);
+#else
+static inline
+QDF_STATUS dp_direct_link_init(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+void dp_direct_link_deinit(struct wlan_dp_psoc_context *dp_ctx, bool is_ssr)
+{
+}
+
+static inline
+QDF_STATUS dp_config_direct_link(struct wlan_dp_intf *dp_intf,
+				 bool config_direct_link,
+				 bool enable_low_latency)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#ifdef WLAN_FEATURE_11BE
+/**
+ * __wlan_dp_update_peer_map_unmap_version() - update peer map unmap version
+ * @version: Peer map unmap version pointer to be updated
+ *
+ * Return: None
+ */
+static inline void
+__wlan_dp_update_peer_map_unmap_version(uint8_t *version)
+{
+	/* 0x32 -> host supports HTT peer map v3 format and peer unmap v2 format. */
+	*version = 0x32;
+}
+#else
+static inline void
+__wlan_dp_update_peer_map_unmap_version(uint8_t *version)
+{
+}
+#endif
+
+#ifdef WLAN_DP_PROFILE_SUPPORT
+/**
+ * wlan_dp_get_profile_info() - Get DP memory profile info
+ *
+ * Return: None
+ */
+struct wlan_dp_memory_profile_info *wlan_dp_get_profile_info(void);
+
+/**
+ * wlan_dp_select_profile_cfg() - Select DP profile configuration
+ * @psoc: psoc context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_dp_select_profile_cfg(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_dp_soc_cfg_sync_profile() - Sync DP soc cfg items with profile
+ * @cdp_soc: cdp soc context
+ *
+ * Return: None
+ */
+void wlan_dp_soc_cfg_sync_profile(struct cdp_soc_t *cdp_soc);
+
+/**
+ * wlan_dp_pdev_cfg_sync_profile() - Sync DP pdev cfg items with profile
+ * @cdp_soc: cdp soc context
+ * @pdev_id: pdev id
+ *
+ * Return: QDF_STATUS
+ */
+void wlan_dp_pdev_cfg_sync_profile(struct cdp_soc_t *cdp_soc, uint8_t pdev_id);
+#else
+
+static inline
+QDF_STATUS wlan_dp_select_profile_cfg(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
+/**
+ * wlan_dp_link_cdp_vdev_delete_notification() - CDP vdev delete notification
+ * @context: osif_vdev handle
+ *
+ * Return: None
+ */
+void wlan_dp_link_cdp_vdev_delete_notification(void *context);
+
+/* DP CFG APIs - START */
+
+#ifdef WLAN_SUPPORT_RX_FISA
+/**
+ * wlan_dp_cfg_is_rx_fisa_enabled() - Get Rx FISA enabled flag
+ * @dp_cfg: soc configuration context
+ *
+ * Return: true if enabled, false otherwise.
+ */
+static inline
+bool wlan_dp_cfg_is_rx_fisa_enabled(struct wlan_dp_psoc_cfg *dp_cfg)
+{
+	return dp_cfg->is_rx_fisa_enabled;
+}
+
+/**
+ * wlan_dp_cfg_is_rx_fisa_lru_del_enabled() - Get Rx FISA LRU del enabled flag
+ * @dp_cfg: soc configuration context
+ *
+ * Return: true if enabled, false otherwise.
+ */
+static inline
+bool wlan_dp_cfg_is_rx_fisa_lru_del_enabled(struct wlan_dp_psoc_cfg *dp_cfg)
+{
+	return dp_cfg->is_rx_fisa_lru_del_enabled;
+}
+#else
+static inline
+bool wlan_dp_cfg_is_rx_fisa_enabled(struct wlan_dp_psoc_cfg *dp_cfg)
+{
+	return false;
+}
+
+static inline
+bool wlan_dp_cfg_is_rx_fisa_lru_del_enabled(struct wlan_dp_psoc_cfg *dp_cfg)
+{
+	return false;
+}
+#endif
+
+
+/* DP CFG APIs - END */
+/**
+ * __wlan_dp_update_def_link() - update DP interface default link
+ * @psoc: psoc handle
+ * @intf_mac: interface MAC address
+ * @vdev: objmgr vdev handle to set the def_link in dp_intf
+ *
+ */
+void __wlan_dp_update_def_link(struct wlan_objmgr_psoc *psoc,
+			       struct qdf_mac_addr *intf_mac,
+			       struct wlan_objmgr_vdev *vdev);
+#endif

+ 158 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_objmgr.h

@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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: This file contains various object manager related wrappers and helpers
+ */
+
+#ifndef __WLAN_DP_OBJMGR_H
+#define __WLAN_DP_OBJMGR_H
+
+#include "wlan_cmn.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_peer_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_utility.h"
+
+struct wlan_dp_intf;
+struct wlan_dp_link;
+
+/* Get/Put Ref */
+
+#define dp_comp_peer_get_ref(peer) wlan_objmgr_peer_try_get_ref(peer, WLAN_DP_ID)
+#define dp_comp_peer_put_ref(peer) wlan_objmgr_peer_release_ref(peer, WLAN_DP_ID)
+
+#define dp_comp_vdev_get_ref(vdev) wlan_objmgr_vdev_try_get_ref(vdev, WLAN_DP_ID)
+#define dp_comp_vdev_put_ref(vdev) wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID)
+
+#define dp_comp_pdev_get_ref(pdev) wlan_objmgr_pdev_try_get_ref(pdev, WLAN_DP_ID)
+#define dp_comp_pdev_put_ref(pdev) wlan_objmgr_pdev_release_ref(pdev, WLAN_DP_ID)
+
+#define dp_comp_psoc_get_ref(psoc) wlan_objmgr_psoc_try_get_ref(psoc, WLAN_DP_ID)
+#define dp_comp_psoc_put_ref(psoc) wlan_objmgr_psoc_release_ref(psoc, WLAN_DP_ID)
+
+/**
+ * dp_get_peer_priv_obj: get DP priv object from peer object
+ * @peer: pointer to peer object
+ *
+ * Return: pointer to DP peer private object
+ */
+static inline struct wlan_dp_sta_info *
+dp_get_peer_priv_obj(struct wlan_objmgr_peer *peer)
+{
+	struct wlan_dp_sta_info *peer_info;
+
+	peer_info = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_COMP_DP);
+	if (!peer_info) {
+		dp_err("peer is null");
+		return NULL;
+	}
+
+	return peer_info;
+}
+
+/**
+ * dp_get_vdev_priv_obj() - Wrapper to retrieve vdev priv obj
+ * @vdev: vdev pointer
+ *
+ * Return: DP vdev private object
+ */
+static inline struct wlan_dp_link *
+dp_get_vdev_priv_obj(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_dp_link *obj;
+
+	if (!vdev) {
+		dp_err("vdev is null");
+		return NULL;
+	}
+
+	obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_COMP_DP);
+
+	return obj;
+}
+
+/**
+ * dp_psoc_get_priv() - Wrapper to retrieve psoc priv obj
+ * @psoc: psoc pointer
+ *
+ * Return: DP psoc private object
+ */
+static inline struct wlan_dp_psoc_context *
+dp_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+
+	dp_ctx = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_COMP_DP);
+	QDF_BUG(dp_ctx);
+
+	return dp_ctx;
+}
+
+/**
+ * dp_objmgr_get_vdev_by_user() - Get reference of vdev from dp_link
+ *  with user id
+ * @dp_link: DP link handle
+ * @dbgid: reference count dbg id
+ *
+ * Return: pointer to vdev object for success, NULL for failure
+ */
+#ifdef WLAN_OBJMGR_REF_ID_TRACE
+#define dp_objmgr_get_vdev_by_user(dp_link, dbgid) \
+	__dp_objmgr_get_vdev_by_user(dp_link, dbgid, __func__, __LINE__)
+struct wlan_objmgr_vdev *
+__dp_objmgr_get_vdev_by_user(struct wlan_dp_link *dp_link,
+			     wlan_objmgr_ref_dbgid id,
+			     const char *func,
+			     int line);
+#else
+#define dp_objmgr_get_vdev_by_user(dp_link, dbgid) \
+	__dp_objmgr_get_vdev_by_user(dp_link, dbgid, __func__)
+struct wlan_objmgr_vdev *
+__dp_objmgr_get_vdev_by_user(struct wlan_dp_link *dp_link,
+			     wlan_objmgr_ref_dbgid id,
+			     const char *func);
+#endif
+
+/**
+ * dp_objmgr_put_vdev_by_user() - Release reference of vdev object with
+ *  user id
+ * @vdev: pointer to vdev object
+ * @dbgid: reference count dbg id
+ *
+ * This API releases vdev object reference which was acquired using
+ * dp_objmgr_get_vdev_by_user().
+ *
+ * Return: void
+ */
+#ifdef WLAN_OBJMGR_REF_ID_TRACE
+#define dp_objmgr_put_vdev_by_user(vdev, dbgid) \
+	__dp_objmgr_put_vdev_by_user(vdev, dbgid, __func__, __LINE__)
+void
+__dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev,
+			     wlan_objmgr_ref_dbgid id, const char *func,
+			     int line);
+#else
+#define dp_objmgr_put_vdev_by_user(vdev, dbgid) \
+	__dp_objmgr_put_vdev_by_user(vdev, dbgid, __func__)
+void
+__dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev,
+			     wlan_objmgr_ref_dbgid id, const char *func);
+#endif
+
+#endif /* __WLAN_DP_OBJMGR_H */

+ 122 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_periodic_sta_stats.h

@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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 Host Device Driver periodic STA statistics related implementation
+ */
+
+#if !defined(WLAN_DP_PERIODIC_STA_STATS_H)
+#define WLAN_DP_PERIODIC_STA_STATS_H
+
+#include "wlan_dp_priv.h"
+#include "wlan_objmgr_psoc_obj.h"
+
+#ifdef WLAN_FEATURE_PERIODIC_STA_STATS
+
+/**
+ * dp_periodic_sta_stats_config() - Initialize periodic stats configuration
+ * @config: Pointer to dp configuration
+ * @psoc: Pointer to psoc
+ *
+ * Return: none
+ */
+void dp_periodic_sta_stats_config(struct wlan_dp_psoc_cfg *config,
+				  struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_periodic_sta_stats_init() - Initialize periodic stats display flag
+ * @dp_intf: Pointer to the station interface
+ *
+ * Return: none
+ */
+void dp_periodic_sta_stats_init(struct wlan_dp_intf *dp_intf);
+
+/**
+ * dp_periodic_sta_stats_display() - Display periodic stats at STA
+ * @dp_ctx: dp context
+ *
+ * Return: none
+ */
+void dp_periodic_sta_stats_display(struct wlan_dp_psoc_context *dp_ctx);
+
+/**
+ * dp_periodic_sta_stats_start() - Start displaying periodic stats for STA
+ * @vdev: vdev handle
+ *
+ * Return: none
+ */
+void dp_periodic_sta_stats_start(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * dp_periodic_sta_stats_stop() - Stop displaying periodic stats for STA
+ * @vdev: vdev handle
+ *
+ * Return: none
+ */
+void dp_periodic_sta_stats_stop(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * dp_periodic_sta_stats_mutex_create() - Create mutex for STA periodic stats
+ * @dp_intf: Pointer to the station interface
+ *
+ * Return: none
+ */
+void dp_periodic_sta_stats_mutex_create(struct wlan_dp_intf *dp_intf);
+
+/**
+ * dp_periodic_sta_stats_mutex_destroy() - Destroy STA periodic stats mutex
+ * @dp_intf: Pointer to the station interface
+ *
+ * Return: none
+ */
+void dp_periodic_sta_stats_mutex_destroy(struct wlan_dp_intf *dp_intf);
+
+#else
+static inline void
+dp_periodic_sta_stats_display(struct wlan_dp_psoc_context *dp_ctx)
+{
+}
+
+static inline void
+dp_periodic_sta_stats_config(struct wlan_dp_psoc_cfg *config,
+			     struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline void dp_periodic_sta_stats_start(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline void dp_periodic_sta_stats_stop(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline void
+dp_periodic_sta_stats_init(struct wlan_dp_intf *dp_intf)
+{
+}
+
+static inline void
+dp_periodic_sta_stats_mutex_create(struct wlan_dp_intf *dp_intf)
+{
+}
+
+static inline void
+dp_periodic_sta_stats_mutex_destroy(struct wlan_dp_intf *dp_intf)
+{
+}
+#endif /* end #ifdef WLAN_FEATURE_PERIODIC_STA_STATS */
+#endif /* end #if !defined(WLAN_DP_PERIODIC_STA_STATS_H) */

+ 163 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_prealloc.h

@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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_DP_PREALLOC_H
+#define _WLAN_DP_PREALLOC_H
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_dp_rx_thread.h>
+#include <qdf_trace.h>
+#include <cdp_txrx_cmn_struct.h>
+#include <cdp_txrx_cmn.h>
+
+#ifdef DP_MEM_PRE_ALLOC
+/**
+ * dp_prealloc_init() - Pre-allocate DP memory
+ * @ctrl_psoc: objmgr psoc
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_prealloc_init(struct cdp_ctrl_objmgr_psoc *ctrl_psoc);
+
+/**
+ * dp_prealloc_deinit() - Free pre-alloced DP memory
+ *
+ * Return: None
+ */
+void dp_prealloc_deinit(void);
+
+/**
+ * dp_prealloc_get_context_memory() - gets pre-alloc DP context memory from
+ *				      global pool
+ * @ctxt_type: type of DP context
+ * @ctxt_size: size of memory needed
+ *
+ * This is done only as part of init happening in a single context. Hence
+ * no lock is used for protection
+ *
+ * Return: Address of context
+ */
+void *dp_prealloc_get_context_memory(uint32_t ctxt_type, qdf_size_t ctxt_size);
+
+/**
+ * dp_prealloc_put_context_memory() - puts back pre-alloc DP context memory to
+ *				      global pool
+ * @ctxt_type: type of DP context
+ * @vaddr: address of DP context
+ *
+ * This is done only as part of de-init happening in a single context. Hence
+ * no lock is used for protection
+ *
+ * Return: Failure if address not found
+ */
+QDF_STATUS dp_prealloc_put_context_memory(uint32_t ctxt_type, void *vaddr);
+
+/**
+ * dp_prealloc_get_coherent() - gets pre-alloc DP memory
+ * @size: size of memory needed
+ * @base_vaddr_unaligned: Unaligned virtual address.
+ * @paddr_unaligned: Unaligned physical address.
+ * @paddr_aligned: Aligned physical address.
+ * @align: Base address alignment.
+ * @align: alignment needed
+ * @ring_type: HAL ring type
+ *
+ * The function does not handle concurrent access to pre-alloc memory.
+ * All ring memory allocation from pre-alloc memory should happen from single
+ * context to avoid race conditions.
+ *
+ * Return: unaligned virtual address if success or null if memory alloc fails.
+ */
+void *dp_prealloc_get_coherent(uint32_t *size, void **base_vaddr_unaligned,
+			       qdf_dma_addr_t *paddr_unaligned,
+			       qdf_dma_addr_t *paddr_aligned,
+			       uint32_t align,
+			       uint32_t ring_type);
+
+/**
+ * dp_prealloc_put_coherent() - puts back pre-alloc DP memory
+ * @size: size of memory to be returned
+ * @vaddr_unligned: Unaligned virtual address.
+ * @paddr: Physical address
+ *
+ * Return: None
+ */
+void dp_prealloc_put_coherent(qdf_size_t size, void *vaddr_unligned,
+			      qdf_dma_addr_t paddr);
+
+/**
+ * dp_prealloc_get_multi_pages() - gets pre-alloc DP multi-pages memory
+ * @src_type: the source that do memory allocation
+ * @element_size: single element size
+ * @element_num: total number of elements should be allocated
+ * @pages: multi page information storage
+ * @cacheable: coherent memory or cacheable memory
+ *
+ * Return: None.
+ */
+void dp_prealloc_get_multi_pages(uint32_t src_type,
+				 qdf_size_t element_size,
+				 uint16_t element_num,
+				 struct qdf_mem_multi_page_t *pages,
+				 bool cacheable);
+
+/**
+ * dp_prealloc_put_multi_pages() - puts back pre-alloc DP multi-pages memory
+ * @src_type: the source that do memory freement
+ * @pages: multi page information storage
+ *
+ * Return: None
+ */
+void dp_prealloc_put_multi_pages(uint32_t src_type,
+				 struct qdf_mem_multi_page_t *pages);
+
+/**
+ * dp_prealloc_get_consistent_mem_unaligned() - gets pre-alloc unaligned
+ *						consistent memory
+ * @size: total memory size
+ * @base_addr: pointer to dma address
+ * @ring_type: HAL ring type that requires memory
+ *
+ * Return: memory virtual address pointer on success, NULL on failure
+ */
+void *dp_prealloc_get_consistent_mem_unaligned(qdf_size_t size,
+					       qdf_dma_addr_t *base_addr,
+					       uint32_t ring_type);
+
+/**
+ * dp_prealloc_put_consistent_mem_unaligned() - puts back pre-alloc unaligned
+ *						consistent memory
+ * @va_unaligned: memory virtual address pointer
+ *
+ * Return: None
+ */
+void dp_prealloc_put_consistent_mem_unaligned(void *va_unaligned);
+
+#else
+static inline
+QDF_STATUS dp_prealloc_init(struct cdp_ctrl_objmgr_psoc *ctrl_psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void dp_prealloc_deinit(void) { }
+
+#endif
+
+uint32_t dp_get_tx_inqueue(ol_txrx_soc_handle soc);
+
+#endif /* _WLAN_DP_PREALLOC_H */

+ 979 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_priv.h

@@ -0,0 +1,979 @@
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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: Declare various struct, macros which are used for private to DP.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_DP_PRIV_STRUCT_H_
+#define _WLAN_DP_PRIV_STRUCT_H_
+
+#include "wlan_dp_public_struct.h"
+#include "cdp_txrx_cmn.h"
+#include "wlan_dp_cfg.h"
+#include "wlan_dp_objmgr.h"
+#include <cdp_txrx_misc.h>
+#include <wlan_dp_rx_thread.h>
+#include "qdf_periodic_work.h"
+#include <cds_api.h>
+#include "pld_common.h"
+#include "wlan_dp_nud_tracking.h"
+#include <i_qdf_net_stats.h>
+#include <qdf_types.h>
+#include "htc_api.h"
+#include "wlan_dp_wfds.h"
+
+#ifndef NUM_TX_RX_HISTOGRAM
+#define NUM_TX_RX_HISTOGRAM 128
+#endif
+
+#define NUM_TX_RX_HISTOGRAM_MASK (NUM_TX_RX_HISTOGRAM - 1)
+
+#if defined(WLAN_FEATURE_DP_BUS_BANDWIDTH) && defined(FEATURE_RUNTIME_PM)
+/**
+ * enum dp_rtpm_tput_policy_state - states to track runtime_pm tput policy
+ * @DP_RTPM_TPUT_POLICY_STATE_INVALID: invalid state
+ * @DP_RTPM_TPUT_POLICY_STATE_REQUIRED: state indicating runtime_pm is required
+ * @DP_RTPM_TPUT_POLICY_STATE_NOT_REQUIRED: state indicating runtime_pm is NOT
+ * required
+ */
+enum dp_rtpm_tput_policy_state {
+	DP_RTPM_TPUT_POLICY_STATE_INVALID,
+	DP_RTPM_TPUT_POLICY_STATE_REQUIRED,
+	DP_RTPM_TPUT_POLICY_STATE_NOT_REQUIRED
+};
+
+/**
+ * struct dp_rtpm_tput_policy_context - RTPM throughput policy context
+ * @curr_state: current state of throughput policy (RTPM require or not)
+ * @wake_lock: wakelock for QDF wake_lock acquire/release APIs
+ * @rtpm_lock: lock use for QDF rutime PM prevent/allow APIs
+ * @high_tput_vote: atomic variable to keep track of voting
+ */
+struct dp_rtpm_tput_policy_context {
+	enum dp_rtpm_tput_policy_state curr_state;
+	qdf_wake_lock_t wake_lock;
+	qdf_runtime_lock_t rtpm_lock;
+	qdf_atomic_t high_tput_vote;
+};
+#endif
+
+#define FISA_FLOW_MAX_AGGR_COUNT        16 /* max flow aggregate count */
+
+/**
+ * struct wlan_dp_psoc_cfg - DP configuration parameters.
+ * @tx_orphan_enable: Enable/Disable tx orphan
+ * @rx_mode: rx mode for packet processing
+ * @tx_comp_loop_pkt_limit: max # of packets to be processed
+ * @rx_reap_loop_pkt_limit: max # of packets to be reaped
+ * @rx_hp_oos_update_limit: max # of HP OOS (out of sync)
+ * @rx_softirq_max_yield_duration_ns: max duration for RX softirq
+ * @periodic_stats_timer_interval: Print selective stats on this specified
+ * interval
+ * @periodic_stats_timer_duration: duration for which periodic timer should run
+ * @bus_bw_super_high_threshold: bus bandwidth super high threshold
+ * @bus_bw_ultra_high_threshold: bus bandwidth ultra high threshold
+ * @bus_bw_very_high_threshold: bus bandwidth very high threshold
+ * @bus_bw_mid_high_threshold: bus bandwidth mid high threshold
+ * @bus_bw_dbs_threshold: bus bandwidth for DBS mode threshold
+ * @bus_bw_high_threshold: bus bandwidth high threshold
+ * @bus_bw_medium_threshold: bandwidth threshold for medium bandwidth
+ * @bus_bw_low_threshold: bandwidth threshold for low bandwidth
+ * @bus_bw_compute_interval: bus bandwidth compute interval
+ * @enable_tcp_delack: enable Dynamic Configuration of Tcp Delayed Ack
+ * @enable_tcp_limit_output: enable TCP limit output
+ * @enable_tcp_adv_win_scale: enable  TCP adv window scaling
+ * @tcp_delack_thres_high: High Threshold inorder to trigger TCP Del Ack
+ * indication
+ * @tcp_delack_thres_low: Low Threshold inorder to trigger TCP Del Ack
+ * indication
+ * @tcp_tx_high_tput_thres: High Threshold inorder to trigger High Tx
+ * Throughput requirement.
+ * @tcp_delack_timer_count: Del Ack Timer Count inorder to trigger TCP Del Ack
+ * indication
+ * @enable_tcp_param_update: enable tcp parameter update
+ * @bus_low_cnt_threshold: Threshold count to trigger low Tput GRO flush skip
+ * @enable_latency_crit_clients: Enable the handling of latency critical clients
+ * * @del_ack_enable: enable Dynamic Configuration of Tcp Delayed Ack
+ * @del_ack_threshold_high: High Threshold inorder to trigger TCP delay ack
+ * @del_ack_threshold_low: Low Threshold inorder to trigger TCP delay ack
+ * @del_ack_timer_value: Timeout value (ms) to send out all TCP del ack frames
+ * @del_ack_pkt_count: The maximum number of TCP delay ack frames
+ * @rx_thread_ul_affinity_mask: CPU mask to affine Rx_thread
+ * @rx_thread_affinity_mask: CPU mask to affine Rx_thread
+ * @cpu_map_list: RPS map for different RX queues
+ * @multicast_replay_filter: enable filtering of replayed multicast packets
+ * @rx_wakelock_timeout: Amount of time to hold wakelock for RX unicast packets
+ * @num_dp_rx_threads: number of dp rx threads
+ * @enable_dp_trace: Enable/Disable DP trace
+ * @dp_trace_config: DP trace configuration
+ * @enable_nud_tracking: Enable/Disable nud tracking
+ * @pkt_bundle_threshold_high: tx bundle high threshold
+ * @pkt_bundle_threshold_low: tx bundle low threshold
+ * @pkt_bundle_timer_value: tx bundle timer value in ms
+ * @pkt_bundle_size: tx bundle size
+ * @dp_proto_event_bitmap: Control for which protocol type diag log should be
+ * sent
+ * @fisa_enable: Enable/Disable FISA
+ * @icmp_req_to_fw_mark_interval: Interval to mark the ICMP Request packet to
+ * be sent to FW.
+ * @lro_enable: Enable/Disable lro
+ * @gro_enable: Enable/Disable gro
+ * @is_rx_fisa_enabled: flag to enable/disable FISA Rx
+ * @is_rx_fisa_lru_del_enabled: flag to enable/disable FST entry delete
+ */
+struct wlan_dp_psoc_cfg {
+	bool tx_orphan_enable;
+
+	uint32_t rx_mode;
+	uint32_t tx_comp_loop_pkt_limit;
+	uint32_t rx_reap_loop_pkt_limit;
+	uint32_t rx_hp_oos_update_limit;
+	uint64_t rx_softirq_max_yield_duration_ns;
+#ifdef WLAN_FEATURE_PERIODIC_STA_STATS
+	uint32_t periodic_stats_timer_interval;
+	uint32_t periodic_stats_timer_duration;
+#endif /* WLAN_FEATURE_PERIODIC_STA_STATS */
+#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
+	uint32_t bus_bw_super_high_threshold;
+	uint32_t bus_bw_ultra_high_threshold;
+	uint32_t bus_bw_very_high_threshold;
+	uint32_t bus_bw_dbs_threshold;
+	uint32_t bus_bw_mid_high_threshold;
+	uint32_t bus_bw_high_threshold;
+	uint32_t bus_bw_medium_threshold;
+	uint32_t bus_bw_low_threshold;
+	uint32_t bus_bw_compute_interval;
+	uint32_t enable_tcp_delack;
+	bool     enable_tcp_limit_output;
+	uint32_t enable_tcp_adv_win_scale;
+	uint32_t tcp_delack_thres_high;
+	uint32_t tcp_delack_thres_low;
+	uint32_t tcp_tx_high_tput_thres;
+	uint32_t tcp_delack_timer_count;
+	bool     enable_tcp_param_update;
+	uint32_t bus_low_cnt_threshold;
+	bool enable_latency_crit_clients;
+#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
+
+#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
+	bool del_ack_enable;
+	uint32_t del_ack_threshold_high;
+	uint32_t del_ack_threshold_low;
+	uint16_t del_ack_timer_value;
+	uint16_t del_ack_pkt_count;
+#endif
+	uint32_t rx_thread_ul_affinity_mask;
+	uint32_t rx_thread_affinity_mask;
+	uint8_t cpu_map_list[CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN];
+	bool multicast_replay_filter;
+	uint32_t rx_wakelock_timeout;
+	uint8_t num_dp_rx_threads;
+#ifdef CONFIG_DP_TRACE
+	bool enable_dp_trace;
+	uint8_t dp_trace_config[DP_TRACE_CONFIG_STRING_LENGTH];
+#endif
+	uint8_t enable_nud_tracking;
+
+#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE
+	uint32_t pkt_bundle_threshold_high;
+	uint32_t pkt_bundle_threshold_low;
+	uint16_t pkt_bundle_timer_value;
+	uint16_t pkt_bundle_size;
+#endif
+	uint32_t dp_proto_event_bitmap;
+	uint32_t fisa_enable;
+
+	int icmp_req_to_fw_mark_interval;
+
+	bool lro_enable;
+	bool gro_enable;
+#ifdef WLAN_SUPPORT_RX_FISA
+	bool is_rx_fisa_enabled;
+	bool is_rx_fisa_lru_del_enabled;
+#endif
+};
+
+/**
+ * struct tx_rx_histogram: structure to keep track of tx and rx packets
+ *				received over 100ms intervals
+ * @interval_rx:	# of rx packets received in the last 100ms interval
+ * @interval_tx:	# of tx packets received in the last 100ms interval
+ * @next_vote_level:	pld_bus_width_type voting level (high or low)
+ *			determined on the basis of total tx and rx packets
+ *			received in the last 100ms interval
+ * @next_rx_level:	pld_bus_width_type voting level (high or low)
+ *			determined on the basis of rx packets received in the
+ *			last 100ms interval
+ * @next_tx_level:	pld_bus_width_type voting level (high or low)
+ *			determined on the basis of tx packets received in the
+ *			last 100ms interval
+ * @is_rx_pm_qos_high: Capture rx_pm_qos voting
+ * @is_tx_pm_qos_high: Capture tx_pm_qos voting
+ * @qtime: timestamp when the record is added
+ *
+ * The structure keeps track of throughput requirements of wlan driver.
+ * An entry is added if either of next_vote_level, next_rx_level or
+ * next_tx_level changes. An entry is not added for every 100ms interval.
+ */
+struct tx_rx_histogram {
+	uint64_t interval_rx;
+	uint64_t interval_tx;
+	uint32_t next_vote_level;
+	uint32_t next_rx_level;
+	uint32_t next_tx_level;
+	bool is_rx_pm_qos_high;
+	bool is_tx_pm_qos_high;
+	uint64_t qtime;
+};
+
+/**
+ * struct dp_stats - DP stats
+ * @tx_rx_stats : Tx/Rx debug stats
+ * @arp_stats: arp debug stats
+ * @dns_stats: dns debug stats
+ * @tcp_stats: tcp debug stats
+ * @icmpv4_stats: icmpv4 debug stats
+ * @dhcp_stats: dhcp debug stats
+ * @eapol_stats: eapol debug stats
+ */
+struct dp_stats {
+	struct dp_tx_rx_stats tx_rx_stats;
+	struct dp_arp_stats arp_stats;
+	struct dp_dns_stats dns_stats;
+	struct dp_tcp_stats tcp_stats;
+	struct dp_icmpv4_stats icmpv4_stats;
+	struct dp_dhcp_stats dhcp_stats;
+	struct dp_eapol_stats eapol_stats;
+};
+
+/**
+ * enum dhcp_phase - Per Peer DHCP Phases
+ * @DHCP_PHASE_ACK: upon receiving DHCP_ACK/NAK message in REQUEST phase or
+ *         DHCP_DELINE message in OFFER phase
+ * @DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase
+ * @DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase
+ * @DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase or
+ *         ACK phase (Renewal process)
+ */
+enum dhcp_phase {
+	DHCP_PHASE_ACK,
+	DHCP_PHASE_DISCOVER,
+	DHCP_PHASE_OFFER,
+	DHCP_PHASE_REQUEST
+};
+
+/**
+ * enum dhcp_nego_status - Per Peer DHCP Negotiation Status
+ * @DHCP_NEGO_STOP: when the peer is in ACK phase or client disassociated
+ * @DHCP_NEGO_IN_PROGRESS: when the peer is in DISCOVER or REQUEST
+ *         (Renewal process) phase
+ */
+enum dhcp_nego_status {
+	DHCP_NEGO_STOP,
+	DHCP_NEGO_IN_PROGRESS
+};
+
+/*
+ * Pending frame type of EAP_FAILURE, bit number used in "pending_eap_frm_type"
+ * of sta_info.
+ */
+#define DP_PENDING_TYPE_EAP_FAILURE  0
+
+enum bss_intf_state {
+	BSS_INTF_STOP,
+	BSS_INTF_START,
+};
+
+struct wlan_dp_sta_info {
+	struct qdf_mac_addr sta_mac;
+	unsigned long pending_eap_frm_type;
+	enum dhcp_phase dhcp_phase;
+	enum dhcp_nego_status dhcp_nego_status;
+};
+
+struct wlan_dp_conn_info {
+	struct qdf_mac_addr bssid;
+	struct qdf_mac_addr peer_macaddr;
+	uint8_t proxy_arp_service;
+	uint8_t is_authenticated;
+};
+
+/**
+ * struct link_monitoring - link speed monitoring related info
+ * @enabled: Is link speed monitoring feature enabled
+ * @rx_linkspeed_threshold: link speed good/bad threshold
+ * @is_rx_linkspeed_good: true means rx link speed good, false means bad
+ */
+struct link_monitoring {
+	uint8_t enabled;
+	uint32_t rx_linkspeed_threshold;
+	uint8_t is_rx_linkspeed_good;
+};
+
+/**
+ * struct direct_link_info - direct link configuration items
+ * @config_set: is the direct link config active
+ * @low_latency: is low latency enabled
+ */
+struct direct_link_info {
+	bool config_set;
+	bool low_latency;
+};
+
+/**
+ * struct dp_fisa_reo_mismatch_stats - reo mismatch sub-case stats for FISA
+ * @allow_cce_match: packet allowed due to cce mismatch
+ * @allow_fse_metdata_mismatch: packet allowed since it belongs to same flow,
+ *			only fse_metadata is not same.
+ * @allow_non_aggr: packet allowed due to any other reason.
+ */
+struct dp_fisa_reo_mismatch_stats {
+	uint32_t allow_cce_match;
+	uint32_t allow_fse_metdata_mismatch;
+	uint32_t allow_non_aggr;
+};
+
+/**
+ * struct dp_fisa_stats - FISA stats
+ * @invalid_flow_index: flow index invalid from RX HW TLV
+ * @update_deferred: workqueue deferred due to suspend
+ * @reo_mismatch: REO ID mismatch
+ * @incorrect_rdi: Incorrect REO dest indication in TLV
+ *		   (typically used for RDI = 0)
+ */
+struct dp_fisa_stats {
+	uint32_t invalid_flow_index;
+	uint32_t update_deferred;
+	struct dp_fisa_reo_mismatch_stats reo_mismatch;
+	uint32_t incorrect_rdi;
+};
+
+/**
+ * enum fisa_aggr_ret - FISA aggregation return code
+ * @FISA_AGGR_DONE: FISA aggregation done
+ * @FISA_AGGR_NOT_ELIGIBLE: Not eligible for FISA aggregation
+ * @FISA_FLUSH_FLOW: FISA flow flushed
+ */
+enum fisa_aggr_ret {
+	FISA_AGGR_DONE,
+	FISA_AGGR_NOT_ELIGIBLE,
+	FISA_FLUSH_FLOW
+};
+
+/**
+ * struct fisa_pkt_hist - FISA Packet history structure
+ * @tlv_hist: array of TLV history
+ * @ts_hist: array of timestamps of fisa packets
+ * @idx: index indicating the next location to be used in the array.
+ */
+struct fisa_pkt_hist {
+	uint8_t *tlv_hist;
+	qdf_time_t ts_hist[FISA_FLOW_MAX_AGGR_COUNT];
+	uint32_t idx;
+};
+
+/**
+ * struct dp_fisa_rx_sw_ft - FISA Flow table entry
+ * @hw_fse: HAL Rx Flow Search Entry which matches HW definition
+ * @flow_hash: Flow hash value
+ * @flow_id_toeplitz: toeplitz hash value
+ * @flow_id: Flow index, equivalent to hash value truncated to FST size
+ * @stats: Stats tracking for this flow
+ * @is_ipv4_addr_entry: Flag indicating whether flow is IPv4 address tuple
+ * @is_valid: Flag indicating whether flow is valid
+ * @is_populated: Flag indicating whether flow is populated
+ * @is_flow_udp: Flag indicating whether flow is UDP stream
+ * @is_flow_tcp: Flag indicating whether flow is TCP stream
+ * @head_skb: HEAD skb where flow is aggregated
+ * @cumulative_l4_checksum: Cumulative L4 checksum
+ * @adjusted_cumulative_ip_length: Cumulative IP length
+ * @cur_aggr: Current aggregate length of flow
+ * @napi_flush_cumulative_l4_checksum: Cumulative L4 chekcsum for current
+ *				       NAPI flush
+ * @napi_flush_cumulative_ip_length: Cumulative IP length
+ * @last_skb: The last skb aggregated in the FISA flow
+ * @head_skb_ip_hdr_offset: IP header offset
+ * @head_skb_l4_hdr_offset: L4 header offset
+ * @rx_flow_tuple_info: RX tuple information
+ * @napi_id: NAPI ID (REO ID) on which the flow is being received
+ * @vdev: VDEV handle corresponding to the FLOW
+ * @vdev_id: DP vdev id
+ * @dp_intf: DP interface handle corresponding to the flow
+ * @bytes_aggregated: Number of bytes currently aggregated
+ * @flush_count: Number of Flow flushes done
+ * @aggr_count: Aggregation count
+ * @do_not_aggregate: Flag to indicate not to aggregate this flow
+ * @hal_cumultive_ip_len: HAL cumulative IP length
+ * @dp_ctx: DP component handle
+ * @soc_hdl: DP SoC handle
+ * @last_hal_aggr_count: last aggregate count fetched from RX PKT TLV
+ * @cur_aggr_gso_size: Current aggreagtesd GSO size
+ * @head_skb_udp_hdr: UDP header address for HEAD skb
+ * @frags_cumulative_len:
+ * @cmem_offset: CMEM offset
+ * @metadata:
+ * @reo_dest_indication: REO destination indication for the FLOW
+ * @flow_init_ts: FLOW init timestamp
+ * @last_accessed_ts: Timestamp when the flow was last accessed
+ * @pkt_hist: FISA aggreagtion packets history
+ * @same_mld_vdev_mismatch: Packets flushed after vdev_mismatch on same MLD
+ * @add_timestamp: FISA entry created timestamp
+ */
+struct dp_fisa_rx_sw_ft {
+	void *hw_fse;
+	uint32_t flow_hash;
+	uint32_t flow_id_toeplitz;
+	uint32_t flow_id;
+	struct cdp_flow_stats stats;
+	uint8_t is_ipv4_addr_entry;
+	uint8_t is_valid;
+	uint8_t is_populated;
+	uint8_t is_flow_udp;
+	uint8_t is_flow_tcp;
+	qdf_nbuf_t head_skb;
+	uint16_t cumulative_l4_checksum;
+	uint16_t adjusted_cumulative_ip_length;
+	uint16_t cur_aggr;
+	uint16_t napi_flush_cumulative_l4_checksum;
+	uint16_t napi_flush_cumulative_ip_length;
+	qdf_nbuf_t last_skb;
+	uint32_t head_skb_ip_hdr_offset;
+	uint32_t head_skb_l4_hdr_offset;
+	struct cdp_rx_flow_tuple_info rx_flow_tuple_info;
+	uint8_t napi_id;
+	struct dp_vdev *vdev;
+	uint8_t vdev_id;
+	struct wlan_dp_intf *dp_intf;
+	uint64_t bytes_aggregated;
+	uint32_t flush_count;
+	uint32_t aggr_count;
+	uint8_t do_not_aggregate;
+	uint16_t hal_cumultive_ip_len;
+	struct wlan_dp_psoc_context *dp_ctx;
+	/* TODO - Only reference needed to this is to get vdev.
+	 * Once that ref is removed, this field can be deleted
+	 */
+	struct dp_soc *soc_hdl;
+	uint32_t last_hal_aggr_count;
+	uint32_t cur_aggr_gso_size;
+	qdf_net_udphdr_t *head_skb_udp_hdr;
+	uint16_t frags_cumulative_len;
+	uint32_t cmem_offset;
+	uint32_t metadata;
+	uint32_t reo_dest_indication;
+	qdf_time_t flow_init_ts;
+	qdf_time_t last_accessed_ts;
+#ifdef WLAN_SUPPORT_RX_FISA_HIST
+	struct fisa_pkt_hist pkt_hist;
+#endif
+	uint64_t same_mld_vdev_mismatch;
+	uint64_t add_timestamp;
+};
+
+#define DP_RX_GET_SW_FT_ENTRY_SIZE sizeof(struct dp_fisa_rx_sw_ft)
+#define MAX_FSE_CACHE_FL_HST 10
+/**
+ * struct fse_cache_flush_history - Debug history cache flush
+ * @timestamp: Entry update timestamp
+ * @flows_added: Number of flows added for this flush
+ * @flows_deleted: Number of flows deleted for this flush
+ */
+struct fse_cache_flush_history {
+	uint64_t timestamp;
+	uint32_t flows_added;
+	uint32_t flows_deleted;
+};
+
+/**
+ * struct dp_rx_fst - FISA handle
+ * @base: Software (DP) FST
+ * @dp_ctx: DP component handle
+ * @hal_rx_fst: Pointer to HAL FST
+ * @hal_rx_fst_base_paddr: Base physical address of HAL RX HW FST
+ * @max_entries: Maximum number of flows FSE supports
+ * @num_entries: Num entries in flow table
+ * @max_skid_length: SKID Length
+ * @hash_mask: Hash mask to obtain legitimate hash entry
+ * @dp_rx_fst_lock: Lock for adding/deleting entries of FST
+ * @add_flow_count: Num of flows added
+ * @del_flow_count: Num of flows deleted
+ * @hash_collision_cnt: Num hash collisions
+ * @soc_hdl: DP SoC handle
+ * @fse_cache_flush_posted: Num FSE cache flush cmds posted
+ * @fse_cache_flush_timer: FSE cache flush timer
+ * @fse_cache_flush_allow: Flag to indicate if FSE cache flush is allowed
+ * @cache_fl_rec: FSE cache flush history
+ * @stats: FISA stats
+ * @fst_update_work: FST CMEM update work
+ * @fst_update_wq: FST CMEM update workqueue
+ * @fst_update_list: List to post event to CMEM update work
+ * @meta_counter:
+ * @cmem_ba:
+ * @dp_rx_sw_ft_lock: SW FST lock
+ * @cmem_resp_event: CMEM response event indicator
+ * @flow_deletion_supported: Flag to indicate if flow delete is supported
+ * @fst_in_cmem: Flag to indicate if FST is stored in CMEM
+ * @pm_suspended: Flag to indicate if driver is suspended
+ * @fst_wq_defer:
+ * @rx_hash_enabled: Flag to indicate if Hash based routing supported
+ * @rx_toeplitz_hash_key: hash key
+ * @rx_pkt_tlv_size: RX packet TLV size
+ */
+struct dp_rx_fst {
+	uint8_t *base;
+	struct wlan_dp_psoc_context *dp_ctx;
+	struct hal_rx_fst *hal_rx_fst;
+	uint64_t hal_rx_fst_base_paddr;
+	uint16_t max_entries;
+	uint16_t num_entries;
+	uint16_t max_skid_length;
+	uint32_t hash_mask;
+	qdf_spinlock_t dp_rx_fst_lock;
+	uint32_t add_flow_count;
+	uint32_t del_flow_count;
+	uint32_t hash_collision_cnt;
+	struct dp_soc *soc_hdl;
+	qdf_atomic_t fse_cache_flush_posted;
+	qdf_timer_t fse_cache_flush_timer;
+	bool fse_cache_flush_allow;
+	struct fse_cache_flush_history cache_fl_rec[MAX_FSE_CACHE_FL_HST];
+	struct dp_fisa_stats stats;
+
+	/* CMEM params */
+	qdf_work_t fst_update_work;
+	qdf_workqueue_t *fst_update_wq;
+	qdf_list_t fst_update_list;
+	uint32_t meta_counter;
+	uint32_t cmem_ba;
+	qdf_spinlock_t dp_rx_sw_ft_lock[MAX_REO_DEST_RINGS];
+	qdf_event_t cmem_resp_event;
+	bool flow_deletion_supported;
+	bool fst_in_cmem;
+	qdf_atomic_t pm_suspended;
+	bool fst_wq_defer;
+	bool rx_hash_enabled;
+	uint8_t *rx_toeplitz_hash_key;
+	uint16_t rx_pkt_tlv_size;
+};
+
+/**
+ * struct wlan_dp_intf - DP interface object related info
+ * @dp_ctx: DP context reference
+ * @link_monitoring: Link monitoring related info
+ * @mac_addr: Device MAC address
+ * @device_mode: Device Mode
+ * @intf_id: Interface ID
+ * @node: list node for membership in the interface list
+ * @dev: netdev reference
+ * @txrx_ops: Interface tx-rx ops
+ * @dp_stats: Device TX/RX statistics
+ * @is_sta_periodic_stats_enabled: Indicate whether to display sta periodic
+ * stats
+ * @periodic_stats_timer_count: count of periodic stats timer
+ * @periodic_stats_timer_counter: periodic stats timer counter
+ * @sta_periodic_stats_lock: sta periodic stats lock
+ * @stats: netdev stats
+ * @con_status: con_status value
+ * @dad: dad value
+ * @pkt_type_bitmap: packet type bitmap value
+ * @track_arp_ip: track ARP ip
+ * @dns_payload: dns payload
+ * @track_dns_domain_len: dns domain length
+ * @track_src_port: track source port value
+ * @track_dest_port: track destination port value
+ * @track_dest_ipv4: track destination ipv4 value
+ * @prev_rx_packets: Rx packets received N/W interface
+ * @prev_tx_packets: Tx packets transmitted on N/W interface
+ * @prev_tx_bytes: Tx bytes transmitted on N/W interface
+ * @prev_fwd_tx_packets: forwarded tx packets count
+ * @prev_fwd_rx_packets: forwarded rx packets count
+ * @nud_tracking: NUD tracking
+ * @mic_work: Work to handle MIC error
+ * @num_active_task: Active task count
+ * @sap_tx_block_mask: SAP TX block mask
+ * @gro_disallowed: GRO disallowed flag
+ * @gro_flushed: GRO flushed flag
+ * @fisa_disallowed: Flag to indicate fisa aggregation not to be done for a
+ *		     particular rx_context
+ * @fisa_force_flushed: Flag to indicate FISA flow has been flushed for a
+ *			particular rx_context
+ * @runtime_disable_rx_thread: Runtime Rx thread flag
+ * @rx_stack: function pointer Rx packet handover
+ * @tx_fn: function pointer to send Tx packet
+ * @bss_state: AP BSS state
+ * @qdf_sta_eap_frm_done_event: EAP frame event management
+ * @traffic_end_ind: store traffic end indication info
+ * @direct_link_config: direct link configuration parameters
+ * @num_links: Number of links for this DP interface
+ * @def_link: Pointer to default link (usually used for TX operation)
+ * @dp_link_list_lock: Lock to protect dp_link_list operatiosn
+ * @dp_link_list: List of dp_links for this DP interface
+ */
+struct wlan_dp_intf {
+	struct wlan_dp_psoc_context *dp_ctx;
+
+	struct link_monitoring link_monitoring;
+
+	struct qdf_mac_addr mac_addr;
+
+	enum QDF_OPMODE device_mode;
+
+	qdf_list_node_t node;
+
+	qdf_netdev_t dev;
+	struct ol_txrx_ops txrx_ops;
+	struct dp_stats dp_stats;
+#ifdef WLAN_FEATURE_PERIODIC_STA_STATS
+	bool is_sta_periodic_stats_enabled;
+	uint16_t periodic_stats_timer_count;
+	uint32_t periodic_stats_timer_counter;
+	qdf_mutex_t sta_periodic_stats_lock;
+#endif /* WLAN_FEATURE_PERIODIC_STA_STATS */
+	qdf_net_dev_stats stats;
+	bool con_status;
+	bool dad;
+	uint32_t pkt_type_bitmap;
+	uint32_t track_arp_ip;
+	uint8_t dns_payload[256];
+	uint32_t track_dns_domain_len;
+	uint32_t track_src_port;
+	uint32_t track_dest_port;
+	uint32_t track_dest_ipv4;
+#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
+	unsigned long prev_rx_packets;
+	unsigned long prev_tx_packets;
+	unsigned long prev_tx_bytes;
+	uint64_t prev_fwd_tx_packets;
+	uint64_t prev_fwd_rx_packets;
+#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
+	struct dp_mic_work mic_work;
+#ifdef WLAN_NUD_TRACKING
+	struct dp_nud_tracking_info nud_tracking;
+#endif
+	qdf_atomic_t num_active_task;
+	uint32_t sap_tx_block_mask;
+
+	qdf_atomic_t gro_disallowed;
+	uint8_t gro_flushed[DP_MAX_RX_THREADS];
+
+#ifdef WLAN_SUPPORT_RX_FISA
+	/*
+	 * Params used for controlling the fisa aggregation dynamically
+	 */
+	uint8_t fisa_disallowed[MAX_REO_DEST_RINGS];
+	uint8_t fisa_force_flushed[MAX_REO_DEST_RINGS];
+#endif
+
+	bool runtime_disable_rx_thread;
+
+	enum bss_intf_state bss_state;
+	qdf_event_t qdf_sta_eap_frm_done_event;
+	struct dp_traffic_end_indication traffic_end_ind;
+#ifdef FEATURE_DIRECT_LINK
+	struct direct_link_info direct_link_config;
+#endif
+	uint8_t num_links;
+	struct wlan_dp_link *def_link;
+	qdf_spinlock_t dp_link_list_lock;
+	qdf_list_t dp_link_list;
+};
+
+#define WLAN_DP_LINK_MAGIC 0x5F44505F4C494E4B	/* "_DP_LINK" in ASCII */
+
+/**
+ * struct wlan_dp_link - DP link (corresponds to objmgr vdev)
+ * @node: list node for membership in the DP links list
+ * @magic: magic number to identify validity of dp_link
+ * @link_id: ID for this DP link (Same as vdev_id)
+ * @mac_addr: mac address of this link
+ * @dp_intf: Parent DP interface for this DP link
+ * @vdev: object manager vdev context
+ * @vdev_lock: vdev spin lock
+ * @conn_info: STA connection information
+ * @destroyed: flag to indicate dp_link destroyed (logical delete)
+ * @cdp_vdev_registered: flag to indicate if corresponding CDP vdev
+ *			 is registered
+ * @cdp_vdev_deleted: flag to indicate if corresponding CDP vdev is deleted
+ * @inactive_list_elem: list node for membership in dp link inactive list
+ */
+struct wlan_dp_link {
+	qdf_list_node_t node;
+	uint64_t magic;
+	uint8_t link_id;
+	struct qdf_mac_addr mac_addr;
+	struct wlan_dp_intf *dp_intf;
+	struct wlan_objmgr_vdev *vdev;
+	qdf_spinlock_t vdev_lock;
+	struct wlan_dp_conn_info conn_info;
+	uint8_t destroyed;
+	uint8_t cdp_vdev_registered;
+	uint8_t	cdp_vdev_deleted;
+	TAILQ_ENTRY(wlan_dp_link) inactive_list_elem;
+};
+
+/**
+ * enum RX_OFFLOAD - Receive offload modes
+ * @CFG_LRO_ENABLED: Large Rx offload
+ * @CFG_GRO_ENABLED: Generic Rx Offload
+ */
+enum RX_OFFLOAD {
+	CFG_LRO_ENABLED = 1,
+	CFG_GRO_ENABLED,
+};
+
+#ifdef FEATURE_DIRECT_LINK
+/**
+ * struct dp_direct_link_context - Datapath Direct Link context
+ * @dp_ctx: pointer to DP psoc priv context
+ * @lpass_ep_id: LPASS data msg service endpoint id
+ * @direct_link_refill_ring_hdl: Direct Link refill ring handle
+ * @dl_wfds: pointer to direct link WFDS context
+ */
+struct dp_direct_link_context {
+	struct wlan_dp_psoc_context *dp_ctx;
+	HTC_ENDPOINT_ID lpass_ep_id;
+	struct dp_srng *direct_link_refill_ring_hdl;
+	struct dp_direct_link_wfds_context *dl_wfds;
+};
+#endif
+
+/**
+ * struct wlan_dp_psoc_context - psoc related data required for DP
+ * @psoc: object manager psoc context
+ * @pdev: object manager pdev context
+ * @qdf_dev: qdf device
+ * @dp_cfg: place holder for DP configuration
+ * @cdp_soc: CDP SoC handle
+ * @hif_handle: HIF handle
+ * @hal_soc: HAL SoC handle
+ * @intf_list_lock: DP interfaces list lock
+ * @intf_list: DP interfaces list
+ * @rps: rps
+ * @dynamic_rps: dynamic rps
+ * @enable_rxthread: Enable/Disable rx thread
+ * @enable_dp_rx_threads: Enable/Disable DP rx threads
+ * @napi_enable: Enable/Disable napi
+ * @dp_ops: DP callbacks registered from other modules
+ * @sb_ops: South bound direction call backs registered in DP
+ * @nb_ops: North bound direction call backs registered in DP
+ * @en_tcp_delack_no_lro: Enable/Disable tcp delack no lro
+ * @no_rx_offload_pkt_cnt: no of rx offload packet count
+ * @no_tx_offload_pkt_cnt: no of tx offload packet count
+ * @is_suspend: to check whether syetem suspend or not
+ * @is_wiphy_suspended: to check whether wiphy suspend or not
+ * @num_latency_critical_clients: num latency critical clients
+ * @high_bus_bw_request: high bus bandwidth request
+ * @bw_vote_time: bus bandwidth vote time
+ * @bus_bw_work: work for periodically computing DDR bus bandwidth requirements
+ * @cur_vote_level: Current vote level
+ * @prev_no_rx_offload_pkts: no of previous rx offload packets
+ * @prev_rx_offload_pkts: previous rx offload packets
+ * @prev_no_tx_offload_pkts: no of previous tx offload packets
+ * @prev_tx_offload_pkts: previous tx offload packets
+ * @cur_tx_level: Current Tx level
+ * @prev_tx: previous tx
+ * @low_tput_gro_enable: Enable/Disable low tput gro
+ * @bus_bw_lock: Bus bandwidth work lock
+ * @cur_rx_level: Current Rx level
+ * @bus_low_vote_cnt: bus low level count
+ * @disable_rx_ol_in_concurrency: disable RX offload in concurrency scenarios
+ * @disable_rx_ol_in_low_tput: disable RX offload in tput scenarios
+ * @txrx_hist_idx: txrx histogram index
+ * @rx_high_ind_cnt: rx high_ind count
+ * @receive_offload_cb: receive offload cb
+ * @dp_agg_param: DP aggregation parameter
+ * @dp_agg_param.rx_aggregation:
+ * @dp_agg_param.gro_force_flush:
+ * @dp_agg_param.tc_based_dyn_gro:
+ * @dp_agg_param.tc_ingress_prio:
+ * @rtpm_tput_policy_ctx: Runtime Tput policy context
+ * @txrx_hist: TxRx histogram
+ * @bbm_ctx: bus bandwidth manager context
+ * @dp_direct_link_lock: Direct link mutex lock
+ * @dp_direct_link_ctx: DP Direct Link context
+ * @arp_connectivity_map: ARP connectivity map
+ * @rx_wake_lock: rx wake lock
+ * @ol_enable: Enable/Disable offload
+ * @rx_fst: FST handle
+ * @fst_cmem_base: FST base in CMEM
+ * @fst_in_cmem: Flag indicating if FST is in CMEM or not
+ * @fisa_enable: Flag to indicate if FISA is enabled or not
+ * @fisa_lru_del_enable: Flag to indicate if LRU flow delete is enabled
+ * @fisa_dynamic_aggr_size_support: Indicate dynamic aggr size programming support
+ * @skip_fisa_param: FISA skip params structure
+ * @skip_fisa_param.skip_fisa: Flag to skip FISA aggr inside @skip_fisa_param
+ * @skip_fisa_param.fisa_force_flush: Force flush inside @skip_fisa_param
+ * @fst_cmem_size: CMEM size for FISA flow table
+ * @inactive_dp_link_list: inactive DP links list
+ * @dp_link_del_lock: DP link delete operation lock
+ */
+struct wlan_dp_psoc_context {
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	qdf_device_t qdf_dev;
+	struct wlan_dp_psoc_cfg dp_cfg;
+	ol_txrx_soc_handle cdp_soc;
+	struct hif_opaque_softc *hif_handle;
+	void *hal_soc;
+
+	qdf_spinlock_t intf_list_lock;
+	qdf_list_t intf_list;
+
+	bool rps;
+	bool dynamic_rps;
+	bool enable_rxthread;
+	bool enable_dp_rx_threads;
+	bool napi_enable;
+
+	struct wlan_dp_psoc_callbacks dp_ops;
+	struct wlan_dp_psoc_sb_ops sb_ops;
+	struct wlan_dp_psoc_nb_ops nb_ops;
+
+	bool en_tcp_delack_no_lro;
+	uint64_t no_rx_offload_pkt_cnt;
+	uint64_t no_tx_offload_pkt_cnt;
+	bool is_suspend;
+	bool is_wiphy_suspended;
+	qdf_atomic_t num_latency_critical_clients;
+	uint8_t high_bus_bw_request;
+	uint64_t bw_vote_time;
+#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
+	struct qdf_periodic_work bus_bw_work;
+	int cur_vote_level;
+	qdf_spinlock_t bus_bw_lock;
+	int cur_rx_level;
+	uint64_t prev_no_rx_offload_pkts;
+	uint64_t prev_rx_offload_pkts;
+	uint64_t prev_no_tx_offload_pkts;
+	uint64_t prev_tx_offload_pkts;
+	int cur_tx_level;
+	uint64_t prev_tx;
+	qdf_atomic_t low_tput_gro_enable;
+	uint32_t bus_low_vote_cnt;
+#ifdef FEATURE_RUNTIME_PM
+	struct dp_rtpm_tput_policy_context rtpm_tput_policy_ctx;
+#endif
+#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
+	qdf_atomic_t disable_rx_ol_in_concurrency;
+	qdf_atomic_t disable_rx_ol_in_low_tput;
+
+	uint16_t txrx_hist_idx;
+	struct tx_rx_histogram *txrx_hist;
+
+	uint32_t rx_high_ind_cnt;
+#ifdef FEATURE_BUS_BANDWIDTH_MGR
+	struct bbm_context *bbm_ctx;
+#endif
+
+	QDF_STATUS(*receive_offload_cb)(struct wlan_dp_intf *, qdf_nbuf_t nbuf);
+
+	struct {
+		qdf_atomic_t rx_aggregation;
+		uint8_t gro_force_flush[DP_MAX_RX_THREADS];
+		bool tc_based_dyn_gro;
+		uint32_t tc_ingress_prio;
+	}
+	dp_agg_param;
+
+	uint32_t arp_connectivity_map;
+
+	qdf_wake_lock_t rx_wake_lock;
+
+	enum RX_OFFLOAD ol_enable;
+#ifdef FEATURE_DIRECT_LINK
+	qdf_mutex_t dp_direct_link_lock;
+	struct dp_direct_link_context *dp_direct_link_ctx;
+#endif
+#ifdef WLAN_SUPPORT_RX_FISA
+	struct dp_rx_fst *rx_fst;
+	uint64_t fst_cmem_base;
+	bool fst_in_cmem;
+	uint8_t fisa_enable;
+	uint8_t fisa_lru_del_enable;
+	bool fisa_dynamic_aggr_size_support;
+	/*
+	 * Params used for controlling the fisa aggregation dynamically
+	 */
+	struct {
+		qdf_atomic_t skip_fisa;
+		uint8_t fisa_force_flush[MAX_REO_DEST_RINGS];
+	} skip_fisa_param;
+
+	/*
+	 * CMEM address and size for FST in CMEM, This is the address
+	 * shared during init time.
+	 */
+	uint64_t fst_cmem_size;
+
+#endif
+	TAILQ_HEAD(, wlan_dp_link) inactive_dp_link_list;
+	qdf_spinlock_t dp_link_del_lock;
+};
+
+#ifdef WLAN_DP_PROFILE_SUPPORT
+/**
+ * enum wlan_dp_cfg_param_type - param context type
+ * @DP_TX_DESC_NUM_CFG: Number of TX desc
+ * @DP_TX_EXT_DESC_NUM_CFG: Number of TX ext desc
+ * @DP_TX_RING_SIZE_CFG: TX ring size
+ * @DP_TX_COMPL_RING_SIZE_CFG: TX completion ring size
+ * @DP_RX_SW_DESC_NUM_CFG: Number of RX S.W descriptors
+ * @DP_REO_DST_RING_SIZE_CFG: RX ring size
+ * @DP_RXDMA_BUF_RING_SIZE_CFG: RXDMA BUF ring size
+ * @DP_RXDMA_REFILL_RING_SIZE_CFG: RXDMA refill ring size
+ * @DP_RX_REFILL_POOL_NUM_CFG: Refill buffer pool size
+ */
+enum wlan_dp_cfg_param_type {
+	DP_TX_DESC_NUM_CFG,
+	DP_TX_EXT_DESC_NUM_CFG,
+	DP_TX_RING_SIZE_CFG,
+	DP_TX_COMPL_RING_SIZE_CFG,
+	DP_RX_SW_DESC_NUM_CFG,
+	DP_REO_DST_RING_SIZE_CFG,
+	DP_RXDMA_BUF_RING_SIZE_CFG,
+	DP_RXDMA_REFILL_RING_SIZE_CFG,
+	DP_RX_REFILL_POOL_NUM_CFG,
+};
+
+/**
+ * struct wlan_dp_memory_profile_ctx - element representing DP config param info
+ * @param_type: DP config param type
+ * @size: size/length of the param to be selected
+ */
+struct wlan_dp_memory_profile_ctx {
+	enum wlan_dp_cfg_param_type param_type;
+	uint32_t size;
+};
+
+/**
+ * struct wlan_dp_memory_profile_info - Current memory profile info
+ * @is_selected: profile is selected or not
+ * @ctx: DP memory profile context
+ * @size: size of profile
+ */
+struct wlan_dp_memory_profile_info {
+	bool is_selected;
+	struct wlan_dp_memory_profile_ctx *ctx;
+	int size;
+};
+#endif
+
+#endif /* end  of _WLAN_DP_PRIV_STRUCT_H_ */

+ 763 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_rx_thread.h

@@ -0,0 +1,763 @@
+/*
+ * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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.
+ */
+
+#if !defined(__WLAN_DP_RX_THREAD_H)
+#define __WLAN_DP_RX_THREAD_H
+
+#include <qdf_lock.h>
+#include <qdf_event.h>
+#include <qdf_threads.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include "cfg_dp.h"
+#include <cdp_txrx_cmn_struct.h>
+#include <cdp_txrx_cmn.h>
+#include "wlan_cfg.h"
+#include "qdf_nbuf.h"
+#include "qdf_threads.h"
+#include "qdf_net_if.h"
+
+/* Maximum number of REO rings supported (for stats tracking) */
+#define DP_RX_TM_MAX_REO_RINGS WLAN_CFG_NUM_REO_DEST_RING
+/* Number of DP RX threads supported */
+#define DP_MAX_RX_THREADS WLAN_CFG_NUM_REO_DEST_RING
+
+/*
+ * struct dp_rx_tm_handle_cmn - Opaque handle for rx_threads to store
+ * rx_tm_handle. This handle will be common for all the threads.
+ * Individual threads should not be accessing
+ * elements from dp_rx_tm_handle. It should be via an API.
+ */
+struct dp_rx_tm_handle_cmn;
+
+/**
+ * struct dp_rx_thread_stats - structure holding stats for DP RX thread
+ * @nbuf_queued: packets queued into the thread per reo ring
+ * @nbuf_queued_total: packets queued into the thread for all reo rings
+ * @nbuf_dequeued: packets de-queued from the thread
+ * @nbuf_sent_to_stack: packets sent to the stack. some dequeued packets may be
+ *			dropped due to no peer or vdev, hence this stat.
+ * @gro_flushes: number of GRO flushes
+ * @gro_flushes_by_vdev_del: number of GRO flushes triggered by vdev del.
+ * @nbufq_max_len: maximum number of nbuf_lists queued for the thread
+ * @dropped_invalid_vdev: packets(nbuf_list) dropped due to no vdev
+ * @rx_flushed: packets flushed after vdev delete
+ * @dropped_invalid_peer: packets(nbuf_list) dropped due to no peer
+ * @dropped_invalid_os_rx_handles: packets(nbuf_list) dropped due to no os rx
+ * handles
+ * @dropped_others: packets dropped due to other reasons
+ * @dropped_enq_fail: packets dropped due to pending queue full
+ * @rx_nbufq_loop_yield: rx loop yield counter
+ */
+struct dp_rx_thread_stats {
+	unsigned int nbuf_queued[DP_RX_TM_MAX_REO_RINGS];
+	unsigned int nbuf_queued_total;
+	unsigned int nbuf_dequeued;
+	unsigned int nbuf_sent_to_stack;
+	unsigned int gro_flushes;
+	unsigned int gro_flushes_by_vdev_del;
+	unsigned int nbufq_max_len;
+	unsigned int dropped_invalid_vdev;
+	unsigned int rx_flushed;
+	unsigned int dropped_invalid_peer;
+	unsigned int dropped_invalid_os_rx_handles;
+	unsigned int dropped_others;
+	unsigned int dropped_enq_fail;
+	unsigned int rx_nbufq_loop_yield;
+};
+
+/**
+ * enum dp_rx_refill_thread_state - enum to keep track of rx refill thread state
+ * @DP_RX_REFILL_THREAD_INVALID: initial invalid state
+ * @DP_RX_REFILL_THREAD_RUNNING: rx refill thread functional(NOT suspended,
+ *                      processing packets or waiting on a wait_queue)
+ * @DP_RX_REFILL_THREAD_SUSPENDING: rx refill thread is suspending
+ * @DP_RX_REFILL_THREAD_SUSPENDED: rx refill_thread suspended
+ */
+enum dp_rx_refill_thread_state {
+	DP_RX_REFILL_THREAD_INVALID,
+	DP_RX_REFILL_THREAD_RUNNING,
+	DP_RX_REFILL_THREAD_SUSPENDING,
+	DP_RX_REFILL_THREAD_SUSPENDED
+};
+
+/**
+ * struct dp_rx_thread - structure holding variables for a single DP RX thread
+ * @id: id of the dp_rx_thread (0 or 1 or 2..DP_MAX_RX_THREADS - 1)
+ * @task: task structure corresponding to the thread
+ * @start_event: handle of Event for DP Rx thread to signal startup
+ * @suspend_event: handle of Event for DP Rx thread to signal suspend
+ * @resume_event: handle of Event for DP Rx thread to signal resume
+ * @shutdown_event: handle of Event for DP Rx thread to signal shutdown
+ * @vdev_del_event: handle of Event for vdev del thread to signal completion
+ *		    for gro flush
+ * @gro_flush_ind: gro flush indication for DP Rx thread
+ * @event_flag: event flag to post events to DP Rx thread
+ * @nbuf_queue:nbuf queue used to store RX packets
+ * @nbufq_len: length of the nbuf queue
+ * @aff_mask: cuurent affinity mask of the DP Rx thread
+ * @stats: per thread stats
+ * @rtm_handle_cmn: abstract RX TM handle. This allows access to the dp_rx_tm
+ *		    structures via APIs.
+ * @napi: napi to deliver packet to stack via GRO
+ * @wait_q: wait queue to conditionally wait on events for DP Rx thread
+ * @netdev: dummy netdev to initialize the napi structure with
+ */
+struct dp_rx_thread {
+	uint8_t id;
+	qdf_thread_t *task;
+	qdf_event_t start_event;
+	qdf_event_t suspend_event;
+	qdf_event_t resume_event;
+	qdf_event_t shutdown_event;
+	qdf_event_t vdev_del_event;
+	qdf_atomic_t gro_flush_ind;
+	unsigned long event_flag;
+	qdf_nbuf_queue_head_t nbuf_queue;
+	unsigned long aff_mask;
+	struct dp_rx_thread_stats stats;
+	struct dp_rx_tm_handle_cmn *rtm_handle_cmn;
+	qdf_napi_struct napi;
+	qdf_wait_queue_head_t wait_q;
+	qdf_dummy_netdev_t netdev;
+};
+
+/**
+ * struct dp_rx_refill_thread - structure holding info of DP Rx refill thread
+ * @task: task structure corresponding to the thread
+ * @start_event: handle of Event for DP Rx refill thread to signal startup
+ * @suspend_event: handle of Event for DP Rx refill thread to signal suspend
+ * @resume_event: handle of Event for DP Rx refill thread to signal resume
+ * @shutdown_event: handle of Event for DP Rx refill thread to signal shutdown
+ * @event_flag: event flag to post events to DP Rx refill thread
+ * @wait_q: wait queue to conditionally wait on events for DP Rx refill thread
+ * @enabled: flag to check whether DP Rx refill thread is enabled
+ * @soc: abstract DP soc reference used in internal API's
+ * @state: state of DP Rx refill thread
+ */
+struct dp_rx_refill_thread {
+	qdf_thread_t *task;
+	qdf_event_t start_event;
+	qdf_event_t suspend_event;
+	qdf_event_t resume_event;
+	qdf_event_t shutdown_event;
+	unsigned long event_flag;
+	qdf_wait_queue_head_t wait_q;
+	bool enabled;
+	void *soc;
+	enum dp_rx_refill_thread_state state;
+};
+
+/**
+ * enum dp_rx_thread_state - enum to keep track of the state of the rx threads
+ * @DP_RX_THREADS_INVALID: initial invalid state
+ * @DP_RX_THREADS_RUNNING: rx threads functional(NOT suspended, processing
+ *			  packets or waiting on a wait_queue)
+ * @DP_RX_THREADS_SUSPENDING: rx thread is suspending
+ * @DP_RX_THREADS_SUSPENDED: rx_threads suspended from cfg8011 suspend
+ */
+enum dp_rx_thread_state {
+	DP_RX_THREADS_INVALID,
+	DP_RX_THREADS_RUNNING,
+	DP_RX_THREADS_SUSPENDING,
+	DP_RX_THREADS_SUSPENDED
+};
+
+/**
+ * struct dp_rx_tm_handle - DP RX thread infrastructure handle
+ * @num_dp_rx_threads: number of DP RX threads initialized
+ * @txrx_handle_cmn: opaque txrx handle to get to pdev and soc
+ * @state: state of the rx_threads. All of them should be in the same state.
+ * @rx_thread: array of pointers of type struct dp_rx_thread
+ * @allow_dropping: flag to indicate frame dropping is enabled
+ */
+struct dp_rx_tm_handle {
+	uint8_t num_dp_rx_threads;
+	struct dp_txrx_handle_cmn *txrx_handle_cmn;
+	enum dp_rx_thread_state state;
+	struct dp_rx_thread **rx_thread;
+	qdf_atomic_t allow_dropping;
+};
+
+/**
+ * enum dp_rx_gro_flush_code - enum differentiate different GRO flushes
+ * @DP_RX_GRO_NOT_FLUSH: not fush indication
+ * @DP_RX_GRO_NORMAL_FLUSH: Regular full flush
+ * @DP_RX_GRO_LOW_TPUT_FLUSH: Flush during low tput level
+ */
+enum dp_rx_gro_flush_code {
+	DP_RX_GRO_NOT_FLUSH = 0,
+	DP_RX_GRO_NORMAL_FLUSH,
+	DP_RX_GRO_LOW_TPUT_FLUSH
+};
+
+/**
+ * struct dp_txrx_config - dp txrx configuration passed to dp txrx modules
+ * @enable_rx_threads: DP rx threads or not
+ */
+struct dp_txrx_config {
+	bool enable_rx_threads;
+};
+
+struct dp_txrx_handle_cmn;
+
+/**
+ * struct dp_txrx_handle - main dp txrx container handle
+ * @pdev: cdp_pdev pdev handle
+ * @soc: ol_txrx_soc_handle soc handle
+ * @refill_thread: rx refill thread infra handle
+ * @rx_tm_hdl: rx thread infrastructure handle
+ * @config: configuration for DP TXRX modules
+ */
+struct dp_txrx_handle {
+	ol_txrx_soc_handle soc;
+	struct cdp_pdev *pdev;
+	struct dp_rx_tm_handle rx_tm_hdl;
+	struct dp_rx_refill_thread refill_thread;
+	struct dp_txrx_config config;
+};
+
+/**
+ * dp_rx_refill_thread_init() - Initialize DP Rx refill threads
+ * @refill_thread: Contains over all rx refill thread info
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS dp_rx_refill_thread_init(struct dp_rx_refill_thread *refill_thread);
+
+/**
+ * dp_rx_refill_thread_deinit() - De-initialize DP Rx refill threads
+ * @refill_thread: Contains over all rx refill thread info
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+dp_rx_refill_thread_deinit(struct dp_rx_refill_thread *refill_thread);
+
+/**
+ * dp_rx_tm_init() - initialize DP Rx thread infrastructure
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
+ * @num_dp_rx_threads: number of DP Rx threads to be initialized
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_init(struct dp_rx_tm_handle *rx_tm_hdl,
+			 uint8_t num_dp_rx_threads);
+
+/**
+ * dp_rx_tm_deinit() - de-initialize DP Rx thread infrastructure
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_deinit(struct dp_rx_tm_handle *rx_tm_hdl);
+
+/**
+ * dp_rx_tm_enqueue_pkt() - enqueue RX packet into RXTI
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
+ * @nbuf_list: single or a list of nbufs to be enqueued into RXTI
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_enqueue_pkt(struct dp_rx_tm_handle *rx_tm_hdl,
+				qdf_nbuf_t nbuf_list);
+
+/**
+ * dp_rx_tm_gro_flush_ind() - flush GRO packets for a RX Context Id
+ * @rx_tm_handle: dp_rx_tm_handle containing the overall thread infrastructure
+ * @rx_ctx_id: RX Thread Context Id for which GRO flush needs to be done
+ * @flush_code: flush code to differentiate low TPUT flush
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_gro_flush_ind(struct dp_rx_tm_handle *rx_tm_handle,
+				  int rx_ctx_id,
+				  enum dp_rx_gro_flush_code flush_code);
+/**
+ * dp_rx_refill_thread_suspend() - Suspend RX refill thread
+ * @refill_thread: pointer to dp_rx_refill_thread object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS
+dp_rx_refill_thread_suspend(struct dp_rx_refill_thread *refill_thread);
+
+/**
+ * dp_rx_tm_suspend() - suspend all threads in RXTI
+ * @rx_tm_handle: pointer to dp_rx_tm_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_handle);
+
+/**
+ * dp_rx_tm_flush_by_vdev_id() - flush rx packets by vdev_id in all
+ * rx thread queues
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
+ *             infrastructure
+ * @vdev_id: vdev id for which packets are to be flushed
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_flush_by_vdev_id(struct dp_rx_tm_handle *rx_tm_hdl,
+				     uint8_t vdev_id);
+
+/**
+ * dp_rx_refill_thread_resume() - Resume RX refill thread
+ * @refill_thread: pointer to dp_rx_refill_thread
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS
+dp_rx_refill_thread_resume(struct dp_rx_refill_thread *refill_thread);
+
+/**
+ * dp_rx_tm_resume() - resume all threads in RXTI
+ * @rx_tm_handle: pointer to dp_rx_tm_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_resume(struct dp_rx_tm_handle *rx_tm_handle);
+
+/**
+ * dp_rx_tm_dump_stats() - dump stats for all threads in RXTI
+ * @rx_tm_handle: pointer to dp_rx_tm_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_dump_stats(struct dp_rx_tm_handle *rx_tm_handle);
+
+/**
+ * dp_rx_thread_get_txrx_handle() - get txrx handle from rx_tm_handle_cmn
+ * @rx_tm_handle_cmn: opaque pointer to dp_rx_tm_handle_cmn struct
+ *
+ * Return: pointer to dp_txrx_handle_cmn handle
+ */
+static inline struct dp_txrx_handle_cmn*
+dp_rx_thread_get_txrx_handle(struct dp_rx_tm_handle_cmn *rx_tm_handle_cmn)
+{
+	return (((struct dp_rx_tm_handle *)rx_tm_handle_cmn)->txrx_handle_cmn);
+}
+
+/**
+ * dp_rx_tm_get_napi_context() - get NAPI context for a RX CTX ID
+ * @rx_ctx_id: RX context ID (RX thread ID) corresponding to which NAPI is
+ *             needed
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
+ *             infrastructure
+ *
+ * Return: NULL on failure, else pointer to NAPI corresponding to rx_ctx_id
+ */
+qdf_napi_struct *dp_rx_tm_get_napi_context(struct dp_rx_tm_handle *rx_tm_hdl,
+					   uint8_t rx_ctx_id);
+
+/**
+ * dp_rx_tm_set_cpu_mask() - set CPU mask for RX threads
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
+ *             infrastructure
+ * @new_mask: New CPU mask pointer
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_set_cpu_mask(struct dp_rx_tm_handle *rx_tm_hdl,
+				 qdf_cpu_mask *new_mask);
+
+#ifdef FEATURE_WLAN_DP_RX_THREADS
+/**
+ * dp_txrx_get_cmn_hdl_frm_ext_hdl() - conversion func ext_hdl->txrx_handle_cmn
+ * @dp_ext_hdl: pointer to dp_txrx_handle structure
+ *
+ * Return: typecasted pointer of type - struct dp_txrx_handle_cmn
+ */
+static inline struct dp_txrx_handle_cmn *
+dp_txrx_get_cmn_hdl_frm_ext_hdl(struct dp_txrx_handle *dp_ext_hdl)
+{
+	return (struct dp_txrx_handle_cmn *)dp_ext_hdl;
+}
+
+/**
+ * dp_txrx_get_ext_hdl_frm_cmn_hdl() - conversion func txrx_handle_cmn->ext_hdl
+ * @txrx_cmn_hdl: pointer to dp_txrx_handle_cmn structure
+ *
+ * Return: typecasted pointer of type - struct dp_txrx_handle
+ */
+static inline struct dp_txrx_handle *
+dp_txrx_get_ext_hdl_frm_cmn_hdl(struct dp_txrx_handle_cmn *txrx_cmn_hdl)
+{
+	return (struct dp_txrx_handle *)txrx_cmn_hdl;
+}
+
+static inline ol_txrx_soc_handle
+dp_txrx_get_soc_from_ext_handle(struct dp_txrx_handle_cmn *txrx_cmn_hdl)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+
+	dp_ext_hdl = dp_txrx_get_ext_hdl_frm_cmn_hdl(txrx_cmn_hdl);
+
+	return dp_ext_hdl->soc;
+}
+
+/**
+ * dp_txrx_init() - initialize DP TXRX module
+ * @soc: ol_txrx_soc_handle
+ * @pdev_id: id of dp pdev handle
+ * @config: configuration for DP TXRX modules
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, uint8_t pdev_id,
+			struct dp_txrx_config *config);
+
+/**
+ * dp_txrx_deinit() - de-initialize DP TXRX module
+ * @soc: ol_txrx_soc_handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_txrx_deinit(ol_txrx_soc_handle soc);
+
+/**
+ * dp_txrx_flush_pkts_by_vdev_id() - flush rx packets for a vdev_id
+ * @soc: ol_txrx_soc_handle object
+ * @vdev_id: vdev_id for which rx packets are to be flushed
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline QDF_STATUS dp_txrx_flush_pkts_by_vdev_id(ol_txrx_soc_handle soc,
+						       uint8_t vdev_id)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!soc) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	qdf_status = dp_rx_tm_flush_by_vdev_id(&dp_ext_hdl->rx_tm_hdl, vdev_id);
+ret:
+	return qdf_status;
+}
+
+/**
+ * dp_txrx_resume() - resume all threads
+ * @soc: ol_txrx_soc_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline QDF_STATUS dp_txrx_resume(ol_txrx_soc_handle soc)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct dp_rx_refill_thread *refill_thread;
+
+	if (!soc) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	refill_thread = &dp_ext_hdl->refill_thread;
+	if (refill_thread->enabled) {
+		qdf_status = dp_rx_refill_thread_resume(refill_thread);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			return qdf_status;
+	}
+
+	qdf_status = dp_rx_tm_resume(&dp_ext_hdl->rx_tm_hdl);
+ret:
+	return qdf_status;
+}
+
+/**
+ * dp_txrx_suspend() - suspend all threads
+ * @soc: ol_txrx_soc_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline QDF_STATUS dp_txrx_suspend(ol_txrx_soc_handle soc)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct dp_rx_refill_thread *refill_thread;
+
+	if (!soc) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	refill_thread = &dp_ext_hdl->refill_thread;
+	if (refill_thread->enabled) {
+		qdf_status = dp_rx_refill_thread_suspend(refill_thread);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			return qdf_status;
+	}
+
+	qdf_status = dp_rx_tm_suspend(&dp_ext_hdl->rx_tm_hdl);
+	if (QDF_IS_STATUS_ERROR(qdf_status) && refill_thread->enabled)
+		dp_rx_refill_thread_resume(refill_thread);
+
+ret:
+	return qdf_status;
+}
+
+/**
+ * dp_rx_enqueue_pkt() - enqueue packet(s) into the thread
+ * @soc: ol_txrx_soc_handle object
+ * @nbuf_list: list of packets to be queued into the rx_thread
+ *
+ * The function accepts a list of skbs connected by the skb->next pointer and
+ * queues them into a RX thread to be sent to the stack.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline
+QDF_STATUS dp_rx_enqueue_pkt(ol_txrx_soc_handle soc, qdf_nbuf_t nbuf_list)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!soc || !nbuf_list) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		dp_err("invalid input params soc %pK nbuf %pK"
+		       , soc, nbuf_list);
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	qdf_status = dp_rx_tm_enqueue_pkt(&dp_ext_hdl->rx_tm_hdl, nbuf_list);
+ret:
+	return qdf_status;
+}
+
+/**
+ * dp_rx_gro_flush_ind() - Flush GRO packets for a given RX CTX Id
+ * @soc: ol_txrx_soc_handle object
+ * @rx_ctx_id: Context Id (Thread for which GRO packets need to be flushed)
+ * @flush_code: flush_code differentiating normal_flush from low_tput_flush
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline
+QDF_STATUS dp_rx_gro_flush_ind(ol_txrx_soc_handle soc, int rx_ctx_id,
+			       enum dp_rx_gro_flush_code flush_code)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!soc) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		dp_err("invalid input param soc %pK", soc);
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	qdf_status = dp_rx_tm_gro_flush_ind(&dp_ext_hdl->rx_tm_hdl, rx_ctx_id,
+					    flush_code);
+ret:
+	return qdf_status;
+}
+
+/**
+ * dp_txrx_ext_dump_stats() - dump txrx external module stats
+ * @soc: ol_txrx_soc_handle object
+ * @stats_id: id  for the module whose stats are needed
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline QDF_STATUS dp_txrx_ext_dump_stats(ol_txrx_soc_handle soc,
+						uint8_t stats_id)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status;
+
+	if (!soc) {
+		dp_err("invalid input params soc %pK", soc);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl)
+		return QDF_STATUS_E_FAULT;
+
+	if (stats_id == CDP_DP_RX_THREAD_STATS)
+		qdf_status = dp_rx_tm_dump_stats(&dp_ext_hdl->rx_tm_hdl);
+	else
+		qdf_status = QDF_STATUS_E_INVAL;
+
+	return qdf_status;
+}
+
+/**
+ * dp_rx_get_napi_context() - get NAPI context for a RX CTX ID
+ * @soc: ol_txrx_soc_handle object
+ * @rx_ctx_id: RX context ID (RX thread ID) corresponding to which NAPI is
+ *             needed
+ *
+ * Return: NULL on failure, else pointer to NAPI corresponding to rx_ctx_id
+ */
+static inline
+qdf_napi_struct *dp_rx_get_napi_context(ol_txrx_soc_handle soc,
+					uint8_t rx_ctx_id)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+
+	if (!soc) {
+		dp_err("soc in NULL!");
+		return NULL;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		dp_err("dp_ext_hdl in NULL!");
+		return NULL;
+	}
+
+	return dp_rx_tm_get_napi_context(&dp_ext_hdl->rx_tm_hdl, rx_ctx_id);
+}
+
+/**
+ * dp_txrx_set_cpu_mask() - set CPU mask for RX threads
+ * @soc: ol_txrx_soc_handle object
+ * @new_mask: New CPU mask pointer
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline
+QDF_STATUS dp_txrx_set_cpu_mask(ol_txrx_soc_handle soc, qdf_cpu_mask *new_mask)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!soc) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	qdf_status = dp_rx_tm_set_cpu_mask(&dp_ext_hdl->rx_tm_hdl, new_mask);
+
+ret:
+	return qdf_status;
+}
+
+#else
+
+static inline
+QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, uint8_t pdev_id,
+			struct dp_txrx_config *config)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_deinit(ol_txrx_soc_handle soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_flush_pkts_by_vdev_id(ol_txrx_soc_handle soc,
+						       uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_resume(ol_txrx_soc_handle soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_suspend(ol_txrx_soc_handle soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS dp_rx_enqueue_pkt(ol_txrx_soc_handle soc, qdf_nbuf_t nbuf_list)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS dp_rx_gro_flush_ind(ol_txrx_soc_handle soc, int rx_ctx_id,
+			       enum dp_rx_gro_flush_code flush_code)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_ext_dump_stats(ol_txrx_soc_handle soc,
+						uint8_t stats_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+qdf_napi_struct *dp_rx_get_napi_context(ol_txrx_soc_handle soc,
+					uint8_t rx_ctx_id)
+{
+	return NULL;
+}
+
+static inline
+QDF_STATUS dp_txrx_set_cpu_mask(ol_txrx_soc_handle soc, qdf_cpu_mask *new_mask)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* FEATURE_WLAN_DP_RX_THREADS */
+
+/**
+ * dp_rx_tm_get_pending() - get number of frame in thread
+ * nbuf queue pending
+ * @soc: ol_txrx_soc_handle object
+ *
+ * Return: number of frames
+ */
+int dp_rx_tm_get_pending(ol_txrx_soc_handle soc);
+#endif /* __WLAN_DP_RX_THREAD_H */

+ 177 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_swlm.h

@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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_DP_SWLM_H_
+#define _WLAN_DP_SWLM_H_
+
+#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
+
+#define DP_SWLM_TCL_TPUT_PASS_THRESH 3
+
+#define DP_SWLM_TCL_RX_TRAFFIC_THRESH	50
+#define DP_SWLM_TCL_TX_TRAFFIC_THRESH	50
+#define DP_SWLM_TCL_TX_PKT_THRESH	2
+
+/* Traffic test time is in us */
+#define DP_SWLM_TCL_TRAFFIC_SAMPLING_TIME 250
+#define DP_SWLM_TCL_TIME_FLUSH_THRESH 1000
+#define DP_SWLM_TCL_TX_THRESH_MULTIPLIER 2
+
+/* Inline Functions */
+
+/**
+ * dp_tx_is_special_frame() - check if this TX frame is a special frame.
+ * @nbuf: TX skb pointer
+ * @frame_mask: the mask for required special frames
+ *
+ * Check if TX frame is a required special frame.
+ *
+ * Returns: true, if this frame is a needed special frame,
+ *	    false, otherwise
+ */
+static inline
+bool dp_tx_is_special_frame(qdf_nbuf_t nbuf, uint32_t frame_mask)
+{
+	if (((frame_mask & FRAME_MASK_IPV4_ARP) &&
+	     qdf_nbuf_is_ipv4_arp_pkt(nbuf)) ||
+	    ((frame_mask & FRAME_MASK_IPV4_DHCP) &&
+	     qdf_nbuf_is_ipv4_dhcp_pkt(nbuf)) ||
+	    ((frame_mask & FRAME_MASK_IPV4_EAPOL) &&
+	     qdf_nbuf_is_ipv4_eapol_pkt(nbuf)) ||
+	    ((frame_mask & FRAME_MASK_IPV6_DHCP) &&
+	     qdf_nbuf_is_ipv6_dhcp_pkt(nbuf)))
+		return true;
+
+	return false;
+}
+
+/**
+ * dp_swlm_tcl_reset_session_data() -  Reset the TCL coalescing session data
+ * @soc: DP soc handle
+ * @ring_id: TCL ring id
+ *
+ * Returns QDF_STATUS
+ */
+static inline QDF_STATUS
+dp_swlm_tcl_reset_session_data(struct dp_soc *soc, uint8_t ring_id)
+{
+	struct dp_swlm_params *params = &soc->swlm.params;
+
+	params->tcl[ring_id].coalesce_end_time = qdf_get_log_timestamp_usecs() +
+		params->time_flush_thresh;
+	params->tcl[ring_id].bytes_coalesced = 0;
+	params->tcl[ring_id].bytes_flush_thresh =
+				params->tcl[ring_id].sampling_session_tx_bytes *
+				params->tx_thresh_multiplier;
+	qdf_timer_sync_cancel(&params->tcl[ring_id].flush_timer);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_swlm_tcl_pre_check() - Pre checks for current packet to be transmitted
+ * @soc: Datapath soc handle
+ * @tcl_data: tcl swlm data
+ *
+ * Returns: QDF_STATUS_SUCCESS, if all pre-check conditions pass
+ *	    QDF_STATUS_E_FAILURE, otherwise
+ */
+static inline QDF_STATUS
+dp_swlm_tcl_pre_check(struct dp_soc *soc,
+		      struct dp_swlm_tcl_data *tcl_data)
+{
+	struct dp_swlm *swlm = &soc->swlm;
+	uint32_t frame_mask = FRAME_MASK_IPV4_ARP | FRAME_MASK_IPV4_DHCP |
+				FRAME_MASK_IPV4_EAPOL | FRAME_MASK_IPV6_DHCP;
+
+	if (tcl_data->tid > DP_VO_TID) {
+		DP_STATS_INC(swlm, tcl[tcl_data->ring_id].tid_fail, 1);
+		goto fail;
+	}
+
+	if (dp_tx_is_special_frame(tcl_data->nbuf, frame_mask)) {
+		DP_STATS_INC(swlm, tcl[tcl_data->ring_id].sp_frames, 1);
+		goto fail;
+	}
+
+	if (tcl_data->num_ll_connections) {
+		DP_STATS_INC(swlm, tcl[tcl_data->ring_id].ll_connection, 1);
+		goto fail;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+fail:
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * dp_swlm_query_policy() - apply software latency policy based on ring type.
+ * @soc: Datapath global soc handle
+ * @ring_type: SRNG type
+ * @query_data: private data for the query corresponding to the ring type
+ *
+ * Returns: 1, if policy is to be applied
+ *	    0, if policy is not to be applied
+ */
+static inline int dp_swlm_query_policy(struct dp_soc *soc, int ring_type,
+				       union swlm_data query_data)
+{
+	struct dp_swlm *swlm = &soc->swlm;
+
+	switch (ring_type) {
+	case TCL_DATA:
+		return swlm->ops->tcl_wr_coalesce_check(soc,
+							query_data.tcl_data);
+	default:
+		dp_err("Ring type %d not supported by SW latency manager",
+		       ring_type);
+		break;
+	}
+
+	return 0;
+}
+
+/* Function Declarations */
+
+/**
+ * dp_soc_swlm_attach() - attach the software latency manager resources
+ * @soc: Datapath global soc handle
+ *
+ * Returns: QDF_STATUS
+ */
+QDF_STATUS dp_soc_swlm_attach(struct dp_soc *soc);
+
+/**
+ * dp_soc_swlm_detach() - detach the software latency manager resources
+ * @soc: Datapath global soc handle
+ *
+ * Returns: QDF_STATUS
+ */
+QDF_STATUS dp_soc_swlm_detach(struct dp_soc *soc);
+
+/**
+ * dp_print_swlm_stats() - Print the SWLM stats
+ * @soc: Datapath soc handle
+ *
+ * Returns: QDF_STATUS
+ */
+QDF_STATUS dp_print_swlm_stats(struct dp_soc *soc);
+
+#endif /* WLAN_DP_FEATURE_SW_LATENCY_MGR */
+
+#endif

+ 674 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_txrx.h

@@ -0,0 +1,674 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_DP_TXRX_H__
+#define __WLAN_DP_TXRX_H__
+
+#include <cds_api.h>
+#include <qdf_tracepoint.h>
+#include <qdf_pkt_add_timestamp.h>
+#include <enet.h>
+#include <qdf_tracepoint.h>
+#include "wlan_dp_priv.h"
+
+/** DP Tx Time out value */
+#define DP_TX_TIMEOUT   qdf_system_msecs_to_ticks(5000)
+
+#define DP_TX_STALL_THRESHOLD 4
+
+#ifdef FEATURE_WLAN_WAPI
+#define IS_DP_ETHERTYPE_WAI(_nbuf) (qdf_ntohs(qdf_nbuf_get_protocol(_nbuf)) == \
+								ETHERTYPE_WAI)
+#else
+#define IS_DP_ETHERTYPE_WAI(_nbuf) (false)
+#endif
+
+#define DP_CONNECTIVITY_CHECK_SET_ARP		1
+#define DP_CONNECTIVITY_CHECK_SET_DNS		2
+#define DP_CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE	3
+#define DP_CONNECTIVITY_CHECK_SET_ICMPV4	4
+#define DP_CONNECTIVITY_CHECK_SET_ICMPV6	5
+#define DP_CONNECTIVITY_CHECK_SET_TCP_SYN	6
+#define DP_CONNECTIVITY_CHECK_SET_TCP_SYN_ACK	7
+#define DP_CONNECTIVITY_CHECK_SET_TCP_ACK	8
+
+/**
+ * wlan_dp_intf_get_pkt_type_bitmap_value() - Get packt type bitmap info
+ * @intf_ctx: DP interface context
+ *
+ * Return: bitmap information
+ */
+uint32_t wlan_dp_intf_get_pkt_type_bitmap_value(void *intf_ctx);
+
+#if defined(WLAN_SUPPORT_RX_FISA)
+/**
+ * dp_rx_skip_fisa() - Set flags to skip fisa aggregation
+ * @dp_ctx: DP component handle
+ * @value: allow or skip fisa
+ *
+ * Return: None
+ */
+void dp_rx_skip_fisa(struct wlan_dp_psoc_context *dp_ctx, uint32_t value);
+#endif
+
+/**
+ * dp_reset_all_intfs_connectivity_stats() - reset connectivity stats
+ * @dp_ctx: pointer to DP Context
+ *
+ * Return: None
+ */
+void dp_reset_all_intfs_connectivity_stats(struct wlan_dp_psoc_context *dp_ctx);
+
+/**
+ * dp_softap_check_wait_for_tx_eap_pkt() - Check and wait for eap failure
+ * pkt completion event
+ * @dp_intf: pointer to DP interface
+ * @mac_addr: mac address of peer
+ *
+ * Check and wait for eap failure pkt tx completion.
+ *
+ * Return: void
+ */
+void dp_softap_check_wait_for_tx_eap_pkt(struct wlan_dp_intf *dp_intf,
+					 struct qdf_mac_addr *mac_addr);
+
+#ifdef SAP_DHCP_FW_IND
+/**
+ * dp_post_dhcp_ind() - Send DHCP START/STOP indication to FW
+ * @dp_link: DP link handle
+ * @mac_addr: mac address
+ * @dhcp_start: true if DHCP start, otherwise DHCP stop
+ *
+ * Return: error number
+ */
+int dp_post_dhcp_ind(struct wlan_dp_link *dp_link,
+		     uint8_t *mac_addr, bool dhcp_start);
+
+/**
+ * dp_softap_inspect_dhcp_packet() - Inspect DHCP packet
+ * @dp_link: DP link handle
+ * @nbuf: pointer to OS packet (sk_buff)
+ * @dir: direction
+ *
+ * Inspect the Tx/Rx frame, and send DHCP START/STOP notification to the FW
+ * through WMI message, during DHCP based IP address acquisition phase.
+ *
+ * - Send DHCP_START notification to FW when SAP gets DHCP Discovery
+ * - Send DHCP_STOP notification to FW when SAP sends DHCP ACK/NAK
+ *
+ * DHCP subtypes are determined by a status octet in the DHCP Message type
+ * option (option code 53 (0x35)).
+ *
+ * Each peer will be in one of 4 DHCP phases, starts from QDF_DHCP_PHASE_ACK,
+ * and transitioned per DHCP message type as it arrives.
+ *
+ * - QDF_DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase
+ * - QDF_DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase
+ * - QDF_DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase
+ *	or ACK phase (Renewal process)
+ * - QDF_DHCP_PHASE_ACK : upon receiving DHCP_ACK/NAK message in REQUEST phase
+ *	or DHCP_DELINE message in OFFER phase
+ *
+ * Return: error number
+ */
+int dp_softap_inspect_dhcp_packet(struct wlan_dp_link *dp_link,
+				  qdf_nbuf_t nbuf,
+				  enum qdf_proto_dir dir);
+#else
+static inline
+int dp_post_dhcp_ind(struct wlan_dp_link *dp_link,
+		     uint8_t *mac_addr, bool dhcp_start)
+{
+	return 0;
+}
+
+static inline
+int dp_softap_inspect_dhcp_packet(struct wlan_dp_link *dp_link,
+				  qdf_nbuf_t nbuf,
+				  enum qdf_proto_dir dir)
+{
+	return 0;
+}
+#endif
+
+/**
+ * dp_rx_flush_packet_cbk() - flush rx packet handler
+ * @dp_link_context: pointer to DP link context
+ * @link_id: vdev_id of the packets to be flushed
+ *
+ * Flush rx packet callback registered with data path. DP will call this to
+ * notify when packets for a particular vdev is to be flushed out.
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS dp_rx_flush_packet_cbk(void *dp_link_context, uint8_t link_id);
+
+/**
+ * dp_softap_start_xmit() - Transmit a frame for SAP interface
+ * @nbuf: pointer to Network buffer
+ * @dp_link: DP link handle
+ *
+ * Return: QDF_STATUS_SUCCESS on successful transmission
+ */
+QDF_STATUS dp_softap_start_xmit(qdf_nbuf_t nbuf, struct wlan_dp_link *dp_link);
+
+/**
+ * dp_softap_tx_timeout() - TX timeout handler
+ * @dp_intf: pointer to DP interface
+ *
+ * Timeout API called for mode interfaces (SoftAP/P2P GO)
+ * when TX transmission takes too long.
+ * called by the OS_IF layer legacy driver.
+ *
+ * Return: None
+ */
+void dp_softap_tx_timeout(struct wlan_dp_intf *dp_intf);
+
+/**
+ * dp_softap_rx_packet_cbk() - Receive packet handler for SAP
+ * @intf_ctx: pointer to DP interface context
+ * @rx_buf: pointer to rx qdf_nbuf
+ *
+ * Receive callback registered with data path.  DP will call this to notify
+ * when one or more packets were received for a registered
+ * STA.
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS
+dp_softap_rx_packet_cbk(void *intf_ctx, qdf_nbuf_t rx_buf);
+
+/**
+ * dp_start_xmit() - Transmit a frame for STA interface
+ * @nbuf: pointer to Network buffer
+ * @dp_link: DP link handle
+ *
+ * Return: QDF_STATUS_SUCCESS on successful transmission
+ */
+QDF_STATUS
+dp_start_xmit(struct wlan_dp_link *dp_link, qdf_nbuf_t nbuf);
+
+/**
+ * dp_tx_timeout() - DP Tx timeout API
+ * @dp_intf: Data path interface pointer
+ *
+ * Function called by OS_IF there is any timeout during transmission.
+ *
+ * Return: none
+ */
+void dp_tx_timeout(struct wlan_dp_intf *dp_intf);
+
+/**
+ * dp_rx_packet_cbk() - Receive packet handler
+ * @dp_link_context: pointer to DP link context
+ * @rx_buf: pointer to rx qdf_nbuf
+ *
+ * Receive callback registered with data path.  DP will call this to notify
+ * when one or more packets were received for a registered
+ * STA.
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS dp_rx_packet_cbk(void *dp_link_context, qdf_nbuf_t rx_buf);
+
+#if defined(WLAN_SUPPORT_RX_FISA)
+/**
+ * wlan_dp_rx_fisa_cbk() - Entry function to FISA to handle aggregation
+ * @dp_soc: core txrx main context
+ * @dp_vdev: Handle DP vdev
+ * @nbuf_list: List nbufs to be aggregated
+ *
+ * Return: Success on aggregation
+ */
+QDF_STATUS wlan_dp_rx_fisa_cbk(void *dp_soc, void *dp_vdev,
+			       qdf_nbuf_t nbuf_list);
+
+/**
+ * wlan_dp_rx_fisa_flush_by_ctx_id() - Flush function to end of context
+ *				   flushing of aggregates
+ * @dp_soc: core txrx main context
+ * @ring_num: REO number to flush the flow Rxed on the REO
+ *
+ * Return: Success on flushing the flows for the REO
+ */
+QDF_STATUS wlan_dp_rx_fisa_flush_by_ctx_id(void *dp_soc, int ring_num);
+
+/**
+ * wlan_dp_rx_fisa_flush_by_vdev_id() - Flush fisa aggregates per vdev id
+ * @dp_soc: core txrx main context
+ * @vdev_id: vdev ID
+ *
+ * Return: Success on flushing the flows for the vdev
+ */
+QDF_STATUS wlan_dp_rx_fisa_flush_by_vdev_id(void *dp_soc, uint8_t vdev_id);
+#else
+static inline QDF_STATUS wlan_dp_rx_fisa_flush_by_vdev_id(void *dp_soc,
+							  uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wlan_dp_rx_deliver_to_stack() - DP helper function to deliver RX pkts to
+ *                                 stack
+ * @dp_intf: pointer to DP interface context
+ * @nbuf: pointer to nbuf
+ *
+ * The function calls the appropriate stack function depending upon the packet
+ * type and whether GRO/LRO is enabled.
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS wlan_dp_rx_deliver_to_stack(struct wlan_dp_intf *dp_intf,
+				       qdf_nbuf_t nbuf);
+
+/**
+ * dp_rx_thread_gro_flush_ind_cbk() - receive handler to flush GRO packets
+ * @link_ctx: pointer to DP interface context
+ * @rx_ctx_id: RX CTX Id for which flush should happen
+ *
+ * Receive callback registered with DP layer which flushes GRO packets
+ * for a given RX CTX ID (RX Thread)
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS dp_rx_thread_gro_flush_ind_cbk(void *link_ctx, int rx_ctx_id);
+
+/**
+ * dp_rx_pkt_thread_enqueue_cbk() - receive pkt handler to enqueue into thread
+ * @link_ctx: pointer to DP link context
+ * @nbuf_list: pointer to qdf_nbuf list
+ *
+ * Receive callback registered with DP layer which enqueues packets into dp rx
+ * thread
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS dp_rx_pkt_thread_enqueue_cbk(void *link_ctx,
+					qdf_nbuf_t nbuf_list);
+
+/**
+ * dp_disable_rx_ol_for_low_tput() - Disable Rx offload in low TPUT scenario
+ * @dp_ctx: dp context
+ * @disable: true/false to disable/enable the Rx offload
+ *
+ * Return: none
+ */
+void dp_disable_rx_ol_for_low_tput(struct wlan_dp_psoc_context *dp_ctx,
+				   bool disable);
+
+/**
+ * dp_tx_rx_collect_connectivity_stats_info() - collect connectivity stats
+ * @nbuf: pointer to n/w buffer
+ * @context: pointer to DP interface
+ * @action: action done on pkt.
+ * @pkt_type: data pkt type
+ *
+ * Return: None
+ */
+void
+dp_tx_rx_collect_connectivity_stats_info(qdf_nbuf_t nbuf, void *context,
+		enum connectivity_stats_pkt_status action, uint8_t *pkt_type);
+
+static inline void
+dp_nbuf_fill_gso_size(qdf_netdev_t dev, qdf_nbuf_t nbuf)
+{
+	unsigned long val;
+
+	if (qdf_nbuf_is_cloned(nbuf) && qdf_nbuf_is_nonlinear(nbuf) &&
+	    qdf_nbuf_get_gso_size(nbuf) == 0 &&
+	    qdf_nbuf_is_ipv4_tcp_pkt(nbuf)) {
+		val = dev->mtu - ((qdf_nbuf_transport_header(nbuf) -
+				   qdf_nbuf_network_header(nbuf))
+				  + qdf_nbuf_get_tcp_hdr_len(nbuf));
+		qdf_nbuf_set_gso_size(nbuf, val);
+	}
+}
+
+#ifdef CONFIG_HL_SUPPORT
+static inline QDF_STATUS
+dp_nbuf_nontso_linearize(qdf_nbuf_t nbuf)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+dp_nbuf_nontso_linearize(qdf_nbuf_t nbuf)
+{
+	if (qdf_nbuf_is_nonlinear(nbuf) && qdf_nbuf_is_tso(nbuf) == false) {
+		if (qdf_unlikely(qdf_nbuf_linearize(nbuf)))
+			return QDF_STATUS_E_NOMEM;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void dp_event_eapol_log(qdf_nbuf_t nbuf, enum qdf_proto_dir dir);
+#else
+static inline
+void dp_event_eapol_log(qdf_nbuf_t nbuf, enum qdf_proto_dir dir)
+{}
+#endif
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+static inline
+qdf_nbuf_t dp_nbuf_orphan(struct wlan_dp_intf *dp_intf,
+			  qdf_nbuf_t nbuf)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx;
+	struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops;
+	unsigned int tx_flow_low_watermark;
+	int need_orphan = 0;
+	int cpu;
+
+	tx_flow_low_watermark =
+	   dp_ops->dp_get_tx_flow_low_watermark(dp_ops->callback_ctx,
+						dp_intf->dev);
+	if (tx_flow_low_watermark > 0) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+		/*
+		 * The TCP TX throttling logic is changed a little after
+		 * 3.19-rc1 kernel, the TCP sending limit will be smaller,
+		 * which will throttle the TCP packets to the host driver.
+		 * The TCP UP LINK throughput will drop heavily. In order to
+		 * fix this issue, need to orphan the socket buffer asap, which
+		 * will call skb's destructor to notify the TCP stack that the
+		 * SKB buffer is unowned. And then the TCP stack will pump more
+		 * packets to host driver.
+		 *
+		 * The TX packets might be dropped for UDP case in the iperf
+		 * testing. So need to be protected by follow control.
+		 */
+		need_orphan = 1;
+#else
+		if (dp_ctx->dp_cfg.tx_orphan_enable)
+			need_orphan = 1;
+#endif
+	} else if (dp_ctx->dp_cfg.tx_orphan_enable) {
+		if (qdf_nbuf_is_ipv4_tcp_pkt(nbuf) ||
+		    qdf_nbuf_is_ipv6_tcp_pkt(nbuf))
+			need_orphan = 1;
+	}
+
+	if (need_orphan) {
+		qdf_nbuf_orphan(nbuf);
+		cpu = qdf_get_smp_processor_id();
+		++dp_intf->dp_stats.tx_rx_stats.per_cpu[cpu].tx_orphaned;
+	} else {
+		nbuf = __qdf_nbuf_unshare(nbuf);
+	}
+
+	return nbuf;
+}
+
+/**
+ * dp_get_tx_resource() - check tx resources and take action
+ * @dp_link: DP link handle
+ * @mac_addr: mac address
+ *
+ * Return: none
+ */
+void dp_get_tx_resource(struct wlan_dp_link *dp_link,
+			struct qdf_mac_addr *mac_addr);
+
+#else
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+/**
+ * dp_nbuf_orphan() - skb_unshare a cloned packed else skb_orphan
+ * @dp_intf: pointer to DP interface
+ * @nbuf: pointer to nbuf data packet
+ *
+ * Return: pointer to nbuf structure
+ */
+static inline
+qdf_nbuf_t dp_nbuf_orphan(struct wlan_dp_intf *dp_intf,
+			  qdf_nbuf_t nbuf)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx;
+	int cpu;
+
+	dp_nbuf_fill_gso_size(dp_intf->dev, nbuf);
+
+	if (unlikely(dp_ctx->dp_cfg.tx_orphan_enable) ||
+	    qdf_nbuf_is_cloned(nbuf)) {
+		/*
+		 * For UDP packets we want to orphan the packet to allow the app
+		 * to send more packets. The flow would ultimately be controlled
+		 * by the limited number of tx descriptors for the vdev.
+		 */
+		cpu = qdf_get_smp_processor_id();
+		++dp_intf->dp_stats.tx_rx_stats.per_cpu[cpu].tx_orphaned;
+		qdf_nbuf_orphan(nbuf);
+	}
+	return nbuf;
+}
+#else
+static inline
+qdf_nbuf_t dp_nbuf_orphan(struct wlan_dp_intf *dp_intf,
+			  qdf_nbuf_t nbuf)
+{
+	qdf_nbuf_t nskb;
+
+	dp_nbuf_fill_gso_size(dp_intf->dev, nbuf);
+	nskb =  __qdf_nbuf_unshare(nbuf);
+
+	return nskb;
+}
+#endif
+
+/**
+ * dp_get_tx_resource() - check tx resources and take action
+ * @dp_link: DP link handle
+ * @mac_addr: mac address
+ *
+ * Return: none
+ */
+static inline
+void dp_get_tx_resource(struct wlan_dp_link *dp_link,
+			struct qdf_mac_addr *mac_addr)
+{
+}
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+/**
+ * dp_start_xmit() - Transmit a frame
+ * @dp_link: DP link handle
+ * @nbuf: n/w buffer
+ *
+ * Function called to Transmit a n/w buffer in STA mode.
+ *
+ * Return: Status of the transmission
+ */
+QDF_STATUS
+dp_start_xmit(struct wlan_dp_link *dp_link, qdf_nbuf_t nbuf);
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+/**
+ * dp_mon_rx_packet_cbk() - Receive callback registered with OL layer.
+ * @context: pointer to qdf context
+ * @rxbuf: pointer to rx qdf_nbuf
+ *
+ * TL will call this to notify the HDD when one or more packets were
+ * received for a registered STA.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS dp_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf);
+
+/**
+ * dp_monitor_set_rx_monitor_cb(): Set rx monitor mode callback function
+ * @txrx: pointer to txrx ops
+ * @rx_monitor_cb: pointer to callback function
+ *
+ * Returns: None
+ */
+void dp_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+				  ol_txrx_rx_mon_fp rx_monitor_cb);
+/**
+ * dp_rx_monitor_callback(): Callback function for receive monitor mode
+ * @vdev: Handle to vdev object
+ * @mpdu: pointer to mpdu to be delivered to os
+ * @rx_status: receive status
+ *
+ * Returns: None
+ */
+void dp_rx_monitor_callback(ol_osif_vdev_handle vdev,
+			    qdf_nbuf_t mpdu,
+			    void *rx_status);
+
+#else
+static inline
+QDF_STATUS dp_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+void dp_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+				  ol_txrx_rx_mon_fp rx_monitor_cb) { }
+
+static inline
+void dp_rx_monitor_callback(ol_osif_vdev_handle vdev, qdf_nbuf_t mpdu,
+			    void *rx_status) { }
+#endif
+
+/**
+ * dp_sta_notify_tx_comp_cb() - notify tx comp callback registered with dp
+ * @nbuf: pointer to nbuf
+ * @ctx: osif context
+ * @flag: tx status flag
+ *
+ * Return: None
+ */
+void dp_sta_notify_tx_comp_cb(qdf_nbuf_t nbuf, void *ctx, uint16_t flag);
+
+/**
+ * dp_softap_notify_tx_compl_cbk() - notify softap tx comp registered with dp
+ * @nbuf: pointer to nbuf
+ * @context: osif context
+ * @flag: tx status flag
+ *
+ * Return: None
+ */
+void dp_softap_notify_tx_compl_cbk(qdf_nbuf_t nbuf,
+				   void *context, uint16_t flag);
+
+/**
+ * dp_rx_pkt_tracepoints_enabled() - Get the state of rx pkt tracepoint
+ *
+ * Return: True if any rx pkt tracepoint is enabled else false
+ */
+static inline bool dp_rx_pkt_tracepoints_enabled(void)
+{
+	return (qdf_trace_dp_rx_tcp_pkt_enabled() ||
+		qdf_trace_dp_rx_udp_pkt_enabled() ||
+		qdf_trace_dp_rx_pkt_enabled());
+}
+
+#ifdef CONFIG_DP_PKT_ADD_TIMESTAMP
+/**
+ * wlan_dp_pkt_add_timestamp() - add timestamp in data payload
+ * @dp_intf: DP interface
+ * @index: timestamp index which decides offset in payload
+ * @nbuf: Network socket buffer
+ *
+ * Return: none
+ */
+void wlan_dp_pkt_add_timestamp(struct wlan_dp_intf *dp_intf,
+			       enum qdf_pkt_timestamp_index index,
+			       qdf_nbuf_t nbuf);
+#else
+static inline
+void wlan_dp_pkt_add_timestamp(struct wlan_dp_intf *dp_intf,
+			  enum qdf_pkt_timestamp_index index,
+			  qdf_nbuf_t nbuf)
+{
+}
+#endif
+
+#if defined(FEATURE_LRO)
+/**
+ * dp_lro_set_reset() - API for Disable/Enable LRO
+ * @dp_intf: DP interface pointer
+ * @enable_flag: enable or disable LRO.
+ *
+ * Return: 0 on success and non zero on failure.
+ */
+QDF_STATUS dp_lro_set_reset(struct wlan_dp_intf *dp_intf, uint8_t enable_flag);
+#else
+static inline
+QDF_STATUS dp_lro_set_reset(struct wlan_dp_intf *dp_intf,
+			    uint8_t enable_flag)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif /* FEATURE_LRO */
+
+#ifdef RECEIVE_OFFLOAD
+/**
+ * dp_rx_ol_init() - Initialize Rx offload mode (LRO or GRO)
+ * @dp_ctx: pointer to DP Context
+ * @is_wifi3_0_target: true if it wifi3.0 target
+ *
+ * Return: 0 on success and non zero on failure.
+ */
+QDF_STATUS dp_rx_ol_init(struct wlan_dp_psoc_context *dp_ctx,
+			 bool is_wifi3_0_target);
+#else /* RECEIVE_OFFLOAD */
+
+static inline QDF_STATUS
+dp_rx_ol_init(struct wlan_dp_psoc_context *dp_ctx,
+	      bool is_wifi3_0_target)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
+#ifdef WLAN_FEATURE_11BE_MLO
+static inline
+void dp_rx_pkt_da_check(struct wlan_dp_intf *dp_intf, qdf_nbuf_t nbuf)
+{
+	/* only do DA check for RX frame from non-regular path */
+	if (!qdf_nbuf_is_exc_frame(nbuf))
+		return;
+
+	if (qdf_mem_cmp(qdf_nbuf_data(nbuf), dp_intf->mac_addr.bytes,
+			ETH_ALEN)) {
+		dp_info("da mac:" QDF_MAC_ADDR_FMT "intf_mac:" QDF_MAC_ADDR_FMT,
+			QDF_MAC_ADDR_REF(qdf_nbuf_data(nbuf)),
+			QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes));
+		qdf_mem_copy(qdf_nbuf_data(nbuf), dp_intf->mac_addr.bytes,
+			     ETH_ALEN);
+	}
+}
+#else
+static inline
+void dp_rx_pkt_da_check(struct wlan_dp_intf *dp_intf, qdf_nbuf_t nbuf)
+{
+}
+#endif
+
+#endif

+ 187 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/inc/wlan_dp_wfds.h

@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the 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_DP_WFDS_H_
+#define _WLAN_DP_WFDS_H_
+
+#ifdef FEATURE_DIRECT_LINK
+
+#include "qdf_atomic.h"
+#include "wlan_dp_priv.h"
+#include "wlan_qmi_public_struct.h"
+#include "wlan_qmi_wfds_api.h"
+
+#define DP_WFDS_CE_MAX_SRNG QMI_WFDS_CE_MAX_SRNG
+
+/**
+ * enum dp_wfds_msg - WFDS message type
+ * @DP_WFDS_REQ_MEM_IND_MSG: Memory request indication message
+ * @DP_WFDS_IPCC_MAP_N_CFG_IND_MSG: IPCC map and configure indication message
+ * @DP_WFDS_MSG_MAX: not a real value just a placeholder for max
+ */
+enum dp_wfds_msg {
+	DP_WFDS_REQ_MEM_IND_MSG,
+	DP_WFDS_IPCC_MAP_N_CFG_IND_MSG,
+	DP_WFDS_MSG_MAX,
+};
+
+/**
+ * enum dp_wfds_state - Datapath WFDS state
+ * @DP_WFDS_SVC_DISCONNECTED: service disconnected
+ * @DP_WFDS_SVC_CONNECTED: service connected
+ * @DP_WFDS_SVC_CONFIG_DONE: configuration msg handshake done
+ * @DP_WFDS_SVC_MEM_CONFIG_DONE: memory handshake with server done
+ * @DP_WFDS_SVC_IPCC_MAP_N_CFG_DONE: IPCC map and cfg handshake completed
+ */
+enum dp_wfds_state {
+	DP_WFDS_SVC_DISCONNECTED,
+	DP_WFDS_SVC_CONNECTED,
+	DP_WFDS_SVC_CONFIG_DONE,
+	DP_WFDS_SVC_MEM_CONFIG_DONE,
+	DP_WFDS_SVC_IPCC_MAP_N_CFG_DONE,
+};
+
+/**
+ * enum dp_wfds_event_type  - Datapath WFDS event type
+ * @DP_WFDS_NEW_SERVER: QMI new server event
+ * @DP_WFDS_MEM_REQ: QMI memory request event
+ * @DP_WFDS_IPCC_MAP_N_CFG: QMI IPCC map and configure event
+ */
+enum dp_wfds_event_type {
+	DP_WFDS_NEW_SERVER,
+	DP_WFDS_MEM_REQ,
+	DP_WFDS_IPCC_MAP_N_CFG,
+};
+
+/**
+ * struct dp_wfds_event - DP QMI event structure
+ * @list_node: node used for adding/deleting to a list
+ * @wfds_evt_type: QMI event type
+ * @data: Pointer to event data
+ */
+struct dp_wfds_event {
+	qdf_list_node_t list_node;
+	enum dp_wfds_event_type wfds_evt_type;
+	void *data;
+};
+
+/**
+ * struct dp_direct_link_iommu_config - Direct link related IOMMU configuration
+ * @shadow_rdptr_paddr: shadow read pointer dma address
+ * @shadow_rdptr_map_size: shadow read pointer memory size
+ * @shadow_wrptr_paddr: shadow write pointer dma address
+ * @shadow_wrptr_map_size: shadow write pointer memory size
+ * @direct_link_srng_ring_base_paddr: SRNG ring base dma address
+ * @direct_link_srng_ring_map_size: SRNG ring memory size
+ * @direct_link_refill_ring_base_paddr: refill SRNG ring base dma address
+ * @direct_link_refill_ring_map_size: refill SRNG ring memory size
+ */
+struct dp_direct_link_iommu_config {
+	qdf_dma_addr_t shadow_rdptr_paddr;
+	uint16_t shadow_rdptr_map_size;
+	qdf_dma_addr_t shadow_wrptr_paddr;
+	uint16_t shadow_wrptr_map_size;
+	qdf_dma_addr_t direct_link_srng_ring_base_paddr[QMI_WFDS_CE_MAX_SRNG];
+	uint16_t direct_link_srng_ring_map_size[QMI_WFDS_CE_MAX_SRNG];
+	qdf_dma_addr_t direct_link_refill_ring_base_paddr;
+	uint16_t direct_link_refill_ring_map_size;
+};
+
+/**
+ * struct dp_direct_link_wfds_context - DP Direct Link WFDS context structure
+ * @direct_link_ctx: direct link context
+ * @wfds_work: work to be scheduled on QMI event
+ * @wfds_wq: QMI workqueue
+ * @wfds_event_list_lock: spinlock for event list access
+ * @wfds_event_list: QMI event list
+ * @wfds_state: QMI state
+ * @num_mem_arenas: Number of memory arenas requested by QMI server
+ * @mem_arena_pages: Pointer to array of mem multi page structure for arenas
+ * @ipcc_dma_addr: ipcc dma address
+ * @ipcc_ce_id: ids of CEs that are configured with IPCC MSI info
+ * @ipcc_ce_id_len: number of valid entries in ipcc_ce_id array
+ * @iommu_cfg: direct link iommu configuration
+ */
+struct dp_direct_link_wfds_context {
+	struct dp_direct_link_context *direct_link_ctx;
+	qdf_work_t wfds_work;
+	qdf_workqueue_t *wfds_wq;
+	qdf_spinlock_t wfds_event_list_lock;
+	qdf_list_t wfds_event_list;
+	qdf_atomic_t wfds_state;
+	uint32_t num_mem_arenas;
+	struct qdf_mem_multi_page_t *mem_arena_pages;
+	uint32_t ipcc_dma_addr;
+	uint8_t ipcc_ce_id[DP_WFDS_CE_MAX_SRNG];
+	uint8_t ipcc_ce_id_len;
+	struct dp_direct_link_iommu_config iommu_cfg;
+};
+
+/**
+ * dp_wfds_handle_request_mem_ind() - Process request memory indication received
+ *  from QMI server
+ * @mem_msg: pointer to memory request indication message
+ *
+ * Return: None
+ */
+void
+dp_wfds_handle_request_mem_ind(struct wlan_qmi_wfds_mem_ind_msg *mem_msg);
+
+/**
+ * dp_wfds_handle_ipcc_map_n_cfg_ind() - Process IPCC map and configure
+ *  indication received from QMI server
+ * @ipcc_msg: pointer to IPCC map and configure indication message
+ *
+ * Return: None
+ */
+void
+dp_wfds_handle_ipcc_map_n_cfg_ind(struct wlan_qmi_wfds_ipcc_map_n_cfg_ind_msg *ipcc_msg);
+
+/**
+ * dp_wfds_new_server() - New server callback triggered when service is up.
+ *  Connect to the service as part of this call.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS dp_wfds_new_server(void);
+
+/**
+ * dp_wfds_del_server() - Del server callback triggered when service is
+ *  down.
+ *
+ * Return: None
+ */
+void dp_wfds_del_server(void);
+
+/**
+ * dp_wfds_init() - Initialize DP WFDS context
+ * @direct_link_ctx: DP Direct Link context
+ *
+ * Return: QDF status
+ */
+QDF_STATUS dp_wfds_init(struct dp_direct_link_context *direct_link_ctx);
+
+/**
+ * dp_wfds_deinit() - Deinitialize DP WFDS context
+ * @direct_link_ctx: DP Direct Link context
+ * @is_ssr: true if SSR is in progress else false
+ *
+ * Return: None
+ */
+void dp_wfds_deinit(struct dp_direct_link_context *direct_link_ctx,
+		    bool is_ssr);
+#endif
+#endif

+ 2347 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/src/wlan_dp_bus_bandwidth.c

@@ -0,0 +1,2347 @@
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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_dp_bus_bandwidth.c
+ *
+ * Bus Bandwidth Manager implementation
+ */
+
+#include "wlan_dp_bus_bandwidth.h"
+#include "wlan_dp_main.h"
+#include <wlan_objmgr_psoc_obj_i.h>
+#include "pld_common.h"
+#include "cds_api.h"
+#include <wlan_nlink_common.h>
+#include "wlan_ipa_ucfg_api.h"
+#include "wlan_dp_rx_thread.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+#include "hif.h"
+#include "qdf_trace.h"
+#include <wlan_cm_api.h>
+#include <qdf_threads.h>
+#include <qdf_net_stats.h>
+#include "wlan_dp_periodic_sta_stats.h"
+#include "wlan_mlme_api.h"
+#include "wlan_dp_txrx.h"
+#include "cdp_txrx_host_stats.h"
+#include "wlan_cm_roam_api.h"
+#include "hif_main.h"
+
+#ifdef FEATURE_BUS_BANDWIDTH_MGR
+/*
+ * bus_bw_table_default: default table which provides bus
+ * bandwidth level corresponding to a given connection mode and throughput
+ * level.
+ */
+static bus_bw_table_type bus_bw_table_default = {
+	[QCA_WLAN_802_11_MODE_11B] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
+				      BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
+				      BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
+				      BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
+				      BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11G] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_5,
+				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
+				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
+				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
+				      BUS_BW_LEVEL_5},
+	[QCA_WLAN_802_11_MODE_11A] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_5,
+				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
+				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
+				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
+				      BUS_BW_LEVEL_5},
+	[QCA_WLAN_802_11_MODE_11N] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
+				      BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
+				      BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
+				      BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
+				      BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11AC] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
+				       BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
+				       BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
+				       BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
+				       BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11AX] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
+				       BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
+				       BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
+				       BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
+				       BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11BE] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
+				       BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
+				       BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
+				       BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
+				       BUS_BW_LEVEL_9},
+};
+
+/*
+ * bus_bw_table_low_latency: table which provides bus
+ * bandwidth level corresponding to a given connection mode and throughput
+ * level in low latency setting.
+ */
+static bus_bw_table_type bus_bw_table_low_latency = {
+	[QCA_WLAN_802_11_MODE_11B] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11G] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11A] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11N] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				      BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11AC] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11AX] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9},
+	[QCA_WLAN_802_11_MODE_11BE] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
+				       BUS_BW_LEVEL_9},
+};
+
+/**
+ * bbm_convert_to_pld_bus_lvl() - Convert from internal bus vote level to
+ *  PLD bus vote level
+ * @vote_lvl: internal bus bw vote level
+ *
+ * Returns: PLD bus vote level
+ */
+static enum pld_bus_width_type
+bbm_convert_to_pld_bus_lvl(enum bus_bw_level vote_lvl)
+{
+	switch (vote_lvl) {
+	case BUS_BW_LEVEL_1:
+		return PLD_BUS_WIDTH_IDLE;
+	case BUS_BW_LEVEL_2:
+		return PLD_BUS_WIDTH_LOW;
+	case BUS_BW_LEVEL_3:
+		return PLD_BUS_WIDTH_MEDIUM;
+	case BUS_BW_LEVEL_4:
+		return PLD_BUS_WIDTH_HIGH;
+	case BUS_BW_LEVEL_5:
+		return PLD_BUS_WIDTH_LOW_LATENCY;
+	case BUS_BW_LEVEL_6:
+		return PLD_BUS_WIDTH_MID_HIGH;
+	case BUS_BW_LEVEL_7:
+		return PLD_BUS_WIDTH_VERY_HIGH;
+	case BUS_BW_LEVEL_8:
+		return PLD_BUS_WIDTH_ULTRA_HIGH;
+	case BUS_BW_LEVEL_9:
+		return PLD_BUS_WIDTH_MAX;
+	case BUS_BW_LEVEL_NONE:
+	default:
+		return PLD_BUS_WIDTH_NONE;
+	}
+}
+
+/**
+ * bbm_get_bus_bw_level_vote() - Select bus bw vote level per interface based
+ *  on connection mode and throughput level
+ * @dp_intf: DP Interface, caller assure that interface is valid.
+ * @tput_level: throughput level
+ *
+ * Returns: Bus bw level
+ */
+static enum bus_bw_level
+bbm_get_bus_bw_level_vote(struct wlan_dp_intf *dp_intf,
+			  enum tput_level tput_level)
+{
+	enum qca_wlan_802_11_mode i;
+	enum qca_wlan_802_11_mode dot11_mode;
+	enum bus_bw_level vote_lvl = BUS_BW_LEVEL_NONE;
+	struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx;
+	struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx;
+	bus_bw_table_type *lkp_table = bbm_ctx->curr_bus_bw_lookup_table;
+	uint16_t client_count[QCA_WLAN_802_11_MODE_INVALID];
+	struct wlan_dp_psoc_callbacks *cb_obj = &dp_ctx->dp_ops;
+	hdd_cb_handle ctx = cb_obj->callback_ctx;
+
+	if (tput_level >= TPUT_LEVEL_MAX) {
+		dp_err("invalid tput level %d", tput_level);
+		return  BUS_BW_LEVEL_NONE;
+	}
+
+	switch (dp_intf->device_mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+		if (!cb_obj->wlan_dp_sta_get_dot11mode(ctx,
+						       dp_intf->dev,
+						       &dot11_mode))
+			break;
+
+		if (dot11_mode >= QCA_WLAN_802_11_MODE_INVALID)
+			break;
+
+		return (*lkp_table)[dot11_mode][tput_level];
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+		if (!cb_obj->wlan_dp_get_ap_client_count(ctx,
+							 dp_intf->dev,
+							 client_count))
+			break;
+
+		for (i = QCA_WLAN_802_11_MODE_11B;
+		     i < QCA_WLAN_802_11_MODE_INVALID; i++) {
+			if (client_count[i] &&
+			    (*lkp_table)[i][tput_level] > vote_lvl)
+				vote_lvl = (*lkp_table)[i][tput_level];
+		}
+
+		return vote_lvl;
+	case QDF_NDI_MODE:
+		if (!cb_obj->wlan_dp_sta_ndi_connected(ctx,
+						       dp_intf->dev))
+			break;
+
+		/*
+		 * If the tput levels are between mid to high range, then
+		 * apply next SNOC voting level BUS_BW_LEVEL_5 which maps
+		 * to PLD_BUS_WIDTH_LOW_LATENCY.
+		 *
+		 * NDI dot11mode is currently hardcoded to 11AC in driver and
+		 * since the bus bw levels in table do not differ between 11AC
+		 * and 11AX, using max supported mode instead. Dot11mode of the
+		 * peers are not saved in driver and legacy modes are not
+		 * supported in NAN.
+		 */
+		if (tput_level <= TPUT_LEVEL_HIGH)
+			return BUS_BW_LEVEL_5;
+		else
+			return (*lkp_table)[QCA_WLAN_802_11_MODE_11AX][tput_level];
+	default:
+		break;
+	}
+
+	return vote_lvl;
+}
+
+/**
+ * bbm_apply_tput_policy() - Apply tput BBM policy by considering
+ *  throughput level and connection modes across adapters
+ * @dp_ctx: DP context
+ * @tput_level: throughput level
+ *
+ * Returns: None
+ */
+static void
+bbm_apply_tput_policy(struct wlan_dp_psoc_context *dp_ctx,
+		      enum tput_level tput_level)
+{
+	struct wlan_dp_intf *dp_intf;
+	struct wlan_dp_intf *dp_intf_next;
+	struct wlan_objmgr_psoc *psoc;
+	enum bus_bw_level next_vote = BUS_BW_LEVEL_NONE;
+	enum bus_bw_level tmp_vote;
+	struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx;
+	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+
+	if (tput_level == TPUT_LEVEL_NONE) {
+		/*
+		 * This is to handle the scenario where bus bw periodic work
+		 * is force cancelled
+		 */
+		if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx))
+			bbm_ctx->per_policy_vote[BBM_TPUT_POLICY] = next_vote;
+		return;
+	}
+
+	psoc = dp_ctx->psoc;
+	if (!psoc) {
+		dp_err("psoc is NULL");
+		return;
+	}
+
+	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
+		if (dp_intf->num_links == 0)
+			continue;
+
+		tmp_vote = bbm_get_bus_bw_level_vote(dp_intf, tput_level);
+		if (tmp_vote > next_vote)
+			next_vote = tmp_vote;
+	}
+
+	bbm_ctx->per_policy_vote[BBM_TPUT_POLICY] = next_vote;
+}
+
+/**
+ * bbm_apply_driver_mode_policy() - Apply driver mode BBM policy
+ * @bbm_ctx: bus bw mgr context
+ * @driver_mode: global driver mode
+ *
+ * Returns: None
+ */
+static void
+bbm_apply_driver_mode_policy(struct bbm_context *bbm_ctx,
+			     enum QDF_GLOBAL_MODE driver_mode)
+{
+	switch (driver_mode) {
+	case QDF_GLOBAL_MONITOR_MODE:
+	case QDF_GLOBAL_FTM_MODE:
+		bbm_ctx->per_policy_vote[BBM_DRIVER_MODE_POLICY] =
+							    BUS_BW_LEVEL_7;
+		return;
+	default:
+		bbm_ctx->per_policy_vote[BBM_DRIVER_MODE_POLICY] =
+							 BUS_BW_LEVEL_NONE;
+		return;
+	}
+}
+
+/**
+ * bbm_apply_non_persistent_policy() - Apply non persistent policy and set
+ *  the bus bandwidth
+ * @dp_ctx: DP context
+ * @flag: flag
+ *
+ * Returns: None
+ */
+static void
+bbm_apply_non_persistent_policy(struct wlan_dp_psoc_context *dp_ctx,
+				enum bbm_non_per_flag flag)
+{
+	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+
+	switch (flag) {
+	case BBM_APPS_RESUME:
+		if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx)) {
+			dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_RESUME;
+			pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev,
+			       bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_RESUME));
+		} else {
+			dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_NONE;
+			pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev,
+				 bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_NONE));
+		}
+		return;
+	case BBM_APPS_SUSPEND:
+		dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_NONE;
+		pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev,
+			    bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_NONE));
+		return;
+	default:
+		dp_info("flag %d not handled in res/sus BBM policy", flag);
+		return;
+	}
+}
+
+/**
+ * bbm_apply_wlm_policy() - Apply WLM based BBM policy by selecting
+ *  lookup tables based on the latency level
+ * @bbm_ctx: Bus BW mgr context
+ * @wlm_level: WLM latency level
+ *
+ * Returns: None
+ */
+static void
+bbm_apply_wlm_policy(struct bbm_context *bbm_ctx, enum wlm_ll_level wlm_level)
+{
+	switch (wlm_level) {
+	case WLM_LL_NORMAL:
+		bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_default;
+		break;
+	case WLM_LL_LOW:
+		bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_low_latency;
+		break;
+	default:
+		dp_info("wlm level %d not handled in BBM WLM policy",
+			wlm_level);
+		break;
+	}
+}
+
+/**
+ * bbm_apply_user_policy() - Apply user specified bus voting
+ *  level
+ * @bbm_ctx: Bus BW mgr context
+ * @set: set or reset flag
+ * @user_level: user bus vote level
+ *
+ * Returns: qdf status
+ */
+static QDF_STATUS
+bbm_apply_user_policy(struct bbm_context *bbm_ctx, bool set,
+		      enum bus_bw_level user_level)
+{
+	if (user_level >= BUS_BW_LEVEL_MAX) {
+		dp_err("Invalid user vote level %d", user_level);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (set)
+		bbm_ctx->per_policy_vote[BBM_USER_POLICY] = user_level;
+	else
+		bbm_ctx->per_policy_vote[BBM_USER_POLICY] = BUS_BW_LEVEL_NONE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * bbm_request_bus_bandwidth() - Set bus bandwidth level
+ * @dp_ctx: DP context
+ *
+ * Returns: None
+ */
+static void
+bbm_request_bus_bandwidth(struct wlan_dp_psoc_context *dp_ctx)
+{
+	enum bbm_policy i;
+	enum bus_bw_level next_vote = BUS_BW_LEVEL_NONE;
+	enum pld_bus_width_type pld_vote;
+	struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx;
+
+	for (i = BBM_DRIVER_MODE_POLICY; i < BBM_MAX_POLICY; i++) {
+		if (bbm_ctx->per_policy_vote[i] > next_vote)
+			next_vote = bbm_ctx->per_policy_vote[i];
+	}
+
+	if (next_vote != bbm_ctx->curr_vote_level) {
+		pld_vote = bbm_convert_to_pld_bus_lvl(next_vote);
+		dp_info("Bus bandwidth vote level change from %d to %d pld_vote: %d",
+			bbm_ctx->curr_vote_level, next_vote, pld_vote);
+		bbm_ctx->curr_vote_level = next_vote;
+		pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev, pld_vote);
+	}
+}
+
+void dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc,
+				     struct bbm_params *params)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+	struct bbm_context *bbm_ctx;
+	QDF_STATUS status;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx || !params)
+		return;
+
+	bbm_ctx = dp_ctx->bbm_ctx;
+
+	qdf_mutex_acquire(&bbm_ctx->bbm_lock);
+
+	switch (params->policy) {
+	case BBM_TPUT_POLICY:
+		bbm_apply_tput_policy(dp_ctx, params->policy_info.tput_level);
+		break;
+	case BBM_NON_PERSISTENT_POLICY:
+		bbm_apply_non_persistent_policy(dp_ctx,
+						params->policy_info.flag);
+		goto done;
+	case BBM_DRIVER_MODE_POLICY:
+		bbm_apply_driver_mode_policy(bbm_ctx,
+					     params->policy_info.driver_mode);
+		break;
+	case BBM_SELECT_TABLE_POLICY:
+		bbm_apply_wlm_policy(bbm_ctx, params->policy_info.wlm_level);
+		goto done;
+	case BBM_USER_POLICY:
+		/*
+		 * This policy is not used currently.
+		 */
+		status = bbm_apply_user_policy(bbm_ctx,
+					       params->policy_info.usr.set,
+					       params->policy_info.usr.user_level);
+		if (QDF_IS_STATUS_ERROR(status))
+			goto done;
+		break;
+	default:
+		dp_info("BBM policy %d not handled", params->policy);
+		goto done;
+	}
+
+	bbm_request_bus_bandwidth(dp_ctx);
+
+done:
+	qdf_mutex_release(&bbm_ctx->bbm_lock);
+}
+
+int dp_bbm_context_init(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+	struct bbm_context *bbm_ctx;
+	QDF_STATUS status;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx)
+		return -EINVAL;
+	bbm_ctx = qdf_mem_malloc(sizeof(*bbm_ctx));
+	if (!bbm_ctx)
+		return -ENOMEM;
+
+	bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_default;
+
+	status = qdf_mutex_create(&bbm_ctx->bbm_lock);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto free_ctx;
+
+	dp_ctx->bbm_ctx = bbm_ctx;
+
+	return 0;
+
+free_ctx:
+	qdf_mem_free(bbm_ctx);
+
+	return qdf_status_to_os_return(status);
+}
+
+void dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+	struct bbm_context *bbm_ctx;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx)
+		return;
+	bbm_ctx = dp_ctx->bbm_ctx;
+	if (!bbm_ctx)
+		return;
+
+	dp_ctx->bbm_ctx = NULL;
+	qdf_mutex_destroy(&bbm_ctx->bbm_lock);
+
+	qdf_mem_free(bbm_ctx);
+}
+#endif /* FEATURE_BUS_BANDWIDTH_MGR */
+#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
+#ifdef FEATURE_RUNTIME_PM
+void dp_rtpm_tput_policy_init(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+	struct dp_rtpm_tput_policy_context *ctx;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	ctx = &dp_ctx->rtpm_tput_policy_ctx;
+	qdf_runtime_lock_init(&ctx->rtpm_lock);
+	ctx->curr_state = DP_RTPM_TPUT_POLICY_STATE_REQUIRED;
+	qdf_atomic_init(&ctx->high_tput_vote);
+}
+
+void dp_rtpm_tput_policy_deinit(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx;
+	struct dp_rtpm_tput_policy_context *ctx;
+
+	dp_ctx = dp_psoc_get_priv(psoc);
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	ctx = &dp_ctx->rtpm_tput_policy_ctx;
+	ctx->curr_state = DP_RTPM_TPUT_POLICY_STATE_INVALID;
+	qdf_runtime_lock_deinit(&ctx->rtpm_lock);
+}
+
+/**
+ * dp_rtpm_tput_policy_prevent() - prevent a runtime bus suspend
+ * @dp_ctx: DP handle
+ *
+ * return: None
+ */
+static void dp_rtpm_tput_policy_prevent(struct wlan_dp_psoc_context *dp_ctx)
+{
+	struct dp_rtpm_tput_policy_context *ctx;
+
+	ctx = &dp_ctx->rtpm_tput_policy_ctx;
+	qdf_runtime_pm_prevent_suspend(&ctx->rtpm_lock);
+}
+
+/**
+ * dp_rtpm_tput_policy_allow() - allow a runtime bus suspend
+ * @dp_ctx: DP handle
+ *
+ * return: None
+ */
+static void dp_rtpm_tput_policy_allow(struct wlan_dp_psoc_context *dp_ctx)
+{
+	struct dp_rtpm_tput_policy_context *ctx;
+
+	ctx = &dp_ctx->rtpm_tput_policy_ctx;
+	qdf_runtime_pm_allow_suspend(&ctx->rtpm_lock);
+}
+
+#define DP_RTPM_POLICY_HIGH_TPUT_THRESH TPUT_LEVEL_MEDIUM
+
+void dp_rtpm_tput_policy_apply(struct wlan_dp_psoc_context *dp_ctx,
+			       enum tput_level tput_level)
+{
+	int vote;
+	enum dp_rtpm_tput_policy_state temp_state;
+	struct dp_rtpm_tput_policy_context *ctx;
+	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (qdf_unlikely(!soc))
+		return;
+
+	ctx = &dp_ctx->rtpm_tput_policy_ctx;
+
+	if (tput_level >= DP_RTPM_POLICY_HIGH_TPUT_THRESH)
+		temp_state = DP_RTPM_TPUT_POLICY_STATE_NOT_REQUIRED;
+	else
+		temp_state = DP_RTPM_TPUT_POLICY_STATE_REQUIRED;
+
+	if (ctx->curr_state == temp_state)
+		return;
+
+	if (temp_state == DP_RTPM_TPUT_POLICY_STATE_REQUIRED) {
+		cdp_set_rtpm_tput_policy_requirement(soc, false);
+		qdf_atomic_dec(&ctx->high_tput_vote);
+		dp_rtpm_tput_policy_allow(dp_ctx);
+	} else {
+		cdp_set_rtpm_tput_policy_requirement(soc, true);
+		qdf_atomic_inc(&ctx->high_tput_vote);
+		dp_rtpm_tput_policy_prevent(dp_ctx);
+	}
+
+	ctx->curr_state = temp_state;
+	vote = qdf_atomic_read(&ctx->high_tput_vote);
+
+	if (vote < 0 || vote > 1) {
+		dp_alert_rl("Incorrect vote!");
+		QDF_BUG(0);
+	}
+}
+
+int dp_rtpm_tput_policy_get_vote(struct wlan_dp_psoc_context *dp_ctx)
+{
+	struct dp_rtpm_tput_policy_context *ctx;
+
+	ctx = &dp_ctx->rtpm_tput_policy_ctx;
+	return qdf_atomic_read(&ctx->high_tput_vote);
+}
+#endif /* FEATURE_RUNTIME_PM */
+
+void dp_reset_tcp_delack(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+
+	enum wlan_tp_level next_level = WLAN_SVC_TP_LOW;
+	struct wlan_rx_tp_data rx_tp_data = {0};
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	if (!dp_ctx->en_tcp_delack_no_lro)
+		return;
+
+	rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
+	rx_tp_data.level = next_level;
+	dp_ctx->rx_high_ind_cnt = 0;
+	wlan_dp_update_tcp_rx_param(dp_ctx, &rx_tp_data);
+}
+
+/**
+ * dp_reset_tcp_adv_win_scale() - Reset TCP advance window scaling
+ * value to default
+ * @dp_ctx: pointer to DP context (Should not be NULL)
+ *
+ * Function used to reset TCP advance window scaling
+ * value to its default value
+ *
+ * Return: None
+ */
+static void dp_reset_tcp_adv_win_scale(struct wlan_dp_psoc_context *dp_ctx)
+{
+	enum wlan_tp_level next_level = WLAN_SVC_TP_NONE;
+	struct wlan_rx_tp_data rx_tp_data = {0};
+
+	if (!dp_ctx->dp_cfg.enable_tcp_adv_win_scale)
+		return;
+
+	rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
+	rx_tp_data.level = next_level;
+	dp_ctx->cur_rx_level = WLAN_SVC_TP_NONE;
+	wlan_dp_update_tcp_rx_param(dp_ctx, &rx_tp_data);
+}
+
+void wlan_dp_update_tcp_rx_param(struct wlan_dp_psoc_context *dp_ctx,
+				 struct wlan_rx_tp_data *data)
+{
+	struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops;
+
+	if (!dp_ctx) {
+		dp_err("psoc is null");
+		return;
+	}
+
+	if (!data) {
+		dp_err("Data is null");
+		return;
+	}
+
+	if (dp_ctx->dp_cfg.enable_tcp_param_update)
+		dp_ops->osif_dp_send_tcp_param_update_event(dp_ctx->psoc,
+							    (union wlan_tp_data *)data,
+							    1);
+	else
+		dp_ops->dp_send_svc_nlink_msg(cds_get_radio_index(),
+					      WLAN_SVC_WLAN_TP_IND,
+					      (void *)data,
+					      sizeof(struct wlan_rx_tp_data));
+}
+
+/**
+ * wlan_dp_update_tcp_tx_param() - update TCP param in Tx dir
+ * @dp_ctx: Pointer to DP context
+ * @data: Parameters to update
+ *
+ * Return: None
+ */
+static void wlan_dp_update_tcp_tx_param(struct wlan_dp_psoc_context *dp_ctx,
+					struct wlan_tx_tp_data *data)
+{
+	enum wlan_tp_level next_tx_level;
+	struct wlan_tx_tp_data *tx_tp_data;
+	struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops;
+
+	if (!dp_ctx) {
+		dp_err("psoc is null");
+		return;
+	}
+
+	if (!data) {
+		dp_err("Data is null");
+		return;
+	}
+
+	tx_tp_data = (struct wlan_tx_tp_data *)data;
+	next_tx_level = tx_tp_data->level;
+
+	if (dp_ctx->dp_cfg.enable_tcp_param_update)
+		dp_ops->osif_dp_send_tcp_param_update_event(dp_ctx->psoc,
+							    (union wlan_tp_data *)data,
+							    0);
+	else
+		dp_ops->dp_send_svc_nlink_msg(cds_get_radio_index(),
+					      WLAN_SVC_WLAN_TP_TX_IND,
+					      &next_tx_level,
+					      sizeof(next_tx_level));
+}
+
+/**
+ * dp_low_tput_gro_flush_skip_handler() - adjust GRO flush for low tput
+ * @dp_ctx: dp_ctx object
+ * @next_vote_level: next bus bandwidth level
+ * @legacy_client: legacy connection mode active
+ *
+ * If bus bandwidth level is PLD_BUS_WIDTH_LOW consistently and hit
+ * the bus_low_cnt_threshold, set flag to skip GRO flush.
+ * If bus bandwidth keeps going to PLD_BUS_WIDTH_IDLE, perform a GRO
+ * flush to avoid TCP traffic stall
+ *
+ * Return: none
+ */
+static inline void dp_low_tput_gro_flush_skip_handler(
+			struct wlan_dp_psoc_context *dp_ctx,
+			enum pld_bus_width_type next_vote_level,
+			bool legacy_client)
+{
+	uint32_t threshold = dp_ctx->dp_cfg.bus_low_cnt_threshold;
+	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
+	int i;
+
+	if (next_vote_level == PLD_BUS_WIDTH_LOW && legacy_client) {
+		if (++dp_ctx->bus_low_vote_cnt >= threshold)
+			qdf_atomic_set(&dp_ctx->low_tput_gro_enable, 1);
+	} else {
+		if (qdf_atomic_read(&dp_ctx->low_tput_gro_enable) &&
+		    dp_ctx->enable_dp_rx_threads) {
+			/* flush pending rx pkts when LOW->IDLE */
+			dp_info("flush queued GRO pkts");
+			for (i = 0; i < cdp_get_num_rx_contexts(soc); i++) {
+				dp_rx_gro_flush_ind(soc, i,
+						    DP_RX_GRO_NORMAL_FLUSH);
+			}
+		}
+
+		dp_ctx->bus_low_vote_cnt = 0;
+		qdf_atomic_set(&dp_ctx->low_tput_gro_enable, 0);
+	}
+}
+
+#ifdef WDI3_STATS_UPDATE
+/**
+ * dp_ipa_set_perf_level() - set IPA perf level
+ * @dp_ctx: handle to dp context
+ * @tx_pkts: transmit packet count
+ * @rx_pkts: receive packet count
+ * @ipa_tx_pkts: IPA transmit packet count
+ * @ipa_rx_pkts: IPA receive packet count
+ *
+ * Return: none
+ */
+static inline
+void dp_ipa_set_perf_level(struct wlan_dp_psoc_context *dp_ctx,
+			   uint64_t *tx_pkts, uint64_t *rx_pkts,
+			   uint32_t *ipa_tx_pkts, uint32_t *ipa_rx_pkts)
+{
+}
+#else
+static void dp_ipa_set_perf_level(struct wlan_dp_psoc_context *dp_ctx,
+				  uint64_t *tx_pkts, uint64_t *rx_pkts,
+				  uint32_t *ipa_tx_pkts, uint32_t *ipa_rx_pkts)
+{
+	if (ucfg_ipa_is_fw_wdi_activated(dp_ctx->pdev)) {
+		ucfg_ipa_uc_stat_query(dp_ctx->pdev, ipa_tx_pkts,
+				       ipa_rx_pkts);
+		*tx_pkts += *ipa_tx_pkts;
+		*rx_pkts += *ipa_rx_pkts;
+
+		ucfg_ipa_set_perf_level(dp_ctx->pdev, *tx_pkts, *rx_pkts);
+		ucfg_ipa_uc_stat_request(dp_ctx->pdev, 2);
+	}
+}
+#endif /* WDI3_STATS_UPDATE */
+
+#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE
+/**
+ * dp_set_vdev_bundle_require_flag() - set vdev bundle require flag
+ * @vdev_id: vdev id
+ * @dp_ctx: handle to dp context
+ * @tx_bytes: Tx bytes
+ *
+ * Return: none
+ */
+static inline
+void dp_set_vdev_bundle_require_flag(uint16_t vdev_id,
+				     struct wlan_dp_psoc_context *dp_ctx,
+				     uint64_t tx_bytes)
+{
+	struct wlan_dp_psoc_cfg *cfg = dp_ctx->dp_cfg;
+
+	cdp_vdev_set_bundle_require_flag(cds_get_context(QDF_MODULE_ID_SOC),
+					 vdev_id, tx_bytes,
+					 cfg->bus_bw_compute_interval,
+					 cfg->pkt_bundle_threshold_high,
+					 cfg->pkt_bundle_threshold_low);
+}
+#else
+static inline
+void dp_set_vdev_bundle_require_flag(uint16_t vdev_id,
+				     struct wlan_dp_psoc_context *dp_ctx,
+				     uint64_t tx_bytes)
+{
+}
+#endif /* WLAN_SUPPORT_TXRX_HL_BUNDLE */
+
+#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
+/**
+ * dp_set_driver_del_ack_enable() - set driver delayed ack enabled flag
+ * @vdev_id: vdev id
+ * @dp_ctx: handle to dp context
+ * @rx_packets: receive packet count
+ *
+ * Return: none
+ */
+static inline
+void dp_set_driver_del_ack_enable(uint16_t vdev_id,
+				  struct wlan_dp_psoc_context *dp_ctx,
+				  uint64_t rx_packets)
+{
+	struct wlan_dp_psoc_cfg *cfg = dp_ctx->dp_cfg;
+
+	cdp_vdev_set_driver_del_ack_enable(cds_get_context(QDF_MODULE_ID_SOC),
+					   vdev_id, rx_packets,
+					   cfg->bus_bw_compute_interval,
+					   cfg->del_ack_threshold_high,
+					   cfg->del_ack_threshold_low);
+}
+#else
+static inline
+void dp_set_driver_del_ack_enable(uint16_t vdev_id,
+				  struct wlan_dp_psoc_context *dp_ctx,
+				  uint64_t rx_packets)
+{
+}
+#endif /* QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK */
+
+#define DP_BW_GET_DIFF(_x, _y) ((unsigned long)((ULONG_MAX - (_y)) + (_x) + 1))
+
+#ifdef RX_PERFORMANCE
+bool dp_is_current_high_throughput(struct wlan_dp_psoc_context *dp_ctx)
+{
+	if (dp_ctx->cur_vote_level < PLD_BUS_WIDTH_MEDIUM)
+		return false;
+	else
+		return true;
+}
+#endif /* RX_PERFORMANCE */
+
+/**
+ * wlan_dp_validate_context() - check the DP context
+ * @dp_ctx: Global DP context pointer
+ *
+ * Return: 0 if the context is valid. Error code otherwise
+ */
+static int wlan_dp_validate_context(struct wlan_dp_psoc_context *dp_ctx)
+{
+	if (!dp_ctx) {
+		dp_err("DP context is null");
+		return -ENODEV;
+	}
+
+	if (cds_is_driver_recovering()) {
+		dp_info("Recovery in progress; state:0x%x",
+			cds_get_driver_state());
+		return -EAGAIN;
+	}
+
+	if (cds_is_load_or_unload_in_progress()) {
+		dp_info("Load/unload in progress; state:0x%x",
+			cds_get_driver_state());
+		return -EAGAIN;
+	}
+
+	if (cds_is_driver_in_bad_state()) {
+		dp_info("Driver in bad state; state:0x%x",
+			cds_get_driver_state());
+		return -EAGAIN;
+	}
+
+	if (cds_is_fw_down()) {
+		dp_info("FW is down; state:0x%x", cds_get_driver_state());
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+
+/**
+ * dp_tp_level_to_str() - Convert TPUT level to string
+ * @level: TPUT level
+ *
+ * Return: converted string
+ */
+static uint8_t *dp_tp_level_to_str(uint32_t level)
+{
+	switch (level) {
+	/* initialize the wlan sub system */
+	case WLAN_SVC_TP_NONE:
+		return "NONE";
+	case WLAN_SVC_TP_LOW:
+		return "LOW";
+	case WLAN_SVC_TP_MEDIUM:
+		return "MED";
+	case WLAN_SVC_TP_HIGH:
+		return "HIGH";
+	default:
+		return "INVAL";
+	}
+}
+
+void wlan_dp_display_tx_rx_histogram(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+	int i;
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	dp_nofl_info("BW compute Interval: %d ms",
+		     dp_ctx->dp_cfg.bus_bw_compute_interval);
+	dp_nofl_info("BW TH - Very High: %d Mid High: %d High: %d Med: %d Low: %d DBS: %d",
+		     dp_ctx->dp_cfg.bus_bw_very_high_threshold,
+		     dp_ctx->dp_cfg.bus_bw_mid_high_threshold,
+		     dp_ctx->dp_cfg.bus_bw_high_threshold,
+		     dp_ctx->dp_cfg.bus_bw_medium_threshold,
+		     dp_ctx->dp_cfg.bus_bw_low_threshold,
+		     dp_ctx->dp_cfg.bus_bw_dbs_threshold);
+	dp_nofl_info("Enable TCP DEL ACK: %d",
+		     dp_ctx->en_tcp_delack_no_lro);
+	dp_nofl_info("TCP DEL High TH: %d TCP DEL Low TH: %d",
+		     dp_ctx->dp_cfg.tcp_delack_thres_high,
+		     dp_ctx->dp_cfg.tcp_delack_thres_low);
+	dp_nofl_info("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_lim)",
+		     dp_ctx->dp_cfg.tcp_tx_high_tput_thres);
+
+	dp_nofl_info("Total entries: %d Current index: %d",
+		     NUM_TX_RX_HISTOGRAM, dp_ctx->txrx_hist_idx);
+
+	if (dp_ctx->txrx_hist) {
+		dp_nofl_info("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level, Rx:Tx pm_qos");
+
+		for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
+			struct tx_rx_histogram *hist;
+
+			/* using dp_log to avoid printing function name */
+			if (dp_ctx->txrx_hist[i].qtime <= 0)
+				continue;
+			hist = &dp_ctx->txrx_hist[i];
+			dp_nofl_info("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s, %s:%s",
+				     i, hist->qtime, hist->interval_rx,
+				     hist->interval_tx,
+				     pld_bus_width_type_to_str(hist->next_vote_level),
+				     dp_tp_level_to_str(hist->next_rx_level),
+				     dp_tp_level_to_str(hist->next_tx_level),
+				     hist->is_rx_pm_qos_high ? "HIGH" : "LOW",
+				     hist->is_tx_pm_qos_high ? "HIGH" : "LOW");
+		}
+	}
+}
+
+void wlan_dp_clear_tx_rx_histogram(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	dp_ctx->txrx_hist_idx = 0;
+	if (dp_ctx->txrx_hist)
+		qdf_mem_zero(dp_ctx->txrx_hist,
+			     (sizeof(struct tx_rx_histogram) *
+			     NUM_TX_RX_HISTOGRAM));
+}
+
+/**
+ * wlan_dp_init_tx_rx_histogram() - init tx/rx histogram stats
+ * @dp_ctx: dp context
+ *
+ * Return: 0 for success or error code
+ */
+static int wlan_dp_init_tx_rx_histogram(struct wlan_dp_psoc_context *dp_ctx)
+{
+	dp_ctx->txrx_hist = qdf_mem_malloc(
+		(sizeof(struct tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
+	if (!dp_ctx->txrx_hist)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/**
+ * wlan_dp_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
+ * @dp_ctx: dp context
+ *
+ * Return: none
+ */
+static void wlan_dp_deinit_tx_rx_histogram(struct wlan_dp_psoc_context *dp_ctx)
+{
+	if (!dp_ctx || !dp_ctx->txrx_hist)
+		return;
+
+	qdf_mem_free(dp_ctx->txrx_hist);
+	dp_ctx->txrx_hist = NULL;
+}
+
+/**
+ * wlan_dp_display_txrx_stats() - Display tx/rx histogram stats
+ * @dp_ctx: dp context
+ *
+ * Return: none
+ */
+static void wlan_dp_display_txrx_stats(struct wlan_dp_psoc_context *dp_ctx)
+{
+	struct wlan_dp_intf *dp_intf = NULL, *next_dp_intf = NULL;
+	struct dp_tx_rx_stats *stats;
+	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+	int i = 0;
+	uint32_t total_rx_pkt, total_rx_dropped,
+		 total_rx_delv, total_rx_refused;
+	uint32_t total_tx_pkt;
+	uint32_t total_tx_dropped;
+	uint32_t total_tx_orphaned;
+
+	dp_for_each_intf_held_safe(dp_ctx, dp_intf, next_dp_intf) {
+		total_rx_pkt = 0;
+		total_rx_dropped = 0;
+		total_rx_delv = 0;
+		total_rx_refused = 0;
+		total_tx_pkt = 0;
+		total_tx_dropped = 0;
+		total_tx_orphaned = 0;
+		stats = &dp_intf->dp_stats.tx_rx_stats;
+
+		if (!dp_intf->num_links)
+			continue;
+
+		dp_info("dp_intf: " QDF_MAC_ADDR_FMT,
+			QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes));
+		for (i = 0; i < NUM_CPUS; i++) {
+			total_rx_pkt += stats->per_cpu[i].rx_packets;
+			total_rx_dropped += stats->per_cpu[i].rx_dropped;
+			total_rx_delv += stats->per_cpu[i].rx_delivered;
+			total_rx_refused += stats->per_cpu[i].rx_refused;
+			total_tx_pkt += stats->per_cpu[i].tx_called;
+			total_tx_dropped += stats->per_cpu[i].tx_dropped;
+			total_tx_orphaned += stats->per_cpu[i].tx_orphaned;
+		}
+
+		for (i = 0; i < NUM_CPUS; i++) {
+			if (!stats->per_cpu[i].tx_called)
+				continue;
+
+			dp_info("Tx CPU[%d]: called %u, dropped %u, orphaned %u",
+				i, stats->per_cpu[i].tx_called,
+				stats->per_cpu[i].tx_dropped,
+				stats->per_cpu[i].tx_orphaned);
+		}
+
+		dp_info("TX - called %u, dropped %u orphan %u",
+			total_tx_pkt, total_tx_dropped,
+			total_tx_orphaned);
+
+		dp_ctx->dp_ops.wlan_dp_display_tx_multiq_stats(ctx,
+							       dp_intf->dev);
+
+		for (i = 0; i < NUM_CPUS; i++) {
+			if (stats->per_cpu[i].rx_packets == 0)
+				continue;
+			dp_info("Rx CPU[%d]: packets %u, dropped %u, delivered %u, refused %u",
+				i, stats->per_cpu[i].rx_packets,
+				stats->per_cpu[i].rx_dropped,
+				stats->per_cpu[i].rx_delivered,
+				stats->per_cpu[i].rx_refused);
+		}
+
+		dp_info("RX - packets %u, dropped %u, unsol_arp_mcast_drp %u, delivered %u, refused %u GRO - agg %u drop %u non-agg %u flush_skip %u low_tput_flush %u disabled(conc %u low-tput %u)",
+			total_rx_pkt, total_rx_dropped,
+			qdf_atomic_read(&stats->rx_usolict_arp_n_mcast_drp),
+			total_rx_delv,
+			total_rx_refused, stats->rx_aggregated,
+			stats->rx_gro_dropped, stats->rx_non_aggregated,
+			stats->rx_gro_flush_skip,
+			stats->rx_gro_low_tput_flush,
+			qdf_atomic_read(&dp_ctx->disable_rx_ol_in_concurrency),
+			qdf_atomic_read(&dp_ctx->disable_rx_ol_in_low_tput));
+	}
+}
+
+/**
+ * dp_display_periodic_stats() - Function to display periodic stats
+ * @dp_ctx: handle to dp context
+ * @data_in_interval: true, if data detected in bw time interval
+ *
+ * The periodicity is determined by dp_ctx->dp_cfg->periodic_stats_disp_time.
+ * Stats show up in wlan driver logs.
+ *
+ * Returns: None
+ */
+static void dp_display_periodic_stats(struct wlan_dp_psoc_context *dp_ctx,
+				      bool data_in_interval)
+{
+	static uint32_t counter;
+	static bool data_in_time_period;
+	ol_txrx_soc_handle soc;
+	uint32_t periodic_stats_disp_time = 0;
+	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+
+	wlan_mlme_stats_get_periodic_display_time(dp_ctx->psoc,
+						  &periodic_stats_disp_time);
+	if (!periodic_stats_disp_time)
+		return;
+
+	soc = cds_get_context(QDF_MODULE_ID_SOC);
+	if (!soc)
+		return;
+
+	counter++;
+	if (data_in_interval)
+		data_in_time_period = data_in_interval;
+
+	if (counter * dp_ctx->dp_cfg.bus_bw_compute_interval >=
+		periodic_stats_disp_time * 1000) {
+		hif_rtpm_display_last_busy_hist(cds_get_context(QDF_MODULE_ID_HIF));
+		if (data_in_time_period) {
+			wlan_dp_display_txrx_stats(dp_ctx);
+			dp_txrx_ext_dump_stats(soc, CDP_DP_RX_THREAD_STATS);
+			cdp_display_stats(soc,
+					  CDP_RX_RING_STATS,
+					  QDF_STATS_VERBOSITY_LEVEL_LOW);
+			cdp_display_stats(soc,
+					  CDP_DP_NAPI_STATS,
+					  QDF_STATS_VERBOSITY_LEVEL_LOW);
+			cdp_display_stats(soc,
+					  CDP_TXRX_PATH_STATS,
+					  QDF_STATS_VERBOSITY_LEVEL_LOW);
+			cdp_display_stats(soc,
+					  CDP_DUMP_TX_FLOW_POOL_INFO,
+					  QDF_STATS_VERBOSITY_LEVEL_LOW);
+			cdp_display_stats(soc,
+					  CDP_DP_SWLM_STATS,
+					  QDF_STATS_VERBOSITY_LEVEL_LOW);
+			dp_ctx->dp_ops.wlan_dp_display_netif_queue_history
+				(ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
+			cdp_display_txrx_hw_info(soc);
+			qdf_dp_trace_dump_stats();
+		}
+		counter = 0;
+		data_in_time_period = false;
+	}
+}
+
+/**
+ * dp_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting
+ * @mask: return variable of cpumask for the TPUT
+ * @enable_perf_cluster: Enable PERF cluster or not
+ *
+ * By default, the function sets CPU mask for silver cluster unless
+ * enable_perf_cluster is set as true.
+ *
+ * Return: none
+ */
+static inline void dp_pm_qos_update_cpu_mask(qdf_cpu_mask *mask,
+					     bool enable_perf_cluster)
+{
+	int package_id;
+	unsigned int cpus;
+	int perf_cpu_cluster = hif_get_perf_cluster_bitmap();
+	int little_cpu_cluster = BIT(CPU_CLUSTER_TYPE_LITTLE);
+
+	qdf_cpumask_clear(mask);
+	qdf_for_each_online_cpu(cpus) {
+		package_id = qdf_topology_physical_package_id(cpus);
+		if (package_id >= 0 &&
+		    (BIT(package_id) & little_cpu_cluster ||
+		     (enable_perf_cluster &&
+		      BIT(package_id) & perf_cpu_cluster))) {
+			qdf_cpumask_set_cpu(cpus, mask);
+		}
+	}
+}
+
+/**
+ * dp_bus_bandwidth_work_tune_rx() - Function to tune for RX
+ * @dp_ctx: handle to dp context
+ * @rx_packets: receive packet count in last bus bandwidth interval
+ * @diff_us: delta time since last invocation.
+ * @next_rx_level: pointer to next_rx_level to be filled
+ * @cpu_mask: pm_qos cpu_mask needed for RX, to be filled
+ * @is_rx_pm_qos_high: pointer indicating if high qos is needed, to be filled
+ *
+ * The function tunes various aspects of driver based on a running average
+ * of RX packets received in last bus bandwidth interval.
+ *
+ * Returns: true if RX level has changed, else return false
+ */
+static
+bool dp_bus_bandwidth_work_tune_rx(struct wlan_dp_psoc_context *dp_ctx,
+				   const uint64_t rx_packets,
+				   uint64_t diff_us,
+				   enum wlan_tp_level *next_rx_level,
+				   qdf_cpu_mask *cpu_mask,
+				   bool *is_rx_pm_qos_high)
+{
+	bool rx_level_change = false;
+	bool rxthread_high_tput_req;
+	uint32_t bw_interval_us;
+	uint32_t delack_timer_cnt = dp_ctx->dp_cfg.tcp_delack_timer_count;
+	uint64_t avg_rx;
+	uint64_t no_rx_offload_pkts, avg_no_rx_offload_pkts;
+	uint64_t rx_offload_pkts, avg_rx_offload_pkts;
+
+	bw_interval_us = dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;
+	no_rx_offload_pkts = dp_ctx->no_rx_offload_pkt_cnt;
+	dp_ctx->no_rx_offload_pkt_cnt = 0;
+
+	/* adjust for any sched delays */
+	no_rx_offload_pkts = no_rx_offload_pkts * bw_interval_us;
+	no_rx_offload_pkts = qdf_do_div(no_rx_offload_pkts, (uint32_t)diff_us);
+
+	/* average no-offload RX packets over last 2 BW intervals */
+	avg_no_rx_offload_pkts = (no_rx_offload_pkts +
+				  dp_ctx->prev_no_rx_offload_pkts) / 2;
+	dp_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
+
+	if (rx_packets >= no_rx_offload_pkts)
+		rx_offload_pkts = rx_packets - no_rx_offload_pkts;
+	else
+		rx_offload_pkts = 0;
+
+	/* average offloaded RX packets over last 2 BW intervals */
+	avg_rx_offload_pkts = (rx_offload_pkts +
+			       dp_ctx->prev_rx_offload_pkts) / 2;
+	dp_ctx->prev_rx_offload_pkts = rx_offload_pkts;
+
+	avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
+
+	qdf_cpumask_clear(cpu_mask);
+
+	if (avg_no_rx_offload_pkts > dp_ctx->dp_cfg.bus_bw_high_threshold) {
+		rxthread_high_tput_req = true;
+		*is_rx_pm_qos_high = true;
+		/*Todo: move hdd implementation to qdf */
+		dp_pm_qos_update_cpu_mask(cpu_mask, true);
+	} else if (avg_rx > dp_ctx->dp_cfg.bus_bw_high_threshold) {
+		rxthread_high_tput_req = false;
+		*is_rx_pm_qos_high = false;
+		dp_pm_qos_update_cpu_mask(cpu_mask, false);
+	} else {
+		*is_rx_pm_qos_high = false;
+		rxthread_high_tput_req = false;
+	}
+
+	/*
+	 * Takes care to set Rx_thread affinity for below case
+	 * 1)LRO/GRO not supported ROME case
+	 * 2)when rx_ol is disabled in cases like concurrency etc
+	 * 3)For UDP cases
+	 */
+	if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
+		dp_warn("Rx thread high_tput(%d) affinity request failed",
+			rxthread_high_tput_req);
+
+	/* fine-tuning parameters for RX Flows */
+	if (avg_rx > dp_ctx->dp_cfg.tcp_delack_thres_high) {
+		if (dp_ctx->cur_rx_level != WLAN_SVC_TP_HIGH &&
+		    ++dp_ctx->rx_high_ind_cnt == delack_timer_cnt) {
+			*next_rx_level = WLAN_SVC_TP_HIGH;
+		}
+	} else {
+		dp_ctx->rx_high_ind_cnt = 0;
+		*next_rx_level = WLAN_SVC_TP_LOW;
+	}
+
+	if (dp_ctx->cur_rx_level != *next_rx_level) {
+		struct wlan_rx_tp_data rx_tp_data = {0};
+
+		dp_ctx->cur_rx_level = *next_rx_level;
+		rx_level_change = true;
+		/* Send throughput indication only if it is enabled.
+		 * Disabling tcp_del_ack will revert the tcp stack behavior
+		 * to default delayed ack. Note that this will disable the
+		 * dynamic delayed ack mechanism across the system
+		 */
+		if (dp_ctx->en_tcp_delack_no_lro)
+			rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
+
+		if (dp_ctx->dp_cfg.enable_tcp_adv_win_scale)
+			rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
+
+		rx_tp_data.level = *next_rx_level;
+		wlan_dp_update_tcp_rx_param(dp_ctx, &rx_tp_data);
+	}
+
+	return rx_level_change;
+}
+
+/**
+ * dp_bus_bandwidth_work_tune_tx() - Function to tune for TX
+ * @dp_ctx: handle to dp context
+ * @tx_packets: transmit packet count in last bus bandwidth interval
+ * @diff_us: delta time since last invocation.
+ * @next_tx_level: pointer to next_tx_level to be filled
+ * @cpu_mask: pm_qos cpu_mask needed for TX, to be filled
+ * @is_tx_pm_qos_high: pointer indicating if high qos is needed, to be filled
+ *
+ * The function tunes various aspects of the driver based on a running average
+ * of TX packets received in last bus bandwidth interval.
+ *
+ * Returns: true if TX level has changed, else return false
+ */
+static
+bool dp_bus_bandwidth_work_tune_tx(struct wlan_dp_psoc_context *dp_ctx,
+				   const uint64_t tx_packets,
+				   uint64_t diff_us,
+				   enum wlan_tp_level *next_tx_level,
+				   qdf_cpu_mask *cpu_mask,
+				   bool *is_tx_pm_qos_high)
+{
+	bool tx_level_change = false;
+	uint32_t bw_interval_us;
+	uint64_t no_tx_offload_pkts, avg_no_tx_offload_pkts;
+	uint64_t tx_offload_pkts, avg_tx_offload_pkts;
+	uint64_t avg_tx;
+
+	bw_interval_us = dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;
+	no_tx_offload_pkts = dp_ctx->no_tx_offload_pkt_cnt;
+
+	/* adjust for any sched delays */
+	no_tx_offload_pkts = no_tx_offload_pkts * bw_interval_us;
+	no_tx_offload_pkts = qdf_do_div(no_tx_offload_pkts, (uint32_t)diff_us);
+
+	/* average no-offload TX packets over last 2 BW intervals */
+	avg_no_tx_offload_pkts = (no_tx_offload_pkts +
+				  dp_ctx->prev_no_tx_offload_pkts) / 2;
+	dp_ctx->no_tx_offload_pkt_cnt = 0;
+	dp_ctx->prev_no_tx_offload_pkts = no_tx_offload_pkts;
+
+	if (tx_packets >= no_tx_offload_pkts)
+		tx_offload_pkts = tx_packets - no_tx_offload_pkts;
+	else
+		tx_offload_pkts = 0;
+
+	/* average offloaded TX packets over last 2 BW intervals */
+	avg_tx_offload_pkts = (tx_offload_pkts +
+			       dp_ctx->prev_tx_offload_pkts) / 2;
+	dp_ctx->prev_tx_offload_pkts = tx_offload_pkts;
+
+	avg_tx = avg_no_tx_offload_pkts + avg_tx_offload_pkts;
+
+	/* fine-tuning parameters for TX Flows */
+	dp_ctx->prev_tx = tx_packets;
+
+	qdf_cpumask_clear(cpu_mask);
+
+	if (avg_no_tx_offload_pkts >
+		dp_ctx->dp_cfg.bus_bw_very_high_threshold) {
+		dp_pm_qos_update_cpu_mask(cpu_mask, true);
+		*is_tx_pm_qos_high = true;
+	} else if (avg_tx > dp_ctx->dp_cfg.bus_bw_high_threshold) {
+		dp_pm_qos_update_cpu_mask(cpu_mask, false);
+		*is_tx_pm_qos_high = false;
+	} else {
+		*is_tx_pm_qos_high = false;
+	}
+
+	if (avg_tx > dp_ctx->dp_cfg.tcp_tx_high_tput_thres)
+		*next_tx_level = WLAN_SVC_TP_HIGH;
+	else
+		*next_tx_level = WLAN_SVC_TP_LOW;
+
+	if (dp_ctx->dp_cfg.enable_tcp_limit_output &&
+	    dp_ctx->cur_tx_level != *next_tx_level) {
+		struct wlan_tx_tp_data tx_tp_data = {0};
+
+		dp_ctx->cur_tx_level = *next_tx_level;
+		tx_level_change = true;
+		tx_tp_data.level = *next_tx_level;
+		tx_tp_data.tcp_limit_output = true;
+		wlan_dp_update_tcp_tx_param(dp_ctx, &tx_tp_data);
+	}
+
+	return tx_level_change;
+}
+
+/**
+ * dp_sap_p2p_update_mid_high_tput() - Update mid high BW for SAP and P2P mode
+ * @dp_ctx: DP context
+ * @total_pkts: Total Tx and Rx packets
+ *
+ * Return: True if mid high threshold is set and opmode is SAP or P2P GO
+ */
+static inline
+bool dp_sap_p2p_update_mid_high_tput(struct wlan_dp_psoc_context *dp_ctx,
+				     uint64_t total_pkts)
+{
+	struct wlan_dp_intf *dp_intf = NULL;
+	struct wlan_dp_intf *dp_intf_next = NULL;
+
+	if (dp_ctx->dp_cfg.bus_bw_mid_high_threshold &&
+	    total_pkts > dp_ctx->dp_cfg.bus_bw_mid_high_threshold) {
+		dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
+			if (dp_intf->device_mode == QDF_SAP_MODE ||
+			    dp_intf->device_mode == QDF_P2P_GO_MODE)
+				return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * dp_pld_request_bus_bandwidth() - Function to control bus bandwidth
+ * @dp_ctx: handle to DP context
+ * @tx_packets: transmit packet count received in BW interval
+ * @rx_packets: receive packet count received in BW interval
+ * @diff_us: delta time since last invocation.
+ *
+ * The function controls the bus bandwidth and dynamic control of
+ * tcp delayed ack configuration.
+ *
+ * Returns: None
+ */
+static void dp_pld_request_bus_bandwidth(struct wlan_dp_psoc_context *dp_ctx,
+					 const uint64_t tx_packets,
+					 const uint64_t rx_packets,
+					 const uint64_t diff_us)
+{
+	uint16_t index;
+	bool vote_level_change = false;
+	bool rx_level_change;
+	bool tx_level_change;
+	bool dptrace_high_tput_req;
+	u64 total_pkts = tx_packets + rx_packets;
+	enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_IDLE;
+	static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
+	enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
+	qdf_cpu_mask pm_qos_cpu_mask_tx, pm_qos_cpu_mask_rx, pm_qos_cpu_mask;
+	bool is_rx_pm_qos_high;
+	bool is_tx_pm_qos_high;
+	bool pmqos_on_low_tput = false;
+	enum tput_level tput_level;
+	bool is_tput_level_high;
+	struct bbm_params param = {0};
+	bool legacy_client = false;
+	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
+	static enum tput_level prev_tput_level = TPUT_LEVEL_NONE;
+	struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops;
+	hdd_cb_handle ctx = dp_ops->callback_ctx;
+
+	if (!soc)
+		return;
+
+	if (dp_ctx->high_bus_bw_request) {
+		next_vote_level = PLD_BUS_WIDTH_VERY_HIGH;
+		tput_level = TPUT_LEVEL_VERY_HIGH;
+	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_super_high_threshold) {
+		next_vote_level = PLD_BUS_WIDTH_MAX;
+		tput_level = TPUT_LEVEL_SUPER_HIGH;
+	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_ultra_high_threshold) {
+		next_vote_level = PLD_BUS_WIDTH_ULTRA_HIGH;
+		tput_level = TPUT_LEVEL_ULTRA_HIGH;
+	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_very_high_threshold) {
+		next_vote_level = PLD_BUS_WIDTH_VERY_HIGH;
+		tput_level = TPUT_LEVEL_VERY_HIGH;
+	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_high_threshold) {
+		next_vote_level = PLD_BUS_WIDTH_HIGH;
+		tput_level = TPUT_LEVEL_HIGH;
+		if (dp_sap_p2p_update_mid_high_tput(dp_ctx, total_pkts)) {
+			next_vote_level = PLD_BUS_WIDTH_MID_HIGH;
+			tput_level = TPUT_LEVEL_MID_HIGH;
+		}
+	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_medium_threshold) {
+		next_vote_level = PLD_BUS_WIDTH_MEDIUM;
+		tput_level = TPUT_LEVEL_MEDIUM;
+	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_low_threshold) {
+		next_vote_level = PLD_BUS_WIDTH_LOW;
+		tput_level = TPUT_LEVEL_LOW;
+	} else {
+		next_vote_level = PLD_BUS_WIDTH_IDLE;
+		tput_level = TPUT_LEVEL_IDLE;
+	}
+
+	/*
+	 * DBS mode requires more DDR/SNOC resources, vote to ultra high
+	 * only when TPUT can reach VHT80 KPI and IPA is disabled,
+	 * for other cases, follow general voting logic
+	 */
+	if (!ucfg_ipa_is_fw_wdi_activated(dp_ctx->pdev) &&
+	    policy_mgr_is_current_hwmode_dbs(dp_ctx->psoc) &&
+	    (total_pkts > dp_ctx->dp_cfg.bus_bw_dbs_threshold) &&
+	    (tput_level < TPUT_LEVEL_SUPER_HIGH)) {
+		next_vote_level = PLD_BUS_WIDTH_ULTRA_HIGH;
+		tput_level = TPUT_LEVEL_ULTRA_HIGH;
+	}
+
+	param.policy = BBM_TPUT_POLICY;
+	param.policy_info.tput_level = tput_level;
+	dp_bbm_apply_independent_policy(dp_ctx->psoc, &param);
+
+	dp_rtpm_tput_policy_apply(dp_ctx, tput_level);
+
+	dptrace_high_tput_req =
+			next_vote_level > PLD_BUS_WIDTH_IDLE ? true : false;
+
+	if (qdf_atomic_read(&dp_ctx->num_latency_critical_clients))
+		legacy_client = true;
+
+	dp_low_tput_gro_flush_skip_handler(dp_ctx, next_vote_level,
+					   legacy_client);
+
+	if (dp_ctx->cur_vote_level != next_vote_level) {
+		/* Set affinity for tx completion grp interrupts */
+		if (tput_level >= TPUT_LEVEL_VERY_HIGH &&
+		    prev_tput_level < TPUT_LEVEL_VERY_HIGH)
+			hif_set_grp_intr_affinity(hif_ctx,
+				cdp_get_tx_rings_grp_bitmap(soc), true);
+		else if (tput_level < TPUT_LEVEL_VERY_HIGH &&
+			 prev_tput_level >= TPUT_LEVEL_VERY_HIGH)
+			hif_set_grp_intr_affinity(hif_ctx,
+				cdp_get_tx_rings_grp_bitmap(soc),
+				false);
+
+		prev_tput_level = tput_level;
+		dp_ctx->cur_vote_level = next_vote_level;
+		vote_level_change = true;
+
+		if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
+		    (next_vote_level == PLD_BUS_WIDTH_IDLE)) {
+			dp_ops->dp_pld_remove_pm_qos(ctx);
+			if (dp_ctx->dynamic_rps)
+				dp_clear_rps_cpu_mask(dp_ctx);
+		} else {
+			dp_ops->dp_pld_request_pm_qos(ctx);
+			if (dp_ctx->dynamic_rps)
+				/*Todo : check once hdd_set_rps_cpu_mask */
+				dp_set_rps_cpu_mask(dp_ctx);
+		}
+
+		if (dp_ctx->dp_cfg.rx_thread_ul_affinity_mask) {
+			if (next_vote_level == PLD_BUS_WIDTH_HIGH &&
+			    tx_packets >
+			    dp_ctx->dp_cfg.bus_bw_high_threshold &&
+			    rx_packets >
+			    dp_ctx->dp_cfg.bus_bw_low_threshold)
+				cds_sched_handle_rx_thread_affinity_req(true);
+			else if (next_vote_level != PLD_BUS_WIDTH_HIGH)
+				cds_sched_handle_rx_thread_affinity_req(false);
+		}
+
+		dp_ops->dp_napi_apply_throughput_policy(ctx,
+							tx_packets,
+							rx_packets);
+
+		if (rx_packets < dp_ctx->dp_cfg.bus_bw_low_threshold)
+			dp_disable_rx_ol_for_low_tput(dp_ctx, true);
+		else
+			dp_disable_rx_ol_for_low_tput(dp_ctx, false);
+
+		/*
+		 * force disable pktlog and only re-enable based
+		 * on ini config
+		 */
+		if (next_vote_level >= PLD_BUS_WIDTH_HIGH)
+			dp_ops->dp_pktlog_enable_disable(ctx,
+							 false, 0, 0);
+		else if (cds_is_packet_log_enabled())
+			dp_ops->dp_pktlog_enable_disable(ctx,
+							 true, 0, 0);
+	}
+
+	qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
+
+	rx_level_change = dp_bus_bandwidth_work_tune_rx(dp_ctx,
+							rx_packets,
+							diff_us,
+							&next_rx_level,
+							&pm_qos_cpu_mask_rx,
+							&is_rx_pm_qos_high);
+
+	tx_level_change = dp_bus_bandwidth_work_tune_tx(dp_ctx,
+							tx_packets,
+							diff_us,
+							&next_tx_level,
+							&pm_qos_cpu_mask_tx,
+							&is_tx_pm_qos_high);
+
+	index = dp_ctx->txrx_hist_idx;
+
+	if (vote_level_change) {
+		/* Clear mask if BW is not HIGH or more */
+		if (next_vote_level < PLD_BUS_WIDTH_HIGH) {
+			is_rx_pm_qos_high = false;
+			is_tx_pm_qos_high = false;
+			qdf_cpumask_clear(&pm_qos_cpu_mask);
+			if (next_vote_level == PLD_BUS_WIDTH_LOW &&
+			    rx_packets > tx_packets &&
+			    !legacy_client) {
+				pmqos_on_low_tput = true;
+				dp_pm_qos_update_cpu_mask(&pm_qos_cpu_mask,
+							  false);
+			}
+		} else {
+			qdf_cpumask_clear(&pm_qos_cpu_mask);
+			qdf_cpumask_or(&pm_qos_cpu_mask,
+				       &pm_qos_cpu_mask_tx,
+				       &pm_qos_cpu_mask_rx);
+
+			/* Default mask in case throughput is high */
+			if (qdf_cpumask_empty(&pm_qos_cpu_mask))
+				dp_pm_qos_update_cpu_mask(&pm_qos_cpu_mask,
+							  false);
+		}
+		dp_ops->dp_pm_qos_update_request(ctx, &pm_qos_cpu_mask);
+		is_tput_level_high =
+			tput_level >= TPUT_LEVEL_HIGH ? true : false;
+		cdp_set_bus_vote_lvl_high(soc, is_tput_level_high);
+	}
+
+	if (vote_level_change || tx_level_change || rx_level_change) {
+		dp_info("tx:%llu[%llu(off)+%llu(no-off)] rx:%llu[%llu(off)+%llu(no-off)] next_level(vote %u rx %u tx %u rtpm %d) pm_qos(rx:%u,%*pb tx:%u,%*pb on_low_tput:%u)",
+			tx_packets,
+			dp_ctx->prev_tx_offload_pkts,
+			dp_ctx->prev_no_tx_offload_pkts,
+			rx_packets,
+			dp_ctx->prev_rx_offload_pkts,
+			dp_ctx->prev_no_rx_offload_pkts,
+			next_vote_level, next_rx_level, next_tx_level,
+			dp_rtpm_tput_policy_get_vote(dp_ctx),
+			is_rx_pm_qos_high,
+			qdf_cpumask_pr_args(&pm_qos_cpu_mask_rx),
+			is_tx_pm_qos_high,
+			qdf_cpumask_pr_args(&pm_qos_cpu_mask_tx),
+			pmqos_on_low_tput);
+
+		if (dp_ctx->txrx_hist) {
+			dp_ctx->txrx_hist[index].next_tx_level = next_tx_level;
+			dp_ctx->txrx_hist[index].next_rx_level = next_rx_level;
+			dp_ctx->txrx_hist[index].is_rx_pm_qos_high =
+				is_rx_pm_qos_high;
+			dp_ctx->txrx_hist[index].is_tx_pm_qos_high =
+				is_tx_pm_qos_high;
+			dp_ctx->txrx_hist[index].next_vote_level =
+				next_vote_level;
+			dp_ctx->txrx_hist[index].interval_rx = rx_packets;
+			dp_ctx->txrx_hist[index].interval_tx = tx_packets;
+			dp_ctx->txrx_hist[index].qtime =
+				qdf_get_log_timestamp();
+			dp_ctx->txrx_hist_idx++;
+			dp_ctx->txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
+		}
+	}
+
+	/* Roaming is a high priority job but gets processed in scheduler
+	 * thread, bypassing printing stats so that kworker exits quickly and
+	 * scheduler thread can utilize CPU.
+	 */
+	if (!dp_ops->dp_is_roaming_in_progress(ctx)) {
+		dp_display_periodic_stats(dp_ctx, (total_pkts > 0) ?
+					  true : false);
+		dp_periodic_sta_stats_display(dp_ctx);
+	}
+
+	hif_affinity_mgr_set_affinity(hif_ctx);
+}
+
+#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION
+/**
+ * dp_rx_check_qdisc_for_intf() - Check if any ingress qdisc is configured
+ *  for given adapter
+ * @dp_intf: pointer to DP interface context
+ *
+ * The function checks if ingress qdisc is registered for a given
+ * net device.
+ *
+ * Return: None
+ */
+static void
+dp_rx_check_qdisc_for_intf(struct wlan_dp_intf *dp_intf)
+{
+	struct wlan_dp_psoc_callbacks *dp_ops;
+	QDF_STATUS status;
+
+	dp_ops = &dp_intf->dp_ctx->dp_ops;
+	status = dp_ops->dp_rx_check_qdisc_configured(dp_intf->dev,
+				 dp_intf->dp_ctx->dp_agg_param.tc_ingress_prio);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (qdf_likely(qdf_atomic_read(&dp_intf->gro_disallowed)))
+			return;
+
+		dp_debug("ingress qdisc/filter configured disable GRO");
+		qdf_atomic_set(&dp_intf->gro_disallowed, 1);
+
+		return;
+	} else if (status == QDF_STATUS_E_NOSUPPORT) {
+		if (qdf_unlikely(qdf_atomic_read(&dp_intf->gro_disallowed))) {
+			dp_debug("ingress qdisc/filter removed enable GRO");
+			qdf_atomic_set(&dp_intf->gro_disallowed, 0);
+		}
+	}
+}
+#else
+static void
+dp_rx_check_qdisc_for_intf(struct wlan_dp_intf *dp_intf)
+{
+}
+#endif
+
+#define NO_RX_PKT_LINK_SPEED_AGEOUT_COUNT 50
+static void
+dp_link_monitoring(struct wlan_dp_psoc_context *dp_ctx,
+		   struct wlan_dp_intf *dp_intf)
+{
+	struct cdp_peer_stats *peer_stats;
+	QDF_STATUS status;
+	ol_txrx_soc_handle soc;
+	struct wlan_objmgr_peer *bss_peer;
+	static uint32_t no_rx_times;
+	uint64_t  rx_packets;
+	uint32_t link_speed;
+	struct wlan_objmgr_psoc *psoc;
+	struct link_monitoring link_mon;
+	struct wlan_dp_link *def_link = dp_intf->def_link;
+
+	/*
+	 *  If throughput is high, link speed should be good,  don't check it
+	 *  to avoid performance penalty
+	 */
+	soc = cds_get_context(QDF_MODULE_ID_SOC);
+	if (cdp_get_bus_lvl_high(soc) == true)
+		return;
+
+	link_mon = dp_intf->link_monitoring;
+	if (!dp_ctx->dp_ops.link_monitoring_cb)
+		return;
+
+	psoc = dp_ctx->psoc;
+	/* If no rx packets received for N sec, set link speed to poor */
+	if (link_mon.is_rx_linkspeed_good) {
+		rx_packets = DP_BW_GET_DIFF(
+			qdf_net_stats_get_rx_pkts(&dp_intf->stats),
+			dp_intf->prev_rx_packets);
+		if (!rx_packets)
+			no_rx_times++;
+		else
+			no_rx_times = 0;
+		if (no_rx_times >= NO_RX_PKT_LINK_SPEED_AGEOUT_COUNT) {
+			no_rx_times = 0;
+			dp_ctx->dp_ops.link_monitoring_cb(psoc,
+							  def_link->link_id,
+							  false);
+			dp_intf->link_monitoring.is_rx_linkspeed_good = false;
+
+			return;
+		}
+	}
+	/* Get rx link speed from dp peer */
+	peer_stats = qdf_mem_malloc(sizeof(*peer_stats));
+	if (!peer_stats)
+		return;
+
+	/* TODO - Temp WAR, check what to do here */
+	/* Peer stats for any link peer is going to return the
+	 * stats from MLD peer, so its okay to query deflink
+	 */
+	bss_peer = wlan_vdev_get_bsspeer(def_link->vdev);
+	if (!bss_peer) {
+		dp_debug("Invalid bss peer");
+		qdf_mem_free(peer_stats);
+		return;
+	}
+
+	status = cdp_host_get_peer_stats(soc, def_link->link_id,
+					 bss_peer->macaddr,
+					 peer_stats);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		qdf_mem_free(peer_stats);
+		return;
+	}
+	/* Convert rx linkspeed from kbps to mbps to compare with threshold */
+	link_speed = peer_stats->rx.last_rx_rate / 1000;
+
+	/*
+	 * When found current rx link speed becomes good(above threshold) or
+	 * poor, update to firmware.
+	 * If the current RX link speed is above the threshold, low rssi
+	 * roaming is not needed. If linkspeed_threshold is set to 0, the
+	 * firmware will not consider RX link speed in the roaming decision,
+	 * driver will send rx link speed poor state to firmware.
+	 */
+	if (!link_mon.rx_linkspeed_threshold) {
+		dp_ctx->dp_ops.link_monitoring_cb(psoc, def_link->link_id,
+						  false);
+		dp_intf->link_monitoring.is_rx_linkspeed_good = false;
+	} else if (link_speed > link_mon.rx_linkspeed_threshold &&
+	     !link_mon.is_rx_linkspeed_good) {
+		dp_ctx->dp_ops.link_monitoring_cb(psoc, def_link->link_id,
+						  true);
+		dp_intf->link_monitoring.is_rx_linkspeed_good = true;
+	} else if (link_speed < link_mon.rx_linkspeed_threshold &&
+		   link_mon.is_rx_linkspeed_good) {
+		dp_ctx->dp_ops.link_monitoring_cb(psoc, def_link->link_id,
+						  false);
+		dp_intf->link_monitoring.is_rx_linkspeed_good = false;
+	}
+
+	qdf_mem_free(peer_stats);
+}
+
+/**
+ * __dp_bus_bw_work_handler() - Bus bandwidth work handler
+ * @dp_ctx: handle to DP context
+ *
+ * The function handles the bus bandwidth work schedule
+ *
+ * Returns: None
+ */
+static void __dp_bus_bw_work_handler(struct wlan_dp_psoc_context *dp_ctx)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_dp_intf *dp_intf = NULL, *con_sap_dp_intf = NULL;
+	struct wlan_dp_intf *dp_intf_next = NULL;
+	struct wlan_dp_link *dp_link = NULL;
+	struct wlan_dp_link *dp_link_next;
+	uint64_t tx_packets = 0, rx_packets = 0, tx_bytes = 0;
+	uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
+	uint64_t fwd_tx_packets_temp = 0, fwd_rx_packets_temp = 0;
+	uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
+	uint64_t total_tx = 0, total_rx = 0;
+	A_STATUS ret;
+	bool connected = false;
+	uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
+	uint64_t sta_tx_bytes = 0, sap_tx_bytes = 0;
+	uint64_t diff_us;
+	uint64_t curr_time_us;
+	uint32_t bw_interval_us;
+	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+
+	if (wlan_dp_validate_context(dp_ctx))
+		goto stop_work;
+
+	if (dp_ctx->is_suspend)
+		return;
+
+	bw_interval_us = dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;
+
+	curr_time_us = qdf_get_log_timestamp();
+	diff_us = qdf_log_timestamp_to_usecs(
+			curr_time_us - dp_ctx->bw_vote_time);
+	dp_ctx->bw_vote_time = curr_time_us;
+
+	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
+		vdev = dp_objmgr_get_vdev_by_user(dp_intf->def_link,
+						  WLAN_DP_ID);
+		if (!vdev)
+			continue;
+
+		if ((dp_intf->device_mode == QDF_STA_MODE ||
+		     dp_intf->device_mode == QDF_P2P_CLIENT_MODE) &&
+		    !wlan_cm_is_vdev_active(vdev)) {
+			dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
+			continue;
+		}
+
+		if ((dp_intf->device_mode == QDF_SAP_MODE ||
+		     dp_intf->device_mode == QDF_P2P_GO_MODE) &&
+		     !dp_ctx->dp_ops.dp_is_ap_active(ctx,
+						     dp_intf->dev)) {
+			dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
+			continue;
+		}
+
+		if (dp_ctx->dp_agg_param.tc_based_dyn_gro)
+			dp_rx_check_qdisc_for_intf(dp_intf);
+
+		tx_packets += DP_BW_GET_DIFF(
+			qdf_net_stats_get_tx_pkts(&dp_intf->stats),
+			dp_intf->prev_tx_packets);
+		rx_packets += DP_BW_GET_DIFF(
+			qdf_net_stats_get_rx_pkts(&dp_intf->stats),
+			dp_intf->prev_rx_packets);
+		tx_bytes = DP_BW_GET_DIFF(
+			qdf_net_stats_get_tx_bytes(&dp_intf->stats),
+			dp_intf->prev_tx_bytes);
+
+		if (dp_intf->device_mode == QDF_STA_MODE &&
+		    wlan_cm_is_vdev_active(vdev)) {
+			dp_ctx->dp_ops.dp_send_mscs_action_frame(ctx,
+							dp_intf->dev);
+			if (dp_intf->link_monitoring.enabled)
+				dp_link_monitoring(dp_ctx, dp_intf);
+		}
+
+		ret = A_ERROR;
+		fwd_tx_packets = 0;
+		fwd_rx_packets = 0;
+		if (dp_intf->device_mode == QDF_SAP_MODE ||
+		    dp_intf->device_mode == QDF_P2P_GO_MODE ||
+		    dp_intf->device_mode == QDF_NDI_MODE) {
+			dp_for_each_link_held_safe(dp_intf, dp_link,
+						   dp_link_next) {
+				ret = cdp_get_intra_bss_fwd_pkts_count(
+					cds_get_context(QDF_MODULE_ID_SOC),
+					dp_link->link_id,
+					&fwd_tx_packets_temp,
+					&fwd_rx_packets_temp);
+				if (ret == A_OK) {
+					fwd_tx_packets += fwd_tx_packets_temp;
+					fwd_rx_packets += fwd_rx_packets_temp;
+				} else {
+					break;
+				}
+			}
+		}
+
+		if (ret == A_OK) {
+			fwd_tx_packets_diff += DP_BW_GET_DIFF(
+				fwd_tx_packets,
+				dp_intf->prev_fwd_tx_packets);
+			fwd_rx_packets_diff += DP_BW_GET_DIFF(
+				fwd_rx_packets,
+				dp_intf->prev_fwd_rx_packets);
+		}
+
+		if (dp_intf->device_mode == QDF_SAP_MODE) {
+			con_sap_dp_intf = dp_intf;
+			sap_tx_bytes =
+				qdf_net_stats_get_tx_bytes(&dp_intf->stats);
+		}
+
+		if (dp_intf->device_mode == QDF_STA_MODE)
+			sta_tx_bytes =
+				qdf_net_stats_get_tx_bytes(&dp_intf->stats);
+
+		dp_for_each_link_held_safe(dp_intf, dp_link, dp_link_next) {
+			dp_set_driver_del_ack_enable(dp_link->link_id, dp_ctx,
+						     rx_packets);
+
+			dp_set_vdev_bundle_require_flag(dp_link->link_id,
+							dp_ctx, tx_bytes);
+		}
+
+		total_rx += qdf_net_stats_get_rx_pkts(&dp_intf->stats);
+		total_tx += qdf_net_stats_get_tx_pkts(&dp_intf->stats);
+
+		qdf_spin_lock_bh(&dp_ctx->bus_bw_lock);
+		dp_intf->prev_tx_packets =
+			qdf_net_stats_get_tx_pkts(&dp_intf->stats);
+		dp_intf->prev_rx_packets =
+			qdf_net_stats_get_rx_pkts(&dp_intf->stats);
+		dp_intf->prev_fwd_tx_packets = fwd_tx_packets;
+		dp_intf->prev_fwd_rx_packets = fwd_rx_packets;
+		dp_intf->prev_tx_bytes =
+			qdf_net_stats_get_tx_bytes(&dp_intf->stats);
+		qdf_spin_unlock_bh(&dp_ctx->bus_bw_lock);
+		connected = true;
+
+		dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
+	}
+
+	if (!connected) {
+		dp_err("bus bandwidth timer running in disconnected state");
+		goto stop_work;
+	}
+
+	/* add intra bss forwarded tx and rx packets */
+	tx_packets += fwd_tx_packets_diff;
+	rx_packets += fwd_rx_packets_diff;
+
+	/* Send embedded Tx packet bytes on STA & SAP interface to IPA driver */
+	ucfg_ipa_update_tx_stats(dp_ctx->pdev, sta_tx_bytes, sap_tx_bytes);
+
+	dp_ipa_set_perf_level(dp_ctx, &tx_packets, &rx_packets,
+			      &ipa_tx_packets, &ipa_rx_packets);
+	if (con_sap_dp_intf) {
+		qdf_net_stats_add_tx_pkts(&con_sap_dp_intf->stats,
+					  ipa_tx_packets);
+		qdf_net_stats_add_rx_pkts(&con_sap_dp_intf->stats,
+					  ipa_rx_packets);
+	}
+
+	tx_packets = tx_packets * bw_interval_us;
+	tx_packets = qdf_do_div(tx_packets, (uint32_t)diff_us);
+
+	rx_packets = rx_packets * bw_interval_us;
+	rx_packets = qdf_do_div(rx_packets, (uint32_t)diff_us);
+
+	dp_pld_request_bus_bandwidth(dp_ctx, tx_packets, rx_packets, diff_us);
+
+	return;
+
+stop_work:
+	qdf_periodic_work_stop_async(&dp_ctx->bus_bw_work);
+}
+
+/**
+ * dp_bus_bw_work_handler() - Bus bandwidth work handler
+ * @context: handle to DP context
+ *
+ * The function handles the bus bandwidth work schedule
+ *
+ * Returns: None
+ */
+static void dp_bus_bw_work_handler(void *context)
+{
+	struct wlan_dp_psoc_context *dp_ctx = context;
+	struct qdf_op_sync *op_sync;
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	if (qdf_op_protect(&op_sync))
+		return;
+
+	__dp_bus_bw_work_handler(dp_ctx);
+
+	qdf_op_unprotect(op_sync);
+}
+
+int dp_bus_bandwidth_init(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
+	QDF_STATUS status;
+
+	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
+		return QDF_STATUS_SUCCESS;
+
+	dp_enter();
+
+	qdf_spinlock_create(&dp_ctx->bus_bw_lock);
+
+	dp_ctx->dp_ops.dp_pm_qos_add_request(ctx);
+
+	wlan_dp_init_tx_rx_histogram(dp_ctx);
+	status = qdf_periodic_work_create(&dp_ctx->bus_bw_work,
+					  dp_bus_bw_work_handler,
+					  dp_ctx);
+
+	dp_exit();
+
+	return qdf_status_to_os_return(status);
+}
+
+void dp_bus_bandwidth_deinit(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+	hdd_cb_handle ctx;
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	ctx = dp_ctx->dp_ops.callback_ctx;
+
+	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
+		return;
+
+	dp_enter();
+
+	/* it is expecting the timer has been stopped or not started
+	 * when coming deinit.
+	 */
+	QDF_BUG(!qdf_periodic_work_stop_sync(&dp_ctx->bus_bw_work));
+
+	qdf_periodic_work_destroy(&dp_ctx->bus_bw_work);
+	qdf_spinlock_destroy(&dp_ctx->bus_bw_lock);
+	wlan_dp_deinit_tx_rx_histogram(dp_ctx);
+	dp_ctx->dp_ops.dp_pm_qos_remove_request(ctx);
+
+	dp_exit();
+}
+
+/**
+ * __dp_bus_bw_compute_timer_start() - start the bus bandwidth timer
+ * @psoc: psoc handle
+ *
+ * Return: None
+ */
+static void __dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
+		return;
+
+	qdf_periodic_work_start(&dp_ctx->bus_bw_work,
+				dp_ctx->dp_cfg.bus_bw_compute_interval);
+	dp_ctx->bw_vote_time = qdf_get_log_timestamp();
+}
+
+void dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc *psoc)
+{
+	dp_enter();
+
+	__dp_bus_bw_compute_timer_start(psoc);
+
+	dp_exit();
+}
+
+void dp_bus_bw_compute_timer_try_start(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+	hdd_cb_handle ctx;
+
+	dp_enter();
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	ctx = dp_ctx->dp_ops.callback_ctx;
+
+	if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx))
+		__dp_bus_bw_compute_timer_start(psoc);
+
+	dp_exit();
+}
+
+/**
+ * __dp_bus_bw_compute_timer_stop() - stop the bus bandwidth timer
+ * @psoc: psoc handle
+ *
+ * Return: None
+ */
+static void __dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+	hdd_cb_handle ctx;
+	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	struct bbm_params param = {0};
+	bool is_any_adapter_conn;
+
+	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
+		return;
+
+	if (!dp_ctx || !soc)
+		return;
+
+	ctx = dp_ctx->dp_ops.callback_ctx;
+	is_any_adapter_conn = dp_ctx->dp_ops.dp_any_adapter_connected(ctx);
+
+	if (!qdf_periodic_work_stop_sync(&dp_ctx->bus_bw_work))
+		goto exit;
+
+	ucfg_ipa_set_perf_level(dp_ctx->pdev, 0, 0);
+
+	dp_reset_tcp_delack(psoc);
+
+	if (!is_any_adapter_conn)
+		dp_reset_tcp_adv_win_scale(dp_ctx);
+
+	cdp_pdev_reset_driver_del_ack(cds_get_context(QDF_MODULE_ID_SOC),
+				      OL_TXRX_PDEV_ID);
+	cdp_pdev_reset_bundle_require_flag(cds_get_context(QDF_MODULE_ID_SOC),
+					   OL_TXRX_PDEV_ID);
+
+	cdp_set_bus_vote_lvl_high(soc, false);
+	dp_ctx->bw_vote_time = 0;
+
+exit:
+	/**
+	 * This check if for the case where the bus bw timer is forcibly
+	 * stopped. We should remove the bus bw voting, if no adapter is
+	 * connected
+	 */
+	if (!is_any_adapter_conn) {
+		uint64_t interval_us =
+			dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;
+		qdf_atomic_set(&dp_ctx->num_latency_critical_clients, 0);
+		dp_pld_request_bus_bandwidth(dp_ctx, 0, 0, interval_us);
+	}
+	param.policy = BBM_TPUT_POLICY;
+	param.policy_info.tput_level = TPUT_LEVEL_NONE;
+	dp_bbm_apply_independent_policy(psoc, &param);
+}
+
+void dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc *psoc)
+{
+	dp_enter();
+
+	__dp_bus_bw_compute_timer_stop(psoc);
+
+	dp_exit();
+}
+
+void dp_bus_bw_compute_timer_try_stop(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+	hdd_cb_handle ctx;
+
+	dp_enter();
+
+	if (!dp_ctx) {
+		dp_err("Unable to get DP context");
+		return;
+	}
+
+	ctx = dp_ctx->dp_ops.callback_ctx;
+
+	if (!dp_ctx->dp_ops.dp_any_adapter_connected(ctx))
+		__dp_bus_bw_compute_timer_stop(psoc);
+
+	dp_exit();
+}
+
+void dp_bus_bw_compute_prev_txrx_stats(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
+	struct wlan_dp_intf *dp_intf;
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+
+	if (!dp_link) {
+		dp_err("No dp_link for objmgr vdev %pK", vdev);
+		return;
+	}
+
+	dp_intf = dp_link->dp_intf;
+	if (!dp_intf) {
+		dp_err("Invalid dp_intf for dp_link %pK (" QDF_MAC_ADDR_FMT ")",
+		       dp_link, QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
+		return;
+	}
+
+	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
+		return;
+
+	qdf_spin_lock_bh(&dp_ctx->bus_bw_lock);
+	dp_intf->prev_tx_packets = qdf_net_stats_get_tx_pkts(&dp_intf->stats);
+	dp_intf->prev_rx_packets = qdf_net_stats_get_rx_pkts(&dp_intf->stats);
+	dp_intf->prev_tx_bytes = qdf_net_stats_get_tx_bytes(&dp_intf->stats);
+
+	/*
+	 * TODO - Should the prev_fwd_tx_packets and
+	 * such stats be per link ??
+	 */
+	cdp_get_intra_bss_fwd_pkts_count(cds_get_context(QDF_MODULE_ID_SOC),
+					 dp_link->link_id,
+					 &dp_intf->prev_fwd_tx_packets,
+					 &dp_intf->prev_fwd_rx_packets);
+	qdf_spin_unlock_bh(&dp_ctx->bus_bw_lock);
+}
+
+void dp_bus_bw_compute_reset_prev_txrx_stats(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
+	struct wlan_dp_intf *dp_intf;
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+
+	if (!dp_link) {
+		dp_err("No dp_link for objmgr vdev %pK", vdev);
+		return;
+	}
+
+	dp_intf = dp_link->dp_intf;
+	if (!dp_intf) {
+		dp_err("Invalid dp_intf for dp_link %pK (" QDF_MAC_ADDR_FMT ")",
+		       dp_link, QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
+		return;
+	}
+
+	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
+		return;
+
+	qdf_spin_lock_bh(&dp_ctx->bus_bw_lock);
+	dp_intf->prev_tx_packets = 0;
+	dp_intf->prev_rx_packets = 0;
+	dp_intf->prev_fwd_tx_packets = 0;
+	dp_intf->prev_fwd_rx_packets = 0;
+	dp_intf->prev_tx_bytes = 0;
+	qdf_spin_unlock_bh(&dp_ctx->bus_bw_lock);
+}
+#endif /* WLAN_FEATURE_DP_BUS_BANDWIDTH */

+ 453 - 0
qcom/opensource/wlan/qcacld-3.0/components/dp/core/src/wlan_dp_bus_bandwidth.h

@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * 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.
+ */
+
+#if !defined(WLAN_DP_BUS_BANDWIDTH_H)
+#define WLAN_DP_BUS_BANDWIDTH_H
+/**
+ * DOC: wlan_dp_bus_bandwidth.h
+ *
+ * Bus Bandwidth Manager implementation
+ */
+
+#include "wlan_dp_priv.h"
+#include <qdf_types.h>
+#include <qca_vendor.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include "wlan_dp_public_struct.h"
+#include "wlan_dp_priv.h"
+#include <cdp_txrx_misc.h>
+
+typedef const enum bus_bw_level
+	bus_bw_table_type[QCA_WLAN_802_11_MODE_INVALID][TPUT_LEVEL_MAX];
+
+/**
+ * struct bbm_context: Bus Bandwidth Manager context
+ *
+ * @curr_bus_bw_lookup_table: current bus bw lookup table
+ * @curr_vote_level: current vote level
+ * @per_policy_vote: per BBM policy related vote
+ * @bbm_lock: BBM API lock
+ */
+struct bbm_context {
+	bus_bw_table_type *curr_bus_bw_lookup_table;
+	enum bus_bw_level curr_vote_level;
+	enum bus_bw_level per_policy_vote[BBM_MAX_POLICY];
+	qdf_mutex_t bbm_lock;
+};
+
+#ifdef FEATURE_BUS_BANDWIDTH_MGR
+/**
+ * dp_bbm_context_init() - Initialize BBM context
+ * @psoc: psoc Handle
+ *
+ * Returns: error code
+ */
+int dp_bbm_context_init(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bbm_context_deinit() - De-initialize BBM context
+ * @psoc: psoc Handle
+ *
+ * Returns: None
+ */
+void dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bbm_apply_independent_policy() - Function to apply independent policies
+ *  to set the bus bw level
+ * @psoc: psoc Handle
+ * @params: BBM policy related params
+ *
+ * The function applies BBM related policies and appropriately sets the bus
+ * bandwidth level.
+ *
+ * Returns: None
+ */
+void dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc,
+				     struct bbm_params *params);
+#else
+static inline int dp_bbm_context_init(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline void dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc,
+				     struct bbm_params *params)
+{
+}
+#endif /* FEATURE_BUS_BANDWIDTH_MGR */
+
+#if defined(WLAN_FEATURE_DP_BUS_BANDWIDTH) && defined(FEATURE_RUNTIME_PM)
+/**
+ * dp_rtpm_tput_policy_init() - Initialize RTPM tput policy
+ * @psoc: psoc handle
+ *
+ * Returns: None
+ */
+void dp_rtpm_tput_policy_init(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_rtpm_tput_policy_deinit() - Deinitialize RTPM tput policy
+ * @psoc: psoc handle
+ *
+ * Returns: None
+ */
+void dp_rtpm_tput_policy_deinit(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_rtpm_tput_policy_apply() - Apply RTPM tput policy
+ * @dp_ctx: dp_ctx handle
+ * @tput_level : Tput level
+ *
+ * Returns: None
+ */
+void dp_rtpm_tput_policy_apply(struct wlan_dp_psoc_context *dp_ctx,
+			       enum tput_level tput_level);
+
+/**
+ * dp_rtpm_tput_policy_get_vote() - Get RTPM tput policy vote
+ * @dp_ctx: dp_ctx handle
+ *
+ * Returns: Current vote
+ */
+int dp_rtpm_tput_policy_get_vote(struct wlan_dp_psoc_context *dp_ctx);
+#else
+static inline
+void dp_rtpm_tput_policy_init(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_rtpm_tput_policy_deinit(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_rtpm_tput_policy_apply(struct wlan_dp_psoc_context *dp_ctx,
+			       enum tput_level tput_level)
+{
+}
+
+static inline int
+dp_rtpm_tput_policy_get_vote(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return -EINVAL;
+}
+#endif /* WLAN_FEATURE_DP_BUS_BANDWIDTH && FEATURE_RUNTIME_PM */
+
+/**
+ * dp_set_high_bus_bw_request() - Set High Bandwidth request value
+ * @psoc: psoc handle
+ * @vdev_id: Vdev ID
+ * @high_bus_bw : Flag to set or clear high bandwidth request
+ *
+ * Return: None
+ */
+static inline void dp_set_high_bus_bw_request(struct wlan_objmgr_psoc *psoc,
+					      uint8_t vdev_id,
+					      bool high_bus_bw)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+
+	if (high_bus_bw)
+		dp_ctx->high_bus_bw_request |= (1 << vdev_id);
+	else
+		dp_ctx->high_bus_bw_request &= ~(1 << vdev_id);
+}
+
+#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
+/**
+ * dp_reset_tcp_delack() - Reset tcp delack value to default
+ * @psoc: psoc handle
+ *
+ * Function used to reset TCP delack value to its default value
+ *
+ * Return: None
+ */
+void dp_reset_tcp_delack(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_dp_update_tcp_rx_param() - update TCP param in RX dir
+ * @dp_ctx: Pointer to DP context
+ * @data: Parameters to update
+ *
+ * Return: None
+ */
+void wlan_dp_update_tcp_rx_param(struct wlan_dp_psoc_context *dp_ctx,
+				 struct wlan_rx_tp_data *data);
+
+#ifdef RX_PERFORMANCE
+/**
+ * dp_is_current_high_throughput() - Check if vote level is high
+ * @dp_ctx: Pointer to DP context
+ *
+ * Function used to check if vote level is high
+ *
+ * Return: True if vote level is high
+ */
+bool dp_is_current_high_throughput(struct wlan_dp_psoc_context *dp_ctx);
+#else
+static inline
+bool dp_is_current_high_throughput(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return false;
+}
+#endif /* RX_PERFORMANCE */
+
+/**
+ * dp_reset_tcp_delack() - Reset TCP delack
+ * @psoc: psoc handle
+ *
+ * Return: None
+ */
+void dp_reset_tcp_delack(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_get_current_throughput_level() - Get the current vote
+ * level
+ * @dp_ctx: DP Context handle
+ *
+ * Return: current vote level
+ */
+static inline enum pld_bus_width_type
+dp_get_current_throughput_level(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return dp_ctx->cur_vote_level;
+}
+
+/**
+ * dp_set_current_throughput_level() - update the current vote
+ * level
+ * @psoc: psoc object
+ * @next_vote_level: pld_bus_width_type voting level
+ *
+ * This function updates the current vote level to the new level
+ * provided
+ *
+ * Return: None
+ */
+static inline void
+dp_set_current_throughput_level(struct wlan_objmgr_psoc *psoc,
+				enum pld_bus_width_type next_vote_level)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+
+	dp_ctx->cur_vote_level = next_vote_level;
+}
+
+/**
+ * wlan_dp_display_tx_rx_histogram() - display tx rx histogram
+ * @psoc: psoc handle
+ *
+ * Return: none
+ */
+void wlan_dp_display_tx_rx_histogram(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_dp_clear_tx_rx_histogram() - clear tx rx histogram
+ * @psoc: psoc handle
+ *
+ * Return: none
+ */
+void wlan_dp_clear_tx_rx_histogram(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bus_bandwidth_init() - Initialize bus bandwidth data structures.
+ * @psoc: psoc handle
+ *
+ * Initialize bus bandwidth related data structures like spinlock and timer.
+ *
+ * Return: None.
+ */
+int dp_bus_bandwidth_init(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bus_bandwidth_deinit() - De-initialize bus bandwidth data structures.
+ * @psoc: psoc handle
+ *
+ * De-initialize bus bandwidth related data structures like timer.
+ *
+ * Return: None.
+ */
+void dp_bus_bandwidth_deinit(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bus_bw_compute_timer_start() - start the bandwidth timer
+ * @psoc: psoc handle
+ *
+ * Return: None
+ */
+void dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bus_bw_compute_timer_try_start() - try to start the bandwidth timer
+ * @psoc: psoc handle
+ *
+ * This function ensures there is at least one interface in the assoc state
+ * before starting the bandwidth timer.
+ *
+ * Return: None
+ */
+void dp_bus_bw_compute_timer_try_start(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bus_bw_compute_timer_stop() - stop the bandwidth timer
+ * @psoc: psoc handle
+ *
+ * Return: None
+ */
+void dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bus_bw_compute_timer_try_stop() - try to stop the bandwidth timer
+ * @psoc: psoc handle
+ *
+ * This function ensures there are no interface in the assoc state before
+ * stopping the bandwidth timer.
+ *
+ * Return: None
+ */
+void dp_bus_bw_compute_timer_try_stop(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * dp_bus_bw_compute_prev_txrx_stats() - get tx and rx stats
+ * @vdev: vdev handle
+ *
+ * This function get the collected tx and rx stats before starting
+ * the bus bandwidth timer.
+ *
+ * Return: None
+ */
+void dp_bus_bw_compute_prev_txrx_stats(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * dp_bus_bw_compute_reset_prev_txrx_stats() - reset previous tx and rx stats
+ * @vdev: vdev handle
+ *
+ * This function resets the previous tx rx stats.
+ *
+ * Return: None
+ */
+void dp_bus_bw_compute_reset_prev_txrx_stats(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * dp_get_bus_bw_high_threshold() - Get the bus bw high threshold
+ * level
+ * @dp_ctx: DP Context handle
+ *
+ * Return: bus bw high threshold
+ */
+static inline uint32_t
+dp_get_bus_bw_high_threshold(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return dp_ctx->dp_cfg.bus_bw_high_threshold;
+}
+
+#else
+static inline
+void dp_reset_tcp_delack(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void wlan_dp_update_tcp_rx_param(struct wlan_dp_psoc_context *dp_ctx,
+				 struct wlan_rx_tp_data *data)
+{
+}
+
+static inline
+bool dp_is_current_high_throughput(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return false;
+}
+
+static inline enum pld_bus_width_type
+dp_get_current_throughput_level(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return PLD_BUS_WIDTH_NONE;
+}
+
+static inline
+void dp_set_current_throughput_level(struct wlan_objmgr_psoc *psoc,
+				     enum pld_bus_width_type next_vote_level)
+{
+}
+
+static inline
+void wlan_dp_display_tx_rx_histogram(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void wlan_dp_clear_tx_rx_histogram(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_bus_bandwidth_init(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_bus_bandwidth_deinit(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_bus_bw_compute_timer_try_start(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_bus_bw_compute_timer_try_stop(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void dp_bus_bw_compute_prev_txrx_stats(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline
+void dp_bus_bw_compute_reset_prev_txrx_stats(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline uint32_t
+dp_get_bus_bw_high_threshold(struct wlan_dp_psoc_context *dp_ctx)
+{
+	return 0;
+}
+
+#endif /* WLAN_FEATURE_DP_BUS_BANDWIDTH */
+#endif /* WLAN_DP_BUS_BANDWIDTH_H */

部分文件因文件數量過多而無法顯示