Commit abbd838c authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge tag 'mt76-for-kvalo-2024-09-06' of https://github.com/nbd168/wireless

mt76 patches for 6.12

- fixes
- mt7915 .sta_state support
- mt7915 hardware restart improvements
parents 0af2b1b2 6bba05d6
Loading
Loading
Loading
Loading
+52 −14
Original line number Diff line number Diff line
@@ -929,14 +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);

	mt76_worker_disable(&dev->tx_worker);
	wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout);
	mt76_update_survey(phy);

@@ -946,14 +951,34 @@ 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));
	mt76_worker_enable(&dev->tx_worker);

	ret = dev->drv->set_channel(phy);

	clear_bit(MT76_RESET, &phy->state);
	mt76_worker_schedule(&dev->tx_worker);

	mutex_unlock(&dev->mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(mt76_set_channel);

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_update_channel);

int mt76_get_survey(struct ieee80211_hw *hw, int idx,
		    struct survey_info *survey)
@@ -1484,21 +1509,32 @@ int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
	struct mt76_phy *phy = hw->priv;
	struct mt76_dev *dev = phy->dev;
	enum mt76_sta_event ev;

	if (old_state == IEEE80211_STA_NOTEXIST &&
	    new_state == IEEE80211_STA_NONE)
		return mt76_sta_add(phy, vif, sta);

	if (old_state == IEEE80211_STA_AUTH &&
	    new_state == IEEE80211_STA_ASSOC &&
	    dev->drv->sta_assoc)
		dev->drv->sta_assoc(dev, vif, sta);

	if (old_state == IEEE80211_STA_NONE &&
	    new_state == IEEE80211_STA_NOTEXIST)
		mt76_sta_remove(dev, vif, sta);

	if (!dev->drv->sta_event)
		return 0;

	if (old_state == IEEE80211_STA_AUTH &&
	    new_state == IEEE80211_STA_ASSOC)
		ev = MT76_STA_EVENT_ASSOC;
	else if (old_state == IEEE80211_STA_ASSOC &&
		 new_state == IEEE80211_STA_AUTHORIZED)
		ev = MT76_STA_EVENT_AUTHORIZE;
	else if (old_state == IEEE80211_STA_ASSOC &&
		 new_state == IEEE80211_STA_AUTH)
		ev = MT76_STA_EVENT_DISASSOC;
	else
		return 0;

	return dev->drv->sta_event(dev, vif, sta, ev);
}
EXPORT_SYMBOL_GPL(mt76_sta_state);

@@ -1521,6 +1557,7 @@ void mt76_wcid_init(struct mt76_wcid *wcid)
{
	INIT_LIST_HEAD(&wcid->tx_list);
	skb_queue_head_init(&wcid->tx_pending);
	skb_queue_head_init(&wcid->tx_offchannel);

	INIT_LIST_HEAD(&wcid->list);
	idr_init(&wcid->pktid);
@@ -1529,7 +1566,7 @@ EXPORT_SYMBOL_GPL(mt76_wcid_init);

void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid)
{
	struct mt76_phy *phy = dev->phys[wcid->phy_idx];
	struct mt76_phy *phy = mt76_dev_phy(dev, wcid->phy_idx);
	struct ieee80211_hw *hw;
	struct sk_buff_head list;
	struct sk_buff *skb;
@@ -1697,14 +1734,15 @@ int mt76_get_rate(struct mt76_dev *dev,
		  struct ieee80211_supported_band *sband,
		  int idx, bool cck)
{
	bool is_2g = sband->band == NL80211_BAND_2GHZ;
	int i, offset = 0, len = sband->n_bitrates;

	if (cck) {
		if (sband != &dev->phy.sband_2g.sband)
		if (!is_2g)
			return 0;

		idx &= ~BIT(2); /* short preamble */
	} else if (sband == &dev->phy.sband_2g.sband) {
	} else if (is_2g) {
		offset = 4;
	}

+20 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
				  int cmd, bool wait_resp,
				  struct sk_buff **ret_skb)
{
	unsigned int retry = 0;
	struct sk_buff *orig_skb = NULL;
	unsigned long expires;
	int ret, seq;

@@ -81,6 +83,14 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,

	mutex_lock(&dev->mcu.mutex);

	if (dev->mcu_ops->mcu_skb_prepare_msg) {
		ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq);
		if (ret < 0)
			goto out;
	}

retry:
	orig_skb = skb_get(skb);
	ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
	if (ret < 0)
		goto out;
@@ -94,6 +104,14 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,

	do {
		skb = mt76_mcu_get_response(dev, expires);
		if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) &&
		    retry++ < dev->mcu_ops->max_retry) {
			dev_err(dev->dev, "Retry message %08x (seq %d)\n",
				cmd, seq);
			skb = orig_skb;
			goto retry;
		}

		ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb, seq);
		if (!ret && ret_skb)
			*ret_skb = skb;
