> 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 <sgruszka@xxxxxxxxxx> > --- > 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 >