summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManjunathappa Prakash <prakashpm@codeaurora.org>2016-11-15 20:03:37 -0800
committerqcabuildsw <qcabuildsw@localhost>2016-12-16 14:47:41 -0800
commit1bf7a9cf54af1eb135688a76cf4b98aa6f759fc4 (patch)
tree136fe099fa2a1623a008f6dafbbf72504c865675
parentb2e269837bd78015efd0902c7eee504b9c72643f (diff)
qcacld-3.0: Disable LRO capability during concurrency
LRO rx jumbo packets cannot be forwarded to other vdev and kernel drops them with warning message: "skbuff: wlan0: received packets cannot be forwarded while LRO is enabled" So disable LRO capability during concurrency. Change-Id: Ib35e1ee5f9c18a846e21ce1eb293e12e17761fa8 CRs-Fixed: 1092193
-rw-r--r--core/cds/inc/cds_sched.h5
-rw-r--r--core/cds/src/cds_api.c4
-rw-r--r--core/cds/src/cds_concurrency.c36
-rw-r--r--core/hdd/inc/wlan_hdd_lro.h10
-rw-r--r--core/hdd/inc/wlan_hdd_main.h2
-rw-r--r--core/hdd/src/wlan_hdd_lro.c29
6 files changed, 83 insertions, 3 deletions
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index c2ce9c1956e8..85c56f32b933 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -245,6 +245,8 @@ typedef struct _cds_msg_wrapper {
} cds_msg_wrapper, *p_cds_msg_wrapper;
+/* forward-declare hdd_context_s as it is used ina function type */
+struct hdd_context_s;
typedef struct _cds_context_type {
/* Messages buffers */
cds_msg_t aMsgBuffers[CDS_CORE_MAX_MESSAGES];
@@ -310,7 +312,10 @@ typedef struct _cds_context_type {
void (*sme_get_nss_for_vdev)(void*, enum tQDF_ADAPTER_MODE,
uint8_t *, uint8_t *);
+ /* Datapath callback functions */
void (*ol_txrx_update_mac_id)(uint8_t , uint8_t);
+ void (*hdd_enable_lro_in_concurrency)(struct hdd_context_s *);
+ void (*hdd_disable_lro_in_concurrency)(struct hdd_context_s *);
/* This list is not sessionized. This mandatory channel list would be
* as per OEMs preference as per the regulatory/other considerations.
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index 8abe471914d5..542b05d3dbce 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -459,6 +459,10 @@ QDF_STATUS cds_open(void)
}
gp_cds_context->ol_txrx_update_mac_id = ol_txrx_update_mac_id;
+ gp_cds_context->hdd_enable_lro_in_concurrency =
+ hdd_enable_lro_in_concurrency;
+ gp_cds_context->hdd_disable_lro_in_concurrency =
+ hdd_disable_lro_in_concurrency;
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
"%s: CDS successfully Opened", __func__);
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index 02d8f8c304ea..9f40b8fd2b7d 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -3790,6 +3790,22 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode,
qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
}
+ /**
+ * Disable LRO if P2P or IBSS or SAP connection has come up or
+ * there are more than one STA connections
+ */
+ if ((cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 1) ||
+ (cds_mode_specific_connection_count(CDS_SAP_MODE, NULL) > 0) ||
+ (cds_mode_specific_connection_count(CDS_P2P_CLIENT_MODE, NULL) >
+ 0) ||
+ (cds_mode_specific_connection_count(CDS_P2P_GO_MODE, NULL) > 0) ||
+ (cds_mode_specific_connection_count(CDS_IBSS_MODE, NULL) > 0)) {
+ if (cds_ctx->hdd_disable_lro_in_concurrency != NULL)
+ cds_ctx->hdd_disable_lro_in_concurrency(hdd_ctx);
+ else
+ cds_warn("hdd_disable_lro_in_concurrency NULL!");
+ };
+
/* set tdls connection tracker state */
cds_set_tdls_ct_mode(hdd_ctx);
cds_dump_current_concurrency();
@@ -3989,6 +4005,13 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode,
uint8_t session_id)
{
hdd_context_t *hdd_ctx;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return;
+ }
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -4014,6 +4037,19 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode,
cds_decr_connection_count(session_id);
+ /* Enable LRO if there no concurrency */
+ if ((cds_mode_specific_connection_count(CDS_STA_MODE, NULL) == 1) &&
+ (cds_mode_specific_connection_count(CDS_SAP_MODE, NULL) == 0) &&
+ (cds_mode_specific_connection_count(CDS_P2P_CLIENT_MODE, NULL) ==
+ 0) &&
+ (cds_mode_specific_connection_count(CDS_P2P_GO_MODE, NULL) == 0) &&
+ (cds_mode_specific_connection_count(CDS_IBSS_MODE, NULL) == 0)) {
+ if (cds_ctx->hdd_enable_lro_in_concurrency != NULL)
+ cds_ctx->hdd_enable_lro_in_concurrency(hdd_ctx);
+ else
+ cds_warn("hdd_enable_lro_in_concurrency NULL!");
+ };
+
/* set tdls connection tracker state */
cds_set_tdls_ct_mode(hdd_ctx);
diff --git a/core/hdd/inc/wlan_hdd_lro.h b/core/hdd/inc/wlan_hdd_lro.h
index 4706526f111b..71debbff1639 100644
--- a/core/hdd/inc/wlan_hdd_lro.h
+++ b/core/hdd/inc/wlan_hdd_lro.h
@@ -165,6 +165,8 @@ void hdd_lro_flush_all(hdd_context_t *hdd_ctx,
hdd_adapter_t *adapter);
void hdd_lro_display_stats(hdd_context_t *hdd_ctx);
+void hdd_enable_lro_in_concurrency(hdd_context_t *hdd_ctx);
+void hdd_disable_lro_in_concurrency(hdd_context_t *hdd_ctx);
#else
struct hdd_lro_s {};
@@ -195,5 +197,13 @@ static inline void hdd_lro_display_stats(hdd_context_t *hdd_ctx)
{
return;
}
+
+static inline void hdd_enable_lro_in_concurrency(hdd_context_t *hdd_ctx)
+{
+}
+
+static inline void hdd_disable_lro_in_concurrency(hdd_context_t *hdd_ctx)
+{
+}
#endif /* FEATURE_LRO */
#endif /* __WLAN_HDD_LRO_H__ */
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 19416786fc66..2f1f29a419b0 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1114,7 +1114,6 @@ struct hdd_adapter_s {
struct hdd_netif_queue_history
queue_oper_history[WLAN_HDD_MAX_HISTORY_ENTRY];
struct hdd_netif_queue_stats queue_oper_stats[WLAN_REASON_TYPE_MAX];
- struct hdd_lro_s lro_info;
ol_txrx_tx_fp tx_fn;
/* debugfs entry */
struct dentry *debugfs_phy;
@@ -1571,6 +1570,7 @@ struct hdd_context_s {
bool roaming_in_progress;
/* bit map to set/reset TDLS by different sources */
unsigned long tdls_source_bitmap;
+ qdf_atomic_t disable_lro_in_concurrency;
};
/*---------------------------------------------------------------------------
diff --git a/core/hdd/src/wlan_hdd_lro.c b/core/hdd/src/wlan_hdd_lro.c
index 0316a0e449c0..d43d576dc5b1 100644
--- a/core/hdd/src/wlan_hdd_lro.c
+++ b/core/hdd/src/wlan_hdd_lro.c
@@ -588,8 +588,11 @@ enum hdd_lro_rx_status hdd_lro_rx(hdd_context_t *hdd_ctx,
{
enum hdd_lro_rx_status status = HDD_LRO_NO_RX;
- if ((adapter->dev->features & NETIF_F_LRO) &&
- QDF_NBUF_CB_RX_TCP_PROTO(skb)) {
+ if (((adapter->dev->features & NETIF_F_LRO) != NETIF_F_LRO) ||
+ qdf_atomic_read(&hdd_ctx->disable_lro_in_concurrency))
+ return status;
+
+ if (QDF_NBUF_CB_RX_TCP_PROTO(skb)) {
struct iphdr *iph;
struct tcphdr *tcph;
struct net_lro_desc *lro_desc = NULL;
@@ -651,3 +654,25 @@ void hdd_lro_display_stats(hdd_context_t *hdd_ctx)
{
hdd_err("LRO stats is broken, will fix it");
}
+
+/**
+ * hdd_enable_lro_in_concurrency() - Enable LRO if concurrency is not active
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void hdd_enable_lro_in_concurrency(hdd_context_t *hdd_ctx)
+{
+ qdf_atomic_set(&hdd_ctx->disable_lro_in_concurrency, 0);
+}
+
+/**
+ * hdd_disable_lro_in_concurrency() - Disable LRO due to concurrency
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void hdd_disable_lro_in_concurrency(hdd_context_t *hdd_ctx)
+{
+ qdf_atomic_set(&hdd_ctx->disable_lro_in_concurrency, 1);
+}