summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c27
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c31
6 files changed, 45 insertions, 37 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index fbaa30930076..44ad6fe0278f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1045,11 +1045,11 @@ ath5k_drain_tx_buffs(struct ath5k_hw *ah)
ath5k_txbuf_free_skb(ah, bf);
- spin_lock_bh(&ah->txbuflock);
+ spin_lock(&ah->txbuflock);
list_move_tail(&bf->list, &ah->txbuf);
ah->txbuf_len++;
txq->txq_len--;
- spin_unlock_bh(&ah->txbuflock);
+ spin_unlock(&ah->txbuflock);
}
txq->link = NULL;
txq->txq_poll_mark = false;
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index a277cf6f339d..4866550ddd96 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -214,6 +214,7 @@ struct ath_frame_info {
enum ath9k_key_type keytype;
u8 keyix;
u8 retries;
+ u8 rtscts_rate;
};
struct ath_buf_state {
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 2b8f61c210e1..abbd6effd60d 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1496,6 +1496,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;
if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
+ ath9k_htc_choose_set_bssid(priv);
if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1))
ath9k_htc_start_ani(priv);
else if (priv->num_sta_assoc_vif == 0)
@@ -1503,13 +1504,11 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
}
}
- if (changed & BSS_CHANGED_BSSID) {
+ if (changed & BSS_CHANGED_IBSS) {
if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
common->curaid = bss_conf->aid;
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
ath9k_htc_set_bssid(priv);
- } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
- ath9k_htc_choose_set_bssid(priv);
}
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 7db1890448f2..1c68e564f503 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -784,13 +784,25 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
{
+ struct ath_common *common = ath9k_hw_common(ah);
+ int i = 0;
+
REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
udelay(100);
REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
- while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
+ while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) {
+
udelay(100);
+ if (WARN_ON_ONCE(i >= 100)) {
+ ath_err(common, "PLL4 meaurement not done\n");
+ break;
+ }
+
+ i++;
+ }
+
return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
}
EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4de4473776ac..dac1a2709e3c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -971,6 +971,15 @@ void ath_hw_pll_work(struct work_struct *work)
hw_pll_work.work);
u32 pll_sqsum;
+ /*
+ * ensure that the PLL WAR is executed only
+ * after the STA is associated (or) if the
+ * beaconing had started in interfaces that
+ * uses beacons.
+ */
+ if (!(sc->sc_flags & SC_OP_BEACONS))
+ return;
+
if (AR_SREV_9485(sc->sc_ah)) {
ath9k_ps_wakeup(sc);
@@ -1443,15 +1452,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
}
}
- if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
- ((vif->type == NL80211_IFTYPE_ADHOC) &&
- sc->nvifs > 0)) {
- ath_err(common, "Cannot create ADHOC interface when other"
- " interfaces already exist.\n");
- ret = -EINVAL;
- goto out;
- }
-
ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
sc->nvifs++;
@@ -1476,15 +1476,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
ath9k_ps_wakeup(sc);
- /* See if new interface type is valid. */
- if ((new_type == NL80211_IFTYPE_ADHOC) &&
- (sc->nvifs > 1)) {
- ath_err(common, "When using ADHOC, it must be the only"
- " interface.\n");
- ret = -EINVAL;
- goto out;
- }
-
if (ath9k_uses_beacons(new_type) &&
!ath9k_uses_beacons(vif->type)) {
if (sc->nbcnvifs >= ATH_BCBUF) {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index d59dd01d6cde..4d571394c7a8 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -938,6 +938,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
struct ieee80211_tx_rate *rates;
const struct ieee80211_rate *rate;
struct ieee80211_hdr *hdr;
+ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
int i;
u8 rix = 0;
@@ -948,18 +949,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
/* set dur_update_en for l-sig computation except for PS-Poll frames */
info->dur_update = !ieee80211_is_pspoll(hdr->frame_control);
-
- /*
- * We check if Short Preamble is needed for the CTS rate by
- * checking the BSS's global flag.
- * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
- */
- rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
- info->rtscts_rate = rate->hw_value;
-
- if (tx_info->control.vif &&
- tx_info->control.vif->bss_conf.use_short_preamble)
- info->rtscts_rate |= rate->hw_value_short;
+ info->rtscts_rate = fi->rtscts_rate;
for (i = 0; i < 4; i++) {
bool is_40, is_sgi, is_sp;
@@ -1001,13 +991,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
}
/* legacy rates */
+ rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
!(rate->flags & IEEE80211_RATE_ERP_G))
phy = WLAN_RC_PHY_CCK;
else
phy = WLAN_RC_PHY_OFDM;
- rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
info->rates[i].Rate = rate->hw_value;
if (rate->hw_value_short) {
if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
@@ -1776,10 +1766,22 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_sta *sta = tx_info->control.sta;
struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ const struct ieee80211_rate *rate;
struct ath_frame_info *fi = get_frame_info(skb);
struct ath_node *an = NULL;
enum ath9k_key_type keytype;
+ bool short_preamble = false;
+
+ /*
+ * We check if Short Preamble is needed for the CTS rate by
+ * checking the BSS's global flag.
+ * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
+ */
+ if (tx_info->control.vif &&
+ tx_info->control.vif->bss_conf.use_short_preamble)
+ short_preamble = true;
+ rate = ieee80211_get_rts_cts_rate(hw, tx_info);
keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
if (sta)
@@ -1794,6 +1796,9 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
fi->keyix = ATH9K_TXKEYIX_INVALID;
fi->keytype = keytype;
fi->framelen = framelen;
+ fi->rtscts_rate = rate->hw_value;
+ if (short_preamble)
+ fi->rtscts_rate |= rate->hw_value_short;
}
u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)