diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h
index b13ce93012ea..0fd97013ba48 100644
--- a/core/hdd/inc/qc_sap_ioctl.h
+++ b/core/hdd/inc/qc_sap_ioctl.h
@@ -257,6 +257,7 @@ enum {
QCSAP_PARAM_SET_TXRX_STATS,
QCASAP_SET_11AX_RATE,
QCASAP_SET_PEER_RATE,
+ QCASAP_PARAM_DCM,
};
int iw_get_channel_list(struct net_device *dev,
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index db8d59459770..1850419efa45 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -3315,6 +3315,12 @@ static __iw_softap_setparam(struct net_device *dev,
case QCASAP_SET_PEER_RATE:
ret = hdd_set_peer_rate(pHostapdAdapter, set_value);
break;
+ case QCASAP_PARAM_DCM:
+ hdd_notice("Set WMI_VDEV_PARAM_HE_DCM: %d", set_value);
+ ret = wma_cli_set_command(pHostapdAdapter->sessionId,
+ WMI_VDEV_PARAM_HE_DCM, set_value,
+ VDEV_CMD);
+ break;
default:
hdd_err("Invalid setparam command %d value %d",
sub_cmd, set_value);
@@ -3621,6 +3627,13 @@ static __iw_softap_getparam(struct net_device *dev,
ret = hdd_sap_get_chan_width(pHostapdAdapter, value);
break;
}
+ case QCASAP_PARAM_DCM:
+ {
+ *value = wma_cli_get_command(pHostapdAdapter->sessionId,
+ WMI_VDEV_PARAM_HE_DCM,
+ VDEV_CMD);
+ break;
+ }
default:
hdd_err("Invalid getparam command %d", sub_cmd);
ret = -EINVAL;
@@ -5787,6 +5800,12 @@ static const struct iw_priv_args hostapd_private_args[] = {
0, "set_peer_rate"
}
,
+ {
+ QCASAP_PARAM_DCM,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "enable_dcm"
+ }
+ ,
};
static const iw_handler hostapd_private[] = {
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index f30d2796b274..808440cb79f4 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -1031,6 +1031,27 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
*/
#define WE_SET_11AX_RATE 91
+/*
+ *
+ * enable_dcm - enable Dual Carrier Modulation(DCM)
+ *
+ * @INPUT: 0/1
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL enables/disables DCM.
+ *
+ * @E.g: iwpriv wlan0 enable_dcm <0/1>
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ *
+ */
+#define WE_SET_DCM 92
+
+
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
#define WE_GET_11D_STATE 1
@@ -1692,6 +1713,25 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
#define WE_CAP_TSF 58
#define WE_GET_ROAM_SYNCH_DELAY 59
+/*
+ *
+ * get_dcm - Get dcm enablement value
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: 0/1
+ * wlan0 get_dcm
+ *
+ * This IOCTL is used get dcm value
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ *
+ */
+#define WE_GET_DCM 60
+
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2)
@@ -8573,6 +8613,12 @@ static int __iw_setint_getnone(struct net_device *dev,
case WE_SET_11AX_RATE:
ret = hdd_set_11ax_rate(pAdapter, set_value, NULL);
break;
+ case WE_SET_DCM:
+ hdd_notice("Set WMI_VDEV_PARAM_HE_DCM: %d", set_value);
+ ret = wma_cli_set_command(pAdapter->sessionId,
+ WMI_VDEV_PARAM_HE_DCM, set_value,
+ VDEV_CMD);
+ break;
default:
{
hdd_err("Invalid sub command %d",
@@ -9282,6 +9328,12 @@ static int __iw_setnone_getint(struct net_device *dev,
ret = wlan_hdd_get_temperature(pAdapter, value);
break;
}
+ case WE_GET_DCM:
+ hdd_notice("GET WMI_VDEV_PARAM_HE_DCM");
+ *value = wma_cli_get_command(pAdapter->sessionId,
+ WMI_VDEV_PARAM_HE_DCM,
+ VDEV_CMD);
+ break;
default:
{
hdd_err("Invalid IOCTL get_value command %d",
@@ -13158,6 +13210,10 @@ static const struct iw_priv_args we_private_args[] = {
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_temp"},
+ {WE_GET_DCM,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_dcm"},
/* handlers for main ioctl */
{WLAN_PRIV_SET_CHAR_GET_NONE,
IW_PRIV_TYPE_CHAR | 512,
@@ -13594,6 +13650,11 @@ static const struct iw_priv_args we_private_args[] = {
0,
"set_11ax_rate"}
,
+ {WE_SET_DCM,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "enable_dcm"}
+ ,
};
const struct iw_handler_def we_handler_def = {
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index ec880b67d9fc..5e472963c1c7 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -827,6 +827,7 @@ typedef struct {
* @pps_params: packet power save parameters
* @qpower_params: qpower parameters
* @gtx_info: GTX offload info
+ * @dcm: DCM enable/disable
*
* This structure stores vdev parameters.
* Some of these parameters are set in fw and some
@@ -853,6 +854,9 @@ typedef struct {
struct pps pps_params;
struct qpower_params qpower_params;
gtx_config_t gtx_info;
+#ifdef WLAN_FEATURE_11AX
+ uint8_t dcm;
+#endif
} vdev_cli_config_t;
/**
diff --git a/core/wma/inc/wma_he.h b/core/wma/inc/wma_he.h
index e2747d3944a1..da1073944fe3 100644
--- a/core/wma/inc/wma_he.h
+++ b/core/wma/inc/wma_he.h
@@ -64,6 +64,27 @@ void wma_update_vdev_he_capable(struct wma_vdev_start_req *req,
*/
QDF_STATUS wma_get_he_capabilities(struct he_capability *he_cap);
+/**
+ * wma_set_he_vdev_param() - update he vdev param in wma
+ * @intr: pointer to wma_txrx_node
+ * @param_id: vdev param id
+ * @value: value of vdev param
+ *
+ * Result: None
+ */
+void wma_set_he_vdev_param(struct wma_txrx_node *intr, WMI_VDEV_PARAM param_id,
+ uint32_t value);
+
+/**
+ * wma_get_he_vdev_param() - retrieve he vdev param from wma
+ * @intr: pointer to wma_txrx_node
+ * @param_id: vdev param id
+ *
+ * Result: param value
+ */
+uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
+ WMI_VDEV_PARAM param_id);
+
#else
static inline void wma_print_he_cap(tDot11fIEvendor_he_cap *he_cap)
{
@@ -130,6 +151,20 @@ static inline void wma_update_vdev_he_capable(struct wma_vdev_start_req *req,
tpSwitchChannelParams params)
{
}
+
+static inline void wma_set_he_vdev_param(struct wma_txrx_node *intr,
+ WMI_VDEV_PARAM param_id, uint32_t value)
+{
+ WMA_LOGI(FL("Unable to update WMI_VDEV_PARAM: %0x"), param_id);
+}
+
+static inline uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
+ WMI_VDEV_PARAM param_id)
+{
+ WMA_LOGI(FL("Unable to update WMI_VDEV_PARAM: %0x"), param_id);
+ return 0;
+}
+
#endif
#endif /* __WMA_HE_H */
diff --git a/core/wma/src/wma_he.c b/core/wma/src/wma_he.c
index 324c04a100fd..eaf6905db335 100644
--- a/core/wma/src/wma_he.c
+++ b/core/wma/src/wma_he.c
@@ -1121,3 +1121,29 @@ QDF_STATUS wma_get_he_capabilities(struct he_capability *he_cap)
return QDF_STATUS_SUCCESS;
}
+
+void wma_set_he_vdev_param(struct wma_txrx_node *intr, WMI_VDEV_PARAM param_id,
+ uint32_t value)
+{
+ switch (param_id) {
+ case WMI_VDEV_PARAM_HE_DCM:
+ intr->config.dcm = value;
+ break;
+ default:
+ WMA_LOGE(FL("Unhandled HE vdev param: %0x"), param_id);
+ break;
+ }
+}
+
+uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
+ WMI_VDEV_PARAM param_id)
+{
+ switch (param_id) {
+ case WMI_VDEV_PARAM_HE_DCM:
+ return intr->config.dcm;
+ default:
+ WMA_LOGE(FL("Unhandled HE vdev param: %0x"), param_id);
+ break;
+ }
+ return 0;
+}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 94c1767200ca..116e84ddff60 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -376,6 +376,9 @@ int wma_cli_get_command(int vdev_id, int param_id, int vpdev)
case WMI_VDEV_PARAM_FIXED_RATE:
ret = intr[vdev_id].config.tx_rate;
break;
+ case WMI_VDEV_PARAM_HE_DCM:
+ ret = wma_get_he_vdev_param(&intr[vdev_id], param_id);
+ break;
default:
WMA_LOGE("Invalid cli_get vdev command/Not"
" yet implemented 0x%x", param_id);
@@ -1407,6 +1410,10 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
case WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE:
intr[vid].config.erx_dri_sample = privcmd->param_value;
break;
+ case WMI_VDEV_PARAM_HE_DCM:
+ wma_set_he_vdev_param(&intr[vid], privcmd->param_id,
+ privcmd->param_value);
+ break;
default:
WMA_LOGE("Invalid wma_cli_set vdev command/Not"
" yet implemented 0x%x", privcmd->param_id);