From 9e5339da1fc26cc6bd1671d283b71ed197cd15f8 Mon Sep 17 00:00:00 2001 From: Krishna Kumaar Natarajan Date: Mon, 5 Dec 2016 14:12:13 -0800 Subject: [PATCH] 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 --- core/hdd/inc/qc_sap_ioctl.h | 4 ++ core/hdd/inc/wlan_hdd_wext.h | 27 +++++++++++ core/hdd/src/wlan_hdd_hostapd.c | 27 ++++++----- core/hdd/src/wlan_hdd_wext.c | 80 ++++++++++++++++++++++++++++++++- 4 files changed, 126 insertions(+), 12 deletions(-) diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h index a7a7865cfdd9..b5971e1ef959 100644 --- a/core/hdd/inc/qc_sap_ioctl.h +++ b/core/hdd/inc/qc_sap_ioctl.h @@ -191,6 +191,9 @@ typedef struct { #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 @@ enum { 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 b949041ebd0d..1d62e7a43931 100644 --- a/core/hdd/inc/wlan_hdd_wext.h +++ b/core/hdd/inc/wlan_hdd_wext.h @@ -36,6 +36,8 @@ #include #include "qdf_event.h" +struct sap_Config; + /* * order of parameters in addTs private ioctl */ @@ -384,6 +386,31 @@ int hdd_set_tx_stbc(hdd_adapter_t *adapter, int value); 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 4e02570da4dc..6188e96ec21a 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -2990,7 +2990,7 @@ static __iw_softap_setparam(struct net_device *dev, } 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 @@ static __iw_softap_setparam(struct net_device *dev, } 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 @@ static __iw_softap_setparam(struct net_device *dev, 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 @@ static __iw_softap_setparam(struct net_device *dev, 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 @@ static __iw_softap_getparam(struct net_device *dev, 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 @@ static const struct iw_priv_args hostapd_private_args[] = { } , #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 c5ef4cf0b976..2d8bc337d8fb 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -1011,6 +1011,26 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { #define WE_SET_CONC_SYSTEM_PREF 89 #define WE_SET_TXRX_STATS 90 +/* + * + * 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 + * + * Supported Feature: STA/SAP + * + * Usage: Internal + * + * + */ +#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 @@ int hdd_set_rx_stbc(hdd_adapter_t *adapter, int value) 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 @@ static int __iw_setint_getnone(struct net_device *dev, 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 @@ static int __iw_setint_getnone(struct net_device *dev, 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 @@ static int __iw_setint_getnone(struct net_device *dev, 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 @@ static const struct iw_priv_args we_private_args[] = { 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 = {