@@ -101,7 +119,9 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
			dev_kfree_skb(skb);
	} while (ret == -EAGAIN);


out:
	dev_kfree_skb(orig_skb);
	mutex_unlock(&dev->mcu.mutex);

	return ret;
+20 −5
Original line number Diff line number Diff line
@@ -162,8 +162,8 @@ enum mt76_dfs_state {

struct mt76_queue_buf {
	dma_addr_t addr;
	u16 len;
	bool skip_unmap;
	u16 len:15,
	    skip_unmap:1;
};

struct mt76_tx_info {
@@ -230,11 +230,14 @@ struct mt76_queue {
};

struct mt76_mcu_ops {
	unsigned int max_retry;
	u32 headroom;
	u32 tailroom;

	int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data,
			    int len, bool wait_resp);
	int (*mcu_skb_prepare_msg)(struct mt76_dev *dev, struct sk_buff *skb,
				   int cmd, int *seq);
	int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb,
				int cmd, int *seq);
	int (*mcu_parse_response)(struct mt76_dev *dev, int cmd,
@@ -347,6 +350,7 @@ struct mt76_wcid {
	u8 hw_key_idx2;

	u8 sta:1;
	u8 sta_disabled:1;
	u8 amsdu:1;
	u8 phy_idx:2;
	u8 link_id:4;
@@ -361,6 +365,7 @@ struct mt76_wcid {

	struct list_head tx_list;
	struct sk_buff_head tx_pending;
	struct sk_buff_head tx_offchannel;

	struct list_head list;
	struct idr pktid;
@@ -466,6 +471,12 @@ enum {
	MT76_STATE_WED_RESET,
};

enum mt76_sta_event {
	MT76_STA_EVENT_ASSOC,
	MT76_STA_EVENT_AUTHORIZE,
	MT76_STA_EVENT_DISASSOC,
};

struct mt76_hw_cap {
	bool has_2ghz;
	bool has_5ghz;
@@ -487,6 +498,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,
@@ -511,8 +523,8 @@ struct mt76_driver_ops {
	int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif,
		       struct ieee80211_sta *sta);

	void (*sta_assoc)(struct mt76_dev *dev, struct ieee80211_vif *vif,
			  struct ieee80211_sta *sta);
	int (*sta_event)(struct mt76_dev *dev, struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta, enum mt76_sta_event ev);

	void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif,
			   struct ieee80211_sta *sta);
@@ -768,6 +780,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 +1383,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 +1497,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;
+2 −2
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
	struct ieee80211_sta *sta;
	struct mt7603_sta *msta;
	struct mt76_wcid *wcid;
	u8 tid = 0, hwq = 0;
	u8 qid, tid = 0, hwq = 0;
	void *priv;
	int idx;
	u32 val;
@@ -57,7 +57,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
	if (ieee80211_is_data_qos(hdr->frame_control)) {
		tid = *ieee80211_get_qos_ctl(hdr) &
			 IEEE80211_QOS_CTL_TAG1D_MASK;
		u8 qid = tid_to_ac[tid];
		qid = tid_to_ac[tid];
		hwq = wmm_queue_map[qid];
		skb_set_queue_mapping(skb, qid);
	} else if (ieee80211_is_data(hdr->frame_control)) {
Loading