wifi: mt76: partially move channel change code to core
authorFelix Fietkau <nbd@nbd.name>
Wed, 28 Aug 2024 06:34:22 +0000 (08:34 +0200)
committerFelix Fietkau <nbd@nbd.name>
Fri, 6 Sep 2024 09:14:37 +0000 (11:14 +0200)
This allows the core code to change the channel. Code deduplication and
preparation for adding scanning code to the core.

Link: https://patch.msgid.link/20240828063422.44813-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
39 files changed:
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
drivers/net/wireless/mediatek/mt76/mt7603/init.c
drivers/net/wireless/mediatek/mt76/mt7603/main.c
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
drivers/net/wireless/mediatek/mt76/mt7615/main.c
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
drivers/net/wireless/mediatek/mt76/mt7615/testmode.c
drivers/net/wireless/mediatek/mt76/mt7615/usb.c
drivers/net/wireless/mediatek/mt76/mt76x0/main.c
drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
drivers/net/wireless/mediatek/mt76/mt7915/main.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
drivers/net/wireless/mediatek/mt76/mt7921/main.c
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
drivers/net/wireless/mediatek/mt76/mt7921/pci.c
drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
drivers/net/wireless/mediatek/mt76/mt7921/usb.c
drivers/net/wireless/mediatek/mt76/mt7996/main.c
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h

index 8733906fcb21363dd5cc03a5631c9af580a4c196..a24186c9a9137578bf9a147682ccfd9d47d41481 100644 (file)
@@ -929,13 +929,19 @@ void mt76_update_survey(struct mt76_phy *phy)
 }
 EXPORT_SYMBOL_GPL(mt76_update_survey);
 
-void mt76_set_channel(struct mt76_phy *phy)
+int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef,
+                    bool offchannel)
 {
        struct mt76_dev *dev = phy->dev;
-       struct ieee80211_hw *hw = phy->hw;
-       struct cfg80211_chan_def *chandef = &hw->conf.chandef;
-       bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
        int timeout = HZ / 5;
+       int ret;
+
+       cancel_delayed_work_sync(&phy->mac_work);
+
+       mutex_lock(&dev->mutex);
+       set_bit(MT76_RESET, &phy->state);
+
+       ieee80211_stop_queues(phy->hw);
 
        wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout);
        mt76_update_survey(phy);
@@ -946,14 +952,35 @@ void mt76_set_channel(struct mt76_phy *phy)
 
        phy->chandef = *chandef;
        phy->chan_state = mt76_channel_state(phy, chandef->chan);
+       phy->offchannel = offchannel;
 
        if (!offchannel)
                phy->main_chan = chandef->chan;
 
        if (chandef->chan != phy->main_chan)
                memset(phy->chan_state, 0, sizeof(*phy->chan_state));
+
+       ret = dev->drv->set_channel(phy);
+
+       clear_bit(MT76_RESET, &phy->state);
+       ieee80211_wake_queues(phy->hw);
+
+       mt76_worker_schedule(&dev->tx_worker);
+
+       mutex_unlock(&dev->mutex);
+
+       return ret;
+}
+
+int mt76_update_channel(struct mt76_phy *phy)
+{
+       struct ieee80211_hw *hw = phy->hw;
+       struct cfg80211_chan_def *chandef = &hw->conf.chandef;
+       bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
+
+       return mt76_set_channel(phy, chandef, offchannel);
 }
-EXPORT_SYMBOL_GPL(mt76_set_channel);
+EXPORT_SYMBOL_GPL(mt76_update_channel);
 
 int mt76_get_survey(struct ieee80211_hw *hw, int idx,
                    struct survey_info *survey)
index 4a58a78d5ed25d07dba95b4ba0fe7c6c2b43a566..6c054f43e7ce6fd159d298743bf4c84c19b90cc5 100644 (file)
@@ -487,6 +487,7 @@ struct mt76_driver_ops {
        u8 mcs_rates;
 
        void (*update_survey)(struct mt76_phy *phy);
+       int (*set_channel)(struct mt76_phy *phy);
 
        int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr,
                              enum mt76_txq_id qid, struct mt76_wcid *wcid,
@@ -768,6 +769,7 @@ struct mt76_phy {
 
        struct cfg80211_chan_def chandef;
        struct ieee80211_channel *main_chan;
+       bool offchannel;
 
        struct mt76_channel_state *chan_state;
        enum mt76_dfs_state dfs_state;
@@ -1370,7 +1372,7 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw,
                                  enum ieee80211_frame_release_type reason,
                                  bool more_data);
 bool mt76_has_tx_pending(struct mt76_phy *phy);
-void mt76_set_channel(struct mt76_phy *phy);
+int mt76_update_channel(struct mt76_phy *phy);
 void mt76_update_survey(struct mt76_phy *phy);
 void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time);
 int mt76_get_survey(struct ieee80211_hw *hw, int idx,
@@ -1484,6 +1486,8 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames);
 void mt76_testmode_tx_pending(struct mt76_phy *phy);
 void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q,
                            struct mt76_queue_entry *e);
