Loading drivers/net/wireless/ath5k/ath5k.h +5 −0 Original line number Diff line number Diff line Loading @@ -1350,4 +1350,9 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) return retval; } static inline int ath5k_pad_size(int hdrlen) { return (hdrlen < 24) ? 0 : hdrlen & 3; } #endif drivers/net/wireless/ath5k/base.c +21 −17 Original line number Diff line number Diff line Loading @@ -1668,7 +1668,7 @@ ath5k_tasklet_rx(unsigned long data) struct ath5k_desc *ds; int ret; int hdrlen; int pad; int padsize; spin_lock(&sc->rxbuflock); if (list_empty(&sc->rxbuf)) { Loading Loading @@ -1753,16 +1753,19 @@ accept: skb_put(skb, rs.rs_datalen); /* * the hardware adds a padding to 4 byte boundaries between * the header and the payload data if the header length is * not multiples of 4 - remove it */ /* The MAC header is padded to have 32-bit boundary if the * packet payload is non-zero. The general calculation for * padsize would take into account odd header lengths: * padsize = (4 - hdrlen % 4) % 4; However, since only * even-length headers are used, padding can only be 0 or 2 * bytes and we can optimize this a bit. In addition, we must * not try to remove padding from short control frames that do * not have payload. */ hdrlen = ieee80211_get_hdrlen_from_skb(skb); if (hdrlen & 3) { pad = hdrlen % 4; memmove(skb->data + pad, skb->data, hdrlen); skb_pull(skb, pad); padsize = ath5k_pad_size(hdrlen); if (padsize) { memmove(skb->data + padsize, skb->data, hdrlen); skb_pull(skb, padsize); } /* Loading Loading @@ -2623,7 +2626,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct ath5k_buf *bf; unsigned long flags; int hdrlen; int pad; int padsize; ath5k_debug_dump_skb(sc, skb, "TX ", 1); Loading @@ -2635,15 +2638,16 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * if this is not the case we add the padding after the header */ hdrlen = ieee80211_get_hdrlen_from_skb(skb); if (hdrlen & 3) { pad = hdrlen % 4; if (skb_headroom(skb) < pad) { padsize = ath5k_pad_size(hdrlen); if (padsize) { if (skb_headroom(skb) < padsize) { ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough" " headroom to pad %d\n", hdrlen, pad); " headroom to pad %d\n", hdrlen, padsize); return -1; } skb_push(skb, pad); memmove(skb->data, skb->data+pad, hdrlen); skb_push(skb, padsize); memmove(skb->data, skb->data+padsize, hdrlen); } spin_lock_irqsave(&sc->txbuflock, flags); Loading drivers/net/wireless/ath5k/desc.c +2 −2 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, /* Verify and set frame length */ /* remove padding we might have added before */ frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; Loading Loading @@ -202,7 +202,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, /* Verify and set frame length */ /* remove padding we might have added before */ frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; Loading drivers/net/wireless/ath9k/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -701,6 +701,7 @@ struct ath_softc { struct ath_hal *sc_ah; void __iomem *mem; spinlock_t sc_resetlock; struct mutex mutex; u8 sc_curbssid[ETH_ALEN]; u8 sc_myaddr[ETH_ALEN]; Loading drivers/net/wireless/ath9k/main.c +188 −189 Original line number Diff line number Diff line Loading @@ -61,7 +61,6 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz) static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) { if (!sc->sc_curaid) sc->cur_rate_table = sc->hw_rate_table[mode]; /* * All protection frames are transmited at 2Mb/s for Loading Loading @@ -623,38 +622,41 @@ static int ath_get_channel(struct ath_softc *sc, return -1; } /* ext_chan_offset: (-1, 0, 1) (below, none, above) */ static u32 ath_get_extchanmode(struct ath_softc *sc, struct ieee80211_channel *chan, int ext_chan_offset, enum ath9k_ht_macmode tx_chan_width) enum nl80211_channel_type channel_type) { u32 chanmode = 0; switch (chan->band) { case IEEE80211_BAND_2GHZ: if ((ext_chan_offset == 0) && (tx_chan_width == ATH9K_HT_MACMODE_20)) switch(channel_type) { case NL80211_CHAN_NO_HT: case NL80211_CHAN_HT20: chanmode = CHANNEL_G_HT20; if ((ext_chan_offset == 1) && (tx_chan_width == ATH9K_HT_MACMODE_2040)) break; case NL80211_CHAN_HT40PLUS: chanmode = CHANNEL_G_HT40PLUS; if ((ext_chan_offset == -1) && (tx_chan_width == ATH9K_HT_MACMODE_2040)) break; case NL80211_CHAN_HT40MINUS: chanmode = CHANNEL_G_HT40MINUS; break; } break; case IEEE80211_BAND_5GHZ: if ((ext_chan_offset == 0) && (tx_chan_width == ATH9K_HT_MACMODE_20)) switch(channel_type) { case NL80211_CHAN_NO_HT: case NL80211_CHAN_HT20: chanmode = CHANNEL_A_HT20; if ((ext_chan_offset == 1) && (tx_chan_width == ATH9K_HT_MACMODE_2040)) break; case NL80211_CHAN_HT40PLUS: chanmode = CHANNEL_A_HT40PLUS; if ((ext_chan_offset == -1) && (tx_chan_width == ATH9K_HT_MACMODE_2040)) break; case NL80211_CHAN_HT40MINUS: chanmode = CHANNEL_A_HT40MINUS; break; } break; default: break; } Loading @@ -662,13 +664,6 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, return chanmode; } static void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot) { ath9k_hw_keyreset(sc->sc_ah, keyix); if (freeslot) clear_bit(keyix, sc->sc_keymap); } static int ath_keyset(struct ath_softc *sc, u16 keyix, struct ath9k_keyval *hk, const u8 mac[ETH_ALEN]) { Loading @@ -680,21 +675,20 @@ static int ath_keyset(struct ath_softc *sc, u16 keyix, return status != false; } static int ath_setkey_tkip(struct ath_softc *sc, struct ieee80211_key_conf *key, static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, struct ath9k_keyval *hk, const u8 *addr) { u8 *key_rxmic = NULL; u8 *key_txmic = NULL; const u8 *key_rxmic; const u8 *key_txmic; key_txmic = key->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; key_rxmic = key->key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; if (addr == NULL) { /* Group key installation */ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); return ath_keyset(sc, key->keyidx, hk, addr); return ath_keyset(sc, keyix, hk, addr); } if (!sc->sc_splitmic) { /* Loading @@ -703,14 +697,14 @@ static int ath_setkey_tkip(struct ath_softc *sc, */ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); return ath_keyset(sc, key->keyidx, hk, addr); return ath_keyset(sc, keyix, hk, addr); } /* * TX key goes at first index, RX key at +32. * The hal handles the MIC keys at index+64. */ memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); if (!ath_keyset(sc, key->keyidx, hk, NULL)) { if (!ath_keyset(sc, keyix, hk, NULL)) { /* Txmic entry failed. No need to proceed further */ DPRINTF(sc, ATH_DBG_KEYCACHE, "Setting TX MIC Key Failed\n"); Loading @@ -719,18 +713,97 @@ static int ath_setkey_tkip(struct ath_softc *sc, memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); /* XXX delete tx key on failure? */ return ath_keyset(sc, key->keyidx+32, hk, addr); return ath_keyset(sc, keyix + 32, hk, addr); } static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) { int i; for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) { if (test_bit(i, sc->sc_keymap) || test_bit(i + 64, sc->sc_keymap)) continue; /* At least one part of TKIP key allocated */ if (sc->sc_splitmic && (test_bit(i + 32, sc->sc_keymap) || test_bit(i + 64 + 32, sc->sc_keymap))) continue; /* At least one part of TKIP key allocated */ /* Found a free slot for a TKIP key */ return i; } return -1; } static int ath_reserve_key_cache_slot(struct ath_softc *sc) { int i; /* First, try to find slots that would not be available for TKIP. */ if (sc->sc_splitmic) { for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 4; i++) { if (!test_bit(i, sc->sc_keymap) && (test_bit(i + 32, sc->sc_keymap) || test_bit(i + 64, sc->sc_keymap) || test_bit(i + 64 + 32, sc->sc_keymap))) return i; if (!test_bit(i + 32, sc->sc_keymap) && (test_bit(i, sc->sc_keymap) || test_bit(i + 64, sc->sc_keymap) || test_bit(i + 64 + 32, sc->sc_keymap))) return i + 32; if (!test_bit(i + 64, sc->sc_keymap) && (test_bit(i , sc->sc_keymap) || test_bit(i + 32, sc->sc_keymap) || test_bit(i + 64 + 32, sc->sc_keymap))) return i + 64; if (!test_bit(i + 64 + 32, sc->sc_keymap) && (test_bit(i, sc->sc_keymap) || test_bit(i + 32, sc->sc_keymap) || test_bit(i + 64, sc->sc_keymap))) return i + 64 + 32; } } else { for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) { if (!test_bit(i, sc->sc_keymap) && test_bit(i + 64, sc->sc_keymap)) return i; if (test_bit(i, sc->sc_keymap) && !test_bit(i + 64, sc->sc_keymap)) return i + 64; } } /* No partially used TKIP slots, pick any available slot */ for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax; i++) { /* Do not allow slots that could be needed for TKIP group keys * to be used. This limitation could be removed if we know that * TKIP will not be used. */ if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) continue; if (sc->sc_splitmic) { if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) continue; if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) continue; } if (!test_bit(i, sc->sc_keymap)) return i; /* Found a free slot for a key */ } /* No free slot found */ return -1; } static int ath_key_config(struct ath_softc *sc, const u8 *addr, struct ieee80211_key_conf *key) { struct ieee80211_vif *vif; struct ath9k_keyval hk; const u8 *mac = NULL; int ret = 0; enum nl80211_iftype opmode; int idx; memset(&hk, 0, sizeof(hk)); Loading @@ -751,62 +824,66 @@ static int ath_key_config(struct ath_softc *sc, hk.kv_len = key->keylen; memcpy(hk.kv_val, key->key, key->keylen); if (!sc->sc_vaps[0]) return -EIO; if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { /* For now, use the default keys for broadcast keys. This may * need to change with virtual interfaces. */ idx = key->keyidx; } else if (key->keyidx) { struct ieee80211_vif *vif; mac = addr; vif = sc->sc_vaps[0]; opmode = vif->type; /* * Strategy: * For STA mc tx, we will not setup a key at * all since we never tx mc. * * For STA mc rx, we will use the keyID. * * For ADHOC mc tx, we will use the keyID, and no macaddr. * * For ADHOC mc rx, we will alloc a slot and plumb the mac of * the peer node. * BUT we will plumb a cleartext key so that we can do * per-Sta default key table lookup in software. */ if (is_broadcast_ether_addr(addr)) { switch (opmode) { case NL80211_IFTYPE_STATION: /* default key: could be group WPA key * or could be static WEP key */ mac = NULL; break; case NL80211_IFTYPE_ADHOC: break; case NL80211_IFTYPE_AP: break; default: ASSERT(0); break; } if (vif->type != NL80211_IFTYPE_AP) { /* Only keyidx 0 should be used with unicast key, but * allow this for client mode for now. */ idx = key->keyidx; } else return -EIO; } else { mac = addr; if (key->alg == ALG_TKIP) idx = ath_reserve_key_cache_slot_tkip(sc); else idx = ath_reserve_key_cache_slot(sc); if (idx < 0) return -EIO; /* no free key cache entries */ } if (key->alg == ALG_TKIP) ret = ath_setkey_tkip(sc, key, &hk, mac); ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac); else ret = ath_keyset(sc, key->keyidx, &hk, mac); ret = ath_keyset(sc, idx, &hk, mac); if (!ret) return -EIO; return 0; set_bit(idx, sc->sc_keymap); if (key->alg == ALG_TKIP) { set_bit(idx + 64, sc->sc_keymap); if (sc->sc_splitmic) { set_bit(idx + 32, sc->sc_keymap); set_bit(idx + 64 + 32, sc->sc_keymap); } } return idx; } static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) { int freeslot; ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx); if (key->hw_key_idx < IEEE80211_WEP_NKID) return; clear_bit(key->hw_key_idx, sc->sc_keymap); if (key->alg != ALG_TKIP) return; freeslot = (key->keyidx >= 4) ? 1 : 0; ath_key_reset(sc, key->keyidx, freeslot); clear_bit(key->hw_key_idx + 64, sc->sc_keymap); if (sc->sc_splitmic) { clear_bit(key->hw_key_idx + 32, sc->sc_keymap); clear_bit(key->hw_key_idx + 64 + 32, sc->sc_keymap); } } static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) Loading @@ -829,45 +906,15 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; } static void ath9k_ht_conf(struct ath_softc *sc, struct ieee80211_bss_conf *bss_conf) { if (sc->hw->conf.ht.enabled) { if (bss_conf->ht.width_40_ok) sc->tx_chan_width = ATH9K_HT_MACMODE_2040; else sc->tx_chan_width = ATH9K_HT_MACMODE_20; ath9k_hw_set11nmac2040(sc->sc_ah, sc->tx_chan_width); DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed HT, chanwidth: %d\n", sc->tx_chan_width); } } static inline int ath_sec_offset(u8 ext_offset) { if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) return 0; else if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) return 1; else if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) return -1; return 0; } static void ath9k_bss_assoc_info(struct ath_softc *sc, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf) { struct ieee80211_hw *hw = sc->hw; struct ieee80211_channel *curchan = hw->conf.channel; struct ath_vap *avp = (void *)vif->drv_priv; int pos; if (bss_conf->assoc) { DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d\n", bss_conf->aid); DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", bss_conf->aid, sc->sc_curbssid); /* New association, store aid */ if (avp->av_opmode == NL80211_IFTYPE_STATION) { Loading @@ -886,40 +933,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; /* Update chainmask */ ath_update_chainmask(sc, hw->conf.ht.enabled); DPRINTF(sc, ATH_DBG_CONFIG, "bssid %pM aid 0x%x\n", sc->sc_curbssid, sc->sc_curaid); pos = ath_get_channel(sc, curchan); if (pos == -1) { DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); return; } if (hw->conf.ht.enabled) { int offset = ath_sec_offset(bss_conf->ht.secondary_channel_offset); sc->tx_chan_width = (bss_conf->ht.width_40_ok) ? ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20; sc->sc_ah->ah_channels[pos].chanmode = ath_get_extchanmode(sc, curchan, offset, sc->tx_chan_width); } else { sc->sc_ah->ah_channels[pos].chanmode = (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; } /* set h/w channel */ if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel: %d\n", curchan->center_freq); /* Start ANI */ mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); Loading Loading @@ -1291,9 +1304,6 @@ static void ath_detach(struct ath_softc *sc) ath_deinit_leds(sc); ieee80211_unregister_hw(hw); ath_rate_control_unregister(); ath_rx_cleanup(sc); ath_tx_cleanup(sc); Loading Loading @@ -1326,6 +1336,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) printk(KERN_ERR "Unable to create debugfs files\n"); spin_lock_init(&sc->sc_resetlock); mutex_init(&sc->mutex); tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, (unsigned long)sc); Loading Loading @@ -1362,18 +1373,6 @@ static int ath_init(u16 devid, struct ath_softc *sc) */ for (i = 0; i < sc->sc_keymax; i++) ath9k_hw_keyreset(ah, (u16) i); /* * Mark key cache slots associated with global keys * as in use. If we knew TKIP was not to be used we * could leave the +32, +64, and +32+64 slots free. * XXX only for splitmic. */ for (i = 0; i < IEEE80211_WEP_NKID; i++) { set_bit(i, sc->sc_keymap); set_bit(i + 32, sc->sc_keymap); set_bit(i + 64, sc->sc_keymap); set_bit(i + 32 + 64, sc->sc_keymap); } /* Collect the channel list using the default country code */ Loading Loading @@ -1574,15 +1573,7 @@ static int ath_attach(u16 devid, struct ath_softc *sc) hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vap); /* Register rate control */ hw->rate_control_algorithm = "ath9k_rate_control"; error = ath_rate_control_register(); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to register rate control algorithm: %d\n", error); ath_rate_control_unregister(); goto bad; } if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); Loading Loading @@ -1615,10 +1606,6 @@ static int ath_attach(u16 devid, struct ath_softc *sc) #endif error = ieee80211_register_hw(hw); if (error != 0) { ath_rate_control_unregister(); goto bad; } /* Initialize LED control */ ath_init_leds(sc); Loading @@ -1626,7 +1613,6 @@ static int ath_attach(u16 devid, struct ath_softc *sc) return 0; detach: ath_detach(sc); bad: return error; } Loading Loading @@ -2146,7 +2132,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ath_softc *sc = hw->priv; struct ieee80211_conf *conf = &hw->conf; if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { mutex_lock(&sc->mutex); if (changed & (IEEE80211_CONF_CHANGE_CHANNEL | IEEE80211_CONF_CHANGE_HT)) { struct ieee80211_channel *curchan = hw->conf.channel; int pos; Loading @@ -2157,6 +2145,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (pos == -1) { DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); mutex_unlock(&sc->mutex); return -EINVAL; } Loading @@ -2165,29 +2154,29 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) && (conf->ht.enabled)) { sc->tx_chan_width = (!!conf->ht.sec_chan_offset) ? ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20; if (conf->ht.enabled) { if (conf->ht.channel_type == NL80211_CHAN_HT40PLUS || conf->ht.channel_type == NL80211_CHAN_HT40MINUS) sc->tx_chan_width = ATH9K_HT_MACMODE_2040; sc->sc_ah->ah_channels[pos].chanmode = ath_get_extchanmode(sc, curchan, conf->ht.sec_chan_offset, sc->tx_chan_width); conf->ht.channel_type); } if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); mutex_unlock(&sc->mutex); return -EINVAL; } } if (changed & IEEE80211_CONF_CHANGE_HT) ath_update_chainmask(sc, conf->ht.enabled); } if (changed & IEEE80211_CONF_CHANGE_POWER) sc->sc_config.txpowlimit = 2 * conf->power_level; mutex_unlock(&sc->mutex); return 0; } Loading Loading @@ -2371,18 +2360,17 @@ static int ath9k_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: ret = ath_key_config(sc, addr, key); if (!ret) { set_bit(key->keyidx, sc->sc_keymap); key->hw_key_idx = key->keyidx; if (ret >= 0) { key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; if (key->alg == ALG_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; ret = 0; } break; case DISABLE_KEY: ath_key_delete(sc, key); clear_bit(key->keyidx, sc->sc_keymap); break; default: ret = -EINVAL; Loading Loading @@ -2417,9 +2405,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; } if (changed & BSS_CHANGED_HT) ath9k_ht_conf(sc, bss_conf); if (changed & BSS_CHANGED_ASSOC) { DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", bss_conf->assoc); Loading Loading @@ -2780,11 +2765,24 @@ static struct pci_driver ath_pci_driver = { static int __init init_ath_pci(void) { int error; printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION); /* Register rate control algorithm */ error = ath_rate_control_register(); if (error != 0) { printk(KERN_ERR "Unable to register rate control algorithm: %d\n", error); ath_rate_control_unregister(); return error; } if (pci_register_driver(&ath_pci_driver) < 0) { printk(KERN_ERR "ath_pci: No devices found, driver not installed.\n"); ath_rate_control_unregister(); pci_unregister_driver(&ath_pci_driver); return -ENODEV; } Loading @@ -2795,6 +2793,7 @@ module_init(init_ath_pci); static void __exit exit_ath_pci(void) { ath_rate_control_unregister(); pci_unregister_driver(&ath_pci_driver); printk(KERN_INFO "%s: Driver unloaded\n", dev_info); } Loading Loading
drivers/net/wireless/ath5k/ath5k.h +5 −0 Original line number Diff line number Diff line Loading @@ -1350,4 +1350,9 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) return retval; } static inline int ath5k_pad_size(int hdrlen) { return (hdrlen < 24) ? 0 : hdrlen & 3; } #endif
drivers/net/wireless/ath5k/base.c +21 −17 Original line number Diff line number Diff line Loading @@ -1668,7 +1668,7 @@ ath5k_tasklet_rx(unsigned long data) struct ath5k_desc *ds; int ret; int hdrlen; int pad; int padsize; spin_lock(&sc->rxbuflock); if (list_empty(&sc->rxbuf)) { Loading Loading @@ -1753,16 +1753,19 @@ accept: skb_put(skb, rs.rs_datalen); /* * the hardware adds a padding to 4 byte boundaries between * the header and the payload data if the header length is * not multiples of 4 - remove it */ /* The MAC header is padded to have 32-bit boundary if the * packet payload is non-zero. The general calculation for * padsize would take into account odd header lengths: * padsize = (4 - hdrlen % 4) % 4; However, since only * even-length headers are used, padding can only be 0 or 2 * bytes and we can optimize this a bit. In addition, we must * not try to remove padding from short control frames that do * not have payload. */ hdrlen = ieee80211_get_hdrlen_from_skb(skb); if (hdrlen & 3) { pad = hdrlen % 4; memmove(skb->data + pad, skb->data, hdrlen); skb_pull(skb, pad); padsize = ath5k_pad_size(hdrlen); if (padsize) { memmove(skb->data + padsize, skb->data, hdrlen); skb_pull(skb, padsize); } /* Loading Loading @@ -2623,7 +2626,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct ath5k_buf *bf; unsigned long flags; int hdrlen; int pad; int padsize; ath5k_debug_dump_skb(sc, skb, "TX ", 1); Loading @@ -2635,15 +2638,16 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * if this is not the case we add the padding after the header */ hdrlen = ieee80211_get_hdrlen_from_skb(skb); if (hdrlen & 3) { pad = hdrlen % 4; if (skb_headroom(skb) < pad) { padsize = ath5k_pad_size(hdrlen); if (padsize) { if (skb_headroom(skb) < padsize) { ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough" " headroom to pad %d\n", hdrlen, pad); " headroom to pad %d\n", hdrlen, padsize); return -1; } skb_push(skb, pad); memmove(skb->data, skb->data+pad, hdrlen); skb_push(skb, padsize); memmove(skb->data, skb->data+padsize, hdrlen); } spin_lock_irqsave(&sc->txbuflock, flags); Loading
drivers/net/wireless/ath5k/desc.c +2 −2 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, /* Verify and set frame length */ /* remove padding we might have added before */ frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; Loading Loading @@ -202,7 +202,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, /* Verify and set frame length */ /* remove padding we might have added before */ frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; Loading
drivers/net/wireless/ath9k/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -701,6 +701,7 @@ struct ath_softc { struct ath_hal *sc_ah; void __iomem *mem; spinlock_t sc_resetlock; struct mutex mutex; u8 sc_curbssid[ETH_ALEN]; u8 sc_myaddr[ETH_ALEN]; Loading
drivers/net/wireless/ath9k/main.c +188 −189 Original line number Diff line number Diff line Loading @@ -61,7 +61,6 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz) static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) { if (!sc->sc_curaid) sc->cur_rate_table = sc->hw_rate_table[mode]; /* * All protection frames are transmited at 2Mb/s for Loading Loading @@ -623,38 +622,41 @@ static int ath_get_channel(struct ath_softc *sc, return -1; } /* ext_chan_offset: (-1, 0, 1) (below, none, above) */ static u32 ath_get_extchanmode(struct ath_softc *sc, struct ieee80211_channel *chan, int ext_chan_offset, enum ath9k_ht_macmode tx_chan_width) enum nl80211_channel_type channel_type) { u32 chanmode = 0; switch (chan->band) { case IEEE80211_BAND_2GHZ: if ((ext_chan_offset == 0) && (tx_chan_width == ATH9K_HT_MACMODE_20)) switch(channel_type) { case NL80211_CHAN_NO_HT: case NL80211_CHAN_HT20: chanmode = CHANNEL_G_HT20; if ((ext_chan_offset == 1) && (tx_chan_width == ATH9K_HT_MACMODE_2040)) break; case NL80211_CHAN_HT40PLUS: chanmode = CHANNEL_G_HT40PLUS; if ((ext_chan_offset == -1) && (tx_chan_width == ATH9K_HT_MACMODE_2040)) break; case NL80211_CHAN_HT40MINUS: chanmode = CHANNEL_G_HT40MINUS; break; } break; case IEEE80211_BAND_5GHZ: if ((ext_chan_offset == 0) && (tx_chan_width == ATH9K_HT_MACMODE_20)) switch(channel_type) { case NL80211_CHAN_NO_HT: case NL80211_CHAN_HT20: chanmode = CHANNEL_A_HT20; if ((ext_chan_offset == 1) && (tx_chan_width == ATH9K_HT_MACMODE_2040)) break; case NL80211_CHAN_HT40PLUS: chanmode = CHANNEL_A_HT40PLUS; if ((ext_chan_offset == -1) && (tx_chan_width == ATH9K_HT_MACMODE_2040)) break; case NL80211_CHAN_HT40MINUS: chanmode = CHANNEL_A_HT40MINUS; break; } break; default: break; } Loading @@ -662,13 +664,6 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, return chanmode; } static void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot) { ath9k_hw_keyreset(sc->sc_ah, keyix); if (freeslot) clear_bit(keyix, sc->sc_keymap); } static int ath_keyset(struct ath_softc *sc, u16 keyix, struct ath9k_keyval *hk, const u8 mac[ETH_ALEN]) { Loading @@ -680,21 +675,20 @@ static int ath_keyset(struct ath_softc *sc, u16 keyix, return status != false; } static int ath_setkey_tkip(struct ath_softc *sc, struct ieee80211_key_conf *key, static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, struct ath9k_keyval *hk, const u8 *addr) { u8 *key_rxmic = NULL; u8 *key_txmic = NULL; const u8 *key_rxmic; const u8 *key_txmic; key_txmic = key->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; key_rxmic = key->key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; if (addr == NULL) { /* Group key installation */ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); return ath_keyset(sc, key->keyidx, hk, addr); return ath_keyset(sc, keyix, hk, addr); } if (!sc->sc_splitmic) { /* Loading @@ -703,14 +697,14 @@ static int ath_setkey_tkip(struct ath_softc *sc, */ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); return ath_keyset(sc, key->keyidx, hk, addr); return ath_keyset(sc, keyix, hk, addr); } /* * TX key goes at first index, RX key at +32. * The hal handles the MIC keys at index+64. */ memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); if (!ath_keyset(sc, key->keyidx, hk, NULL)) { if (!ath_keyset(sc, keyix, hk, NULL)) { /* Txmic entry failed. No need to proceed further */ DPRINTF(sc, ATH_DBG_KEYCACHE, "Setting TX MIC Key Failed\n"); Loading @@ -719,18 +713,97 @@ static int ath_setkey_tkip(struct ath_softc *sc, memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); /* XXX delete tx key on failure? */ return ath_keyset(sc, key->keyidx+32, hk, addr); return ath_keyset(sc, keyix + 32, hk, addr); } static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) { int i; for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) { if (test_bit(i, sc->sc_keymap) || test_bit(i + 64, sc->sc_keymap)) continue; /* At least one part of TKIP key allocated */ if (sc->sc_splitmic && (test_bit(i + 32, sc->sc_keymap) || test_bit(i + 64 + 32, sc->sc_keymap))) continue; /* At least one part of TKIP key allocated */ /* Found a free slot for a TKIP key */ return i; } return -1; } static int ath_reserve_key_cache_slot(struct ath_softc *sc) { int i; /* First, try to find slots that would not be available for TKIP. */ if (sc->sc_splitmic) { for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 4; i++) { if (!test_bit(i, sc->sc_keymap) && (test_bit(i + 32, sc->sc_keymap) || test_bit(i + 64, sc->sc_keymap) || test_bit(i + 64 + 32, sc->sc_keymap))) return i; if (!test_bit(i + 32, sc->sc_keymap) && (test_bit(i, sc->sc_keymap) || test_bit(i + 64, sc->sc_keymap) || test_bit(i + 64 + 32, sc->sc_keymap))) return i + 32; if (!test_bit(i + 64, sc->sc_keymap) && (test_bit(i , sc->sc_keymap) || test_bit(i + 32, sc->sc_keymap) || test_bit(i + 64 + 32, sc->sc_keymap))) return i + 64; if (!test_bit(i + 64 + 32, sc->sc_keymap) && (test_bit(i, sc->sc_keymap) || test_bit(i + 32, sc->sc_keymap) || test_bit(i + 64, sc->sc_keymap))) return i + 64 + 32; } } else { for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) { if (!test_bit(i, sc->sc_keymap) && test_bit(i + 64, sc->sc_keymap)) return i; if (test_bit(i, sc->sc_keymap) && !test_bit(i + 64, sc->sc_keymap)) return i + 64; } } /* No partially used TKIP slots, pick any available slot */ for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax; i++) { /* Do not allow slots that could be needed for TKIP group keys * to be used. This limitation could be removed if we know that * TKIP will not be used. */ if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) continue; if (sc->sc_splitmic) { if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) continue; if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) continue; } if (!test_bit(i, sc->sc_keymap)) return i; /* Found a free slot for a key */ } /* No free slot found */ return -1; } static int ath_key_config(struct ath_softc *sc, const u8 *addr, struct ieee80211_key_conf *key) { struct ieee80211_vif *vif; struct ath9k_keyval hk; const u8 *mac = NULL; int ret = 0; enum nl80211_iftype opmode; int idx; memset(&hk, 0, sizeof(hk)); Loading @@ -751,62 +824,66 @@ static int ath_key_config(struct ath_softc *sc, hk.kv_len = key->keylen; memcpy(hk.kv_val, key->key, key->keylen); if (!sc->sc_vaps[0]) return -EIO; if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { /* For now, use the default keys for broadcast keys. This may * need to change with virtual interfaces. */ idx = key->keyidx; } else if (key->keyidx) { struct ieee80211_vif *vif; mac = addr; vif = sc->sc_vaps[0]; opmode = vif->type; /* * Strategy: * For STA mc tx, we will not setup a key at * all since we never tx mc. * * For STA mc rx, we will use the keyID. * * For ADHOC mc tx, we will use the keyID, and no macaddr. * * For ADHOC mc rx, we will alloc a slot and plumb the mac of * the peer node. * BUT we will plumb a cleartext key so that we can do * per-Sta default key table lookup in software. */ if (is_broadcast_ether_addr(addr)) { switch (opmode) { case NL80211_IFTYPE_STATION: /* default key: could be group WPA key * or could be static WEP key */ mac = NULL; break; case NL80211_IFTYPE_ADHOC: break; case NL80211_IFTYPE_AP: break; default: ASSERT(0); break; } if (vif->type != NL80211_IFTYPE_AP) { /* Only keyidx 0 should be used with unicast key, but * allow this for client mode for now. */ idx = key->keyidx; } else return -EIO; } else { mac = addr; if (key->alg == ALG_TKIP) idx = ath_reserve_key_cache_slot_tkip(sc); else idx = ath_reserve_key_cache_slot(sc); if (idx < 0) return -EIO; /* no free key cache entries */ } if (key->alg == ALG_TKIP) ret = ath_setkey_tkip(sc, key, &hk, mac); ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac); else ret = ath_keyset(sc, key->keyidx, &hk, mac); ret = ath_keyset(sc, idx, &hk, mac); if (!ret) return -EIO; return 0; set_bit(idx, sc->sc_keymap); if (key->alg == ALG_TKIP) { set_bit(idx + 64, sc->sc_keymap); if (sc->sc_splitmic) { set_bit(idx + 32, sc->sc_keymap); set_bit(idx + 64 + 32, sc->sc_keymap); } } return idx; } static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) { int freeslot; ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx); if (key->hw_key_idx < IEEE80211_WEP_NKID) return; clear_bit(key->hw_key_idx, sc->sc_keymap); if (key->alg != ALG_TKIP) return; freeslot = (key->keyidx >= 4) ? 1 : 0; ath_key_reset(sc, key->keyidx, freeslot); clear_bit(key->hw_key_idx + 64, sc->sc_keymap); if (sc->sc_splitmic) { clear_bit(key->hw_key_idx + 32, sc->sc_keymap); clear_bit(key->hw_key_idx + 64 + 32, sc->sc_keymap); } } static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) Loading @@ -829,45 +906,15 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; } static void ath9k_ht_conf(struct ath_softc *sc, struct ieee80211_bss_conf *bss_conf) { if (sc->hw->conf.ht.enabled) { if (bss_conf->ht.width_40_ok) sc->tx_chan_width = ATH9K_HT_MACMODE_2040; else sc->tx_chan_width = ATH9K_HT_MACMODE_20; ath9k_hw_set11nmac2040(sc->sc_ah, sc->tx_chan_width); DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed HT, chanwidth: %d\n", sc->tx_chan_width); } } static inline int ath_sec_offset(u8 ext_offset) { if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) return 0; else if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) return 1; else if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) return -1; return 0; } static void ath9k_bss_assoc_info(struct ath_softc *sc, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf) { struct ieee80211_hw *hw = sc->hw; struct ieee80211_channel *curchan = hw->conf.channel; struct ath_vap *avp = (void *)vif->drv_priv; int pos; if (bss_conf->assoc) { DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d\n", bss_conf->aid); DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", bss_conf->aid, sc->sc_curbssid); /* New association, store aid */ if (avp->av_opmode == NL80211_IFTYPE_STATION) { Loading @@ -886,40 +933,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; /* Update chainmask */ ath_update_chainmask(sc, hw->conf.ht.enabled); DPRINTF(sc, ATH_DBG_CONFIG, "bssid %pM aid 0x%x\n", sc->sc_curbssid, sc->sc_curaid); pos = ath_get_channel(sc, curchan); if (pos == -1) { DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); return; } if (hw->conf.ht.enabled) { int offset = ath_sec_offset(bss_conf->ht.secondary_channel_offset); sc->tx_chan_width = (bss_conf->ht.width_40_ok) ? ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20; sc->sc_ah->ah_channels[pos].chanmode = ath_get_extchanmode(sc, curchan, offset, sc->tx_chan_width); } else { sc->sc_ah->ah_channels[pos].chanmode = (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; } /* set h/w channel */ if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel: %d\n", curchan->center_freq); /* Start ANI */ mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); Loading Loading @@ -1291,9 +1304,6 @@ static void ath_detach(struct ath_softc *sc) ath_deinit_leds(sc); ieee80211_unregister_hw(hw); ath_rate_control_unregister(); ath_rx_cleanup(sc); ath_tx_cleanup(sc); Loading Loading @@ -1326,6 +1336,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) printk(KERN_ERR "Unable to create debugfs files\n"); spin_lock_init(&sc->sc_resetlock); mutex_init(&sc->mutex); tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, (unsigned long)sc); Loading Loading @@ -1362,18 +1373,6 @@ static int ath_init(u16 devid, struct ath_softc *sc) */ for (i = 0; i < sc->sc_keymax; i++) ath9k_hw_keyreset(ah, (u16) i); /* * Mark key cache slots associated with global keys * as in use. If we knew TKIP was not to be used we * could leave the +32, +64, and +32+64 slots free. * XXX only for splitmic. */ for (i = 0; i < IEEE80211_WEP_NKID; i++) { set_bit(i, sc->sc_keymap); set_bit(i + 32, sc->sc_keymap); set_bit(i + 64, sc->sc_keymap); set_bit(i + 32 + 64, sc->sc_keymap); } /* Collect the channel list using the default country code */ Loading Loading @@ -1574,15 +1573,7 @@ static int ath_attach(u16 devid, struct ath_softc *sc) hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vap); /* Register rate control */ hw->rate_control_algorithm = "ath9k_rate_control"; error = ath_rate_control_register(); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to register rate control algorithm: %d\n", error); ath_rate_control_unregister(); goto bad; } if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); Loading Loading @@ -1615,10 +1606,6 @@ static int ath_attach(u16 devid, struct ath_softc *sc) #endif error = ieee80211_register_hw(hw); if (error != 0) { ath_rate_control_unregister(); goto bad; } /* Initialize LED control */ ath_init_leds(sc); Loading @@ -1626,7 +1613,6 @@ static int ath_attach(u16 devid, struct ath_softc *sc) return 0; detach: ath_detach(sc); bad: return error; } Loading Loading @@ -2146,7 +2132,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ath_softc *sc = hw->priv; struct ieee80211_conf *conf = &hw->conf; if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { mutex_lock(&sc->mutex); if (changed & (IEEE80211_CONF_CHANGE_CHANNEL | IEEE80211_CONF_CHANGE_HT)) { struct ieee80211_channel *curchan = hw->conf.channel; int pos; Loading @@ -2157,6 +2145,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (pos == -1) { DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); mutex_unlock(&sc->mutex); return -EINVAL; } Loading @@ -2165,29 +2154,29 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) && (conf->ht.enabled)) { sc->tx_chan_width = (!!conf->ht.sec_chan_offset) ? ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20; if (conf->ht.enabled) { if (conf->ht.channel_type == NL80211_CHAN_HT40PLUS || conf->ht.channel_type == NL80211_CHAN_HT40MINUS) sc->tx_chan_width = ATH9K_HT_MACMODE_2040; sc->sc_ah->ah_channels[pos].chanmode = ath_get_extchanmode(sc, curchan, conf->ht.sec_chan_offset, sc->tx_chan_width); conf->ht.channel_type); } if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); mutex_unlock(&sc->mutex); return -EINVAL; } } if (changed & IEEE80211_CONF_CHANGE_HT) ath_update_chainmask(sc, conf->ht.enabled); } if (changed & IEEE80211_CONF_CHANGE_POWER) sc->sc_config.txpowlimit = 2 * conf->power_level; mutex_unlock(&sc->mutex); return 0; } Loading Loading @@ -2371,18 +2360,17 @@ static int ath9k_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: ret = ath_key_config(sc, addr, key); if (!ret) { set_bit(key->keyidx, sc->sc_keymap); key->hw_key_idx = key->keyidx; if (ret >= 0) { key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; if (key->alg == ALG_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; ret = 0; } break; case DISABLE_KEY: ath_key_delete(sc, key); clear_bit(key->keyidx, sc->sc_keymap); break; default: ret = -EINVAL; Loading Loading @@ -2417,9 +2405,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; } if (changed & BSS_CHANGED_HT) ath9k_ht_conf(sc, bss_conf); if (changed & BSS_CHANGED_ASSOC) { DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", bss_conf->assoc); Loading Loading @@ -2780,11 +2765,24 @@ static struct pci_driver ath_pci_driver = { static int __init init_ath_pci(void) { int error; printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION); /* Register rate control algorithm */ error = ath_rate_control_register(); if (error != 0) { printk(KERN_ERR "Unable to register rate control algorithm: %d\n", error); ath_rate_control_unregister(); return error; } if (pci_register_driver(&ath_pci_driver) < 0) { printk(KERN_ERR "ath_pci: No devices found, driver not installed.\n"); ath_rate_control_unregister(); pci_unregister_driver(&ath_pci_driver); return -ENODEV; } Loading @@ -2795,6 +2793,7 @@ module_init(init_ath_pci); static void __exit exit_ath_pci(void) { ath_rate_control_unregister(); pci_unregister_driver(&ath_pci_driver); printk(KERN_INFO "%s: Driver unloaded\n", dev_info); } Loading