Commit 3eedb6f4 authored by Christian Lamparter's avatar Christian Lamparter Committed by John W. Linville

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: default avatarChristian Lamparter <chunkeey@googlemail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2a6cef51
...@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar) ...@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
int carl9170_update_beacon(struct ar9170 *ar, const bool submit) 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 carl9170_vif_info *cvif;
struct ieee80211_tx_info *txinfo;
__le32 *data, *old = NULL; __le32 *data, *old = NULL;
u32 word, off, addr, len; u32 word, off, addr, len;
int i = 0, err = 0; int i = 0, err = 0;
...@@ -487,7 +488,13 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit) ...@@ -487,7 +488,13 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
if (!skb) { if (!skb) {
err = -ENOMEM; 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); spin_lock_bh(&ar->beacon_lock);
...@@ -504,11 +511,8 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit) ...@@ -504,11 +511,8 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
wiphy_err(ar->hw->wiphy, "beacon does not " wiphy_err(ar->hw->wiphy, "beacon does not "
"fit into device memory!\n"); "fit into device memory!\n");
} }
spin_unlock_bh(&ar->beacon_lock);
dev_kfree_skb_any(skb);
err = -EINVAL; err = -EINVAL;
goto out_unlock; goto err_unlock;
} }
if (len > AR9170_MAC_BCN_LENGTH_MAX) { if (len > AR9170_MAC_BCN_LENGTH_MAX) {
...@@ -518,22 +522,22 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit) ...@@ -518,22 +522,22 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
AR9170_MAC_BCN_LENGTH_MAX, len); AR9170_MAC_BCN_LENGTH_MAX, len);
} }
spin_unlock_bh(&ar->beacon_lock);
dev_kfree_skb_any(skb);
err = -EMSGSIZE; 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 */ word = __carl9170_ratetable[i].hw_value & 0xf;
if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { if (i < 4)
carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
((skb->len + FCS_LEN) << (3 + 16)) + 0x0400); else
} else { word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
((skb->len + FCS_LEN) << 16) + 0x001b); 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++) { for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
/* /*
...@@ -557,7 +561,7 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit) ...@@ -557,7 +561,7 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
cvif->beacon = skb; cvif->beacon = skb;
spin_unlock_bh(&ar->beacon_lock); spin_unlock_bh(&ar->beacon_lock);
if (err) if (err)
goto out_unlock; goto err_free;
if (submit) { if (submit) {
err = carl9170_bcn_ctrl(ar, cvif->id, err = carl9170_bcn_ctrl(ar, cvif->id,
...@@ -565,10 +569,18 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit) ...@@ -565,10 +569,18 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
addr, skb->len + FCS_LEN); addr, skb->len + FCS_LEN);
if (err) if (err)
goto out_unlock; goto err_free;
} }
out_unlock: out_unlock:
rcu_read_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; return err;
} }
......
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