wifi: mt76: mt7925: MT7927 (Filogic 380) support
Subsystems (2)
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
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
@@ -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
PATCH v5 2/21 wifi: mt76: mt7925: add 320MHz bandwidth to bss_rlm_tlv
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 3/21 wifi: mt76: mt7925: handle 320MHz bandwidth in RXV and TXS
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 4/21 wifi: mt76: mt7925: populate EHT 320MHz MCS map in sta_rec
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 5/21 wifi: mt76: mt7925: advertise EHT 320MHz capabilities for 6GHz band
In reply to Sean WangFrom: 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
@@ -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
@@ -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
PATCH v5 6/21 wifi: mt76: mt7925: add MT7927 chip ID helpers
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 7/21 wifi: mt76: mt7925: add MT7927 firmware paths
In reply to Sean WangFrom: 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
@@ -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
@@ -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
PATCH v5 8/21 wifi: mt76: mt7925: use irq_map for chip-specific interrupt handling
In reply to Sean WangFrom: 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
@@ -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
@@ -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
@@ -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
PATCH v5 9/21 wifi: mt76: mt7925: disable ASPM and runtime PM for MT7927
In reply to Sean WangFrom: 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
@@ -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
@@ -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
PATCH v5 10/21 wifi: mt76: connac: replace is_mt7925() with is_connac3()
In reply to Sean WangFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v5 11/21 wifi: mt76: mt7925: use link-specific removal for non-MLD STA
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 12/21 wifi: mt76: connac: tolerate inactive BSS deactivation
In reply to Sean WangFrom: 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
@@ -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
@@ -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
@@ -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
PATCH v5 13/21 wifi: mt76: mt792x: add MT7927 WFSYS reset support
In reply to Sean WangFrom: 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
@@ -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
@@ -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
PATCH v5 14/21 wifi: mt76: mt792x: factor out common DMA queue allocation
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 15/21 wifi: mt76: mt7925: switch DMA init to common mt792x queue helpers
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 16/21 wifi: mt76: mt792x: add MT7927-specific PCIe DMA support
In reply to Sean WangFrom: 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
@@ -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
@@ -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
PATCH v5 17/21 wifi: mt76: mt7925: sync MT7927 BSS band assignment
In reply to Sean WangFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v5 18/21 wifi: mt76: mt7925: add MBMC event handling
In reply to Sean WangFrom: 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
@@ -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
@@ -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
@@ -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
PATCH v5 19/21 wifi: mt76: mt792x: enable CNM ops for MT7927
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 20/21 wifi: mt76: mt7925: add MT7927 PCIe support
In reply to Sean WangFrom: 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
@@ -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
PATCH v5 21/21 wifi: mt76: mt7925: add MT7927 USB support
In reply to Sean WangFrom: 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
@@ -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
@@ -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