diff options
| author | Mohit Khanna <mkhanna@qca.qualcomm.com> | 2015-10-14 20:21:05 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2015-10-21 00:24:47 -0700 |
| commit | 80f4dc4c08b001ff9180a18cd4ceeb4dbf1cc6bd (patch) | |
| tree | 91c07556f6c4a3963f9c0018bb01c5c9217bf41c | |
| parent | b34e0e2ac99060c00b64daf183b4210b3d0d6b83 (diff) | |
qcacld-2.0: allow rps cpu map to be read from ini
- Currently wlan driver only sends WLAN_SVC_RPS_ENABLE_IND message along
with the interface name to cnss-daemon. This change allows wlan driver
to send rps cpu mask from the ini file (for each rx queue) to be sent
along with this message.
- Enable RPS mask as "e e e e" by default in WLAN ini file.
Change-Id: I869d4dd70533eefbff03ed97976700d4e0e75c1d
CRs-Fixed: 919192
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_cfg.h | 46 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg.c | 54 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_dp_utils.c | 41 | ||||
| -rw-r--r-- | CORE/SVC/external/wlan_nlink_common.h | 31 | ||||
| -rwxr-xr-x | firmware_bin/WCNSS_qcom_cfg.ini | 6 |
5 files changed, 171 insertions, 7 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index 41dabfd6cf15..c61bb22f3432 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -2532,6 +2532,47 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ #define CFG_RX_HANDLE_DEFAULT (WLAN_HDD_RX_HANDLE_RX_THREAD) #endif /* MDM_PLATFORM */ +/* List of RPS CPU maps for different rx queues registered by WLAN driver + * Ref - Kernel/Documentation/networking/scaling.txt + * RPS CPU map for a particular RX queue, selects CPU(s) for bottom half + * processing of RX packets. For example, for a system with 4 CPUs, + * 0xe: Use CPU1 - CPU3 and donot use CPU0. + * 0x0: RPS is disabled, packets are processed on the interrupting CPU. +.* + * WLAN driver registers NUM_TX_QUEUES queues for tx and rx each during + * alloc_netdev_mq. Hence, we need to have a cpu mask for each of the rx queues. + * + * For example, if the NUM_TX_QUEUES is 4, a sample WLAN ini entry may look like + * rpsRxQueueCpuMapList=a b c d + * For a 4 CPU system (CPU0 - CPU3), this implies: + * 0xa - (1010) use CPU1, CPU3 for rx queue 0 + * 0xb - (1011) use CPU0, CPU1 and CPU3 for rx queue 1 + * 0xc - (1100) use CPU2, CPU3 for rx queue 2 + * 0xd - (1101) use CPU0, CPU2 and CPU3 for rx queue 3 + + * In practice, we may want to avoid the cores which are heavily loaded. + */ + +/* Name of the ini file entry to specify RPS map for different RX queus */ +#define CFG_RPS_RX_QUEUE_CPU_MAP_LIST_NAME "rpsRxQueueCpuMapList" + +/* Default value of rpsRxQueueCpuMapList. Different platforms may have + * different configurations for NUM_TX_QUEUES and # of cpus, and will need to + * configure an appropriate value via ini file. Setting default value to 'e' to + * avoid use of CPU0 (since its heavily used by other system processes) by rx + * queue 0, which is currently being used for rx packet processing. + */ +#define CFG_RPS_RX_QUEUE_CPU_MAP_LIST_DEFAULT "e" + +/* Maximum length of string used to hold a list of cpu maps for various rx + * queues. Considering a 16 core system with 5 rx queues, a RPS CPU map + * list may look like - + * rpsRxQueueCpuMapList = ffff ffff ffff ffff ffff + * (all 5 rx queues can be processed on all 16 cores) + * max string len = 24 + 1(for '\0'). Considering 30 to be on safe side. + */ +#define CFG_RPS_RX_QUEUE_CPU_MAP_LIST_LEN 30 + /* SAR Thermal limit values for 2g and 5g */ #define CFG_SET_TXPOWER_LIMIT2G_NAME "TxPower2g" @@ -3762,6 +3803,7 @@ typedef struct v_U32_t TxPower5g; v_U32_t gEnableDebugLog; v_U8_t rxhandle; + uint8_t cpu_map_list[CFG_RPS_RX_QUEUE_CPU_MAP_LIST_LEN]; v_BOOL_t fDfsPhyerrFilterOffload; v_U8_t gSapPreferredChanLocation; v_U8_t gDisableDfsJapanW53; @@ -4098,6 +4140,10 @@ VOS_STATUS hdd_string_to_u8_array( char *str, tANI_U8 *intArray, tANI_U8 *len, VOS_STATUS hdd_hex_string_to_u8_array(char *str, uint8_t *array, uint8_t *len, uint8_t array_max_len); +VOS_STATUS hdd_hex_string_to_u16_array(char *str, + uint16_t *int_array, uint8_t *len, uint8_t int_array_max_len); + + #ifdef MDNS_OFFLOAD VOS_STATUS hdd_string_to_string_array(char *data, uint8_t *datalist, char separator, uint8_t *num_entries, diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index 4dd0157b8777..3073955e9066 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -3245,6 +3245,12 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_RX_HANDLE_DEFAULT, CFG_RX_HANDLE_MIN, CFG_RX_HANDLE_MAX), + + REG_VARIABLE_STRING( CFG_RPS_RX_QUEUE_CPU_MAP_LIST_NAME, WLAN_PARAM_String, + hdd_config_t, cpu_map_list, + VAR_FLAGS_OPTIONAL, + (void *)CFG_RPS_RX_QUEUE_CPU_MAP_LIST_DEFAULT ), + REG_VARIABLE( CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME, WLAN_PARAM_Integer, hdd_config_t, fDfsPhyerrFilterOffload, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -5644,6 +5650,54 @@ VOS_STATUS hdd_string_to_u8_array(char *str, uint8_t *array, array_max_len, false); } +/** + * hdd_hex_string_to_u16_array() - convert a hex string to a uint16 array + * @str: input string + * @int_array: pointer to input array of type uint16 + * @len: pointer to number of elements which the function adds to the array + * @int_array_max_len: maximum number of elements in input uint16 array + * + * This function is used to convert a space separated hex string to an array of + * uint16_t. For example, an input string str = "a b c d" would be converted to + * a unint16 array, int_array = {0xa, 0xb, 0xc, 0xd}, *len = 4. + * This assumes that input value int_array_max_len >= 4. + * + * Return: VOS_STATUS_SUCCESS - if the conversion is successful + * non zero value - if the conversion is a failure + */ +VOS_STATUS hdd_hex_string_to_u16_array(char *str, + uint16_t *int_array, uint8_t *len, uint8_t int_array_max_len) +{ + char *s = str; + int val = 0; + if (str == NULL || int_array == NULL || len == NULL) + return VOS_STATUS_E_INVAL; + + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("str %p intArray %p intArrayMaxLen %d"), + s, int_array, int_array_max_len); + + *len = 0; + + while ((s != NULL) && (*len < int_array_max_len)) { + /* + * Increment length only if sscanf successfully extracted one + * element. Any other return value means error. Ignore it. + */ + if (sscanf(s, "%x", &val) == 1) { + int_array[*len] = (uint16_t) val; + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("s %p val %x intArray[%d]=0x%x"), + s, val, *len, int_array[*len]); + *len += 1; + } + s = strpbrk(s, " "); + if (s) + s++; + } + return VOS_STATUS_SUCCESS; +} + #ifdef MDNS_OFFLOAD VOS_STATUS hdd_string_to_string_array(char *data, uint8_t *datalist, char separator, uint8_t *num_entries, diff --git a/CORE/HDD/src/wlan_hdd_dp_utils.c b/CORE/HDD/src/wlan_hdd_dp_utils.c index 69cbf2a47617..16a153151295 100644 --- a/CORE/HDD/src/wlan_hdd_dp_utils.c +++ b/CORE/HDD/src/wlan_hdd_dp_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -40,6 +40,7 @@ ----------------------------------------------------------------------------*/ #include <wlan_hdd_dp_utils.h> #include <wlan_hdd_main.h> +#include <sirDebug.h> /**----------------------------------------------------------------------------- Preprocessor definitions and constants @@ -234,17 +235,49 @@ VOS_STATUS hdd_string_to_hex( char *pSrcMac, int length, char *pDescMac ) */ void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt) { + int i = 0; + uint8_t cpu_map_list_len = 0; hdd_adapter_t *adapter; hdd_adapter_list_node_t *adapter_node, *next; VOS_STATUS status = VOS_STATUS_SUCCESS; + struct wlan_rps_data rps_data; + + rps_data.num_queues = NUM_TX_QUEUES; + + hddLog(LOG1, FL("cpu_map_list '%s'"), hdd_ctxt->cfg_ini->cpu_map_list); + + /* in case no cpu map list is provided, simply return */ + if (!strlen(hdd_ctxt->cfg_ini->cpu_map_list)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("no cpu map list found")); + return; + } + + if (VOS_STATUS_SUCCESS != + hdd_hex_string_to_u16_array(hdd_ctxt->cfg_ini->cpu_map_list, + rps_data.cpu_map_list, + &cpu_map_list_len, + WLAN_SVC_IFACE_NUM_QUEUES)) { + return; + } + + rps_data.num_queues = + (cpu_map_list_len < rps_data.num_queues) ? + cpu_map_list_len : rps_data.num_queues; + + for (i = 0; i < rps_data.num_queues; i++) { + hddLog(LOG1, FL("cpu_map_list[%d] = 0x%x"), + i, rps_data.cpu_map_list[i]); + } status = hdd_get_front_adapter (hdd_ctxt, &adapter_node); while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) { adapter = adapter_node->pAdapter; - if (NULL != adapter) + if (NULL != adapter) { + strlcpy(rps_data.ifname, adapter->dev->name, + sizeof(rps_data.ifname)); wlan_hdd_send_svc_nlink_msg(WLAN_SVC_RPS_ENABLE_IND, - (void *)adapter->dev->name, - strlen(adapter->dev->name)); + &rps_data, sizeof(rps_data)); + } status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next); adapter_node = next; } diff --git a/CORE/SVC/external/wlan_nlink_common.h b/CORE/SVC/external/wlan_nlink_common.h index 6c1bd32aa9c7..8bf9f87e3b10 100644 --- a/CORE/SVC/external/wlan_nlink_common.h +++ b/CORE/SVC/external/wlan_nlink_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -38,7 +38,9 @@ #define WLAN_NLINK_COMMON_H__ #include <linux/netlink.h> - +#ifdef QCA_FEATURE_RPS +#include <linux/if.h> +#endif /*--------------------------------------------------------------------------- * External Functions *-------------------------------------------------------------------------*/ @@ -103,6 +105,12 @@ #define WLAN_SVC_MAX_NUM_CHAN 128 #define WLAN_SVC_COUNTRY_CODE_LEN 3 +/* + * Maximim number of queues supported by WLAN driver. Setting an upper + * limit. Actual number of queues may be smaller than this value. + */ +#define WLAN_SVC_IFACE_NUM_QUEUES 6 + // Event data for WLAN_BTC_QUERY_STATE_RSP & WLAN_STA_ASSOC_DONE_IND typedef struct { @@ -155,6 +163,25 @@ struct wlan_version_data { char fw_version[WLAN_SVC_MAX_STR_LEN]; }; +#ifdef QCA_FEATURE_RPS +/** + * struct wlan_rps_data - structure to send RPS info to cnss-daemon + * @ifname: interface name for which the RPS data belongs to + * @num_queues: number of rx queues for which RPS data is being sent + * @cpu_map_list: array of cpu maps for different rx queues supported by + * the wlan driver + * + * The structure specifies the format of data exchanged between wlan + * driver and cnss-daemon. On receipt of the data, cnss-daemon is expected + * to apply the 'cpu_map' for each rx queue belonging to the interface 'ifname' + */ +struct wlan_rps_data { + char ifname[IFNAMSIZ]; + uint16_t num_queues; + uint16_t cpu_map_list[WLAN_SVC_IFACE_NUM_QUEUES]; +}; +#endif + struct wlan_dfs_info { uint16_t channel; uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN]; diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini index f8686eeaf31a..78f539463b24 100755 --- a/firmware_bin/WCNSS_qcom_cfg.ini +++ b/firmware_bin/WCNSS_qcom_cfg.ini @@ -499,7 +499,11 @@ isP2pDeviceAddrAdministrated=1 # 0: no rx thread, no RPS, for MDM # 1: RX thread # 2: RPS -rxhandle=1 +rxhandle=2 + +# Set RPS CPU MAP as 0xe for the 4 RX queues +# This allows use of CPU1-CPU3 but not CPU0 for 4 RX queues +rpsRxQueueCpuMapList=e e e e # Set Thermal Power limit TxPower2g=10 |
