Skip to contentSkip to conversation

wifi: mt76: mt7925: MT7927 (Filogic 380) support

PATCH New Sean Wang 1 participant 22 messages Apr 25

Subsystems (2)
lore
Share & tools
lore

Sean Wang

author
#0 lore raw

v5 cover wifi: mt76: mt7925: MT7927 (Filogic 380) support

This series adds support for MediaTek MT7927 (Filogic 380), a combo WiFi 7 + BT 5.4 device, in the mt7925 driver.

Patches 1-5 add generic 320MHz EHT support without MT7927-specific references.

Patches 6-9 add the initial MT7927 enablement pieces, including chip ID helpers, firmware paths, per-chip IRQ map handling, and disabling ASPM and runtime PM for MT7927.

Patches 10-21 add the remaining MT7927 support needed to make the device usable, including connac3 helper cleanup, non-MLD link removal handling, inactive BSS deactivation tolerance, WFSYS reset support, common DMA queue helper refactoring, MT7927 PCIe DMA configuration, BSS band assignment sync, MBMC event handling, CNM ops enablement, and PCIe/USB device support.

The follow-up MT7927 support patches are folded into this version so users and testers can apply one complete series for MT7927 enablement.

Tested hardware:
- ASUS ROG Crosshair X870E Hero (BT 0489:e13a, WiFi 14c3:6639)
- ASUS ProArt X870E-Creator WiFi (BT 0489:e13a / 13d3:3588, WiFi 14c3:6639)
- ASUS ROG Strix X870-I (WiFi 14c3:7927)
- ASUS ROG Strix X870-F Gaming WiFi (BT 0489:e13a, WiFi 14c3:7927)
- ASUS ROG Strix X870E-E (BT 13d3:3588, WiFi 14c3:7927)
- ASUS ROG STRIX B850-E GAMING WIFI (BT 0489:e13a, WiFi 14c3:7927)
- Gigabyte X870E Aorus Master X3D (BT 0489:e10f, WiFi 14c3:7927)
- Gigabyte Z790 AORUS MASTER X (BT 0489:e10f, WiFi 14c3:7927)
- Gigabyte Z790 AORUS ELITE X WiFi7 (BT 0489:e10f, WiFi 14c3:7927)
- MSI MEG X870E ACE MAX (BT 0489:e110, WiFi 14c3:7927)
- Lenovo Legion Pro 7 16ARX9 (BT 0489:e0fa, WiFi 14c3:7927)
- Lenovo Legion Pro 7 16AFR10H (BT 0489:e0fa, WiFi 14c3:7927)
- TP-Link Archer TBE550E PCIe (BT 0489:e116, WiFi 14c3:7927)
- EDUP EP-MT7927BE M.2 card (WiFi 14c3:7927)
- Foxconn/Azurewave M.2 modules (WiFi 14c3:6639)
- AMD RZ738 reference design (WiFi 14c3:0738)

Tested on Arch Linux, CachyOS, EndeavourOS, Fedora (Bazzite), NixOS, openSUSE Tumbleweed, and Ubuntu across kernels 6.13-6.19.

Changes since v4:
- Add Reviewed-by tags to patches 1-9.
- Add MT7927 follow-up support:
- replace is_mt7925() with is_connac3()
- use link-specific removal for non-MLD STA
- tolerate inactive BSS deactivation
- add MT7927 WFSYS reset support
- factor out common DMA queue allocation
- switch mt7925 DMA init to common mt792x queue helpers
- add MT7927-specific PCIe DMA support
- sync MT7927 BSS band assignment
- add MBMC event handling
- enable CNM ops for MT7927
- add MT7927 PCIe support
- add MT7927 USB support

Changes since v3:
- Dropped patches 9-13 (DMA, HW init, band_idx, PCI IDs). Sean Wang will submit these as part of a generic layer refactor. The CNM quirk (v3 patch 13 feedback) will be folded into mt792x_get_mac80211_ops() as part of that work.
- Fixed is_320mhz_supported() to use mt76_chip() directly instead of is_mt7927() which was not yet defined at that point (patch 5).
- Trimmed verbose inline comments in ASPM/PM patch per review feedback. Detail kept in commit message (patch 9).
- Added tested hardware: ASUS ROG STRIX B850-E GAMING WIFI.

Changes since v2 (suggested by Sean Wang):
- Fixed is_320mhz_supported() to check for MT7927 only, not the entire mt7925 family. MT7925 does not support 320MHz (patch 5).
- Dropped phy_cap_info[7] 320MHz additions (NON_OFDMA_UL_MU_MIMO and MU_BEAMFORMER) to keep capabilities conservative (patch 5).
- Disabled runtime PM for MT7927 (patch 9). The combo chip shares a CONNINFRA power domain between WiFi and BT; SET_OWN/CLR_OWN transitions crash BT firmware. Discovered via user reports of BT lockups after enabling power_save=1 (Reported-by: Nitin Gurram).

Changes since v1 (suggested by Sean Wang):
- Reorganized from 18 patches into 13 across 8 logical groups
- Common 320MHz patches first, chip-specific changes later
- Introduced mt792x_dma_config struct to reuse mt7925_dma_init()
- Replaced is_mt7927() with is_320mhz_supported() in common patches

Link to v4: https://lore.kernel.org/linux-wireless/[email protected]/
Link to v3: https://lore.kernel.org/linux-wireless/[email protected]/
Link to v2: https://lore.kernel.org/linux-wireless/[email protected]/
Link to v1: https://lore.kernel.org/linux-wireless/[email protected]/

Javier Tia (9):
wifi: mt76: mt7925: fix stale pointer comparisons in change_vif_links
wifi: mt76: mt7925: add 320MHz bandwidth to bss_rlm_tlv
wifi: mt76: mt7925: handle 320MHz bandwidth in RXV and TXS
wifi: mt76: mt7925: populate EHT 320MHz MCS map in sta_rec
wifi: mt76: mt7925: advertise EHT 320MHz capabilities for 6GHz band
wifi: mt76: mt7925: add MT7927 chip ID helpers
wifi: mt76: mt7925: add MT7927 firmware paths
wifi: mt76: mt7925: use irq_map for chip-specific interrupt handling
wifi: mt76: mt7925: disable ASPM and runtime PM for MT7927

Sean Wang (12):
wifi: mt76: connac: replace is_mt7925() with is_connac3()
wifi: mt76: mt7925: use link-specific removal for non-MLD STA
wifi: mt76: connac: tolerate inactive BSS deactivation
wifi: mt76: mt792x: add MT7927 WFSYS reset support
wifi: mt76: mt792x: factor out common DMA queue allocation
wifi: mt76: mt7925: switch DMA init to common mt792x queue helpers
wifi: mt76: mt792x: add MT7927-specific PCIe DMA support
wifi: mt76: mt7925: sync MT7927 BSS band assignment
wifi: mt76: mt7925: add MBMC event handling
wifi: mt76: mt792x: enable CNM ops for MT7927
wifi: mt76: mt7925: add MT7927 PCIe support
wifi: mt76: mt7925: add MT7927 USB support

 .../net/wireless/mediatek/mt76/mt76_connac.h  |  16 ++
 .../wireless/mediatek/mt76/mt76_connac_mac.c  |   4 +-
 .../wireless/mediatek/mt76/mt76_connac_mcu.c  |  13 +-
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  |  26 ++-
 .../net/wireless/mediatek/mt76/mt7925/init.c  |  12 +-
 .../net/wireless/mediatek/mt76/mt7925/mac.c   |   9 +
 .../net/wireless/mediatek/mt76/mt7925/main.c  |  80 ++++++-
 .../net/wireless/mediatek/mt76/mt7925/mcu.c   |  43 +++-
 .../net/wireless/mediatek/mt76/mt7925/mcu.h   |   3 +-
 .../wireless/mediatek/mt76/mt7925/mt7925.h    |  25 +++
 .../net/wireless/mediatek/mt76/mt7925/pci.c   | 133 +++++++++---
 .../wireless/mediatek/mt76/mt7925/pci_mac.c   |  12 +-
 .../net/wireless/mediatek/mt76/mt7925/usb.c   |  15 ++
 drivers/net/wireless/mediatek/mt76/mt792x.h   |  25 +++
 .../net/wireless/mediatek/mt76/mt792x_core.c  |  11 +
 .../net/wireless/mediatek/mt76/mt792x_dma.c   | 198 ++++++++++++++++--
 .../net/wireless/mediatek/mt76/mt792x_regs.h  |  23 ++
 .../net/wireless/mediatek/mt76/mt792x_usb.c   |   2 +-
 drivers/net/wireless/mediatek/mt76/usb.c      |   1 +
 19 files changed, 578 insertions(+), 73 deletions(-)

base-commit: e8c819df02436f2c2379766946735e1f06a7c923

Signature · 1 line
2.43.0
author
#1 lore raw