+int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef,
+                    bool offchannel);
 
 /* usb */
 static inline bool mt76u_urb_error(struct urb *urb)
index c223f7c19e6da12a8ce6611ad35fd6d86159a490..6457ee06bb5a151963b6669e527a4a2959171f01 100644 (file)
@@ -107,7 +107,7 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
        struct sk_buff *skb;
        int i, nframes;
 
-       if (mt76_hw(dev)->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+       if (dev->mphy.offchannel)
                return;
 
        data.dev = dev;
index f84c9a06af753dbc69e9e0d479135f8d0d4234c8..1528a8be7762de274d799cebb7a211bbf930bf61 100644 (file)
@@ -18,6 +18,7 @@ const struct mt76_driver_ops mt7603_drv_ops = {
        .sta_assoc = mt7603_sta_assoc,
        .sta_remove = mt7603_sta_remove,
        .update_survey = mt7603_update_channel,
+       .set_channel = mt7603_set_channel,
 };
 
 static void
index f35fa643c0da2357cabc3a1f9fff097d2d0e08f6..3d3a4cc2bab102296e1c3cd0da8dff9fc8cf80dc 100644 (file)
@@ -133,30 +133,24 @@ void mt7603_init_edcca(struct mt7603_dev *dev)
        mt7603_edcca_set_strict(dev, false);
 }
 
-static int
-mt7603_set_channel(struct ieee80211_hw *hw, struct cfg80211_chan_def *def)
+int mt7603_set_channel(struct mt76_phy *mphy)
 {
-       struct mt7603_dev *dev = hw->priv;
+       struct mt7603_dev *dev = container_of(mphy->dev, struct mt7603_dev, mt76);
+       struct cfg80211_chan_def *def = &mphy->chandef;
+
        u8 *rssi_data = (u8 *)dev->mt76.eeprom.data;
        int idx, ret;
        u8 bw = MT_BW_20;
        bool failed = false;
 
-       ieee80211_stop_queues(hw);
-       cancel_delayed_work_sync(&dev->mphy.mac_work);
        tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
 
-       mutex_lock(&dev->mt76.mutex);
-       set_bit(MT76_RESET, &dev->mphy.state);
-
        mt7603_beacon_set_timer(dev, -1, 0);
-       mt76_set_channel(&dev->mphy);
        mt7603_mac_stop(dev);
 
        if (def->width == NL80211_CHAN_WIDTH_40)
                bw = MT_BW_40;
 
-       dev->mphy.chandef = *def;
        mt76_rmw_field(dev, MT_AGG_BWCR, MT_AGG_BWCR_BW, bw);
        ret = mt7603_mcu_set_channel(dev);
        if (ret) {
@@ -180,10 +174,6 @@ mt7603_set_channel(struct ieee80211_hw *hw, struct cfg80211_chan_def *def)
        mt7603_mac_set_timing(dev);
        mt7603_mac_start(dev);
 
-       clear_bit(MT76_RESET, &dev->mphy.state);
-
-       mt76_txq_schedule_all(&dev->mphy);
-
        ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
                                     msecs_to_jiffies(MT7603_WATCHDOG_TIME));
 
@@ -199,17 +189,14 @@ mt7603_set_channel(struct ieee80211_hw *hw, struct cfg80211_chan_def *def)
        mt7603_init_edcca(dev);
 
 out:
-       if (!(mt76_hw(dev)->conf.flags & IEEE80211_CONF_OFFCHANNEL))
+       if (!mphy->offchannel)
                mt7603_beacon_set_timer(dev, -1, dev->mt76.beacon_int);
-       mutex_unlock(&dev->mt76.mutex);
 
        tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
 
        if (failed)
                mt7603_mac_work(&dev->mphy.mac_work.work);
 
-       ieee80211_wake_queues(hw);
-
        return ret;
 }
 
@@ -227,7 +214,7 @@ static int mt7603_set_sar_specs(struct ieee80211_hw *hw,
        if (err)
                return err;
 
-       return mt7603_set_channel(hw, &mphy->chandef);
+       return mt76_update_channel(mphy);
 }
 
 static int
@@ -238,7 +225,7 @@ mt7603_config(struct ieee80211_hw *hw, u32 changed)
 
        if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
                       IEEE80211_CONF_CHANGE_POWER))
-               ret = mt7603_set_channel(hw, &hw->conf.chandef);
+               ret = mt76_update_channel(&dev->mphy);
 
        if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
                mutex_lock(&dev->mt76.mutex);
index 9e58df7042ad163f4ab0739e31526e9f5bed47d0..dbdfe596f29e521eaedca9b7fe7f4882fa3a216b 100644 (file)
@@ -213,6 +213,7 @@ void mt7603_mac_sta_poll(struct mt7603_dev *dev);
 
 void mt7603_pse_client_reset(struct mt7603_dev *dev);
 
