#define B43_DEFAULT_SHORT_RETRY_LIMIT 7
#define B43_DEFAULT_LONG_RETRY_LIMIT 4
+#define B43_PHY_TX_BADNESS_LIMIT 1000
+
/* Max size of a security key */
#define B43_SEC_KEYSIZE 16
/* Security algorithms. */
/* OFDM address read/write caching for hardware auto-increment. */
u16 ofdm_addr;
u8 ofdm_valid; /* 0: invalid, 1: read, 2: write */
+
+ /* PHY TX errors counter. */
+ atomic_t txerr_cnt;
};
/* Data structures for DMA transmission, per 80211 core. */
if (unlikely(reason & B43_IRQ_MAC_TXERR))
b43err(dev->wl, "MAC transmission error\n");
- if (unlikely(reason & B43_IRQ_PHY_TXERR))
+ if (unlikely(reason & B43_IRQ_PHY_TXERR)) {
b43err(dev->wl, "PHY transmission error\n");
+ rmb();
+ if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) {
+ atomic_set(&dev->phy.txerr_cnt,
+ B43_PHY_TX_BADNESS_LIMIT);
+ b43err(dev->wl, "Too many PHY TX errors, "
+ "restarting the controller\n");
+ b43_controller_restart(dev, "PHY TX errors");
+ }
+ }
if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK |
B43_DMAIRQ_NONFATALMASK))) {
/* OFDM address caching. */
phy->ofdm_valid = 0;
+ /* PHY TX errors counter. */
+ atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
+
err = 0;
b43dbg(dev->wl, "Chip initialized\n");
out:
}
b43_phy_xmitpower(dev); //FIXME: unless scanning?
//TODO for APHY (temperature?)
+
+ atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
+ wmb();
}
static void do_periodic_work(struct b43_wldev *dev)