[RFC] ath10k: add set_bitrate_mask callback

Kalle Valo kvalo at qca.qualcomm.com
Mon Dec 16 07:33:04 EST 2013


Janusz Dziedzic <janusz.dziedzic at tieto.com> writes:

> Add set_bitrate_mask callback. Currently
> ath10k HW is limited to handle only single
> fixed rate setting.
>
> Example:
> iw wlanX set bitrates legacy-5 ht-mcs-5 vht-mcs-5 2:9
> will setup VHT, nss=2, mcs=9
>
> iw wlanX set bitrates legacy-5 18 ht-mcs-5 vht-mcs-5
> will setup legacy, 18Mbps
>
> iw wlanX set bitrates legacy-5 ht-mcs-5 3 vht-mcs-5
> will setup HT, nss=1, mcs=3
>
> Signed-off-by: Janusz Dziedzic <janusz.dziedzic at tieto.com>

It would be good to document the nl80211 patch this depends to. Makes my
life easier.

> +static int ath10k_check_single_mask(u32 mask)
> +{
> +	int bit;
> +
> +	bit = ffs(mask);
> +	if (!bit)
> +		return 0;
> +
> +	mask &= ~BIT(bit - 1);
> +	if (mask)
> +		return 2;
> +
> +	return 1;
> +}

This fuction needs documentation what does and what meaning the return
values have.

> +static bool ath10k_default_bitrate_mask(
> +				struct ath10k *ar,
> +				enum ieee80211_band band,
> +				const struct cfg80211_bitrate_mask *mask)
> +{

If you can't fit it properly, you can do this:

static bool
ath10k_default_bitrate_mask(struct ath10k *ar,
			    enum ieee80211_band band,
			    const struct cfg80211_bitrate_mask *mask)

> +	u32 legacy = 0x00FF;
> +	u8 ht = 0xFF, i;
> +	u16 vht = 0x3FF;

Lowe case hex, please.

> +
> +	switch (band) {
> +	case IEEE80211_BAND_2GHZ:
> +		legacy= 0x00FFF;
> +		vht = 0;
> +		break;
> +	case IEEE80211_BAND_5GHZ:
> +		break;
> +	default:
> +		return false;
> +	}
> +
> +	if (mask->control[band].legacy != legacy)
> +		return false;
> +
> +	for (i = 0; i < ar->num_rf_chains; i++)
> +		if (mask->control[band].ht_mcs[i] != ht)
> +			return false;
> +
> +	for (i = 0; i < ar->num_rf_chains; i++)
> +		if (mask->control[band].vht_mcs[i] != vht)
> +			return false;
> +
> +	return true;
> +}
> +
> +static bool ath10k_bitrate_mask_correct(
> +			const struct cfg80211_bitrate_mask *mask,
> +			enum ieee80211_band band,
> +			enum wmi_rate_preamble *preamble)
> +{

Same here.

> +	int legacy = 0, ht = 0, vht = 0, i;
> +
> +	*preamble = WMI_RATE_PREAMBLE_OFDM;
> +
> +	/* check legacy */
> +	legacy = ath10k_check_single_mask(mask->control[band].legacy);
> +	if (legacy > 1)
> +		return false;
> +
> +	/* check HT */
> +	for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
> +		ht += ath10k_check_single_mask(mask->control[band].ht_mcs[i]);
> +	if (ht > 1)
> +		return false;
> +
> +	/* check VHT */
> +	for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
> +		vht += ath10k_check_single_mask(mask->control[band].vht_mcs[i]);
> +	if (vht > 1)
> +		return false;
> +
> +	/* Currently we support only one fixed_rate */
> +	if ((legacy + ht + vht) != 1)
> +		return false;
> +
> +	if (ht)
> +		*preamble = WMI_RATE_PREAMBLE_HT;
> +	else if (vht)
> +		*preamble = WMI_RATE_PREAMBLE_VHT;
> +
> +	return true;
> +}
> +
> +static u8 ath10k_get_fixed_rate(const struct cfg80211_bitrate_mask *mask,
> +				enum ieee80211_band band)
> +{
> +	u8 fixed_rate = 0, fixed_pream = 0, fixed_nss = 0, i;
> +	enum wmi_rate_preamble preamble;
> +
> +	if (!ath10k_bitrate_mask_correct(mask, band, &preamble))
> +		return WMI_FIXED_RATE_NONE;
> +
> +	fixed_pream = preamble;
> +
> +	switch (preamble) {
> +	case WMI_RATE_PREAMBLE_CCK:
> +	case WMI_RATE_PREAMBLE_OFDM:
> +		i = ffs(mask->control[band].legacy) - 1;

Empty line here.

> +		if (band == IEEE80211_BAND_2GHZ && i < 4)
> +			fixed_pream = WMI_RATE_PREAMBLE_CCK;

Empty line here.

> +		if (band == IEEE80211_BAND_5GHZ)
> +			i += 4;

Empty line here.

> +		WARN_ON(i >= ARRAY_SIZE(cck_ofdm_rate));
> +		fixed_rate = cck_ofdm_rate[i];
> +		break;
> +	case WMI_RATE_PREAMBLE_HT:
> +		for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
> +			if (mask->control[band].ht_mcs[i])
> +				break;

Empty line here.

> +		fixed_rate = ffs(mask->control[band].ht_mcs[i]) - 1;
> +		fixed_nss = i;
> +		break;
> +	case WMI_RATE_PREAMBLE_VHT:
> +		for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
> +			if (mask->control[band].vht_mcs[i])
> +				break;

And here as well.

> +		fixed_rate = ffs(mask->control[band].vht_mcs[i]) - 1;
> +		fixed_nss = i;
> +		break;
> +	}
> +
> +	fixed_nss <<= 4;
> +	fixed_pream <<= 6;
> +
> +	ath10k_dbg(ATH10K_DBG_MAC, "fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n",
> +		   fixed_pream, fixed_nss, fixed_rate);

"mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n"

> +
> +	return fixed_pream | fixed_nss | fixed_rate;
> +}
> +
> +static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw,
> +				   struct ieee80211_vif *vif,
> +				   const struct cfg80211_bitrate_mask *mask)
> +{
> +	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
> +	struct ath10k *ar = arvif->ar;
> +	enum ieee80211_band band = ar->hw->conf.chandef.chan->band;
> +	u8 fixed_rate = WMI_FIXED_RATE_NONE;
> +	u32 vdev_param;
> +	int ret = 0;
> +
> +	if (!ath10k_default_bitrate_mask(ar, band, mask)) {
> +		fixed_rate = ath10k_get_fixed_rate(mask, band);
> +		/* Someone request unsuported mask set */
> +		if (fixed_rate == WMI_FIXED_RATE_NONE)
> +			return -EINVAL;
> +	}
> +
> +	mutex_lock(&ar->conf_mutex);
> +
> +	if (arvif->fixed_rate == fixed_rate)
> +		goto exit;
> +
> +	if (fixed_rate == WMI_FIXED_RATE_NONE)
> +		ath10k_dbg(ATH10K_DBG_MAC, "set bitrate mask, disable fixed rate settings\n");

"mac disable fixed bitrate mask" or something like that.

> +
> +
> +	vdev_param = ar->wmi.vdev_param->fixed_rate;
> +	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
> +					vdev_param, fixed_rate);

It would be good to document the format for fixed_rate in wmi.h.

> +	if (ret) {
> +		ath10k_warn("Could not set fixed_rate param 0x%02x\n",
> +			    fixed_rate);

Print error code as well:

"Could not set fixed_rate param 0x%02x: %d\n"

-- 
Kalle Valo



More information about the ath10k mailing list