+int mt7603_set_channel(struct mt76_phy *mphy);
 int mt7603_mcu_set_channel(struct mt7603_dev *dev);
 int mt7603_mcu_set_eeprom(struct mt7603_dev *dev);
 void mt7603_mcu_exit(struct mt7603_dev *dev);
index 50e262c1622f93d87d0abce399f3843556c64400..3769753880075730dea0d01d051993f7c60e3825 100644 (file)
@@ -282,19 +282,14 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,
        mt76_wcid_cleanup(&dev->mt76, &mvif->sta.wcid);
 }
 
-int mt7615_set_channel(struct mt7615_phy *phy)
+int mt7615_set_channel(struct mt76_phy *mphy)
 {
+       struct mt7615_phy *phy = mphy->priv;
        struct mt7615_dev *dev = phy->dev;
        bool ext_phy = phy != &dev->phy;
        int ret;
 
-       cancel_delayed_work_sync(&phy->mt76->mac_work);
-
-       mt7615_mutex_acquire(dev);
-
-       set_bit(MT76_RESET, &phy->mt76->state);
-
-       mt76_set_channel(phy->mt76);
+       mt76_connac_pm_wake(mphy, &dev->pm);
 
        if (is_mt7615(&dev->mt76) && dev->flash_eeprom) {
                ret = mt7615_mcu_apply_rx_dcoc(phy);
@@ -325,11 +320,8 @@ int mt7615_set_channel(struct mt7615_phy *phy)
        phy->chfreq = mt76_rr(dev, MT_CHFREQ(ext_phy));
 
 out:
-       clear_bit(MT76_RESET, &phy->mt76->state);
+       mt76_connac_power_save_sched(mphy, &dev->pm);
 
-       mt7615_mutex_release(dev);
-
-       mt76_worker_schedule(&dev->mt76.tx_worker);
        if (!mt76_testmode_enabled(phy->mt76)) {
                unsigned long timeout = mt7615_get_macwork_timeout(dev);
 
@@ -339,6 +331,7 @@ out:
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(mt7615_set_channel);
 
 static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                          struct ieee80211_vif *vif, struct ieee80211_sta *sta,
@@ -425,11 +418,7 @@ static int mt7615_set_sar_specs(struct ieee80211_hw *hw,
        if (mt7615_firmware_offload(phy->dev))
                return mt76_connac_mcu_set_rate_txpower(phy->mt76);
 
-       ieee80211_stop_queues(hw);
-       err = mt7615_set_channel(phy);
-       ieee80211_wake_queues(hw);
-
-       return err;
+       return mt76_update_channel(phy->mt76);
 }
 
 static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
@@ -448,9 +437,7 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
                        mt7615_mutex_release(dev);
                }
 #endif
-               ieee80211_stop_queues(hw);
-               ret = mt7615_set_channel(phy);
-               ieee80211_wake_queues(hw);
+               ret = mt76_update_channel(phy->mt76);
        }
 
        mt7615_mutex_acquire(dev);
index d50d967828be0d3bb4ef9757e04b7ad90dd4bec5..3b57d967190a98abdf9c0fbfe69880a0b49ef45f 100644 (file)
@@ -2151,7 +2151,7 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
        if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
            phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)
                req.switch_reason = CH_SWITCH_NORMAL;
-       else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+       else if (phy->mt76->offchannel)
                req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
        else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
                                          NL80211_IFTYPE_AP))
index 87a956ea3ad74f6fb62a873eba0f499e04a99c32..dbb2c82407df2758d5c95c0160e72c8cf6807d8d 100644 (file)
@@ -182,6 +182,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
                .sta_add = mt7615_mac_sta_add,
                .sta_remove = mt7615_mac_sta_remove,
                .update_survey = mt7615_update_channel,
+               .set_channel = mt7615_set_channel,
        };
        struct mt76_bus_ops *bus_ops;
        struct ieee80211_ops *ops;
index a20322aae96725adbcba17e3b26448d246ece29b..68f4a7727a269e27c11e04bb29531e725a55bc80 100644 (file)
@@ -457,7 +457,7 @@ void mt7615_roc_work(struct work_struct *work);
 void mt7615_roc_timer(struct timer_list *timer);
 void mt7615_init_txpower(struct mt7615_dev *dev,
                         struct ieee80211_supported_band *sband);
-int mt7615_set_channel(struct mt7615_phy *phy);
+int mt7615_set_channel(struct mt76_phy *mphy);
 void mt7615_init_work(struct mt7615_dev *dev);
 
 int mt7615_mcu_restart(struct mt76_dev *dev);
