qcacld-3.0: [11AX] Add support to configure 11ax rate
Add support for to configure 11ax rates using set_11ax_rate
iwpriv command.
Change-Id: I55ab5cc3b51f92ab5c2e347d3b17e392456b90b8
CRs-Fixed: 1073481
diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h
index a7a7865..b5971e1 100644
--- a/core/hdd/inc/qc_sap_ioctl.h
+++ b/core/hdd/inc/qc_sap_ioctl.h
@@ -191,6 +191,9 @@
#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf)
#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1)
+#define RC_2_RATE_IDX_11AX(_rc) ((_rc) & 0x1f)
+#define HT_RC_2_STREAMS_11AX(_rc) (((_rc) >> 5) & 0x7)
+
enum {
QCSAP_PARAM_MAX_ASSOC = 1,
QCSAP_PARAM_GET_WLAN_DBG,
@@ -252,6 +255,7 @@
QCASAP_PARAM_RX_STBC,
QCSAP_PARAM_CHAN_WIDTH,
QCSAP_PARAM_SET_TXRX_STATS,
+ QCASAP_SET_11AX_RATE,
};
int iw_get_channel_list(struct net_device *dev,
diff --git a/core/hdd/inc/wlan_hdd_wext.h b/core/hdd/inc/wlan_hdd_wext.h
index b949041..1d62e7a 100644
--- a/core/hdd/inc/wlan_hdd_wext.h
+++ b/core/hdd/inc/wlan_hdd_wext.h
@@ -36,6 +36,8 @@
#include <linux/timer.h>
#include "qdf_event.h"
+struct sap_Config;
+
/*
* order of parameters in addTs private ioctl
*/
@@ -384,6 +386,31 @@
int hdd_get_rx_stbc(hdd_adapter_t *adapter, int *value);
int hdd_set_rx_stbc(hdd_adapter_t *adapter, int value);
+/**
+ * hdd_assemble_rate_code() - assemble rate code to be sent to FW
+ * @preamble: rate preamble
+ * @nss: number of streams
+ * @rate: rate index
+ *
+ * Rate code assembling is different for targets which are 11ax capable.
+ * Check for the target support and assemble the rate code accordingly.
+ *
+ * Return: assembled rate code
+ */
+int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate);
+
+/**
+ * hdd_set_11ax_rate() - set 11ax rate
+ * @adapter: adapter being modified
+ * @value: new 11ax rate code
+ * @sap_config: pointer to SAP config to check HW mode
+ * this will be NULL for call from STA persona
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_set_11ax_rate(hdd_adapter_t *adapter, int value,
+ struct sap_Config *sap_config);
+
void wlan_hdd_change_country_code_callback(void *pAdapter);
int hdd_set_band(struct net_device *dev, u8 ui_band);
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 4e02570..6188e96 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -2990,7 +2990,7 @@
}
preamble = WMI_RATE_PREAMBLE_OFDM;
}
- set_value = (preamble << 6) | (nss << 4) | rix;
+ set_value = hdd_assemble_rate_code(preamble, nss, rix);
}
hdd_notice("SET_HT_RATE val %d rix %d preamble %x nss %d",
set_value, rix, preamble, nss);
@@ -3015,11 +3015,11 @@
}
if (set_value != 0xff) {
- rix = RC_2_RATE_IDX_11AC(set_value);
- preamble = WMI_RATE_PREAMBLE_VHT;
- nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
+ rix = RC_2_RATE_IDX_11AC(set_value);
+ preamble = WMI_RATE_PREAMBLE_VHT;
+ nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
- set_value = (preamble << 6) | (nss << 4) | rix;
+ set_value = hdd_assemble_rate_code(preamble, nss, rix);
}
hdd_notice("SET_VHT_RATE val %d rix %d preamble %x nss %d",
set_value, rix, preamble, nss);
@@ -3033,7 +3033,6 @@
case QCASAP_SHORT_GI:
{
hdd_notice("QCASAP_SET_SHORT_GI val %d", set_value);
-
/* same as 40MHZ */
ret = sme_update_ht_config(hHal, pHostapdAdapter->sessionId,
WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
@@ -3302,7 +3301,11 @@
case QCASAP_PARAM_RX_STBC:
ret = hdd_set_rx_stbc(pHostapdAdapter, set_value);
break;
-
+ case QCASAP_SET_11AX_RATE:
+ ret = hdd_set_11ax_rate(pHostapdAdapter, set_value,
+ &pHostapdAdapter->sessionCtx.ap.
+ sapConfig);
+ break;
default:
hdd_err("Invalid setparam command %d value %d",
sub_cmd, set_value);
@@ -3452,8 +3455,7 @@
case QCASAP_SHORT_GI:
{
*value = (int)sme_get_ht_config(hHal,
- pHostapdAdapter->
- sessionId,
+ pHostapdAdapter->sessionId,
WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
break;
}
@@ -5764,7 +5766,12 @@
}
,
#endif
-
+ {
+ QCASAP_SET_11AX_RATE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_11ax_rate"
+ }
+ ,
};
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 c5ef4cf..2d8bc33 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -1011,6 +1011,26 @@
#define WE_SET_CONC_SYSTEM_PREF 89
#define WE_SET_TXRX_STATS 90
+/*
+ * <ioctl>
+ * set_11ax_rate - set 11ax rates to FW
+ *
+ * @INPUT: rate code
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL fixes the Tx data rate of 11AX.
+ *
+ * @E.g: iwpriv wlan0 set_11ax_rate <rate code>
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_11AX_RATE 91
+
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
#define WE_GET_11D_STATE 1
@@ -3952,6 +3972,54 @@
return ret;
}
+int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
+{
+ int set_value;
+
+ if (sme_is_feature_supported_by_fw(DOT11AX))
+ set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble);
+ else
+ set_value = (preamble << 6) | (nss << 4) | rate;
+
+ return set_value;
+}
+
+int hdd_set_11ax_rate(hdd_adapter_t *adapter, int set_value,
+ struct sap_Config *sap_config)
+{
+ uint8_t preamble = 0, nss = 0, rix = 0;
+ int ret;
+
+ if (!sap_config) {
+ if (!sme_is_feature_supported_by_fw(DOT11AX)) {
+ hdd_err("Target does not support 11ax");
+ return -EIO;
+ }
+ } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
+ sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
+ hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch = %d",
+ sap_config->SapHw_mode, sap_config->channel);
+ return -EIO;
+ }
+
+ if (set_value != 0xff) {
+ rix = RC_2_RATE_IDX_11AX(set_value);
+ preamble = WMI_RATE_PREAMBLE_HE;
+ nss = HT_RC_2_STREAMS_11AX(set_value);
+
+ set_value = hdd_assemble_rate_code(preamble, nss, rix);
+ }
+
+ hdd_notice("SET_11AX_RATE val %d rix %d preamble %x nss %d",
+ set_value, rix, preamble, nss);
+
+ ret = wma_cli_set_command(adapter->sessionId,
+ WMI_VDEV_PARAM_FIXED_RATE,
+ set_value, VDEV_CMD);
+
+ return ret;
+}
+
/**
* __iw_set_commit() - SIOCSIWCOMMIT ioctl handler
* @dev: device upon which the ioctl was received
@@ -7863,7 +7931,7 @@
WMI_RATE_PREAMBLE_OFDM;
}
}
- set_value = (preamble << 6) | (nss << 4) | rix;
+ set_value = hdd_assemble_rate_code(preamble, nss, rix);
}
hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
set_value, rix, preamble, nss);
@@ -7883,7 +7951,7 @@
preamble = WMI_RATE_PREAMBLE_VHT;
nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
- set_value = (preamble << 6) | (nss << 4) | rix;
+ set_value = hdd_assemble_rate_code(preamble, nss, rix);
}
hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
set_value, rix, preamble, nss);
@@ -8438,6 +8506,9 @@
hdd_ctx->config->conc_system_pref = set_value;
break;
}
+ case WE_SET_11AX_RATE:
+ ret = hdd_set_11ax_rate(pAdapter, set_value, NULL);
+ break;
default:
{
hdd_err("Invalid sub command %d",
@@ -13453,6 +13524,11 @@
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"hostroamdelay"}
,
+ {WE_SET_11AX_RATE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_11ax_rate"}
+ ,
};
const struct iw_handler_def we_handler_def = {