Message ID | 1548678108-9526-2-git-send-email-sgruszka@redhat.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Kalle Valo |
Headers | show |
Series | mt76x02: Beacon support for USB | expand |
> Use vif_mask to count interfaces to allow to set mac address in HW > if there is only one interface and report error if we create > interface with wrong BSSID resulting in already used index. > > Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> > --- > v2: > - do not change vif index calculation > - return error for already used index > > drivers/net/wireless/mediatek/mt76/mt76x02.h | 2 ++ > drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 12 +++++++++++- > 2 files changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h > index 6d96766a6ed3..be077443bdb0 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h > +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h > @@ -73,6 +73,8 @@ struct mt76x02_dev { > > struct mutex phy_mutex; > > + u16 vif_mask; > + > u8 txdone_seq; > DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c > index 062614ad0d51..2e805d5493de 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c > +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c > @@ -292,7 +292,6 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) > > if (vif->addr[0] & BIT(1)) > idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7); > - > /* > * Client mode typically only has one configurable BSSID register, > * which is used for bssidx=0. This is linked to the MAC address. > @@ -309,6 +308,15 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) > if (vif->type == NL80211_IFTYPE_STATION) > idx += 8; > Maybe we shoud grub dev->mt76.mutex here, since we can have multiple processes trying to add an interface > + if (dev->vif_mask & BIT(idx)) > + return -EBUSY; > + > + /* Allow to change address in HW if we create first interface. */ > + if (!dev->vif_mask && !ether_addr_equal(dev->mt76.macaddr, vif->addr)) > + mt76x02_mac_setaddr(dev, vif->addr); > + > + dev->vif_mask |= BIT(idx); > + > mt76x02_vif_init(dev, vif, idx); > return 0; > } > @@ -318,8 +326,10 @@ void mt76x02_remove_interface(struct ieee80211_hw *hw, > struct ieee80211_vif *vif) > { > struct mt76x02_dev *dev = hw->priv; > + struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; > > mt76_txq_remove(&dev->mt76, vif->txq); > + dev->vif_mask &= ~BIT(mvif->idx); If we are removing the first configured interface, should we have to update MT_MAC_ADDR_DW{0,1} regs? Regards, Lorenzo > } > EXPORT_SYMBOL_GPL(mt76x02_remove_interface); > > -- > 2.19.2 >
On Mon, Jan 28, 2019 at 02:35:39PM +0100, Lorenzo Bianconi wrote: > > > > Maybe we shoud grub dev->mt76.mutex here, since we can have multiple processes trying > to add an interface Interface creation and deletion are protected by rtnl_lock(), can not be performed concurrently. > > @@ -318,8 +326,10 @@ void mt76x02_remove_interface(struct ieee80211_hw *hw, > > struct ieee80211_vif *vif) > > { > > struct mt76x02_dev *dev = hw->priv; > > + struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; > > > > mt76_txq_remove(&dev->mt76, vif->txq); > > + dev->vif_mask &= ~BIT(mvif->idx); > > If we are removing the first configured interface, should we have to update > MT_MAC_ADDR_DW{0,1} regs? What for ? Thanks Stanislaw
> On Mon, Jan 28, 2019 at 02:35:39PM +0100, Lorenzo Bianconi wrote: > > > > > > > Maybe we shoud grub dev->mt76.mutex here, since we can have multiple processes trying > > to add an interface > > Interface creation and deletion are protected by rtnl_lock(), can not > be performed concurrently. Yes, right :)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h index 6d96766a6ed3..be077443bdb0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h @@ -73,6 +73,8 @@ struct mt76x02_dev { struct mutex phy_mutex; + u16 vif_mask; + u8 txdone_seq; DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 062614ad0d51..2e805d5493de 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -292,7 +292,6 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) if (vif->addr[0] & BIT(1)) idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7); - /* * Client mode typically only has one configurable BSSID register, * which is used for bssidx=0. This is linked to the MAC address. @@ -309,6 +308,15 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) if (vif->type == NL80211_IFTYPE_STATION) idx += 8; + if (dev->vif_mask & BIT(idx)) + return -EBUSY; + + /* Allow to change address in HW if we create first interface. */ + if (!dev->vif_mask && !ether_addr_equal(dev->mt76.macaddr, vif->addr)) + mt76x02_mac_setaddr(dev, vif->addr); + + dev->vif_mask |= BIT(idx); + mt76x02_vif_init(dev, vif, idx); return 0; } @@ -318,8 +326,10 @@ void mt76x02_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x02_dev *dev = hw->priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; mt76_txq_remove(&dev->mt76, vif->txq); + dev->vif_mask &= ~BIT(mvif->idx); } EXPORT_SYMBOL_GPL(mt76x02_remove_interface);
Use vif_mask to count interfaces to allow to set mac address in HW if there is only one interface and report error if we create interface with wrong BSSID resulting in already used index. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> --- v2: - do not change vif index calculation - return error for already used index drivers/net/wireless/mediatek/mt76/mt76x02.h | 2 ++ drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-)