PATCH v5 1/21 wifi: mt76: mt7925: fix stale pointer comparisons in change_vif_links

From: Javier Tia <[email protected]>

In the error path of mt7925_change_vif_links(), the free: label iterates over link_ids to clean up, but compares against mconf and mlink which hold stale values from the last loop iteration rather than the current link_id being freed.

Use array-indexed access (mconfs[link_id] / mlinks[link_id]) to compare against the correct per-link pointers.

---
 drivers/net/wireless/mediatek/mt76/mt7925/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/main.c +2 -2
index 73d3722739d0..4d8ca04a128b 100644
@@ -2179,9 +2179,9 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		rcu_assign_pointer(mvif->link_conf[link_id], NULL);
 		rcu_assign_pointer(mvif->sta.link[link_id], NULL);
 
-		if (mconf != &mvif->bss_conf)
+		if (mconfs[link_id] != &mvif->bss_conf)
 			devm_kfree(dev->mt76.dev, mconfs[link_id]);
-		if (mlink != &mvif->sta.deflink)
+		if (mlinks[link_id] != &mvif->sta.deflink)
 			devm_kfree(dev->mt76.dev, mlinks[link_id]);
 	}
 
Signature · 1 line
2.43.0
author
#2 lore raw

PATCH v5 2/21 wifi: mt76: mt7925: add 320MHz bandwidth to bss_rlm_tlv

In reply to Sean Wang

From: Javier Tia <[email protected]>

bss_rlm_tlv() in mt7925_mcu_bss_rlm_tlv() has no case for NL80211_CHAN_WIDTH_320. When associated to a 320MHz BSS, the switch falls through to default and sends bw=0 (CMD_CBW_20MHZ) to firmware via BSS_RLM TLV. Firmware then configures the RX radio for 20MHz and cannot decode the AP's 320MHz frames, resulting in complete data path failure at 320MHz.

Add the missing NL80211_CHAN_WIDTH_320 case with CMD_CBW_320MHZ and center_chan2.

Tested on ASUS RT-BE92U: 320MHz throughput goes from 0 Mbps to 841 Mbps (iperf3 -t30 -P8), PHY 4803 Mbps EHT-MCS11.

---
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +4 -0
index 37cdf3e8a067..016c534f748c 100644
@@ -2334,6 +2334,10 @@ void mt7925_mcu_bss_rlm_tlv(struct sk_buff *skb, struct mt76_phy *phy,
 	case NL80211_CHAN_WIDTH_160:
 		req->bw = CMD_CBW_160MHZ;
 		break;
+	case NL80211_CHAN_WIDTH_320:
+		req->bw = CMD_CBW_320MHZ;
+		req->center_chan2 = ieee80211_frequency_to_channel(freq2);
+		break;
 	case NL80211_CHAN_WIDTH_5:
 		req->bw = CMD_CBW_5MHZ;
 		break;
Signature · 1 line
2.43.0
author
#3 lore raw

PATCH v5 3/21 wifi: mt76: mt7925: handle 320MHz bandwidth in RXV and TXS

In reply to Sean Wang

From: Javier Tia <[email protected]>

The RX vector (RXV) and TX status (TXS) parsing in mac.c lack handling for 320MHz channel width. When the hardware reports 320MHz in the bandwidth field, mt7925_mac_fill_rx_rate() returns -EINVAL and mt7925_mac_add_txs_skb() records no bandwidth stats.

Add IEEE80211_STA_RX_BW_320 cases to both functions. The RXV parser also handles BW_320+1 since the hardware can report 320MHz in two adjacent encoding positions.

---
 drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/mac.c +9 -0
index c47bd812b66b..d681005cc6ff 100644
@@ -339,6 +339,11 @@ mt7925_mac_fill_rx_rate(struct mt792x_dev *dev,
 	case IEEE80211_STA_RX_BW_160:
 		status->bw = RATE_INFO_BW_160;
 		break;
+	/* RXV can report 320 in two positions */
+	case IEEE80211_STA_RX_BW_320:
+	case IEEE80211_STA_RX_BW_320 + 1:
+		status->bw = RATE_INFO_BW_320;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -997,6 +1002,10 @@ mt7925_mac_add_txs_skb(struct mt792x_dev *dev, struct mt76_wcid *wcid,
 	stats->tx_mode[mode]++;
 
 	switch (FIELD_GET(MT_TXS0_BW, txs)) {
+	case IEEE80211_STA_RX_BW_320:
+		rate.bw = RATE_INFO_BW_320;
+		stats->tx_bw[4]++;
+		break;
 	case IEEE80211_STA_RX_BW_160:
 		rate.bw = RATE_INFO_BW_160;
 		stats->tx_bw[3]++;
Signature · 1 line
2.43.0
author
#4 lore raw

PATCH v5 4/21 wifi: mt76: mt7925: populate EHT 320MHz MCS map in sta_rec

In reply to Sean Wang

From: Javier Tia <[email protected]>

The sta_rec_eht structure has a mcs_map_bw320 field, and the channel width mapping includes NL80211_CHAN_WIDTH_320, but the 320MHz MCS/NSS map was never copied from the station's EHT capabilities to the MCU TLV. This prevents negotiation of 320MHz channel width even when both the hardware and firmware advertise support for it.

Add the missing memcpy for the 320MHz MCS map, matching the existing pattern for BW20, BW80, and BW160.

---
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +1 -0
index 016c534f748c..f403d9d925e3 100644
@@ -1667,6 +1667,7 @@ mt7925_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_link_sta *link_sta)
 		memcpy(eht->mcs_map_bw20, &mcs_map->only_20mhz, sizeof(eht->mcs_map_bw20));
 	memcpy(eht->mcs_map_bw80, &mcs_map->bw._80, sizeof(eht->mcs_map_bw80));
 	memcpy(eht->mcs_map_bw160, &mcs_map->bw._160, sizeof(eht->mcs_map_bw160));
+	memcpy(eht->mcs_map_bw320, &mcs_map->bw._320, sizeof(eht->mcs_map_bw320));
 }
 
 static void
Signature · 1 line
2.43.0
author
#5 lore raw

PATCH v5 5/21 wifi: mt76: mt7925: advertise EHT 320MHz capabilities for 6GHz band

In reply to Sean Wang

From: Javier Tia <[email protected]>

mt7925_init_eht_caps() only populates EHT MCS/NSS maps for BW <= 80 and BW = 160, but never sets BW = 320. This means iw phy shows no 320MHz MCS map entries even though the hardware supports 320MHz operation in the 6GHz band.

Add the missing 320MHz capability bits for 6GHz:
- PHY_CAP0: IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ
- PHY_CAP1: beamformee SS for 320MHz
- PHY_CAP2: sounding dimensions for 320MHz
- PHY_CAP6: MCS15 support for 320MHz width
- MCS/NSS: populate bw._320 maps for 6GHz band

Introduce is_320mhz_supported() to gate 320MHz on MT7927 only, since MT7925 does not support 320MHz operation.

---
 .../net/wireless/mediatek/mt76/mt76_connac.h  |  5 +++++
 .../net/wireless/mediatek/mt76/mt7925/main.c  | 22 ++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt76_connac.h +5 -0
index 51423c7740bd..802cb26ed6e3 100644
@@ -177,6 +177,11 @@ static inline bool is_mt7925(struct mt76_dev *dev)
 	return mt76_chip(dev) == 0x7925;
 }
 
+static inline bool is_320mhz_supported(struct mt76_dev *dev)
+{
+	return mt76_chip(dev) == 0x7927;
+}
+
 static inline bool is_mt7920(struct mt76_dev *dev)
 {
 	return mt76_chip(dev) == 0x7920;
drivers/net/wireless/mediatek/mt76/mt7925/main.c +21 -1
index 4d8ca04a128b..bf38d6502970 100644
@@ -183,6 +183,10 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 		IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |
 		IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
 
+	if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76))
+		eht_cap_elem->phy_cap_info[0] |=
+			IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
+
 	eht_cap_elem->phy_cap_info[0] |=
 		u8_encode_bits(u8_get_bits(sts - 1, BIT(0)),
 			       IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK);
@@ -193,10 +197,20 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 		u8_encode_bits(sts - 1,
 			       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK);
 
+	if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76))
+		eht_cap_elem->phy_cap_info[1] |=
+			u8_encode_bits(sts - 1,
+				       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK);
+
 	eht_cap_elem->phy_cap_info[2] =
 		u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK) |
 		u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK);
 
+	if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76))
+		eht_cap_elem->phy_cap_info[2] |=
+			u8_encode_bits(sts - 1,
+				       IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK);
+
 	eht_cap_elem->phy_cap_info[3] =
 		IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK |
 		IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |
@@ -217,7 +231,8 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 		u8_encode_bits(u8_get_bits(0x11, GENMASK(1, 0)),
 			       IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK);
 
