summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCNSS_WLAN Service <cnssbldsw@qualcomm.com>2017-09-01 20:54:19 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-09-01 20:54:19 -0700
commit4e5f013d7cb472d37af7a1e362e887ca65e68b6b (patch)
tree13baa83bc6926bb7e55608b47916d80ca5856810
parent11f69018a680dc175618c5f5969d569396c1a2ec (diff)
parent38ed038b3c59d8ee80aa5203837d66f101a03ae3 (diff)
Merge "qcacld-3.0: Send TX timeout event for TX data stall" into wlan-cld3.driver.lnx.1.1
-rw-r--r--core/hdd/inc/wlan_hdd_main.h8
-rw-r--r--core/hdd/src/wlan_hdd_assoc.c2
-rw-r--r--core/hdd/src/wlan_hdd_softap_tx_rx.c42
-rw-r--r--core/hdd/src/wlan_hdd_tx_rx.c64
4 files changed, 68 insertions, 48 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index e28aceed91a6..467855a812d2 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -89,6 +89,9 @@
#else
#define HDD_TX_TIMEOUT msecs_to_jiffies(5000)
#endif
+
+#define HDD_TX_STALL_THRESHOLD 4
+
/** Hdd Default MTU */
#define HDD_DEFAULT_MTU (1500)
@@ -470,6 +473,11 @@ typedef struct hdd_tx_rx_stats_s {
__u32 txflow_pause_cnt;
__u32 txflow_unpause_cnt;
__u32 txflow_timer_cnt;
+
+ /*tx timeout stats*/
+ __u32 tx_timeout_cnt;
+ __u32 cont_txtimeout_cnt;
+ u64 jiffies_last_txtimeout;
} hdd_tx_rx_stats_t;
#ifdef WLAN_FEATURE_11W
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index 672d52c59756..cc0ef6b03eee 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -1713,6 +1713,8 @@ static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
pAdapter->dad = false;
+ pAdapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0;
+
/* Unblock anyone waiting for disconnect to complete */
complete(&pAdapter->disconnect_comp_var);
hdd_print_bss_info(pHddStaCtx);
diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c
index b0aade85a0a5..c3caee5153bf 100644
--- a/core/hdd/src/wlan_hdd_softap_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -255,6 +255,8 @@ static int __hdd_softap_hard_start_xmit(struct sk_buff *skb,
uint32_t num_seg;
++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
+ pAdapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0;
+
/* Prevent this function from being called during SSR since TL
* context may not be reinitialized at this time which may
* lead to a crash.
@@ -478,30 +480,6 @@ int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return ret;
}
-#ifdef FEATURE_WLAN_DIAG_SUPPORT
-/**
- * hdd_wlan_datastall_sap_event()- Send SAP datastall information
- *
- * This Function send send SAP datastall diag event
- *
- * Return: void.
- */
-static void hdd_wlan_datastall_sap_event(void)
-{
- WLAN_HOST_DIAG_EVENT_DEF(sap_data_stall,
- struct host_event_wlan_datastall);
- qdf_mem_zero(&sap_data_stall, sizeof(sap_data_stall));
- sap_data_stall.reason = SOFTAP_TX_TIMEOUT;
- WLAN_HOST_DIAG_EVENT_REPORT(&sap_data_stall,
- EVENT_WLAN_SOFTAP_DATASTALL);
-}
-#else
-static inline void hdd_wlan_datastall_sap_event(void)
-{
-
-}
-#endif
-
/**
* __hdd_softap_tx_timeout() - TX timeout handler
* @dev: pointer to network device
@@ -548,7 +526,21 @@ static void __hdd_softap_tx_timeout(struct net_device *dev)
ol_tx_dump_flow_pool_info();
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
"carrier state: %d", netif_carrier_ok(dev));
- hdd_wlan_datastall_sap_event();
+
+ ++adapter->hdd_stats.hddTxRxStats.tx_timeout_cnt;
+ ++adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt;
+
+ if (adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt >
+ HDD_TX_STALL_THRESHOLD) {
+ QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+ "Detected data stall due to continuous TX timeouts");
+ adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0;
+ ol_txrx_post_data_stall_event(
+ DATA_STALL_LOG_INDICATOR_HOST_DRIVER,
+ DATA_STALL_LOG_HOST_SOFTAP_TX_TIMEOUT,
+ 0xFF, 0xFF,
+ DATA_STALL_LOG_RECOVERY_TRIGGER_PDR);
+ }
}
/**
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index 4c6c8d9df30a..7d7444df4e29 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -508,6 +508,7 @@ static int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
wlan_hdd_latency_opt(pAdapter, skb);
++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
+ pAdapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0;
if (QDF_NBUF_CB_GET_PACKET_TYPE(skb) == QDF_NBUF_CB_PACKET_TYPE_ARP) {
is_arp = true;
@@ -805,28 +806,6 @@ QDF_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *pHddStaCtx,
return QDF_STATUS_E_FAILURE;
}
-#ifdef FEATURE_WLAN_DIAG_SUPPORT
-/**
- * hdd_wlan_datastall_sta_event()- send sta datastall information
- *
- * This Function send send sta datastall status diag event
- *
- * Return: void.
- */
-static void hdd_wlan_datastall_sta_event(void)
-{
- WLAN_HOST_DIAG_EVENT_DEF(sta_data_stall,
- struct host_event_wlan_datastall);
- qdf_mem_zero(&sta_data_stall, sizeof(sta_data_stall));
- sta_data_stall.reason = STA_TX_TIMEOUT;
- WLAN_HOST_DIAG_EVENT_REPORT(&sta_data_stall, EVENT_WLAN_STA_DATASTALL);
-}
-#else
-static inline void hdd_wlan_datastall_sta_event(void)
-{
-}
-#endif
-
/**
* __hdd_tx_timeout() - TX timeout handler
* @dev: pointer to network device
@@ -842,6 +821,7 @@ static void __hdd_tx_timeout(struct net_device *dev)
hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_context_t *hdd_ctx;
struct netdev_queue *txq;
+ u64 diff_jiffies;
int i = 0;
TX_TIMEOUT_TRACE(dev, QDF_MODULE_ID_HDD_DATA);
@@ -867,7 +847,45 @@ static void __hdd_tx_timeout(struct net_device *dev)
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
wlan_hdd_display_netif_queue_history(hdd_ctx);
ol_tx_dump_flow_pool_info();
- hdd_wlan_datastall_sta_event();
+
+ ++adapter->hdd_stats.hddTxRxStats.tx_timeout_cnt;
+ ++adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt;
+
+ diff_jiffies = jiffies -
+ adapter->hdd_stats.hddTxRxStats.jiffies_last_txtimeout;
+
+ if ((adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt > 1) &&
+ (diff_jiffies > (HDD_TX_TIMEOUT * 2))) {
+ /*
+ * In case when there is no traffic is running, it may
+ * possible tx time-out may once happen and later system
+ * recovered then continuous tx timeout count has to be
+ * reset as it is gets modified only when traffic is running.
+ * If over a period of time if this count reaches to threshold
+ * then host triggers a false subsystem restart. In genuine
+ * time out case kernel will call the tx time-out back to back
+ * at interval of HDD_TX_TIMEOUT. Here now check if previous
+ * TX TIME out has occurred more than twice of HDD_TX_TIMEOUT
+ * back then host may recovered here from data stall.
+ */
+ adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0;
+ QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+ "Reset continous tx timeout stat");
+ }
+
+ adapter->hdd_stats.hddTxRxStats.jiffies_last_txtimeout = jiffies;
+
+ if (adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt >
+ HDD_TX_STALL_THRESHOLD) {
+ QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+ "Data stall due to continuous TX timeouts");
+ adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0;
+ ol_txrx_post_data_stall_event(
+ DATA_STALL_LOG_INDICATOR_HOST_DRIVER,
+ DATA_STALL_LOG_HOST_STA_TX_TIMEOUT,
+ 0xFF, 0xFF,
+ DATA_STALL_LOG_RECOVERY_TRIGGER_PDR);
+ }
}
/**