summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h13
-rw-r--r--core/hdd/inc/wlan_hdd_main.h23
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c13
-rw-r--r--core/hdd/src/wlan_hdd_main.c54
-rw-r--r--core/utils/nlink/inc/wlan_nlink_common.h22
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__ */