Skip to content

Commit

Permalink
Merge tag 'mt76-for-kvalo-2024-09-06' of https://github.com/nbd168/wi…
Browse files Browse the repository at this point in the history
…reless

mt76 patches for 6.12

- fixes
- mt7915 .sta_state support
- mt7915 hardware restart improvements
  • Loading branch information
Kalle Valo committed Sep 9, 2024
2 parents 0af2b1b + 6bba05d commit abbd838
Show file tree
Hide file tree
Showing 62 changed files with 622 additions and 406 deletions.
66 changes: 52 additions & 14 deletions drivers/net/wireless/mediatek/mt76/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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)
Expand Down Expand Up @@ -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);

return 0;
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);

Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
20 changes: 20 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -94,14 +104,24 @@ 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;
else
dev_kfree_skb(skb);
} while (ret == -EAGAIN);


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

return ret;
Expand Down
25 changes: 20 additions & 5 deletions drivers/net/wireless/mediatek/mt76/mt76.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/mediatek/mt76/mt7603/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ int mt7603_eeprom_init(struct mt7603_dev *dev)
is_mt7688(dev))
dev->mphy.antenna_mask = 1;

dev->mphy.chainmask = dev->mphy.antenna_mask;
mt76_eeprom_override(&dev->mphy);

return 0;
Expand Down
9 changes: 6 additions & 3 deletions drivers/net/wireless/mediatek/mt76/mt7603/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ const struct mt76_driver_ops mt7603_drv_ops = {
.rx_poll_complete = mt7603_rx_poll_complete,
.sta_ps = mt7603_sta_ps,
.sta_add = mt7603_sta_add,
.sta_assoc = mt7603_sta_assoc,
.sta_event = mt7603_sta_event,
.sta_remove = mt7603_sta_remove,
.update_survey = mt7603_update_channel,
.set_channel = mt7603_set_channel,
};

static void
Expand Down Expand Up @@ -456,11 +457,13 @@ mt7603_init_txpower(struct mt7603_dev *dev,
int target_power = eeprom[MT_EE_TX_POWER_0_START_2G + 2] & ~BIT(7);
u8 *rate_power = &eeprom[MT_EE_TX_POWER_CCK];
bool ext_pa = eeprom[MT_EE_NIC_CONF_0 + 1] & BIT(1);
u8 ext_pa_pwr;
int max_offset, cur_offset;
int i;

if (ext_pa && is_mt7603(dev))
target_power = eeprom[MT_EE_TX_POWER_TSSI_OFF] & ~BIT(7);
ext_pa_pwr = eeprom[MT_EE_TX_POWER_TSSI_OFF];
if (ext_pa && is_mt7603(dev) && ext_pa_pwr != 0 && ext_pa_pwr != 0xff)
target_power = ext_pa_pwr & ~BIT(7);

if (target_power & BIT(6))
target_power = -(target_power & GENMASK(5, 0));
Expand Down
Loading

0 comments on commit abbd838

Please sign in to comment.