index 9692890ba51b7b61c43991cb20a59d8394188c1e..aebfc4576aa494e91915039350d3c4dac44bb9c9 100644 (file)
@@ -87,6 +87,7 @@ static int mt7663s_probe(struct sdio_func *func,
                .sta_add = mt7615_mac_sta_add,
                .sta_remove = mt7615_mac_sta_remove,
                .update_survey = mt7615_update_channel,
+               .set_channel = mt7615_set_channel,
        };
        static const struct mt76_bus_ops mt7663s_ops = {
                .rr = mt76s_rr,
index a3d1cfa729edadea83cba955a1cbb07db59606b7..03f5af84424bdde995385d1998e213432e586da2 100644 (file)
@@ -141,7 +141,7 @@ mt7615_tm_init(struct mt7615_phy *phy)
        mt7615_mcu_set_sku_en(phy, phy->mt76->test.state == MT76_TM_STATE_OFF);
 
        mutex_unlock(&dev->mt76.mutex);
-       mt7615_set_channel(phy);
+       mt76_update_channel(phy->mt76);
        mt7615_ops.configure_filter(phy->mt76->hw, 0, &total_flags, 0);
        mutex_lock(&dev->mt76.mutex);
 
index 9335ca0776febeac10e355ff5ea8238bc537be4d..5020af52c68c1327ea27b9d7ef329783ed1693f7 100644 (file)
@@ -123,6 +123,7 @@ static int mt7663u_probe(struct usb_interface *usb_intf,
                .sta_add = mt7615_mac_sta_add,
                .sta_remove = mt7615_mac_sta_remove,
                .update_survey = mt7615_update_channel,
+               .set_channel = mt7615_set_channel,
        };
        static struct mt76_bus_ops bus_ops = {
                .rr = mt7663u_rr,
index 07380cce8755ea8a839889e0d9fee49c2aafc5ac..4aa2dcedc87448b1324813ec43d39cff51617d91 100644 (file)
@@ -8,16 +8,15 @@
 #include <linux/etherdevice.h>
 #include "mt76x0.h"
 
-static void
-mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
+int mt76x0_set_channel(struct mt76_phy *mphy)
 {
-       cancel_delayed_work_sync(&dev->cal_work);
+       struct mt76x02_dev *dev = container_of(mphy->dev, struct mt76x02_dev, mt76);
+
        mt76x02_pre_tbtt_enable(dev, false);
        if (mt76_is_mmio(&dev->mt76))
                tasklet_disable(&dev->dfs_pd.dfs_tasklet);
 
-       mt76_set_channel(&dev->mphy);
-       mt76x0_phy_set_channel(dev, chandef);
+       mt76x0_phy_set_channel(dev, &mphy->chandef);
 
        mt76x02_mac_cc_reset(dev);
        mt76x02_edcca_init(dev);
@@ -28,8 +27,9 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
        }
        mt76x02_pre_tbtt_enable(dev, true);
 
-       mt76_txq_schedule_all(&dev->mphy);
+       return 0;
 }
+EXPORT_SYMBOL_GPL(mt76x0_set_channel);
 
 int mt76x0_set_sar_specs(struct ieee80211_hw *hw,
                         const struct cfg80211_sar_specs *sar)
@@ -61,13 +61,10 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct mt76x02_dev *dev = hw->priv;
 
-       mutex_lock(&dev->mt76.mutex);
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
+               mt76_update_channel(&dev->mphy);
 
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ieee80211_stop_queues(hw);
-               mt76x0_set_channel(dev, &hw->conf.chandef);
-               ieee80211_wake_queues(hw);
-       }
+       mutex_lock(&dev->mt76.mutex);
 
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
                struct mt76_phy *mphy = &dev->mphy;
index 99dcb8feb9f771132a38b24226f57ec6cad5414c..50f755344968377211dd028de19186c91415e1e8 100644 (file)
@@ -49,6 +49,7 @@ void mt76x0_chip_onoff(struct mt76x02_dev *dev, bool enable, bool reset);
 void mt76x0_mac_stop(struct mt76x02_dev *dev);
 
 int mt76x0_config(struct ieee80211_hw *hw, u32 changed);
+int mt76x0_set_channel(struct mt76_phy *mphy);
 int mt76x0_set_sar_specs(struct ieee80211_hw *hw,
                         const struct cfg80211_sar_specs *sar);
 
index 2ecee7c5c80d9f438596ac4dc5d01600428d87e4..1eb955f3ca130bd0a1d89d178dec097b6c53821a 100644 (file)
@@ -159,6 +159,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                             MT_DRV_SW_RX_AIRTIME,
                .survey_flags = SURVEY_INFO_TIME_TX,
                .update_survey = mt76x02_update_channel,
+               .set_channel = mt76x0_set_channel,
                .tx_prepare_skb = mt76x02_tx_prepare_skb,
                .tx_complete_skb = mt76x02_tx_complete_skb,
                .rx_skb = mt76x02_queue_rx_skb,
