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

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
Loading
Loading
Loading
Loading
+32 −20
Original line number Diff line number Diff line
@@ -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;
}