diff options
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/init.c | 33 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/main.c | 111 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/sdio.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/usb.c | 7 |
7 files changed, 157 insertions, 17 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index e9353e9929a9..79b8055ce4c4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -26,6 +26,27 @@ static const struct ieee80211_iface_combination if_comb[] = { .max_interfaces = MT7921_MAX_INTERFACES, .num_different_channels = 1, .beacon_int_infra_match = true, + }, +}; + +static const struct ieee80211_iface_limit if_limits_chanctx[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP), + } +}; + +static const struct ieee80211_iface_combination if_comb_chanctx[] = { + { + .limits = if_limits_chanctx, + .n_limits = ARRAY_SIZE(if_limits_chanctx), + .max_interfaces = 2, + .num_different_channels = 2, + .beacon_int_infra_match = false, } }; @@ -66,17 +87,19 @@ mt7921_init_wiphy(struct ieee80211_hw *hw) hw->sta_data_size = sizeof(struct mt7921_sta); hw->vif_data_size = sizeof(struct mt7921_vif); - if (dev->fw_features & MT7921_FW_CAP_CNM) + if (dev->fw_features & MT7921_FW_CAP_CNM) { wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; - else + wiphy->iface_combinations = if_comb_chanctx; + wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx); + } else { wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; - - wiphy->iface_combinations = if_comb; + wiphy->iface_combinations = if_comb; + wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); + } wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP | WIPHY_FLAG_4ADDR_STATION); wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); - wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); wiphy->max_remain_on_channel_duration = 5000; wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN; wiphy->max_scan_ssids = 4; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index eeab756240a2..443a4a49bc9e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -168,14 +168,6 @@ static void mt7921_get_status_freq_info(struct mt7921_dev *dev, struct mt76_phy *mphy, struct mt76_rx_status *status, u8 chfreq) { - if (!test_bit(MT76_HW_SCANNING, &mphy->state) && - !test_bit(MT76_HW_SCHED_SCANNING, &mphy->state) && - !test_bit(MT76_STATE_ROC, &mphy->state)) { - status->freq = mphy->chandef.chan->center_freq; - status->band = mphy->chandef.chan->band; - return; - } - if (chfreq > 180) { status->band = NL80211_BAND_6GHZ; chfreq = (chfreq - 181) * 4 + 1; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 012c92d49f49..41df17efdb3a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -858,7 +858,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif, if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, &mvif->sta.wcid, - true, NULL); + true, mvif->ctx); mt7921_mac_wtbl_update(dev, msta->wcid.idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); @@ -891,7 +891,7 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, if (!sta->tdls) mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, &mvif->sta.wcid, false, - NULL); + mvif->ctx); } spin_lock_bh(&dev->sta_poll_lock); @@ -1645,7 +1645,7 @@ mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt7921_mutex_acquire(dev); err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, - true, NULL); + true, mvif->ctx); if (err) goto out; @@ -1677,12 +1677,108 @@ mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto out; mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, false, - NULL); + mvif->ctx); out: mt7921_mutex_release(dev); } +static int +mt7921_add_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx) +{ + return 0; +} + +static void +mt7921_remove_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx) +{ +} + +static void mt7921_ctx_iter(void *priv, u8 *mac, + struct ieee80211_vif *vif) +{ + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct ieee80211_chanctx_conf *ctx = priv; + + if (ctx != mvif->ctx) + return; + + mt76_connac_mcu_uni_set_chctx(mvif->phy->mt76, &mvif->mt76, ctx); +} + +static void +mt7921_change_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx, + u32 changed) +{ + struct mt7921_phy *phy = mt7921_hw_phy(hw); + + mt7921_mutex_acquire(phy->dev); + ieee80211_iterate_active_interfaces(phy->mt76->hw, + IEEE80211_IFACE_ITER_ACTIVE, + mt7921_ctx_iter, ctx); + mt7921_mutex_release(phy->dev); +} + +static int +mt7921_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx) +{ + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt7921_dev *dev = mt7921_hw_dev(hw); + + mutex_lock(&dev->mt76.mutex); + mvif->ctx = ctx; + mutex_unlock(&dev->mt76.mutex); + + return 0; +} + +static void +mt7921_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx) +{ + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt7921_dev *dev = mt7921_hw_dev(hw); + + mutex_lock(&dev->mt76.mutex); + mvif->ctx = NULL; + mutex_unlock(&dev->mt76.mutex); +} + +static void mt7921_mgd_prepare_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_prep_tx_info *info) +{ + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt7921_dev *dev = mt7921_hw_dev(hw); + u16 duration = info->duration ? info->duration : + jiffies_to_msecs(HZ); + + mt7921_mutex_acquire(dev); + mt7921_set_roc(mvif->phy, mvif, mvif->ctx->def.chan, duration, + MT7921_ROC_REQ_JOIN); + mt7921_mutex_release(dev); +} + +static void mt7921_mgd_complete_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_prep_tx_info *info) +{ + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt7921_dev *dev = mt7921_hw_dev(hw); + + mt7921_mutex_acquire(dev); + mt7921_abort_roc(mvif->phy, mvif); + mt7921_mutex_release(dev); +} + const struct ieee80211_ops mt7921_ops = { .tx = mt7921_tx, .start = mt7921_start, @@ -1735,6 +1831,13 @@ const struct ieee80211_ops mt7921_ops = { .set_sar_specs = mt7921_set_sar_specs, .remain_on_channel = mt7921_remain_on_channel, .cancel_remain_on_channel = mt7921_cancel_remain_on_channel, + .add_chanctx = mt7921_add_chanctx, + .remove_chanctx = mt7921_remove_chanctx, + .change_chanctx = mt7921_change_chanctx, + .assign_vif_chanctx = mt7921_assign_vif_chanctx, + .unassign_vif_chanctx = mt7921_unassign_vif_chanctx, + .mgd_prepare_tx = mt7921_mgd_prepare_tx, + .mgd_complete_tx = mt7921_mgd_complete_tx, }; EXPORT_SYMBOL_GPL(mt7921_ops); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 4f0147e40bc3..ac70a978dbed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -171,6 +171,7 @@ struct mt7921_vif { struct ewma_rssi rssi; struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; + struct ieee80211_chanctx_conf *ctx; }; struct mib_stats { diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index 32ad26ef3a68..28342ec940f0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -297,6 +297,13 @@ static int mt7921_pci_probe(struct pci_dev *pdev, if (!(features & MT7921_FW_CAP_CNM)) { ops->remain_on_channel = NULL; ops->cancel_remain_on_channel = NULL; + ops->add_chanctx = NULL; + ops->remove_chanctx = NULL; + ops->change_chanctx = NULL; + ops->assign_vif_chanctx = NULL; + ops->unassign_vif_chanctx = NULL; + ops->mgd_prepare_tx = NULL; + ops->mgd_complete_tx = NULL; } mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), ops, &drv_ops); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c index e07a8fb87421..8ce4252b8ae7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c @@ -140,6 +140,13 @@ static int mt7921s_probe(struct sdio_func *func, if (!(features & MT7921_FW_CAP_CNM)) { ops->remain_on_channel = NULL; ops->cancel_remain_on_channel = NULL; + ops->add_chanctx = NULL; + ops->remove_chanctx = NULL; + ops->change_chanctx = NULL; + ops->assign_vif_chanctx = NULL; + ops->unassign_vif_chanctx = NULL; + ops->mgd_prepare_tx = NULL; + ops->mgd_complete_tx = NULL; } mdev = mt76_alloc_device(&func->dev, sizeof(*dev), ops, &drv_ops); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c index 8a49d3de2073..5321d20dcdcb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c @@ -218,6 +218,13 @@ static int mt7921u_probe(struct usb_interface *usb_intf, if (!(features & MT7921_FW_CAP_CNM)) { ops->remain_on_channel = NULL; ops->cancel_remain_on_channel = NULL; + ops->add_chanctx = NULL; + ops->remove_chanctx = NULL; + ops->change_chanctx = NULL; + ops->assign_vif_chanctx = NULL; + ops->unassign_vif_chanctx = NULL; + ops->mgd_prepare_tx = NULL; + ops->mgd_complete_tx = NULL; } ops->stop = mt7921u_stop; |