index 390f502e97f03a5818a49eacb66b8bc51cb5acab..b031c500b74156bb4b354c779054d8ad4f123c99 100644 (file)
@@ -217,6 +217,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
                .drv_flags = MT_DRV_SW_RX_AIRTIME,
                .survey_flags = SURVEY_INFO_TIME_TX,
                .update_survey = mt76x02_update_channel,
+               .set_channel = mt76x0_set_channel,
                .tx_prepare_skb = mt76x02u_tx_prepare_skb,
                .tx_complete_skb = mt76x02u_tx_complete_skb,
                .tx_status_data = mt76x02_tx_status_data,
index 35b7ebc2c9c625e6d7ce329a4597ad91d6506401..4a49a3036a46b21a32cc9c31a9f87425310fbae7 100644 (file)
@@ -22,7 +22,7 @@ static void mt76x02_pre_tbtt_tasklet(struct tasklet_struct *t)
        struct sk_buff *skb;
        int i;
 
-       if (mt76_hw(dev)->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+       if (dev->mphy.offchannel)
                return;
 
        __skb_queue_head_init(&data.q);
index 29b9a15f8dbe797e44e4a188ac3e9ff806d495a4..0e1ede9314d8f76c3dcba19161c8dec399eeeae1 100644 (file)
@@ -188,10 +188,7 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
        struct sk_buff *skb;
        int nbeacons;
 
-       if (!dev->mt76.beacon_mask)
-               return;
-
-       if (mt76_hw(dev)->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+       if (!dev->mt76.beacon_mask || dev->mphy.offchannel)
                return;
 
        __skb_queue_head_init(&data.q);
index be1217329a77236ce090eec1b76cadeceadf5204..f051721bb00eb9f5c893bf4776ec2250b7e0487c 100644 (file)
@@ -47,6 +47,8 @@ void mt76x2_phy_power_on(struct mt76x02_dev *dev);
 void mt76x2_stop_hardware(struct mt76x02_dev *dev);
 int mt76x2_eeprom_init(struct mt76x02_dev *dev);
 int mt76x2_apply_calibration_data(struct mt76x02_dev *dev, int channel);
+int mt76x2e_set_channel(struct mt76_phy *phy);
+int mt76x2u_set_channel(struct mt76_phy *phy);
 
 void mt76x2_phy_set_antenna(struct mt76x02_dev *dev);
 int mt76x2_phy_start(struct mt76x02_dev *dev);
index 30959746e9242712e8196724157db8c93caa96f3..67c9d1caa0bd6371804e92a2cc00d80b2ce99c58 100644 (file)
@@ -25,6 +25,7 @@ mt76x2e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                             MT_DRV_SW_RX_AIRTIME,
                .survey_flags = SURVEY_INFO_TIME_TX,
                .update_survey = mt76x02_update_channel,
+               .set_channel = mt76x2e_set_channel,
                .tx_prepare_skb = mt76x02_tx_prepare_skb,
                .tx_complete_skb = mt76x02_tx_complete_skb,
                .rx_skb = mt76x02_queue_rx_skb,
index 6accea55131906b9f54c8e288aeead6eff8e01e5..eb70130d2711ac702158fb6b806717ace65a099d 100644 (file)
@@ -32,33 +32,25 @@ mt76x2_stop(struct ieee80211_hw *hw, bool suspend)
        mt76x2_stop_hardware(dev);
 }
 
-static void
-mt76x2_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
+int mt76x2e_set_channel(struct mt76_phy *phy)
 {
-       cancel_delayed_work_sync(&dev->cal_work);
+       struct mt76x02_dev *dev = container_of(phy->dev, struct mt76x02_dev, mt76);
+
        tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
        tasklet_disable(&dev->dfs_pd.dfs_tasklet);
 
-       mutex_lock(&dev->mt76.mutex);
-       set_bit(MT76_RESET, &dev->mphy.state);
-
-       mt76_set_channel(&dev->mphy);
-
        mt76x2_mac_stop(dev, true);
-       mt76x2_phy_set_channel(dev, chandef);
+       mt76x2_phy_set_channel(dev, &phy->chandef);
 
        mt76x02_mac_cc_reset(dev);
        mt76x02_dfs_init_params(dev);
 
        mt76x2_mac_resume(dev);
 
-       clear_bit(MT76_RESET, &dev->mphy.state);
-       mutex_unlock(&dev->mt76.mutex);
-
        tasklet_enable(&dev->dfs_pd.dfs_tasklet);
        tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
 
-       mt76_txq_schedule_all(&dev->mphy);
+       return 0;
 }
 
 static int
@@ -95,11 +87,8 @@ mt76x2_config(struct ieee80211_hw *hw, u32 changed)
 
        mutex_unlock(&dev->mt76.mutex);
 
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ieee80211_stop_queues(hw);
-               mt76x2_set_channel(dev, &hw->conf.chandef);
-               ieee80211_wake_queues(hw);
-       }
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
+               mt76_update_channel(&dev->mphy);
 
        return 0;
 }
