qcacld-3.0: Add vendor event to update TCP paramenter

Currently, TCP params are configured through cnss-daemon.

Add vendor event to configure TCP params through Wi-Fi HAL.

Change-Id: I5ca3e33a8b15b5d499f771098ce8a3c58e4bb850
CRs-Fixed: 2349253
This commit is contained in:
Alok Kumar
2018-11-08 19:19:28 +05:30
committed by nshrivas
parent e265432489
commit 2fad644d65
7 changed files with 231 additions and 17 deletions

View File

@@ -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 \

View File

@@ -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

View File

@@ -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) */

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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,