qcacld-3.0: Changes to support different rx data path

Changes to configure different rx data path rx_thread,
RPS or NAPI through ini parameters. Also added support
for RPS mask setting using cnss-daemon.

CRs-fixed: 1026370
Change-Id: I23ab8fe0f05245b38cf4b37e93da8fd99d4c1f68
This commit is contained in:
Nirav Shah
2016-07-18 11:12:59 +05:30
committed by qcabuildsw
parent aedea909b4
commit bd36b0690b
11 changed files with 282 additions and 43 deletions

View File

@@ -307,7 +307,6 @@ QDF_STATUS cds_open(void)
}
/*Open the WMA module */
qdf_status = wma_open(gp_cds_context,
hdd_update_tgt_cfg,
hdd_dfs_indicate_radar, cds_cfg);

View File

@@ -48,6 +48,10 @@
#define FW_MODULE_LOG_LEVEL_STRING_LENGTH (255)
#define CFG_ENABLE_RX_THREAD (1 << 0)
#define CFG_ENABLE_RPS (1 << 1)
#define CFG_ENABLE_NAPI (1 << 2)
#ifdef DHCP_SERVER_OFFLOAD
#define IPADDR_NUM_ENTRIES (4)
#define IPADDR_STRING_LENGTH (16)
@@ -2318,12 +2322,6 @@ typedef enum {
#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX (0xFF)
#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0x0F)
/* This will be used only for debugging purpose, will be removed after sometime */
#define CFG_ENABLE_RX_THREAD "gEnableRxThread"
#define CFG_ENABLE_RX_THREAD_MIN (0)
#define CFG_ENABLE_RX_THREAD_MAX (1)
#define CFG_ENABLE_RX_THREAD_DEFAULT (1)
/* SAR Thermal limit values for 2g and 5g */
#define CFG_SET_TXPOWER_LIMIT2G_NAME "TxPower2g"
@@ -2915,11 +2913,6 @@ enum dot11p_mode {
#define CFG_DOT11P_MODE_MIN (WLAN_HDD_11P_DISABLED)
#define CFG_DOT11P_MODE_MAX (WLAN_HDD_11P_CONCURRENT)
#define CFG_NAPI_NAME "gEnableNAPI"
#define CFG_NAPI_MIN (0)
#define CFG_NAPI_MAX (1)
#define CFG_NAPI_DEFAULT (0)
#ifdef FEATURE_WLAN_EXTSCAN
#define CFG_EXTSCAN_PASSIVE_MAX_CHANNEL_TIME_NAME "gExtScanPassiveMaxChannelTime"
#define CFG_EXTSCAN_PASSIVE_MAX_CHANNEL_TIME_MIN (0)
@@ -3408,6 +3401,66 @@ enum dot11p_mode {
#define CFG_SUB_20_CHANNEL_WIDTH_MIN (WLAN_SUB_20_CH_WIDTH_NONE)
#define CFG_SUB_20_CHANNEL_WIDTH_MAX (WLAN_SUB_20_CH_WIDTH_10)
#define CFG_SUB_20_CHANNEL_WIDTH_DEFAULT (WLAN_SUB_20_CH_WIDTH_NONE)
/*
* This parameter determines that which defered method will be use in rx path
* If no bits are set then rx path processing will happen in tasklet context.
* Bit 0: rx_thread enable
* Bit 1: RPS enable
* Bit 2: NAPI enable
*/
#define CFG_RX_MODE_NAME "rx_mode"
#define CFG_RX_MODE_MIN (0)
#define CFG_RX_MODE_MAX (CFG_ENABLE_RX_THREAD | CFG_ENABLE_RPS | \
CFG_ENABLE_NAPI)
#ifdef MDM_PLATFORM
#define CFG_RX_MODE_DEFAULT (0)
#else
#define CFG_RX_MODE_DEFAULT (CFG_ENABLE_RX_THREAD | CFG_ENABLE_NAPI)
#endif
/* 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
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -3847,7 +3900,6 @@ struct hdd_config {
uint32_t TxPower2g;
uint32_t TxPower5g;
uint32_t gEnableDebugLog;
uint8_t enableRxThread;
bool fDfsPhyerrFilterOffload;
uint8_t gSapPreferredChanLocation;
uint8_t gDisableDfsJapanW53;
@@ -3998,9 +4050,8 @@ struct hdd_config {
bool fastpath_enable;
#endif
uint8_t dot11p_mode;
#ifdef FEATURE_NAPI
bool napi_enable;
#endif
uint8_t rx_mode;
uint8_t cpu_map_list[CFG_RPS_RX_QUEUE_CPU_MAP_LIST_LEN];
#ifdef FEATURE_WLAN_EXTSCAN
uint32_t extscan_passive_max_chn_time;
uint32_t extscan_passive_min_chn_time;

View File

@@ -1462,6 +1462,9 @@ struct hdd_context_s {
qdf_mc_timer_t iface_change_timer;
/* Interface change lock */
struct mutex iface_change_lock;
bool rps;
bool enableRxThread;
bool napi_enable;
};
/*---------------------------------------------------------------------------

View File

@@ -113,4 +113,5 @@ const char *hdd_action_type_to_string(enum netif_action_type action);
void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
enum netif_action_type action, enum netif_reason_type reason);
int hdd_set_mon_rx_cb(struct net_device *dev);
void hdd_send_rps_ind(hdd_adapter_t *adapter);
#endif /* end #if !defined(WLAN_HDD_TX_RX_H) */

View File

@@ -2870,13 +2870,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN,
CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX),
REG_VARIABLE(CFG_ENABLE_RX_THREAD, WLAN_PARAM_Integer,
struct hdd_config, enableRxThread,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_ENABLE_RX_THREAD_DEFAULT,
CFG_ENABLE_RX_THREAD_MIN,
CFG_ENABLE_RX_THREAD_MAX),
REG_VARIABLE(CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME,
WLAN_PARAM_Integer,
struct hdd_config, fDfsPhyerrFilterOffload,
@@ -3568,15 +3561,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_DOT11P_MODE_MIN,
CFG_DOT11P_MODE_MAX),
#ifdef FEATURE_NAPI
REG_VARIABLE(CFG_NAPI_NAME, WLAN_PARAM_Integer,
struct hdd_config, napi_enable,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_NAPI_DEFAULT,
CFG_NAPI_MIN,
CFG_NAPI_MAX),
#endif /* FEATURE_NAPI */
#ifdef FEATURE_WLAN_EXTSCAN
REG_VARIABLE(CFG_EXTSCAN_PASSIVE_MAX_CHANNEL_TIME_NAME,
WLAN_PARAM_Integer,
@@ -3989,6 +3973,19 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ADAPT_DWELL_WIFI_THRESH_MIN,
CFG_ADAPT_DWELL_WIFI_THRESH_MAX),
REG_VARIABLE(CFG_RX_MODE_NAME, WLAN_PARAM_Integer,
struct hdd_config, rx_mode,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_RX_MODE_DEFAULT,
CFG_RX_MODE_MIN,
CFG_RX_MODE_MAX),
REG_VARIABLE_STRING(CFG_RPS_RX_QUEUE_CPU_MAP_LIST_NAME,
WLAN_PARAM_String,
struct hdd_config, cpu_map_list,
VAR_FLAGS_OPTIONAL,
(void *)CFG_RPS_RX_QUEUE_CPU_MAP_LIST_DEFAULT),
REG_VARIABLE(CFG_INTERFACE_CHANGE_WAIT_NAME, WLAN_PARAM_Integer,
struct hdd_config, iface_change_wait_time,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
@@ -5520,14 +5517,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
"Name = [max_scan_count] value = [%d]",
pHddCtx->config->max_scan_count);
#ifdef FEATURE_NAPI_DEBUG
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
"Name = [%s] value = [%d]",
CFG_ENABLE_RX_THREAD, pHddCtx->config->enableRxThread);
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
"Name = [%s] value = [%d]",
CFG_NAPI_NAME, pHddCtx->config->napi_enable);
#endif
CFG_RX_MODE_NAME, pHddCtx->config->rx_mode);
QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_HIGH,
"Name = [%s] Value = [%u]",
CFG_CE_CLASSIFY_ENABLE_NAME,
@@ -5845,6 +5837,30 @@ static void hdd_override_all_ps(hdd_context_t *hdd_ctx)
cfg_ini->wowEnable = 0;
}
/**
* hdd_set_rx_mode_value() - set rx_mode values
* @hdd_ctx: hdd context
*
* Return: none
*/
void hdd_set_rx_mode_value(hdd_context_t *hdd_ctx)
{
if (hdd_ctx->config->rx_mode & CFG_ENABLE_RX_THREAD &&
hdd_ctx->config->rx_mode & CFG_ENABLE_RPS) {
hdd_err("rx_mode wrong configuration. Make it default");
hdd_ctx->config->rx_mode = CFG_RX_MODE_DEFAULT;
}
if (hdd_ctx->config->rx_mode & CFG_ENABLE_RX_THREAD)
hdd_ctx->enableRxThread = true;
if (hdd_ctx->config->rx_mode & CFG_ENABLE_RPS)
hdd_ctx->rps = true;
if (hdd_ctx->config->rx_mode & CFG_ENABLE_NAPI)
hdd_ctx->napi_enable = true;
}
/**
* hdd_parse_config_ini() - parse the ini configuration file
* @pHddCtx: the pointer to hdd context
@@ -5943,10 +5959,11 @@ QDF_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx)
/* Loop through the registry table and apply all these configs */
qdf_status = hdd_apply_cfg_ini(pHddCtx, cfgIniTable, i);
hdd_set_rx_mode_value(pHddCtx);
#ifdef FEATURE_NAPI
if (QDF_STATUS_SUCCESS == qdf_status)
hdd_napi_event(NAPI_EVT_INI_FILE,
(void *)pHddCtx->config->napi_enable);
(void *)pHddCtx->napi_enable);
#endif /* FEATURE_NAPI */
if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
hdd_override_all_ps(pHddCtx);
@@ -6126,6 +6143,54 @@ QDF_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: QDF_STATUS_SUCCESS - if the conversion is successful
* non zero value - if the conversion is a failure
*/
QDF_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;
uint32_t val = 0;
if (str == NULL || int_array == NULL || len == NULL)
return QDF_STATUS_E_INVAL;
hdd_err("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;
hdd_debug("s %p val %x intArray[%d]=0x%x",
s, val, *len, int_array[*len]);
*len += 1;
}
s = strpbrk(s, " ");
if (s)
s++;
}
return QDF_STATUS_SUCCESS;
}
/**
* hdd_update_config_dat() - scan the string and convery to u8 array
* @str: the pointer to the string

View File

@@ -562,7 +562,7 @@ int hdd_lro_enable(hdd_context_t *hdd_ctx,
hdd_lro_desc_info_init(hdd_lro);
hdd_lro->lro_mgr->dev = adapter->dev;
if (hdd_ctx->config->enableRxThread)
if (hdd_ctx->enableRxThread)
hdd_lro->lro_mgr->features = LRO_F_NI;
if (hdd_napi_enabled(HDD_NAPI_ANY))

View File

@@ -199,6 +199,28 @@ struct sock *cesium_nl_srv_sock;
void wlan_hdd_auto_shutdown_cb(void);
#endif
/**
* hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
* @hdd_ctx: pointer to hdd_context_t
*
* Return: none
*/
void hdd_set_rps_cpu_mask(hdd_context_t *hdd_ctx)
{
hdd_adapter_t *adapter;
hdd_adapter_list_node_t *adapter_node, *next;
QDF_STATUS status = QDF_STATUS_SUCCESS;
status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
adapter = adapter_node->pAdapter;
if (NULL != adapter)
hdd_send_rps_ind(adapter);
status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
adapter_node = next;
}
}
/**
* wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
* @vdev_id: vdev_id
@@ -6569,7 +6591,7 @@ int hdd_update_cds_config(hdd_context_t *hdd_ctx)
cds_cfg->ip_tcp_udp_checksum_offload =
hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
cds_cfg->enable_rxthread = hdd_ctx->config->enableRxThread;
cds_cfg->enable_rxthread = hdd_ctx->enableRxThread;
cds_cfg->ce_classify_enabled =
hdd_ctx->config->ce_classify_enabled;
cds_cfg->tx_chain_mask_cck = hdd_ctx->config->tx_chain_mask_cck;
@@ -7472,6 +7494,8 @@ int hdd_wlan_startup(struct device *dev)
hdd_ctx->target_hw_version,
hdd_ctx->target_hw_name);
if (hdd_ctx->rps)
hdd_set_rps_cpu_mask(hdd_ctx);
ret = hdd_register_notifiers(hdd_ctx);
if (ret)
@@ -7927,6 +7951,7 @@ void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
case WLAN_SVC_WLAN_TP_IND:
case WLAN_SVC_WLAN_TP_TX_IND:
case WLAN_SVC_RPS_ENABLE_IND:
ani_hdr->length = len;
nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);

View File

@@ -2047,6 +2047,10 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
__func__);
return ERR_PTR(-ENOSPC);
}
if (pHddCtx->rps)
hdd_send_rps_ind(pAdapter);
EXIT();
return pAdapter->dev->ieee80211_ptr;
}

View File

@@ -609,7 +609,8 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
* it to stack
*/
qdf_net_buf_debug_release_skb(rxBuf);
if (hdd_napi_enabled(HDD_NAPI_ANY) && !pHddCtx->config->enableRxThread)
if (hdd_napi_enabled(HDD_NAPI_ANY) &&
!pHddCtx->enableRxThread)
rxstat = netif_receive_skb(skb);
else
rxstat = netif_rx_ni(skb);

