Commit f4fdd771 authored by Felix Fietkau's avatar Felix Fietkau
Browse files

wifi: mt76: partially move channel change code to core

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: default avatarFelix Fietkau <nbd@nbd.name>
parent e43b87f6
Loading
Loading
Loading
Loading
+32 −5
Original line number Diff line number Diff line
@@ -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)
+5 −1
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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
+7 −20
Original line number Diff line number Diff line
@@ -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);
Loading