-	val = width == NL80211_CHAN_WIDTH_160 ? 0x7 :
+	val = width == NL80211_CHAN_WIDTH_320 ? 0xf :
+	      width == NL80211_CHAN_WIDTH_160 ? 0x7 :
 	      width == NL80211_CHAN_WIDTH_80 ? 0x3 : 0x1;
 	eht_cap_elem->phy_cap_info[6] =
 		u8_encode_bits(u8_get_bits(0x11, GENMASK(4, 2)),
@@ -239,6 +254,11 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 	eht_nss->bw._160.rx_tx_mcs9_max_nss = val;
 	eht_nss->bw._160.rx_tx_mcs11_max_nss = val;
 	eht_nss->bw._160.rx_tx_mcs13_max_nss = val;
+	if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76)) {
+		eht_nss->bw._320.rx_tx_mcs9_max_nss = val;
+		eht_nss->bw._320.rx_tx_mcs11_max_nss = val;
+		eht_nss->bw._320.rx_tx_mcs13_max_nss = val;
+	}
 }
 
 int mt7925_init_mlo_caps(struct mt792x_phy *phy)
Signature · 1 line
2.43.0
author
#6 lore raw

PATCH v5 6/21 wifi: mt76: mt7925: add MT7927 chip ID helpers

In reply to Sean Wang

From: Javier Tia <[email protected]>

The MediaTek MT7927 (Filogic 380) combo chip uses MT7927 WiFi silicon that is architecturally compatible with MT7925. Extend is_mt7925() to match chip ID 0x7927, and add is_mt7927() for code paths that need MT7927-specific handling.

Also add 0x7927 to is_mt76_fw_txp() to match MT7925's TXP format.

---
 drivers/net/wireless/mediatek/mt76/mt76_connac.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt76_connac.h +7 -1
index 802cb26ed6e3..45479cc29134 100644
@@ -174,7 +174,12 @@ extern const struct wiphy_wowlan_support mt76_connac_wowlan_support;
 
 static inline bool is_mt7925(struct mt76_dev *dev)
 {
-	return mt76_chip(dev) == 0x7925;
+	return mt76_chip(dev) == 0x7925 || mt76_chip(dev) == 0x7927;
+}
+
+static inline bool is_mt7927(struct mt76_dev *dev)
+{
+	return mt76_chip(dev) == 0x7927;
 }
 
 static inline bool is_320mhz_supported(struct mt76_dev *dev)
@@ -284,6 +289,7 @@ static inline bool is_mt76_fw_txp(struct mt76_dev *dev)
 	case 0x7922:
 	case 0x7902:
 	case 0x7925:
+	case 0x7927:
 	case 0x7663:
 	case 0x7622:
 		return false;
Signature · 1 line
2.43.0
author
#7 lore raw

PATCH v5 7/21 wifi: mt76: mt7925: add MT7927 firmware paths

In reply to Sean Wang

From: Javier Tia <[email protected]>

Add firmware path definitions for MT7927 WiFi firmware (WIFI_RAM_CODE and PATCH_MCU) and the corresponding MODULE_FIRMWARE declarations. Add MT7927 cases to mt792x_ram_name() and mt792x_patch_name() so the driver loads the correct firmware for the 0x7927 chip ID.

PCI device table entries are deferred to a later patch to allow infrastructure setup before device enablement.

---
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 2 ++
 drivers/net/wireless/mediatek/mt76/mt792x.h     | 6 ++++++
 2 files changed, 8 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/pci.c +2 -0
index c4161754c01d..f820d5aeb723 100644
@@ -633,6 +633,8 @@ module_pci_driver(mt7925_pci_driver);
 MODULE_DEVICE_TABLE(pci, mt7925_pci_device_table);
 MODULE_FIRMWARE(MT7925_FIRMWARE_WM);
 MODULE_FIRMWARE(MT7925_ROM_PATCH);
+MODULE_FIRMWARE(MT7927_FIRMWARE_WM);
+MODULE_FIRMWARE(MT7927_ROM_PATCH);
 MODULE_AUTHOR("Deren Wu <[email protected]>");
 MODULE_AUTHOR("Lorenzo Bianconi <[email protected]>");
 MODULE_DESCRIPTION("MediaTek MT7925E (PCIe) wireless driver");
drivers/net/wireless/mediatek/mt76/mt792x.h +6 -0
index 4ff93f2cd624..09840483fe2a 100644
@@ -46,12 +46,14 @@
 #define MT7921_FIRMWARE_WM	"mediatek/WIFI_RAM_CODE_MT7961_1.bin"
 #define MT7922_FIRMWARE_WM	"mediatek/WIFI_RAM_CODE_MT7922_1.bin"
 #define MT7925_FIRMWARE_WM	"mediatek/mt7925/WIFI_RAM_CODE_MT7925_1_1.bin"
+#define MT7927_FIRMWARE_WM	"mediatek/mt7927/WIFI_RAM_CODE_MT6639_2_1.bin"
 
 #define MT7902_ROM_PATCH	"mediatek/WIFI_MT7902_patch_mcu_1_1_hdr.bin"
 #define MT7920_ROM_PATCH	"mediatek/WIFI_MT7961_patch_mcu_1a_2_hdr.bin"
 #define MT7921_ROM_PATCH	"mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin"
 #define MT7922_ROM_PATCH	"mediatek/WIFI_MT7922_patch_mcu_1_1_hdr.bin"
 #define MT7925_ROM_PATCH	"mediatek/mt7925/WIFI_MT7925_PATCH_MCU_1_1_hdr.bin"
+#define MT7927_ROM_PATCH	"mediatek/mt7927/WIFI_MT6639_PATCH_MCU_2_1_hdr.bin"
 
 #define MT792x_SDIO_HDR_TX_BYTES	GENMASK(15, 0)
 #define MT792x_SDIO_HDR_PKT_TYPE	GENMASK(17, 16)
@@ -459,6 +461,8 @@ static inline char *mt792x_ram_name(struct mt792x_dev *dev)
 		return MT7922_FIRMWARE_WM;
 	case 0x7925:
 		return MT7925_FIRMWARE_WM;
+	case 0x7927:
+		return MT7927_FIRMWARE_WM;
 	default:
 		return MT7921_FIRMWARE_WM;
 	}
@@ -475,6 +479,8 @@ static inline char *mt792x_patch_name(struct mt792x_dev *dev)
 		return MT7922_ROM_PATCH;
 	case 0x7925:
 		return MT7925_ROM_PATCH;
+	case 0x7927:
+		return MT7927_ROM_PATCH;
 	default:
 		return MT7921_ROM_PATCH;
 	}
Signature · 1 line
2.43.0
author
#8 lore raw

PATCH v5 8/21 wifi: mt76: mt7925: use irq_map for chip-specific interrupt handling

In reply to Sean Wang

From: Javier Tia <[email protected]>

The mac_reset and resume paths use the hardcoded MT_INT_RX_DONE_ALL constant (bits 0-2) to re-enable RX interrupts. This is correct for MT7925 (RX rings 0, 1, 2) but wrong for chips using different ring indices.

Define a per-chip irq_map with the correct RX interrupt enable bits and replace hardcoded MT_INT_RX_DONE_ALL with irq_map field reads in the resume and mac_reset paths. Add the MT7927 irq_map with interrupt bits matching its RX ring layout (rings 4, 6, 7), selected at probe time based on PCI device ID.

This ensures the correct interrupt bits are enabled regardless of the chip variant.

---
 .../net/wireless/mediatek/mt76/mt7925/pci.c   | 21 +++++++++++++++++--
 .../wireless/mediatek/mt76/mt7925/pci_mac.c   |  5 ++++-
 .../net/wireless/mediatek/mt76/mt792x_regs.h  |  3 +++
 3 files changed, 26 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/pci.c +19 -2
index f820d5aeb723..604c0e9ae7ba 100644
@@ -266,6 +266,18 @@ static int mt7925_dma_init(struct mt792x_dev *dev)
 	return mt792x_dma_enable(dev);
 }
 