index e92bb871f2318afd1b8cbaa111e05c7b8d40d057..e832ad53e2393b4fd3be1bde3a8c4a03612e7a8d 100644 (file)
@@ -32,6 +32,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
                .drv_flags = MT_DRV_SW_RX_AIRTIME,
                .survey_flags = SURVEY_INFO_TIME_TX,
                .update_survey = mt76x02_update_channel,
+               .set_channel = mt76x2u_set_channel,
                .tx_prepare_skb = mt76x02u_tx_prepare_skb,
                .tx_complete_skb = mt76x02u_tx_complete_skb,
                .tx_status_data = mt76x02_tx_status_data,
index ba0241c366726241ea048089f6a832e360be147e..83e7061b10e2d2b3d8ff28e3d1fe90553c7db71d 100644 (file)
@@ -31,32 +31,20 @@ static void mt76x2u_stop(struct ieee80211_hw *hw, bool suspend)
        mt76x2u_stop_hw(dev);
 }
 
-static int
-mt76x2u_set_channel(struct mt76x02_dev *dev,
-                   struct cfg80211_chan_def *chandef)
+int mt76x2u_set_channel(struct mt76_phy *mphy)
 {
+       struct mt76x02_dev *dev = container_of(mphy->dev, struct mt76x02_dev, mt76);
        int err;
 
-       cancel_delayed_work_sync(&dev->cal_work);
        mt76x02_pre_tbtt_enable(dev, false);
-
-       mutex_lock(&dev->mt76.mutex);
-       set_bit(MT76_RESET, &dev->mphy.state);
-
-       mt76_set_channel(&dev->mphy);
-
        mt76x2_mac_stop(dev, false);
 
-       err = mt76x2u_phy_set_channel(dev, chandef);
+       err = mt76x2u_phy_set_channel(dev, &mphy->chandef);
 
        mt76x02_mac_cc_reset(dev);
        mt76x2_mac_resume(dev);
 
-       clear_bit(MT76_RESET, &dev->mphy.state);
-       mutex_unlock(&dev->mt76.mutex);
-
        mt76x02_pre_tbtt_enable(dev, true);
-       mt76_txq_schedule_all(&dev->mphy);
 
        return err;
 }
@@ -93,11 +81,8 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
 
        mutex_unlock(&dev->mt76.mutex);
 
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ieee80211_stop_queues(hw);
-               err = mt76x2u_set_channel(dev, &hw->conf.chandef);
-               ieee80211_wake_queues(hw);
-       }
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
+               mt76_update_channel(&dev->mphy);
 
        return err;
 }
index 049223df9beb15dc3d44e2aff5689b2acb68ced3..87a7b1589af20d16e086b6a967021ac8feee2f2e 100644 (file)
@@ -317,18 +317,12 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
        mt76_wcid_cleanup(&dev->mt76, &msta->wcid);
 }
 
-int mt7915_set_channel(struct mt7915_phy *phy)
+int mt7915_set_channel(struct mt76_phy *mphy)
 {
+       struct mt7915_phy *phy = mphy->priv;
        struct mt7915_dev *dev = phy->dev;
        int ret;
 
-       cancel_delayed_work_sync(&phy->mt76->mac_work);
-
-       mutex_lock(&dev->mt76.mutex);
-       set_bit(MT76_RESET, &phy->mt76->state);
-
-       mt76_set_channel(phy->mt76);
-
        if (dev->cal) {
                ret = mt7915_mcu_apply_tx_dpd(phy);
                if (ret)
@@ -347,11 +341,6 @@ int mt7915_set_channel(struct mt7915_phy *phy)
        phy->noise = 0;
 
 out:
-       clear_bit(MT76_RESET, &phy->mt76->state);
-       mutex_unlock(&dev->mt76.mutex);
-
-       mt76_txq_schedule_all(phy->mt76);
-
        if (!mt76_testmode_enabled(phy->mt76))
                ieee80211_queue_delayed_work(phy->mt76->hw,
                                             &phy->mt76->mac_work,
@@ -464,11 +453,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
                        mutex_unlock(&dev->mt76.mutex);
                }
 #endif
-               ieee80211_stop_queues(hw);
-               ret = mt7915_set_channel(phy);
+               ret = mt76_update_channel(phy->mt76);
                if (ret)
                        return ret;
-               ieee80211_wake_queues(hw);
        }
 
        if (changed & (IEEE80211_CONF_CHANGE_POWER |
index 2185cd24e2e1cd8e098e502bc03a25ab712e8674..b2cad75eafb9b57e400405e66487c9475c113109 100644 (file)
@@ -2747,7 +2747,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
 
        if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)
                req.switch_reason = CH_SWITCH_NORMAL;
-       else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL ||
+       else if (phy->mt76->offchannel ||
                 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
                req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
        else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
index d6ecd698cdcd08de199f3a180e48e6dd99504706..ec7cf57521d9d60f631a68cc4be0e8296af0e728 100644 (file)
@@ -929,6 +929,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
                .sta_add = mt7915_mac_sta_add,
                .sta_remove = mt7915_mac_sta_remove,
                .update_survey = mt7915_update_channel,
+               .set_channel = mt7915_set_channel,
        };
        struct mt7915_dev *dev;
        struct mt76_dev *mdev;
index a30d08eb0656a231df40187391741332ff554db8..712471c2a8e91a69916b398cdce2059632dc8914 100644 (file)
@@ -463,7 +463,7 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
                             struct ieee80211_sta *sta, bool changed);
 int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta);
