summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/carl9170
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2010-10-30 02:36:53 +0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-15 21:25:35 +0300
commit3eedb6f436858f3e864139dc184adc9a51440c92 (patch)
tree85367b42ac609cffd673c18940a498bf9a4af3cb /drivers/net/wireless/ath/carl9170
parent2a6cef513fab525399e484edc9bfb39b6d462f76 (diff)
downloadlinux-3eedb6f436858f3e864139dc184adc9a51440c92.tar.xz
carl9170: configurable beacon rates
Previously, the beacon rate was fixed to either: * 1Mb/s [2.4GHz band] * 6Mb/s [5GHz band] This limitation has been addressed and now the beacon rate is selected by ieee80211_tx_info's rate control info, almost like any ordinary data frame. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index c34eeeeb8af3..385cf508479b 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct carl9170_vif_info *cvif;
+ struct ieee80211_tx_info *txinfo;
__le32 *data, *old = NULL;
u32 word, off, addr, len;
int i = 0, err = 0;
@@ -487,7 +488,13 @@ found:
if (!skb) {
err = -ENOMEM;
- goto out_unlock;
+ goto err_free;
+ }
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
+ err = -EINVAL;
+ goto err_free;
}
spin_lock_bh(&ar->beacon_lock);
@@ -504,11 +511,8 @@ found:
wiphy_err(ar->hw->wiphy, "beacon does not "
"fit into device memory!\n");
}
-
- spin_unlock_bh(&ar->beacon_lock);
- dev_kfree_skb_any(skb);
err = -EINVAL;
- goto out_unlock;
+ goto err_unlock;
}
if (len > AR9170_MAC_BCN_LENGTH_MAX) {
@@ -518,22 +522,22 @@ found:
AR9170_MAC_BCN_LENGTH_MAX, len);
}
- spin_unlock_bh(&ar->beacon_lock);
- dev_kfree_skb_any(skb);
err = -EMSGSIZE;
- goto out_unlock;
+ goto err_unlock;
}
- carl9170_async_regwrite_begin(ar);
+ i = txinfo->control.rates[0].idx;
+ if (txinfo->band != IEEE80211_BAND_2GHZ)
+ i += 4;
- /* XXX: use skb->cb info */
- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
- carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400);
- } else {
- carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + FCS_LEN) << 16) + 0x001b);
- }
+ word = __carl9170_ratetable[i].hw_value & 0xf;
+ if (i < 4)
+ word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
+ else
+ word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
+
+ carl9170_async_regwrite_begin(ar);
+ carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
/*
@@ -557,7 +561,7 @@ found:
cvif->beacon = skb;
spin_unlock_bh(&ar->beacon_lock);
if (err)
- goto out_unlock;
+ goto err_free;
if (submit) {
err = carl9170_bcn_ctrl(ar, cvif->id,
@@ -565,10 +569,18 @@ found:
addr, skb->len + FCS_LEN);
if (err)
- goto out_unlock;
+ goto err_free;
}
out_unlock:
rcu_read_unlock();
+ return 0;
+
+err_unlock:
+ spin_unlock_bh(&ar->beacon_lock);
+
+err_free:
+ rcu_read_unlock();
+ dev_kfree_skb_any(skb);
return err;
}