+static const struct mt792x_irq_map mt7927_irq_map = {
+	.host_irq_enable = MT_WFDMA0_HOST_INT_ENA,
+	.tx = {
+		.all_complete_mask = MT_INT_TX_DONE_ALL,
+		.mcu_complete_mask = MT_INT_TX_DONE_MCU,
+	},
+	.rx = {
+		.data_complete_mask = MT7927_RX_DONE_INT_ENA4,
+		.wm_complete_mask = MT7927_RX_DONE_INT_ENA6,
+		.wm2_complete_mask = MT7927_RX_DONE_INT_ENA7,
+	},
+};
 static int mt7925_pci_probe(struct pci_dev *pdev,
 			    const struct pci_device_id *id)
 {
@@ -310,6 +322,7 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	struct mt76_bus_ops *bus_ops;
 	struct mt792x_dev *dev;
 	struct mt76_dev *mdev;
+	bool is_mt7927_hw;
 	u8 features;
 	int ret;
 	u16 cmd;
@@ -358,7 +371,8 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	dev = container_of(mdev, struct mt792x_dev, mt76);
 	dev->fw_features = features;
 	dev->hif_ops = &mt7925_pcie_ops;
-	dev->irq_map = &irq_map;
+	is_mt7927_hw = (pdev->device == 0x6639 || pdev->device == 0x7927);
+	dev->irq_map = is_mt7927_hw ? &mt7927_irq_map : &irq_map;
 	mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
 	tasklet_init(&mdev->irq_tasklet, mt792x_irq_tasklet, (unsigned long)dev);
 
@@ -549,7 +563,10 @@ static int _mt7925_pci_resume(struct device *device, bool restore)
 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
 	mt76_connac_irq_enable(&dev->mt76,
 			       dev->irq_map->tx.all_complete_mask |
-			       MT_INT_RX_DONE_ALL | MT_INT_MCU_CMD);
+			       dev->irq_map->rx.data_complete_mask |
+			       dev->irq_map->rx.wm_complete_mask |
+			       dev->irq_map->rx.wm2_complete_mask |
+			       MT_INT_MCU_CMD);
 	mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);
 
 	/* put dma enabled */
drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c +4 -1
index 3072850c2752..1626a3684082 100644
@@ -118,7 +118,10 @@ int mt7925e_mac_reset(struct mt792x_dev *dev)
 
 	mt76_wr(dev, dev->irq_map->host_irq_enable,
 		dev->irq_map->tx.all_complete_mask |
-		MT_INT_RX_DONE_ALL | MT_INT_MCU_CMD);
+		dev->irq_map->rx.data_complete_mask |
+		dev->irq_map->rx.wm_complete_mask |
+		dev->irq_map->rx.wm2_complete_mask |
+		MT_INT_MCU_CMD);
 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
 
 	err = mt792xe_mcu_fw_pmctrl(dev);
drivers/net/wireless/mediatek/mt76/mt792x_regs.h +3 -0
index d2a8b2b0df32..20d27ae89aca 100644
@@ -310,6 +310,9 @@
 #define HOST_RX_DONE_INT_ENA1		BIT(1)
 #define HOST_RX_DONE_INT_ENA2		BIT(2)
 #define HOST_RX_DONE_INT_ENA3		BIT(3)
+#define MT7927_RX_DONE_INT_ENA4		BIT(12)
+#define MT7927_RX_DONE_INT_ENA6		BIT(14)
+#define MT7927_RX_DONE_INT_ENA7		BIT(15)
 #define HOST_TX_DONE_INT_ENA0		BIT(4)
 #define HOST_TX_DONE_INT_ENA1		BIT(5)
 #define HOST_TX_DONE_INT_ENA2		BIT(6)
Signature · 1 line
2.43.0
author
#9 lore raw

PATCH v5 9/21 wifi: mt76: mt7925: disable ASPM and runtime PM for MT7927

In reply to Sean Wang

From: Javier Tia <[email protected]>

Disable PCIe ASPM unconditionally for MT7927. The CONNINFRA power domain and WFDMA register access are unreliable with PCIe L1 active, causing throughput to drop from 1+ Gbps to ~200 Mbps.

Disable runtime PM and deep sleep for MT7927. The combo chip shares a CONNINFRA power domain between WiFi (PCIe) and BT (USB). SET_OWN/CLR_OWN transitions on the LPCTL register crash the BT firmware, requiring a full power cycle to recover. PM enablement will be addressed in a follow-up once safe power state transitions are determined.

---
 drivers/net/wireless/mediatek/mt76/mt7925/init.c | 3 ++-
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c  | 6 ++++--
 2 files changed, 6 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/init.c +2 -1
index c0c5cb9aff75..a8c2ca7c0efc 100644
@@ -232,7 +232,8 @@ int mt7925_register_device(struct mt792x_dev *dev)
 	dev->pm.idle_timeout = MT792x_PM_TIMEOUT;
 	dev->pm.stats.last_wake_event = jiffies;
 	dev->pm.stats.last_doze_event = jiffies;
