diff options
author | David S. Miller <davem@davemloft.net> | 2009-03-17 17:29:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-17 17:29:22 -0400 |
commit | f10023a4ef3f5cc05457b059c6880bc447adfa1f (patch) | |
tree | e5d229bb9719b0be27289a6736d2e22254da06f0 | |
parent | 4ada8107f465b97326751de66d3c11ed78bf8214 (diff) | |
parent | 640c65eae673d2caf6e7bf61c1eb4e9513b88fda (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
-rw-r--r-- | drivers/net/wireless/ath9k/ath9k.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 33 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/hw.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 8 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 | ||||
-rw-r--r-- | net/wireless/Kconfig | 10 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_ccmp.c | 2 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_tkip.c | 4 |
9 files changed, 81 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index d27813502953..6650f609ece4 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h | |||
@@ -587,8 +587,8 @@ struct ath9k_country_entry { | |||
587 | u8 iso[3]; | 587 | u8 iso[3]; |
588 | }; | 588 | }; |
589 | 589 | ||
590 | #define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg) | 590 | #define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val)) |
591 | #define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg) | 591 | #define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg)) |
592 | 592 | ||
593 | #define SM(_v, _f) (((_v) << _f##_S) & _f) | 593 | #define SM(_v, _f) (((_v) << _f##_S) & _f) |
594 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) | 594 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) |
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 4ca2aed236e0..139566cbbf65 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -701,6 +701,7 @@ struct ath_softc { | |||
701 | struct ath_hal *sc_ah; | 701 | struct ath_hal *sc_ah; |
702 | void __iomem *mem; | 702 | void __iomem *mem; |
703 | spinlock_t sc_resetlock; | 703 | spinlock_t sc_resetlock; |
704 | spinlock_t sc_serial_rw; | ||
704 | struct mutex mutex; | 705 | struct mutex mutex; |
705 | 706 | ||
706 | u8 sc_curbssid[ETH_ALEN]; | 707 | u8 sc_curbssid[ETH_ALEN]; |
@@ -751,4 +752,36 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); | |||
751 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); | 752 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); |
752 | int ath_cabq_update(struct ath_softc *); | 753 | int ath_cabq_update(struct ath_softc *); |
753 | 754 | ||
755 | /* | ||
756 | * Read and write, they both share the same lock. We do this to serialize | ||
757 | * reads and writes on Atheros 802.11n PCI devices only. This is required | ||
758 | * as the FIFO on these devices can only accept sanely 2 requests. After | ||
759 | * that the device goes bananas. Serializing the reads/writes prevents this | ||
760 | * from happening. | ||
761 | */ | ||
762 | |||
763 | static inline void ath9k_iowrite32(struct ath_hal *ah, u32 reg_offset, u32 val) | ||
764 | { | ||
765 | if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) { | ||
766 | unsigned long flags; | ||
767 | spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); | ||
768 | iowrite32(val, ah->ah_sc->mem + reg_offset); | ||
769 | spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); | ||
770 | } else | ||
771 | iowrite32(val, ah->ah_sc->mem + reg_offset); | ||
772 | } | ||
773 | |||
774 | static inline unsigned int ath9k_ioread32(struct ath_hal *ah, u32 reg_offset) | ||
775 | { | ||
776 | u32 val; | ||
777 | if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) { | ||
778 | unsigned long flags; | ||
779 | spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); | ||
780 | val = ioread32(ah->ah_sc->mem + reg_offset); | ||
781 | spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); | ||
782 | } else | ||
783 | val = ioread32(ah->ah_sc->mem + reg_offset); | ||
784 | return val; | ||
785 | } | ||
786 | |||
754 | #endif /* CORE_H */ | 787 | #endif /* CORE_H */ |
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 34474edefc97..c38a00bbce64 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c | |||
@@ -437,6 +437,25 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah) | |||
437 | } | 437 | } |
438 | 438 | ||
439 | ah->ah_config.intr_mitigation = 1; | 439 | ah->ah_config.intr_mitigation = 1; |
440 | |||
441 | /* | ||
442 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) | ||
443 | * _and_ if on non-uniprocessor systems (Multiprocessor/HT). | ||
444 | * This means we use it for all AR5416 devices, and the few | ||
445 | * minor PCI AR9280 devices out there. | ||
446 | * | ||
447 | * Serialization is required because these devices do not handle | ||
448 | * well the case of two concurrent reads/writes due to the latency | ||
449 | * involved. During one read/write another read/write can be issued | ||
450 | * on another CPU while the previous read/write may still be working | ||
451 | * on our hardware, if we hit this case the hardware poops in a loop. | ||
452 | * We prevent this by serializing reads and writes. | ||
453 | * | ||
454 | * This issue is not present on PCI-Express devices or pre-AR5416 | ||
455 | * devices (legacy, 802.11abg). | ||
456 | */ | ||
457 | if (num_possible_cpus() > 1) | ||
458 | ah->ah_config.serialize_regmode = SER_REG_MODE_AUTO; | ||
440 | } | 459 | } |
441 | 460 | ||
442 | static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, | 461 | static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, |
@@ -668,7 +687,8 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
668 | } | 687 | } |
669 | 688 | ||
670 | if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) { | 689 | if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) { |
671 | if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) { | 690 | if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI || |
691 | (AR_SREV_9280(ah) && !ah->ah_isPciExpress)) { | ||
672 | ah->ah_config.serialize_regmode = | 692 | ah->ah_config.serialize_regmode = |
673 | SER_REG_MODE_ON; | 693 | SER_REG_MODE_ON; |
674 | } else { | 694 | } else { |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 0e80990d8e84..3c04044a60bd 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -1336,6 +1336,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1336 | printk(KERN_ERR "Unable to create debugfs files\n"); | 1336 | printk(KERN_ERR "Unable to create debugfs files\n"); |
1337 | 1337 | ||
1338 | spin_lock_init(&sc->sc_resetlock); | 1338 | spin_lock_init(&sc->sc_resetlock); |
1339 | spin_lock_init(&sc->sc_serial_rw); | ||
1339 | mutex_init(&sc->mutex); | 1340 | mutex_init(&sc->mutex); |
1340 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | 1341 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); |
1341 | tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, | 1342 | tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index a611ad857983..847057d682b1 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -575,13 +575,17 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
575 | 575 | ||
576 | r = fill_ctrlset(mac, skb); | 576 | r = fill_ctrlset(mac, skb); |
577 | if (r) | 577 | if (r) |
578 | return r; | 578 | goto fail; |
579 | 579 | ||
580 | info->rate_driver_data[0] = hw; | 580 | info->rate_driver_data[0] = hw; |
581 | 581 | ||
582 | r = zd_usb_tx(&mac->chip.usb, skb); | 582 | r = zd_usb_tx(&mac->chip.usb, skb); |
583 | if (r) | 583 | if (r) |
584 | return r; | 584 | goto fail; |
585 | return 0; | ||
586 | |||
587 | fail: | ||
588 | dev_kfree_skb(skb); | ||
585 | return 0; | 589 | return 0; |
586 | } | 590 | } |
587 | 591 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 94de5033f0b6..37e3d5ef7e3f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -752,6 +752,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
752 | skb_copy_queue_mapping(frag, first); | 752 | skb_copy_queue_mapping(frag, first); |
753 | 753 | ||
754 | frag->do_not_encrypt = first->do_not_encrypt; | 754 | frag->do_not_encrypt = first->do_not_encrypt; |
755 | frag->dev = first->dev; | ||
756 | frag->iif = first->iif; | ||
755 | 757 | ||
756 | pos += copylen; | 758 | pos += copylen; |
757 | left -= copylen; | 759 | left -= copylen; |
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index e28e2b8fa436..092ae6faccca 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig | |||
@@ -102,3 +102,13 @@ config LIB80211_CRYPT_CCMP | |||
102 | 102 | ||
103 | config LIB80211_CRYPT_TKIP | 103 | config LIB80211_CRYPT_TKIP |
104 | tristate | 104 | tristate |
105 | |||
106 | config LIB80211_DEBUG | ||
107 | bool "lib80211 debugging messages" | ||
108 | depends on LIB80211 | ||
109 | default n | ||
110 | ---help--- | ||
111 | You can enable this if you want verbose debugging messages | ||
112 | from lib80211. | ||
113 | |||
114 | If unsure, say N. | ||
diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c index db428194c16a..2301dc1edc4c 100644 --- a/net/wireless/lib80211_crypt_ccmp.c +++ b/net/wireless/lib80211_crypt_ccmp.c | |||
@@ -337,6 +337,7 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
337 | pos += 8; | 337 | pos += 8; |
338 | 338 | ||
339 | if (ccmp_replay_check(pn, key->rx_pn)) { | 339 | if (ccmp_replay_check(pn, key->rx_pn)) { |
340 | #ifdef CONFIG_LIB80211_DEBUG | ||
340 | if (net_ratelimit()) { | 341 | if (net_ratelimit()) { |
341 | printk(KERN_DEBUG "CCMP: replay detected: STA=%pM " | 342 | printk(KERN_DEBUG "CCMP: replay detected: STA=%pM " |
342 | "previous PN %02x%02x%02x%02x%02x%02x " | 343 | "previous PN %02x%02x%02x%02x%02x%02x " |
@@ -346,6 +347,7 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
346 | key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], | 347 | key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], |
347 | pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); | 348 | pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); |
348 | } | 349 | } |
350 | #endif | ||
349 | key->dot11RSNAStatsCCMPReplays++; | 351 | key->dot11RSNAStatsCCMPReplays++; |
350 | return -4; | 352 | return -4; |
351 | } | 353 | } |
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c index 7e8e22bfed90..c36287399d7e 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/net/wireless/lib80211_crypt_tkip.c | |||
@@ -465,12 +465,14 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
465 | pos += 8; | 465 | pos += 8; |
466 | 466 | ||
467 | if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { | 467 | if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { |
468 | #ifdef CONFIG_LIB80211_DEBUG | ||
468 | if (net_ratelimit()) { | 469 | if (net_ratelimit()) { |
469 | printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" | 470 | printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" |
470 | " previous TSC %08x%04x received TSC " | 471 | " previous TSC %08x%04x received TSC " |
471 | "%08x%04x\n", hdr->addr2, | 472 | "%08x%04x\n", hdr->addr2, |
472 | tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); | 473 | tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); |
473 | } | 474 | } |
475 | #endif | ||
474 | tkey->dot11RSNAStatsTKIPReplays++; | 476 | tkey->dot11RSNAStatsTKIPReplays++; |
475 | return -4; | 477 | return -4; |
476 | } | 478 | } |
@@ -505,10 +507,12 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
505 | * it needs to be recalculated for the next packet. */ | 507 | * it needs to be recalculated for the next packet. */ |
506 | tkey->rx_phase1_done = 0; | 508 | tkey->rx_phase1_done = 0; |
507 | } | 509 | } |
510 | #ifdef CONFIG_LIB80211_DEBUG | ||
508 | if (net_ratelimit()) { | 511 | if (net_ratelimit()) { |
509 | printk(KERN_DEBUG "TKIP: ICV error detected: STA=" | 512 | printk(KERN_DEBUG "TKIP: ICV error detected: STA=" |
510 | "%pM\n", hdr->addr2); | 513 | "%pM\n", hdr->addr2); |
511 | } | 514 | } |
515 | #endif | ||
512 | tkey->dot11RSNAStatsTKIPICVErrors++; | 516 | tkey->dot11RSNAStatsTKIPICVErrors++; |
513 | return -5; | 517 | return -5; |
514 | } | 518 | } |