diff options
| -rw-r--r-- | core/hdd/inc/wlan_hdd_cfg.h | 13 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 23 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg.c | 13 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 54 | ||||
| -rw-r--r-- | core/utils/nlink/inc/wlan_nlink_common.h | 22 |
5 files changed, 111 insertions, 14 deletions
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 4af4a4f258a6..82c99e896b6c 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -2181,6 +2181,18 @@ typedef enum { #define CFG_TCP_DELACK_THRESHOLD_LOW_DEFAULT (1000) #define CFG_TCP_DELACK_THRESHOLD_LOW_MIN (0) #define CFG_TCP_DELACK_THRESHOLD_LOW_MAX (10000) + +/* TCP_TX_HIGH_TPUT_THRESHOLD specifies the threshold of packets transmitted + * over a period of 100 ms beyond which TCP can be considered to have a high + * TX throughput requirement. The driver uses this condition to tweak TCP TX + * specific parameters (via cnss-daemon). + * default - 500 + */ +#define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_NAME "gTcpTxHighTputThreshold" +#define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_DEFAULT (500) +#define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MIN (0) +#define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MAX (16000) + #endif /* MSM_PLATFORM */ #ifdef WLAN_FEATURE_11W @@ -3172,6 +3184,7 @@ struct hdd_config { uint32_t busBandwidthComputeInterval; uint32_t tcpDelackThresholdHigh; uint32_t tcpDelackThresholdLow; + uint32_t tcp_tx_high_tput_thres; #endif /* MSM_PLATFORM */ /* FW debug log parameters */ diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 3e4ad444ec1c..103082ca7d83 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -317,6 +317,26 @@ extern spinlock_t hdd_context_lock; #define NUM_TX_RX_HISTOGRAM 1024 #define NUM_TX_RX_HISTOGRAM_MASK (NUM_TX_RX_HISTOGRAM - 1) +/** + * struct hdd_tx_rx_histogram - structure to keep track of tx and rx packets + * received over 100ms intervals + * @interval_rx: # of rx packets received in the last 100ms interval + * @interval_tx: # of tx packets received in the last 100ms interval + * @total_rx: # of total rx packets received on interface + * @total_tx: # of total tx packets received on interface + * @next_vote_level: cnss_bus_width_type voting level (high or low) + * determined on the basis of total tx and rx packets + * received in the last 100ms interval + * @next_rx_level: cnss_bus_width_type voting level (high or low) + * determined on the basis of rx packets received in the + * last 100ms interval + * @next_tx_level: cnss_bus_width_type voting level (high or low) + * determined on the basis of tx packets received in the + * last 100ms interval + * + * The structure keeps track of throughput requirements of wlan driver in 100ms + * intervals for later analysis. + */ struct hdd_tx_rx_histogram { uint64_t interval_rx; uint64_t interval_tx; @@ -324,6 +344,7 @@ struct hdd_tx_rx_histogram { uint64_t total_tx; uint32_t next_vote_level; uint32_t next_rx_level; + uint32_t next_tx_level; }; typedef struct hdd_tx_rx_stats_s { @@ -1215,6 +1236,8 @@ struct hdd_context_s { spinlock_t bus_bw_lock; int cur_rx_level; uint64_t prev_rx; + int cur_tx_level; + uint64_t prev_tx; #endif /* VHT80 allowed */ bool isVHT80Allowed; diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 4b13ed73b7f3..1ba3b80c8444 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -2973,6 +2973,14 @@ REG_TABLE_ENTRY g_registry_table[] = { CFG_TCP_DELACK_THRESHOLD_LOW_DEFAULT, CFG_TCP_DELACK_THRESHOLD_LOW_MIN, CFG_TCP_DELACK_THRESHOLD_LOW_MAX), + + REG_VARIABLE(CFG_TCP_TX_HIGH_TPUT_THRESHOLD_NAME, WLAN_PARAM_Integer, + struct hdd_config, tcp_tx_high_tput_thres, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TCP_TX_HIGH_TPUT_THRESHOLD_DEFAULT, + CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MIN, + CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MAX), + #endif REG_VARIABLE(CFG_ENABLE_FW_LOG_TYPE, WLAN_PARAM_Integer, @@ -4913,6 +4921,11 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH, "Name = [gTcpDelAckThresholdLow] Value = [%u] ", pHddCtx->config->tcpDelackThresholdLow); + CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_TCP_TX_HIGH_TPUT_THRESHOLD_NAME, + pHddCtx->config->tcp_tx_high_tput_thres); + #endif CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 85e62e6a441f..0c242fed3e57 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -3942,14 +3942,17 @@ static CDF_STATUS wlan_hdd_regulatory_init(hdd_context_t *hdd_ctx) #ifdef MSM_PLATFORM void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx, - uint64_t tx_packets, uint64_t rx_packets) + const uint64_t tx_packets, const uint64_t rx_packets) { #ifdef CONFIG_CNSS uint64_t total = tx_packets + rx_packets; + uint64_t temp_rx = 0; + uint64_t temp_tx = 0; enum cnss_bus_width_type next_vote_level = CNSS_BUS_WIDTH_NONE; + enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE; + enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE; + - uint64_t temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2; - enum cnss_bus_width_type next_rx_level = CNSS_BUS_WIDTH_NONE; if (total > hdd_ctx->config->busBandwidthHighThreshold) next_vote_level = CNSS_BUS_WIDTH_HIGH; else if (total > hdd_ctx->config->busBandwidthMediumThreshold) @@ -3959,8 +3962,8 @@ void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx, else next_vote_level = CNSS_BUS_WIDTH_NONE; - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_vote_level - = next_vote_level; + hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_vote_level = + next_vote_level; if (hdd_ctx->cur_vote_level != next_vote_level) { hddLog(CDF_TRACE_LEVEL_DEBUG, @@ -3971,14 +3974,18 @@ void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx, hdd_ctx->cur_vote_level = next_vote_level; cnss_request_bus_bandwidth(next_vote_level); } + + /* fine-tuning parameters for RX Flows */ + temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2; + hdd_ctx->prev_rx = rx_packets; if (temp_rx > hdd_ctx->config->tcpDelackThresholdHigh) - next_rx_level = CNSS_BUS_WIDTH_HIGH; + next_rx_level = WLAN_SVC_TP_HIGH; else - next_rx_level = CNSS_BUS_WIDTH_LOW; + next_rx_level = WLAN_SVC_TP_LOW; - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_rx_level - = next_rx_level; + hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_rx_level = + next_rx_level; if (hdd_ctx->cur_rx_level != next_rx_level) { hddLog(CDF_TRACE_LEVEL_DEBUG, @@ -3990,6 +3997,25 @@ void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx, sizeof(next_rx_level)); } + /* fine-tuning parameters for TX Flows */ + temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2; + hdd_ctx->prev_tx = tx_packets; + if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres) + next_tx_level = WLAN_SVC_TP_HIGH; + else + next_tx_level = WLAN_SVC_TP_LOW; + + if (hdd_ctx->cur_tx_level != next_tx_level) { + hdd_debug("change TCP TX trigger level %d, average_tx: %llu", + next_tx_level, temp_tx); + hdd_ctx->cur_tx_level = next_tx_level; + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_TX_IND, + &next_tx_level, + sizeof(next_tx_level)); + } + + hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_tx_level = + next_tx_level; hdd_ctx->hdd_txrx_hist_idx++; hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK; #endif @@ -4097,18 +4123,19 @@ void wlan_hdd_display_tx_rx_histogram(hdd_context_t *hdd_ctx) hdd_ctx->config->tcpDelackThresholdLow); #endif - hddLog(CDF_TRACE_LEVEL_ERROR, "index, total_rx, interval_rx," - "total_tx, interval_tx, next_vote_level, next_rx_level"); + hddLog(CDF_TRACE_LEVEL_ERROR, + "index, total_rx, interval_rx, total_tx, interval_tx, next_vote_level, next_rx_level, next_tx_level"); for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) { hddLog(CDF_TRACE_LEVEL_ERROR, - "%d: %llu, %llu, %llu, %llu, %d, %d", + "%d: %llu, %llu, %llu, %llu, %d, %d, %d", i, hdd_ctx->hdd_txrx_hist[i].total_rx, hdd_ctx->hdd_txrx_hist[i].interval_rx, hdd_ctx->hdd_txrx_hist[i].total_tx, hdd_ctx->hdd_txrx_hist[i].interval_tx, hdd_ctx->hdd_txrx_hist[i].next_vote_level, - hdd_ctx->hdd_txrx_hist[i].next_rx_level); + hdd_ctx->hdd_txrx_hist[i].next_rx_level, + hdd_ctx->hdd_txrx_hist[i].next_tx_level); } return; } @@ -6158,6 +6185,7 @@ void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len) case WLAN_SVC_DFS_RADAR_DETECT_IND: case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND: case WLAN_SVC_WLAN_TP_IND: + case WLAN_SVC_WLAN_TP_TX_IND: ani_hdr->length = len; nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len)); nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr); diff --git a/core/utils/nlink/inc/wlan_nlink_common.h b/core/utils/nlink/inc/wlan_nlink_common.h index 7dc7646832c7..399de6e2ccd5 100644 --- a/core/utils/nlink/inc/wlan_nlink_common.h +++ b/core/utils/nlink/inc/wlan_nlink_common.h @@ -79,7 +79,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_WLAN_TP_TX_IND 0x10B #define WLAN_SVC_MAX_SSID_LEN 32 #define WLAN_SVC_MAX_BSSID_LEN 6 #define WLAN_SVC_MAX_STR_LEN 16 @@ -136,4 +136,24 @@ struct wlan_dfs_info { uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN]; }; +/** + * enum wlan_tp_level - indicates wlan throughput level + * @WLAN_SVC_TP_NONE: used for initialization + * @WLAN_SVC_TP_LOW: used to identify low throughput level + * @WLAN_SVC_TP_MEDIUM: used to identify medium throughput level + * @WLAN_SVC_TP_HIGH: used to identify high throughput level + * + * The different throughput levels are determined on the basis of # of tx and + * rx packets and other threshold values. For example, if the # of total + * packets sent or received by the driver is greater than 500 in the last 100ms + * , the driver has a high throughput requirement. The driver may tweak certain + * system parameters based on the throughput level. + */ +enum wlan_tp_level { + WLAN_SVC_TP_NONE, + WLAN_SVC_TP_LOW, + WLAN_SVC_TP_MEDIUM, + WLAN_SVC_TP_HIGH, +}; + #endif /* WLAN_NLINK_COMMON_H__ */ |