View File

@@ -891,7 +891,7 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
if (HDD_LRO_NO_RX ==
hdd_lro_rx(pHddCtx, pAdapter, skb)) {
if (hdd_napi_enabled(HDD_NAPI_ANY) &&
!pHddCtx->config->enableRxThread)
!pHddCtx->enableRxThread)
rxstat = netif_receive_skb(skb);
else
rxstat = netif_rx_ni(skb);
@@ -1234,3 +1234,67 @@ exit:
ret = qdf_status_to_os_return(qdf_status);
return ret;
}
/**
* hdd_send_rps_ind() - send rps indication to daemon
* @adapter: adapter context
*
* If RPS feature enabled by INI, send RPS enable indication to daemon
* Indication contents is the name of interface to find correct sysfs node
* Should send all available interfaces
*
* Return: none
*/
void hdd_send_rps_ind(hdd_adapter_t *adapter)
{
int i;
uint8_t cpu_map_list_len = 0;
hdd_context_t *hdd_ctxt = NULL;
struct wlan_rps_data rps_data;
if (!adapter) {
hdd_err("adapter is NULL");
return;
}
hdd_ctxt = WLAN_HDD_GET_CTX(adapter);
rps_data.num_queues = NUM_TX_QUEUES;
hdd_info("cpu_map_list '%s'", hdd_ctxt->config->cpu_map_list);
/* in case no cpu map list is provided, simply return */
if (!strlen(hdd_ctxt->config->cpu_map_list)) {
hdd_err("no cpu map list found");
goto err;
}
if (QDF_STATUS_SUCCESS !=
hdd_hex_string_to_u16_array(hdd_ctxt->config->cpu_map_list,
rps_data.cpu_map_list,
&cpu_map_list_len,
WLAN_SVC_IFACE_NUM_QUEUES)) {
hdd_err("invalid cpu map list");
goto err;
}
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++) {
hdd_info("cpu_map_list[%d] = 0x%x",
i, rps_data.cpu_map_list[i]);
}
strlcpy(rps_data.ifname, adapter->dev->name,
sizeof(rps_data.ifname));
wlan_hdd_send_svc_nlink_msg(WLAN_SVC_RPS_ENABLE_IND,
&rps_data, sizeof(rps_data));
err:
hdd_err("Wrong RPS configuration. enabling rx_thread");
hdd_ctxt->rps = false;
hdd_ctxt->enableRxThread = true;
}

View File

@@ -38,6 +38,8 @@
#define WLAN_NLINK_COMMON_H__
#include <linux/netlink.h>
#include <linux/if.h>
/*---------------------------------------------------------------------------
* External Functions
@@ -79,6 +81,7 @@
#define WLAN_SVC_WLAN_VERSION_IND 0x107
#define WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND 0x108
#define WLAN_SVC_WLAN_TP_IND 0x109
#define WLAN_SVC_RPS_ENABLE_IND 0x10A
#define WLAN_SVC_WLAN_TP_TX_IND 0x10B
#define WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND 0x10C
#define WLAN_SVC_MAX_SSID_LEN 32
@@ -143,6 +146,29 @@ struct wlan_dfs_info {
uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN];
};
/*
* 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
/**
* 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];
};
/**
* enum wlan_tp_level - indicates wlan throughput level
* @WLAN_SVC_TP_NONE: used for initialization