> 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 <sgrus...@redhat.com>
> ---
>  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
> 

Reply via email to