Переглянути джерело

qcacld-3.0: Support for vendor issuing Enable/Disable LRO command

Add support for Enable/Disable LRO at run time through vendor
command. In case of USB tethering with WLAN0 as upstream,
vendor command will be issued to disable LRO. On reception
driver will disable LRO and enable tcpdelack.

Change-Id: If64da28c040868d5b42af202c647251db1a684c0
CRs-Fixed: 2060320
Poddar, Siddarth 7 роки тому
батько
коміт
4b3f731265

+ 18 - 0
core/hdd/inc/wlan_hdd_lro.h

@@ -50,6 +50,18 @@ int hdd_lro_init(struct hdd_context *hdd_ctx);
 enum hdd_lro_rx_status hdd_lro_rx(struct hdd_context *hdd_ctx,
 	 struct hdd_adapter *adapter, struct sk_buff *skb);
 void hdd_lro_display_stats(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_lro_set_reset() - vendor command for Disable/Enable LRO
+ * @hdd_ctx: hdd context
+ * @hdd_adapter_t: adapter
+ * @enable_flag: enable or disable LRO.
+ *
+ * Return: none
+ */
+QDF_STATUS hdd_lro_set_reset(struct hdd_context *hdd_ctx,
+					  struct hdd_adapter *adapter,
+					  uint8_t enable_flag);
 void hdd_disable_lro_in_concurrency(bool);
 /**
  * hdd_disable_lro_for_low_tput() - enable/disable LRO based on tput
@@ -77,6 +89,12 @@ static inline void hdd_lro_display_stats(struct hdd_context *hdd_ctx)
 {
 }
 
+static inline QDF_STATUS hdd_lro_set_reset(struct hdd_context *hdd_ctx,
+					  struct hdd_adapter *adapter,
+					  uint8_t enable_flag)
+{
+	return 0;
+}
 static inline void hdd_disable_lro_in_concurrency(bool disable)
 {
 }

+ 1 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1704,6 +1704,7 @@ struct hdd_context {
 	bool imps_enabled;
 	int user_configured_pkt_filter_rules;
 	bool is_fils_roaming_supported;
+	qdf_atomic_t vendor_disable_lro_flag;
 	qdf_atomic_t disable_lro_in_concurrency;
 	qdf_atomic_t disable_lro_in_low_tput;
 	bool en_tcp_delack_no_lro;

+ 8 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -5845,6 +5845,7 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
 		.len = QDF_MAC_ADDR_SIZE},
 	[RX_BLOCKSIZE_WINLIMIT] = {.type = NLA_U32},
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_LRO] = {.type = NLA_U8 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA] = {.type = NLA_U32 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN] = {.type = NLA_U32 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST] = {.type = NLA_U32 },
@@ -6235,6 +6236,13 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
 		if (status != QDF_STATUS_SUCCESS)
 			ret_val = -EPERM;
 	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LRO]) {
+		enable_flag = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LRO]);
+		ret_val = hdd_lro_set_reset(hdd_ctx, adapter,
+							 enable_flag);
+	}
+
 	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE]) {
 		enable_flag =
 			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE]);

+ 35 - 0
core/hdd/src/wlan_hdd_lro.c

@@ -210,6 +210,41 @@ void hdd_lro_display_stats(struct hdd_context *hdd_ctx)
 	hdd_debug("LRO stats is broken, will fix it");
 }
 
+QDF_STATUS
+hdd_lro_set_reset(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
+			       uint8_t enable_flag)
+{
+	if (!hdd_ctx->config->lro_enable ||
+		 QDF_STA_MODE != adapter->device_mode) {
+		hdd_debug("LRO is already Disabled");
+		return 0;
+	}
+
+	if (enable_flag) {
+		qdf_atomic_set(&hdd_ctx->vendor_disable_lro_flag, 0);
+		adapter->dev->features |= NETIF_F_LRO;
+	} else {
+		/* Disable LRO, Enable tcpdelack*/
+		qdf_atomic_set(&hdd_ctx->vendor_disable_lro_flag, 1);
+		adapter->dev->features &= ~NETIF_F_LRO;
+		hdd_debug("LRO Disabled");
+
+		if (hdd_ctx->en_tcp_delack_no_lro) {
+			struct wlan_rx_tp_data rx_tp_data;
+
+			hdd_debug("Enable TCP delack as LRO is disabled");
+			rx_tp_data.rx_tp_flags = TCP_DEL_ACK_IND;
+			rx_tp_data.level = hdd_ctx->cur_rx_level;
+			wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+						WLAN_SVC_WLAN_TP_IND,
+						&rx_tp_data,
+						sizeof(rx_tp_data));
+			hdd_ctx->en_tcp_delack_no_lro = 1;
+		}
+	}
+	return 0;
+}
+
 /**
  * hdd_disable_lro_in_concurrency() - Disable LRO due to concurrency
  * @disable: bool value

+ 6 - 0
core/hdd/src/wlan_hdd_main.c

@@ -3502,6 +3502,12 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
 	if (ret_val)
 		hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
 
+	/*
+	 * In case of USB tethering, LRO is disabled. If SSR happened
+	 * during that time, then as part of SSR init, do not enable
+	 * the LRO again. Keep the LRO state same as before SSR.
+	 */
+	if (!(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
 	adapter->dev->features |= NETIF_F_LRO;
 
 	/* rcpi info initialization */