Commit f10023a4 authored by David S. Miller's avatar David S. Miller
parents 4ada8107 640c65ea
...@@ -587,8 +587,8 @@ struct ath9k_country_entry { ...@@ -587,8 +587,8 @@ struct ath9k_country_entry {
u8 iso[3]; u8 iso[3];
}; };
#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg) #define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg) #define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
#define SM(_v, _f) (((_v) << _f##_S) & _f) #define SM(_v, _f) (((_v) << _f##_S) & _f)
#define MS(_v, _f) (((_v) & _f) >> _f##_S) #define MS(_v, _f) (((_v) & _f) >> _f##_S)
......
...@@ -701,6 +701,7 @@ struct ath_softc { ...@@ -701,6 +701,7 @@ struct ath_softc {
struct ath_hal *sc_ah; struct ath_hal *sc_ah;
void __iomem *mem; void __iomem *mem;
spinlock_t sc_resetlock; spinlock_t sc_resetlock;
spinlock_t sc_serial_rw;
struct mutex mutex; struct mutex mutex;
u8 sc_curbssid[ETH_ALEN]; u8 sc_curbssid[ETH_ALEN];
...@@ -751,4 +752,36 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); ...@@ -751,4 +752,36 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
int ath_cabq_update(struct ath_softc *); int ath_cabq_update(struct ath_softc *);
/*
* Read and write, they both share the same lock. We do this to serialize
* reads and writes on Atheros 802.11n PCI devices only. This is required
* as the FIFO on these devices can only accept sanely 2 requests. After
* that the device goes bananas. Serializing the reads/writes prevents this
* from happening.
*/
static inline void ath9k_iowrite32(struct ath_hal *ah, u32 reg_offset, u32 val)
{
if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) {
unsigned long flags;
spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
iowrite32(val, ah->ah_sc->mem + reg_offset);
spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
} else
iowrite32(val, ah->ah_sc->mem + reg_offset);
}
static inline unsigned int ath9k_ioread32(struct ath_hal *ah, u32 reg_offset)
{
u32 val;
if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) {
unsigned long flags;
spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
val = ioread32(ah->ah_sc->mem + reg_offset);
spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
} else
val = ioread32(ah->ah_sc->mem + reg_offset);
return val;
}
#endif /* CORE_H */ #endif /* CORE_H */
...@@ -437,6 +437,25 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah) ...@@ -437,6 +437,25 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah)
} }
ah->ah_config.intr_mitigation = 1; ah->ah_config.intr_mitigation = 1;
/*
* We need this for PCI devices only (Cardbus, PCI, miniPCI)
* _and_ if on non-uniprocessor systems (Multiprocessor/HT).
* This means we use it for all AR5416 devices, and the few
* minor PCI AR9280 devices out there.
*
* Serialization is required because these devices do not handle
* well the case of two concurrent reads/writes due to the latency
* involved. During one read/write another read/write can be issued
* on another CPU while the previous read/write may still be working
* on our hardware, if we hit this case the hardware poops in a loop.
* We prevent this by serializing reads and writes.
*
* This issue is not present on PCI-Express devices or pre-AR5416
* devices (legacy, 802.11abg).
*/
if (num_possible_cpus() > 1)
ah->ah_config.serialize_regmode = SER_REG_MODE_AUTO;
} }
static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, 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,7 +687,8 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
} }
if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) { if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI ||
(AR_SREV_9280(ah) && !ah->ah_isPciExpress)) {
ah->ah_config.serialize_regmode = ah->ah_config.serialize_regmode =
SER_REG_MODE_ON; SER_REG_MODE_ON;
} else { } else {
......
...@@ -1336,6 +1336,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1336,6 +1336,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
printk(KERN_ERR "Unable to create debugfs files\n"); printk(KERN_ERR "Unable to create debugfs files\n");
spin_lock_init(&sc->sc_resetlock); spin_lock_init(&sc->sc_resetlock);
spin_lock_init(&sc->sc_serial_rw);
mutex_init(&sc->mutex); mutex_init(&sc->mutex);
tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
......
...@@ -575,13 +575,17 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -575,13 +575,17 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
r = fill_ctrlset(mac, skb); r = fill_ctrlset(mac, skb);
if (r) if (r)
return r; goto fail;
info->rate_driver_data[0] = hw; info->rate_driver_data[0] = hw;
r = zd_usb_tx(&mac->chip.usb, skb); r = zd_usb_tx(&mac->chip.usb, skb);
if (r) if (r)
return r; goto fail;
return 0;
fail:
dev_kfree_skb(skb);
return 0; return 0;
} }
......
...@@ -752,6 +752,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) ...@@ -752,6 +752,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
skb_copy_queue_mapping(frag, first); skb_copy_queue_mapping(frag, first);
frag->do_not_encrypt = first->do_not_encrypt; frag->do_not_encrypt = first->do_not_encrypt;
frag->dev = first->dev;
frag->iif = first->iif;
pos += copylen; pos += copylen;
left -= copylen; left -= copylen;
......
...@@ -102,3 +102,13 @@ config LIB80211_CRYPT_CCMP ...@@ -102,3 +102,13 @@ config LIB80211_CRYPT_CCMP
config LIB80211_CRYPT_TKIP config LIB80211_CRYPT_TKIP
tristate tristate
config LIB80211_DEBUG
bool "lib80211 debugging messages"
depends on LIB80211
default n
---help---
You can enable this if you want verbose debugging messages
from lib80211.
If unsure, say N.
...@@ -337,6 +337,7 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) ...@@ -337,6 +337,7 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
pos += 8; pos += 8;
if (ccmp_replay_check(pn, key->rx_pn)) { if (ccmp_replay_check(pn, key->rx_pn)) {
#ifdef CONFIG_LIB80211_DEBUG
if (net_ratelimit()) { if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: replay detected: STA=%pM " printk(KERN_DEBUG "CCMP: replay detected: STA=%pM "
"previous PN %02x%02x%02x%02x%02x%02x " "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,6 +347,7 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], key->rx_pn[3], key->rx_pn[4], key->rx_pn[5],
pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]);
} }
#endif
key->dot11RSNAStatsCCMPReplays++; key->dot11RSNAStatsCCMPReplays++;
return -4; return -4;
} }
......
...@@ -465,12 +465,14 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) ...@@ -465,12 +465,14 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
pos += 8; pos += 8;
if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
#ifdef CONFIG_LIB80211_DEBUG
if (net_ratelimit()) { if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
" previous TSC %08x%04x received TSC " " previous TSC %08x%04x received TSC "
"%08x%04x\n", hdr->addr2, "%08x%04x\n", hdr->addr2,
tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
} }
#endif
tkey->dot11RSNAStatsTKIPReplays++; tkey->dot11RSNAStatsTKIPReplays++;
return -4; return -4;
} }
...@@ -505,10 +507,12 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) ...@@ -505,10 +507,12 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
* it needs to be recalculated for the next packet. */ * it needs to be recalculated for the next packet. */
tkey->rx_phase1_done = 0; tkey->rx_phase1_done = 0;
} }
#ifdef CONFIG_LIB80211_DEBUG
if (net_ratelimit()) { if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: ICV error detected: STA=" printk(KERN_DEBUG "TKIP: ICV error detected: STA="
"%pM\n", hdr->addr2); "%pM\n", hdr->addr2);
} }
#endif
tkey->dot11RSNAStatsTKIPICVErrors++; tkey->dot11RSNAStatsTKIPICVErrors++;
return -5; return -5;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment