> Use information about protection that mac80211 provide to us.
> Used protection should be part of ht capabilites that either
> remote AP provde to us in STA mode or is set in hostapd.conf
> in ht_capab option.
>
> Signed-off-by: Stanislaw Gruszka <[email protected]>
> ---
> drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 58
> +++++++++++++++++++++++
> drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | 2 +
> drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 ++
> 3 files changed, 64 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> index 567a7ab47fab..6096efc4119b 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> @@ -753,6 +753,64 @@ void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev,
> u32 val)
> MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> }
>
> +void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot,
> + int ht_mode)
> +{
> + int mode = ht_mode & IEEE80211_HT_OP_MODE_PROTECTION;
> + bool non_gf = !!(ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
> + u32 prot[6];
> + bool ht_rts[4] = {};
> + int i;
> +
> + for (i = 0; i < 6; i++) {
maybe better ARRAY_SIZE() here?
> + prot[i] = mt76_rr(dev, MT_CCK_PROT_CFG + i * 4);
> + if (i >= 2)
> + prot[i] &= ~(MT_PROT_CFG_CTRL | MT_PROT_CFG_RATE);
> + }
> +
> + if (legacy_prot) {
> + prot[1] &= ~MT_PROT_CFG_CTRL;
> + prot[1] |= MT_PROT_CTRL_CTS2SELF;
> +
> + prot[2] |= MT_PROT_RATE_CCK_11;
> + prot[3] |= MT_PROT_RATE_CCK_11;
> + prot[4] |= MT_PROT_RATE_CCK_11;
> + prot[5] |= MT_PROT_RATE_CCK_11;
> + } else {
> + prot[2] |= MT_PROT_RATE_OFDM_24;
> + prot[3] |= MT_PROT_RATE_DUP_OFDM_24;
> + prot[4] |= MT_PROT_RATE_OFDM_24;
> + prot[5] |= MT_PROT_RATE_DUP_OFDM_24;
> + }
> +
> + switch (mode) {
> + case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
I think you can cover it with 'default' case
> + break;
> +
> + case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
> + ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
> + break;
> +
> + case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
> + ht_rts[1] = ht_rts[3] = true;
> + break;
> +
> + case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
> + ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
> + break;
this code is duplicated of 'IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER'.
maybe better to have:
case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
break;
> + }
> +
> + if (non_gf)
> + ht_rts[2] = ht_rts[3] = true;
> +
> + for (i = 0; i < 4; i++)
ARRAY_SIZE() here?
> + if (ht_rts[i])
> + prot[i + 2] |= MT_PROT_CTRL_RTS_CTS;
> +
> + for (i = 0; i < 6; i++)
ARRAY_SIZE() here?
> + mt76_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]);
> +}
> +
> void mt76x02_update_channel(struct mt76_dev *mdev)
> {
> struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> index 34da8c600db8..9035397ae081 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> @@ -197,6 +197,8 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
> struct mt76x02_tx_status *stat, u8 *update);
> int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
> void *rxi);
> +void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot,
> + int ht_mode);
> void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, u32 val);
> void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr);
> void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi
> *txwi,
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index fda67b0923a6..51db4d3dcc13 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -682,6 +682,10 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
> tasklet_enable(&dev->pre_tbtt_tasklet);
> }
>
> + if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
> + mt76x02_mac_set_tx_protection(dev, info->use_cts_prot,
> + info->ht_operation_mode);
> +
> if (changed & BSS_CHANGED_BASIC_RATES &&
> vif->type == NL80211_IFTYPE_STATION) {
> mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates);
> --
> 1.9.3
>