-	if (!mt76_is_usb(&dev->mt76)) {
+	/* MT7927: runtime PM crashes BT firmware on the shared CONNINFRA domain */
+	if (!mt76_is_usb(&dev->mt76) && !is_mt7927(&dev->mt76)) {
 		dev->pm.enable_user = true;
 		dev->pm.enable = true;
 		dev->pm.ds_enable_user = true;
drivers/net/wireless/mediatek/mt76/mt7925/pci.c +4 -2
index 604c0e9ae7ba..1f05c212be02 100644
@@ -350,7 +350,10 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	if (ret)
 		goto err_free_pci_vec;
 
-	if (mt7925_disable_aspm)
+	is_mt7927_hw = (pdev->device == 0x6639 || pdev->device == 0x7927);
+
+	/* MT7927: ASPM L1 causes unreliable WFDMA register access */
+	if (mt7925_disable_aspm || is_mt7927_hw)
 		mt76_pci_disable_aspm(pdev);
 
 	ops = mt792x_get_mac80211_ops(&pdev->dev, &mt7925_ops,
@@ -371,7 +374,6 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	dev = container_of(mdev, struct mt792x_dev, mt76);
 	dev->fw_features = features;
 	dev->hif_ops = &mt7925_pcie_ops;
-	is_mt7927_hw = (pdev->device == 0x6639 || pdev->device == 0x7927);
 	dev->irq_map = is_mt7927_hw ? &mt7927_irq_map : &irq_map;
 	mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
 	tasklet_init(&mdev->irq_tasklet, mt792x_irq_tasklet, (unsigned long)dev);
Signature · 1 line
2.43.0
author
#10 lore raw

PATCH v5 10/21 wifi: mt76: connac: replace is_mt7925() with is_connac3()

In reply to Sean Wang

From: Sean Wang <[email protected]>

Use is_connac3() instead of is_mt7925() to avoid confusion when more chips join.

---
 drivers/net/wireless/mediatek/mt76/mt76_connac.h     | 7 ++++++-
 drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 4 ++--
 drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 4 ++--
 drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h | 2 +-
 drivers/net/wireless/mediatek/mt76/mt792x_usb.c      | 2 +-
 5 files changed, 12 insertions(+), 7 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac.h +6 -1
index 45479cc29134..1994863dc59d 100644
@@ -172,11 +172,16 @@ struct mt76_connac_tx_free {
 
 extern const struct wiphy_wowlan_support mt76_connac_wowlan_support;
 
-static inline bool is_mt7925(struct mt76_dev *dev)
+static inline bool is_connac3(struct mt76_dev *dev)
 {
 	return mt76_chip(dev) == 0x7925 || mt76_chip(dev) == 0x7927;
 }
 
+static inline bool is_mt7925(struct mt76_dev *dev)
+{
+	return mt76_chip(dev) == 0x7925;
+}
+
 static inline bool is_mt7927(struct mt76_dev *dev)
 {
 	return mt76_chip(dev) == 0x7927;
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +2 -2
index 0339e2e7ab60..c341595e9138 100644
@@ -173,7 +173,7 @@ void mt76_connac_write_hw_txp(struct mt76_dev *dev,
 
 	txp->msdu_id[0] = cpu_to_le16(id | MT_MSDU_ID_VALID);
 
-	if (is_mt7663(dev) || is_connac2(dev) || is_mt7925(dev))
+	if (is_mt7663(dev) || is_connac2(dev) || is_connac3(dev))
 		last_mask = MT_TXD_LEN_LAST;
 	else
 		last_mask = MT_TXD_LEN_AMSDU_LAST |
@@ -217,7 +217,7 @@ mt76_connac_txp_skb_unmap_hw(struct mt76_dev *dev,
 	u32 last_mask;
 	int i;
 
-	if (is_mt7663(dev) || is_connac2(dev) || is_mt7925(dev))
+	if (is_mt7663(dev) || is_connac2(dev) || is_connac3(dev))
 		last_mask = MT_TXD_LEN_LAST;
 	else
 		last_mask = MT_TXD_LEN_MSDU_LAST;
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +2 -2
index 89bd52ea8bf7..2b1c887d6709 100644
@@ -67,7 +67,7 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
 
 	if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
 	    (is_connac2(dev) && addr == 0x900000) ||
-	    (is_mt7925(dev) && (addr == 0x900000 || addr == 0xe0002800)) ||
+	    (is_connac3(dev) && (addr == 0x900000 || addr == 0xe0002800)) ||
 	    (is_mt799x(dev) && addr == 0x900000))
 		cmd = MCU_CMD(PATCH_START_REQ);
 	else
@@ -3084,7 +3084,7 @@ static u32 mt76_connac2_get_data_mode(struct mt76_dev *dev, u32 info)
 {
 	u32 mode = DL_MODE_NEED_RSP;
 
-	if ((!is_connac2(dev) && !is_mt7925(dev)) || info == PATCH_SEC_NOT_SUPPORT)
+	if ((!is_connac2(dev) && !is_connac3(dev)) || info == PATCH_SEC_NOT_SUPPORT)
 		return mode;
 
 	switch (FIELD_GET(PATCH_SEC_ENC_TYPE_MASK, info)) {
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +1 -1
index ac5126ab68ff..552cb94edaa0 100644
@@ -1878,7 +1878,7 @@ mt76_connac_mcu_gen_dl_mode(struct mt76_dev *dev, u8 feature_set, bool is_wa)
 
 	ret |= feature_set & FW_FEATURE_SET_ENCRYPT ?
 	       DL_MODE_ENCRYPT | DL_MODE_RESET_SEC_IV : 0;
-	if (is_connac2(dev) || is_mt7925(dev))
+	if (is_connac2(dev) || is_connac3(dev))
 		ret |= feature_set & FW_FEATURE_ENCRY_MODE ?
 		       DL_CONFIG_ENCRY_MODE_SEL : 0;
 	ret |= FIELD_PREP(DL_MODE_KEY_IDX,
drivers/net/wireless/mediatek/mt76/mt792x_usb.c +1 -1
index 47827d1c5ccb..7bb9840112ac 100644
@@ -263,7 +263,7 @@ EXPORT_SYMBOL_GPL(mt792xu_dma_init);
 
 int mt792xu_wfsys_reset(struct mt792x_dev *dev)
 {
-	const struct mt792xu_wfsys_desc *desc = is_mt7925(&dev->mt76) ?
+	const struct mt792xu_wfsys_desc *desc = is_connac3(&dev->mt76) ?
 						&mt7925_wfsys_desc :
 						&mt7921_wfsys_desc;
 	u32 val;
Signature · 1 line
2.43.0
author
#11 lore raw

PATCH v5 11/21 wifi: mt76: mt7925: use link-specific removal for non-MLD STA

In reply to Sean Wang

From: Sean Wang <[email protected]>

Use the default link removal path for non-MLD STA instead of the multi-link flow.

---
 drivers/net/wireless/mediatek/mt76/mt7925/main.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/main.c +6 -6
index bf38d6502970..044043a8768d 100644
@@ -1338,14 +1338,14 @@ void mt7925_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 	struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
 	struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
-	unsigned long rem;
 
-	rem = ieee80211_vif_is_mld(vif) ? msta->valid_links : BIT(0);
-
-	mt7925_mac_sta_remove_links(dev, vif, sta, rem);
-
-	if (ieee80211_vif_is_mld(vif))
+	if (ieee80211_vif_is_mld(vif)) {
+		mt7925_mac_sta_remove_links(dev, vif, sta, msta->valid_links);
 		mt7925_mcu_del_dev(mdev, vif);
+	} else {
+		mt7925_mac_link_sta_remove(mdev, vif, &sta->deflink,
+					   &msta->deflink);
+	}
 
 	if (vif->type == NL80211_IFTYPE_STATION) {
 		mvif->wep_sta = NULL;
Signature · 1 line
2.43.0
author
#12 lore raw

PATCH v5 12/21 wifi: mt76: connac: tolerate inactive BSS deactivation

In reply to Sean Wang

From: Sean Wang <[email protected]>

Firmware may return wlan_failure when deactivating a BSS that is already inactive. This is a valid teardown case and should not fail the remove path.

Keep activation failures unchanged since they still indicate that firmware failed to create or activate the BSS state.

---
 .../wireless/mediatek/mt76/mt76_connac_mcu.c  |  9 +++++++-
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  | 23 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7925/mcu.c   |  6 +++--
 3 files changed, 35 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +8 -1
index 2b1c887d6709..0f2d580c7b4a 100644
@@ -1227,6 +1227,9 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
 	len = enable ? sizeof(dev_req) : sizeof(basic_req);
 
 	err = mt76_mcu_send_msg(dev, cmd, data, len, true);
+	if (err && cmd == MCU_UNI_CMD(BSS_INFO_UPDATE))
+		err = mt76_connac_mcu_bss_deact_err(dev, err, enable);
+
 	if (err < 0)
 		return err;
 
@@ -1234,7 +1237,11 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
 	data = enable ? (void *)&basic_req : (void *)&dev_req;
 	len = enable ? sizeof(basic_req) : sizeof(dev_req);
 
-	return mt76_mcu_send_msg(dev, cmd, data, len, true);
+	err = mt76_mcu_send_msg(dev, cmd, data, len, true);
+	if (err && cmd == MCU_UNI_CMD(BSS_INFO_UPDATE))
+		err = mt76_connac_mcu_bss_deact_err(dev, err, enable);
+
+	return err;
 }
 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev);
 
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +23 -0
index 552cb94edaa0..4691b9b5e2be 100644
@@ -1906,6 +1906,29 @@ mt76_connac_mcu_get_wlan_idx(struct mt76_dev *dev, struct mt76_wcid *wcid,
 	}
 }
 
+#define MT76_CONNAC_MCU_STATUS_WLAN_FAILURE	0xc0000001
+
+static inline int
+mt76_connac_mcu_bss_deact_err(struct mt76_dev *mdev, int err, bool enable)
+{
+	if (err != (int)MT76_CONNAC_MCU_STATUS_WLAN_FAILURE)
+		return err;
+
+	/* Ignore wlan_failure state false alarm when deactivating an
+	 * inactive network. It does not harm the firmware state.
+	 */
+	if (!enable) {
+		dev_dbg(mdev->dev,
+			"ignore wlan_failure when bss is deactivated\n");
+		return 0;
+	}
+
+	dev_warn(mdev->dev,
+		 "wlan_failure when bss is activated\n");
+
+	return err;
+}
+
 struct sk_buff *
 __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif_link *mvif,
 				struct mt76_wcid *wcid, int len);
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +4 -2
index f403d9d925e3..b338d6bf02f5 100644
@@ -2832,6 +2832,7 @@ int mt7925_mcu_add_bss_info_sta(struct mt792x_phy *phy,
 	struct mt792x_bss_conf *mconf = mt792x_link_conf_to_mconf(link_conf);
 	struct mt792x_dev *dev = phy->dev;
 	struct sk_buff *skb;
+	int err;
 
 	skb = __mt7925_mcu_alloc_bss_req(&dev->mt76, &mconf->mt76,
 					 MT7925_BSS_UPDATE_MAX_SIZE);
@@ -2857,8 +2858,9 @@ int mt7925_mcu_add_bss_info_sta(struct mt792x_phy *phy,
 		mt7925_mcu_bss_mbssid_tlv(skb, link_conf, enable);
 	}
 
-	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-				     MCU_UNI_CMD(BSS_INFO_UPDATE), true);
+	err = mt76_mcu_skb_send_msg(&dev->mt76, skb,
+				    MCU_UNI_CMD(BSS_INFO_UPDATE), true);
+	return mt76_connac_mcu_bss_deact_err(&dev->mt76, err, enable);
 }
 
 int mt7925_mcu_add_bss_info(struct mt792x_phy *phy,
Signature · 1 line
2.43.0
author
#13 lore raw

PATCH v5 13/21 wifi: mt76: mt792x: add MT7927 WFSYS reset support

In reply to Sean Wang

From: Sean Wang <[email protected]>

Add a dedicated MT7927 WFSYS reset path in mt792x_wfsys_reset().

Unlike the existing connac2/connac3 reset flow that toggles the WFSYS software reset bit and waits for init-done, MT7927 reset is driven through CBInfra and requires polling ROMCODE_INDEX until the MCU returns to the idle value after reset.

Keep this dormant for now: no MT7927 PCI IDs are added by this patch, so it only prepares the reset logic without making the driver bind to MT7927 hardware yet.

---
 .../net/wireless/mediatek/mt76/mt792x_dma.c   | 57 ++++++++++++++++++-
 .../net/wireless/mediatek/mt76/mt792x_regs.h  | 11 ++++
 2 files changed, 67 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt792x_dma.c +56 -1
index 002aece857b2..2835bf273154 100644
@@ -370,7 +370,54 @@ int mt792x_poll_rx(struct napi_struct *napi, int budget)
 }
 EXPORT_SYMBOL_GPL(mt792x_poll_rx);
 
-int mt792x_wfsys_reset(struct mt792x_dev *dev)
+static void mt7927_sema_status_read(struct mt792x_dev *dev, u32 addr)
+{
+	u32 remap;
+
+	remap = mt76_rr(dev, MT7927_PCIE2AP_REMAP_WF_0_54);
+	mt76_wr(dev, MT7927_PCIE2AP_REMAP_WF_0_54,
+		(remap & ~MT7927_PCIE2AP_REMAP_WF_0_54_MASK) |
+		MT7927_PCIE2AP_REMAP_WF_0_54_VAL);
+	usleep_range(10, 20);
+
+	mt76_rr(dev, addr);
+
+	mt76_wr(dev, MT7927_PCIE2AP_REMAP_WF_0_54, remap);
+	usleep_range(10, 20);
+}
+
+static int mt7927_wfsys_reset(struct mt792x_dev *dev)
+{
+	struct mt76_dev *mdev = &dev->mt76;
+	u32 val;
+
+	mt7927_sema_status_read(dev, MT7927_SEMA_OWN_STA);
+
+	mt76_set(dev, MT7927_CBINFRA_RGU_WF_RST,
+		 MT7927_CBINFRA_RGU_WF_RST_WF_SUBSYS);
+	usleep_range(1000, 2000);
+
+	mt76_clear(dev, MT7927_CBINFRA_RGU_WF_RST,
+		   MT7927_CBINFRA_RGU_WF_RST_WF_SUBSYS);
+	usleep_range(5000, 10000);
+
+	mt76_wr(dev, MT7927_CBINFRA_MCU_OWN_SET, BIT(0));
+
+	if (!__mt76_poll_msec(mdev, MT7927_ROMCODE_INDEX, 0xffff,
+			      MT7927_MCU_IDLE_VALUE, 200)) {
+		val = mt76_rr(dev, MT7927_ROMCODE_INDEX);
+		dev_err(mdev->dev,
+			"MT7927 WFSYS reset timeout (ROMCODE_INDEX=0x%04x)\n",
+			val & 0xffff);
+		return -ETIMEDOUT;
+	}
+
+	mt7927_sema_status_read(dev, MT7927_SEMA_OWN_STA_REP);
+
+	return 0;
+}
+
+static int mt792x_wfsys_reset_default(struct mt792x_dev *dev)
 {
 	u32 addr = is_connac2(&dev->mt76) ? 0x18000140 : 0x7c000140;
 
@@ -384,5 +431,13 @@ int mt792x_wfsys_reset(struct mt792x_dev *dev)
 
 	return 0;
 }
+
+int mt792x_wfsys_reset(struct mt792x_dev *dev)
+{
+	if (is_mt7927(&dev->mt76))
+		return mt7927_wfsys_reset(dev);
+
+	return mt792x_wfsys_reset_default(dev);
+}
 EXPORT_SYMBOL_GPL(mt792x_wfsys_reset);
 
drivers/net/wireless/mediatek/mt76/mt792x_regs.h +11 -0
index 20d27ae89aca..17504ef8e80d 100644
@@ -493,4 +493,15 @@
 #define WFSYS_SW_RST_B			BIT(0)
 #define WFSYS_SW_INIT_DONE		BIT(4)
 
+/* CBInfra registers - MT7927 combo chip */
+#define MT7927_CBINFRA_RGU_WF_RST		0x1f8600
+#define MT7927_CBINFRA_RGU_WF_RST_WF_SUBSYS	BIT(4)
+#define MT7927_CBINFRA_MCU_OWN_SET		0x1f5034
+#define MT7927_ROMCODE_INDEX			0xc1604
+#define MT7927_MCU_IDLE_VALUE			0x1d1e
+#define MT7927_PCIE2AP_REMAP_WF_0_54		0x21008
+#define MT7927_PCIE2AP_REMAP_WF_0_54_MASK	GENMASK(15, 0)
+#define MT7927_PCIE2AP_REMAP_WF_0_54_VAL	0x00001807
+#define MT7927_SEMA_OWN_STA			0x40000
+#define MT7927_SEMA_OWN_STA_REP			0x40400
 #endif /* __MT792X_REGS_H */
Signature · 1 line
2.43.0
author
#14 lore raw

PATCH v5 14/21 wifi: mt76: mt792x: factor out common DMA queue allocation

In reply to Sean Wang

From: Sean Wang <[email protected]>

The mt792x PCIe DMA setup uses the same standard queue allocation sequence for data, MCU, firmware download and RX rings.

Factor this part out into a small common helper so later chip support can reuse the existing flow without duplicating the queue setup logic.

This keeps the common DMA skeleton in one place and makes follow-up chip-specific DMA changes smaller and easier to review.

---
 drivers/net/wireless/mediatek/mt76/mt792x.h   | 19 +++++++
 .../net/wireless/mediatek/mt76/mt792x_dma.c   | 56 +++++++++++++++++++
 2 files changed, 75 insertions(+)
drivers/net/wireless/mediatek/mt76/mt792x.h +19 -0
index 09840483fe2a..59562567cc13 100644
@@ -206,6 +206,23 @@ struct mt792x_irq_map {
 	} rx;
 };
 
+struct mt792x_dma_ring {
+	u8 qid;
+	u16 n_desc;
+	u32 ring_base;
+};
+
+struct mt792x_dma_layout {
+	struct mt792x_dma_ring tx_data0;
+	struct mt792x_dma_ring tx_mcu;
+	struct mt792x_dma_ring tx_fwdl;
+	struct mt792x_dma_ring rx_data;
+	struct mt792x_dma_ring rx_mcu;
+};
+
+#define mt792x_dma_ring(_qid, _n_desc, _ring_base) \
+	{ .qid = (_qid), .n_desc = (_n_desc), .ring_base = (_ring_base) }
+
 #define mt792x_init_reset(dev)		((dev)->hif_ops->init_reset(dev))
 #define mt792x_dev_reset(dev)		((dev)->hif_ops->reset(dev))
 #define mt792x_mcu_init(dev)		((dev)->hif_ops->mcu_init(dev))
@@ -421,6 +438,8 @@ void mt792x_sta_statistics(struct ieee80211_hw *hw,
 void mt792x_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,
 			       s16 coverage_class);
 void mt792x_dma_cleanup(struct mt792x_dev *dev);
+int mt792x_dma_alloc_queues(struct mt792x_dev *dev,
+			    const struct mt792x_dma_layout *layout);
 int mt792x_dma_enable(struct mt792x_dev *dev);
 int mt792x_wpdma_reset(struct mt792x_dev *dev, bool force);
 int mt792x_wpdma_reinit_cond(struct mt792x_dev *dev);
drivers/net/wireless/mediatek/mt76/mt792x_dma.c +56 -0

62 lines not on this page · raw message

Signature · 1 line
2.43.0
author
#15 lore raw

PATCH v5 15/21 wifi: mt76: mt7925: switch DMA init to common mt792x queue helpers

In reply to Sean Wang

From: Sean Wang <[email protected]>

Convert mt7925 DMA init to use the common mt792x queue allocation helper and isolate the mt7925-specific prefetch/WFDMA setup.

This removes duplicated DMA setup code and prepares the path for follow-up chip-specific DMA support with smaller deltas.

---
 .../net/wireless/mediatek/mt76/mt7925/pci.c   | 57 +++++++------------
 .../net/wireless/mediatek/mt76/mt792x_dma.c   | 46 +++++++++------
 2 files changed, 48 insertions(+), 55 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/pci.c +19 -38
index 1f05c212be02..39c663687c3c 100644
@@ -210,48 +210,29 @@ static u32 mt7925_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
 	return dev->bus_ops->rmw(mdev, addr, mask, val);
 }
 
+static const struct mt792x_dma_layout mt7925_dma_layout = {
+	.tx_data0 = mt792x_dma_ring(MT7925_TXQ_BAND0,
+				    MT7925_TX_RING_SIZE,
+				    MT_TX_RING_BASE),
+	.tx_mcu = mt792x_dma_ring(MT7925_TXQ_MCU_WM,
+				  MT7925_TX_MCU_RING_SIZE,
+				  MT_TX_RING_BASE),
+	.tx_fwdl = mt792x_dma_ring(MT7925_TXQ_FWDL,
+				   MT7925_TX_FWDL_RING_SIZE,
+				   MT_TX_RING_BASE),
+	.rx_mcu = mt792x_dma_ring(MT7925_RXQ_MCU_WM,
+				  MT7925_RX_MCU_RING_SIZE,
+				  MT_RX_EVENT_RING_BASE),
+	.rx_data = mt792x_dma_ring(MT7925_RXQ_BAND0,
+				   MT7925_RX_RING_SIZE,
+				   MT_RX_DATA_RING_BASE),
+};
+
 static int mt7925_dma_init(struct mt792x_dev *dev)
 {
 	int ret;
 
-	mt76_dma_attach(&dev->mt76);
-
-	ret = mt792x_dma_disable(dev, true);
-	if (ret)
-		return ret;
-
-	/* init tx queue */
-	ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7925_TXQ_BAND0,
-					 MT7925_TX_RING_SIZE,
-					 MT_TX_RING_BASE, NULL, 0);
-	if (ret)
-		return ret;
-
-	mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4);
-
-	/* command to WM */
-	ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7925_TXQ_MCU_WM,
-				  MT7925_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
-	if (ret)
-		return ret;
-
-	/* firmware download */
-	ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7925_TXQ_FWDL,
-				  MT7925_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);
-	if (ret)
-		return ret;
-
-	/* rx event */
-	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
-			       MT7925_RXQ_MCU_WM, MT7925_RX_MCU_RING_SIZE,
-			       MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE);
-	if (ret)
-		return ret;
-
-	/* rx data */
-	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
-			       MT7925_RXQ_BAND0, MT7925_RX_RING_SIZE,
-			       MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE);
+	ret = mt792x_dma_alloc_queues(dev, &mt7925_dma_layout);
 	if (ret)
 		return ret;
 
