---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1048,6 +1048,8 @@ static int ath9k_start(struct ieee80211_
- "Starting driver with initial channel: %d MHz\n",
- curchan->center_freq);
-
-+ ath9k_ps_wakeup(sc);
-+
- mutex_lock(&sc->mutex);
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -176,6 +176,8 @@ static void ieee80211_send_addba_resp(st
+ memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
++ else if (sdata->vif.type == NL80211_IFTYPE_WDS)
++ memcpy(mgmt->bssid, da, ETH_ALEN);
- /* setup initial channel */
-@@ -1143,6 +1145,8 @@ static int ath9k_start(struct ieee80211_
- mutex_unlock:
- mutex_unlock(&sc->mutex);
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -79,7 +79,8 @@ static void ieee80211_send_addba_request
+ memcpy(mgmt->da, da, ETH_ALEN);
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+- sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
++ sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
++ sdata->vif.type == NL80211_IFTYPE_WDS)
+ memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+@@ -398,7 +399,8 @@ int ieee80211_start_tx_ba_session(struct
+ */
+ if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+- sdata->vif.type != NL80211_IFTYPE_AP)
++ sdata->vif.type != NL80211_IFTYPE_AP &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ return -EINVAL;
-+ ath9k_ps_restore(sc);
-+
- return r;
+ if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
+--- a/net/mac80211/debugfs_sta.c
++++ b/net/mac80211/debugfs_sta.c
+@@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil
+ char buf[100];
+ struct sta_info *sta = file->private_data;
+ u32 staflags = get_sta_flags(sta);
+- int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
++ int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s",
+ staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
+ staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
+ staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
+@@ -67,7 +67,6 @@ static ssize_t sta_flags_read(struct fil
+ staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
+ staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
+ staflags & WLAN_STA_WME ? "WME\n" : "",
+- staflags & WLAN_STA_WDS ? "WDS\n" : "",
+ staflags & WLAN_STA_MFP ? "MFP\n" : "");
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
-
---- a/net/mac80211/ibss.c
-+++ b/net/mac80211/ibss.c
-@@ -661,7 +661,6 @@ static void ieee80211_sta_find_ibss(stru
- static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *req)
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
{
-- struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(req);
- struct ieee80211_mgmt *mgmt = (void *)req->data;
- struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
-@@ -685,7 +684,7 @@ static void ieee80211_rx_mgmt_probe_req(
- mgmt->bssid, tx_last_beacon);
- #endif /* CONFIG_MAC80211_IBSS_DEBUG */
+- struct sta_info *sta;
+ u32 changed = 0;
+ int res;
+ u32 hw_reconf_flags = 0;
+@@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_
-- if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH))
-+ if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
- return;
+ set_bit(SDATA_STATE_RUNNING, &sdata->state);
- if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -659,18 +659,14 @@ minstrel_ht_update_caps(void *priv, stru
- struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
- struct ieee80211_local *local = hw_to_local(mp->hw);
- u16 sta_cap = sta->ht_cap.cap;
-+ int n_supported = 0;
- int ack_dur;
- int stbc;
- int i;
-
- /* fall back to the old minstrel for legacy stations */
-- if (!sta->ht_cap.ht_supported) {
-- msp->is_ht = false;
-- memset(&msp->legacy, 0, sizeof(msp->legacy));
-- msp->legacy.r = msp->ratelist;
-- msp->legacy.sample_table = msp->sample_table;
-- return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy);
+- if (sdata->vif.type == NL80211_IFTYPE_WDS) {
+- /* Create STA entry for the WDS peer */
+- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
+- GFP_KERNEL);
+- if (!sta) {
+- res = -ENOMEM;
+- goto err_del_interface;
+- }
+-
+- /* no locking required since STA is not live yet */
+- sta->flags |= WLAN_STA_AUTHORIZED;
+-
+- res = sta_info_insert(sta);
+- if (res) {
+- /* STA has been freed */
+- goto err_del_interface;
+- }
+-
+- rate_control_rate_init(sta);
- }
-+ if (!sta->ht_cap.ht_supported)
-+ goto use_legacy;
+-
+ /*
+ * set_multicast_list will be invoked by the networking core
+ * which will check whether any increments here were done in
+@@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_
+ netif_tx_start_all_queues(dev);
- BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) !=
- MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS);
-@@ -725,7 +721,22 @@ minstrel_ht_update_caps(void *priv, stru
+ return 0;
+- err_del_interface:
+- drv_remove_interface(local, &sdata->vif);
++
+ err_stop:
+ if (!local->open_count)
+ drv_stop(local);
+@@ -718,6 +695,70 @@ static void ieee80211_if_setup(struct ne
+ dev->destructor = free_netdev;
+ }
- mi->groups[i].supported =
- mcs->rx_mask[minstrel_mcs_groups[i].streams - 1];
++static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
++ struct sk_buff *skb)
++{
++ struct ieee80211_local *local = sdata->local;
++ struct ieee80211_rx_status *rx_status;
++ struct ieee802_11_elems elems;
++ struct ieee80211_mgmt *mgmt;
++ struct sta_info *sta;
++ size_t baselen;
++ u32 rates = 0;
++ u16 stype;
++ bool new = false;
++ enum ieee80211_band band = local->hw.conf.channel->band;
++ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
+
-+ if (mi->groups[i].supported)
-+ n_supported++;
- }
++ rx_status = IEEE80211_SKB_RXCB(skb);
++ mgmt = (struct ieee80211_mgmt *) skb->data;
++ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
+
-+ if (!n_supported)
-+ goto use_legacy;
++ if (stype != IEEE80211_STYPE_BEACON)
++ return;
+
-+ return;
++ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
++ if (baselen > skb->len)
++ return;
+
-+use_legacy:
-+ msp->is_ht = false;
-+ memset(&msp->legacy, 0, sizeof(msp->legacy));
-+ msp->legacy.r = msp->ratelist;
-+ msp->legacy.sample_table = msp->sample_table;
-+ return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy);
- }
-
- static void
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -814,8 +814,8 @@ struct ieee80211_local {
-
- struct rate_control_ref *rate_ctrl;
-
-- struct crypto_blkcipher *wep_tx_tfm;
-- struct crypto_blkcipher *wep_rx_tfm;
-+ struct crypto_cipher *wep_tx_tfm;
-+ struct crypto_cipher *wep_rx_tfm;
- u32 wep_iv;
-
- /* see iface.c */
---- a/net/mac80211/tkip.c
-+++ b/net/mac80211/tkip.c
-@@ -202,7 +202,7 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
- * @payload_len is the length of payload (_not_ including IV/ICV length).
- * @ta is the transmitter addresses.
- */
--int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
-+int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
- struct ieee80211_key *key,
- u8 *pos, size_t payload_len, u8 *ta)
++ ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
++ skb->len - baselen, &elems);
++
++ rates = ieee80211_sta_get_rates(local, &elems, band);
++
++ rcu_read_lock();
++
++ sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
++
++ if (!sta) {
++ rcu_read_unlock();
++ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
++ GFP_KERNEL);
++ if (!sta)
++ return;
++
++ new = true;
++ }
++
++ sta->last_rx = jiffies;
++ sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
++
++ if (elems.ht_cap_elem)
++ ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
++ elems.ht_cap_elem, &sta->sta.ht_cap);
++
++ if (elems.wmm_param)
++ set_sta_flags(sta, WLAN_STA_WME);
++
++ if (new) {
++ sta->flags = WLAN_STA_AUTHORIZED;
++ rate_control_rate_init(sta);
++ sta_info_insert_rcu(sta);
++ }
++
++ rcu_read_unlock();
++}
++
+ static void ieee80211_iface_work(struct work_struct *work)
{
-@@ -223,7 +223,7 @@ int ieee80211_tkip_encrypt_data(struct c
- * beginning of the buffer containing IEEE 802.11 header payload, i.e.,
- * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the
- * length of payload, including IV, Ext. IV, MIC, ICV. */
--int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
-+int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm,
- struct ieee80211_key *key,
- u8 *payload, size_t payload_len, u8 *ta,
- u8 *ra, int only_iv, int queue,
---- a/net/mac80211/tkip.h
-+++ b/net/mac80211/tkip.h
-@@ -15,7 +15,7 @@
-
- u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
-
--int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
-+int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
- struct ieee80211_key *key,
- u8 *pos, size_t payload_len, u8 *ta);
- enum {
-@@ -24,7 +24,7 @@ enum {
- TKIP_DECRYPT_INVALID_KEYIDX = -2,
- TKIP_DECRYPT_REPLAY = -3,
- };
--int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
-+int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm,
- struct ieee80211_key *key,
- u8 *payload, size_t payload_len, u8 *ta,
- u8 *ra, int only_iv, int queue,
---- a/net/mac80211/wep.c
-+++ b/net/mac80211/wep.c
-@@ -30,17 +30,15 @@ int ieee80211_wep_init(struct ieee80211_
- /* start WEP IV from a random value */
- get_random_bytes(&local->wep_iv, WEP_IV_LEN);
-
-- local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
-- CRYPTO_ALG_ASYNC);
-+ local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(local->wep_tx_tfm)) {
- local->wep_rx_tfm = ERR_PTR(-EINVAL);
- return PTR_ERR(local->wep_tx_tfm);
+ struct ieee80211_sub_if_data *sdata =
+@@ -822,6 +863,9 @@ static void ieee80211_iface_work(struct
+ break;
+ ieee80211_mesh_rx_queued_mgmt(sdata, skb);
+ break;
++ case NL80211_IFTYPE_WDS:
++ ieee80211_wds_rx_queued_mgmt(sdata, skb);
++ break;
+ default:
+ WARN(1, "frame for unexpected interface type");
+ break;
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2137,7 +2137,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+ */
+ if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+- sdata->vif.type != NL80211_IFTYPE_AP)
++ sdata->vif.type != NL80211_IFTYPE_AP &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ break;
+
+ /* verify action_code is present */
+@@ -2335,13 +2336,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+
+ if (!ieee80211_vif_is_mesh(&sdata->vif) &&
+ sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+- sdata->vif.type != NL80211_IFTYPE_STATION)
++ sdata->vif.type != NL80211_IFTYPE_STATION &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ return RX_DROP_MONITOR;
+
+ switch (stype) {
+ case cpu_to_le16(IEEE80211_STYPE_BEACON):
+ case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+- /* process for all: mesh, mlme, ibss */
++ /* process for all: mesh, mlme, ibss, wds */
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+ case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+@@ -2680,10 +2682,16 @@ static int prepare_for_handlers(struct i
+ }
+ break;
+ case NL80211_IFTYPE_WDS:
+- if (bssid || !ieee80211_is_data(hdr->frame_control))
+- return 0;
+ if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
+ return 0;
++
++ if (ieee80211_is_data(hdr->frame_control) ||
++ ieee80211_is_action(hdr->frame_control)) {
++ if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
++ return 0;
++ } else if (!ieee80211_is_beacon(hdr->frame_control))
++ return 0;
++
+ break;
+ default:
+ /* should never get here */
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -31,7 +31,6 @@
+ * frames.
+ * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
+ * @WLAN_STA_WME: Station is a QoS-STA.
+- * @WLAN_STA_WDS: Station is one of our WDS peers.
+ * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
+ * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
+ * frame to this station is transmitted.
+@@ -54,7 +53,6 @@ enum ieee80211_sta_info_flags {
+ WLAN_STA_SHORT_PREAMBLE = 1<<4,
+ WLAN_STA_ASSOC_AP = 1<<5,
+ WLAN_STA_WME = 1<<6,
+- WLAN_STA_WDS = 1<<7,
+ WLAN_STA_CLEAR_PS_FILT = 1<<9,
+ WLAN_STA_MFP = 1<<10,
+ WLAN_STA_BLOCK_BA = 1<<11,
+--- a/drivers/net/wireless/ath/ath9k/beacon.c
++++ b/drivers/net/wireless/ath/ath9k/beacon.c
+@@ -384,7 +384,9 @@ void ath_beacon_tasklet(unsigned long da
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "beacon is officially stuck\n");
+ sc->sc_flags |= SC_OP_TSF_RESET;
++ spin_lock(&sc->sc_pcu_lock);
+ ath_reset(sc, true);
++ spin_unlock(&sc->sc_pcu_lock);
+ }
+
+ return;
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -617,8 +617,11 @@ void ath_hw_check(struct work_struct *wo
+ ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
+ "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
+ if (busy >= 99) {
+- if (++sc->hw_busy_count >= 3)
++ if (++sc->hw_busy_count >= 3) {
++ spin_lock_bh(&sc->sc_pcu_lock);
+ ath_reset(sc, true);
++ spin_unlock_bh(&sc->sc_pcu_lock);
++ }
+ } else if (busy >= 0)
+ sc->hw_busy_count = 0;
+
+@@ -637,7 +640,9 @@ static void ath_hw_pll_rx_hang_check(str
+ /* Rx is hung for more than 500ms. Reset it */
+ ath_dbg(common, ATH_DBG_RESET,
+ "Possible RX hang, resetting");
++ spin_lock_bh(&sc->sc_pcu_lock);
+ ath_reset(sc, true);
++ spin_unlock_bh(&sc->sc_pcu_lock);
+ count = 0;
+ }
+ } else
+@@ -674,7 +679,9 @@ void ath9k_tasklet(unsigned long data)
+
+ if ((status & ATH9K_INT_FATAL) ||
+ (status & ATH9K_INT_BB_WATCHDOG)) {
++ spin_lock(&sc->sc_pcu_lock);
+ ath_reset(sc, true);
++ spin_unlock(&sc->sc_pcu_lock);
+ return;
}
-- local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
-- CRYPTO_ALG_ASYNC);
-+ local->wep_rx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(local->wep_rx_tfm)) {
-- crypto_free_blkcipher(local->wep_tx_tfm);
-+ crypto_free_cipher(local->wep_tx_tfm);
- local->wep_tx_tfm = ERR_PTR(-EINVAL);
- return PTR_ERR(local->wep_rx_tfm);
+@@ -980,7 +987,6 @@ int ath_reset(struct ath_softc *sc, bool
+ del_timer_sync(&common->ani.timer);
+
+ ath9k_ps_wakeup(sc);
+- spin_lock_bh(&sc->sc_pcu_lock);
+
+ ieee80211_stop_queues(hw);
+
+@@ -1023,7 +1029,6 @@ int ath_reset(struct ath_softc *sc, bool
}
-@@ -51,9 +49,9 @@ int ieee80211_wep_init(struct ieee80211_
- void ieee80211_wep_free(struct ieee80211_local *local)
- {
- if (!IS_ERR(local->wep_tx_tfm))
-- crypto_free_blkcipher(local->wep_tx_tfm);
-+ crypto_free_cipher(local->wep_tx_tfm);
- if (!IS_ERR(local->wep_rx_tfm))
-- crypto_free_blkcipher(local->wep_rx_tfm);
-+ crypto_free_cipher(local->wep_rx_tfm);
+
+ ieee80211_wake_queues(hw);
+- spin_unlock_bh(&sc->sc_pcu_lock);
+
+ /* Start ANI */
+ if (!common->disable_ani)
+@@ -2326,9 +2331,9 @@ static void ath9k_flush(struct ieee80211
+ ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+ drain_txq = ath_drain_all_txq(sc, false);
+- spin_unlock_bh(&sc->sc_pcu_lock);
+ if (!drain_txq)
+ ath_reset(sc, false);
++ spin_unlock_bh(&sc->sc_pcu_lock);
+ ath9k_ps_restore(sc);
+ ieee80211_wake_queues(hw);
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -565,11 +565,8 @@ static void ath_tx_complete_aggr(struct
+
+ rcu_read_unlock();
+
+- if (needreset) {
+- spin_unlock_bh(&sc->sc_pcu_lock);
++ if (needreset)
+ ath_reset(sc, false);
+- spin_lock_bh(&sc->sc_pcu_lock);
+- }
}
- static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
-@@ -127,12 +125,11 @@ static void ieee80211_wep_remove_iv(stru
- /* Perform WEP encryption using given key. data buffer must have tailroom
- * for 4-byte ICV. data_len must not include this ICV. Note: this function
- * does _not_ add IV. data = RC4(data | CRC32(data)) */
--int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-+int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len)
+ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
+@@ -2169,7 +2166,9 @@ static void ath_tx_complete_poll_work(st
+ if (needreset) {
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
+ "tx hung, resetting the chip\n");
++ spin_lock_bh(&sc->sc_pcu_lock);
+ ath_reset(sc, true);
++ spin_unlock_bh(&sc->sc_pcu_lock);
+ }
+
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+@@ -236,7 +236,7 @@ static void ar9003_paprd_get_gain_table(
+ memset(entry, 0, sizeof(ah->paprd_gain_table_entries));
+ memset(index, 0, sizeof(ah->paprd_gain_table_index));
+
+- for (i = 0; i < 32; i++) {
++ for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
+ entry[i] = REG_READ(ah, reg);
+ index[i] = (entry[i] >> 24) & 0xff;
+ reg += 4;
+@@ -246,13 +246,13 @@ static void ar9003_paprd_get_gain_table(
+ static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain,
+ int target_power)
{
-- struct blkcipher_desc desc = { .tfm = tfm };
-- struct scatterlist sg;
- __le32 icv;
-+ int i;
-
- if (IS_ERR(tfm))
- return -1;
-@@ -140,9 +137,9 @@ int ieee80211_wep_encrypt_data(struct cr
- icv = cpu_to_le32(~crc32_le(~0, data, data_len));
- put_unaligned(icv, (__le32 *)(data + data_len));
-
-- crypto_blkcipher_setkey(tfm, rc4key, klen);
-- sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
-- crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
-+ crypto_cipher_setkey(tfm, rc4key, klen);
-+ for (i = 0; i < data_len + WEP_ICV_LEN; i++)
-+ crypto_cipher_encrypt_one(tfm, data + i, data + i);
+- int olpc_gain_delta = 0;
++ int olpc_gain_delta = 0, cl_gain_mod;
+ int alpha_therm, alpha_volt;
+ int therm_cal_value, volt_cal_value;
+ int therm_value, volt_value;
+ int thermal_gain_corr, voltage_gain_corr;
+ int desired_scale, desired_gain = 0;
+- u32 reg;
++ u32 reg_olpc = 0, reg_cl_gain = 0;
- return 0;
+ REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
+@@ -271,15 +271,29 @@ static unsigned int ar9003_get_desired_g
+ volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4,
+ AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE);
+
+- if (chain == 0)
+- reg = AR_PHY_TPC_11_B0;
+- else if (chain == 1)
+- reg = AR_PHY_TPC_11_B1;
+- else
+- reg = AR_PHY_TPC_11_B2;
++ switch (chain) {
++ case 0:
++ reg_olpc = AR_PHY_TPC_11_B0;
++ reg_cl_gain = AR_PHY_CL_TAB_0;
++ break;
++ case 1:
++ reg_olpc = AR_PHY_TPC_11_B1;
++ reg_cl_gain = AR_PHY_CL_TAB_1;
++ break;
++ case 2:
++ reg_olpc = AR_PHY_TPC_11_B2;
++ reg_cl_gain = AR_PHY_CL_TAB_2;
++ break;
++ default:
++ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
++ "Invalid chainmask: %d\n", chain);
++ break;
++ }
+
+- olpc_gain_delta = REG_READ_FIELD(ah, reg,
++ olpc_gain_delta = REG_READ_FIELD(ah, reg_olpc,
+ AR_PHY_TPC_11_OLPC_GAIN_DELTA);
++ cl_gain_mod = REG_READ_FIELD(ah, reg_cl_gain,
++ AR_PHY_CL_TAB_CL_GAIN_MOD);
+
+ if (olpc_gain_delta >= 128)
+ olpc_gain_delta = olpc_gain_delta - 256;
+@@ -289,7 +303,7 @@ static unsigned int ar9003_get_desired_g
+ voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) +
+ (128 / 2)) / 128;
+ desired_gain = target_power - olpc_gain_delta - thermal_gain_corr -
+- voltage_gain_corr + desired_scale;
++ voltage_gain_corr + desired_scale + cl_gain_mod;
+
+ return desired_gain;
}
-@@ -186,19 +183,18 @@ int ieee80211_wep_encrypt(struct ieee802
- /* Perform WEP decryption using given key. data buffer includes encrypted
- * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV.
- * Return 0 on success and -1 on ICV mismatch. */
--int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-+int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len)
- {
-- struct blkcipher_desc desc = { .tfm = tfm };
-- struct scatterlist sg;
- __le32 crc;
-+ int i;
-
- if (IS_ERR(tfm))
- return -1;
-
-- crypto_blkcipher_setkey(tfm, rc4key, klen);
-- sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
-- crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
-+ crypto_cipher_setkey(tfm, rc4key, klen);
-+ for (i = 0; i < data_len + WEP_ICV_LEN; i++)
-+ crypto_cipher_decrypt_one(tfm, data + i, data + i);
-
- crc = cpu_to_le32(~crc32_le(~0, data, data_len));
- if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0)
---- a/net/mac80211/wep.h
-+++ b/net/mac80211/wep.h
-@@ -18,12 +18,12 @@
-
- int ieee80211_wep_init(struct ieee80211_local *local);
- void ieee80211_wep_free(struct ieee80211_local *local);
--int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-+int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len);
- int ieee80211_wep_encrypt(struct ieee80211_local *local,
- struct sk_buff *skb,
- const u8 *key, int keylen, int keyidx);
--int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-+int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len);
- bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
+@@ -727,7 +741,7 @@ int ar9003_paprd_setup_gain_table(struct
+ desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
+
+ gain_index = 0;
+- for (i = 0; i < 32; i++) {
++ for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
+ if (ah->paprd_gain_table_index[i] >= desired_gain)
+ break;
+ gain_index++;
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+@@ -1121,6 +1121,9 @@
+ #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5 0x3F00
+ #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S 8
+
++#define AR_PHY_CL_TAB_CL_GAIN_MOD 0x1f
++#define AR_PHY_CL_TAB_CL_GAIN_MOD_S 0
++
+ void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
+ #endif /* AR9003_PHY_H */