diff options
author | Stefano Brivio <stefano.brivio@polimi.it> | 2007-11-25 05:10:33 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:05:01 -0500 |
commit | 00e0b8cb74ed7c16b2bc41eb33a16eae5b6e2d5c (patch) | |
tree | d8cd9b1ecb6ad15523a35191a6c1eabaf01c04b8 /drivers/net/wireless/b43 | |
parent | d8be11ee95be9ec9eabfec9f635e0feac972369b (diff) |
b43: reinit on too many PHY TX errors
Restart the hardware on too many PHY TX errors. A thousand PHY TX errors
per 15 seconds means we won't be able to recover for sure.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r-- | drivers/net/wireless/b43/b43.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 17 |
2 files changed, 21 insertions, 1 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 97ea96320c7e..d07b56e5ea69 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -393,6 +393,8 @@ enum { | |||
393 | #define B43_DEFAULT_SHORT_RETRY_LIMIT 7 | 393 | #define B43_DEFAULT_SHORT_RETRY_LIMIT 7 |
394 | #define B43_DEFAULT_LONG_RETRY_LIMIT 4 | 394 | #define B43_DEFAULT_LONG_RETRY_LIMIT 4 |
395 | 395 | ||
396 | #define B43_PHY_TX_BADNESS_LIMIT 1000 | ||
397 | |||
396 | /* Max size of a security key */ | 398 | /* Max size of a security key */ |
397 | #define B43_SEC_KEYSIZE 16 | 399 | #define B43_SEC_KEYSIZE 16 |
398 | /* Security algorithms. */ | 400 | /* Security algorithms. */ |
@@ -548,6 +550,9 @@ struct b43_phy { | |||
548 | /* OFDM address read/write caching for hardware auto-increment. */ | 550 | /* OFDM address read/write caching for hardware auto-increment. */ |
549 | u16 ofdm_addr; | 551 | u16 ofdm_addr; |
550 | u8 ofdm_valid; /* 0: invalid, 1: read, 2: write */ | 552 | u8 ofdm_valid; /* 0: invalid, 1: read, 2: write */ |
553 | |||
554 | /* PHY TX errors counter. */ | ||
555 | atomic_t txerr_cnt; | ||
551 | }; | 556 | }; |
552 | 557 | ||
553 | /* Data structures for DMA transmission, per 80211 core. */ | 558 | /* Data structures for DMA transmission, per 80211 core. */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 69c68c29dd93..084bbac01734 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -1394,8 +1394,17 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev) | |||
1394 | if (unlikely(reason & B43_IRQ_MAC_TXERR)) | 1394 | if (unlikely(reason & B43_IRQ_MAC_TXERR)) |
1395 | b43err(dev->wl, "MAC transmission error\n"); | 1395 | b43err(dev->wl, "MAC transmission error\n"); |
1396 | 1396 | ||
1397 | if (unlikely(reason & B43_IRQ_PHY_TXERR)) | 1397 | if (unlikely(reason & B43_IRQ_PHY_TXERR)) { |
1398 | b43err(dev->wl, "PHY transmission error\n"); | 1398 | b43err(dev->wl, "PHY transmission error\n"); |
1399 | rmb(); | ||
1400 | if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) { | ||
1401 | atomic_set(&dev->phy.txerr_cnt, | ||
1402 | B43_PHY_TX_BADNESS_LIMIT); | ||
1403 | b43err(dev->wl, "Too many PHY TX errors, " | ||
1404 | "restarting the controller\n"); | ||
1405 | b43_controller_restart(dev, "PHY TX errors"); | ||
1406 | } | ||
1407 | } | ||
1399 | 1408 | ||
1400 | if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | | 1409 | if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | |
1401 | B43_DMAIRQ_NONFATALMASK))) { | 1410 | B43_DMAIRQ_NONFATALMASK))) { |
@@ -2257,6 +2266,9 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
2257 | /* OFDM address caching. */ | 2266 | /* OFDM address caching. */ |
2258 | phy->ofdm_valid = 0; | 2267 | phy->ofdm_valid = 0; |
2259 | 2268 | ||
2269 | /* PHY TX errors counter. */ | ||
2270 | atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); | ||
2271 | |||
2260 | err = 0; | 2272 | err = 0; |
2261 | b43dbg(dev->wl, "Chip initialized\n"); | 2273 | b43dbg(dev->wl, "Chip initialized\n"); |
2262 | out: | 2274 | out: |
@@ -2341,6 +2353,9 @@ static void b43_periodic_every15sec(struct b43_wldev *dev) | |||
2341 | } | 2353 | } |
2342 | b43_phy_xmitpower(dev); //FIXME: unless scanning? | 2354 | b43_phy_xmitpower(dev); //FIXME: unless scanning? |
2343 | //TODO for APHY (temperature?) | 2355 | //TODO for APHY (temperature?) |
2356 | |||
2357 | atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); | ||
2358 | wmb(); | ||
2344 | } | 2359 | } |
2345 | 2360 | ||
2346 | static void do_periodic_work(struct b43_wldev *dev) | 2361 | static void do_periodic_work(struct b43_wldev *dev) |