drivers/net/wireless/mediatek/mt76/mt792x_dma.c +29 -17

61 lines not on this page · raw message

Signature · 1 line
2.43.0
author
#16 lore raw

PATCH v5 16/21 wifi: mt76: mt792x: add MT7927-specific PCIe DMA support

In reply to Sean Wang

From: Sean Wang <[email protected]>

Add the MT7927-specific PCIe DMA queue layout and local DMA setup, including the extra RX ring and WFDMA/prefetch programming.

MT7927 does not follow the mt7925 DMA configuration, so provide a separate DMA init path while reusing the existing common queue setup.

This keeps the chip-specific changes local and prepares the driver for later MT7927 enablement without affecting existing devices.

---
 .../wireless/mediatek/mt76/mt7925/mt7925.h    | 13 +++++
 .../net/wireless/mediatek/mt76/mt7925/pci.c   | 53 ++++++++++++++++++-
 .../net/wireless/mediatek/mt76/mt792x_dma.c   | 41 +++++++++++++-
 .../net/wireless/mediatek/mt76/mt792x_regs.h  |  9 ++++
 4 files changed, 113 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +13 -0
index 46b480f7d813..984be40ca76d 100644
@@ -126,6 +126,19 @@ enum mt7925_rxq_id {
 	MT7925_RXQ_MCU_WM2, /* for tx done */
 };
 
