diff options
| author | Ahmad Kholaif <akholaif@qca.qualcomm.com> | 2014-01-13 21:21:42 -0800 |
|---|---|---|
| committer | Prakash Dhavali <pdhavali@qca.qualcomm.com> | 2014-01-26 20:06:35 -0800 |
| commit | ca654f3381b2fc81a2e217817d49324a66cbe506 (patch) | |
| tree | 6accc2da710dbb8c48ae8fba6c6d0f1ff9a106fc | |
| parent | 96f3f60dad5650d21ffab346362022446098f561 (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.h | 2 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_hostapd.c | 178 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wext.c | 162 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 310 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.h | 3 | ||||
| -rw-r--r-- | firmware_bin/WCNSS_qcom_cfg.ini | 2 |
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 |