-int mt7915_set_channel(struct mt7915_phy *phy);
+int mt7915_set_channel(struct mt76_phy *mphy);
 int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd);
 int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif);
 int mt7915_mcu_update_edca(struct mt7915_dev *dev, void *req);
index 0d76ae31b37669c8b2f45c5585b2d5e1471a5dd8..1ed8e77eb549c65bcdc90bb32d4c4fd0dc47f32a 100644 (file)
@@ -425,7 +425,7 @@ static void
 mt7915_tm_update_channel(struct mt7915_phy *phy)
 {
        mutex_unlock(&phy->dev->mt76.mutex);
-       mt7915_set_channel(phy);
+       mt76_update_channel(phy->mt76);
        mutex_lock(&phy->dev->mt76.mutex);
 
        mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
index 23b228804289be7e962704b7754de5d3155cf732..ffb2b68ddd519f8fb1b32642da44275aa5290625 100644 (file)
@@ -455,37 +455,30 @@ static int mt7921_cancel_remain_on_channel(struct ieee80211_hw *hw,
        return mt7921_abort_roc(phy, mvif);
 }
 
-static int mt7921_set_channel(struct mt792x_phy *phy)
+int mt7921_set_channel(struct mt76_phy *mphy)
 {
+       struct mt792x_phy *phy = mphy->priv;
        struct mt792x_dev *dev = phy->dev;
        int ret;
 
-       cancel_delayed_work_sync(&phy->mt76->mac_work);
-
-       mt792x_mutex_acquire(dev);
-       set_bit(MT76_RESET, &phy->mt76->state);
-
-       mt76_set_channel(phy->mt76);
-
+       mt76_connac_pm_wake(mphy, &dev->pm);
        ret = mt7921_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));
        if (ret)
                goto out;
 
        mt792x_mac_set_timeing(phy);
-
        mt792x_mac_reset_counters(phy);
        phy->noise = 0;
 
 out:
-       clear_bit(MT76_RESET, &phy->mt76->state);
-       mt792x_mutex_release(dev);
+       mt76_connac_power_save_sched(mphy, &dev->pm);
 
-       mt76_worker_schedule(&dev->mt76.tx_worker);
-       ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mt76->mac_work,
+       ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
                                     MT792x_WATCHDOG_TIME);
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(mt7921_set_channel);
 
 static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                          struct ieee80211_vif *vif, struct ieee80211_sta *sta,
@@ -620,11 +613,9 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed)
        int ret = 0;
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ieee80211_stop_queues(hw);
-               ret = mt7921_set_channel(phy);
+               ret = mt76_update_channel(phy->mt76);
                if (ret)
                        return ret;
-               ieee80211_wake_queues(hw);
        }
 
        mt792x_mutex_acquire(dev);
index 394fcd7993450ba83689dabe66d1ead253395dcc..02c1de8620a7f2a596c2353c60286b01f75a170d 100644 (file)
@@ -890,7 +890,7 @@ int mt7921_mcu_set_chan_info(struct mt792x_phy *phy, int cmd)
        if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
            dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
                req.switch_reason = CH_SWITCH_NORMAL;
-       else if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+       else if (phy->mt76->offchannel)
                req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
        else if (!cfg80211_reg_can_beacon(dev->mt76.hw->wiphy, chandef,
                                          NL80211_IFTYPE_AP))
index 6c5392c5d207e6909d65aafeb3c17f633714a9bd..0b4f4c8d88589a3c278ca42cc35d6696f68b661e 100644 (file)
@@ -186,6 +186,7 @@ int __mt7921_start(struct mt792x_phy *phy);
 int mt7921_register_device(struct mt792x_dev *dev);
 void mt7921_unregister_device(struct mt792x_dev *dev);
 int mt7921_run_firmware(struct mt792x_dev *dev);