+enum mt7927_txq_id {
+	MT7927_TXQ_BAND0 = MT7925_TXQ_BAND0,
+	MT7927_TXQ_BAND1 = MT7925_TXQ_BAND1,
+	MT7927_TXQ_MCU_WM = MT7925_TXQ_MCU_WM,
+	MT7927_TXQ_FWDL = MT7925_TXQ_FWDL,
+};
+
+enum mt7927_rxq_id {
+	MT7927_RXQ_BAND0 = 4,
+	MT7927_RXQ_MCU_WM = 6,
+	MT7927_RXQ_DATA2 = 7,
+};
+
 enum {
 	MODE_OPEN = 0,
 	MODE_SHARED = 1,
drivers/net/wireless/mediatek/mt76/mt7925/pci.c +52 -1

65 lines not on this page · raw message

drivers/net/wireless/mediatek/mt76/mt792x_dma.c +39 -2

61 lines not on this page · raw message

drivers/net/wireless/mediatek/mt76/mt792x_regs.h +9 -0
index 17504ef8e80d..4cd5b33b640e 100644
@@ -301,7 +301,9 @@
 #define MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN	BIT(12)
 #define MT_WFDMA0_GLO_CFG_RX_WB_DDONE	BIT(13)
 #define MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN BIT(15)
+#define MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN	BIT(20)
 #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2	BIT(21)
+#define MT_WFDMA0_GLO_CFG_ADDR_EXT_EN		BIT(26)
 #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO	BIT(27)
 #define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO	BIT(28)
 #define MT_WFDMA0_GLO_CFG_CLK_GAT_DIS	BIT(30)
@@ -368,6 +370,13 @@
 #define MT_WFDMA_EXT_CSR_HIF_MISC	MT_WFDMA_EXT_CSR(0x44)
 #define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY	BIT(0)
 
+#define MT_WFDMA_PREFETCH_CTRL		MT_WFDMA_EXT_CSR(0x30)
+#define MT_WFDMA_PREFETCH_CFG0		MT_WFDMA_EXT_CSR(0xf0)
+#define MT_WFDMA_PREFETCH_CFG1		MT_WFDMA_EXT_CSR(0xf4)
+#define MT_WFDMA_PREFETCH_CFG2		MT_WFDMA_EXT_CSR(0xf8)
+#define MT_WFDMA_PREFETCH_CFG3		MT_WFDMA_EXT_CSR(0xfc)
+#define MT_WFDMA0_GLO_CFG_EXT1		MT_WFDMA0(0x2b4)
+
 #define MT_SWDEF_BASE			0x41f200
 #define MT_SWDEF(ofs)			(MT_SWDEF_BASE + (ofs))
 #define MT_SWDEF_MODE			MT_SWDEF(0x3c)
Signature · 1 line
2.43.0
author
#17 lore raw

PATCH v5 17/21 wifi: mt76: mt7925: sync MT7927 BSS band assignment

In reply to Sean Wang

From: Sean Wang <[email protected]>

MT7927 needs DBDC enabled and uses a fixed firmware band assignment for 2.4GHz and 5/6GHz BSS contexts.

Reprogram the STA dev context when the channel context is assigned so the firmware sees the updated band_idx before the BSS is used. This avoids stale band programming after band changes.

---
 .../net/wireless/mediatek/mt76/mt7925/init.c  |  9 ++++
 .../net/wireless/mediatek/mt76/mt7925/main.c  | 42 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7925/mcu.c   |  1 +
 .../wireless/mediatek/mt76/mt7925/mt7925.h    | 12 ++++++
 .../wireless/mediatek/mt76/mt7925/pci_mac.c   |  7 ++++
 5 files changed, 71 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/init.c +9 -0
index a8c2ca7c0efc..e85b0d104fbe 100644
@@ -117,6 +117,15 @@ static int __mt7925_init_hardware(struct mt792x_dev *dev)
 	if (ret)
 		goto out;
 
+	if (is_mt7927(&dev->mt76)) {
+		ret = mt7925_mcu_set_dbdc(&dev->mphy, true);
+		if (ret) {
+			dev_warn(dev->mt76.dev,
+				 "MT7927 DBDC enable failed: %d\n", ret);
+			ret = 0;
+		}
+	}
+
 out:
 	return ret;
 }
drivers/net/wireless/mediatek/mt76/mt7925/main.c +42 -0

66 lines not on this page · raw message

drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +1 -0
index b338d6bf02f5..f7e14cc53dac 100644
@@ -2918,6 +2918,7 @@ int mt7925_mcu_set_dbdc(struct mt76_phy *phy, bool enable)
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mt7925_mcu_set_dbdc);
 
 static void
 mt7925_mcu_build_scan_ie_tlv(struct mt76_dev *mdev,
drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +12 -0
index 984be40ca76d..242f83f90dd4 100644
@@ -252,6 +252,18 @@ struct mt7925_txpwr {
 	s8 eht996x3_484[16][2];
 };
 
+static inline u8 mt7927_band_idx(enum nl80211_band band)
+{
+	switch (band) {
+	case NL80211_BAND_2GHZ:
+		return 0;
+	case NL80211_BAND_5GHZ:
+	case NL80211_BAND_6GHZ:
+	default:
+		return 1;
+	}
+}
+
 extern const struct ieee80211_ops mt7925_ops;
 
 int __mt7925_start(struct mt792x_phy *phy);
drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c +7 -0
index 1626a3684082..97683949a305 100644
@@ -3,6 +3,7 @@
 
 #include "mt7925.h"
 #include "../dma.h"
+#include "mcu.h"
 #include "mac.h"
 
 int mt7925e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
@@ -144,6 +145,12 @@ int mt7925e_mac_reset(struct mt792x_dev *dev)
 	if (err)
 		goto out;
 
+	if (is_mt7927(&dev->mt76)) {
+		err = mt7925_mcu_set_dbdc(&dev->mphy, true);
+		if (err)
+			goto out;
+	}
+
 	err = __mt7925_start(&dev->phy);
 out:
 	clear_bit(MT76_RESET, &dev->mphy.state);
Signature · 1 line
2.43.0
author
#18 lore raw

PATCH v5 18/21 wifi: mt76: mt7925: add MBMC event handling

In reply to Sean Wang

From: Sean Wang <[email protected]>

Handle MBMC unsolicited events from firmware to report the current MBMC state. This helps validate MT7927 band setup.

---
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  |  1 +
 .../net/wireless/mediatek/mt76/mt7925/mcu.c   | 31 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7925/mcu.h   |  3 +-
 3 files changed, 34 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +1 -0
index 4691b9b5e2be..6d0429f40b0f 100644
@@ -1069,6 +1069,7 @@ enum {
 	MCU_UNI_EVENT_SCAN_DONE = 0x0e,
 	MCU_UNI_EVENT_RDD_REPORT = 0x11,
 	MCU_UNI_EVENT_ROC = 0x27,
+	MCU_UNI_EVENT_MBMC = 0x28,
 	MCU_UNI_EVENT_TX_DONE = 0x2d,
 	MCU_UNI_EVENT_THERMAL = 0x35,
 	MCU_UNI_EVENT_RSSI_MONITOR = 0x41,
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +31 -0
index f7e14cc53dac..4a06f0a1ce03 100644
@@ -566,6 +566,34 @@ mt7925_mcu_uni_debug_msg_event(struct mt792x_dev *dev, struct sk_buff *skb)
 	}
 }
 
