aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/base.c')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c138
1 files changed, 72 insertions, 66 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 3a1c156d275f..2b3cf39dd4b1 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -59,7 +59,7 @@
59#include "reg.h" 59#include "reg.h"
60#include "debug.h" 60#include "debug.h"
61 61
62static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */ 62static u8 ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
63static int modparam_nohwcrypt; 63static int modparam_nohwcrypt;
64module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 64module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
65MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 65MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -376,7 +376,7 @@ static int ath5k_stop_hw(struct ath5k_softc *sc);
376static irqreturn_t ath5k_intr(int irq, void *dev_id); 376static irqreturn_t ath5k_intr(int irq, void *dev_id);
377static void ath5k_tasklet_reset(unsigned long data); 377static void ath5k_tasklet_reset(unsigned long data);
378 378
379static void ath5k_calibrate(unsigned long data); 379static void ath5k_tasklet_calibrate(unsigned long data);
380 380
381/* 381/*
382 * Module init/exit functions 382 * Module init/exit functions
@@ -471,7 +471,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
471 * DMA to work so force a reasonable value here if it 471 * DMA to work so force a reasonable value here if it
472 * comes up zero. 472 * comes up zero.
473 */ 473 */
474 csz = L1_CACHE_BYTES / sizeof(u32); 474 csz = L1_CACHE_BYTES >> 2;
475 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); 475 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
476 } 476 }
477 /* 477 /*
@@ -544,7 +544,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
544 __set_bit(ATH_STAT_INVALID, sc->status); 544 __set_bit(ATH_STAT_INVALID, sc->status);
545 545
546 sc->iobase = mem; /* So we can unmap it on detach */ 546 sc->iobase = mem; /* So we can unmap it on detach */
547 sc->cachelsz = csz * sizeof(u32); /* convert to bytes */ 547 sc->common.cachelsz = csz << 2; /* convert to bytes */
548 sc->opmode = NL80211_IFTYPE_STATION; 548 sc->opmode = NL80211_IFTYPE_STATION;
549 sc->bintval = 1000; 549 sc->bintval = 1000;
550 mutex_init(&sc->lock); 550 mutex_init(&sc->lock);
@@ -799,8 +799,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
799 tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); 799 tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
800 tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); 800 tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
801 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); 801 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
802 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
802 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); 803 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
803 setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
804 804
805 ret = ath5k_eeprom_read_mac(ah, mac); 805 ret = ath5k_eeprom_read_mac(ah, mac);
806 if (ret) { 806 if (ret) {
@@ -1071,10 +1071,9 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
1071} 1071}
1072 1072
1073/* 1073/*
1074 * Set/change channels. If the channel is really being changed, 1074 * Set/change channels. We always reset the chip.
1075 * it's done by reseting the chip. To accomplish this we must 1075 * To accomplish this we must first cleanup any pending DMA,
1076 * first cleanup any pending DMA, then restart stuff after a la 1076 * then restart stuff after a la ath5k_init.
1077 * ath5k_init.
1078 * 1077 *
1079 * Called with sc->lock. 1078 * Called with sc->lock.
1080 */ 1079 */
@@ -1084,19 +1083,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
1084 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", 1083 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
1085 sc->curchan->center_freq, chan->center_freq); 1084 sc->curchan->center_freq, chan->center_freq);
1086 1085
1087 if (chan->center_freq != sc->curchan->center_freq || 1086 /*
1088 chan->hw_value != sc->curchan->hw_value) { 1087 * To switch channels clear any pending DMA operations;
1089 1088 * wait long enough for the RX fifo to drain, reset the
1090 /* 1089 * hardware at the new frequency, and then re-enable
1091 * To switch channels clear any pending DMA operations; 1090 * the relevant bits of the h/w.
1092 * wait long enough for the RX fifo to drain, reset the 1091 */
1093 * hardware at the new frequency, and then re-enable 1092 return ath5k_reset(sc, chan);
1094 * the relevant bits of the h/w.
1095 */
1096 return ath5k_reset(sc, chan);
1097 }
1098
1099 return 0;
1100} 1093}
1101 1094
1102static void 1095static void
@@ -1158,27 +1151,20 @@ static
1158struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) 1151struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
1159{ 1152{
1160 struct sk_buff *skb; 1153 struct sk_buff *skb;
1161 unsigned int off;
1162 1154
1163 /* 1155 /*
1164 * Allocate buffer with headroom_needed space for the 1156 * Allocate buffer with headroom_needed space for the
1165 * fake physical layer header at the start. 1157 * fake physical layer header at the start.
1166 */ 1158 */
1167 skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1); 1159 skb = ath_rxbuf_alloc(&sc->common,
1160 sc->rxbufsize + sc->common.cachelsz - 1,
1161 GFP_ATOMIC);
1168 1162
1169 if (!skb) { 1163 if (!skb) {
1170 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", 1164 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
1171 sc->rxbufsize + sc->cachelsz - 1); 1165 sc->rxbufsize + sc->common.cachelsz - 1);
1172 return NULL; 1166 return NULL;
1173 } 1167 }
1174 /*
1175 * Cache-line-align. This is important (for the
1176 * 5210 at least) as not doing so causes bogus data
1177 * in rx'd frames.
1178 */
1179 off = ((unsigned long)skb->data) % sc->cachelsz;
1180 if (off != 0)
1181 skb_reserve(skb, sc->cachelsz - off);
1182 1168
1183 *skb_addr = pci_map_single(sc->pdev, 1169 *skb_addr = pci_map_single(sc->pdev,
1184 skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); 1170 skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
@@ -1620,10 +1606,10 @@ ath5k_rx_start(struct ath5k_softc *sc)
1620 struct ath5k_buf *bf; 1606 struct ath5k_buf *bf;
1621 int ret; 1607 int ret;
1622 1608
1623 sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->cachelsz); 1609 sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz);
1624 1610
1625 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n", 1611 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
1626 sc->cachelsz, sc->rxbufsize); 1612 sc->common.cachelsz, sc->rxbufsize);
1627 1613
1628 spin_lock_bh(&sc->rxbuflock); 1614 spin_lock_bh(&sc->rxbuflock);
1629 sc->rxlink = NULL; 1615 sc->rxlink = NULL;
@@ -2371,7 +2357,7 @@ ath5k_init(struct ath5k_softc *sc)
2371 sc->curband = &sc->sbands[sc->curchan->band]; 2357 sc->curband = &sc->sbands[sc->curchan->band];
2372 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | 2358 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
2373 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | 2359 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2374 AR5K_INT_FATAL | AR5K_INT_GLOBAL; 2360 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI;
2375 ret = ath5k_reset(sc, NULL); 2361 ret = ath5k_reset(sc, NULL);
2376 if (ret) 2362 if (ret)
2377 goto done; 2363 goto done;
@@ -2388,8 +2374,8 @@ ath5k_init(struct ath5k_softc *sc)
2388 /* Set ack to be sent at low bit-rates */ 2374 /* Set ack to be sent at low bit-rates */
2389 ath5k_hw_set_ack_bitrate_high(ah, false); 2375 ath5k_hw_set_ack_bitrate_high(ah, false);
2390 2376
2391 mod_timer(&sc->calib_tim, round_jiffies(jiffies + 2377 /* Set PHY calibration inteval */
2392 msecs_to_jiffies(ath5k_calinterval * 1000))); 2378 ah->ah_cal_intval = ath5k_calinterval;
2393 2379
2394 ret = 0; 2380 ret = 0;
2395done: 2381done:
@@ -2453,37 +2439,39 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2453 ret = ath5k_stop_locked(sc); 2439 ret = ath5k_stop_locked(sc);
2454 if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { 2440 if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
2455 /* 2441 /*
2456 * Set the chip in full sleep mode. Note that we are 2442 * Don't set the card in full sleep mode!
2457 * careful to do this only when bringing the interface 2443 *
2458 * completely to a stop. When the chip is in this state 2444 * a) When the device is in this state it must be carefully
2459 * it must be carefully woken up or references to 2445 * woken up or references to registers in the PCI clock
2460 * registers in the PCI clock domain may freeze the bus 2446 * domain may freeze the bus (and system). This varies
2461 * (and system). This varies by chip and is mostly an 2447 * by chip and is mostly an issue with newer parts
2462 * issue with newer parts that go to sleep more quickly. 2448 * (madwifi sources mentioned srev >= 0x78) that go to
2463 */ 2449 * sleep more quickly.
2464 if (sc->ah->ah_mac_srev >= 0x78) { 2450 *
2465 /* 2451 * b) On older chips full sleep results a weird behaviour
2466 * XXX 2452 * during wakeup. I tested various cards with srev < 0x78
2467 * don't put newer MAC revisions > 7.8 to sleep because 2453 * and they don't wake up after module reload, a second
2468 * of the above mentioned problems 2454 * module reload is needed to bring the card up again.
2469 */ 2455 *
2470 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, " 2456 * Until we figure out what's going on don't enable
2471 "not putting device to sleep\n"); 2457 * full chip reset on any chip (this is what Legacy HAL
2472 } else { 2458 * and Sam's HAL do anyway). Instead Perform a full reset
2473 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 2459 * on the device (same as initial state after attach) and
2474 "putting device to full sleep\n"); 2460 * leave it idle (keep MAC/BB on warm reset) */
2475 ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0); 2461 ret = ath5k_hw_on_hold(sc->ah);
2476 } 2462
2463 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2464 "putting device to sleep\n");
2477 } 2465 }
2478 ath5k_txbuf_free(sc, sc->bbuf); 2466 ath5k_txbuf_free(sc, sc->bbuf);
2479 2467
2480 mmiowb(); 2468 mmiowb();
2481 mutex_unlock(&sc->lock); 2469 mutex_unlock(&sc->lock);
2482 2470
2483 del_timer_sync(&sc->calib_tim);
2484 tasklet_kill(&sc->rxtq); 2471 tasklet_kill(&sc->rxtq);
2485 tasklet_kill(&sc->txtq); 2472 tasklet_kill(&sc->txtq);
2486 tasklet_kill(&sc->restq); 2473 tasklet_kill(&sc->restq);
2474 tasklet_kill(&sc->calib);
2487 tasklet_kill(&sc->beacontq); 2475 tasklet_kill(&sc->beacontq);
2488 2476
2489 ath5k_rfkill_hw_stop(sc->ah); 2477 ath5k_rfkill_hw_stop(sc->ah);
@@ -2539,6 +2527,9 @@ ath5k_intr(int irq, void *dev_id)
2539 if (status & AR5K_INT_BMISS) { 2527 if (status & AR5K_INT_BMISS) {
2540 /* TODO */ 2528 /* TODO */
2541 } 2529 }
2530 if (status & AR5K_INT_SWI) {
2531 tasklet_schedule(&sc->calib);
2532 }
2542 if (status & AR5K_INT_MIB) { 2533 if (status & AR5K_INT_MIB) {
2543 /* 2534 /*
2544 * These stats are also used for ANI i think 2535 * These stats are also used for ANI i think
@@ -2555,6 +2546,8 @@ ath5k_intr(int irq, void *dev_id)
2555 if (unlikely(!counter)) 2546 if (unlikely(!counter))
2556 ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); 2547 ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
2557 2548
2549 ath5k_hw_calibration_poll(ah);
2550
2558 return IRQ_HANDLED; 2551 return IRQ_HANDLED;
2559} 2552}
2560 2553
@@ -2571,11 +2564,19 @@ ath5k_tasklet_reset(unsigned long data)
2571 * for temperature/environment changes. 2564 * for temperature/environment changes.
2572 */ 2565 */
2573static void 2566static void
2574ath5k_calibrate(unsigned long data) 2567ath5k_tasklet_calibrate(unsigned long data)
2575{ 2568{
2576 struct ath5k_softc *sc = (void *)data; 2569 struct ath5k_softc *sc = (void *)data;
2577 struct ath5k_hw *ah = sc->ah; 2570 struct ath5k_hw *ah = sc->ah;
2578 2571
2572 /* Only full calibration for now */
2573 if (ah->ah_swi_mask != AR5K_SWI_FULL_CALIBRATION)
2574 return;
2575
2576 /* Stop queues so that calibration
2577 * doesn't interfere with tx */
2578 ieee80211_stop_queues(sc->hw);
2579
2579 ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", 2580 ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
2580 ieee80211_frequency_to_channel(sc->curchan->center_freq), 2581 ieee80211_frequency_to_channel(sc->curchan->center_freq),
2581 sc->curchan->hw_value); 2582 sc->curchan->hw_value);
@@ -2593,8 +2594,11 @@ ath5k_calibrate(unsigned long data)
2593 ieee80211_frequency_to_channel( 2594 ieee80211_frequency_to_channel(
2594 sc->curchan->center_freq)); 2595 sc->curchan->center_freq));
2595 2596
2596 mod_timer(&sc->calib_tim, round_jiffies(jiffies + 2597 ah->ah_swi_mask = 0;
2597 msecs_to_jiffies(ath5k_calinterval * 1000))); 2598
2599 /* Wake queues */
2600 ieee80211_wake_queues(sc->hw);
2601
2598} 2602}
2599 2603
2600 2604
@@ -2811,9 +2815,11 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2811 2815
2812 mutex_lock(&sc->lock); 2816 mutex_lock(&sc->lock);
2813 2817
2814 ret = ath5k_chan_set(sc, conf->channel); 2818 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
2815 if (ret < 0) 2819 ret = ath5k_chan_set(sc, conf->channel);
2816 goto unlock; 2820 if (ret < 0)
2821 goto unlock;
2822 }
2817 2823
2818 if ((changed & IEEE80211_CONF_CHANGE_POWER) && 2824 if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
2819 (sc->power_level != conf->power_level)) { 2825 (sc->power_level != conf->power_level)) {