+int mt7921_set_channel(struct mt76_phy *mphy);
 int mt7921_mcu_set_bss_pm(struct mt792x_dev *dev, struct ieee80211_vif *vif,
                          bool enable);
 int mt7921_mcu_sta_update(struct mt792x_dev *dev, struct ieee80211_sta *sta,
index a7430216a80df0857e1385b108aa962ad29f93aa..bb8cfff78dc5889b5b45d82fb21abfbfbbb0a130 100644 (file)
@@ -247,6 +247,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
                .sta_assoc = mt7921_mac_sta_assoc,
                .sta_remove = mt7921_mac_sta_remove,
                .update_survey = mt792x_update_channel,
+               .set_channel = mt7921_set_channel,
        };
        static const struct mt792x_hif_ops mt7921_pcie_ops = {
                .init_reset = mt7921e_init_reset,
index 004d942ee11a86dc91ea9b6a3e1aa82131a751db..2ef502d0ce9a4a401746b77b49aa0be515523d07 100644 (file)
@@ -103,6 +103,7 @@ static int mt7921s_probe(struct sdio_func *func,
                .sta_assoc = mt7921_mac_sta_assoc,
                .sta_remove = mt7921_mac_sta_remove,
                .update_survey = mt792x_update_channel,
+               .set_channel = mt7921_set_channel,
        };
        static const struct mt76_bus_ops mt7921s_ops = {
                .rr = mt76s_rr,
index 8b7c03c47598de7bf9037ed40cb370607a837af4..3b5e52db4a13de00ef523ca55cfea933c45fa1d0 100644 (file)
@@ -154,6 +154,7 @@ static int mt7921u_probe(struct usb_interface *usb_intf,
                .sta_assoc = mt7921_mac_sta_assoc,
                .sta_remove = mt7921_mac_sta_remove,
                .update_survey = mt792x_update_channel,
+               .set_channel = mt7921_set_channel,
        };
        static const struct mt792x_hif_ops hif_ops = {
                .mcu_init = mt7921u_mcu_init,
index d43bd5c2432e72f97a3943d3ae785bfa8179648c..39f071ece35e6e980d22924cafa07f7c37af1f4d 100644 (file)
@@ -291,18 +291,11 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
        mt76_wcid_cleanup(&dev->mt76, &msta->wcid);
 }
 
-int mt7996_set_channel(struct mt7996_phy *phy)
+int mt7996_set_channel(struct mt76_phy *mphy)
 {
-       struct mt7996_dev *dev = phy->dev;
+       struct mt7996_phy *phy = mphy->priv;
        int ret;
 
-       cancel_delayed_work_sync(&phy->mt76->mac_work);
-
-       mutex_lock(&dev->mt76.mutex);
-       set_bit(MT76_RESET, &phy->mt76->state);
-
-       mt76_set_channel(phy->mt76);
-
        ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);
        if (ret)
                goto out;
@@ -318,13 +311,7 @@ int mt7996_set_channel(struct mt7996_phy *phy)
        phy->noise = 0;
 
 out:
-       clear_bit(MT76_RESET, &phy->mt76->state);
-       mutex_unlock(&dev->mt76.mutex);
-
-       mt76_txq_schedule_all(phy->mt76);
-
-       ieee80211_queue_delayed_work(phy->mt76->hw,
-                                    &phy->mt76->mac_work,
+       ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
                                     MT7996_WATCHDOG_TIME);
 
        return ret;
@@ -415,11 +402,9 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
        int ret;
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ieee80211_stop_queues(hw);
-               ret = mt7996_set_channel(phy);
+               ret = mt76_update_channel(phy->mt76);
                if (ret)
                        return ret;
-               ieee80211_wake_queues(hw);
        }
 
        if (changed & (IEEE80211_CONF_CHANGE_POWER |
index 8855095fef10a0ceb95c62142270683a74fcec5f..a1a0df43e1cda224905c0a52f18ec1e2ef9cd62b 100644 (file)
@@ -3463,7 +3463,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
 
        if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)
                req.switch_reason = CH_SWITCH_NORMAL;
-       else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL ||
+       else if (phy->mt76->offchannel ||
                 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
                req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
        else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
index 928a9663b49e0ccba21d7d85bcd0ba7e1d5ebbc5..40e45fb2b62607895a9911b3ae849dda57cbbc30 100644 (file)
@@ -620,6 +620,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
                .sta_add = mt7996_mac_sta_add,
                .sta_remove = mt7996_mac_sta_remove,
                .update_survey = mt7996_update_channel,
+               .set_channel = mt7996_set_channel,
        };
        struct mt7996_dev *dev;
        struct mt76_dev *mdev;
index 177cfff31120ed72d2e3a1e34be994fcb8bd5344..ab8c9070630b0f1a0dfb7efe093f87b7e0a24d1f 100644 (file)
@@ -468,7 +468,7 @@ int mt7996_mcu_add_obss_spr(struct mt7996_phy *phy, struct ieee80211_vif *vif,
                            struct ieee80211_he_obss_pd *he_obss_pd);
 int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
                             struct ieee80211_sta *sta, bool changed);
-int mt7996_set_channel(struct mt7996_phy *phy);
+int mt7996_set_channel(struct mt76_phy *mphy);
 int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag);
 int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif);
 int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,