+static void
+mt7925_mcu_handle_mbmc_event(struct mt792x_dev *dev, struct sk_buff *skb)
+{
+	struct mbmc_conf_tlv *tlv;
+	u32 tlv_len;
+
+	skb_pull(skb, sizeof(struct mt7925_mcu_rxd) + 4);
+	tlv_len = skb->len;
+	tlv = (struct mbmc_conf_tlv *)skb->data;
+
+	while (tlv_len >= sizeof(*tlv) &&
+	       le16_to_cpu(tlv->len) >= sizeof(*tlv) &&
+	       le16_to_cpu(tlv->len) <= tlv_len) {
+		u16 tag = le16_to_cpu(tlv->tag);
+
+		if (tag == UNI_MBMC_SETTING || tag == UNI_MBMC_NO_RESP_SETTING) {
+			dev_dbg(dev->mt76.dev,
+				"MBMC event: tag=%u mbmc_en=%u\n",
+				tag, tlv->mbmc_en);
+			break;
+		}
+
+		tlv_len -= le16_to_cpu(tlv->len);
+		tlv = (struct mbmc_conf_tlv *)
+			((u8 *)tlv + le16_to_cpu(tlv->len));
+	}
+}
+
 static void
 mt7925_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev,
 				    struct sk_buff *skb)
@@ -584,6 +612,9 @@ mt7925_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev,
 	case MCU_UNI_EVENT_ROC:
 		mt7925_mcu_uni_roc_event(dev, skb);
 		break;
+	case MCU_UNI_EVENT_MBMC:
+		mt7925_mcu_handle_mbmc_event(dev, skb);
+		break;
 	case MCU_UNI_EVENT_SCAN_DONE:
 		mt7925_mcu_scan_event(dev, skb);
 		return;
drivers/net/wireless/mediatek/mt76/mt7925/mcu.h +2 -1
index 56e2772f3ffe..293f173b23dd 100644
@@ -143,7 +143,8 @@ enum {
 };
 
 enum {
-	UNI_MBMC_SETTING,
+	UNI_MBMC_SETTING = 0,
+	UNI_MBMC_NO_RESP_SETTING = 1,
 };
 
 enum {
Signature · 1 line
2.43.0
author
#19 lore raw

PATCH v5 19/21 wifi: mt76: mt792x: enable CNM ops for MT7927

In reply to Sean Wang

From: Sean Wang <[email protected]>

Enable CNM support for MT7927 so mac80211 keeps remain-on-channel callbacks available. MT7927 needs them at runtime even when the capability is not advertised through the normal firmware feature path.

---
 drivers/net/wireless/mediatek/mt76/mt792x_core.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/net/wireless/mediatek/mt76/mt792x_core.c +11 -0
index 152cfcca2f90..3fdcd0599ff2 100644
@@ -759,6 +759,13 @@ mt792x_get_offload_capability(struct device *dev, const char *fw_wm)
 	return offload_caps;
 }
 
+static bool mt792x_needs_cnm_runtime(const void *drv_data)
+{
+	const char *fw_wm = drv_data;
+
+	return fw_wm && !strcmp(fw_wm, MT7927_FIRMWARE_WM);
+}
+
 struct ieee80211_ops *
 mt792x_get_mac80211_ops(struct device *dev,
 			const struct ieee80211_ops *mac80211_ops,
@@ -772,6 +779,10 @@ mt792x_get_mac80211_ops(struct device *dev,
 		return NULL;
 
 	*fw_features = mt792x_get_offload_capability(dev, drv_data);
+
+	if (mt792x_needs_cnm_runtime(drv_data))
+		*fw_features |= MT792x_FW_CAP_CNM;
+
 	if (!(*fw_features & MT792x_FW_CAP_CNM)) {
 		ops->remain_on_channel = NULL;
 		ops->cancel_remain_on_channel = NULL;
Signature · 1 line
2.43.0
author
#20 lore raw

PATCH v5 20/21 wifi: mt76: mt7925: add MT7927 PCIe support

In reply to Sean Wang

From: Sean Wang <[email protected]>

Add the missing MT7927 device support in the mt7925 PCI path. This ensures MT7927 is identified correctly and uses the proper initialization flow.

---
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7925/pci.c +15 -1
index 7455cf7eddc5..41e6ec9223e9 100644
@@ -16,6 +16,12 @@ static const struct pci_device_id mt7925_pci_device_table[] = {
 		.driver_data = (kernel_ulong_t)MT7925_FIRMWARE_WM },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0717),
 		.driver_data = (kernel_ulong_t)MT7925_FIRMWARE_WM },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7927),
+		.driver_data = (kernel_ulong_t)MT7927_FIRMWARE_WM },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x6639),
+		.driver_data = (kernel_ulong_t)MT7927_FIRMWARE_WM },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0738),
+		.driver_data = (kernel_ulong_t)MT7927_FIRMWARE_WM },
 	{ },
 };
 
@@ -376,7 +382,8 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	if (ret)
 		goto err_free_pci_vec;
 
-	is_mt7927_hw = (pdev->device == 0x6639 || pdev->device == 0x7927);
+	is_mt7927_hw = (pdev->device == 0x6639 || pdev->device == 0x7927 ||
+			pdev->device == 0x0738);
 
 	/* MT7927: ASPM L1 causes unreliable WFDMA register access */
 	if (mt7925_disable_aspm || is_mt7927_hw)
@@ -436,6 +443,13 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 
 	dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
 
+	if (is_mt7927_hw && mt76_chip(mdev) != 0x7927) {
+		dev_info(mdev->dev,
+			 "MT7927 raw CHIPID=0x%04x, forcing chip=0x7927\n",
+			 mt76_chip(mdev));
+		mdev->rev = (0x7927 << 16) | (mdev->rev & 0xff);
+	}
+
 	mt76_rmw_field(dev, MT_HW_EMI_CTL, MT_HW_EMI_CTL_SLPPROT_EN, 1);
 
 	ret = mt792x_wfsys_reset(dev);
Signature · 1 line
2.43.0
author
#21 lore raw

PATCH v5 21/21 wifi: mt76: mt7925: add MT7927 USB support

In reply to Sean Wang

From: Sean Wang <[email protected]>

Add the MT7927 USB device ID and normalize the raw 0x6639 CHIPID to MT7927 so the shared mt7925u code can use the proper chip-specific paths.

Restore the required band setup after USB MAC reset before restarting the device.

---
 drivers/net/wireless/mediatek/mt76/mt7925/usb.c | 15 +++++++++++++++
 drivers/net/wireless/mediatek/mt76/usb.c        |  1 +
 2 files changed, 16 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/usb.c +15 -0
index d9968f03856d..7c64f3c1a2d9 100644
@@ -10,6 +10,8 @@
 #include "mac.h"
 
 static const struct usb_device_id mt7925u_device_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x6639, 0xff, 0xff, 0xff),
+		.driver_info = (kernel_ulong_t)MT7925_FIRMWARE_WM },
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7925, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)MT7925_FIRMWARE_WM },
 	/* Netgear, Inc. A9000 */
@@ -120,6 +122,12 @@ static int mt7925u_mac_reset(struct mt792x_dev *dev)
 	if (err)
 		goto out;
 
+	if (is_mt7927(&dev->mt76)) {
+		err = mt7925_mcu_set_dbdc(&dev->mphy, true);
+		if (err)
+			goto out;
+	}
+
 	err = __mt7925_start(&dev->phy);
 out:
 	clear_bit(MT76_RESET, &dev->mphy.state);
@@ -198,6 +206,13 @@ static int mt7925u_probe(struct usb_interface *usb_intf,
 		    (mt76_rr(dev, MT_HW_REV) & 0xff);
 	dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
 
+	if (mt76_chip(mdev) == 0x6639) {
+		dev_dbg(mdev->dev,
+			"MT7927 raw CHIPID=0x%04x, forcing chip=0x7927\n",
+			mt76_chip(mdev));
+		mdev->rev = (0x7927 << 16) | (mdev->rev & 0xff);
+	}
+
 	if (mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY)) {
 		ret = mt792xu_wfsys_reset(dev);
 		if (ret)
drivers/net/wireless/mediatek/mt76/usb.c +1 -0
index 632ae755c7a6..9bd61c9e94ed 100644
@@ -925,6 +925,7 @@ mt76u_ac_to_hwq(struct mt76_dev *dev, struct mt76_queue *q, u8 qid)
 		q->ep = q->hw_idx + 1;
 		break;
 	}
+	case 0x6639:
 	case 0x7961:
 	case 0x7925:
 		q->hw_idx = mt76_ac_to_hwq(ac);
Signature · 1 line
2.43.0