diff --git a/core/hdd/inc/hdd_dp_cfg.h b/core/hdd/inc/hdd_dp_cfg.h index 9ad8c3b08b6d..118ba0bf8d47 100644 --- a/core/hdd/inc/hdd_dp_cfg.h +++ b/core/hdd/inc/hdd_dp_cfg.h @@ -773,6 +773,10 @@ #define CFG_DP_ENABLE_FASTPATH_ALL #endif +#define CFG_DP_ENABLE_TCP_PARAM_UPDATE \ + CFG_INI_BOOL("enable_tcp_param_update", \ + false, "configure TCP param through Wi-Fi HAL") + #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL #define CFG_HDD_DP_LEGACY_TX_FLOW \ CFG(CFG_DP_LL_TX_FLOW_LWM) \ @@ -813,6 +817,7 @@ CFG(CFG_DP_RX_MODE) \ CFG(CFG_DP_CE_SERVICE_MAX_RX_IND_FLUSH) \ CFG(CFG_DP_CE_SERVICE_MAX_YIELD_TIME) \ + CFG(CFG_DP_ENABLE_TCP_PARAM_UPDATE) \ CFG_DP_ENABLE_FASTPATH_ALL #define CFG_HDD_DP_ALL \ CFG_HDD_DP \ diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index c0530adb1149..066d308ac168 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -6841,6 +6841,7 @@ struct hdd_config { uint32_t tcp_delack_thres_low; uint32_t tcp_tx_high_tput_thres; uint32_t tcp_delack_timer_count; + bool enable_tcp_param_update; u8 periodic_stats_disp_time; #endif /* MSM_PLATFORM */ #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 41d6d771dc36..4bcc53304c3e 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -3695,4 +3695,54 @@ void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx, struct qdf_mac_addr *curr_mac_addr, struct qdf_mac_addr *new_mac_addr); +#ifdef MSM_PLATFORM +/** + * wlan_hdd_send_tcp_param_update_event() - Send vendor event to update + * TCP parameter through Wi-Fi HAL + * @hdd_ctx: Pointer to HDD context + * @data: Parameters to update + * @dir: Direction(tx/rx) to update + * + * Return: None + */ +void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx, + void *data, + uint8_t dir); + +/** + * wlan_hdd_update_tcp_rx_param() - update TCP param in RX dir + * @hdd_ctx: Pointer to HDD context + * @data: Parameters to update + * + * Return: None + */ +void wlan_hdd_update_tcp_rx_param(struct hdd_context *hdd_ctx, void *data); + +/** + * wlan_hdd_update_tcp_tx_param() - update TCP param in TX dir + * @hdd_ctx: Pointer to HDD context + * @data: Parameters to update + * + * Return: None + */ +void wlan_hdd_update_tcp_tx_param(struct hdd_context *hdd_ctx, void *data); +#else +static inline +void wlan_hdd_update_tcp_rx_param(struct hdd_context *hdd_ctx, void *data) +{ +} + +static inline +void wlan_hdd_update_tcp_tx_param(struct hdd_context *hdd_ctx, void *data) +{ +} + +static inline +void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx, + void *data, + uint8_t dir) +{ +} + +#endif /* MSM_PLATFORM */ #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index ddfbc4dc4630..050098b26746 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1456,6 +1456,10 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = .vendor_id = QCA_NL80211_VENDOR_ID, .subcmd = QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO, }, + [QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT, + }, #ifdef WLAN_UMAC_CONVERGENCE COMMON_VENDOR_EVENTS #endif diff --git a/core/hdd/src/wlan_hdd_lro.c b/core/hdd/src/wlan_hdd_lro.c index f5057f7dcfe5..6acccbf44c91 100644 --- a/core/hdd/src/wlan_hdd_lro.c +++ b/core/hdd/src/wlan_hdd_lro.c @@ -148,10 +148,7 @@ hdd_lro_set_reset(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, hdd_debug("Enable TCP delack as LRO is disabled"); rx_tp_data.rx_tp_flags = TCP_DEL_ACK_IND; rx_tp_data.level = GET_CUR_RX_LVL(hdd_ctx); - wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, - WLAN_SVC_WLAN_TP_IND, - &rx_tp_data, - sizeof(rx_tp_data)); + wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data); hdd_ctx->en_tcp_delack_no_lro = 1; } } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 15bfaaecc129..f5a77bc51c1e 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -377,6 +377,166 @@ void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter, } #endif /* QCA_HL_NETDEV_FLOW_CONTROL */ +#ifdef MSM_PLATFORM +void wlan_hdd_update_tcp_rx_param(struct hdd_context *hdd_ctx, void *data) +{ + if (!hdd_ctx) { + hdd_err("HDD context is null"); + return; + } + + if (!data) { + hdd_err("Data is null"); + return; + } + if (hdd_ctx->config->enable_tcp_param_update) + wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 1); + else + wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, + WLAN_SVC_WLAN_TP_IND, + data, + sizeof(struct wlan_rx_tp_data)); +} + +void wlan_hdd_update_tcp_tx_param(struct hdd_context *hdd_ctx, void *data) +{ + enum wlan_tp_level next_tx_level; + struct wlan_tx_tp_data *tx_tp_data; + + if (!hdd_ctx) { + hdd_err("HDD context is null"); + return; + } + + if (!data) { + hdd_err("Data is null"); + return; + } + + tx_tp_data = (struct wlan_tx_tp_data *)data; + next_tx_level = tx_tp_data->level; + + if (hdd_ctx->config->enable_tcp_param_update) + wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 0); + else + wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, + WLAN_SVC_WLAN_TP_TX_IND, + &next_tx_level, + sizeof(next_tx_level)); +} + +/** + * wlan_hdd_send_tcp_param_update_event() - Send vendor event to update + * TCP parameter through Wi-Fi HAL + * @hdd_ctx: Pointer to HDD context + * @data: Parameters to update + * @dir: Direction(tx/rx) to update + * + * Return: None + */ +void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx, + void *data, + uint8_t dir) +{ + struct sk_buff *vendor_event; + uint32_t event_len; + bool tcp_limit_output = false; + bool tcp_del_ack_ind_enabled = false; + bool tcp_adv_win_scl_enabled = false; + enum wlan_tp_level next_tp_level = WLAN_SVC_TP_NONE; + + event_len = sizeof(uint8_t) + sizeof(uint8_t) + NLMSG_HDRLEN; + + if (dir == 0) /*TX Flow */ { + struct wlan_tx_tp_data *tx_tp_data = + (struct wlan_tx_tp_data *)data; + + next_tp_level = tx_tp_data->level; + + if (tx_tp_data->tcp_limit_output) { + /* TCP_LIMIT_OUTPUT_BYTES */ + event_len += sizeof(uint32_t); + tcp_limit_output = true; + } + } else if (dir == 1) /* RX Flow */ { + struct wlan_rx_tp_data *rx_tp_data = + (struct wlan_rx_tp_data *)data; + + next_tp_level = rx_tp_data->level; + + if (rx_tp_data->rx_tp_flags & TCP_DEL_ACK_IND_MASK) { + event_len += sizeof(uint32_t); /* TCP_DELACK_SEG */ + tcp_del_ack_ind_enabled = true; + } + if (rx_tp_data->rx_tp_flags & TCP_ADV_WIN_SCL_MASK) { + event_len += sizeof(uint32_t); /* TCP_ADV_WIN_SCALE */ + tcp_adv_win_scl_enabled = true; + } + } else { + hdd_err("Invalid Direction [%d]", dir); + return; + } + + vendor_event = + cfg80211_vendor_event_alloc( + hdd_ctx->wiphy, + NULL, event_len, + QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT_INDEX, + GFP_KERNEL); + + if (!vendor_event) { + hdd_err("cfg80211_vendor_event_alloc failed"); + return; + } + + if (nla_put_u8( + vendor_event, + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION, + dir)) + goto tcp_param_change_nla_failed; + + if (nla_put_u8( + vendor_event, + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL, + (next_tp_level == WLAN_SVC_TP_LOW ? + QCA_WLAN_THROUGHPUT_LEVEL_LOW : + QCA_WLAN_THROUGHPUT_LEVEL_HIGH))) + goto tcp_param_change_nla_failed; + + if (tcp_limit_output && + nla_put_u32( + vendor_event, + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES, + (next_tp_level == WLAN_SVC_TP_LOW ? + TCP_LIMIT_OUTPUT_BYTES_LOW : + TCP_LIMIT_OUTPUT_BYTES_HI))) + goto tcp_param_change_nla_failed; + + if (tcp_del_ack_ind_enabled && + (nla_put_u32( + vendor_event, + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG, + (next_tp_level == WLAN_SVC_TP_LOW ? + TCP_DEL_ACK_LOW : TCP_DEL_ACK_HI)))) + goto tcp_param_change_nla_failed; + + if (tcp_adv_win_scl_enabled && + (nla_put_u32( + vendor_event, + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE, + (next_tp_level == WLAN_SVC_TP_LOW ? + WIN_SCALE_LOW : WIN_SCALE_HI)))) + goto tcp_param_change_nla_failed; + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + return; + +tcp_param_change_nla_failed: + hdd_err("nla_put api failed"); + kfree_skb(vendor_event); +} +#endif /* MSM_PLATFORM */ + /** * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer * @vdev_id: vdev_id @@ -7450,9 +7610,7 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL; rx_tp_data.level = next_rx_level; - wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, - WLAN_SVC_WLAN_TP_IND, &rx_tp_data, - sizeof(rx_tp_data)); + wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data); } /* fine-tuning parameters for TX Flows */ @@ -7465,14 +7623,15 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, if ((hdd_ctx->config->enable_tcp_limit_output) && (hdd_ctx->cur_tx_level != next_tx_level)) { + struct wlan_tx_tp_data tx_tp_data = {0}; + hdd_debug("change TCP TX trigger level %d, average_tx: %llu", next_tx_level, temp_tx); hdd_ctx->cur_tx_level = next_tx_level; tx_level_change = true; - wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, - WLAN_SVC_WLAN_TP_TX_IND, - &next_tx_level, - sizeof(next_tx_level)); + tx_tp_data.level = next_tx_level; + tx_tp_data.tcp_limit_output = true; + wlan_hdd_update_tcp_tx_param(hdd_ctx, &tx_tp_data); } index = hdd_ctx->hdd_txrx_hist_idx; diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 182d5e538492..f4cb1338c856 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -1739,10 +1739,7 @@ void hdd_disable_rx_ol_in_concurrency(bool disable) hdd_info("Enable TCP delack as LRO disabled in concurrency"); rx_tp_data.rx_tp_flags = TCP_DEL_ACK_IND; rx_tp_data.level = GET_CUR_RX_LVL(hdd_ctx); - wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, - WLAN_SVC_WLAN_TP_IND, - &rx_tp_data, - sizeof(rx_tp_data)); + wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data); hdd_ctx->en_tcp_delack_no_lro = 1; } qdf_atomic_set(&hdd_ctx->disable_lro_in_concurrency, 1); @@ -2653,8 +2650,7 @@ void hdd_reset_tcp_delack(struct hdd_context *hdd_ctx) rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND; rx_tp_data.level = next_level; hdd_ctx->rx_high_ind_cnt = 0; - wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, WLAN_SVC_WLAN_TP_IND, - &rx_tp_data, sizeof(rx_tp_data)); + wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data); } #endif /* MSM_PLATFORM */ @@ -2740,6 +2736,8 @@ static void hdd_ini_tcp_settings(struct hdd_config *config, cfg_get(psoc, CFG_DP_TCP_DELACK_TIMER_COUNT); config->tcp_tx_high_tput_thres = cfg_get(psoc, CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD); + config->enable_tcp_param_update = + cfg_get(psoc, CFG_DP_ENABLE_TCP_PARAM_UPDATE); } #else static void hdd_ini_bus_bandwidth(struct hdd_config *config,