summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAhmad Kholaif <akholaif@qca.qualcomm.com>2014-01-13 21:21:42 -0800
committerPrakash Dhavali <pdhavali@qca.qualcomm.com>2014-01-26 20:06:35 -0800
commitca654f3381b2fc81a2e217817d49324a66cbe506 (patch)
tree6accc2da710dbb8c48ae8fba6c6d0f1ff9a106fc
parent96f3f60dad5650d21ffab346362022446098f561 (diff)
CLD: Add iwpriv cmds to set channel time quota & latency for MCC
To help with CST testing for MCC, 2 new iwpriv commands are added to allow run-time configuration of both channel time and channel latency for home channels in MCC mode. The commands are: - iwpriv <MCC mode> setMccLatency <latency in ms> - iwpriv <MCC mode> setMccQuota <quota in ms> Notes: - MCC mode: wlan0 or p2p0. Only MCC modes STA and P2P are currently assumed. - latency: minimum non-zero value is 30ms. Otherwise, use 0 for default setting - quota: minimum is 20ms, and maximum is 80ms. - Setting the MCC latency and/or quota for home channels is only possible iff MCC Adaptive Scheduler feature is disabled. - Based on the adapter specified in the command, i.e., wlan0 vs. p2p0, host driver finds out the operating channel and formats both the channel number and latency (or quota) in a bit vector then passes it to WMA. - In the case of iwpriv setMccQuota cmd, host driver finds out the other MCC mode/adapter and its corresponding channel number. Then it formats channel numbers of both MCC modes/adapters and the time quota specified in the iwpriv cmd as a bit vector and passes it on to WMI. - setMccQuota specifies the time quota for a single adapter/mode, while host driver calculates quota for the 2nd MCC adapter as: 100 - quota_of_first_adapter Change-Id: If9caec2bb497ffb21c2497de9b448a3095dcea6b CRs-fixed: 592965
-rw-r--r--CORE/HDD/inc/qc_sap_ioctl.h2
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c178
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c162
-rw-r--r--CORE/SERVICES/WMA/wma.c310
-rw-r--r--CORE/SERVICES/WMA/wma.h3
-rw-r--r--firmware_bin/WCNSS_qcom_cfg.ini2
6 files changed, 656 insertions, 1 deletions
diff --git a/CORE/HDD/inc/qc_sap_ioctl.h b/CORE/HDD/inc/qc_sap_ioctl.h
index 61ee976e7ec3..d4b052eb743a 100644
--- a/CORE/HDD/inc/qc_sap_ioctl.h
+++ b/CORE/HDD/inc/qc_sap_ioctl.h
@@ -285,6 +285,8 @@ enum {
QCSAP_PARAM_AUTO_CHANNEL = 9,
QCSAP_PARAM_SET_MC_RATE = 10,
QCSAP_PARAM_SET_TXRX_FW_STATS=11,
+ QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY = 12,
+ QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA = 13,
};
int iw_softap_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 d86b142aceff..9fc88280c2dd 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -77,6 +77,7 @@
#endif
#include "cfgApi.h"
#include "wniCfgAp.h"
+#include "wlan_hdd_misc.h"
#ifdef QCA_WIFI_2_0
#include "wma.h"
@@ -1325,6 +1326,179 @@ static iw_softap_setparam(struct net_device *dev,
set_value, VDEV_CMD);
break;
}
+ case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
+ {
+ tVOS_CONCURRENCY_MODE concurrent_state = 0;
+ v_U8_t first_adapter_operating_channel = 0;
+ int ret = 0; /* success */
+ hddLog(LOG1, "%s: iwpriv cmd to set MCC latency with val: "
+ "%dms", __func__, set_value);
+ concurrent_state = hdd_get_concurrency_mode();
+ /**
+ * Check if concurrency mode is active.
+ * Need to modify this code to support MCC modes other than
+ * STA/P2P GO
+ */
+ if (concurrent_state == (VOS_STA | VOS_P2P_GO))
+ {
+ hddLog(LOG1, "%s: STA & P2P are both enabled", __func__);
+ /**
+ * The channel number and latency are formatted in
+ * a bit vector then passed on to WMA layer.
+ +**********************************************+
+ | bits 31-16 | bits 15-8 | bits 7-0 |
+ | Unused | latency - Chan. 1 | channel no.|
+ +**********************************************+
+ */
+
+ /* Get the operating channel of the designated vdev */
+ first_adapter_operating_channel =
+ hdd_get_operating_channel
+ (
+ pHostapdAdapter->pHddCtx,
+ pHostapdAdapter->device_mode
+ );
+ /* Move the time latency for the adapter to bits 15-8 */
+ set_value = set_value << 8;
+ /* Store the channel number at bits 7-0 of the bit vector
+ * as per the bit format above.
+ */
+ set_value = set_value | first_adapter_operating_channel;
+ /* Send command to WMA */
+ ret = process_wma_set_command
+ (
+ (int)pHostapdAdapter->sessionId,
+ (int)WMA_VDEV_MCC_SET_TIME_LATENCY,
+ set_value, VDEV_CMD
+ );
+ }
+ else
+ {
+ hddLog(LOG1, "%s: MCC is not active. Exit w/o setting"
+ " latency", __func__);
+ }
+ break;
+ }
+
+ case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
+ {
+ v_U8_t first_adapter_operating_channel = 0;
+ v_U8_t second_adapter_opertaing_channel = 0;
+ tVOS_CONCURRENCY_MODE concurrent_state = 0;
+ hdd_adapter_t *staAdapter = NULL;
+ int ret = 0; /* success */
+
+ hddLog(LOG1, "%s: iwpriv cmd to set MCC quota value %dms",
+ __func__, set_value);
+ /**
+ * Check if concurrency mode is active.
+ * Need to modify this code to support MCC modes other than
+ * STA/P2P GO
+ */
+ concurrent_state = hdd_get_concurrency_mode();
+ if (concurrent_state == (VOS_STA | VOS_P2P_GO))
+ {
+ hddLog(LOG1, "%s: STA & P2P are both enabled", __func__);
+ /**
+ * The channel numbers for both adapters and the time
+ * quota for the 1st adapter, i.e., one specified in cmd
+ * are formatted as a bit vector then passed on to WMA
+ +************************************************+
+ |bit 31-24 |bit 23-16 | bits 15-8 |bits 7-0 |
+ | Unused | Quota for| chan. # for |chan. # for|
+ | | 1st chan.| 1st chan. |2nd chan. |
+ +************************************************+
+ */
+
+ /* Get the operating channel of the specified vdev */
+ first_adapter_operating_channel =
+ hdd_get_operating_channel
+ (
+ pHostapdAdapter->pHddCtx,
+ pHostapdAdapter->device_mode
+ );
+ hddLog(LOG1, "%s: 1st channel No.:%d and quota:%dms",
+ __func__, first_adapter_operating_channel,
+ set_value);
+ /* Move the time quota for first adapter to bits 15-8 */
+ set_value = set_value << 8;
+ /** Store the operating channel number of 1st adapter at
+ * the lower 8-bits of bit vector.
+ */
+ set_value = set_value | first_adapter_operating_channel;
+ if (pHostapdAdapter->device_mode ==
+ WLAN_HDD_INFRA_STATION)
+ {
+ /* iwpriv cmd issued on wlan0; get p2p0 vdev chan. */
+ if ((concurrent_state & VOS_P2P_CLIENT) != 0)
+ {
+ /* The 2nd MCC vdev is P2P client */
+ staAdapter = hdd_get_adapter
+ (
+ pHostapdAdapter->pHddCtx,
+ WLAN_HDD_P2P_CLIENT
+ );
+ } else
+ {
+ /* The 2nd MCC vdev is P2P GO */
+ staAdapter = hdd_get_adapter
+ (
+ pHostapdAdapter->pHddCtx,
+ WLAN_HDD_P2P_GO
+ );
+ }
+ }
+ else
+ {
+ /* iwpriv cmd issued on p2p0; get channel for wlan0 */
+ staAdapter = hdd_get_adapter
+ (
+ pHostapdAdapter->pHddCtx,
+ WLAN_HDD_INFRA_STATION
+ );
+ }
+ if (staAdapter != NULL)
+ {
+ second_adapter_opertaing_channel =
+ hdd_get_operating_channel
+ (
+ staAdapter->pHddCtx,
+ staAdapter->device_mode
+ );
+ hddLog(LOG1, "%s: 2nd vdev channel No. is:%d",
+ __func__, second_adapter_opertaing_channel);
+ /* Move the time quota and operating channel number
+ * for the first adapter to bits 23-16 & bits 15-8
+ * of set_value vector, respectively.
+ */
+ set_value = set_value << 8;
+ /* Store the channel number for 2nd MCC vdev at bits
+ * 7-0 of set_value vector as per the bit format above.
+ */
+ set_value = set_value |
+ second_adapter_opertaing_channel;
+ ret = process_wma_set_command
+ (
+ (int)pHostapdAdapter->sessionId,
+ (int)WMA_VDEV_MCC_SET_TIME_QUOTA,
+ set_value,
+ VDEV_CMD
+ );
+ }
+ else
+ {
+ hddLog(LOGE, "%s: NULL adapter handle. Exit",
+ __func__);
+ }
+ }
+ else
+ {
+ hddLog(LOG1, "%s: MCC is not active. "
+ "Exit w/o setting latency", __func__);
+ }
+ break;
+ }
+
#endif /* QCA_WIFI_2_0 */
default:
hddLog(LOGE, FL("Invalid setparam command %d value %d"),
@@ -3241,6 +3415,10 @@ static const struct iw_priv_args hostapd_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
{ QCSAP_PARAM_SET_TXRX_FW_STATS,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txrx_fw_stats" },
+ { QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMccLatency" },
+ { QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMccQuota" },
#ifdef QCA_WIFI_2_0
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 3cf8d9afa968..4e75c9206a82 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -221,6 +221,9 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WE_SET_GTX_STEP 67
#define WE_SET_GTX_MINTPC 68
#define WE_SET_GTX_BWMASK 69
+/* Private ioctl to configure MCC home channels time quota and latency */
+#define WE_MCC_CONFIG_LATENCY 70
+#define WE_MCC_CONFIG_QUOTA 71
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -5298,6 +5301,156 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
break;
}
+ case WE_MCC_CONFIG_LATENCY:
+ {
+ tVOS_CONCURRENCY_MODE concurrent_state = 0;
+ v_U8_t first_adapter_operating_channel = 0;
+ int ret = 0; /* success */
+
+ hddLog(LOG1, "iwpriv cmd to set MCC latency with val %dms",
+ set_value);
+ /**
+ * Check if concurrency mode is active.
+ * Need to modify this code to support MCC modes other than STA/P2P
+ */
+ concurrent_state = hdd_get_concurrency_mode();
+ if ((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
+ (concurrent_state == (VOS_STA | VOS_P2P_GO)))
+ {
+ hddLog(LOG1, "STA & P2P are both enabled");
+ /**
+ * The channel number and latency are formatted in
+ * a bit vector then passed on to WMA layer.
+ +**********************************************+
+ |bits 31-16 | bits 15-8 | bits 7-0 |
+ | Unused | latency - Chan. 1 | channel no. |
+ +**********************************************+
+ */
+ /* Get the operating channel of the designated vdev */
+ first_adapter_operating_channel =
+ hdd_get_operating_channel
+ (
+ pAdapter->pHddCtx,
+ pAdapter->device_mode
+ );
+ /* Move the time latency for the adapter to bits 15-8 */
+ set_value = set_value << 8;
+ /* Store the channel number at bits 7-0 of the bit vector */
+ set_value = set_value | first_adapter_operating_channel;
+ /* Send command to WMA */
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMA_VDEV_MCC_SET_TIME_LATENCY,
+ set_value, VDEV_CMD);
+ }
+ else
+ {
+ hddLog(LOG1, "#s: MCC is not active. Exit w/o setting latency",
+ __func__);
+ }
+ break;
+ }
+
+ case WE_MCC_CONFIG_QUOTA:
+ {
+ v_U8_t first_adapter_operating_channel = 0;
+ v_U8_t second_adapter_opertaing_channel = 0;
+ hdd_adapter_t *staAdapter = NULL;
+ int ret = 0; /* success */
+
+ tVOS_CONCURRENCY_MODE concurrent_state = hdd_get_concurrency_mode();
+ hddLog(LOG1, "iwpriv cmd to set MCC quota with val %dms",
+ set_value);
+ /**
+ * Check if concurrency mode is active.
+ * Need to modify this code to support MCC modes other than STA/P2P
+ */
+ if ((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
+ (concurrent_state == (VOS_STA | VOS_P2P_GO)))
+ {
+ hddLog(LOG1, "STA & P2P are both enabled");
+ /**
+ * The channel numbers for both adapters and the time
+ * quota for the 1st adapter, i.e., one specified in cmd
+ * are formatted as a bit vector then passed on to WMA
+ +************************************************************+
+ |bit 31-24 | bit 23-16 | bits 15-8 | bits 7-0 |
+ | Unused | Quota for | chan. # for | chan. # for |
+ | | 1st chan. | 1st chan. | 2nd chan. |
+ +************************************************************+
+ */
+ /* Get the operating channel of the specified vdev */
+ first_adapter_operating_channel =
+ hdd_get_operating_channel
+ (
+ pAdapter->pHddCtx,
+ pAdapter->device_mode
+ );
+ hddLog(LOG1, "1st channel No.:%d and quota:%dms",
+ first_adapter_operating_channel, set_value);
+ /* Move the time quota for first channel to bits 15-8 */
+ set_value = set_value << 8;
+ /** Store the channel number of 1st channel at bits 7-0
+ * of the bit vector
+ */
+ set_value = set_value | first_adapter_operating_channel;
+ /* Find out the 2nd MCC adapter and its operating channel */
+ if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
+ {
+ /* iwpriv cmd was issued on wlan0; get p2p0 vdev channel */
+ if ((concurrent_state & VOS_P2P_CLIENT) != 0)
+ {
+ /* The 2nd MCC vdev is P2P client */
+ staAdapter = hdd_get_adapter(pAdapter->pHddCtx,
+ WLAN_HDD_P2P_CLIENT);
+ } else
+ {
+ /* The 2nd MCC vdev is P2P GO */
+ staAdapter = hdd_get_adapter(pAdapter->pHddCtx,
+ WLAN_HDD_P2P_GO);
+ }
+ }
+ else
+ {
+ /* iwpriv cmd was issued on p2p0; get wlan0 vdev channel */
+ staAdapter = hdd_get_adapter(pAdapter->pHddCtx,
+ WLAN_HDD_INFRA_STATION);
+ }
+ if (staAdapter != NULL)
+ {
+ second_adapter_opertaing_channel =
+ hdd_get_operating_channel
+ (
+ staAdapter->pHddCtx,
+ staAdapter->device_mode
+ );
+ hddLog(LOG1, "2nd vdev channel No. is:%d",
+ second_adapter_opertaing_channel);
+ /** Now move the time quota and channel number of the
+ * 1st adapter to bits 23-16 and bits 15-8 of the bit
+ * vector, respectively.
+ */
+ set_value = set_value << 8;
+ /* Store the channel number for 2nd MCC vdev at bits
+ * 7-0 of set_value
+ */
+ set_value = set_value | second_adapter_opertaing_channel;
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMA_VDEV_MCC_SET_TIME_QUOTA,
+ set_value, VDEV_CMD);
+ }
+ else
+ {
+ hddLog(LOGE, "NULL adapter handle. Exit");
+ }
+ }
+ else
+ {
+ hddLog(LOG1, "#s: MCC is not active. Exit w/o setting latency",
+ __func__);
+ }
+ break;
+ }
+
#endif
default:
{
@@ -9491,6 +9644,15 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "set_qnodatapoll" },
+ /* handlers for MCC time quota and latency sub ioctls */
+ { WE_MCC_CONFIG_LATENCY,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "setMccLatency" },
+
+ { WE_MCC_CONFIG_QUOTA,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "setMccQuota" },
+
#endif
{ WLAN_PRIV_SET_NONE_GET_INT,
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 6454f6a6cdaf..5173e7836962 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -81,6 +81,7 @@
#include "wlan_qct_wda.h"
#include "wlan_qct_wda_msg.h"
#include "limApi.h"
+#include "limSessionUtils.h"
#include "wdi_out.h"
#include "wdi_in.h"
@@ -149,6 +150,10 @@
#define WMI_DEFAULT_NOISE_FLOOR_DBM (-96)
+#define WMI_MCC_MIN_CHANNEL_QUOTA 20
+#define WMI_MCC_MAX_CHANNEL_QUOTA 80
+#define WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY 30
+
static void wma_send_msg(tp_wma_handle wma_handle, u_int16_t msg_type,
void *body_ptr, u_int32_t body_val);
@@ -2884,6 +2889,268 @@ static VOS_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(tANI_U32 mcc_ada
return VOS_STATUS_SUCCESS;
}
+/**
+ * Currently used to set time latency for an MCC vdev/adapter using operating
+ * channel of it and channel number. The info is provided run time using
+ * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>.
+ */
+static VOS_STATUS wma_set_mcc_channel_time_latency
+ (
+ tp_wma_handle wma,
+ tANI_U32 mcc_channel,
+ tANI_U32 mcc_channel_time_latency
+ )
+{
+ int ret = -1;
+ wmi_buf_t buf = 0;
+ wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL;
+ u_int16_t len = 0;
+ u_int8_t *buf_ptr = NULL;
+ tANI_U32 cfg_val = 0;
+ wmi_resmgr_chan_latency chan_latency;
+ struct sAniSirGlobal *pMac = NULL;
+ /* Note: we only support MCC time latency for a single channel */
+ u_int32_t num_channels = 1;
+ u_int32_t channel1 = mcc_channel;
+ u_int32_t chan1_freq = vos_chan_to_freq( channel1 );
+ u_int32_t latency_chan1 = mcc_channel_time_latency;
+
+ if (!wma) {
+ WMA_LOGE("%s:NULL wma ptr. Exiting.\n", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+ pMac =
+ (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE,
+ wma->vos_context);
+ if (!pMac) {
+ WMA_LOGE("%s:NULL pMac ptr. Exiting.\n", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ /* First step is to confirm if MCC is active */
+ if (!limIsInMCC(pMac)) {
+ WMA_LOGE("%s: MCC is not active. Exiting.\n", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+ /* Confirm MCC adaptive scheduler feature is disabled */
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+ &cfg_val) == eSIR_SUCCESS) {
+ if (cfg_val == WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX) {
+ WMA_LOGD("%s: Can't set channel latency while MCC "
+ "ADAPTIVE SCHED is enabled. Exit\n", __func__);
+ return VOS_STATUS_SUCCESS;
+ }
+ } else {
+ WMA_LOGE("%s: Failed to get value for MCC_ADAPTIVE_SCHED, "
+ "Exit w/o setting latency.\n", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+ /* If 0ms latency is provided, then FW will set to a default.
+ * Otherwise, latency must be at least 30ms.
+ */
+ if ((latency_chan1 > 0) &&
+ (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) {
+ WMA_LOGE("%s: Invalid time latency for Channel #1 = %dms. "
+ "Minimum is 30ms (or 0 to use default value by "
+ "firmware)\n", __func__, latency_chan1);
+ return VOS_STATUS_E_INVAL;
+ }
+
+ /* Set WMI CMD for channel time latency here */
+ len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) +
+ WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array*/
+ num_channels * sizeof(wmi_resmgr_chan_latency);
+ buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+ return VOS_STATUS_E_NOMEM;
+ }
+ buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+ cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *)
+ wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmdTL->tlv_header,
+ WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_resmgr_set_chan_latency_cmd_fixed_param));
+ cmdTL->num_chans = num_channels;
+ /* Update channel time latency information for home channel(s) */
+ buf_ptr += sizeof(*cmdTL);
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+ num_channels * sizeof(wmi_resmgr_chan_latency));
+ buf_ptr += WMI_TLV_HDR_SIZE;
+ chan_latency.chan_mhz = chan1_freq;
+ chan_latency.latency = latency_chan1;
+ vos_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency));
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_RESMGR_SET_CHAN_LATENCY_CMDID);
+ if (ret) {
+ WMA_LOGE("%s: Failed to send MCC Channel Time Latency command",
+ __func__);
+ adf_nbuf_free(buf);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+ return VOS_STATUS_SUCCESS;
+}
+
+/**
+ * Currently used to set time quota for 2 MCC vdevs/adapters using (operating
+ * channel, quota) for each mode . The info is provided run time using
+ * iwpriv command: iwpriv <wlan0 | p2p0> setMccQuota <quota in ms>.
+ * Note: the quota provided in command is for the same mode in cmd. HDD
+ * checks if MCC mode is active, gets the second mode and its operating chan.
+ * Quota for the 2nd role is calculated as 100 - quota of first mode.
+ */
+static VOS_STATUS wma_set_mcc_channel_time_quota
+ (
+ tp_wma_handle wma,
+ tANI_U32 adapter_1_chan_number,
+ tANI_U32 adapter_1_quota,
+ tANI_U32 adapter_2_chan_number
+ )
+{
+ int ret = -1;
+ wmi_buf_t buf = 0;
+ u_int16_t len = 0;
+ u_int8_t *buf_ptr = NULL;
+ tANI_U32 cfg_val = 0;
+ struct sAniSirGlobal *pMac = NULL;
+ wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL;
+ wmi_resmgr_chan_time_quota chan_quota;
+ u_int32_t channel1 = adapter_1_chan_number;
+ u_int32_t channel2 = adapter_2_chan_number;
+ u_int32_t quota_chan1 = adapter_1_quota;
+ /* Knowing quota of 1st chan., derive quota for 2nd chan. */
+ u_int32_t quota_chan2 = 100 - quota_chan1;
+ /* Note: setting time quota for MCC requires info for 2 channels */
+ u_int32_t num_channels = 2;
+ u_int32_t chan1_freq = vos_chan_to_freq(adapter_1_chan_number);
+ u_int32_t chan2_freq = vos_chan_to_freq(adapter_2_chan_number);
+
+ WMA_LOGD("%s: Channel1:%d, freq1:%dMHz, Quota1:%dms, "
+ "Channel2:%d, freq2:%dMHz, Quota2:%dms\n", __func__,
+ channel1, chan1_freq, quota_chan1, channel2, chan2_freq,
+ quota_chan2);
+
+ if (!wma) {
+ WMA_LOGE("%s:NULL wma ptr. Exiting.\n", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+ pMac =
+ (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE,
+ wma->vos_context);
+ if (!pMac) {
+ WMA_LOGE("%s:NULL pMac ptr. Exiting.\n", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ /* First step is to confirm if MCC is active */
+ if (!limIsInMCC(pMac)) {
+ WMA_LOGD("%s: MCC is not active. Exiting.\n", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ /* Confirm MCC adaptive scheduler feature is disabled */
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+ &cfg_val) == eSIR_SUCCESS) {
+ if (cfg_val == WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX) {
+ WMA_LOGD("%s: Can't set channel quota while "
+ "MCC_ADAPTIVE_SCHED is enabled. Exit\n",
+ __func__);
+ return VOS_STATUS_SUCCESS;
+ }
+ } else {
+ WMA_LOGE("%s: Failed to retrieve "
+ "WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED. Exit\n",
+ __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ /**
+ * Perform sanity check on time quota values provided.
+ */
+ if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA ||
+ quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) {
+ WMA_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum "
+ "is 20ms & maximum is 80ms\n", __func__, quota_chan1);
+ return VOS_STATUS_E_INVAL;
+ }
+ /* Set WMI CMD for channel time quota here */
+ len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) +
+ WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */
+ num_channels * sizeof(wmi_resmgr_chan_time_quota);
+ buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_NOMEM;
+ }
+ buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+ cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *)
+ wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmdTQ->tlv_header,
+ WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_resmgr_set_chan_time_quota_cmd_fixed_param));
+ cmdTQ->num_chans = num_channels;
+
+ /* Update channel time quota information for home channel(s) */
+ buf_ptr += sizeof(*cmdTQ);
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+ num_channels * sizeof(wmi_resmgr_chan_time_quota));
+ buf_ptr += WMI_TLV_HDR_SIZE;
+ chan_quota.chan_mhz = chan1_freq;
+ chan_quota.channel_time_quota = quota_chan1;
+ vos_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
+ /* Construct channel and quota record for the 2nd MCC mode. */
+ buf_ptr += sizeof(chan_quota);
+ chan_quota.chan_mhz = chan2_freq;
+ chan_quota.channel_time_quota = quota_chan2;
+ vos_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota));
+
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID);
+ if (ret) {
+ WMA_LOGE("Failed to send MCC Channel Time Quota command");
+ adf_nbuf_free(buf);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_FAILURE;
+ }
+ return VOS_STATUS_SUCCESS;
+}
+
+static v_BOOL_t wma_set_enable_disable_roam_scan_offload(tp_wma_handle wma_handle,
+ bool cfg_roam_offload_enabled)
+{
+ if (wma_handle->roam_offload_enabled && !cfg_roam_offload_enabled) {
+ /* User changed it from enable to disable */
+ if (wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, wma_handle->roam_offload_vdev_id,
+ WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 0)) {
+ /* could not disable roam offload in firmware. Disable it for host. */
+ WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD = 0");
+ }
+ wma_handle->roam_offload_enabled = FALSE;
+ } else if (!wma_handle->roam_offload_enabled && cfg_roam_offload_enabled) {
+ /* User changed it from disable to enable */
+ if (wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, wma_handle->roam_offload_vdev_id,
+ WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 1)) {
+ /* could not enable roam offload in firmware. Disable it for host. */
+ WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD = 1");
+ } else {
+ wma_handle->roam_offload_enabled = TRUE;
+ }
+ }
+
+ return (wma_handle->roam_offload_enabled);
+}
/* function : wma_vdev_attach
* Descriptin :
* Args :
@@ -5802,6 +6069,49 @@ static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle,
wma_set_smps_params(wma_handle, privcmd->param_vdev_id,
privcmd->param_value);
break;
+ case WMA_VDEV_MCC_SET_TIME_LATENCY:
+ {
+ /* Extract first MCC adapter/vdev channel number and latency */
+ tANI_U8 mcc_channel = privcmd->param_value & 0x000000FF;
+ tANI_U8 mcc_channel_latency =
+ (privcmd->param_value & 0x0000FF00) >> 8;
+ int ret = -1;
+ WMA_LOGD("%s: Parsed input: Channel #1:%d, latency:%dms\n",
+ __func__, mcc_channel, mcc_channel_latency);
+ ret = wma_set_mcc_channel_time_latency
+ (
+ wma_handle,
+ mcc_channel,
+ mcc_channel_latency
+ );
+ }
+ break;
+ case WMA_VDEV_MCC_SET_TIME_QUOTA:
+ {
+ /** Extract the MCC 2 adapters/vdevs channel numbers and time
+ * quota value for the first adapter only (which is specified
+ * in iwpriv command.
+ */
+ tANI_U8 adapter_2_chan_number =
+ privcmd->param_value & 0x000000FF;
+ tANI_U8 adapter_1_chan_number =
+ (privcmd->param_value & 0x0000FF00) >> 8;
+ tANI_U8 adapter_1_quota =
+ (privcmd->param_value & 0x00FF0000) >> 16;
+ int ret = -1;
+
+ WMA_LOGD("%s: Parsed input: Channel #1:%d, Channel #2:%d,"
+ "quota 1:%dms\n", __func__, adapter_1_chan_number,
+ adapter_2_chan_number, adapter_1_quota);
+ ret = wma_set_mcc_channel_time_quota
+ (
+ wma_handle,
+ adapter_1_chan_number,
+ adapter_1_quota,
+ adapter_2_chan_number
+ );
+ }
+ break;
default:
WMA_LOGE("Invalid wma config command id:%d",
privcmd->param_id);
diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h
index 599950a580ad..f5b8afad042b 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -1179,6 +1179,9 @@ typedef struct {
enum wma_cfg_cmd_id {
WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID = WMI_CMDID_MAX,
WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
+ /* Set time latency and time quota for MCC home channels */
+ WMA_VDEV_MCC_SET_TIME_LATENCY,
+ WMA_VDEV_MCC_SET_TIME_QUOTA,
/* Add any new command before this */
WMA_CMD_ID_MAX
};
diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini
index cf861ec524d0..f055b00bc261 100644
--- a/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/firmware_bin/WCNSS_qcom_cfg.ini
@@ -487,7 +487,7 @@ gVhtMpduLen=2
# Enable or Disable MCC Adaptive Scheduler at the FW
# 1=Enable (default), 0=Disable
-gEnableMCCAdaptiveScheduler=0
+gEnableMCCAdaptiveScheduler=1
#Enable or Disable p2p device address administered
isP2pDeviceAddrAdministrated=0