This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

WILINK8-WIFI-MCP8: corrupted packet in RX

Part Number: WILINK8-WIFI-MCP8
Other Parts Discussed in Thread: WL1271

We currently have a number of customers where we are seeing many of the "corrupted packet in RX" messages.  These customers have also complained of unstable wireless network connections.

One customer is also seeing large number of  "wlcore: WARNING no fw rx ba on tid x" message in the log.

We are using Wilink 1807 with embedded linux 

MAC Version: Rev 8.9.0.0.76
PHY Version: Rev 8.2.0.0.240

We have tried keeping track of the number of corrupt packets and forcing a wilink reset if the counts exceeds a threshold, but this doesn't seem to be a viable workaround as the corrupt packets are still being received as soon as the wilink comes back up.



--- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -84,6 +84,7 @@ EXPORT_SYMBOL_GPL(wl1271_debugfs_update_stats); DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); +DEBUGFS_READONLY_FILE(corrupted_packets, "%u", wl->corrupted_packets); DEBUGFS_READONLY_FILE(excessive_retries, "%u", wl->stats.excessive_retries); @@ -1249,6 +1250,7 @@ DEBUGFS_ADD(tx_queue_len, rootdir); DEBUGFS_ADD(retry_count, rootdir); + DEBUGFS_ADD(corrupted_packets, rootdir); DEBUGFS_ADD(excessive_retries, rootdir); DEBUGFS_ADD(gpio_power, rootdir); --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -557,6 +557,16 @@ if (!intr) { done = true; continue; + } + + if (wl->corrupted_packets > 50){ + wl1271_error("Too many corrupt packets received (%d>50)! starting recovery.",wl->corrupted_packets); + wl->corrupted_packets = 0; + wl->watchdog_recovery = true; + ret = -EIO; + + /* restarting the chip. ignore any other interrupt. */ + goto out; } if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { @@ -5968,6 +5978,7 @@ wl->active_sta_count = 0; wl->active_link_count = 0; wl->fwlog_size = 0; + wl->corrupted_packets = 0; init_waitqueue_head(&wl->fwlog_waitq); /* The system link is always allocated */ @@ -5968,6 +5978,7 @@ wl->active_sta_count = 0; wl->active_link_count = 0; wl->fwlog_size = 0; + wl->corrupted_packets = 0; init_waitqueue_head(&wl->fwlog_waitq); /* The system link is always allocated */ --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -148,13 +148,15 @@ /* discard corrupted packets */ if (desc->status & WL1271_RX_DESC_DECRYPT_FAIL) { - hdr = (void *)(data + sizeof(*desc) + offset_to_data); + /*hdr = (void *)(data + sizeof(*desc) + offset_to_data); wl1271_warning("corrupted packet in RX: status: 0x%x len: %d", desc->status & WL1271_RX_DESC_STATUS_MASK, pkt_data_len); wl1271_dump((DEBUG_RX|DEBUG_CMD), "PKT: ", data + sizeof(*desc), min(pkt_data_len, - ieee80211_hdrlen(hdr->frame_control))); + ieee80211_hdrlen(hdr->frame_control)));*/ + wl->corrupted_packets++; + wl1271_notice("corrupt packet rx:%d", wl->corrupted_packets); return -EINVAL; } --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -493,6 +493,8 @@ /* interface combinations supported by the hw */ const struct ieee80211_iface_combination *iface_combinations; u8 n_iface_combinations; + + unsigned int corrupted_packets; }; int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);

--- a/drivers/net/wireless/ti/wl1251/main.c+++ b/drivers/net/wireless/ti/wl1251/main.c@@ -1464,7 +1464,7 @@   wl->mac80211_registered = true; - wl1251_notice("loaded");+ wl1251_notice("loaded (wl1251 main.c)");   return 0; }--- a/drivers/net/wireless/ti/wlcore/debugfs.c+++ b/drivers/net/wireless/ti/wlcore/debugfs.c@@ -84,6 +84,7 @@ EXPORT_SYMBOL_GPL(wl1271_debugfs_update_stats);  DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count);+DEBUGFS_READONLY_FILE(corrupted_packets, "%u", wl->corrupted_packets); DEBUGFS_READONLY_FILE(excessive_retries, "%u",        wl->stats.excessive_retries); @@ -1249,6 +1250,7 @@   DEBUGFS_ADD(tx_queue_len, rootdir);  DEBUGFS_ADD(retry_count, rootdir);+ DEBUGFS_ADD(corrupted_packets, rootdir);  DEBUGFS_ADD(excessive_retries, rootdir);   DEBUGFS_ADD(gpio_power, rootdir);--- a/drivers/net/wireless/ti/wlcore/main.c+++ b/drivers/net/wireless/ti/wlcore/main.c@@ -557,6 +557,16 @@  if (!intr) {  done = true;  continue;+ }++ if (wl->corrupted_packets > 50){+ wl1271_error("Too many corrupt packets received (%d>50)! starting recovery.",wl->corrupted_packets);+ wl->corrupted_packets = 0; + wl->watchdog_recovery = true;+ ret = -EIO;++ /* restarting the chip. ignore any other interrupt. */+ goto out;  }   if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {@@ -5743,7 +5753,7 @@   wl1271_debugfs_init(wl); - wl1271_notice("loaded");+ wl1271_notice("loaded (wlcore.c main)");  out:  return ret;@@ -5968,6 +5978,7 @@  wl->active_sta_count = 0;  wl->active_link_count = 0;  wl->fwlog_size = 0;+ wl->corrupted_packets = 0;  init_waitqueue_head(&wl->fwlog_waitq);   /* The system link is always allocated */
@@ -5743,7 +5753,7 @@   wl1271_debugfs_init(wl); - wl1271_notice("loaded");+ wl1271_notice("loaded (wlcore.c main)");  out:  return ret;@@ -5968,6 +5978,7 @@  wl->active_sta_count = 0;  wl->active_link_count = 0;  wl->fwlog_size = 0;+ wl->corrupted_packets = 0;  init_waitqueue_head(&wl->fwlog_waitq);   /* The system link is always allocated */--- a/drivers/net/wireless/ti/wlcore/rx.c+++ b/drivers/net/wireless/ti/wlcore/rx.c@@ -148,13 +148,15 @@   /* discard corrupted packets */  if (desc->status & WL1271_RX_DESC_DECRYPT_FAIL) {- hdr = (void *)(data + sizeof(*desc) + offset_to_data);+ /*hdr = (void *)(data + sizeof(*desc) + offset_to_data);  wl1271_warning("corrupted packet in RX: status: 0x%x len: %d",         desc->status & WL1271_RX_DESC_STATUS_MASK,         pkt_data_len);  wl1271_dump((DEBUG_RX|DEBUG_CMD), "PKT: ", data + sizeof(*desc),      min(pkt_data_len,- ieee80211_hdrlen(hdr->frame_control)));+ ieee80211_hdrlen(hdr->frame_control)));*/+ wl->corrupted_packets++;+ wl1271_notice("corrupt packet rx:%d", wl->corrupted_packets);  return -EINVAL;  } --- a/drivers/net/wireless/ti/wlcore/wlcore.h+++ b/drivers/net/wireless/ti/wlcore/wlcore.h@@ -493,6 +493,8 @@  /* interface combinations supported by the hw */  const struct ieee80211_iface_combination *iface_combinations;  u8 n_iface_combinations;++ unsigned int corrupted_packets; };  int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);