diff options
| author | Manjunathappa Prakash <prakashpm@codeaurora.org> | 2016-11-15 20:03:37 -0800 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-12-16 14:47:41 -0800 |
| commit | 1bf7a9cf54af1eb135688a76cf4b98aa6f759fc4 (patch) | |
| tree | 136fe099fa2a1623a008f6dafbbf72504c865675 | |
| parent | b2e269837bd78015efd0902c7eee504b9c72643f (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.h | 5 | ||||
| -rw-r--r-- | core/cds/src/cds_api.c | 4 | ||||
| -rw-r--r-- | core/cds/src/cds_concurrency.c | 36 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_lro.h | 10 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 2 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_lro.c | 29 |
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); +} |
