summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/driver-api/index.rst1
-rw-r--r--Documentation/driver-api/wbrf.rst78
-rw-r--r--drivers/bcma/driver_pci_host.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/bmi.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c17
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/coredump.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/coredump.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/debugfs_sta.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.h20
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h4
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c17
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/qmi.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/rx_desc.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/sdio.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/thermal.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/usb.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/wow.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ath11k/ahb.c10
-rw-r--r--drivers/net/wireless/ath/ath11k/ce.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/ce.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/core.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/dbring.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/dbring.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/debug.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/debugfs.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/debugfs.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/debugfs_sta.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/debugfs_sta.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_rx.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_tx.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_tx.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/fw.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/hal.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/hal.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_desc.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_rx.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_rx.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/hif.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/htc.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/htc.h6
-rw-r--r--drivers/net/wireless/ath/ath11k/hw.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.c16
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/mhi.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/mhi.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/pcic.c6
-rw-r--r--drivers/net/wireless/ath/ath11k/peer.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/peer.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/qmi.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/qmi.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/reg.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/reg.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/rx_desc.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/spectral.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/spectral.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/thermal.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/thermal.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/trace.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/wmi.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/wmi.h63
-rw-r--r--drivers/net/wireless/ath/ath11k/wow.h1
-rw-r--r--drivers/net/wireless/ath/ath12k/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ath12k/core.c6
-rw-r--r--drivers/net/wireless/ath/ath12k/core.h5
-rw-r--r--drivers/net/wireless/ath/ath12k/dbring.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/dp.c6
-rw-r--r--drivers/net/wireless/ath/ath12k/dp.h13
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_mon.c15
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_mon.h4
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_rx.c151
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_rx.h8
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_tx.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/hal.c6
-rw-r--r--drivers/net/wireless/ath/ath12k/hal.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/hal_rx.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/hal_rx.h3
-rw-r--r--drivers/net/wireless/ath/ath12k/hif.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/hw.c5
-rw-r--r--drivers/net/wireless/ath/ath12k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c190
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.h3
-rw-r--r--drivers/net/wireless/ath/ath12k/mhi.c18
-rw-r--r--drivers/net/wireless/ath/ath12k/pci.c174
-rw-r--r--drivers/net/wireless/ath/ath12k/pci.h4
-rw-r--r--drivers/net/wireless/ath/ath12k/peer.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/qmi.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/qmi.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/reg.c21
-rw-r--r--drivers/net/wireless/ath/ath12k/reg.h4
-rw-r--r--drivers/net/wireless/ath/ath12k/rx_desc.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.h64
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c8
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/common-init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/common-spectral.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c36
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c6
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c6
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c6
-rw-r--r--drivers/net/wireless/intel/iwlegacy/common.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.c18
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/file.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h15
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h17
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c17
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h21
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h11
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h23
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c16
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c31
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c14
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/drv.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c47
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx.c34
-rw-r--r--drivers/net/wireless/marvell/libertas/Kconfig2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cfg80211.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/fw.h1
-rw-r--r--drivers/net/wireless/marvell/mwifiex/ioctl.h1
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sdio.c19
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sdio.h2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/uap_cmd.c8
-rw-r--r--drivers/net/wireless/mediatek/mt76/dma.c258
-rw-r--r--drivers/net/wireless/mediatek/mt76/dma.h54
-rw-r--r--drivers/net/wireless/mediatek/mt76/eeprom.c22
-rw-r--r--drivers/net/wireless/mediatek/mt76/mac80211.c60
-rw-r--r--drivers/net/wireless/mediatek/mt76/mmio.c108
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76.h105
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7603/dma.c9
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7603/soc.c7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/dma.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mcu.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/soc.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac.h8
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h29
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/dma.c46
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/init.c30
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mac.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/main.c21
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mcu.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mcu.h2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mmio.c118
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/soc.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/init.c23
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/main.c38
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mcu.c17
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/pci.c7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/sdio.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/main.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/mcu.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/pci.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt792x.h6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c53
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt792x_mac.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/dma.c398
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c38
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/init.c520
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mac.c219
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/main.c89
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mcu.c642
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mcu.h253
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mmio.c295
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h160
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/pci.c79
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/regs.h182
-rw-r--r--drivers/net/wireless/mediatek/mt76/sdio.c18
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800lib.c15
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00link.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00queue.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pci.c98
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pci.h24
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c76
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c16
-rw-r--r--drivers/net/wireless/realtek/rtw88/debug.c6
-rw-r--r--drivers/net/wireless/realtek/rtw88/debug.h6
-rw-r--r--drivers/net/wireless/realtek/rtw88/main.c5
-rw-r--r--drivers/net/wireless/realtek/rtw88/sdio.c35
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.c8
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.c12
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h86
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.c70
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.h18
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c175
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.h154
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.c834
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.h146
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac80211.c21
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac_be.c765
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.c22
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.h4
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c511
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.h33
-rw-r--r--drivers/net/wireless/realtek/rtw89/ps.h4
-rw-r--r--drivers/net/wireless/realtek/rtw89/reg.h2234
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851b.c22
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a.c22
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b.c22
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c.c22
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a.c347
-rw-r--r--drivers/net/wireless/realtek/rtw89/ser.c10
-rw-r--r--drivers/net/wireless/realtek/rtw89/wow.c7
-rw-r--r--drivers/net/wireless/silabs/wfx/sta.c42
-rw-r--r--drivers/platform/x86/amd/Kconfig14
-rw-r--r--drivers/platform/x86/amd/Makefile1
-rw-r--r--drivers/platform/x86/amd/wbrf.c317
-rw-r--r--include/linux/acpi_amd_wbrf.h91
-rw-r--r--include/net/cfg80211.h99
-rw-r--r--include/net/mac80211.h23
-rw-r--r--include/uapi/linux/nl80211.h136
-rw-r--r--net/mac80211/Makefile2
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/chan.c13
-rw-r--r--net/mac80211/debugfs.c1
-rw-r--r--net/mac80211/driver-ops.h2
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/ieee80211_i.h20
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/mesh_hwmp.c2
-rw-r--r--net/mac80211/mesh_pathtbl.c8
-rw-r--r--net/mac80211/mlme.c25
-rw-r--r--net/mac80211/rx.c4
-rw-r--r--net/mac80211/scan.c4
-rw-r--r--net/mac80211/sta_info.c8
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tdls.c18
-rw-r--r--net/mac80211/tx.c7
-rw-r--r--net/mac80211/wbrf.c95
-rw-r--r--net/wireless/Makefile4
-rw-r--r--net/wireless/chan.c3
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/mlme.c2
-rw-r--r--net/wireless/nl80211.c289
-rw-r--r--net/wireless/nl80211.h2
-rw-r--r--net/wireless/rdev-ops.h26
-rw-r--r--net/wireless/scan.c108
-rw-r--r--net/wireless/trace.h22
292 files changed, 10703 insertions, 2086 deletions
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index f549a68951d7..8bc4ebe7a36f 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -115,6 +115,7 @@ available subsections can be seen below.
hte/index
wmi
dpll
+ wbrf
.. only:: subproject and html
diff --git a/Documentation/driver-api/wbrf.rst b/Documentation/driver-api/wbrf.rst
new file mode 100644
index 000000000000..f48bfa029813
--- /dev/null
+++ b/Documentation/driver-api/wbrf.rst
@@ -0,0 +1,78 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+=================================
+WBRF - Wifi Band RFI Mitigations
+=================================
+
+Due to electrical and mechanical constraints in certain platform designs
+there may be likely interference of relatively high-powered harmonics of
+the GPU memory clocks with local radio module frequency bands used by
+certain Wifi bands.
+
+To mitigate possible RFI interference producers can advertise the
+frequencies in use and consumers can use this information to avoid using
+these frequencies for sensitive features.
+
+When a platform is known to have this issue with any contained devices,
+the platform designer will advertise the availability of this feature via
+ACPI devices with a device specific method (_DSM).
+* Producers with this _DSM will be able to advertise the frequencies in use.
+* Consumers with this _DSM will be able to register for notifications of
+frequencies in use.
+
+Some general terms
+==================
+
+Producer: such component who can produce high-powered radio frequency
+Consumer: such component who can adjust its in-use frequency in
+response to the radio frequencies of other components to mitigate the
+possible RFI.
+
+To make the mechanism function, those producers should notify active use
+of their particular frequencies so that other consumers can make relative
+internal adjustments as necessary to avoid this resonance.
+
+ACPI interface
+==============
+
+Although initially used by for wifi + dGPU use cases, the ACPI interface
+can be scaled to any type of device that a platform designer discovers
+can cause interference.
+
+The GUID used for the _DSM is 7B7656CF-DC3D-4C1C-83E9-66E721DE3070.
+
+3 functions are available in this _DSM:
+
+* 0: discover # of functions available
+* 1: record RF bands in use
+* 2: retrieve RF bands in use
+
+Driver programming interface
+============================
+
+.. kernel-doc:: drivers/platform/x86/amd/wbrf.c
+
+Sample Usage
+=============
+
+The expected flow for the producers:
+1. During probe, call `acpi_amd_wbrf_supported_producer` to check if WBRF
+can be enabled for the device.
+2. On using some frequency band, call `acpi_amd_wbrf_add_remove` with 'add'
+param to get other consumers properly notified.
+3. Or on stopping using some frequency band, call
+`acpi_amd_wbrf_add_remove` with 'remove' param to get other consumers notified.
+
+The expected flow for the consumers:
+1. During probe, call `acpi_amd_wbrf_supported_consumer` to check if WBRF
+can be enabled for the device.
+2. Call `amd_wbrf_register_notifier` to register for notification
+of frequency band change(add or remove) from other producers.
+3. Call the `amd_wbrf_retrieve_freq_band` initally to retrieve
+current active frequency bands considering some producers may broadcast
+such information before the consumer is up.
+4. On receiving a notification for frequency band change, run
+`amd_wbrf_retrieve_freq_band` again to retrieve the latest
+active frequency bands.
+5. During driver cleanup, call `amd_wbrf_unregister_notifier` to
+unregister the notifier.
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index aa0581cda718..ed3be52ab63d 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -280,7 +280,7 @@ static u8 bcma_find_pci_capability(struct bcma_drv_pci *pc, unsigned int dev,
/* check for Header type 0 */
bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
sizeof(u8));
- if ((byte_val & 0x7F) != PCI_HEADER_TYPE_NORMAL)
+ if ((byte_val & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL)
return cap_ptr;
/* check if the capability pointer field exists */
diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c
index af6546572df2..9a4f8e815412 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.c
+++ b/drivers/net/wireless/ath/ath10k/bmi.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "bmi.h"
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index c27b8204718a..afae4a8027f8 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "hif.h"
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 6cdb225b7eac..0032f8aa892f 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@@ -100,6 +101,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA988X_HW_2_0_VERSION,
@@ -140,6 +142,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA9887_HW_1_0_VERSION,
@@ -181,6 +184,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -217,6 +221,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -257,6 +262,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -297,6 +303,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA6174_HW_3_0_VERSION,
@@ -337,6 +344,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -381,6 +389,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = true,
},
{
.id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -427,6 +436,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA9984_HW_1_0_DEV_VERSION,
@@ -480,6 +490,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA9888_HW_2_0_DEV_VERSION,
@@ -530,6 +541,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA9377_HW_1_0_DEV_VERSION,
@@ -570,6 +582,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -612,6 +625,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -645,6 +659,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = QCA4019_HW_1_0_DEV_VERSION,
@@ -692,6 +707,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
+ .mcast_frame_registration = false,
},
{
.id = WCN3990_HW_1_0_DEV_VERSION,
@@ -725,6 +741,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_restart_disconnect = true,
.use_fw_tx_credits = false,
.delay_unmap_buffer = true,
+ .mcast_frame_registration = false,
},
};
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 4b5239de4018..c110d15528bd 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CORE_H_
@@ -607,7 +608,7 @@ struct ath10k_vif {
u8 tim_bitmap[64];
u8 tim_len;
u32 ssid_len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 ssid[IEEE80211_MAX_SSID_LEN] __nonstring;
bool hidden_ssid;
/* P2P_IE with NoA attribute for P2P_GO case */
u32 noa_len;
diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c
index 2d1634a890dd..bb3a276b7ed5 100644
--- a/drivers/net/wireless/ath/ath10k/coredump.c
+++ b/drivers/net/wireless/ath/ath10k/coredump.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "coredump.h"
diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h
index 437b9759f05d..e5ef0352e319 100644
--- a/drivers/net/wireless/ath/ath10k/coredump.h
+++ b/drivers/net/wireless/ath/ath10k/coredump.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: ISC */
/*
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _COREDUMP_H_
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index ad9cf953a2fc..b93a64bf8190 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
index 87a3365330ff..394bf3c32abf 100644
--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index 5bfeecb95fca..a6e21ce90bad 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h
index 0d180faf3b77..7ff665020015 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -246,26 +246,12 @@ struct ath10k_htc_lookahead_bundle {
struct ath10k_htc_record {
struct ath10k_ath10k_htc_record_hdr hdr;
union {
- struct ath10k_htc_credit_report credit_report[0];
- struct ath10k_htc_lookahead_report lookahead_report[0];
- struct ath10k_htc_lookahead_bundle lookahead_bundle[0];
- u8 pauload[0];
+ DECLARE_FLEX_ARRAY(struct ath10k_htc_credit_report, credit_report);
+ DECLARE_FLEX_ARRAY(struct ath10k_htc_lookahead_report, lookahead_report);
+ DECLARE_FLEX_ARRAY(struct ath10k_htc_lookahead_bundle, lookahead_bundle);
};
} __packed __aligned(4);
-/*
- * note: the trailer offset is dynamic depending
- * on payload length. this is only a struct layout draft
- */
-struct ath10k_htc_frame {
- struct ath10k_htc_hdr hdr;
- union {
- struct ath10k_htc_msg msg;
- u8 payload[0];
- };
- struct ath10k_htc_record trailer[0];
-} __packed __aligned(4);
-
/*******************/
/* Host-side stuff */
/*******************/
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index c80470e8886a..4a9270e2a4c8 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _HTT_H_
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index b261d6371c0f..fa0f598ed6bf 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index be4d4536aaa8..9725feecefd6 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/etherdevice.h>
@@ -40,7 +41,6 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw,
struct ath10k *ar = hw->priv;
struct ath10k_sta *arsta;
struct ath10k_vif *arvif = (void *)txq->vif->drv_priv;
- unsigned long frame_cnt;
unsigned long byte_cnt;
int idx;
u32 bit;
@@ -67,7 +67,7 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw,
bit = BIT(peer_id % 32);
idx = peer_id / 32;
- ieee80211_txq_get_depth(txq, &frame_cnt, &byte_cnt);
+ ieee80211_txq_get_depth(txq, NULL, &byte_cnt);
count = ath10k_htt_tx_txq_calc_size(byte_cnt);
if (unlikely(peer_id >= ar->htt.tx_q_state.num_peers) ||
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index 6d32b43a4da6..8fafe096adff 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: ISC
/*
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/types.h>
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 9643031a4427..93c073091996 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _HW_H_
@@ -639,6 +640,9 @@ struct ath10k_hw_params {
bool use_fw_tx_credits;
bool delay_unmap_buffer;
+
+ /* The hardware support multicast frame registrations */
+ bool mcast_frame_registration;
};
struct htt_resp;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 2cf693f3fea9..090bcf148d0c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "mac.h"
@@ -1242,7 +1243,7 @@ static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
return ar->monitor ||
(!test_bit(ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST,
ar->running_fw->fw_file.fw_features) &&
- (ar->filter_flags & FIF_OTHER_BSS)) ||
+ (ar->filter_flags & (FIF_OTHER_BSS | FIF_MCAST_ACTION))) ||
test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
}
@@ -6025,10 +6026,15 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw,
{
struct ath10k *ar = hw->priv;
int ret;
+ unsigned int supported = SUPPORTED_FILTERS;
mutex_lock(&ar->conf_mutex);
- *total_flags &= SUPPORTED_FILTERS;
+ if (ar->hw_params.mcast_frame_registration)
+ supported |= FIF_MCAST_ACTION;
+
+ *total_flags &= supported;
+
ar->filter_flags = *total_flags;
ret = ath10k_monitor_recalc(ar);
@@ -6121,9 +6127,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
if (ieee80211_vif_is_mesh(vif)) {
/* mesh doesn't use SSID but firmware needs it */
- strncpy(arvif->u.ap.ssid, "mesh",
- sizeof(arvif->u.ap.ssid));
arvif->u.ap.ssid_len = 4;
+ memcpy(arvif->u.ap.ssid, "mesh", arvif->u.ap.ssid_len);
}
}
@@ -10118,6 +10123,10 @@ int ath10k_mac_register(struct ath10k *ar)
NL80211_EXT_FEATURE_SET_SCAN_DWELL);
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL);
+ if (ar->hw_params.mcast_frame_registration)
+ wiphy_ext_feature_set(ar->hw->wiphy,
+ NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS);
+
if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||
test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))
wiphy_ext_feature_set(ar->hw->wiphy,
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 2f8c785277af..3de2de6d44bc 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/pci.h>
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 480cd97ab739..27bb4cf2dfea 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _PCI_H_
diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c
index 52c1a3de8da6..38e939f572a9 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: ISC
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/completion.h>
diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c
index 1c81e454f943..0e85c75d2278 100644
--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c
+++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: ISC
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/soc/qcom/qmi.h>
diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h
index f0db991408dc..9f311f3bc9e7 100644
--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h
+++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: ISC */
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef WCN3990_QMI_SVC_V01_H
diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h
index 777e53aa69dc..564293df1e9a 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _RX_DESC_H_
diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
index 56fbcfb80bf8..0ab5433f6cf6 100644
--- a/drivers/net/wireless/ath/ath10k/sdio.c
+++ b/drivers/net/wireless/ath/ath10k/sdio.c
@@ -3,6 +3,7 @@
* Copyright (c) 2004-2011 Atheros Communications Inc.
* Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc.
* Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
diff --git a/drivers/net/wireless/ath/ath10k/thermal.c b/drivers/net/wireless/ath/ath10k/thermal.c
index cefd97323dfe..31c8d7fbb095 100644
--- a/drivers/net/wireless/ath/ath10k/thermal.c
+++ b/drivers/net/wireless/ath/ath10k/thermal.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: ISC
/*
* Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/device.h>
diff --git a/drivers/net/wireless/ath/ath10k/usb.h b/drivers/net/wireless/ath/ath10k/usb.h
index 48e066ba8162..7e4cfbb673c9 100644
--- a/drivers/net/wireless/ath/ath10k/usb.h
+++ b/drivers/net/wireless/ath/ath10k/usb.h
@@ -3,6 +3,7 @@
* Copyright (c) 2004-2011 Atheros Communications Inc.
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
* Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _USB_H_
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index dbb48d70f2e9..83a8f07a687f 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _WMI_TLV_H
#define _WMI_TLV_H
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 05fa7d4c0e1a..88befe92f95d 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/skbuff.h>
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index b112e8826093..9146df98fcee 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _WMI_H_
diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c
index 20b9aa8ddf7d..aa7b2e703f3d 100644
--- a/drivers/net/wireless/ath/ath10k/wow.c
+++ b/drivers/net/wireless/ath/ath10k/wow.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2015-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "mac.h"
diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless/ath/ath11k/Kconfig
index ad5cc6cac05b..27f0523bf967 100644
--- a/drivers/net/wireless/ath/ath11k/Kconfig
+++ b/drivers/net/wireless/ath/ath11k/Kconfig
@@ -2,7 +2,7 @@
config ATH11K
tristate "Qualcomm Technologies 802.11ax chipset support"
depends on MAC80211 && HAS_DMA
- depends on CRYPTO_MICHAEL_MIC
+ select CRYPTO_MICHAEL_MIC
select ATH_COMMON
select QCOM_QMI_HELPERS
help
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 235336ef2a7a..7c0a23517949 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -803,8 +803,8 @@ static int ath11k_core_get_rproc(struct ath11k_base *ab)
prproc = rproc_get_by_phandle(rproc_phandle);
if (!prproc) {
- ath11k_err(ab, "failed to get rproc\n");
- return -EINVAL;
+ ath11k_dbg(ab, ATH11K_DBG_AHB, "failed to get rproc, deferring\n");
+ return -EPROBE_DEFER;
}
ab_ahb->tgt_rproc = prproc;
@@ -1251,7 +1251,7 @@ static void ath11k_ahb_free_resources(struct ath11k_base *ab)
platform_set_drvdata(pdev, NULL);
}
-static int ath11k_ahb_remove(struct platform_device *pdev)
+static void ath11k_ahb_remove(struct platform_device *pdev)
{
struct ath11k_base *ab = platform_get_drvdata(pdev);
@@ -1267,8 +1267,6 @@ static int ath11k_ahb_remove(struct platform_device *pdev)
qmi_fail:
ath11k_ahb_free_resources(ab);
-
- return 0;
}
static void ath11k_ahb_shutdown(struct platform_device *pdev)
@@ -1296,7 +1294,7 @@ static struct platform_driver ath11k_ahb_driver = {
.of_match_table = ath11k_ahb_of_match,
},
.probe = ath11k_ahb_probe,
- .remove = ath11k_ahb_remove,
+ .remove_new = ath11k_ahb_remove,
.shutdown = ath11k_ahb_shutdown,
};
diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c
index 289d47ae92af..e66e86bdec20 100644
--- a/drivers/net/wireless/ath/ath11k/ce.c
+++ b/drivers/net/wireless/ath/ath11k/ce.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "dp_rx.h"
diff --git a/drivers/net/wireless/ath/ath11k/ce.h b/drivers/net/wireless/ath/ath11k/ce.h
index c0f6a0ba86df..69946fc70077 100644
--- a/drivers/net/wireless/ath/ath11k/ce.h
+++ b/drivers/net/wireless/ath/ath11k/ce.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_CE_H
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index f12b606e2d2e..7e3b6779f4e9 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -599,7 +599,6 @@ struct ath11k {
struct ath11k_base *ab;
struct ath11k_pdev *pdev;
struct ieee80211_hw *hw;
- struct ieee80211_ops *ops;
struct ath11k_pdev_wmi *wmi;
struct ath11k_pdev_dp dp;
u8 mac_addr[ETH_ALEN];
diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c
index 5536e8642331..fbb6e8d8a476 100644
--- a/drivers/net/wireless/ath/ath11k/dbring.c
+++ b/drivers/net/wireless/ath/ath11k/dbring.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath11k/dbring.h b/drivers/net/wireless/ath/ath11k/dbring.h
index ef906c687b8c..2f93b78a50df 100644
--- a/drivers/net/wireless/ath/ath11k/dbring.h
+++ b/drivers/net/wireless/ath/ath11k/dbring.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_DBRING_H
diff --git a/drivers/net/wireless/ath/ath11k/debug.c b/drivers/net/wireless/ath/ath11k/debug.c
index f5c8a34c8802..2b8544355fc1 100644
--- a/drivers/net/wireless/ath/ath11k/debug.c
+++ b/drivers/net/wireless/ath/ath11k/debug.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/vmalloc.h>
diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h
index 9c52804ef8ac..cc8934d15697 100644
--- a/drivers/net/wireless/ath/ath11k/debug.h
+++ b/drivers/net/wireless/ath/ath11k/debug.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ATH11K_DEBUG_H_
diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c
index be76e7d1c436..a847bc0d50c0 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/vmalloc.h>
diff --git a/drivers/net/wireless/ath/ath11k/debugfs.h b/drivers/net/wireless/ath/ath11k/debugfs.h
index 3af0169f6cf2..44d15845f39a 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs.h
+++ b/drivers/net/wireless/ath/ath11k/debugfs.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ATH11K_DEBUGFS_H_
diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
index 0207fc4910f3..870e86a31bf8 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/vmalloc.h>
diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h
index 96219301f05b..476689bbd4da 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h
+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef DEBUG_HTT_STATS_H
diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.c b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
index 8c177fba6f14..f56a24b6c8da 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/vmalloc.h>
diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.h b/drivers/net/wireless/ath/ath11k/debugfs_sta.h
index e6c11b3a40aa..ace877e19275 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.h
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ATH11K_DEBUGFS_STA_H_
diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index a7252b52555c..8975dc57ad77 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <crypto/hash.h>
diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h
index 15815af453b2..2f6dd69d3be2 100644
--- a/drivers/net/wireless/ath/ath11k/dp.h
+++ b/drivers/net/wireless/ath/ath11k/dp.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_DP_H
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 7eac93ce7a1d..afd481f5858f 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/ieee80211.h>
diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c
index a5fa08bc623b..c1072e66e3e8 100644
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h
index 68a21ea9b934..61be2265e09f 100644
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_DP_TX_H
diff --git a/drivers/net/wireless/ath/ath11k/fw.c b/drivers/net/wireless/ath/ath11k/fw.c
index 8f84fba29886..4e36292a79db 100644
--- a/drivers/net/wireless/ath/ath11k/fw.c
+++ b/drivers/net/wireless/ath/ath11k/fw.c
@@ -133,7 +133,7 @@ static int ath11k_fw_request_firmware_api_n(struct ath11k_base *ab,
len -= ie_len;
data += ie_len;
- };
+ }
return 0;
diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c
index 23f3af8e372d..c060c4b5c0cc 100644
--- a/drivers/net/wireless/ath/ath11k/hal.c
+++ b/drivers/net/wireless/ath/ath11k/hal.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/dma-mapping.h>
#include "hal_tx.h"
diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h
index 1942d41d6de5..80447f488954 100644
--- a/drivers/net/wireless/ath/ath11k/hal.h
+++ b/drivers/net/wireless/ath/ath11k/hal.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_HAL_H
diff --git a/drivers/net/wireless/ath/ath11k/hal_desc.h b/drivers/net/wireless/ath/ath11k/hal_desc.h
index d895ea878d9f..b2fd180bd28e 100644
--- a/drivers/net/wireless/ath/ath11k/hal_desc.h
+++ b/drivers/net/wireless/ath/ath11k/hal_desc.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c
index 41946795d620..e758ee8e17c9 100644
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "debug.h"
diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.h b/drivers/net/wireless/ath/ath11k/hal_rx.h
index 472a52cf5889..0fa9aef9d533 100644
--- a/drivers/net/wireless/ath/ath11k/hal_rx.h
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_HAL_RX_H
diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h
index d68ed4214dec..877a4073fed6 100644
--- a/drivers/net/wireless/ath/ath11k/hif.h
+++ b/drivers/net/wireless/ath/ath11k/hif.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _HIF_H_
diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c
index 2c2e425c8665..23054ab29a5e 100644
--- a/drivers/net/wireless/ath/ath11k/htc.c
+++ b/drivers/net/wireless/ath/ath11k/htc.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/skbuff.h>
#include <linux/ctype.h>
diff --git a/drivers/net/wireless/ath/ath11k/htc.h b/drivers/net/wireless/ath/ath11k/htc.h
index d31e501c807c..86f77eacaea7 100644
--- a/drivers/net/wireless/ath/ath11k/htc.h
+++ b/drivers/net/wireless/ath/ath11k/htc.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_HTC_H
@@ -150,10 +151,7 @@ struct ath11k_htc_credit_report {
struct ath11k_htc_record {
struct ath11k_htc_record_hdr hdr;
- union {
- struct ath11k_htc_credit_report credit_report[0];
- u8 pauload[0];
- };
+ struct ath11k_htc_credit_report credit_report[];
} __packed __aligned(4);
enum ath11k_htc_svc_gid {
diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c
index d7b5ec6e6904..77d8f9237680 100644
--- a/drivers/net/wireless/ath/ath11k/hw.c
+++ b/drivers/net/wireless/ath/ath11k/hw.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/types.h>
diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h
index d51a99669dd6..1b070747a5db 100644
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_HW_H
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 7f7b39817773..db241589424d 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -4654,6 +4654,14 @@ static int ath11k_station_disassoc(struct ath11k *ar,
return 0;
}
+static u32 ath11k_mac_max_nss(const u8 *ht_mcs_mask, const u16 *vht_mcs_mask,
+ const u16 *he_mcs_mask)
+{
+ return max3(ath11k_mac_max_ht_nss(ht_mcs_mask),
+ ath11k_mac_max_vht_nss(vht_mcs_mask),
+ ath11k_mac_max_he_nss(he_mcs_mask));
+}
+
static void ath11k_sta_rc_update_wk(struct work_struct *wk)
{
struct ath11k *ar;
@@ -4699,9 +4707,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
mutex_lock(&ar->conf_mutex);
nss = max_t(u32, 1, nss);
- nss = min(nss, max(max(ath11k_mac_max_ht_nss(ht_mcs_mask),
- ath11k_mac_max_vht_nss(vht_mcs_mask)),
- ath11k_mac_max_he_nss(he_mcs_mask)));
+ nss = min(nss, ath11k_mac_max_nss(ht_mcs_mask, vht_mcs_mask, he_mcs_mask));
if (changed & IEEE80211_RC_BW_CHANGED) {
/* Get the peer phymode */
@@ -8391,9 +8397,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
ath11k_warn(ar->ab,
"could not update fixed rate settings to all peers due to mcs/nss incompatibility\n");
nss = min_t(u32, ar->num_tx_chains,
- max(max(ath11k_mac_max_ht_nss(ht_mcs_mask),
- ath11k_mac_max_vht_nss(vht_mcs_mask)),
- ath11k_mac_max_he_nss(he_mcs_mask)));
+ ath11k_mac_max_nss(ht_mcs_mask, vht_mcs_mask, he_mcs_mask));
/* If multiple rates across different preambles are given
* we can reconfigure this info with all peers using PEER_ASSOC
diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h
index 0231783ad754..0dfdeed5177b 100644
--- a/drivers/net/wireless/ath/ath11k/mac.h
+++ b/drivers/net/wireless/ath/ath11k/mac.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_MAC_H
diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
index afeabd6ecc67..6835c14b82cc 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/msi.h>
diff --git a/drivers/net/wireless/ath/ath11k/mhi.h b/drivers/net/wireless/ath/ath11k/mhi.h
index 8d9f852da695..f81fba2644a4 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.h
+++ b/drivers/net/wireless/ath/ath11k/mhi.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ATH11K_MHI_H
#define _ATH11K_MHI_H
diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c
index 16d1e332193f..15e2ceb22a44 100644
--- a/drivers/net/wireless/ath/ath11k/pcic.c
+++ b/drivers/net/wireless/ath/ath11k/pcic.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
@@ -460,8 +460,6 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab)
{
int i;
- set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
-
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
@@ -471,6 +469,8 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab)
}
ath11k_pcic_ext_grp_enable(irq_grp);
}
+
+ set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
}
EXPORT_SYMBOL(ath11k_pcic_ext_irq_enable);
diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
index 1c79a932d17f..6d0126c39301 100644
--- a/drivers/net/wireless/ath/ath11k/peer.c
+++ b/drivers/net/wireless/ath/ath11k/peer.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h
index 9bd385d0a38c..3ad2f3355b14 100644
--- a/drivers/net/wireless/ath/ath11k/peer.h
+++ b/drivers/net/wireless/ath/ath11k/peer.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_PEER_H
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index c270dc46d506..2c7cab62b9bb 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/elf.h>
diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
index d477e2be814b..7e06d100af57 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.h
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_QMI_H
diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
index 3c7debae800a..b4fd4d2107c7 100644
--- a/drivers/net/wireless/ath/ath11k/reg.c
+++ b/drivers/net/wireless/ath/ath11k/reg.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/rtnetlink.h>
diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h
index 84daa6543b6a..f28902f85e41 100644
--- a/drivers/net/wireless/ath/ath11k/reg.h
+++ b/drivers/net/wireless/ath/ath11k/reg.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_REG_H
diff --git a/drivers/net/wireless/ath/ath11k/rx_desc.h b/drivers/net/wireless/ath/ath11k/rx_desc.h
index 786d5f36f5e5..2da6da727278 100644
--- a/drivers/net/wireless/ath/ath11k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath11k/rx_desc.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_RX_DESC_H
#define ATH11K_RX_DESC_H
diff --git a/drivers/net/wireless/ath/ath11k/spectral.c b/drivers/net/wireless/ath/ath11k/spectral.c
index 0b7b7122cc05..79e091134515 100644
--- a/drivers/net/wireless/ath/ath11k/spectral.c
+++ b/drivers/net/wireless/ath/ath11k/spectral.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/relay.h>
diff --git a/drivers/net/wireless/ath/ath11k/spectral.h b/drivers/net/wireless/ath/ath11k/spectral.h
index 96bfa16e18e9..789cff7c64a7 100644
--- a/drivers/net/wireless/ath/ath11k/spectral.h
+++ b/drivers/net/wireless/ath/ath11k/spectral.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_SPECTRAL_H
diff --git a/drivers/net/wireless/ath/ath11k/thermal.c b/drivers/net/wireless/ath/ath11k/thermal.c
index c9b012f97ba5..c29b11ab5bfa 100644
--- a/drivers/net/wireless/ath/ath11k/thermal.c
+++ b/drivers/net/wireless/ath/ath11k/thermal.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/device.h>
diff --git a/drivers/net/wireless/ath/ath11k/thermal.h b/drivers/net/wireless/ath/ath11k/thermal.h
index 83cb67686733..cdaf4e01d92e 100644
--- a/drivers/net/wireless/ath/ath11k/thermal.h
+++ b/drivers/net/wireless/ath/ath11k/thermal.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _ATH11K_THERMAL_
diff --git a/drivers/net/wireless/ath/ath11k/trace.h b/drivers/net/wireless/ath/ath11k/trace.h
index 9535745fe026..235ab8ea715f 100644
--- a/drivers/net/wireless/ath/ath11k/trace.h
+++ b/drivers/net/wireless/ath/ath11k/trace.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 2845b4313d3a..8a65fa04b48d 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/skbuff.h>
#include <linux/ctype.h>
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 100bb816b592..ff0a9a92beeb 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH11K_WMI_H
@@ -1096,25 +1096,27 @@ enum wmi_tlv_vdev_param {
};
enum wmi_tlv_peer_flags {
- WMI_TLV_PEER_AUTH = 0x00000001,
- WMI_TLV_PEER_QOS = 0x00000002,
- WMI_TLV_PEER_NEED_PTK_4_WAY = 0x00000004,
- WMI_TLV_PEER_NEED_GTK_2_WAY = 0x00000010,
- WMI_TLV_PEER_APSD = 0x00000800,
- WMI_TLV_PEER_HT = 0x00001000,
- WMI_TLV_PEER_40MHZ = 0x00002000,
- WMI_TLV_PEER_STBC = 0x00008000,
- WMI_TLV_PEER_LDPC = 0x00010000,
- WMI_TLV_PEER_DYN_MIMOPS = 0x00020000,
- WMI_TLV_PEER_STATIC_MIMOPS = 0x00040000,
- WMI_TLV_PEER_SPATIAL_MUX = 0x00200000,
- WMI_TLV_PEER_VHT = 0x02000000,
- WMI_TLV_PEER_80MHZ = 0x04000000,
- WMI_TLV_PEER_PMF = 0x08000000,
+ WMI_PEER_AUTH = 0x00000001,
+ WMI_PEER_QOS = 0x00000002,
+ WMI_PEER_NEED_PTK_4_WAY = 0x00000004,
+ WMI_PEER_NEED_GTK_2_WAY = 0x00000010,
+ WMI_PEER_HE = 0x00000400,
+ WMI_PEER_APSD = 0x00000800,
+ WMI_PEER_HT = 0x00001000,
+ WMI_PEER_40MHZ = 0x00002000,
+ WMI_PEER_STBC = 0x00008000,
+ WMI_PEER_LDPC = 0x00010000,
+ WMI_PEER_DYN_MIMOPS = 0x00020000,
+ WMI_PEER_STATIC_MIMOPS = 0x00040000,
+ WMI_PEER_SPATIAL_MUX = 0x00200000,
+ WMI_PEER_TWT_REQ = 0x00400000,
+ WMI_PEER_TWT_RESP = 0x00800000,
+ WMI_PEER_VHT = 0x02000000,
+ WMI_PEER_80MHZ = 0x04000000,
+ WMI_PEER_PMF = 0x08000000,
WMI_PEER_IS_P2P_CAPABLE = 0x20000000,
WMI_PEER_160MHZ = 0x40000000,
WMI_PEER_SAFEMODE_EN = 0x80000000,
-
};
/** Enum list of TLV Tags for each parameter structure type. */
@@ -2580,7 +2582,6 @@ struct wmi_service_available_event {
struct ath11k_pdev_wmi {
struct ath11k_wmi_base *wmi_ab;
enum ath11k_htc_ep_id eid;
- const struct wmi_peer_flags_map *peer_flags;
u32 rx_decap_mode;
wait_queue_head_t tx_ce_desc_wq;
};
@@ -4062,31 +4063,6 @@ struct wmi_unit_test_cmd {
#define MAX_SUPPORTED_RATES 128
-#define WMI_PEER_AUTH 0x00000001
-#define WMI_PEER_QOS 0x00000002
-#define WMI_PEER_NEED_PTK_4_WAY 0x00000004
-#define WMI_PEER_NEED_GTK_2_WAY 0x00000010
-#define WMI_PEER_HE 0x00000400
-#define WMI_PEER_APSD 0x00000800
-#define WMI_PEER_HT 0x00001000
-#define WMI_PEER_40MHZ 0x00002000
-#define WMI_PEER_STBC 0x00008000
-#define WMI_PEER_LDPC 0x00010000
-#define WMI_PEER_DYN_MIMOPS 0x00020000
-#define WMI_PEER_STATIC_MIMOPS 0x00040000
-#define WMI_PEER_SPATIAL_MUX 0x00200000
-#define WMI_PEER_TWT_REQ 0x00400000
-#define WMI_PEER_TWT_RESP 0x00800000
-#define WMI_PEER_VHT 0x02000000
-#define WMI_PEER_80MHZ 0x04000000
-#define WMI_PEER_PMF 0x08000000
-/* TODO: Place holder for WLAN_PEER_F_PS_PRESEND_REQUIRED = 0x10000000.
- * Need to be cleaned up
- */
-#define WMI_PEER_IS_P2P_CAPABLE 0x20000000
-#define WMI_PEER_160MHZ 0x40000000
-#define WMI_PEER_SAFEMODE_EN 0x80000000
-
struct beacon_tmpl_params {
u8 vdev_id;
u32 tim_ie_offset;
@@ -5754,7 +5730,6 @@ struct ath11k_wmi_base {
struct completion unified_ready;
DECLARE_BITMAP(svc_map, WMI_MAX_EXT2_SERVICE);
wait_queue_head_t tx_credits_wq;
- const struct wmi_peer_flags_map *peer_flags;
u32 num_mem_chunks;
u32 rx_decap_mode;
struct wmi_host_mem_chunk mem_chunks[WMI_MAX_MEM_REQS];
diff --git a/drivers/net/wireless/ath/ath11k/wow.h b/drivers/net/wireless/ath/ath11k/wow.h
index 553ba850d910..c85811e3f42b 100644
--- a/drivers/net/wireless/ath/ath11k/wow.h
+++ b/drivers/net/wireless/ath/ath11k/wow.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _WOW_H_
diff --git a/drivers/net/wireless/ath/ath12k/Kconfig b/drivers/net/wireless/ath/ath12k/Kconfig
index 4f9c514c13e7..e135d2b1b61d 100644
--- a/drivers/net/wireless/ath/ath12k/Kconfig
+++ b/drivers/net/wireless/ath/ath12k/Kconfig
@@ -2,7 +2,7 @@
config ATH12K
tristate "Qualcomm Technologies Wi-Fi 7 support (ath12k)"
depends on MAC80211 && HAS_DMA && PCI
- depends on CRYPTO_MICHAEL_MIC
+ select CRYPTO_MICHAEL_MIC
select QCOM_QMI_HELPERS
select MHI_BUS
select QRTR
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index b936760b5140..6c01b282fcd3 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@@ -698,13 +698,15 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
ret = ath12k_core_rfkill_config(ab);
if (ret && ret != -EOPNOTSUPP) {
ath12k_err(ab, "failed to config rfkill: %d\n", ret);
- goto err_core_stop;
+ goto err_core_pdev_destroy;
}
mutex_unlock(&ab->core_lock);
return 0;
+err_core_pdev_destroy:
+ ath12k_core_pdev_destroy(ab);
err_core_stop:
ath12k_core_stop(ab);
ath12k_mac_destroy(ab);
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 68c42ca44fcb..8458dc292821 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_CORE_H
@@ -199,6 +199,8 @@ enum ath12k_dev_flags {
ATH12K_FLAG_REGISTERED,
ATH12K_FLAG_QMI_FAIL,
ATH12K_FLAG_HTC_SUSPEND_COMPLETE,
+ ATH12K_FLAG_CE_IRQ_ENABLED,
+ ATH12K_FLAG_EXT_IRQ_ENABLED,
};
enum ath12k_monitor_flags {
@@ -467,7 +469,6 @@ struct ath12k {
struct ath12k_base *ab;
struct ath12k_pdev *pdev;
struct ieee80211_hw *hw;
- struct ieee80211_ops *ops;
struct ath12k_wmi_pdev *wmi;
struct ath12k_pdev_dp dp;
u8 mac_addr[ETH_ALEN];
diff --git a/drivers/net/wireless/ath/ath12k/dbring.c b/drivers/net/wireless/ath/ath12k/dbring.c
index 8fbf868e6f7e..788160c84c68 100644
--- a/drivers/net/wireless/ath/ath12k/dbring.c
+++ b/drivers/net/wireless/ath/ath12k/dbring.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath12k/debug.c b/drivers/net/wireless/ath/ath12k/debug.c
index 45d33279e665..fe5a732ba9ec 100644
--- a/drivers/net/wireless/ath/ath12k/debug.c
+++ b/drivers/net/wireless/ath/ath12k/debug.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/vmalloc.h>
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index 6893466f61f0..a6f81f2f97ef 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <crypto/hash.h>
@@ -961,9 +961,7 @@ int ath12k_dp_service_srng(struct ath12k_base *ab,
struct ath12k_dp *dp = &ab->dp;
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
- ath12k_dp_rx_bufs_replenish(ab, 0, rx_ring, 0,
- ab->hw_params->hal_params->rx_buf_rbm,
- true);
+ ath12k_dp_rx_bufs_replenish(ab, rx_ring, 0);
}
/* TODO: Implement handler for other interrupts */
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 61f765432516..1df3cdd46140 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_DP_H
@@ -31,7 +31,7 @@ struct dp_srng {
u32 ring_id;
};
-struct dp_rxdma_ring {
+struct dp_rxdma_mon_ring {
struct dp_srng refill_buf_ring;
struct idr bufs_idr;
/* Protects bufs_idr */
@@ -39,6 +39,11 @@ struct dp_rxdma_ring {
int bufs_max;
};
+struct dp_rxdma_ring {
+ struct dp_srng refill_buf_ring;
+ int bufs_max;
+};
+
#define ATH12K_TX_COMPL_NEXT(x) (((x) + 1) % DP_TX_COMP_RING_SIZE)
struct dp_tx_ring {
@@ -353,8 +358,8 @@ struct ath12k_dp {
struct dp_rxdma_ring rx_refill_buf_ring;
struct dp_srng rx_mac_buf_ring[MAX_RXDMA_PER_PDEV];
struct dp_srng rxdma_err_dst_ring[MAX_RXDMA_PER_PDEV];
- struct dp_rxdma_ring rxdma_mon_buf_ring;
- struct dp_rxdma_ring tx_mon_buf_ring;
+ struct dp_rxdma_mon_ring rxdma_mon_buf_ring;
+ struct dp_rxdma_mon_ring tx_mon_buf_ring;
struct ath12k_reo_q_addr_lut reoq_lut;
};
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index f44bc5494ce7..be4b39f5fa80 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "dp_mon.h"
@@ -797,7 +797,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_base *ab,
/* TODO: add msdu start parsing logic */
break;
case HAL_MON_BUF_ADDR: {
- struct dp_rxdma_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring;
+ struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring;
struct dp_mon_packet_info *packet_info =
(struct dp_mon_packet_info *)tlv_data;
int buf_id = u32_get_bits(packet_info->cookie,
@@ -1091,7 +1091,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
spin_unlock_bh(&ar->ab->base_lock);
ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
- "rx skb %pK len %u peer %pM %u %s %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
+ "rx skb %pK len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
msdu,
msdu->len,
peer ? peer->addr : NULL,
@@ -1104,6 +1104,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
(status->bw == RATE_INFO_BW_40) ? "40" : "",
(status->bw == RATE_INFO_BW_80) ? "80" : "",
(status->bw == RATE_INFO_BW_160) ? "160" : "",
+ (status->bw == RATE_INFO_BW_320) ? "320" : "",
status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",
status->rate_idx,
status->nss,
@@ -1259,7 +1260,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
}
int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab,
- struct dp_rxdma_ring *buf_ring,
+ struct dp_rxdma_mon_ring *buf_ring,
int req_entries)
{
struct hal_mon_buf_ring *mon_buf;
@@ -1902,7 +1903,7 @@ ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab,
}
case HAL_MON_BUF_ADDR: {
- struct dp_rxdma_ring *buf_ring = &ab->dp.tx_mon_buf_ring;
+ struct dp_rxdma_mon_ring *buf_ring = &ab->dp.tx_mon_buf_ring;
struct dp_mon_packet_info *packet_info =
(struct dp_mon_packet_info *)tlv_data;
int buf_id = u32_get_bits(packet_info->cookie,
@@ -2067,7 +2068,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int mac_id, int *budget,
struct ath12k_skb_rxcb *rxcb;
struct dp_srng *mon_dst_ring;
struct hal_srng *srng;
- struct dp_rxdma_ring *buf_ring;
+ struct dp_rxdma_mon_ring *buf_ring;
u64 cookie;
u32 ppdu_id;
int num_buffs_reaped = 0, srng_id, buf_id;
@@ -2480,7 +2481,7 @@ int ath12k_dp_mon_rx_process_stats(struct ath12k *ar, int mac_id,
struct ath12k_skb_rxcb *rxcb;
struct dp_srng *mon_dst_ring;
struct hal_srng *srng;
- struct dp_rxdma_ring *buf_ring;
+ struct dp_rxdma_mon_ring *buf_ring;
struct ath12k_sta *arsta = NULL;
struct ath12k_peer *peer;
u64 cookie;
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h
index c18c385798a1..fb9e9c176ce5 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.h
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_DP_MON_H
@@ -80,7 +80,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
int mac_id, struct sk_buff *skb,
struct napi_struct *napi);
int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab,
- struct dp_rxdma_ring *buf_ring,
+ struct dp_rxdma_mon_ring *buf_ring,
int req_entries);
int ath12k_dp_mon_srng_process(struct ath12k *ar, int mac_id,
int *budget, enum dp_monitor_mode monitor_mode,
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 3543fadac4a5..1ee83f765929 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/ieee80211.h>
@@ -256,22 +256,20 @@ static int ath12k_dp_purge_mon_ring(struct ath12k_base *ab)
}
/* Returns number of Rx buffers replenished */
-int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, int mac_id,
+int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
struct dp_rxdma_ring *rx_ring,
- int req_entries,
- enum hal_rx_buf_return_buf_manager mgr,
- bool hw_cc)
+ int req_entries)
{
struct ath12k_buffer_addr *desc;
struct hal_srng *srng;
struct sk_buff *skb;
int num_free;
int num_remain;
- int buf_id;
u32 cookie;
dma_addr_t paddr;
struct ath12k_dp *dp = &ab->dp;
struct ath12k_rx_desc_info *rx_desc;
+ enum hal_rx_buf_return_buf_manager mgr = ab->hw_params->hal_params->rx_buf_rbm;
req_entries = min(req_entries, rx_ring->bufs_max);
@@ -307,42 +305,29 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, int mac_id,
if (dma_mapping_error(ab->dev, paddr))
goto fail_free_skb;
- if (hw_cc) {
- spin_lock_bh(&dp->rx_desc_lock);
-
- /* Get desc from free list and store in used list
- * for cleanup purposes
- *
- * TODO: pass the removed descs rather than
- * add/read to optimize
- */
- rx_desc = list_first_entry_or_null(&dp->rx_desc_free_list,
- struct ath12k_rx_desc_info,
- list);
- if (!rx_desc) {
- spin_unlock_bh(&dp->rx_desc_lock);
- goto fail_dma_unmap;
- }
-
- rx_desc->skb = skb;
- cookie = rx_desc->cookie;
- list_del(&rx_desc->list);
- list_add_tail(&rx_desc->list, &dp->rx_desc_used_list);
+ spin_lock_bh(&dp->rx_desc_lock);
+ /* Get desc from free list and store in used list
+ * for cleanup purposes
+ *
+ * TODO: pass the removed descs rather than
+ * add/read to optimize
+ */
+ rx_desc = list_first_entry_or_null(&dp->rx_desc_free_list,
+ struct ath12k_rx_desc_info,
+ list);
+ if (!rx_desc) {
spin_unlock_bh(&dp->rx_desc_lock);
- } else {
- spin_lock_bh(&rx_ring->idr_lock);
- buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
- rx_ring->bufs_max * 3, GFP_ATOMIC);
- spin_unlock_bh(&rx_ring->idr_lock);
- if (buf_id < 0)
- goto fail_dma_unmap;
- cookie = u32_encode_bits(mac_id,
- DP_RXDMA_BUF_COOKIE_PDEV_ID) |
- u32_encode_bits(buf_id,
- DP_RXDMA_BUF_COOKIE_BUF_ID);
+ goto fail_dma_unmap;
}
+ rx_desc->skb = skb;
+ cookie = rx_desc->cookie;
+ list_del(&rx_desc->list);
+ list_add_tail(&rx_desc->list, &dp->rx_desc_used_list);
+
+ spin_unlock_bh(&dp->rx_desc_lock);
+
desc = ath12k_hal_srng_src_get_next_entry(ab, srng);
if (!desc)
goto fail_buf_unassign;
@@ -361,17 +346,11 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, int mac_id,
return req_entries - num_remain;
fail_buf_unassign:
- if (hw_cc) {
- spin_lock_bh(&dp->rx_desc_lock);
- list_del(&rx_desc->list);
- list_add_tail(&rx_desc->list, &dp->rx_desc_free_list);
- rx_desc->skb = NULL;
- spin_unlock_bh(&dp->rx_desc_lock);
- } else {
- spin_lock_bh(&rx_ring->idr_lock);
- idr_remove(&rx_ring->bufs_idr, buf_id);
- spin_unlock_bh(&rx_ring->idr_lock);
- }
+ spin_lock_bh(&dp->rx_desc_lock);
+ list_del(&rx_desc->list);
+ list_add_tail(&rx_desc->list, &dp->rx_desc_free_list);
+ rx_desc->skb = NULL;
+ spin_unlock_bh(&dp->rx_desc_lock);
fail_dma_unmap:
dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
@@ -385,8 +364,8 @@ fail_free_skb:
return req_entries - num_remain;
}
-static int ath12k_dp_rxdma_buf_ring_free(struct ath12k_base *ab,
- struct dp_rxdma_ring *rx_ring)
+static int ath12k_dp_rxdma_mon_buf_ring_free(struct ath12k_base *ab,
+ struct dp_rxdma_mon_ring *rx_ring)
{
struct sk_buff *skb;
int buf_id;
@@ -411,46 +390,49 @@ static int ath12k_dp_rxdma_buf_ring_free(struct ath12k_base *ab,
static int ath12k_dp_rxdma_buf_free(struct ath12k_base *ab)
{
struct ath12k_dp *dp = &ab->dp;
- struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
- ath12k_dp_rxdma_buf_ring_free(ab, rx_ring);
+ ath12k_dp_rxdma_mon_buf_ring_free(ab, &dp->rxdma_mon_buf_ring);
+
+ ath12k_dp_rxdma_mon_buf_ring_free(ab, &dp->tx_mon_buf_ring);
+
+ return 0;
+}
- rx_ring = &dp->rxdma_mon_buf_ring;
- ath12k_dp_rxdma_buf_ring_free(ab, rx_ring);
+static int ath12k_dp_rxdma_mon_ring_buf_setup(struct ath12k_base *ab,
+ struct dp_rxdma_mon_ring *rx_ring,
+ u32 ringtype)
+{
+ int num_entries;
- rx_ring = &dp->tx_mon_buf_ring;
- ath12k_dp_rxdma_buf_ring_free(ab, rx_ring);
+ num_entries = rx_ring->refill_buf_ring.size /
+ ath12k_hal_srng_get_entrysize(ab, ringtype);
+
+ rx_ring->bufs_max = num_entries;
+ ath12k_dp_mon_buf_replenish(ab, rx_ring, num_entries);
return 0;
}
static int ath12k_dp_rxdma_ring_buf_setup(struct ath12k_base *ab,
- struct dp_rxdma_ring *rx_ring,
- u32 ringtype)
+ struct dp_rxdma_ring *rx_ring)
{
int num_entries;
num_entries = rx_ring->refill_buf_ring.size /
- ath12k_hal_srng_get_entrysize(ab, ringtype);
+ ath12k_hal_srng_get_entrysize(ab, HAL_RXDMA_BUF);
rx_ring->bufs_max = num_entries;
- if ((ringtype == HAL_RXDMA_MONITOR_BUF) || (ringtype == HAL_TX_MONITOR_BUF))
- ath12k_dp_mon_buf_replenish(ab, rx_ring, num_entries);
- else
- ath12k_dp_rx_bufs_replenish(ab, 0, rx_ring, num_entries,
- ab->hw_params->hal_params->rx_buf_rbm,
- ringtype == HAL_RXDMA_BUF);
+ ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_entries);
+
return 0;
}
static int ath12k_dp_rxdma_buf_setup(struct ath12k_base *ab)
{
struct ath12k_dp *dp = &ab->dp;
- struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
int ret;
- ret = ath12k_dp_rxdma_ring_buf_setup(ab, rx_ring,
- HAL_RXDMA_BUF);
+ ret = ath12k_dp_rxdma_ring_buf_setup(ab, &dp->rx_refill_buf_ring);
if (ret) {
ath12k_warn(ab,
"failed to setup HAL_RXDMA_BUF\n");
@@ -458,18 +440,18 @@ static int ath12k_dp_rxdma_buf_setup(struct ath12k_base *ab)
}
if (ab->hw_params->rxdma1_enable) {
- rx_ring = &dp->rxdma_mon_buf_ring;
- ret = ath12k_dp_rxdma_ring_buf_setup(ab, rx_ring,
- HAL_RXDMA_MONITOR_BUF);
+ ret = ath12k_dp_rxdma_mon_ring_buf_setup(ab,
+ &dp->rxdma_mon_buf_ring,
+ HAL_RXDMA_MONITOR_BUF);
if (ret) {
ath12k_warn(ab,
"failed to setup HAL_RXDMA_MONITOR_BUF\n");
return ret;
}
- rx_ring = &dp->tx_mon_buf_ring;
- ret = ath12k_dp_rxdma_ring_buf_setup(ab, rx_ring,
- HAL_TX_MONITOR_BUF);
+ ret = ath12k_dp_rxdma_mon_ring_buf_setup(ab,
+ &dp->tx_mon_buf_ring,
+ HAL_TX_MONITOR_BUF);
if (ret) {
ath12k_warn(ab,
"failed to setup HAL_TX_MONITOR_BUF\n");
@@ -1339,9 +1321,6 @@ ath12k_update_per_peer_tx_stats(struct ath12k *ar,
u8 tid = HTT_PPDU_STATS_NON_QOS_TID;
bool is_ampdu = false;
- if (!usr_stats)
- return;
-
if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE)))
return;
@@ -2438,7 +2417,7 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap
spin_unlock_bh(&ab->base_lock);
ath12k_dbg(ab, ATH12K_DBG_DATA,
- "rx skb %pK len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
+ "rx skb %pK len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
msdu,
msdu->len,
peer ? peer->addr : NULL,
@@ -2452,6 +2431,7 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap
(status->bw == RATE_INFO_BW_40) ? "40" : "",
(status->bw == RATE_INFO_BW_80) ? "80" : "",
(status->bw == RATE_INFO_BW_160) ? "160" : "",
+ (status->bw == RATE_INFO_BW_320) ? "320" : "",
status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",
status->rate_idx,
status->nss,
@@ -2714,9 +2694,7 @@ try_again:
if (!total_msdu_reaped)
goto exit;
- /* TODO: Move to implicit BM? */
- ath12k_dp_rx_bufs_replenish(ab, 0, rx_ring, num_buffs_reaped,
- ab->hw_params->hal_params->rx_buf_rbm, true);
+ ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_buffs_reaped);
ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list,
ring_id);
@@ -3494,8 +3472,7 @@ exit:
rx_ring = &dp->rx_refill_buf_ring;
- ath12k_dp_rx_bufs_replenish(ab, 0, rx_ring, tot_n_bufs_reaped,
- ab->hw_params->hal_params->rx_buf_rbm, true);
+ ath12k_dp_rx_bufs_replenish(ab, rx_ring, tot_n_bufs_reaped);
return tot_n_bufs_reaped;
}
@@ -3808,8 +3785,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
if (!num_buffs_reaped)
goto done;
- ath12k_dp_rx_bufs_replenish(ab, 0, rx_ring, num_buffs_reaped,
- ab->hw_params->hal_params->rx_buf_rbm, true);
+ ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_buffs_reaped);
rcu_read_lock();
for (i = 0; i < ab->num_radios; i++) {
@@ -4090,9 +4066,6 @@ int ath12k_dp_rx_alloc(struct ath12k_base *ab)
struct ath12k_dp *dp = &ab->dp;
int i, ret;
- idr_init(&dp->rx_refill_buf_ring.bufs_idr);
- spin_lock_init(&dp->rx_refill_buf_ring.idr_lock);
-
idr_init(&dp->rxdma_mon_buf_ring.bufs_idr);
spin_lock_init(&dp->rxdma_mon_buf_ring.idr_lock);
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index c955b5c859d1..05b3d5581dbe 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_DP_RX_H
#define ATH12K_DP_RX_H
@@ -116,11 +116,9 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id,
struct napi_struct *napi,
int budget);
-int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, int mac_id,
+int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
struct dp_rxdma_ring *rx_ring,
- int req_entries,
- enum hal_rx_buf_return_buf_manager mgr,
- bool hw_cc);
+ int req_entries);
int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar);
int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id);
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index 492ca6ce6714..62f9cdbb811c 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"
diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
index eca86fc25a60..a489369d8068 100644
--- a/drivers/net/wireless/ath/ath12k/hal.c
+++ b/drivers/net/wireless/ath/ath12k/hal.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/dma-mapping.h>
#include "hal_tx.h"
@@ -889,8 +889,8 @@ static u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
static bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc)
{
- return __le16_to_cpu(desc->u.wcn7850.msdu_end.info5) &
- RX_MSDU_END_INFO5_DA_IS_MCBC;
+ return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) &
+ RX_MSDU_END_INFO13_MCAST_BCAST;
}
static void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc,
diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h
index 66035a787c72..fc47e7e6b498 100644
--- a/drivers/net/wireless/ath/ath12k/hal.h
+++ b/drivers/net/wireless/ath/ath12k/hal.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_HAL_H
diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.c b/drivers/net/wireless/ath/ath12k/hal_rx.c
index f6afbd8196bf..4f25eb9f7745 100644
--- a/drivers/net/wireless/ath/ath12k/hal_rx.c
+++ b/drivers/net/wireless/ath/ath12k/hal_rx.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "debug.h"
diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/hal_rx.h
index fcfb6c819047..095216eabc01 100644
--- a/drivers/net/wireless/ath/ath12k/hal_rx.h
+++ b/drivers/net/wireless/ath/ath12k/hal_rx.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_HAL_RX_H
@@ -61,6 +61,7 @@ enum hal_rx_bw {
HAL_RX_BW_40MHZ,
HAL_RX_BW_80MHZ,
HAL_RX_BW_160MHZ,
+ HAL_RX_BW_320MHZ,
HAL_RX_BW_MAX,
};
diff --git a/drivers/net/wireless/ath/ath12k/hif.h b/drivers/net/wireless/ath/ath12k/hif.h
index 4095fd82b1b3..c653ca1f59b2 100644
--- a/drivers/net/wireless/ath/ath12k/hif.h
+++ b/drivers/net/wireless/ath/ath12k/hif.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_HIF_H
diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c
index 2245fb510ba2..de60d988d860 100644
--- a/drivers/net/wireless/ath/ath12k/hw.c
+++ b/drivers/net/wireless/ath/ath12k/hw.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/types.h>
@@ -949,7 +949,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.rx_mac_buf_ring = true,
.vdev_start_delay = true,
- .interface_modes = BIT(NL80211_IFTYPE_STATION),
+ .interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_AP),
.supports_monitor = false,
.idle_ps = true,
diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
index 2d6427cf41a4..d2622bfef942 100644
--- a/drivers/net/wireless/ath/ath12k/hw.h
+++ b/drivers/net/wireless/ath/ath12k/hw.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_HW_H
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index fc0d14ea328e..88cec54c6c2e 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <net/mac80211.h>
@@ -343,6 +343,9 @@ ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw)
case ATH12K_BW_160:
ret = RATE_INFO_BW_160;
break;
+ case ATH12K_BW_320:
+ ret = RATE_INFO_BW_320;
+ break;
}
return ret;
@@ -359,6 +362,8 @@ enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw b
return ATH12K_BW_80;
case RATE_INFO_BW_160:
return ATH12K_BW_160;
+ case RATE_INFO_BW_320:
+ return ATH12K_BW_320;
default:
return ATH12K_BW_20;
}
@@ -3726,6 +3731,9 @@ static u32 ath12k_mac_ieee80211_sta_bw_to_wmi(struct ath12k *ar,
case IEEE80211_STA_RX_BW_160:
bw = WMI_PEER_CHWIDTH_160MHZ;
break;
+ case IEEE80211_STA_RX_BW_320:
+ bw = WMI_PEER_CHWIDTH_320MHZ;
+ break;
default:
ath12k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n",
sta->deflink.bandwidth, sta->addr);
@@ -4987,7 +4995,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
if (ret) {
ath12k_warn(ar->ab, "failed to queue management frame %d\n",
ret);
- ieee80211_free_txskb(ar->hw, skb);
+ ieee80211_free_txskb(hw, skb);
}
return;
}
@@ -4995,7 +5003,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
ret = ath12k_dp_tx(ar, arvif, skb);
if (ret) {
ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret);
- ieee80211_free_txskb(ar->hw, skb);
+ ieee80211_free_txskb(hw, skb);
}
}
@@ -5596,7 +5604,7 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw,
goto err_peer_del;
param_id = WMI_VDEV_PARAM_RTS_THRESHOLD;
- param_value = ar->hw->wiphy->rts_threshold;
+ param_value = hw->wiphy->rts_threshold;
ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
param_id, param_value);
if (ret) {
@@ -6258,10 +6266,11 @@ ath12k_mac_update_active_vif_chan(struct ath12k *ar,
struct ieee80211_chanctx_conf *ctx)
{
struct ath12k_mac_change_chanctx_arg arg = { .ctx = ctx };
+ struct ieee80211_hw *hw = ar->hw;
lockdep_assert_held(&ar->conf_mutex);
- ieee80211_iterate_active_interfaces_atomic(ar->hw,
+ ieee80211_iterate_active_interfaces_atomic(hw,
IEEE80211_IFACE_ITER_NORMAL,
ath12k_mac_change_chanctx_cnt_iter,
&arg);
@@ -6272,7 +6281,7 @@ ath12k_mac_update_active_vif_chan(struct ath12k *ar,
if (!arg.vifs)
return;
- ieee80211_iterate_active_interfaces_atomic(ar->hw,
+ ieee80211_iterate_active_interfaces_atomic(hw,
IEEE80211_IFACE_ITER_NORMAL,
ath12k_mac_change_chanctx_fill_iter,
&arg);
@@ -6380,8 +6389,8 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
}
if (ab->hw_params->vdev_start_delay &&
- (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
- arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) {
+ arvif->vdev_type != WMI_VDEV_TYPE_AP &&
+ arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) {
param.vdev_id = arvif->vdev_id;
param.peer_type = WMI_PEER_TYPE_DEFAULT;
param.peer_addr = ar->mac_addr;
@@ -6836,7 +6845,7 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
arvif->vdev_id, ret);
return ret;
}
- ieee80211_iterate_stations_atomic(ar->hw,
+ ieee80211_iterate_stations_atomic(hw,
ath12k_mac_disable_peer_fixed_rate,
arvif);
} else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask,
@@ -6882,14 +6891,14 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
return -EINVAL;
}
- ieee80211_iterate_stations_atomic(ar->hw,
+ ieee80211_iterate_stations_atomic(hw,
ath12k_mac_disable_peer_fixed_rate,
arvif);
mutex_lock(&ar->conf_mutex);
arvif->bitrate_mask = *mask;
- ieee80211_iterate_stations_atomic(ar->hw,
+ ieee80211_iterate_stations_atomic(hw,
ath12k_mac_set_bitrate_mask_iter,
arvif);
@@ -6927,7 +6936,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
ath12k_warn(ar->ab, "pdev %d successfully recovered\n",
ar->pdev->pdev_id);
ar->state = ATH12K_STATE_ON;
- ieee80211_wake_queues(ar->hw);
+ ieee80211_wake_queues(hw);
if (ab->is_reset) {
recovery_count = atomic_inc_return(&ab->recovery_count);
@@ -7151,6 +7160,7 @@ static u32 ath12k_get_phy_id(struct ath12k *ar, u32 band)
static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
u32 supported_bands)
{
+ struct ieee80211_hw *hw = ar->hw;
struct ieee80211_supported_band *band;
struct ath12k_wmi_hal_reg_capabilities_ext_arg *reg_cap;
void *channels;
@@ -7176,7 +7186,7 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
band->channels = channels;
band->n_bitrates = ath12k_g_rates_size;
band->bitrates = ath12k_g_rates;
- ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
if (ar->ab->hw_params->single_pdev_only) {
phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_2G_CAP);
@@ -7203,7 +7213,7 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
band->channels = channels;
band->n_bitrates = ath12k_a_rates_size;
band->bitrates = ath12k_a_rates;
- ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band;
+ hw->wiphy->bands[NL80211_BAND_6GHZ] = band;
ath12k_mac_update_ch_list(ar, band,
reg_cap->low_5ghz_chan,
reg_cap->high_5ghz_chan);
@@ -7225,7 +7235,7 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
band->channels = channels;
band->n_bitrates = ath12k_a_rates_size;
band->bitrates = ath12k_a_rates;
- ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
if (ar->ab->hw_params->single_pdev_only) {
phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP);
@@ -7244,6 +7254,8 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
static int ath12k_mac_setup_iface_combinations(struct ath12k *ar)
{
struct ath12k_base *ab = ar->ab;
+ struct ieee80211_hw *hw = ar->hw;
+ struct wiphy *wiphy = hw->wiphy;
struct ieee80211_iface_combination *combinations;
struct ieee80211_iface_limit *limits;
int n_limits, max_interfaces;
@@ -7294,8 +7306,8 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k *ar)
BIT(NL80211_CHAN_WIDTH_40) |
BIT(NL80211_CHAN_WIDTH_80);
- ar->hw->wiphy->iface_combinations = combinations;
- ar->hw->wiphy->n_iface_combinations = 1;
+ wiphy->iface_combinations = combinations;
+ wiphy->n_iface_combinations = 1;
return 0;
}
@@ -7339,9 +7351,12 @@ static const struct wiphy_iftype_ext_capab ath12k_iftypes_ext_capa[] = {
static void __ath12k_mac_unregister(struct ath12k *ar)
{
+ struct ieee80211_hw *hw = ar->hw;
+ struct wiphy *wiphy = hw->wiphy;
+
cancel_work_sync(&ar->regd_update_work);
- ieee80211_unregister_hw(ar->hw);
+ ieee80211_unregister_hw(hw);
idr_for_each(&ar->txmgmt_idr, ath12k_mac_tx_mgmt_pending_free, ar);
idr_destroy(&ar->txmgmt_idr);
@@ -7350,10 +7365,10 @@ static void __ath12k_mac_unregister(struct ath12k *ar)
kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
- kfree(ar->hw->wiphy->iface_combinations[0].limits);
- kfree(ar->hw->wiphy->iface_combinations);
+ kfree(wiphy->iface_combinations[0].limits);
+ kfree(wiphy->iface_combinations);
- SET_IEEE80211_DEV(ar->hw, NULL);
+ SET_IEEE80211_DEV(hw, NULL);
}
void ath12k_mac_unregister(struct ath12k_base *ab)
@@ -7375,6 +7390,8 @@ void ath12k_mac_unregister(struct ath12k_base *ab)
static int __ath12k_mac_register(struct ath12k *ar)
{
struct ath12k_base *ab = ar->ab;
+ struct ieee80211_hw *hw = ar->hw;
+ struct wiphy *wiphy = hw->wiphy;
struct ath12k_pdev_cap *cap = &ar->pdev->cap;
static const u32 cipher_suites[] = {
WLAN_CIPHER_SUITE_TKIP,
@@ -7392,9 +7409,9 @@ static int __ath12k_mac_register(struct ath12k *ar)
ath12k_pdev_caps_update(ar);
- SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
+ SET_IEEE80211_PERM_ADDR(hw, ar->mac_addr);
- SET_IEEE80211_DEV(ar->hw, ab->dev);
+ SET_IEEE80211_DEV(hw, ab->dev);
ret = ath12k_mac_setup_channels_rates(ar,
cap->supported_bands);
@@ -7410,103 +7427,102 @@ static int __ath12k_mac_register(struct ath12k *ar)
goto err_free_channels;
}
- ar->hw->wiphy->available_antennas_rx = cap->rx_chain_mask;
- ar->hw->wiphy->available_antennas_tx = cap->tx_chain_mask;
+ wiphy->available_antennas_rx = cap->rx_chain_mask;
+ wiphy->available_antennas_tx = cap->tx_chain_mask;
- ar->hw->wiphy->interface_modes = ab->hw_params->interface_modes;
+ wiphy->interface_modes = ab->hw_params->interface_modes;
- if (ar->hw->wiphy->bands[NL80211_BAND_2GHZ] &&
- ar->hw->wiphy->bands[NL80211_BAND_5GHZ] &&
- ar->hw->wiphy->bands[NL80211_BAND_6GHZ])
- ieee80211_hw_set(ar->hw, SINGLE_SCAN_ON_ALL_BANDS);
+ if (wiphy->bands[NL80211_BAND_2GHZ] &&
+ wiphy->bands[NL80211_BAND_5GHZ] &&
+ wiphy->bands[NL80211_BAND_6GHZ])
+ ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
- ieee80211_hw_set(ar->hw, SIGNAL_DBM);
- ieee80211_hw_set(ar->hw, SUPPORTS_PS);
- ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
- ieee80211_hw_set(ar->hw, MFP_CAPABLE);
- ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
- ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
- ieee80211_hw_set(ar->hw, AP_LINK_PS);
- ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
- ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
- ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
- ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
- ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
- ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
- ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
+ ieee80211_hw_set(hw, SIGNAL_DBM);
+ ieee80211_hw_set(hw, SUPPORTS_PS);
+ ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
+ ieee80211_hw_set(hw, MFP_CAPABLE);
+ ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
+ ieee80211_hw_set(hw, HAS_RATE_CONTROL);
+ ieee80211_hw_set(hw, AP_LINK_PS);
+ ieee80211_hw_set(hw, SPECTRUM_MGMT);
+ ieee80211_hw_set(hw, CONNECTION_MONITOR);
+ ieee80211_hw_set(hw, SUPPORTS_PER_STA_GTK);
+ ieee80211_hw_set(hw, CHANCTX_STA_CSA);
+ ieee80211_hw_set(hw, QUEUE_CONTROL);
+ ieee80211_hw_set(hw, SUPPORTS_TX_FRAG);
+ ieee80211_hw_set(hw, REPORTS_LOW_ACK);
if (ht_cap & WMI_HT_CAP_ENABLED) {
- ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
- ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
- ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER);
- ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU);
- ieee80211_hw_set(ar->hw, USES_RSS);
+ ieee80211_hw_set(hw, AMPDU_AGGREGATION);
+ ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
+ ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
+ ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
+ ieee80211_hw_set(hw, USES_RSS);
}
- ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
- ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+ wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
+ wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
/* TODO: Check if HT capability advertised from firmware is different
* for each band for a dual band capable radio. It will be tricky to
* handle it when the ht capability different for each band.
*/
if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS)
- ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
+ wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
- ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
- ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
+ wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
+ wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
- ar->hw->max_listen_interval = ATH12K_MAX_HW_LISTEN_INTERVAL;
+ hw->max_listen_interval = ATH12K_MAX_HW_LISTEN_INTERVAL;
- ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
- ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
- ar->hw->wiphy->max_remain_on_channel_duration = 5000;
+ wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+ wiphy->max_remain_on_channel_duration = 5000;
- ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
- ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
+ wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
+ wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
NL80211_FEATURE_AP_SCAN;
ar->max_num_stations = TARGET_NUM_STATIONS;
ar->max_num_peers = TARGET_NUM_PEERS_PDEV;
- ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
+ wiphy->max_ap_assoc_sta = ar->max_num_stations;
- ar->hw->queues = ATH12K_HW_MAX_QUEUES;
- ar->hw->wiphy->tx_queue_len = ATH12K_QUEUE_LEN;
- ar->hw->offchannel_tx_hw_queue = ATH12K_HW_MAX_QUEUES - 1;
- ar->hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
+ hw->queues = ATH12K_HW_MAX_QUEUES;
+ wiphy->tx_queue_len = ATH12K_QUEUE_LEN;
+ hw->offchannel_tx_hw_queue = ATH12K_HW_MAX_QUEUES - 1;
+ hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
- ar->hw->vif_data_size = sizeof(struct ath12k_vif);
- ar->hw->sta_data_size = sizeof(struct ath12k_sta);
+ hw->vif_data_size = sizeof(struct ath12k_vif);
+ hw->sta_data_size = sizeof(struct ath12k_sta);
- wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
- wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
- ar->hw->wiphy->cipher_suites = cipher_suites;
- ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+ wiphy->cipher_suites = cipher_suites;
+ wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
- ar->hw->wiphy->iftype_ext_capab = ath12k_iftypes_ext_capa;
- ar->hw->wiphy->num_iftype_ext_capab =
- ARRAY_SIZE(ath12k_iftypes_ext_capa);
+ wiphy->iftype_ext_capab = ath12k_iftypes_ext_capa;
+ wiphy->num_iftype_ext_capab = ARRAY_SIZE(ath12k_iftypes_ext_capa);
if (ar->supports_6ghz) {
- wiphy_ext_feature_set(ar->hw->wiphy,
+ wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_FILS_DISCOVERY);
- wiphy_ext_feature_set(ar->hw->wiphy,
+ wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);
}
- wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_PUNCT);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_PUNCT);
- ath12k_reg_init(ar);
+ ath12k_reg_init(hw);
if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) {
- ar->hw->netdev_features = NETIF_F_HW_CSUM;
- ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
- ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
+ hw->netdev_features = NETIF_F_HW_CSUM;
+ ieee80211_hw_set(hw, SW_CRYPTO_CONTROL);
+ ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
}
- ret = ieee80211_register_hw(ar->hw);
+ ret = ieee80211_register_hw(hw);
if (ret) {
ath12k_err(ar->ab, "ieee80211 registration failed: %d\n", ret);
goto err_free_if_combs;
@@ -7518,7 +7534,7 @@ static int __ath12k_mac_register(struct ath12k *ar)
* while. But that time is so short and in practise it make
* a difference in real life.
*/
- ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
+ wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
/* Apply the regd received during initialization */
ret = ath12k_regd_update(ar, true);
@@ -7530,11 +7546,11 @@ static int __ath12k_mac_register(struct ath12k *ar)
return 0;
err_unregister_hw:
- ieee80211_unregister_hw(ar->hw);
+ ieee80211_unregister_hw(hw);
err_free_if_combs:
- kfree(ar->hw->wiphy->iface_combinations[0].limits);
- kfree(ar->hw->wiphy->iface_combinations);
+ kfree(wiphy->iface_combinations[0].limits);
+ kfree(wiphy->iface_combinations);
err_free_channels:
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
@@ -7542,7 +7558,7 @@ err_free_channels:
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
err:
- SET_IEEE80211_DEV(ar->hw, NULL);
+ SET_IEEE80211_DEV(hw, NULL);
return ret;
}
diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h
index 59b4e8f5eee0..7c63bb628adc 100644
--- a/drivers/net/wireless/ath/ath12k/mac.h
+++ b/drivers/net/wireless/ath/ath12k/mac.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_MAC_H
@@ -43,6 +43,7 @@ enum ath12k_supported_bw {
ATH12K_BW_40 = 1,
ATH12K_BW_80 = 2,
ATH12K_BW_160 = 3,
+ ATH12K_BW_320 = 4,
};
extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default;
diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c
index 39e640293cdc..d5441ddb374b 100644
--- a/drivers/net/wireless/ath/ath12k/mhi.c
+++ b/drivers/net/wireless/ath/ath12k/mhi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/msi.h>
@@ -251,6 +251,7 @@ static int ath12k_mhi_get_msi(struct ath12k_pci *ab_pci)
u32 user_base_data, base_vector;
int ret, num_vectors, i;
int *irq;
+ unsigned int msi_data;
ret = ath12k_pci_get_user_msi_assignment(ab,
"MHI", &num_vectors,
@@ -265,9 +266,15 @@ static int ath12k_mhi_get_msi(struct ath12k_pci *ab_pci)
if (!irq)
return -ENOMEM;
- for (i = 0; i < num_vectors; i++)
- irq[i] = ath12k_pci_get_msi_irq(ab->dev,
- base_vector + i);
+ msi_data = base_vector;
+ for (i = 0; i < num_vectors; i++) {
+ if (test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+ irq[i] = ath12k_pci_get_msi_irq(ab->dev,
+ msi_data++);
+ else
+ irq[i] = ath12k_pci_get_msi_irq(ab->dev,
+ msi_data);
+ }
ab_pci->mhi_ctrl->irq = irq;
ab_pci->mhi_ctrl->nr_irqs = num_vectors;
@@ -374,6 +381,9 @@ int ath12k_mhi_register(struct ath12k_pci *ab_pci)
goto free_controller;
}
+ if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+ mhi_ctrl->irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
+
mhi_ctrl->iova_start = 0;
mhi_ctrl->iova_stop = 0xffffffff;
mhi_ctrl->sbl_size = SZ_512K;
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index 3006cd3fbe11..f0d2e2d8719c 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@@ -60,6 +60,17 @@ static const struct ath12k_msi_config ath12k_msi_config[] = {
},
};
+static const struct ath12k_msi_config msi_config_one_msi = {
+ .total_vectors = 1,
+ .total_users = 4,
+ .users = (struct ath12k_msi_user[]) {
+ { .name = "MHI", .num_vectors = 3, .base_vector = 0 },
+ { .name = "CE", .num_vectors = 1, .base_vector = 0 },
+ { .name = "WAKE", .num_vectors = 1, .base_vector = 0 },
+ { .name = "DP", .num_vectors = 1, .base_vector = 0 },
+ },
+};
+
static const char *irq_name[ATH12K_IRQ_NUM_MAX] = {
"bhi",
"mhi-er0",
@@ -355,16 +366,30 @@ static void ath12k_pci_free_irq(struct ath12k_base *ab)
static void ath12k_pci_ce_irq_enable(struct ath12k_base *ab, u16 ce_id)
{
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
u32 irq_idx;
+ /* In case of one MSI vector, we handle irq enable/disable in a
+ * uniform way since we only have one irq
+ */
+ if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+ return;
+
irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_id;
enable_irq(ab->irq_num[irq_idx]);
}
static void ath12k_pci_ce_irq_disable(struct ath12k_base *ab, u16 ce_id)
{
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
u32 irq_idx;
+ /* In case of one MSI vector, we handle irq enable/disable in a
+ * uniform way since we only have one irq
+ */
+ if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+ return;
+
irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_id;
disable_irq_nosync(ab->irq_num[irq_idx]);
}
@@ -373,6 +398,8 @@ static void ath12k_pci_ce_irqs_disable(struct ath12k_base *ab)
{
int i;
+ clear_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags);
+
for (i = 0; i < ab->hw_params->ce_count; i++) {
if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
continue;
@@ -397,20 +424,27 @@ static void ath12k_pci_sync_ce_irqs(struct ath12k_base *ab)
static void ath12k_pci_ce_tasklet(struct tasklet_struct *t)
{
struct ath12k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq);
+ int irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num;
ath12k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num);
- ath12k_pci_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num);
+ enable_irq(ce_pipe->ab->irq_num[irq_idx]);
}
static irqreturn_t ath12k_pci_ce_interrupt_handler(int irq, void *arg)
{
struct ath12k_ce_pipe *ce_pipe = arg;
+ struct ath12k_base *ab = ce_pipe->ab;
+ int irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num;
+
+ if (!test_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags))
+ return IRQ_HANDLED;
/* last interrupt received for this CE */
ce_pipe->timestamp = jiffies;
- ath12k_pci_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
+ disable_irq_nosync(ab->irq_num[irq_idx]);
+
tasklet_schedule(&ce_pipe->intr_tq);
return IRQ_HANDLED;
@@ -418,8 +452,15 @@ static irqreturn_t ath12k_pci_ce_interrupt_handler(int irq, void *arg)
static void ath12k_pci_ext_grp_disable(struct ath12k_ext_irq_grp *irq_grp)
{
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(irq_grp->ab);
int i;
+ /* In case of one MSI vector, we handle irq enable/disable
+ * in a uniform way since we only have one irq
+ */
+ if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+ return;
+
for (i = 0; i < irq_grp->num_irq; i++)
disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
}
@@ -428,6 +469,8 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab)
{
int i;
+ clear_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
+
for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
@@ -440,8 +483,15 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab)
static void ath12k_pci_ext_grp_enable(struct ath12k_ext_irq_grp *irq_grp)
{
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(irq_grp->ab);
int i;
+ /* In case of one MSI vector, we handle irq enable/disable in a
+ * uniform way since we only have one irq
+ */
+ if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+ return;
+
for (i = 0; i < irq_grp->num_irq; i++)
enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
}
@@ -467,11 +517,13 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget)
napi);
struct ath12k_base *ab = irq_grp->ab;
int work_done;
+ int i;
work_done = ath12k_dp_service_srng(ab, irq_grp, budget);
if (work_done < budget) {
napi_complete_done(napi, work_done);
- ath12k_pci_ext_grp_enable(irq_grp);
+ for (i = 0; i < irq_grp->num_irq; i++)
+ enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
}
if (work_done > budget)
@@ -483,13 +535,19 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget)
static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg)
{
struct ath12k_ext_irq_grp *irq_grp = arg;
+ struct ath12k_base *ab = irq_grp->ab;
+ int i;
+
+ if (!test_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags))
+ return IRQ_HANDLED;
ath12k_dbg(irq_grp->ab, ATH12K_DBG_PCI, "ext irq:%d\n", irq);
/* last interrupt received for this group */
irq_grp->timestamp = jiffies;
- ath12k_pci_ext_grp_disable(irq_grp);
+ for (i = 0; i < irq_grp->num_irq; i++)
+ disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
napi_schedule(&irq_grp->napi);
@@ -498,6 +556,7 @@ static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg)
static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
{
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
int i, j, ret, num_vectors = 0;
u32 user_base_data = 0, base_vector = 0, base_idx;
@@ -544,23 +603,32 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
ret = request_irq(irq, ath12k_pci_ext_interrupt_handler,
- IRQF_SHARED,
+ ab_pci->irq_flags,
"DP_EXT_IRQ", irq_grp);
if (ret) {
ath12k_err(ab, "failed request irq %d: %d\n",
vector, ret);
return ret;
}
-
- disable_irq_nosync(ab->irq_num[irq_idx]);
}
+ ath12k_pci_ext_grp_disable(irq_grp);
}
return 0;
}
+static int ath12k_pci_set_irq_affinity_hint(struct ath12k_pci *ab_pci,
+ const struct cpumask *m)
+{
+ if (test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+ return 0;
+
+ return irq_set_affinity_hint(ab_pci->pdev->irq, m);
+}
+
static int ath12k_pci_config_irq(struct ath12k_base *ab)
{
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
struct ath12k_ce_pipe *ce_pipe;
u32 msi_data_start;
u32 msi_data_count, msi_data_idx;
@@ -589,7 +657,7 @@ static int ath12k_pci_config_irq(struct ath12k_base *ab)
tasklet_setup(&ce_pipe->intr_tq, ath12k_pci_ce_tasklet);
ret = request_irq(irq, ath12k_pci_ce_interrupt_handler,
- IRQF_SHARED, irq_name[irq_idx],
+ ab_pci->irq_flags, irq_name[irq_idx],
ce_pipe);
if (ret) {
ath12k_err(ab, "failed to request irq %d: %d\n",
@@ -626,6 +694,8 @@ static void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab)
{
int i;
+ set_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags);
+
for (i = 0; i < ab->hw_params->ce_count; i++) {
if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
continue;
@@ -670,16 +740,27 @@ static int ath12k_pci_msi_alloc(struct ath12k_pci *ab_pci)
msi_config->total_vectors,
msi_config->total_vectors,
PCI_IRQ_MSI);
- if (num_vectors != msi_config->total_vectors) {
- ath12k_err(ab, "failed to get %d MSI vectors, only %d available",
- msi_config->total_vectors, num_vectors);
- if (num_vectors >= 0)
- return -EINVAL;
- else
- return num_vectors;
+ if (num_vectors == msi_config->total_vectors) {
+ set_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags);
+ ab_pci->irq_flags = IRQF_SHARED;
+ } else {
+ num_vectors = pci_alloc_irq_vectors(ab_pci->pdev,
+ 1,
+ 1,
+ PCI_IRQ_MSI);
+ if (num_vectors < 0) {
+ ret = -EINVAL;
+ goto reset_msi_config;
+ }
+ clear_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags);
+ ab_pci->msi_config = &msi_config_one_msi;
+ ab_pci->irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
+ ath12k_dbg(ab, ATH12K_DBG_PCI, "request MSI one vector\n");
}
+ ath12k_info(ab, "MSI vectors: %d\n", num_vectors);
+
ath12k_pci_msi_disable(ab_pci);
msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
@@ -700,6 +781,7 @@ static int ath12k_pci_msi_alloc(struct ath12k_pci *ab_pci)
free_msi_vector:
pci_free_irq_vectors(ab_pci->pdev);
+reset_msi_config:
return ret;
}
@@ -708,6 +790,25 @@ static void ath12k_pci_msi_free(struct ath12k_pci *ab_pci)
pci_free_irq_vectors(ab_pci->pdev);
}
+static int ath12k_pci_config_msi_data(struct ath12k_pci *ab_pci)
+{
+ struct msi_desc *msi_desc;
+
+ msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
+ if (!msi_desc) {
+ ath12k_err(ab_pci->ab, "msi_desc is NULL!\n");
+ pci_free_irq_vectors(ab_pci->pdev);
+ return -EINVAL;
+ }
+
+ ab_pci->msi_ep_base_data = msi_desc->msg.data;
+
+ ath12k_dbg(ab_pci->ab, ATH12K_DBG_PCI, "pci after request_irq msi_ep_base_data %d\n",
+ ab_pci->msi_ep_base_data);
+
+ return 0;
+}
+
static int ath12k_pci_claim(struct ath12k_pci *ab_pci, struct pci_dev *pdev)
{
struct ath12k_base *ab = ab_pci->ab;
@@ -891,11 +992,11 @@ int ath12k_pci_get_user_msi_assignment(struct ath12k_base *ab, char *user_name,
for (idx = 0; idx < msi_config->total_users; idx++) {
if (strcmp(user_name, msi_config->users[idx].name) == 0) {
*num_vectors = msi_config->users[idx].num_vectors;
- *user_base_data = msi_config->users[idx].base_vector
- + ab_pci->msi_ep_base_data;
- *base_vector = msi_config->users[idx].base_vector;
+ *base_vector = msi_config->users[idx].base_vector;
+ *user_base_data = *base_vector + ab_pci->msi_ep_base_data;
- ath12k_dbg(ab, ATH12K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
+ ath12k_dbg(ab, ATH12K_DBG_PCI,
+ "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
user_name, *num_vectors, *user_base_data,
*base_vector);
@@ -956,6 +1057,8 @@ void ath12k_pci_ext_irq_enable(struct ath12k_base *ab)
{
int i;
+ set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
+
for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
@@ -1000,7 +1103,10 @@ int ath12k_pci_start(struct ath12k_base *ab)
set_bit(ATH12K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
- ath12k_pci_aspm_restore(ab_pci);
+ if (test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+ ath12k_pci_aspm_restore(ab_pci);
+ else
+ ath12k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n");
ath12k_pci_ce_irqs_enable(ab);
ath12k_ce_rx_post_buf(ab);
@@ -1262,10 +1368,16 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
if (ret)
goto err_pci_msi_free;
+ ret = ath12k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
+ if (ret) {
+ ath12k_err(ab, "failed to set irq affinity %d\n", ret);
+ goto err_pci_msi_free;
+ }
+
ret = ath12k_mhi_register(ab_pci);
if (ret) {
ath12k_err(ab, "failed to register mhi: %d\n", ret);
- goto err_pci_msi_free;
+ goto err_irq_affinity_cleanup;
}
ret = ath12k_hal_srng_init(ab);
@@ -1286,6 +1398,17 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
goto err_ce_free;
}
+ /* kernel may allocate a dummy vector before request_irq and
+ * then allocate a real vector when request_irq is called.
+ * So get msi_data here again to avoid spurious interrupt
+ * as msi_data will configured to srngs.
+ */
+ ret = ath12k_pci_config_msi_data(ab_pci);
+ if (ret) {
+ ath12k_err(ab, "failed to config msi_data: %d\n", ret);
+ goto err_free_irq;
+ }
+
ret = ath12k_core_init(ab);
if (ret) {
ath12k_err(ab, "failed to init core: %d\n", ret);
@@ -1308,6 +1431,9 @@ err_mhi_unregister:
err_pci_msi_free:
ath12k_pci_msi_free(ab_pci);
+err_irq_affinity_cleanup:
+ ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
+
err_pci_free_region:
ath12k_pci_free_region(ab_pci);
@@ -1322,6 +1448,8 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
struct ath12k_base *ab = pci_get_drvdata(pdev);
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
+ ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
+
if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
ath12k_pci_power_down(ab);
ath12k_qmi_deinit_service(ab);
@@ -1348,7 +1476,9 @@ qmi_fail:
static void ath12k_pci_shutdown(struct pci_dev *pdev)
{
struct ath12k_base *ab = pci_get_drvdata(pdev);
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
+ ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
ath12k_pci_power_down(ab);
}
diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h
index 0f24fd9395cd..b2edf32ada20 100644
--- a/drivers/net/wireless/ath/ath12k/pci.h
+++ b/drivers/net/wireless/ath/ath12k/pci.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_PCI_H
#define ATH12K_PCI_H
@@ -84,6 +84,7 @@ enum ath12k_pci_flags {
ATH12K_PCI_FLAG_INIT_DONE,
ATH12K_PCI_FLAG_IS_MSI_64,
ATH12K_PCI_ASPM_RESTORE,
+ ATH12K_PCI_FLAG_MULTI_MSI_VECTORS,
};
struct ath12k_pci_ops {
@@ -108,6 +109,7 @@ struct ath12k_pci {
/* enum ath12k_pci_flags */
unsigned long flags;
u16 link_ctl;
+ unsigned long irq_flags;
const struct ath12k_pci_ops *pci_ops;
};
diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h
index c6edb24cbedd..7b3500b5c8c2 100644
--- a/drivers/net/wireless/ath/ath12k/peer.h
+++ b/drivers/net/wireless/ath/ath12k/peer.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_PEER_H
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index f6e949c618d0..77a132f6bbd1 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/elf.h>
diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h
index e20d6511d1ca..e25bbaa125e8 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.h
+++ b/drivers/net/wireless/ath/ath12k/qmi.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_QMI_H
diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
index 5c006256c82a..f924bc13ccff 100644
--- a/drivers/net/wireless/ath/ath12k/reg.c
+++ b/drivers/net/wireless/ath/ath12k/reg.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/rtnetlink.h>
#include "core.h"
@@ -28,11 +28,11 @@ static const struct ieee80211_regdomain ath12k_world_regd = {
}
};
-static bool ath12k_regdom_changes(struct ath12k *ar, char *alpha2)
+static bool ath12k_regdom_changes(struct ieee80211_hw *hw, char *alpha2)
{
const struct ieee80211_regdomain *regd;
- regd = rcu_dereference_rtnl(ar->hw->wiphy->regd);
+ regd = rcu_dereference_rtnl(hw->wiphy->regd);
/* This can happen during wiphy registration where the previous
* user request is received before we update the regd received
* from firmware.
@@ -71,7 +71,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
return;
}
- if (!ath12k_regdom_changes(ar, request->alpha2)) {
+ if (!ath12k_regdom_changes(hw, request->alpha2)) {
ath12k_dbg(ar->ab, ATH12K_DBG_REG, "Country is already set\n");
return;
}
@@ -199,6 +199,7 @@ static void ath12k_copy_regd(struct ieee80211_regdomain *regd_orig,
int ath12k_regd_update(struct ath12k *ar, bool init)
{
+ struct ieee80211_hw *hw = ar->hw;
struct ieee80211_regdomain *regd, *regd_copy = NULL;
int ret, regd_len, pdev_id;
struct ath12k_base *ab;
@@ -246,9 +247,9 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
}
rtnl_lock();
- wiphy_lock(ar->hw->wiphy);
- ret = regulatory_set_wiphy_regd_sync(ar->hw->wiphy, regd_copy);
- wiphy_unlock(ar->hw->wiphy);
+ wiphy_lock(hw->wiphy);
+ ret = regulatory_set_wiphy_regd_sync(hw->wiphy, regd_copy);
+ wiphy_unlock(hw->wiphy);
rtnl_unlock();
kfree(regd_copy);
@@ -729,10 +730,10 @@ void ath12k_regd_update_work(struct work_struct *work)
}
}
-void ath12k_reg_init(struct ath12k *ar)
+void ath12k_reg_init(struct ieee80211_hw *hw)
{
- ar->hw->wiphy->regulatory_flags = REGULATORY_WIPHY_SELF_MANAGED;
- ar->hw->wiphy->reg_notifier = ath12k_reg_notifier;
+ hw->wiphy->regulatory_flags = REGULATORY_WIPHY_SELF_MANAGED;
+ hw->wiphy->reg_notifier = ath12k_reg_notifier;
}
void ath12k_reg_free(struct ath12k_base *ab)
diff --git a/drivers/net/wireless/ath/ath12k/reg.h b/drivers/net/wireless/ath/ath12k/reg.h
index 35569f03042d..29c7ec3260da 100644
--- a/drivers/net/wireless/ath/ath12k/reg.h
+++ b/drivers/net/wireless/ath/ath12k/reg.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_REG_H
@@ -89,7 +89,7 @@ enum ath12k_reg_phy_bitmap {
ATH12K_REG_PHY_BITMAP_NO11BE = BIT(6),
};
-void ath12k_reg_init(struct ath12k *ar);
+void ath12k_reg_init(struct ieee80211_hw *hw);
void ath12k_reg_free(struct ath12k_base *ab);
void ath12k_regd_update_work(struct work_struct *work);
struct ieee80211_regdomain *ath12k_reg_build_regd(struct ath12k_base *ab,
diff --git a/drivers/net/wireless/ath/ath12k/rx_desc.h b/drivers/net/wireless/ath/ath12k/rx_desc.h
index c4058abc516e..55f20c446ca9 100644
--- a/drivers/net/wireless/ath/ath12k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath12k/rx_desc.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_RX_DESC_H
#define ATH12K_RX_DESC_H
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 0e5bf5ce8d4c..11cc3005c0f9 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/skbuff.h>
#include <linux/ctype.h>
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 629373d67421..06e5b9b4049b 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef ATH12K_WMI_H
@@ -1146,25 +1146,27 @@ enum wmi_tlv_vdev_param {
};
enum wmi_tlv_peer_flags {
- WMI_TLV_PEER_AUTH = 0x00000001,
- WMI_TLV_PEER_QOS = 0x00000002,
- WMI_TLV_PEER_NEED_PTK_4_WAY = 0x00000004,
- WMI_TLV_PEER_NEED_GTK_2_WAY = 0x00000010,
- WMI_TLV_PEER_APSD = 0x00000800,
- WMI_TLV_PEER_HT = 0x00001000,
- WMI_TLV_PEER_40MHZ = 0x00002000,
- WMI_TLV_PEER_STBC = 0x00008000,
- WMI_TLV_PEER_LDPC = 0x00010000,
- WMI_TLV_PEER_DYN_MIMOPS = 0x00020000,
- WMI_TLV_PEER_STATIC_MIMOPS = 0x00040000,
- WMI_TLV_PEER_SPATIAL_MUX = 0x00200000,
- WMI_TLV_PEER_VHT = 0x02000000,
- WMI_TLV_PEER_80MHZ = 0x04000000,
- WMI_TLV_PEER_PMF = 0x08000000,
+ WMI_PEER_AUTH = 0x00000001,
+ WMI_PEER_QOS = 0x00000002,
+ WMI_PEER_NEED_PTK_4_WAY = 0x00000004,
+ WMI_PEER_NEED_GTK_2_WAY = 0x00000010,
+ WMI_PEER_HE = 0x00000400,
+ WMI_PEER_APSD = 0x00000800,
+ WMI_PEER_HT = 0x00001000,
+ WMI_PEER_40MHZ = 0x00002000,
+ WMI_PEER_STBC = 0x00008000,
+ WMI_PEER_LDPC = 0x00010000,
+ WMI_PEER_DYN_MIMOPS = 0x00020000,
+ WMI_PEER_STATIC_MIMOPS = 0x00040000,
+ WMI_PEER_SPATIAL_MUX = 0x00200000,
+ WMI_PEER_TWT_REQ = 0x00400000,
+ WMI_PEER_TWT_RESP = 0x00800000,
+ WMI_PEER_VHT = 0x02000000,
+ WMI_PEER_80MHZ = 0x04000000,
+ WMI_PEER_PMF = 0x08000000,
WMI_PEER_IS_P2P_CAPABLE = 0x20000000,
WMI_PEER_160MHZ = 0x40000000,
WMI_PEER_SAFEMODE_EN = 0x80000000,
-
};
enum wmi_tlv_peer_flags_ext {
@@ -2220,6 +2222,7 @@ enum wmi_peer_chwidth {
WMI_PEER_CHWIDTH_40MHZ = 1,
WMI_PEER_CHWIDTH_80MHZ = 2,
WMI_PEER_CHWIDTH_160MHZ = 3,
+ WMI_PEER_CHWIDTH_320MHZ = 4,
};
enum wmi_beacon_gen_mode {
@@ -3844,31 +3847,6 @@ struct wmi_unit_test_cmd {
#define MAX_SUPPORTED_RATES 128
-#define WMI_PEER_AUTH 0x00000001
-#define WMI_PEER_QOS 0x00000002
-#define WMI_PEER_NEED_PTK_4_WAY 0x00000004
-#define WMI_PEER_NEED_GTK_2_WAY 0x00000010
-#define WMI_PEER_HE 0x00000400
-#define WMI_PEER_APSD 0x00000800
-#define WMI_PEER_HT 0x00001000
-#define WMI_PEER_40MHZ 0x00002000
-#define WMI_PEER_STBC 0x00008000
-#define WMI_PEER_LDPC 0x00010000
-#define WMI_PEER_DYN_MIMOPS 0x00020000
-#define WMI_PEER_STATIC_MIMOPS 0x00040000
-#define WMI_PEER_SPATIAL_MUX 0x00200000
-#define WMI_PEER_TWT_REQ 0x00400000
-#define WMI_PEER_TWT_RESP 0x00800000
-#define WMI_PEER_VHT 0x02000000
-#define WMI_PEER_80MHZ 0x04000000
-#define WMI_PEER_PMF 0x08000000
-/* TODO: Place holder for WLAN_PEER_F_PS_PRESEND_REQUIRED = 0x10000000.
- * Need to be cleaned up
- */
-#define WMI_PEER_IS_P2P_CAPABLE 0x20000000
-#define WMI_PEER_160MHZ 0x40000000
-#define WMI_PEER_SAFEMODE_EN 0x80000000
-
struct ath12k_wmi_vht_rate_set_params {
__le32 tlv_header;
__le32 rx_max_rate;
@@ -4770,7 +4748,6 @@ struct wmi_probe_tmpl_cmd {
struct ath12k_wmi_pdev {
struct ath12k_wmi_base *wmi_ab;
enum ath12k_htc_ep_id eid;
- const struct wmi_peer_flags_map *peer_flags;
u32 rx_decap_mode;
};
@@ -4784,7 +4761,6 @@ struct ath12k_wmi_base {
struct completion unified_ready;
DECLARE_BITMAP(svc_map, WMI_MAX_EXT2_SERVICE);
wait_queue_head_t tx_credits_wq;
- const struct wmi_peer_flags_map *peer_flags;
u32 num_mem_chunks;
u32 rx_decap_mode;
struct ath12k_wmi_host_mem_chunk_arg mem_chunks[WMI_MAX_MEM_REQS];
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
index 08bd5d3b00f1..f27308ccb2f1 100644
--- a/drivers/net/wireless/ath/ath5k/ahb.c
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -185,7 +185,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
return ret;
}
-static int ath_ahb_remove(struct platform_device *pdev)
+static void ath_ahb_remove(struct platform_device *pdev)
{
struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
struct ieee80211_hw *hw = platform_get_drvdata(pdev);
@@ -193,7 +193,7 @@ static int ath_ahb_remove(struct platform_device *pdev)
u32 reg;
if (!hw)
- return 0;
+ return;
ah = hw->priv;
@@ -215,13 +215,11 @@ static int ath_ahb_remove(struct platform_device *pdev)
ath5k_deinit_ah(ah);
iounmap(ah->iobase);
ieee80211_free_hw(hw);
-
- return 0;
}
static struct platform_driver ath_ahb_driver = {
.probe = ath_ahb_probe,
- .remove = ath_ahb_remove,
+ .remove_new = ath_ahb_remove,
.driver = {
.name = "ar231x-wmac",
},
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 693296ee9693..e85b713950b1 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -489,7 +489,4 @@ struct ath5k_eeprom_info {
/* Spur mitigation data (fbin values for spur channels) */
u16 ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS];
-
- /* Antenna raw switch tables */
- u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
};
diff --git a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
index 708c8969b503..a5eb43f30320 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
+++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
@@ -125,7 +125,7 @@ static void owl_rescan(struct pci_dev *pdev)
static void owl_fw_cb(const struct firmware *fw, void *context)
{
- struct owl_ctx *ctx = (struct owl_ctx *)context;
+ struct owl_ctx *ctx = context;
complete(&ctx->eeprom_load);
diff --git a/drivers/net/wireless/ath/ath9k/common-init.c b/drivers/net/wireless/ath/ath9k/common-init.c
index 82de0fadbc95..7c13a1deb3ac 100644
--- a/drivers/net/wireless/ath/ath9k/common-init.c
+++ b/drivers/net/wireless/ath/ath9k/common-init.c
@@ -124,7 +124,7 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
int ath9k_cmn_init_channels_rates(struct ath_common *common)
{
- struct ath_hw *ah = (struct ath_hw *)common->ah;
+ struct ath_hw *ah = common->ah;
void *channels;
BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
index a5349c72c332..4b27445a5fb8 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
@@ -471,7 +471,7 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h
u8 sample_buf[SPECTRAL_SAMPLE_MAX_LEN] = {0};
struct ath_hw *ah = spec_priv->ah;
struct ath_common *common = ath9k_hw_common(spec_priv->ah);
- struct ath_softc *sc = (struct ath_softc *)common->priv;
+ struct ath_softc *sc = common->priv;
u8 num_bins, *vdata = (u8 *)hdr;
struct ath_radar_info *radar_info;
int len = rs->rs_datalen;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index a0376a6787b8..d84e3ee7b5d9 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1376,7 +1376,7 @@ void ath9k_deinit_debug(struct ath_softc *sc)
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct ath_softc *sc = common->priv;
sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
sc->hw->wiphy->debugfsdir);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 90cfe39aa433..0c7841f95228 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -70,7 +70,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev);
static void hif_usb_regout_cb(struct urb *urb)
{
- struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
+ struct cmd_buf *cmd = urb->context;
switch (urb->status) {
case 0:
@@ -134,7 +134,7 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
static void hif_usb_mgmt_cb(struct urb *urb)
{
- struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
+ struct cmd_buf *cmd = urb->context;
struct hif_device_usb *hif_dev;
unsigned long flags;
bool txok = true;
@@ -252,7 +252,7 @@ static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev,
static void hif_usb_tx_cb(struct urb *urb)
{
- struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
+ struct tx_buf *tx_buf = urb->context;
struct hif_device_usb *hif_dev;
bool txok = true;
@@ -687,7 +687,7 @@ invalid_pkt:
static void ath9k_hif_usb_rx_cb(struct urb *urb)
{
- struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
+ struct rx_buf *rx_buf = urb->context;
struct hif_device_usb *hif_dev = rx_buf->hif_dev;
struct sk_buff *skb = rx_buf->skb;
int ret;
@@ -734,7 +734,7 @@ free:
static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
{
- struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
+ struct rx_buf *rx_buf = urb->context;
struct hif_device_usb *hif_dev = rx_buf->hif_dev;
struct sk_buff *skb = rx_buf->skb;
int ret;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index 278ddc713fdc..f7c6d9bc9311 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -482,7 +482,7 @@ void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv)
int ath9k_htc_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
priv->hw->wiphy->debugfsdir);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index dae3d9c7b640..0aa5bdeb44a1 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -63,12 +63,12 @@ static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
static void ath9k_htc_op_ps_wakeup(struct ath_common *common)
{
- ath9k_htc_ps_wakeup((struct ath9k_htc_priv *) common->priv);
+ ath9k_htc_ps_wakeup(common->priv);
}
static void ath9k_htc_op_ps_restore(struct ath_common *common)
{
- ath9k_htc_ps_restore((struct ath9k_htc_priv *) common->priv);
+ ath9k_htc_ps_restore(common->priv);
}
static const struct ath_ps_ops ath9k_htc_ps_ops = {
@@ -235,7 +235,7 @@ static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
__be32 val, reg = cpu_to_be32(reg_offset);
int r;
@@ -257,7 +257,7 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr,
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
__be32 tmpaddr[8];
__be32 tmpval[8];
int i, ret;
@@ -282,7 +282,7 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr,
static void ath9k_regwrite_multi(struct ath_common *common)
{
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
u32 rsp_status;
int r;
@@ -303,7 +303,7 @@ static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
const __be32 buf[2] = {
cpu_to_be32(reg_offset),
cpu_to_be32(val),
@@ -324,7 +324,7 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
mutex_lock(&priv->wmi->multi_write_mutex);
@@ -347,7 +347,7 @@ static void ath9k_regwrite(void *hw_priv, u32 val, u32 reg_offset)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
if (atomic_read(&priv->wmi->mwrite_cnt))
ath9k_regwrite_buffer(hw_priv, val, reg_offset);
@@ -359,7 +359,7 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
atomic_inc(&priv->wmi->mwrite_cnt);
}
@@ -368,7 +368,7 @@ static void ath9k_regwrite_flush(void *hw_priv)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
atomic_dec(&priv->wmi->mwrite_cnt);
@@ -385,7 +385,7 @@ static void ath9k_reg_rmw_buffer(void *hw_priv,
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
u32 rsp_status;
int r;
@@ -423,7 +423,7 @@ static void ath9k_reg_rmw_flush(void *hw_priv)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
u32 rsp_status;
int r;
@@ -455,7 +455,7 @@ static void ath9k_enable_rmw_buffer(void *hw_priv)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
return;
@@ -468,7 +468,7 @@ static void ath9k_reg_rmw_single(void *hw_priv,
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
struct register_rmw buf, buf_ret;
int ret;
@@ -490,7 +490,7 @@ static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+ struct ath9k_htc_priv *priv = common->priv;
if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags)) {
u32 val;
@@ -518,7 +518,7 @@ static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
static bool ath_usb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
- struct ath_hw *ah = (struct ath_hw *) common->ah;
+ struct ath_hw *ah = common->ah;
(void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
@@ -970,7 +970,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
err_init:
ath9k_stop_wmi(priv);
- hif_dev = (struct hif_device_usb *)htc_handle->hif_dev;
+ hif_dev = htc_handle->hif_dev;
ath9k_hif_usb_dealloc_urbs(hif_dev);
ath9k_destroy_wmi(priv);
err_free:
@@ -988,7 +988,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
ath9k_deinit_device(htc_handle->drv_priv);
ath9k_stop_wmi(htc_handle->drv_priv);
- ath9k_hif_usb_dealloc_urbs((struct hif_device_usb *)htc_handle->hif_dev);
+ ath9k_hif_usb_dealloc_urbs(htc_handle->hif_dev);
ath9k_destroy_wmi(htc_handle->drv_priv);
ieee80211_free_hw(htc_handle->drv_priv->hw);
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 800177021baf..efcaeccb055a 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -652,9 +652,10 @@ void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event)
struct ath9k_htc_tx_event *tx_pend;
int i;
- for (i = 0; i < txs->cnt; i++) {
- WARN_ON(txs->cnt > HTC_MAX_TX_STATUS);
+ if (WARN_ON_ONCE(txs->cnt > HTC_MAX_TX_STATUS))
+ return;
+ for (i = 0; i < txs->cnt; i++) {
__txs = &txs->txstatus[i];
skb = ath9k_htc_tx_get_packet(priv, __txs);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 99667aba289d..eb631fd3336d 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -89,7 +89,7 @@ static void htc_process_target_rdy(struct htc_target *target,
void *buf)
{
struct htc_endpoint *endpoint;
- struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
+ struct htc_ready_msg *htc_ready_msg = buf;
target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 4f00400c7ffb..7fad7e75af6a 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -151,12 +151,12 @@ static void ath9k_deinit_softc(struct ath_softc *sc);
static void ath9k_op_ps_wakeup(struct ath_common *common)
{
- ath9k_ps_wakeup((struct ath_softc *) common->priv);
+ ath9k_ps_wakeup(common->priv);
}
static void ath9k_op_ps_restore(struct ath_common *common)
{
- ath9k_ps_restore((struct ath_softc *) common->priv);
+ ath9k_ps_restore(common->priv);
}
static const struct ath_ps_ops ath9k_ps_ops = {
@@ -174,7 +174,7 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct ath_softc *sc = common->priv;
if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
unsigned long flags;
@@ -189,7 +189,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct ath_softc *sc = common->priv;
u32 val;
if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
@@ -229,7 +229,7 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl
{
struct ath_hw *ah = hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct ath_softc *sc = common->priv;
unsigned long flags;
u32 val;
@@ -608,7 +608,7 @@ static int ath9k_nvmem_request_eeprom(struct ath_softc *sc)
}
/* devres manages the calibration values release on shutdown */
- ah->nvmem_blob = (u16 *)devm_kmemdup(sc->dev, buf, len, GFP_KERNEL);
+ ah->nvmem_blob = devm_kmemdup(sc->dev, buf, len, GFP_KERNEL);
kfree(buf);
if (!ah->nvmem_blob)
return -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 9d84003db800..d1e5767aab3c 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -304,7 +304,7 @@ fail_paprd:
void ath_ani_calibrate(struct timer_list *t)
{
struct ath_common *common = from_timer(common, t, ani.timer);
- struct ath_softc *sc = (struct ath_softc *)common->priv;
+ struct ath_softc *sc = common->priv;
struct ath_hw *ah = sc->sc_ah;
bool longcal = false;
bool shortcal = false;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1494feedb27d..c48ff0ffbfef 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2383,7 +2383,22 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw,
{
struct ath_softc *sc = hw->priv;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct cfg80211_chan_def *chandef = &sc->cur_chan->chandef;
+ struct ieee80211_channel *chan = chandef->chan;
+ int pos = chan->hw_value;
set_bit(ATH_OP_SCANNING, &common->op_flags);
+
+ /* Reset current survey */
+ if (!sc->cur_chan->offchannel) {
+ if (sc->cur_survey != &sc->survey[pos]) {
+ if (sc->cur_survey)
+ sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
+ sc->cur_survey = &sc->survey[pos];
+ }
+
+ memset(sc->cur_survey, 0, sizeof(struct survey_info));
+ sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
+ }
}
static void ath9k_sw_scan_complete(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 0633589b85c2..e655cd8bbf94 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -781,7 +781,7 @@ static const struct pci_device_id ath_pci_id_table[] = {
/* return bus cachesize in 4B word units */
static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
{
- struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct ath_softc *sc = common->priv;
u8 u8tmp;
pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE, &u8tmp);
@@ -799,7 +799,7 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
- struct ath_hw *ah = (struct ath_hw *) common->ah;
+ struct ath_hw *ah = common->ah;
common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
@@ -820,7 +820,7 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
/* Need to be called after we discover btcoex capabilities */
static void ath_pci_aspm_init(struct ath_common *common)
{
- struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct ath_softc *sc = common->priv;
struct ath_hw *ah = sc->sc_ah;
struct pci_dev *pdev = to_pci_dev(sc->dev);
struct pci_dev *parent;
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 2bd1163177f0..41119fb177e3 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1644,7 +1644,7 @@ out_err:
return ret;
}
-static int wcn36xx_remove(struct platform_device *pdev)
+static void wcn36xx_remove(struct platform_device *pdev)
{
struct ieee80211_hw *hw = platform_get_drvdata(pdev);
struct wcn36xx *wcn = hw->priv;
@@ -1666,8 +1666,6 @@ static int wcn36xx_remove(struct platform_device *pdev)
mutex_destroy(&wcn->hal_mutex);
ieee80211_free_hw(hw);
-
- return 0;
}
static const struct of_device_id wcn36xx_of_match[] = {
@@ -1678,7 +1676,7 @@ MODULE_DEVICE_TABLE(of, wcn36xx_of_match);
static struct platform_driver wcn36xx_driver = {
.probe = wcn36xx_probe,
- .remove = wcn36xx_remove,
+ .remove_new = wcn36xx_remove,
.driver = {
.name = "wcn36xx",
.of_match_table = wcn36xx_of_match,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index a194b0e68eb5..b6d458e022fa 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -578,18 +578,16 @@ static int __init brcmf_common_pd_probe(struct platform_device *pdev)
return 0;
}
-static int brcmf_common_pd_remove(struct platform_device *pdev)
+static void brcmf_common_pd_remove(struct platform_device *pdev)
{
brcmf_dbg(INFO, "Enter\n");
if (brcmfmac_pdata->power_off)
brcmfmac_pdata->power_off();
-
- return 0;
}
static struct platform_driver brcmf_pd = {
- .remove = brcmf_common_pd_remove,
+ .remove_new = brcmf_common_pd_remove,
.driver = {
.name = BRCMFMAC_PDATA_NAME,
}
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index 054fef680aba..17570d62c896 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -541,6 +541,9 @@ il_leds_init(struct il_priv *il)
il->led.name =
kasprintf(GFP_KERNEL, "%s-led", wiphy_name(il->hw->wiphy));
+ if (!il->led.name)
+ return;
+
il->led.brightness_set = il_led_brightness_set;
il->led.blink_set = il_led_blink_set;
il->led.max_brightness = 1;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 3975a53a9f20..f6e399d1e95c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -880,10 +880,10 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
cpu_to_le32(fwrt->trans->hw_rev_step);
memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable,
sizeof(dump_info->fw_human_readable));
- strncpy(dump_info->dev_human_readable, fwrt->trans->name,
- sizeof(dump_info->dev_human_readable) - 1);
- strncpy(dump_info->bus_human_readable, fwrt->dev->bus->name,
- sizeof(dump_info->bus_human_readable) - 1);
+ strscpy_pad(dump_info->dev_human_readable, fwrt->trans->name,
+ sizeof(dump_info->dev_human_readable));
+ strscpy_pad(dump_info->bus_human_readable, fwrt->dev->bus->name,
+ sizeof(dump_info->bus_human_readable));
dump_info->num_of_lmacs = fwrt->smem_cfg.num_lmacs;
dump_info->lmac_err_id[0] =
cpu_to_le32(fwrt->dump.lmac_err_id[0]);
@@ -3395,3 +3395,13 @@ void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt)
iwl_trans_send_cmd(fwrt->trans, &hcmd);
}
IWL_EXPORT_SYMBOL(iwl_fw_disable_dbg_asserts);
+
+void iwl_fw_dbg_clear_monitor_buf(struct iwl_fw_runtime *fwrt)
+{
+ struct iwl_fw_dbg_params params = {0};
+
+ iwl_fw_dbg_stop_sync(fwrt);
+ iwl_dbg_tlv_init_cfg(fwrt);
+ iwl_fw_dbg_stop_restart_recording(fwrt, &params, false);
+}
+IWL_EXPORT_SYMBOL(iwl_fw_dbg_clear_monitor_buf);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 66b233250c7c..eb38c686b5cb 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -330,6 +330,7 @@ void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt,
u32 timepoint,
u32 timepoint_data);
void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt);
+void iwl_fw_dbg_clear_monitor_buf(struct iwl_fw_runtime *fwrt);
#define IWL_FW_CHECK_FAILED(_obj, _fmt, ...) \
IWL_ERR_LIMIT(_obj, _fmt, __VA_ARGS__)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 03f6e520145f..c38e5194c55f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -20,7 +20,7 @@ struct iwl_ucode_header {
__le32 init_size; /* bytes of init code */
__le32 init_data_size; /* bytes of init data */
__le32 boot_size; /* bytes of bootstrap code */
- u8 data[0]; /* in same order as sizes */
+ u8 data[]; /* in same order as sizes */
} v1;
struct {
__le32 build; /* build number */
@@ -29,7 +29,7 @@ struct iwl_ucode_header {
__le32 init_size; /* bytes of init code */
__le32 init_data_size; /* bytes of init data */
__le32 boot_size; /* bytes of bootstrap code */
- u8 data[0]; /* in same order as sizes */
+ u8 data[]; /* in same order as sizes */
} v2;
} u;
};
@@ -243,6 +243,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
* version tables.
* @IWL_UCODE_TLV_API_REDUCED_SCAN_CONFIG: This ucode supports v3 of
* SCAN_CONFIG_DB_CMD_API_S.
+ * @IWL_UCODE_TLV_API_NO_HOST_DISABLE_TX: Firmware offloaded the station disable tx
+ * logic.
*
* @NUM_IWL_UCODE_TLV_API: number of bits used
*/
@@ -280,6 +282,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57,
IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER = (__force iwl_ucode_tlv_api_t)58,
IWL_UCODE_TLV_API_BAND_IN_RX_DATA = (__force iwl_ucode_tlv_api_t)59,
+ IWL_UCODE_TLV_API_NO_HOST_DISABLE_TX = (__force iwl_ucode_tlv_api_t)66,
NUM_IWL_UCODE_TLV_API
/*
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index b658cf228fbe..3b14f6476743 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -1274,7 +1274,7 @@ iwl_dbg_tlv_tp_trigger(struct iwl_fw_runtime *fwrt, bool sync,
return 0;
}
-static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt)
+void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt)
{
enum iwl_fw_ini_buffer_location *ini_dest = &fwrt->trans->dbg.ini_dest;
int ret, i;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
index 06fb7d665390..7ed6329fd8ca 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
@@ -57,6 +57,7 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
enum iwl_fw_ini_time_point tp_id,
union iwl_dbg_tlv_tp_data *tp_data,
bool sync);
+void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt);
static inline void iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
enum iwl_fw_ini_time_point tp_id,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
index 347fd95c4e3a..2c280a2fe3df 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
@@ -3,7 +3,7 @@
*
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2018 - 2019, 2023 Intel Corporation
*****************************************************************************/
#if !defined(__IWLWIFI_DEVICE_TRACE_DATA) || defined(TRACE_HEADER_MULTI_READ)
@@ -36,20 +36,17 @@ TRACE_EVENT(iwlwifi_dev_tx_tb,
TRACE_EVENT(iwlwifi_dev_rx_data,
TP_PROTO(const struct device *dev,
- const struct iwl_trans *trans,
- void *rxbuf, size_t len),
- TP_ARGS(dev, trans, rxbuf, len),
+ void *rxbuf, size_t len, size_t start),
+ TP_ARGS(dev, rxbuf, len, start),
TP_STRUCT__entry(
DEV_ENTRY
- __dynamic_array(u8, data,
- len - iwl_rx_trace_len(trans, rxbuf, len, NULL))
+ __dynamic_array(u8, data, len - start)
),
TP_fast_assign(
- size_t offs = iwl_rx_trace_len(trans, rxbuf, len, NULL);
DEV_ASSIGN;
- if (offs < len)
+ if (start < len)
memcpy(__get_dynamic_array(data),
- ((u8 *)rxbuf) + offs, len - offs);
+ ((u8 *)rxbuf) + start, len - start);
),
TP_printk("[%s] RX frame data", __get_str(dev))
);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
index 46ed723f138a..e656bf6bc003 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
@@ -4,7 +4,7 @@
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018, 2023 Intel Corporation
*****************************************************************************/
#if !defined(__IWLWIFI_DEVICE_TRACE_IWLWIFI) || defined(TRACE_HEADER_MULTI_READ)
@@ -50,23 +50,20 @@ TRACE_EVENT(iwlwifi_dev_hcmd,
);
TRACE_EVENT(iwlwifi_dev_rx,
- TP_PROTO(const struct device *dev, const struct iwl_trans *trans,
- struct iwl_rx_packet *pkt, size_t len),
- TP_ARGS(dev, trans, pkt, len),
+ TP_PROTO(const struct device *dev,
+ struct iwl_rx_packet *pkt, size_t len, size_t trace_len,
+ size_t hdr_offset),
+ TP_ARGS(dev, pkt, len, trace_len, hdr_offset),
TP_STRUCT__entry(
DEV_ENTRY
__field(u16, cmd)
__field(u8, hdr_offset)
- __dynamic_array(u8, rxbuf,
- iwl_rx_trace_len(trans, pkt, len, NULL))
+ __dynamic_array(u8, rxbuf, trace_len)
),
TP_fast_assign(
- size_t hdr_offset = 0;
-
DEV_ASSIGN;
__entry->cmd = WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd);
- memcpy(__get_dynamic_array(rxbuf), pkt,
- iwl_rx_trace_len(trans, pkt, len, &hdr_offset));
+ memcpy(__get_dynamic_array(rxbuf), pkt, trace_len);
__entry->hdr_offset = hdr_offset;
),
TP_printk("[%s] RX cmd %#.2x",
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
index e46639b097f4..7e686297963d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018, 2023 Intel Corporation
*****************************************************************************/
#include <linux/module.h>
@@ -20,4 +20,17 @@
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event);
-#endif
+#else
+#include "iwl-devtrace.h"
+#endif /* __CHECKER__ */
+
+void __trace_iwlwifi_dev_rx(struct iwl_trans *trans, void *pkt, size_t len)
+{
+ size_t hdr_offset = 0, trace_len;
+
+ trace_len = iwl_rx_trace_len(trans, pkt, len, &hdr_offset);
+ trace_iwlwifi_dev_rx(trans->dev, pkt, len, trace_len, hdr_offset);
+
+ if (trace_len < len)
+ trace_iwlwifi_dev_rx_data(trans->dev, pkt, len, trace_len);
+}
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
index 01fb7b900a6d..c3e09f4fefeb 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
@@ -7,12 +7,12 @@
*****************************************************************************/
#ifndef __IWLWIFI_DEVICE_TRACE
+#define __IWLWIFI_DEVICE_TRACE
#include <linux/skbuff.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
#include "iwl-trans.h"
-#if !defined(__IWLWIFI_DEVICE_TRACE)
static inline bool iwl_trace_data(struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -70,9 +70,6 @@ static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size +
ieee80211_hdrlen(hdr->frame_control);
}
-#endif
-
-#define __IWLWIFI_DEVICE_TRACE
#include <linux/tracepoint.h>
#include <linux/device.h>
@@ -98,4 +95,20 @@ static inline void trace_ ## name(proto) {}
#include "iwl-devtrace-data.h"
#include "iwl-devtrace-iwlwifi.h"
+#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
+DECLARE_TRACEPOINT(iwlwifi_dev_rx);
+DECLARE_TRACEPOINT(iwlwifi_dev_rx_data);
+#endif
+
+void __trace_iwlwifi_dev_rx(struct iwl_trans *trans, void *pkt, size_t len);
+
+static inline void maybe_trace_iwlwifi_dev_rx(struct iwl_trans *trans,
+ void *pkt, size_t len)
+{
+#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
+ if (tracepoint_enabled(iwlwifi_dev_rx) ||
+ tracepoint_enabled(iwlwifi_dev_rx_data))
+ __trace_iwlwifi_dev_rx(trans, pkt, len);
+#endif
+}
#endif /* __IWLWIFI_DEVICE_TRACE */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 6015e1255d2a..480f8edbfd35 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -1029,7 +1029,8 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |
IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK |
IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK |
- IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK);
+ IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK |
+ IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK);
iftype_data->eht_cap.eht_cap_elem.phy_cap_info[4] &=
~(IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO |
IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
index af5f9b210f22..3dc618a7c70f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
@@ -64,8 +64,6 @@ struct iwl_cfg;
* received on the RSS queue(s). The queue parameter indicates which of the
* RSS queues received this frame; it will always be non-zero.
* This method must not sleep.
- * @async_cb: called when an ASYNC command with CMD_WANT_ASYNC_CALLBACK set
- * completes. Must be atomic.
* @queue_full: notifies that a HW queue is full.
* Must be atomic and called with BH disabled.
* @queue_not_full: notifies that a HW queue is not full any more.
@@ -96,8 +94,6 @@ struct iwl_op_mode_ops {
struct iwl_rx_cmd_buffer *rxb);
void (*rx_rss)(struct iwl_op_mode *op_mode, struct napi_struct *napi,
struct iwl_rx_cmd_buffer *rxb, unsigned int queue);
- void (*async_cb)(struct iwl_op_mode *op_mode,
- const struct iwl_device_cmd *cmd);
void (*queue_full)(struct iwl_op_mode *op_mode, int queue);
void (*queue_not_full)(struct iwl_op_mode *op_mode, int queue);
bool (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
@@ -147,13 +143,6 @@ static inline void iwl_op_mode_rx_rss(struct iwl_op_mode *op_mode,
op_mode->ops->rx_rss(op_mode, napi, rxb, queue);
}
-static inline void iwl_op_mode_async_cb(struct iwl_op_mode *op_mode,
- const struct iwl_device_cmd *cmd)
-{
- if (op_mode->ops->async_cb)
- op_mode->ops->async_cb(op_mode, cmd);
-}
-
static inline void iwl_op_mode_queue_full(struct iwl_op_mode *op_mode,
int queue)
{
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
index 4bd759432d44..f95098c21c7d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
@@ -172,10 +172,6 @@ int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
return -EIO;
}
- if (WARN_ON((cmd->flags & CMD_WANT_ASYNC_CALLBACK) &&
- !(cmd->flags & CMD_ASYNC)))
- return -EINVAL;
-
if (!(cmd->flags & CMD_ASYNC))
lock_map_acquire_read(&trans->sync_cmd_lockdep_map);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 05e72a2125b3..ef7dc0a7b56c 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -110,8 +110,7 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt)
* @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of
* the response. The caller needs to call iwl_free_resp when done.
* @CMD_SEND_IN_RFKILL: Send the command even if the NIC is in RF-kill.
- * @CMD_WANT_ASYNC_CALLBACK: the op_mode's async callback function must be
- * called after this command completes. Valid only with CMD_ASYNC.
+ * @CMD_BLOCK_TXQS: Block TXQs while the comment is executing.
* @CMD_SEND_IN_D3: Allow the command to be sent in D3 mode, relevant to
* SUSPEND and RESUME commands. We are in D3 mode when we set
* trans->system_pm_mode to IWL_PLAT_PM_MODE_D3.
@@ -120,7 +119,7 @@ enum CMD_MODE {
CMD_ASYNC = BIT(0),
CMD_WANT_SKB = BIT(1),
CMD_SEND_IN_RFKILL = BIT(2),
- CMD_WANT_ASYNC_CALLBACK = BIT(3),
+ CMD_BLOCK_TXQS = BIT(3),
CMD_SEND_IN_D3 = BIT(4),
};
@@ -534,11 +533,6 @@ struct iwl_pnvm_image {
* @wait_txq_empty: wait until specific tx queue is empty. May sleep.
* @freeze_txq_timer: prevents the timer of the queue from firing until the
* queue is set to awake. Must be atomic.
- * @block_txq_ptrs: stop updating the write pointers of the Tx queues. Note
- * that the transport needs to refcount the calls since this function
- * will be called several times with block = true, and then the queues
- * need to be unblocked only after the same number of calls with
- * block = false.
* @write8: write a u8 to a register at offset ofs from the BAR
* @write32: write a u32 to a register at offset ofs from the BAR
* @read32: read a u32 register at offset ofs from the BAR
@@ -613,7 +607,6 @@ struct iwl_trans_ops {
int (*wait_txq_empty)(struct iwl_trans *trans, int queue);
void (*freeze_txq_timer)(struct iwl_trans *trans, unsigned long txqs,
bool freeze);
- void (*block_txq_ptrs)(struct iwl_trans *trans, bool block);
void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
@@ -1407,18 +1400,6 @@ static inline void iwl_trans_freeze_txq_timer(struct iwl_trans *trans,
trans->ops->freeze_txq_timer(trans, txqs, freeze);
}
-static inline void iwl_trans_block_txq_ptrs(struct iwl_trans *trans,
- bool block)
-{
- if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
- IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
- return;
- }
-
- if (trans->ops->block_txq_ptrs)
- trans->ops->block_txq_ptrs(trans, block);
-}
-
static inline int iwl_trans_wait_tx_queues_empty(struct iwl_trans *trans,
u32 txqs)
{
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index 329c545f65fd..e016fce7ab24 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -1714,6 +1714,20 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
return count;
}
+static ssize_t iwl_dbgfs_fw_dbg_clear_write(struct iwl_mvm *mvm,
+ char *buf, size_t count,
+ loff_t *ppos)
+{
+ if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&mvm->mutex);
+ iwl_fw_dbg_clear_monitor_buf(&mvm->fwrt);
+ mutex_unlock(&mvm->mutex);
+
+ return count;
+}
+
static ssize_t iwl_dbgfs_dbg_time_point_write(struct iwl_mvm *mvm,
char *buf, size_t count,
loff_t *ppos)
@@ -2166,6 +2180,7 @@ MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
+MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_clear, 64);
MVM_DEBUGFS_WRITE_FILE_OPS(dbg_time_point, 64);
MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
(IWL_RSS_INDIRECTION_TABLE_SIZE * 2));
@@ -2372,6 +2387,7 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm)
MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600);
MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600);
MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200);
+ MVM_DEBUGFS_ADD_FILE(fw_dbg_clear, mvm->debugfs_dir, 0200);
MVM_DEBUGFS_ADD_FILE(dbg_time_point, mvm->debugfs_dir, 0200);
MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
index 6af606e5da65..1628bf55458f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
@@ -874,6 +874,9 @@ void iwl_mvm_mld_sta_modify_disable_tx(struct iwl_mvm *mvm,
cmd.sta_id = cpu_to_le32(mvmsta->deflink.sta_id);
cmd.disable = cpu_to_le32(disable);
+ if (WARN_ON(iwl_mvm_has_no_host_disable_tx(mvm)))
+ return;
+
ret = iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(MAC_CONF_GROUP, STA_DISABLE_TX_CMD),
CMD_ASYNC, sizeof(cmd), &cmd);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index f2af3e571409..40627961b834 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -947,6 +947,7 @@ struct iwl_mvm {
/* the vif that requested the current scan */
struct iwl_mvm_vif *scan_vif;
+ u8 scan_link_id;
/* rx chain antennas set through debugfs for the scan command */
u8 scan_rx_ant;
@@ -1513,6 +1514,12 @@ static inline bool iwl_mvm_has_quota_low_latency(struct iwl_mvm *mvm)
IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY);
}
+static inline bool iwl_mvm_has_no_host_disable_tx(struct iwl_mvm *mvm)
+{
+ return fw_has_api(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_API_NO_HOST_DISABLE_TX);
+}
+
static inline bool iwl_mvm_has_tlc_offload(const struct iwl_mvm *mvm)
{
return fw_has_capa(&mvm->fw->ucode_capa,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 1627b2f819db..adbbe19aeae5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1703,18 +1703,6 @@ void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
iwl_mvm_rx_common(mvm, rxb, pkt);
}
-static void iwl_mvm_async_cb(struct iwl_op_mode *op_mode,
- const struct iwl_device_cmd *cmd)
-{
- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-
- /*
- * For now, we only set the CMD_WANT_ASYNC_CALLBACK for ADD_STA
- * commands that need to block the Tx queues.
- */
- iwl_trans_block_txq_ptrs(mvm->trans, false);
-}
-
static int iwl_mvm_is_static_queue(struct iwl_mvm *mvm, int queue)
{
return queue == mvm->aux_queue || queue == mvm->probe_queue ||
@@ -2024,7 +2012,6 @@ static void iwl_op_mode_mvm_time_point(struct iwl_op_mode *op_mode,
#define IWL_MVM_COMMON_OPS \
/* these could be differentiated */ \
- .async_cb = iwl_mvm_async_cb, \
.queue_full = iwl_mvm_stop_sw_queue, \
.queue_not_full = iwl_mvm_wake_sw_queue, \
.hw_rf_kill = iwl_mvm_set_hw_rfkill_state, \
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 75c5c58e14a5..7b6f1cdca067 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -101,6 +101,7 @@ struct iwl_mvm_scan_params {
bool scan_6ghz;
bool enable_6ghz_passive;
bool respect_p2p_go, respect_p2p_go_hb;
+ s8 tsf_report_link_id;
u8 bssid[ETH_ALEN] __aligned(2);
};
@@ -2342,20 +2343,15 @@ iwl_mvm_scan_umac_fill_general_p_v12(struct iwl_mvm *mvm,
if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2)
gp->num_of_fragments[SCAN_HB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS;
+ mvm->scan_link_id = 0;
+
if (version < 16) {
gp->scan_start_mac_or_link_id = scan_vif->id;
} else {
- struct iwl_mvm_vif_link_info *link_info;
- u8 link_id = 0;
+ struct iwl_mvm_vif_link_info *link_info =
+ scan_vif->link[params->tsf_report_link_id];
- /* Use one of the active link (if any). In the future it would
- * be possible that the link ID would be part of the scan
- * request coming from upper layers so we would need to use it.
- */
- if (vif->active_links)
- link_id = ffs(vif->active_links) - 1;
-
- link_info = scan_vif->link[link_id];
+ mvm->scan_link_id = params->tsf_report_link_id;
if (!WARN_ON(!link_info))
gp->scan_start_mac_or_link_id = link_info->fw_link_id;
}
@@ -2977,6 +2973,14 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (req->duration)
params.iter_notif = true;
+ params.tsf_report_link_id = req->tsf_report_link_id;
+ if (params.tsf_report_link_id < 0) {
+ if (vif->active_links)
+ params.tsf_report_link_id = __ffs(vif->active_links);
+ else
+ params.tsf_report_link_id = 0;
+ }
+
iwl_mvm_build_scan_probe(mvm, vif, ies, &params);
iwl_mvm_scan_6ghz_passive_scan(mvm, &params, vif);
@@ -3164,8 +3168,13 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
.aborted = aborted,
.scan_start_tsf = mvm->scan_start,
};
+ struct iwl_mvm_vif *scan_vif = mvm->scan_vif;
+ struct iwl_mvm_vif_link_info *link_info =
+ scan_vif->link[mvm->scan_link_id];
+
+ if (!WARN_ON(!link_info))
+ memcpy(info.tsf_bssid, link_info->bssid, ETH_ALEN);
- memcpy(info.tsf_bssid, mvm->scan_vif->deflink.bssid, ETH_ALEN);
ieee80211_scan_completed(mvm->hw, &info);
mvm->scan_vif = NULL;
cancel_delayed_work(&mvm->scan_timeout_dwork);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index bba96a968890..efe3e111ea0a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -4111,10 +4111,8 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
}
/* block the Tx queues until the FW updated the sleep Tx count */
- iwl_trans_block_txq_ptrs(mvm->trans, true);
-
ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA,
- CMD_ASYNC | CMD_WANT_ASYNC_CALLBACK,
+ CMD_ASYNC | CMD_BLOCK_TXQS,
iwl_mvm_add_sta_cmd_size(mvm), &cmd);
if (ret)
IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
@@ -4152,7 +4150,8 @@ void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,
int ret;
if (mvm->mld_api_is_used) {
- iwl_mvm_mld_sta_modify_disable_tx(mvm, mvmsta, disable);
+ if (!iwl_mvm_has_no_host_disable_tx(mvm))
+ iwl_mvm_mld_sta_modify_disable_tx(mvm, mvmsta, disable);
return;
}
@@ -4169,7 +4168,8 @@ void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
if (mvm->mld_api_is_used) {
- iwl_mvm_mld_sta_modify_disable_tx_ap(mvm, sta, disable);
+ if (!iwl_mvm_has_no_host_disable_tx(mvm))
+ iwl_mvm_mld_sta_modify_disable_tx_ap(mvm, sta, disable);
return;
}
@@ -4224,7 +4224,9 @@ void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
int i;
if (mvm->mld_api_is_used) {
- iwl_mvm_mld_modify_all_sta_disable_tx(mvm, mvmvif, disable);
+ if (!iwl_mvm_has_no_host_disable_tx(mvm))
+ iwl_mvm_mld_modify_all_sta_disable_tx(mvm, mvmvif,
+ disable);
return;
}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 26a0953603ab..2c9b98c8184b 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1121,9 +1121,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
/*
* Read rf id and cdb info from prph register and store it
*/
-static int get_crf_id(struct iwl_trans *iwl_trans)
+static void get_crf_id(struct iwl_trans *iwl_trans)
{
- int ret = 0;
u32 sd_reg_ver_addr;
u32 val = 0;
@@ -1150,8 +1149,6 @@ static int get_crf_id(struct iwl_trans *iwl_trans)
IWL_INFO(iwl_trans, "Detected crf-id 0x%x, cnv-id 0x%x wfpm id 0x%x\n",
iwl_trans->hw_crf_id, iwl_trans->hw_cnv_id,
iwl_trans->hw_wfpm_id);
-
- return ret;
}
/*
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 146bc7bd14fb..ab0c72c55b2d 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1351,8 +1351,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
if (len < sizeof(*pkt) || offset > max_len)
break;
- trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len);
- trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len);
+ maybe_trace_iwlwifi_dev_rx(trans, pkt, len);
/* Reclaim a command buffer only if this packet is a response
* to a (driver-originated) command.
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index a468e5efeecd..f39c436f0b6d 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2107,18 +2107,29 @@ static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
container_of(wk, struct iwl_trans_pcie_removal, work);
struct pci_dev *pdev = removal->pdev;
static char *prop[] = {"EVENT=INACCESSIBLE", NULL};
- struct pci_bus *bus = pdev->bus;
+ struct pci_bus *bus;
+
+ pci_lock_rescan_remove();
+
+ bus = pdev->bus;
+ /* in this case, something else already removed the device */
+ if (!bus)
+ goto out;
dev_err(&pdev->dev, "Device gone - attempting removal\n");
+
kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
- pci_lock_rescan_remove();
- pci_dev_put(pdev);
+
pci_stop_and_remove_bus_device(pdev);
- if (removal->rescan && bus) {
+ pci_dev_put(pdev);
+
+ if (removal->rescan) {
if (bus->parent)
bus = bus->parent;
pci_rescan_bus(bus);
}
+
+out:
pci_unlock_rescan_remove();
kfree(removal);
@@ -2133,6 +2144,7 @@ void iwl_trans_pcie_remove(struct iwl_trans *trans, bool rescan)
return;
IWL_ERR(trans, "Device gone - scheduling removal!\n");
+ iwl_pcie_dump_csr(trans);
/*
* get a module reference to avoid doing this
@@ -2365,32 +2377,6 @@ static int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs,
ofs, val);
}
-static void iwl_trans_pcie_block_txq_ptrs(struct iwl_trans *trans, bool block)
-{
- int i;
-
- for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
- struct iwl_txq *txq = trans->txqs.txq[i];
-
- if (i == trans->txqs.cmd.q_id)
- continue;
-
- spin_lock_bh(&txq->lock);
-
- if (!block && !(WARN_ON_ONCE(!txq->block))) {
- txq->block--;
- if (!txq->block) {
- iwl_write32(trans, HBUS_TARG_WRPTR,
- txq->write_ptr | (i << 8));
- }
- } else if (block) {
- txq->block++;
- }
-
- spin_unlock_bh(&txq->lock);
- }
-}
-
#define IWL_FLUSH_WAIT_MS 2000
static int iwl_trans_pcie_rxq_dma_data(struct iwl_trans *trans, int queue,
@@ -3572,7 +3558,6 @@ static const struct iwl_trans_ops trans_ops_pcie = {
.wait_tx_queues_empty = iwl_trans_pcie_wait_txqs_empty,
.freeze_txq_timer = iwl_trans_txq_freeze_timer,
- .block_txq_ptrs = iwl_trans_pcie_block_txq_ptrs,
#ifdef CONFIG_IWLWIFI_DEBUGFS
.debugfs_cleanup = iwl_trans_pcie_debugfs_cleanup,
#endif
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index c72a84d8bb4f..aabbef114bc2 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2020, 2023 Intel Corporation
*/
#include <net/tso.h>
#include <linux/tcp.h>
@@ -42,6 +42,9 @@ int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
struct iwl_tfh_tfd *tfd;
unsigned long flags;
+ if (WARN_ON(cmd->flags & CMD_BLOCK_TXQS))
+ return -EINVAL;
+
copy_size = sizeof(struct iwl_cmd_header_wide);
cmd_size = sizeof(struct iwl_cmd_header_wide);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 2f39b639c43f..6c2b37e56c78 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -873,6 +873,33 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
/*************** HOST COMMAND QUEUE FUNCTIONS *****/
+static void iwl_trans_pcie_block_txq_ptrs(struct iwl_trans *trans, bool block)
+{
+ int i;
+
+ for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
+ struct iwl_txq *txq = trans->txqs.txq[i];
+
+ if (i == trans->txqs.cmd.q_id)
+ continue;
+
+ /* we skip the command queue (obviously) so it's OK to nest */
+ spin_lock_nested(&txq->lock, 1);
+
+ if (!block && !(WARN_ON_ONCE(!txq->block))) {
+ txq->block--;
+ if (!txq->block) {
+ iwl_write32(trans, HBUS_TARG_WRPTR,
+ txq->write_ptr | (i << 8));
+ }
+ } else if (block) {
+ txq->block++;
+ }
+
+ spin_unlock(&txq->lock);
+ }
+}
+
/*
* iwl_pcie_enqueue_hcmd - enqueue a uCode command
* @priv: device private data point
@@ -1137,6 +1164,9 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto out;
}
+ if (cmd->flags & CMD_BLOCK_TXQS)
+ iwl_trans_pcie_block_txq_ptrs(trans, true);
+
/* Increment and update queue's write index */
txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr);
iwl_pcie_txq_inc_wr_ptr(trans, txq);
@@ -1202,8 +1232,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
meta->source->_rx_page_order = trans_pcie->rx_page_order;
}
- if (meta->flags & CMD_WANT_ASYNC_CALLBACK)
- iwl_op_mode_async_cb(trans->op_mode, cmd);
+ if (meta->flags & CMD_BLOCK_TXQS)
+ iwl_trans_pcie_block_txq_ptrs(trans, false);
iwl_pcie_cmdq_reclaim(trans, txq_id, index);
diff --git a/drivers/net/wireless/marvell/libertas/Kconfig b/drivers/net/wireless/marvell/libertas/Kconfig
index 56156a021be3..36b234bc5be8 100644
--- a/drivers/net/wireless/marvell/libertas/Kconfig
+++ b/drivers/net/wireless/marvell/libertas/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config LIBERTAS
tristate "Marvell 8xxx Libertas WLAN driver support"
- depends on USB || SDIO || SPI
+ depends on USB || MMC || SPI
depends on CFG80211
select LIB80211
select FW_LOADER
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 7a15ea8072e6..3604abcbcff9 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2047,6 +2047,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
mwifiex_set_sys_config_invalid_data(bss_cfg);
+ memcpy(bss_cfg->mac_addr, priv->curr_addr, ETH_ALEN);
+
if (params->beacon_interval)
bss_cfg->beacon_period = params->beacon_interval;
if (params->dtim_period)
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index 8e6db904e5b2..62f3c9a52a1d 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -165,6 +165,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32)
#define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35)
#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
+#define TLV_TYPE_UAP_MAC_ADDRESS (PROPRIETARY_TLV_BASE_ID + 43)
#define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44)
#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48)
diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h
index 091e7ca79376..e8825f302de8 100644
--- a/drivers/net/wireless/marvell/mwifiex/ioctl.h
+++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h
@@ -107,6 +107,7 @@ struct mwifiex_uap_bss_param {
u8 qos_info;
u8 power_constraint;
struct mwifiex_types_wmm_info wmm_info;
+ u8 mac_addr[ETH_ALEN];
};
enum {
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index 6462a0ffe698..ef3e68d1059c 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -331,6 +331,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
.can_dump_fw = false,
.can_auto_tdls = false,
.can_ext_scan = false,
+ .fw_ready_extra_delay = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -346,6 +347,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
.can_dump_fw = false,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -361,6 +363,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
.can_dump_fw = false,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -376,6 +379,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
.can_dump_fw = true,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
@@ -392,6 +396,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
.fw_dump_enh = true,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
@@ -408,6 +413,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
.fw_dump_enh = true,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = true,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
@@ -425,6 +431,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
.fw_dump_enh = true,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
@@ -440,6 +447,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
.can_dump_fw = false,
.can_auto_tdls = true,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
@@ -456,6 +464,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
.fw_dump_enh = true,
.can_auto_tdls = true,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
@@ -471,6 +480,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
.can_dump_fw = false,
.can_auto_tdls = false,
.can_ext_scan = true,
+ .fw_ready_extra_delay = false,
};
static struct memory_type_mapping generic_mem_type_map[] = {
@@ -563,6 +573,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
card->fw_dump_enh = data->fw_dump_enh;
card->can_auto_tdls = data->can_auto_tdls;
card->can_ext_scan = data->can_ext_scan;
+ card->fw_ready_extra_delay = data->fw_ready_extra_delay;
INIT_WORK(&card->work, mwifiex_sdio_work);
}
@@ -766,6 +777,7 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
u32 poll_num)
{
+ struct sdio_mmc_card *card = adapter->card;
int ret = 0;
u16 firmware_stat;
u32 tries;
@@ -783,6 +795,13 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
ret = -1;
}
+ if (card->fw_ready_extra_delay &&
+ firmware_stat == FIRMWARE_READY_SDIO)
+ /* firmware might pretend to be ready, when it's not.
+ * Wait a little bit more as a workaround.
+ */
+ msleep(100);
+
return ret;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h
index b86a9263a6a8..cb63ad55d675 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.h
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.h
@@ -255,6 +255,7 @@ struct sdio_mmc_card {
bool fw_dump_enh;
bool can_auto_tdls;
bool can_ext_scan;
+ bool fw_ready_extra_delay;
struct mwifiex_sdio_mpa_tx mpa_tx;
struct mwifiex_sdio_mpa_rx mpa_rx;
@@ -278,6 +279,7 @@ struct mwifiex_sdio_device {
bool fw_dump_enh;
bool can_auto_tdls;
bool can_ext_scan;
+ bool fw_ready_extra_delay;
};
/*
diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
index e78a201cd150..491e36611909 100644
--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
@@ -468,6 +468,7 @@ void mwifiex_config_uap_11d(struct mwifiex_private *priv,
static int
mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
{
+ struct host_cmd_tlv_mac_addr *mac_tlv;
struct host_cmd_tlv_dtim_period *dtim_period;
struct host_cmd_tlv_beacon_period *beacon_period;
struct host_cmd_tlv_ssid *ssid;
@@ -487,6 +488,13 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
int i;
u16 cmd_size = *param_size;
+ mac_tlv = (struct host_cmd_tlv_mac_addr *)tlv;
+ mac_tlv->header.type = cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS);
+ mac_tlv->header.len = cpu_to_le16(ETH_ALEN);
+ memcpy(mac_tlv->mac_addr, bss_cfg->mac_addr, ETH_ALEN);
+ cmd_size += sizeof(struct host_cmd_tlv_mac_addr);
+ tlv += sizeof(struct host_cmd_tlv_mac_addr);
+
if (bss_cfg->ssid.ssid_len) {
ssid = (struct host_cmd_tlv_ssid *)tlv;
ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 511fe7e6e744..8bbb0e17229d 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -9,11 +9,11 @@
#if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)
-#define Q_READ(_dev, _q, _field) ({ \
+#define Q_READ(_q, _field) ({ \
u32 _offset = offsetof(struct mt76_queue_regs, _field); \
u32 _val; \
if ((_q)->flags & MT_QFLAG_WED) \
- _val = mtk_wed_device_reg_read(&(_dev)->mmio.wed, \
+ _val = mtk_wed_device_reg_read((_q)->wed, \
((_q)->wed_regs + \
_offset)); \
else \
@@ -21,10 +21,10 @@
_val; \
})
-#define Q_WRITE(_dev, _q, _field, _val) do { \
+#define Q_WRITE(_q, _field, _val) do { \
u32 _offset = offsetof(struct mt76_queue_regs, _field); \
if ((_q)->flags & MT_QFLAG_WED) \
- mtk_wed_device_reg_write(&(_dev)->mmio.wed, \
+ mtk_wed_device_reg_write((_q)->wed, \
((_q)->wed_regs + _offset), \
_val); \
else \
@@ -33,8 +33,8 @@
#else
-#define Q_READ(_dev, _q, _field) readl(&(_q)->regs->_field)
-#define Q_WRITE(_dev, _q, _field, _val) writel(_val, &(_q)->regs->_field)
+#define Q_READ(_q, _field) readl(&(_q)->regs->_field)
+#define Q_WRITE(_q, _field, _val) writel(_val, &(_q)->regs->_field)
#endif
@@ -188,41 +188,67 @@ EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
static void
mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
{
- Q_WRITE(dev, q, desc_base, q->desc_dma);
- Q_WRITE(dev, q, ring_size, q->ndesc);
- q->head = Q_READ(dev, q, dma_idx);
+ Q_WRITE(q, desc_base, q->desc_dma);
+ if (q->flags & MT_QFLAG_WED_RRO_EN)
+ Q_WRITE(q, ring_size, MT_DMA_RRO_EN | q->ndesc);
+ else
+ Q_WRITE(q, ring_size, q->ndesc);
+ q->head = Q_READ(q, dma_idx);
q->tail = q->head;
}
static void
-mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
+__mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
+ bool reset_idx)
{
- int i;
-
if (!q || !q->ndesc)
return;
- /* clear descriptors */
- for (i = 0; i < q->ndesc; i++)
- q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
+ if (!mt76_queue_is_wed_rro_ind(q)) {
+ int i;
+
+ /* clear descriptors */
+ for (i = 0; i < q->ndesc; i++)
+ q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
+ }
- Q_WRITE(dev, q, cpu_idx, 0);
- Q_WRITE(dev, q, dma_idx, 0);
+ if (reset_idx) {
+ Q_WRITE(q, cpu_idx, 0);
+ Q_WRITE(q, dma_idx, 0);
+ }
mt76_dma_sync_idx(dev, q);
}
+static void
+mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
+{
+ __mt76_dma_queue_reset(dev, q, true);
+}
+
static int
mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
struct mt76_queue_buf *buf, void *data)
{
- struct mt76_desc *desc = &q->desc[q->head];
struct mt76_queue_entry *entry = &q->entry[q->head];
struct mt76_txwi_cache *txwi = NULL;
- u32 buf1 = 0, ctrl;
+ struct mt76_desc *desc;
int idx = q->head;
+ u32 buf1 = 0, ctrl;
int rx_token;
+ if (mt76_queue_is_wed_rro_ind(q)) {
+ struct mt76_wed_rro_desc *rro_desc;
+
+ rro_desc = (struct mt76_wed_rro_desc *)q->desc;
+ data = &rro_desc[q->head];
+ goto done;
+ }
+
+ desc = &q->desc[q->head];
ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ buf1 = FIELD_PREP(MT_DMA_CTL_SDP0_H, buf->addr >> 32);
+#endif
if (mt76_queue_is_wed_rx(q)) {
txwi = mt76_get_rxwi(dev);
@@ -244,6 +270,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
WRITE_ONCE(desc->info, 0);
+done:
entry->dma_addr[0] = buf->addr;
entry->dma_len[0] = buf->len;
entry->txwi = txwi;
@@ -288,11 +315,18 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
entry->dma_len[0] = buf[0].len;
ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ info |= FIELD_PREP(MT_DMA_CTL_SDP0_H, buf[0].addr >> 32);
+#endif
if (i < nbufs - 1) {
entry->dma_addr[1] = buf[1].addr;
entry->dma_len[1] = buf[1].len;
buf1 = buf[1].addr;
ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ info |= FIELD_PREP(MT_DMA_CTL_SDP1_H,
+ buf[1].addr >> 32);
+#endif
if (buf[1].skip_unmap)
entry->skip_buf1 = true;
}
@@ -343,7 +377,7 @@ static void
mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q)
{
wmb();
- Q_WRITE(dev, q, cpu_idx, q->head);
+ Q_WRITE(q, cpu_idx, q->head);
}
static void
@@ -359,7 +393,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
if (flush)
last = -1;
else
- last = Q_READ(dev, q, dma_idx);
+ last = Q_READ(q, dma_idx);
while (q->queued > 0 && q->tail != last) {
mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
@@ -371,7 +405,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
}
if (!flush && q->tail == last)
- last = Q_READ(dev, q, dma_idx);
+ last = Q_READ(q, dma_idx);
}
spin_unlock_bh(&q->cleanup_lock);
@@ -392,19 +426,26 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
{
struct mt76_queue_entry *e = &q->entry[idx];
struct mt76_desc *desc = &q->desc[idx];
- void *buf;
+ u32 ctrl, desc_info, buf1;
+ void *buf = e->buf;
+
+ if (mt76_queue_is_wed_rro_ind(q))
+ goto done;
+ ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
if (len) {
- u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
*len = FIELD_GET(MT_DMA_CTL_SD_LEN0, ctrl);
*more = !(ctrl & MT_DMA_CTL_LAST_SEC0);
}
+ desc_info = le32_to_cpu(desc->info);
if (info)
- *info = le32_to_cpu(desc->info);
+ *info = desc_info;
+
+ buf1 = le32_to_cpu(desc->buf1);
+ mt76_dma_should_drop_buf(drop, ctrl, buf1, desc_info);
if (mt76_queue_is_wed_rx(q)) {
- u32 buf1 = le32_to_cpu(desc->buf1);
u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
struct mt76_txwi_cache *t = mt76_rx_token_release(dev, token);
@@ -420,23 +461,16 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
t->ptr = NULL;
mt76_put_rxwi(dev, t);
-
- if (drop) {
- u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
-
- *drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A |
- MT_DMA_CTL_DROP));
-
+ if (drop)
*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
- }
} else {
- buf = e->buf;
- e->buf = NULL;
dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0],
SKB_WITH_OVERHEAD(q->buf_size),
page_pool_get_dma_dir(q->page_pool));
}
+done:
+ e->buf = NULL;
return buf;
}
@@ -450,11 +484,16 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
if (!q->queued)
return NULL;
- if (flush)
- q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
- else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)))
+ if (mt76_queue_is_wed_rro_data(q))
return NULL;
+ if (!mt76_queue_is_wed_rro_ind(q)) {
+ if (flush)
+ q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
+ else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)))
+ return NULL;
+ }
+
q->tail = (q->tail + 1) % q->ndesc;
q->queued--;
@@ -606,11 +645,14 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
spin_lock_bh(&q->lock);
while (q->queued < q->ndesc - 1) {
+ struct mt76_queue_buf qbuf = {};
enum dma_data_direction dir;
- struct mt76_queue_buf qbuf;
dma_addr_t addr;
int offset;
- void *buf;
+ void *buf = NULL;
+
+ if (mt76_queue_is_wed_rro_ind(q))
+ goto done;
buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
if (!buf)
@@ -621,6 +663,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
qbuf.addr = addr + q->buf_offset;
+done:
qbuf.len = len - q->buf_offset;
qbuf.skip_unmap = false;
if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
@@ -630,7 +673,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
frames++;
}
- if (frames)
+ if (frames || mt76_queue_is_wed_rx(q))
mt76_dma_kick_queue(dev, q);
spin_unlock_bh(&q->lock);
@@ -641,15 +684,14 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
{
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
- struct mtk_wed_device *wed = &dev->mmio.wed;
- int ret, type, ring;
- u8 flags;
+ int ret = 0, type, ring;
+ u16 flags;
if (!q || !q->ndesc)
return -EINVAL;
flags = q->flags;
- if (!mtk_wed_device_active(wed))
+ if (!q->wed || !mtk_wed_device_active(q->wed))
q->flags &= ~MT_QFLAG_WED;
if (!(q->flags & MT_QFLAG_WED))
@@ -660,29 +702,52 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
switch (type) {
case MT76_WED_Q_TX:
- ret = mtk_wed_device_tx_ring_setup(wed, ring, q->regs, reset);
+ ret = mtk_wed_device_tx_ring_setup(q->wed, ring, q->regs,
+ reset);
if (!ret)
- q->wed_regs = wed->tx_ring[ring].reg_base;
+ q->wed_regs = q->wed->tx_ring[ring].reg_base;
break;
case MT76_WED_Q_TXFREE:
/* WED txfree queue needs ring to be initialized before setup */
q->flags = 0;
mt76_dma_queue_reset(dev, q);
mt76_dma_rx_fill(dev, q, false);
- q->flags = flags;
- ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
+ ret = mtk_wed_device_txfree_ring_setup(q->wed, q->regs);
if (!ret)
- q->wed_regs = wed->txfree_ring.reg_base;
+ q->wed_regs = q->wed->txfree_ring.reg_base;
break;
case MT76_WED_Q_RX:
- ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
+ ret = mtk_wed_device_rx_ring_setup(q->wed, ring, q->regs,
+ reset);
if (!ret)
- q->wed_regs = wed->rx_ring[ring].reg_base;
+ q->wed_regs = q->wed->rx_ring[ring].reg_base;
+ break;
+ case MT76_WED_RRO_Q_DATA:
+ q->flags &= ~MT_QFLAG_WED;
+ __mt76_dma_queue_reset(dev, q, false);
+ mtk_wed_device_rro_rx_ring_setup(q->wed, ring, q->regs);
+ q->head = q->ndesc - 1;
+ q->queued = q->head;
+ break;
+ case MT76_WED_RRO_Q_MSDU_PG:
+ q->flags &= ~MT_QFLAG_WED;
+ __mt76_dma_queue_reset(dev, q, false);
+ mtk_wed_device_msdu_pg_rx_ring_setup(q->wed, ring, q->regs);
+ q->head = q->ndesc - 1;
+ q->queued = q->head;
+ break;
+ case MT76_WED_RRO_Q_IND:
+ q->flags &= ~MT_QFLAG_WED;
+ mt76_dma_queue_reset(dev, q);
+ mt76_dma_rx_fill(dev, q, false);
+ mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
break;
default:
ret = -EINVAL;
+ break;
}
+ q->flags = flags;
return ret;
#else
@@ -706,11 +771,26 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
q->buf_size = bufsize;
q->hw_idx = idx;
- size = q->ndesc * sizeof(struct mt76_desc);
- q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
+ size = mt76_queue_is_wed_rro_ind(q) ? sizeof(struct mt76_wed_rro_desc)
+ : sizeof(struct mt76_desc);
+ q->desc = dmam_alloc_coherent(dev->dma_dev, q->ndesc * size,
+ &q->desc_dma, GFP_KERNEL);
if (!q->desc)
return -ENOMEM;
+ if (mt76_queue_is_wed_rro_ind(q)) {
+ struct mt76_wed_rro_desc *rro_desc;
+ int i;
+
+ rro_desc = (struct mt76_wed_rro_desc *)q->desc;
+ for (i = 0; i < q->ndesc; i++) {
+ struct mt76_wed_rro_ind *cmd;
+
+ cmd = (struct mt76_wed_rro_ind *)&rro_desc[i];
+ cmd->magic_cnt = MT_DMA_WED_IND_CMD_CNT - 1;
+ }
+ }
+
size = q->ndesc * sizeof(*q->entry);
q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
if (!q->entry)
@@ -724,8 +804,13 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
if (ret)
return ret;
- if (q->flags != MT_WED_Q_TXFREE)
- mt76_dma_queue_reset(dev, q);
+ if (mtk_wed_device_active(&dev->mmio.wed)) {
+ if ((mtk_wed_get_rx_capa(&dev->mmio.wed) && mt76_queue_is_wed_rro(q)) ||
+ mt76_queue_is_wed_tx_free(q))
+ return 0;
+ }
+
+ mt76_dma_queue_reset(dev, q);
return 0;
}
@@ -747,7 +832,8 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
if (!buf)
break;
- mt76_put_page_pool_buf(buf, false);
+ if (!mt76_queue_is_wed_rro(q))
+ mt76_put_page_pool_buf(buf, false);
} while (1);
spin_lock_bh(&q->lock);
@@ -763,22 +849,31 @@ static void
mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
{
struct mt76_queue *q = &dev->q_rx[qid];
- int i;
if (!q->ndesc)
return;
- for (i = 0; i < q->ndesc; i++)
- q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
+ if (!mt76_queue_is_wed_rro_ind(q)) {
+ int i;
+
+ for (i = 0; i < q->ndesc; i++)
+ q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
+ }
mt76_dma_rx_cleanup(dev, q);
/* reset WED rx queues */
mt76_dma_wed_setup(dev, q, true);
- if (q->flags != MT_WED_Q_TXFREE) {
- mt76_dma_sync_idx(dev, q);
- mt76_dma_rx_fill(dev, q, false);
- }
+
+ if (mt76_queue_is_wed_tx_free(q))
+ return;
+
+ if (mtk_wed_device_active(&dev->mmio.wed) &&
+ mt76_queue_is_wed_rro(q))
+ return;
+
+ mt76_dma_sync_idx(dev, q);
+ mt76_dma_rx_fill(dev, q, false);
}
static void
@@ -818,8 +913,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
bool more;
if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
- q->flags == MT_WED_Q_TXFREE) {
- dma_idx = Q_READ(dev, q, dma_idx);
+ mt76_queue_is_wed_tx_free(q)) {
+ dma_idx = Q_READ(q, dma_idx);
check_ddone = true;
}
@@ -829,7 +924,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
if (check_ddone) {
if (q->tail == dma_idx)
- dma_idx = Q_READ(dev, q, dma_idx);
+ dma_idx = Q_READ(q, dma_idx);
if (q->tail == dma_idx)
break;
@@ -957,6 +1052,20 @@ void mt76_dma_attach(struct mt76_dev *dev)
}
EXPORT_SYMBOL_GPL(mt76_dma_attach);
+void mt76_dma_wed_reset(struct mt76_dev *dev)
+{
+ struct mt76_mmio *mmio = &dev->mmio;
+
+ if (!test_bit(MT76_STATE_WED_RESET, &dev->phy.state))
+ return;
+
+ complete(&mmio->wed_reset);
+
+ if (!wait_for_completion_timeout(&mmio->wed_reset_complete, 3 * HZ))
+ dev_err(dev->dev, "wed reset complete timeout\n");
+}
+EXPORT_SYMBOL_GPL(mt76_dma_wed_reset);
+
void mt76_dma_cleanup(struct mt76_dev *dev)
{
int i;
@@ -981,16 +1090,23 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
mt76_for_each_q_rx(dev, i) {
struct mt76_queue *q = &dev->q_rx[i];
+ if (mtk_wed_device_active(&dev->mmio.wed) &&
+ mt76_queue_is_wed_rro(q))
+ continue;
+
netif_napi_del(&dev->napi[i]);
mt76_dma_rx_cleanup(dev, q);
page_pool_destroy(q->page_pool);
}
- mt76_free_pending_txwi(dev);
- mt76_free_pending_rxwi(dev);
-
if (mtk_wed_device_active(&dev->mmio.wed))
mtk_wed_device_detach(&dev->mmio.wed);
+
+ if (mtk_wed_device_active(&dev->mmio.wed_hif2))
+ mtk_wed_device_detach(&dev->mmio.wed_hif2);
+
+ mt76_free_pending_txwi(dev);
+ mt76_free_pending_rxwi(dev);
}
EXPORT_SYMBOL_GPL(mt76_dma_cleanup);
diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h
index 1b090d78cd05..c479cc6388ef 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.h
+++ b/drivers/net/wireless/mediatek/mt76/dma.h
@@ -19,12 +19,23 @@
#define MT_DMA_CTL_TO_HOST_A BIT(12)
#define MT_DMA_CTL_DROP BIT(14)
#define MT_DMA_CTL_TOKEN GENMASK(31, 16)
+#define MT_DMA_CTL_SDP1_H GENMASK(19, 16)
+#define MT_DMA_CTL_SDP0_H GENMASK(3, 0)
#define MT_DMA_CTL_WO_DROP BIT(8)
#define MT_DMA_PPE_CPU_REASON GENMASK(15, 11)
#define MT_DMA_PPE_ENTRY GENMASK(30, 16)
+#define MT_DMA_INFO_DMA_FRAG BIT(9)
#define MT_DMA_INFO_PPE_VLD BIT(31)
+#define MT_DMA_CTL_PN_CHK_FAIL BIT(13)
+#define MT_DMA_CTL_VER_MASK BIT(7)
+
+#define MT_DMA_RRO_EN BIT(13)
+
+#define MT_DMA_WED_IND_CMD_CNT 8
+#define MT_DMA_WED_IND_REASON GENMASK(15, 12)
+
#define MT_DMA_HDR_LEN 4
#define MT_RX_INFO_LEN 4
#define MT_FCE_INFO_LEN 4
@@ -37,6 +48,11 @@ struct mt76_desc {
__le32 info;
} __packed __aligned(4);
+struct mt76_wed_rro_desc {
+ __le32 buf0;
+ __le32 buf1;
+} __packed __aligned(4);
+
enum mt76_qsel {
MT_QSEL_MGMT,
MT_QSEL_HCCA,
@@ -54,9 +70,47 @@ enum mt76_mcu_evt_type {
EVT_EVENT_DFS_DETECT_RSP,
};
+enum mt76_dma_wed_ind_reason {
+ MT_DMA_WED_IND_REASON_NORMAL,
+ MT_DMA_WED_IND_REASON_REPEAT,
+ MT_DMA_WED_IND_REASON_OLDPKT,
+};
+
int mt76_dma_rx_poll(struct napi_struct *napi, int budget);
void mt76_dma_attach(struct mt76_dev *dev);
void mt76_dma_cleanup(struct mt76_dev *dev);
int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset);
+void mt76_dma_wed_reset(struct mt76_dev *dev);
+
+static inline void
+mt76_dma_reset_tx_queue(struct mt76_dev *dev, struct mt76_queue *q)
+{
+ dev->queue_ops->reset_q(dev, q);
+ if (mtk_wed_device_active(&dev->mmio.wed))
+ mt76_dma_wed_setup(dev, q, true);
+}
+
+static inline void
+mt76_dma_should_drop_buf(bool *drop, u32 ctrl, u32 buf1, u32 info)
+{
+ if (!drop)
+ return;
+
+ *drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A | MT_DMA_CTL_DROP));
+ if (!(ctrl & MT_DMA_CTL_VER_MASK))
+ return;
+
+ switch (FIELD_GET(MT_DMA_WED_IND_REASON, buf1)) {
+ case MT_DMA_WED_IND_REASON_REPEAT:
+ *drop = true;
+ break;
+ case MT_DMA_WED_IND_REASON_OLDPKT:
+ *drop = !(info & MT_DMA_INFO_DMA_FRAG);
+ break;
+ default:
+ *drop = !!(ctrl & MT_DMA_CTL_PN_CHK_FAIL);
+ break;
+ }
+}
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
index 7725dd6763ef..0bc66cc19acd 100644
--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
@@ -28,7 +28,7 @@ static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len)
return 0;
}
-static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len)
+int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len)
{
#ifdef CONFIG_MTD
struct device_node *np = dev->dev->of_node;
@@ -67,7 +67,7 @@ static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offs
goto out_put_node;
}
- offset = be32_to_cpup(list);
+ offset += be32_to_cpup(list);
ret = mtd_read(mtd, offset, len, &retlen, eep);
put_mtd_device(mtd);
if (mtd_is_bitflip(ret))
@@ -105,8 +105,10 @@ out_put_node:
return -ENOENT;
#endif
}
+EXPORT_SYMBOL_GPL(mt76_get_of_data_from_mtd);
-static int mt76_get_of_epprom_from_nvmem(struct mt76_dev *dev, void *eep, int len)
+int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
+ const char *cell_name, int len)
{
struct device_node *np = dev->dev->of_node;
struct nvmem_cell *cell;
@@ -114,7 +116,7 @@ static int mt76_get_of_epprom_from_nvmem(struct mt76_dev *dev, void *eep, int le
size_t retlen;
int ret = 0;
- cell = of_nvmem_cell_get(np, "eeprom");
+ cell = of_nvmem_cell_get(np, cell_name);
if (IS_ERR(cell))
return PTR_ERR(cell);
@@ -136,8 +138,9 @@ exit:
return ret;
}
+EXPORT_SYMBOL_GPL(mt76_get_of_data_from_nvmem);
-int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
+static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
{
struct device_node *np = dev->dev->of_node;
int ret;
@@ -149,13 +152,12 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
if (!ret)
return 0;
- ret = mt76_get_of_epprom_from_mtd(dev, eep, offset, len);
+ ret = mt76_get_of_data_from_mtd(dev, eep, 0, len);
if (!ret)
return 0;
- return mt76_get_of_epprom_from_nvmem(dev, eep, len);
+ return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
}
-EXPORT_SYMBOL_GPL(mt76_get_of_eeprom);
void
mt76_eeprom_override(struct mt76_phy *phy)
@@ -379,7 +381,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
if (!np)
return target_power;
- txs_delta = mt76_get_txs_delta(np, hweight8(phy->antenna_mask));
+ txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask));
val = mt76_get_of_array(np, "rates-cck", &len, ARRAY_SIZE(dest->cck));
mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val,
@@ -412,6 +414,6 @@ mt76_eeprom_init(struct mt76_dev *dev, int len)
if (!dev->eeprom.data)
return -ENOMEM;
- return !mt76_get_of_eeprom(dev, dev->eeprom.data, 0, len);
+ return !mt76_get_of_eeprom(dev, dev->eeprom.data, len);
}
EXPORT_SYMBOL_GPL(mt76_eeprom_init);
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 51a767121b0d..8a3a90d1bfac 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -197,10 +197,33 @@ static int mt76_led_init(struct mt76_phy *phy)
{
struct mt76_dev *dev = phy->dev;
struct ieee80211_hw *hw = phy->hw;
+ struct device_node *np = dev->dev->of_node;
if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set)
return 0;
+ np = of_get_child_by_name(np, "led");
+ if (np) {
+ if (!of_device_is_available(np)) {
+ of_node_put(np);
+ dev_info(dev->dev,
+ "led registration was explicitly disabled by dts\n");
+ return 0;
+ }
+
+ if (phy == &dev->phy) {
+ int led_pin;
+
+ if (!of_property_read_u32(np, "led-sources", &led_pin))
+ phy->leds.pin = led_pin;
+
+ phy->leds.al =
+ of_property_read_bool(np, "led-active-low");
+ }
+
+ of_node_put(np);
+ }
+
snprintf(phy->leds.name, sizeof(phy->leds.name), "mt76-%s",
wiphy_name(hw->wiphy));
@@ -211,20 +234,8 @@ static int mt76_led_init(struct mt76_phy *phy)
mt76_tpt_blink,
ARRAY_SIZE(mt76_tpt_blink));
- if (phy == &dev->phy) {
- struct device_node *np = dev->dev->of_node;
-
- np = of_get_child_by_name(np, "led");
- if (np) {
- int led_pin;
-
- if (!of_property_read_u32(np, "led-sources", &led_pin))
- phy->leds.pin = led_pin;
- phy->leds.al = of_property_read_bool(np,
- "led-active-low");
- of_node_put(np);
- }
- }
+ dev_info(dev->dev,
+ "registering led '%s'\n", phy->leds.name);
return led_classdev_register(dev->dev, &phy->leds.cdev);
}
@@ -1537,7 +1548,7 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
int *dbm)
{
struct mt76_phy *phy = hw->priv;
- int n_chains = hweight8(phy->antenna_mask);
+ int n_chains = hweight16(phy->chainmask);
int delta = mt76_tx_power_nss_delta(n_chains);
*dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
@@ -1725,7 +1736,7 @@ EXPORT_SYMBOL_GPL(mt76_get_antenna);
struct mt76_queue *
mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
- int ring_base, u32 flags)
+ int ring_base, void *wed, u32 flags)
{
struct mt76_queue *hwq;
int err;
@@ -1735,6 +1746,7 @@ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
return ERR_PTR(-ENOMEM);
hwq->flags = flags;
+ hwq->wed = wed;
err = dev->queue_ops->alloc(dev, hwq, idx, n_desc, 0, ring_base);
if (err < 0)
@@ -1842,3 +1854,19 @@ enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy)
return MT_DFS_STATE_ACTIVE;
}
EXPORT_SYMBOL_GPL(mt76_phy_dfs_state);
+
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+int mt76_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct net_device *netdev, enum tc_setup_type type,
+ void *type_data)
+{
+ struct mt76_phy *phy = hw->priv;
+ struct mtk_wed_device *wed = &phy->dev->mmio.wed;
+
+ if (!mtk_wed_device_active(wed))
+ return -EOPNOTSUPP;
+
+ return mtk_wed_device_setup_tc(wed, netdev, type, type_data);
+}
+EXPORT_SYMBOL_GPL(mt76_net_setup_tc);
+#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
diff --git a/drivers/net/wireless/mediatek/mt76/mmio.c b/drivers/net/wireless/mediatek/mt76/mmio.c
index 86e3d2ac4d0d..c3e0e23e0161 100644
--- a/drivers/net/wireless/mediatek/mt76/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mmio.c
@@ -4,6 +4,7 @@
*/
#include "mt76.h"
+#include "dma.h"
#include "trace.h"
static u32 mt76_mmio_rr(struct mt76_dev *dev, u32 offset)
@@ -84,6 +85,113 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr,
}
EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+{
+ struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+ int i;
+
+ for (i = 0; i < dev->rx_token_size; i++) {
+ struct mt76_txwi_cache *t;
+
+ t = mt76_rx_token_release(dev, i);
+ if (!t || !t->ptr)
+ continue;
+
+ mt76_put_page_pool_buf(t->ptr, false);
+ t->ptr = NULL;
+
+ mt76_put_rxwi(dev, t);
+ }
+
+ mt76_free_pending_rxwi(dev);
+}
+EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
+
+u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+{
+ struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+ struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
+ struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+ int i, len = SKB_WITH_OVERHEAD(q->buf_size);
+ struct mt76_txwi_cache *t = NULL;
+
+ for (i = 0; i < size; i++) {
+ enum dma_data_direction dir;
+ dma_addr_t addr;
+ u32 offset;
+ int token;
+ void *buf;
+
+ t = mt76_get_rxwi(dev);
+ if (!t)
+ goto unmap;
+
+ buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
+ if (!buf)
+ goto unmap;
+
+ addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
+ dir = page_pool_get_dma_dir(q->page_pool);
+ dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
+
+ desc->buf0 = cpu_to_le32(addr);
+ token = mt76_rx_token_consume(dev, buf, t, addr);
+ if (token < 0) {
+ mt76_put_page_pool_buf(buf, false);
+ goto unmap;
+ }
+
+ token = FIELD_PREP(MT_DMA_CTL_TOKEN, token);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ token |= FIELD_PREP(MT_DMA_CTL_SDP0_H, addr >> 32);
+#endif
+ desc->token |= cpu_to_le32(token);
+ desc++;
+ }
+
+ return 0;
+
+unmap:
+ if (t)
+ mt76_put_rxwi(dev, t);
+ mt76_mmio_wed_release_rx_buf(wed);
+
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(mt76_mmio_wed_init_rx_buf);
+
+int mt76_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+{
+ struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+
+ spin_lock_bh(&dev->token_lock);
+ dev->token_size = wed->wlan.token_start;
+ spin_unlock_bh(&dev->token_lock);
+
+ return !wait_event_timeout(dev->tx_wait, !dev->wed_token_count, HZ);
+}
+EXPORT_SYMBOL_GPL(mt76_mmio_wed_offload_enable);
+
+void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+{
+ struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+
+ spin_lock_bh(&dev->token_lock);
+ dev->token_size = dev->drv->token_size;
+ spin_unlock_bh(&dev->token_lock);
+}
+EXPORT_SYMBOL_GPL(mt76_mmio_wed_offload_disable);
+
+void mt76_mmio_wed_reset_complete(struct mtk_wed_device *wed)
+{
+ struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+
+ complete(&dev->mmio.wed_reset_complete);
+}
+EXPORT_SYMBOL_GPL(mt76_mmio_wed_reset_complete);
+#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
+
void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs)
{
static const struct mt76_bus_ops mt76_mmio_ops = {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index ea828ba0b83a..b20c34d5a0f7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -29,15 +29,22 @@
#define MT76_TOKEN_FREE_THR 64
#define MT_QFLAG_WED_RING GENMASK(1, 0)
-#define MT_QFLAG_WED_TYPE GENMASK(3, 2)
-#define MT_QFLAG_WED BIT(4)
+#define MT_QFLAG_WED_TYPE GENMASK(4, 2)
+#define MT_QFLAG_WED BIT(5)
+#define MT_QFLAG_WED_RRO BIT(6)
+#define MT_QFLAG_WED_RRO_EN BIT(7)
#define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \
FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
FIELD_PREP(MT_QFLAG_WED_RING, _n))
+#define __MT_WED_RRO_Q(_type, _n) (MT_QFLAG_WED_RRO | __MT_WED_Q(_type, _n))
+
#define MT_WED_Q_TX(_n) __MT_WED_Q(MT76_WED_Q_TX, _n)
#define MT_WED_Q_RX(_n) __MT_WED_Q(MT76_WED_Q_RX, _n)
#define MT_WED_Q_TXFREE __MT_WED_Q(MT76_WED_Q_TXFREE, 0)
+#define MT_WED_RRO_Q_DATA(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_DATA, _n)
+#define MT_WED_RRO_Q_MSDU_PG(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n)
+#define MT_WED_RRO_Q_IND __MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0)
struct mt76_dev;
struct mt76_phy;
@@ -59,6 +66,9 @@ enum mt76_wed_type {
MT76_WED_Q_TX,
MT76_WED_Q_TXFREE,
MT76_WED_Q_RX,
+ MT76_WED_RRO_Q_DATA,
+ MT76_WED_RRO_Q_MSDU_PG,
+ MT76_WED_RRO_Q_IND,
};
struct mt76_bus_ops {
@@ -107,6 +117,16 @@ enum mt76_rxq_id {
MT_RXQ_MAIN_WA,
MT_RXQ_BAND2,
MT_RXQ_BAND2_WA,
+ MT_RXQ_RRO_BAND0,
+ MT_RXQ_RRO_BAND1,
+ MT_RXQ_RRO_BAND2,
+ MT_RXQ_MSDU_PAGE_BAND0,
+ MT_RXQ_MSDU_PAGE_BAND1,
+ MT_RXQ_MSDU_PAGE_BAND2,
+ MT_RXQ_TXFREE_BAND0,
+ MT_RXQ_TXFREE_BAND1,
+ MT_RXQ_TXFREE_BAND2,
+ MT_RXQ_RRO_IND,
__MT_RXQ_MAX
};
@@ -163,7 +183,7 @@ struct mt76_queue_entry {
struct urb *urb;
int buf_sz;
};
- u32 dma_addr[2];
+ dma_addr_t dma_addr[2];
u16 dma_len[2];
u16 wcid;
bool skip_buf0:1;
@@ -184,6 +204,7 @@ struct mt76_queue {
spinlock_t lock;
spinlock_t cleanup_lock;
struct mt76_queue_entry *entry;
+ struct mt76_rro_desc *rro_desc;
struct mt76_desc *desc;
u16 first;
@@ -197,8 +218,9 @@ struct mt76_queue {
u8 buf_offset;
u8 hw_idx;
- u8 flags;
+ u16 flags;
+ struct mtk_wed_device *wed;
u32 wed_regs;
dma_addr_t desc_dma;
@@ -353,6 +375,17 @@ struct mt76_txq {
bool aggr;
};
+struct mt76_wed_rro_ind {
+ u32 se_id : 12;
+ u32 rsv : 4;
+ u32 start_sn : 12;
+ u32 ind_reason : 4;
+ u32 ind_cnt : 13;
+ u32 win_sz : 3;
+ u32 rsv2 : 13;
+ u32 magic_cnt : 3;
+};
+
struct mt76_txwi_cache {
struct list_head list;
dma_addr_t dma_addr;
@@ -371,6 +404,7 @@ struct mt76_rx_tid {
spinlock_t lock;
struct delayed_work reorder_work;
+ u16 id;
u16 head;
u16 size;
u16 nframes;
@@ -575,8 +609,7 @@ struct mt76_sdio {
struct mt76_worker txrx_worker;
struct mt76_worker status_worker;
struct mt76_worker net_worker;
-
- struct work_struct stat_work;
+ struct mt76_worker stat_worker;
u8 *xmit_buf;
u32 xmit_buf_sz;
@@ -603,6 +636,7 @@ struct mt76_mmio {
u32 irqmask;
struct mtk_wed_device wed;
+ struct mtk_wed_device wed_hif2;
struct completion wed_reset;
struct completion wed_reset_complete;
};
@@ -1047,6 +1081,12 @@ bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs);
void mt76_pci_disable_aspm(struct pci_dev *pdev);
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+int mt76_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct net_device *netdev, enum tc_setup_type type,
+ void *type_data);
+#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
+
static inline u16 mt76_chip(struct mt76_dev *dev)
{
return dev->rev >> 16;
@@ -1057,6 +1097,14 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
return dev->rev & 0xffff;
}
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size);
+void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed);
+int mt76_mmio_wed_offload_enable(struct mtk_wed_device *wed);
+void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed);
+void mt76_mmio_wed_reset_complete(struct mtk_wed_device *wed);
+#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
+
#define mt76xx_chip(dev) mt76_chip(&((dev)->mt76))
#define mt76xx_rev(dev) mt76_rev(&((dev)->mt76))
@@ -1102,19 +1150,22 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
int mt76_eeprom_init(struct mt76_dev *dev, int len);
void mt76_eeprom_override(struct mt76_phy *phy);
-int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len);
+int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
+int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
+ const char *cell_name, int len);
struct mt76_queue *
mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
- int ring_base, u32 flags);
+ int ring_base, void *wed, u32 flags);
u16 mt76_calculate_default_rate(struct mt76_phy *phy,
struct ieee80211_vif *vif, int rateidx);
static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx,
- int n_desc, int ring_base, u32 flags)
+ int n_desc, int ring_base, void *wed,
+ u32 flags)
{
struct mt76_queue *q;
- q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, flags);
+ q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, wed, flags);
if (IS_ERR(q))
return PTR_ERR(q);
@@ -1128,7 +1179,7 @@ static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx,
{
struct mt76_queue *q;
- q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, 0);
+ q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, NULL, 0);
if (IS_ERR(q))
return PTR_ERR(q);
@@ -1547,10 +1598,38 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
struct mt76_power_limits *dest,
s8 target_power);
-static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q)
{
return (q->flags & MT_QFLAG_WED) &&
- FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
+ FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
+}
+
+static inline bool mt76_queue_is_wed_rro(struct mt76_queue *q)
+{
+ return q->flags & MT_QFLAG_WED_RRO;
+}
+
+static inline bool mt76_queue_is_wed_rro_ind(struct mt76_queue *q)
+{
+ return mt76_queue_is_wed_rro(q) &&
+ FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_IND;
+}
+
+static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q)
+{
+ return mt76_queue_is_wed_rro(q) &&
+ (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA ||
+ FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG);
+}
+
+static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+{
+ if (!(q->flags & MT_QFLAG_WED))
+ return false;
+
+ return FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX ||
+ mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q);
+
}
struct mt76_txwi_cache *
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index 03ba11a61c90..7a2f5d38562b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -173,13 +173,14 @@ int mt7603_dma_init(struct mt7603_dev *dev)
for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
- MT7603_TX_RING_SIZE, MT_TX_RING_BASE, 0);
+ MT7603_TX_RING_SIZE, MT_TX_RING_BASE,
+ NULL, 0);
if (ret)
return ret;
}
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
- MT7603_PSD_RING_SIZE, MT_TX_RING_BASE, 0);
+ MT7603_PSD_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
@@ -189,12 +190,12 @@ int mt7603_dma_init(struct mt7603_dev *dev)
return ret;
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_BEACON, MT_TX_HW_QUEUE_BCN,
- MT_MCU_RING_SIZE, MT_TX_RING_BASE, 0);
+ MT_MCU_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_CAB, MT_TX_HW_QUEUE_BMC,
- MT_MCU_RING_SIZE, MT_TX_RING_BASE, 0);
+ MT_MCU_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/soc.c b/drivers/net/wireless/mediatek/mt76/mt7603/soc.c
index ba927033bbe8..ec02148a7f1f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/soc.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/soc.c
@@ -52,15 +52,12 @@ error:
return ret;
}
-static int
-mt76_wmac_remove(struct platform_device *pdev)
+static void mt76_wmac_remove(struct platform_device *pdev)
{
struct mt76_dev *mdev = platform_get_drvdata(pdev);
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
mt7603_unregister_device(dev);
-
- return 0;
}
static const struct of_device_id of_wmac_match[] = {
@@ -74,7 +71,7 @@ MODULE_FIRMWARE(MT7628_FIRMWARE_E2);
struct platform_driver mt76_wmac_driver = {
.probe = mt76_wmac_probe,
- .remove = mt76_wmac_remove,
+ .remove_new = mt76_wmac_remove,
.driver = {
.name = "mt76_wmac",
.of_match_table = of_wmac_match,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
index 0ce01ccc5dce..e7135b2f1742 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
@@ -26,14 +26,14 @@ mt7622_init_tx_queues_multi(struct mt7615_dev *dev)
for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
MT7615_TX_RING_SIZE / 2,
- MT_TX_RING_BASE, 0);
+ MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
}
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT7622_TXQ_MGMT,
MT7615_TX_MGMT_RING_SIZE,
- MT_TX_RING_BASE, 0);
+ MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
@@ -55,7 +55,7 @@ mt7615_init_tx_queues(struct mt7615_dev *dev)
return mt7622_init_tx_queues_multi(dev);
ret = mt76_connac_init_tx_queues(&dev->mphy, 0, MT7615_TX_RING_SIZE,
- MT_TX_RING_BASE, 0);
+ MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
index 955974a82180..ae34d019e588 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
@@ -453,7 +453,7 @@ mt7615_mcu_scan_event(struct mt7615_dev *dev, struct sk_buff *skb)
else
mphy = &dev->mt76.phy;
- phy = (struct mt7615_phy *)mphy->priv;
+ phy = mphy->priv;
spin_lock_bh(&dev->mt76.lock);
__skb_queue_tail(&phy->scan_event_list, skb);
@@ -481,7 +481,7 @@ mt7615_mcu_roc_event(struct mt7615_dev *dev, struct sk_buff *skb)
ieee80211_ready_on_channel(mphy->hw);
- phy = (struct mt7615_phy *)mphy->priv;
+ phy = mphy->priv;
phy->roc_grant = true;
wake_up(&phy->roc_wait);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index fc547a0031ea..67cedd2555f9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -204,8 +204,8 @@ static int mt7663s_suspend(struct device *dev)
mt76_worker_disable(&mdev->mt76.sdio.txrx_worker);
mt76_worker_disable(&mdev->mt76.sdio.status_worker);
mt76_worker_disable(&mdev->mt76.sdio.net_worker);
+ mt76_worker_disable(&mdev->mt76.sdio.stat_worker);
- cancel_work_sync(&mdev->mt76.sdio.stat_work);
clear_bit(MT76_READING_STATS, &mdev->mphy.state);
mt76_tx_status_check(&mdev->mt76, true);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/soc.c b/drivers/net/wireless/mediatek/mt76/mt7615/soc.c
index f13d1b418742..12e3e4a91d27 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/soc.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/soc.c
@@ -45,13 +45,11 @@ static int mt7622_wmac_probe(struct platform_device *pdev)
return mt7615_mmio_probe(&pdev->dev, mem_base, irq, mt7615e_reg_map);
}
-static int mt7622_wmac_remove(struct platform_device *pdev)
+static void mt7622_wmac_remove(struct platform_device *pdev)
{
struct mt7615_dev *dev = platform_get_drvdata(pdev);
mt7615_unregister_device(dev);
-
- return 0;
}
static const struct of_device_id mt7622_wmac_of_match[] = {
@@ -65,7 +63,7 @@ struct platform_driver mt7622_wmac_driver = {
.of_match_table = mt7622_wmac_of_match,
},
.probe = mt7622_wmac_probe,
- .remove = mt7622_wmac_remove,
+ .remove_new = mt7622_wmac_remove,
};
MODULE_FIRMWARE(MT7622_FIRMWARE_N9);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index 1f29d8cd900c..fdde3d70b300 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -222,6 +222,11 @@ static inline bool is_mt7996(struct mt76_dev *dev)
return mt76_chip(dev) == 0x7990;
}
+static inline bool is_mt7992(struct mt76_dev *dev)
+{
+ return mt76_chip(dev) == 0x7992;
+}
+
static inline bool is_mt7622(struct mt76_dev *dev)
{
if (!IS_ENABLED(CONFIG_MT7622_WMAC))
@@ -391,7 +396,8 @@ mt76_connac_mutex_release(struct mt76_dev *dev, struct mt76_connac_pm *pm)
void mt76_connac_gen_ppe_thresh(u8 *he_ppet, int nss);
int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
- int ring_base, u32 flags);
+ int ring_base, void *wed, u32 flags);
+
void mt76_connac_write_hw_txp(struct mt76_dev *dev,
struct mt76_tx_info *tx_info,
void *txp_ptr, u32 id);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
index 2250252b2047..83dcd964bfd0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
@@ -239,11 +239,13 @@ enum tx_mgnt_type {
#define MT_TXD6_TX_SRC GENMASK(31, 30)
#define MT_TXD6_VTA BIT(28)
-#define MT_TXD6_BW GENMASK(25, 22)
+#define MT_TXD6_FIXED_BW BIT(25)
+#define MT_TXD6_BW GENMASK(24, 22)
#define MT_TXD6_TX_RATE GENMASK(21, 16)
#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15)
#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10)
#define MT_TXD6_MSDU_CNT GENMASK(9, 4)
+#define MT_TXD6_MSDU_CNT_V2 GENMASK(15, 10)
#define MT_TXD6_DIS_MAT BIT(3)
#define MT_TXD6_DAS BIT(2)
#define MT_TXD6_AMSDU_CAP BIT(1)
@@ -259,6 +261,9 @@ enum tx_mgnt_type {
#define MT_TXD9_WLAN_IDX GENMASK(23, 8)
+#define MT_TXP_BUF_LEN GENMASK(11, 0)
+#define MT_TXP_DMA_ADDR_H GENMASK(15, 12)
+
#define MT_TX_RATE_STBC BIT(14)
#define MT_TX_RATE_NSS GENMASK(13, 10)
#define MT_TX_RATE_MODE GENMASK(9, 6)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
index 93402d2c2538..c7914643e9c0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
@@ -256,11 +256,12 @@ void mt76_connac_txp_skb_unmap(struct mt76_dev *dev,
EXPORT_SYMBOL_GPL(mt76_connac_txp_skb_unmap);
int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
- int ring_base, u32 flags)
+ int ring_base, void *wed, u32 flags)
{
int i, err;
- err = mt76_init_tx_queue(phy, 0, idx, n_desc, ring_base, flags);
+ err = mt76_init_tx_queue(phy, 0, idx, n_desc, ring_base,
+ wed, flags);
if (err < 0)
return err;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index ae6bf3c968df..96494ba2fdf7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -67,7 +67,8 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
(is_mt7921(dev) && addr == 0x900000) ||
(is_mt7925(dev) && addr == 0x900000) ||
- (is_mt7996(dev) && addr == 0x900000))
+ (is_mt7996(dev) && addr == 0x900000) ||
+ (is_mt7992(dev) && addr == 0x900000))
cmd = MCU_CMD(PATCH_START_REQ);
else
cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ);
@@ -1359,7 +1360,7 @@ u8 mt76_connac_get_phy_mode_ext(struct mt76_phy *phy, struct ieee80211_vif *vif,
sband = phy->hw->wiphy->bands[band];
eht_cap = ieee80211_get_eht_iftype_cap(sband, vif->type);
- if (!eht_cap || !eht_cap->has_eht)
+ if (!eht_cap || !eht_cap->has_eht || !vif->bss_conf.eht_support)
return mode;
switch (band) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 0563b1b22f48..ae6d0179727d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -416,6 +416,14 @@ struct sta_rec_he_6g_capa {
u8 rsv[2];
} __packed;
+struct sta_rec_pn_info {
+ __le16 tag;
+ __le16 len;
+ u8 pn[6];
+ u8 tsc_type;
+ u8 rsv;
+} __packed;
+
struct sec_key {
u8 cipher_id;
u8 cipher_len;
@@ -768,6 +776,7 @@ struct wtbl_raw {
sizeof(struct sta_rec_sec) + \
sizeof(struct sta_rec_ra_fixed) + \
sizeof(struct sta_rec_he_6g_capa) + \
+ sizeof(struct sta_rec_pn_info) + \
sizeof(struct tlv) + \
MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)
@@ -798,6 +807,7 @@ enum {
STA_REC_HE_V2 = 0x19,
STA_REC_MLD = 0x20,
STA_REC_EHT = 0x22,
+ STA_REC_PN_INFO = 0x26,
STA_REC_HDRT = 0x28,
STA_REC_HDR_TRANS = 0x2B,
STA_REC_MAX_NUM
@@ -1021,7 +1031,9 @@ enum {
MCU_UNI_EVENT_RDD_REPORT = 0x11,
MCU_UNI_EVENT_ROC = 0x27,
MCU_UNI_EVENT_TX_DONE = 0x2d,
+ MCU_UNI_EVENT_THERMAL = 0x35,
MCU_UNI_EVENT_NIC_CAPAB = 0x43,
+ MCU_UNI_EVENT_WED_RRO = 0x57,
MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
};
@@ -1088,6 +1100,13 @@ enum mcu_cipher_type {
MCU_CIPHER_GCMP_256,
MCU_CIPHER_WAPI,
MCU_CIPHER_BIP_CMAC_128,
+ MCU_CIPHER_BIP_CMAC_256,
+ MCU_CIPHER_BCN_PROT_CMAC_128,
+ MCU_CIPHER_BCN_PROT_CMAC_256,
+ MCU_CIPHER_BCN_PROT_GMAC_128,
+ MCU_CIPHER_BCN_PROT_GMAC_256,
+ MCU_CIPHER_BIP_GMAC_128,
+ MCU_CIPHER_BIP_GMAC_256,
};
enum {
@@ -1240,6 +1259,7 @@ enum {
MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
MCU_UNI_CMD_THERMAL = 0x35,
MCU_UNI_CMD_VOW = 0x37,
+ MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
MCU_UNI_CMD_RRO = 0x57,
MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
MCU_UNI_CMD_PER_STA_INFO = 0x6d,
@@ -1307,6 +1327,7 @@ enum {
UNI_BSS_INFO_RATE = 11,
UNI_BSS_INFO_QBSS = 15,
UNI_BSS_INFO_SEC = 16,
+ UNI_BSS_INFO_BCN_PROT = 17,
UNI_BSS_INFO_TXCMD = 18,
UNI_BSS_INFO_UAPSD = 19,
UNI_BSS_INFO_PS = 21,
@@ -1325,7 +1346,7 @@ enum {
};
enum UNI_ALL_STA_INFO_TAG {
- UNI_ALL_STA_TX_RATE,
+ UNI_ALL_STA_TXRX_RATE,
UNI_ALL_STA_TX_STAT,
UNI_ALL_STA_TXRX_ADM_STAT,
UNI_ALL_STA_TXRX_AIR_TIME,
@@ -1768,6 +1789,12 @@ mt76_connac_mcu_get_cipher(int cipher)
return MCU_CIPHER_GCMP;
case WLAN_CIPHER_SUITE_GCMP_256:
return MCU_CIPHER_GCMP_256;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ return MCU_CIPHER_BIP_GMAC_128;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ return MCU_CIPHER_BIP_GMAC_256;
+ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+ return MCU_CIPHER_BIP_CMAC_256;
case WLAN_CIPHER_SUITE_SMS4:
return MCU_CIPHER_WAPI;
default:
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 9b5e3fb7b0df..e5ad635d3c56 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -199,13 +199,14 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
ret = mt76_init_tx_queue(&dev->mphy, i, mt76_ac_to_hwq(i),
MT76x02_TX_RING_SIZE,
- MT_TX_RING_BASE, 0);
+ MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
}
ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
- MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE, 0);
+ MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE,
+ NULL, 0);
if (ret)
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
index 59a44d79aaed..c91a1c54027f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
@@ -9,18 +9,20 @@ static int
mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc, int ring_base)
{
struct mt7915_dev *dev = phy->dev;
+ struct mtk_wed_device *wed = NULL;
- if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
if (is_mt798x(&dev->mt76))
ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
else
ring_base = MT_WED_TX_RING_BASE;
idx -= MT_TXQ_ID(0);
+ wed = &dev->mt76.mmio.wed;
}
return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc, ring_base,
- MT_WED_Q_TX(idx));
+ wed, MT_WED_Q_TX(idx));
}
static int mt7915_poll_tx(struct napi_struct *napi, int budget)
@@ -492,7 +494,8 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
if (mtk_wed_device_active(&mdev->mmio.wed) && is_mt7915(mdev)) {
wa_rx_base = MT_WED_RX_RING_BASE;
wa_rx_idx = MT7915_RXQ_MCU_WA;
- dev->mt76.q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE;
+ mdev->q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE;
+ mdev->q_rx[MT_RXQ_MCU_WA].wed = &mdev->mmio.wed;
} else {
wa_rx_base = MT_RXQ_RING_BASE(MT_RXQ_MCU_WA);
wa_rx_idx = MT_RXQ_ID(MT_RXQ_MCU_WA);
@@ -507,9 +510,10 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
if (!dev->phy.mt76->band_idx) {
if (mtk_wed_device_active(&mdev->mmio.wed) &&
mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
- dev->mt76.q_rx[MT_RXQ_MAIN].flags =
+ mdev->q_rx[MT_RXQ_MAIN].flags =
MT_WED_Q_RX(MT7915_RXQ_BAND0);
dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
+ mdev->q_rx[MT_RXQ_MAIN].wed = &mdev->mmio.wed;
}
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
@@ -528,6 +532,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
if (mtk_wed_device_active(&mdev->mmio.wed)) {
mdev->q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
+ mdev->q_rx[MT_RXQ_MAIN_WA].wed = &mdev->mmio.wed;
if (is_mt7916(mdev)) {
wa_rx_base = MT_WED_RX_RING_BASE;
wa_rx_idx = MT7915_RXQ_MCU_WA;
@@ -544,9 +549,10 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
if (dev->dbdc_support || dev->phy.mt76->band_idx) {
if (mtk_wed_device_active(&mdev->mmio.wed) &&
mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
- dev->mt76.q_rx[MT_RXQ_BAND1].flags =
+ mdev->q_rx[MT_RXQ_BAND1].flags =
MT_WED_Q_RX(MT7915_RXQ_BAND1);
dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
+ mdev->q_rx[MT_RXQ_BAND1].wed = &mdev->mmio.wed;
}
/* rx data queue for band1 */
@@ -581,28 +587,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
return 0;
}
-static void mt7915_dma_wed_reset(struct mt7915_dev *dev)
-{
- struct mt76_dev *mdev = &dev->mt76;
-
- if (!test_bit(MT76_STATE_WED_RESET, &dev->mphy.state))
- return;
-
- complete(&mdev->mmio.wed_reset);
-
- if (!wait_for_completion_timeout(&dev->mt76.mmio.wed_reset_complete,
- 3 * HZ))
- dev_err(dev->mt76.dev, "wed reset complete timeout\n");
-}
-
-static void
-mt7915_dma_reset_tx_queue(struct mt7915_dev *dev, struct mt76_queue *q)
-{
- mt76_queue_reset(dev, q);
- if (mtk_wed_device_active(&dev->mt76.mmio.wed))
- mt76_dma_wed_setup(&dev->mt76, q, true);
-}
-
int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
{
struct mt76_phy *mphy_ext = dev->mt76.phys[MT_BAND1];
@@ -630,20 +614,20 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
mtk_wed_device_dma_reset(wed);
mt7915_dma_disable(dev, force);
- mt7915_dma_wed_reset(dev);
+ mt76_dma_wed_reset(&dev->mt76);
/* reset hw queues */
for (i = 0; i < __MT_TXQ_MAX; i++) {
- mt7915_dma_reset_tx_queue(dev, dev->mphy.q_tx[i]);
+ mt76_dma_reset_tx_queue(&dev->mt76, dev->mphy.q_tx[i]);
if (mphy_ext)
- mt7915_dma_reset_tx_queue(dev, mphy_ext->q_tx[i]);
+ mt76_dma_reset_tx_queue(&dev->mt76, mphy_ext->q_tx[i]);
}
for (i = 0; i < __MT_MCUQ_MAX; i++)
mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
mt76_for_each_q_rx(&dev->mt76, i) {
- if (dev->mt76.q_rx[i].flags == MT_WED_Q_TXFREE)
+ if (mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i]))
continue;
mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
index 76be7308460b..3bb2643d1b26 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
@@ -11,6 +11,7 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
u8 *eeprom = mdev->eeprom.data;
u32 val = eeprom[MT_EE_DO_PRE_CAL];
u32 offs;
+ int ret;
if (!dev->flash_mode)
return 0;
@@ -25,7 +26,11 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
- return mt76_get_of_eeprom(mdev, dev->cal, offs, val);
+ ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, val);
+ if (!ret)
+ return ret;
+
+ return mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", val);
}
static int mt7915_check_eeprom(struct mt7915_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
index f3e56817d36e..adc26a222823 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
@@ -144,7 +144,8 @@ static inline bool
mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
{
u8 *eep = dev->mt76.eeprom.data;
- u8 val = eep[MT_EE_WIFI_CONF + 7];
+ u8 offs = is_mt7981(&dev->mt76) ? 8 : 7;
+ u8 val = eep[MT_EE_WIFI_CONF + offs];
if (band == NL80211_BAND_2GHZ)
return val & MT_EE_WIFI_CONF7_TSSI0_2G;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 81478289f17e..cea2f6d9050a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -275,10 +275,11 @@ static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
mt7915_led_set_config(led_cdev, 0xff, 0);
}
-void mt7915_init_txpower(struct mt7915_dev *dev,
- struct ieee80211_supported_band *sband)
+static void __mt7915_init_txpower(struct mt7915_phy *phy,
+ struct ieee80211_supported_band *sband)
{
- int i, n_chains = hweight8(dev->mphy.antenna_mask);
+ struct mt7915_dev *dev = phy->dev;
+ int i, n_chains = hweight16(phy->mt76->chainmask);
int nss_delta = mt76_tx_power_nss_delta(n_chains);
int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);
struct mt76_power_limits limits;
@@ -296,7 +297,7 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
}
target_power += pwr_delta;
- target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
+ target_power = mt76_get_rate_power_limits(phy->mt76, chan,
&limits,
target_power);
target_power += nss_delta;
@@ -307,6 +308,19 @@ void mt7915_init_txpower(struct mt7915_dev *dev,
}
}
+void mt7915_init_txpower(struct mt7915_phy *phy)
+{
+ if (!phy)
+ return;
+
+ if (phy->mt76->cap.has_2ghz)
+ __mt7915_init_txpower(phy, &phy->mt76->sband_2g.sband);
+ if (phy->mt76->cap.has_5ghz)
+ __mt7915_init_txpower(phy, &phy->mt76->sband_5g.sband);
+ if (phy->mt76->cap.has_6ghz)
+ __mt7915_init_txpower(phy, &phy->mt76->sband_6g.sband);
+}
+
static void
mt7915_regd_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
@@ -322,9 +336,7 @@ mt7915_regd_notifier(struct wiphy *wiphy,
if (dev->mt76.region == NL80211_DFS_UNSET)
mt7915_mcu_rdd_background_enable(phy, NULL);
- mt7915_init_txpower(dev, &mphy->sband_2g.sband);
- mt7915_init_txpower(dev, &mphy->sband_5g.sband);
- mt7915_init_txpower(dev, &mphy->sband_6g.sband);
+ mt7915_init_txpower(phy);
mphy->dfs_state = MT_DFS_STATE_UNKNOWN;
mt7915_dfs_init_radar_detector(phy);
@@ -442,6 +454,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
mt76_set_stream_caps(phy->mt76, true);
mt7915_set_stream_vht_txbf_caps(phy);
mt7915_set_stream_he_caps(phy);
+ mt7915_init_txpower(phy);
wiphy->available_antennas_rx = phy->mt76->antenna_mask;
wiphy->available_antennas_tx = phy->mt76->antenna_mask;
@@ -703,9 +716,6 @@ static void mt7915_init_work(struct work_struct *work)
mt7915_mcu_set_eeprom(dev);
mt7915_mac_init(dev);
- mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
- mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
- mt7915_init_txpower(dev, &dev->mphy.sband_6g.sband);
mt7915_txbf_init(dev);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 2222fb9aa103..b01edbed969c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1247,7 +1247,7 @@ mt7915_phy_get_nf(struct mt7915_phy *phy, int idx)
void mt7915_update_channel(struct mt76_phy *mphy)
{
- struct mt7915_phy *phy = (struct mt7915_phy *)mphy->priv;
+ struct mt7915_phy *phy = mphy->priv;
struct mt76_channel_state *state = mphy->chan_state;
int nf;
@@ -1401,8 +1401,8 @@ mt7915_mac_restart(struct mt7915_dev *dev)
goto out;
mt7915_mac_init(dev);
- mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
- mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
+ mt7915_init_txpower(&dev->phy);
+ mt7915_init_txpower(phy2);
ret = mt7915_txbf_init(dev);
if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index a3fd54cc1911..df2d4279790d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1059,8 +1059,9 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
phy->mt76->antenna_mask = tx_ant;
- /* handle a variant of mt7916 which has 3T3R but nss2 on 5 GHz band */
- if (is_mt7916(&dev->mt76) && band && hweight8(tx_ant) == max_nss)
+ /* handle a variant of mt7916/mt7981 which has 3T3R but nss2 on 5 GHz band */
+ if ((is_mt7916(&dev->mt76) || is_mt7981(&dev->mt76)) &&
+ band && hweight8(tx_ant) == max_nss)
phy->mt76->chainmask = (dev->chainmask >> chainshift) << chainshift;
else
phy->mt76->chainmask = tx_ant << (chainshift * band);
@@ -1653,20 +1654,6 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
return 0;
}
-
-static int
-mt7915_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct net_device *netdev, enum tc_setup_type type,
- void *type_data)
-{
- struct mt7915_dev *dev = mt7915_hw_dev(hw);
- struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-
- if (!mtk_wed_device_active(wed))
- return -EOPNOTSUPP;
-
- return mtk_wed_device_setup_tc(wed, netdev, type, type_data);
-}
#endif
const struct ieee80211_ops mt7915_ops = {
@@ -1721,6 +1708,6 @@ const struct ieee80211_ops mt7915_ops = {
.set_radar_background = mt7915_set_radar_background,
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
.net_fill_forward_path = mt7915_net_fill_forward_path,
- .net_setup_tc = mt7915_net_setup_tc,
+ .net_setup_tc = mt76_net_setup_tc,
#endif
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index b22f06d4411a..c67c4f6ca2aa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -269,7 +269,7 @@ mt7915_mcu_rx_thermal_notify(struct mt7915_dev *dev, struct sk_buff *skb)
dev->mt76.phys[MT_BAND1])
mphy = dev->mt76.phys[MT_BAND1];
- phy = (struct mt7915_phy *)mphy->priv;
+ phy = mphy->priv;
phy->throttle_state = t->ctrl.duty.duty_cycle;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 1592b5d6751a..b41ac4aaced7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -519,7 +519,7 @@ static inline s8
mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
{
struct mt76_phy *mphy = phy->mt76;
- int n_chains = hweight8(mphy->antenna_mask);
+ int n_chains = hweight16(mphy->chainmask);
txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * 2);
txpower -= mt76_tx_power_nss_delta(n_chains);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
index e7d8e03f826f..aff4f21e843d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
@@ -542,105 +542,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
}
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
-{
- struct mt7915_dev *dev;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-
- spin_lock_bh(&dev->mt76.token_lock);
- dev->mt76.token_size = wed->wlan.token_start;
- spin_unlock_bh(&dev->mt76.token_lock);
-
- return !wait_event_timeout(dev->mt76.tx_wait,
- !dev->mt76.wed_token_count, HZ);
-}
-
-static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
-{
- struct mt7915_dev *dev;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-
- spin_lock_bh(&dev->mt76.token_lock);
- dev->mt76.token_size = MT7915_TOKEN_SIZE;
- spin_unlock_bh(&dev->mt76.token_lock);
-}
-
-static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
-{
- struct mt7915_dev *dev;
- int i;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- for (i = 0; i < dev->mt76.rx_token_size; i++) {
- struct mt76_txwi_cache *t;
-
- t = mt76_rx_token_release(&dev->mt76, i);
- if (!t || !t->ptr)
- continue;
-
- mt76_put_page_pool_buf(t->ptr, false);
- t->ptr = NULL;
-
- mt76_put_rxwi(&dev->mt76, t);
- }
-
- mt76_free_pending_rxwi(&dev->mt76);
-}
-
-static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
-{
- struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
- struct mt76_txwi_cache *t = NULL;
- struct mt7915_dev *dev;
- struct mt76_queue *q;
- int i, len;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- q = &dev->mt76.q_rx[MT_RXQ_MAIN];
- len = SKB_WITH_OVERHEAD(q->buf_size);
-
- for (i = 0; i < size; i++) {
- enum dma_data_direction dir;
- dma_addr_t addr;
- u32 offset;
- int token;
- void *buf;
-
- t = mt76_get_rxwi(&dev->mt76);
- if (!t)
- goto unmap;
-
- buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
- if (!buf)
- goto unmap;
-
- addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
- dir = page_pool_get_dma_dir(q->page_pool);
- dma_sync_single_for_device(dev->mt76.dma_dev, addr, len, dir);
-
- desc->buf0 = cpu_to_le32(addr);
- token = mt76_rx_token_consume(&dev->mt76, buf, t, addr);
- if (token < 0) {
- mt76_put_page_pool_buf(buf, false);
- goto unmap;
- }
-
- desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
- token));
- desc++;
- }
-
- return 0;
-
-unmap:
- if (t)
- mt76_put_rxwi(&dev->mt76, t);
- mt7915_mmio_wed_release_rx_buf(wed);
- return -ENOMEM;
-}
-
static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
struct mtk_wed_wo_rx_stats *stats)
{
@@ -694,13 +595,6 @@ out:
return ret;
}
-
-static void mt7915_mmio_wed_reset_complete(struct mtk_wed_device *wed)
-{
- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
-
- complete(&dev->mmio.wed_reset_complete);
-}
#endif
int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
@@ -742,7 +636,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
if (!res)
- return -ENOMEM;
+ return 0;
wed->wlan.platform_dev = plat_dev;
wed->wlan.bus_type = MTK_WED_BUS_AXI;
@@ -778,13 +672,13 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
}
wed->wlan.init_buf = mt7915_wed_init_buf;
- wed->wlan.offload_enable = mt7915_mmio_wed_offload_enable;
- wed->wlan.offload_disable = mt7915_mmio_wed_offload_disable;
- wed->wlan.init_rx_buf = mt7915_mmio_wed_init_rx_buf;
- wed->wlan.release_rx_buf = mt7915_mmio_wed_release_rx_buf;
+ wed->wlan.offload_enable = mt76_mmio_wed_offload_enable;
+ wed->wlan.offload_disable = mt76_mmio_wed_offload_disable;
+ wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
+ wed->wlan.release_rx_buf = mt76_mmio_wed_release_rx_buf;
wed->wlan.update_wo_rx_stats = mt7915_mmio_wed_update_rx_stats;
wed->wlan.reset = mt7915_mmio_wed_reset;
- wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete;
+ wed->wlan.reset_complete = mt76_mmio_wed_reset_complete;
dev->mt76.rx_token_size = wed->wlan.rx_npkt;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index d317c523b23f..4727d9c7b11d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -425,8 +425,7 @@ void mt7915_dma_cleanup(struct mt7915_dev *dev);
int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset);
int mt7915_txbf_init(struct mt7915_dev *dev);
-void mt7915_init_txpower(struct mt7915_dev *dev,
- struct ieee80211_supported_band *sband);
+void mt7915_init_txpower(struct mt7915_phy *phy);
void mt7915_reset(struct mt7915_dev *dev);
int mt7915_run(struct ieee80211_hw *hw);
int mt7915_mcu_init(struct mt7915_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c
index 06e3d9db996c..8b4809703efc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c
@@ -1282,13 +1282,11 @@ free_device:
return ret;
}
-static int mt798x_wmac_remove(struct platform_device *pdev)
+static void mt798x_wmac_remove(struct platform_device *pdev)
{
struct mt7915_dev *dev = platform_get_drvdata(pdev);
mt7915_unregister_device(dev);
-
- return 0;
}
static const struct of_device_id mt798x_wmac_of_match[] = {
@@ -1305,7 +1303,7 @@ struct platform_driver mt798x_wmac_driver = {
.of_match_table = mt798x_wmac_of_match,
},
.probe = mt798x_wmac_probe,
- .remove = mt798x_wmac_remove,
+ .remove_new = mt798x_wmac_remove,
};
MODULE_FIRMWARE(MT7986_FIRMWARE_WA);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
index 7d6a9d746011..48433c6d5e7d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
@@ -110,24 +110,37 @@ mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)
}
}
+void mt7921_regd_update(struct mt792x_dev *dev)
+{
+ struct mt76_dev *mdev = &dev->mt76;
+ struct ieee80211_hw *hw = mdev->hw;
+ struct wiphy *wiphy = hw->wiphy;
+
+ mt7921_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env);
+ mt7921_regd_channel_update(wiphy, dev);
+ mt76_connac_mcu_set_channel_domain(hw->priv);
+ mt7921_set_tx_sar_pwr(hw, NULL);
+}
+EXPORT_SYMBOL_GPL(mt7921_regd_update);
+
static void
mt7921_regd_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct mt792x_dev *dev = mt792x_hw_dev(hw);
+ struct mt76_connac_pm *pm = &dev->pm;
memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));
dev->mt76.region = request->dfs_region;
dev->country_ie_env = request->country_ie_env;
+ if (pm->suspended)
+ return;
+
mt792x_mutex_acquire(dev);
- mt7921_mcu_set_clc(dev, request->alpha2, request->country_ie_env);
- mt76_connac_mcu_set_channel_domain(hw->priv);
- mt7921_set_tx_sar_pwr(hw, NULL);
+ mt7921_regd_update(dev);
mt792x_mutex_release(dev);
-
- mt7921_regd_channel_update(wiphy, dev);
}
int mt7921_mac_init(struct mt792x_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 510a575a973b..0645417e0582 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -683,17 +683,45 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw,
}
static void
-mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif)
+mt7921_calc_vif_num(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+ u32 *num = priv;
+
+ if (!priv)
+ return;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
+ *num += 1;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)
{
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
struct mt792x_phy *phy = mvif->phy;
struct mt792x_dev *dev = phy->dev;
+ u32 valid_vif_num = 0;
+
+ ieee80211_iterate_active_interfaces(mt76_hw(dev),
+ IEEE80211_IFACE_ITER_RESUME_ALL,
+ mt7921_calc_vif_num, &valid_vif_num);
- if (hweight64(dev->mt76.vif_mask) > 1) {
+ if (valid_vif_num > 1) {
phy->power_type = MT_AP_DEFAULT;
goto out;
}
+ if (!is_add)
+ vif->bss_conf.power_type = IEEE80211_REG_UNSET_AP;
+
switch (vif->bss_conf.power_type) {
case IEEE80211_REG_SP_AP:
phy->power_type = MT_AP_SP;
@@ -705,6 +733,8 @@ mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif)
phy->power_type = MT_AP_LPI;
break;
case IEEE80211_REG_UNSET_AP:
+ phy->power_type = MT_AP_UNSET;
+ break;
default:
phy->power_type = MT_AP_DEFAULT;
break;
@@ -749,7 +779,7 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
if (ret)
return ret;
- mt7921_regd_set_6ghz_power_type(vif);
+ mt7921_regd_set_6ghz_power_type(vif, true);
mt76_connac_power_save_sched(&dev->mphy, &dev->pm);
@@ -811,6 +841,8 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
list_del_init(&msta->wcid.poll_list);
spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ mt7921_regd_set_6ghz_power_type(vif, false);
+
mt76_connac_power_save_sched(&dev->mphy, &dev->pm);
}
EXPORT_SYMBOL_GPL(mt7921_mac_sta_remove);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 2cc2d2788f83..f5582477c7e4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -160,7 +160,7 @@ static void
mt7921_mcu_scan_event(struct mt792x_dev *dev, struct sk_buff *skb)
{
struct mt76_phy *mphy = &dev->mt76.phy;
- struct mt792x_phy *phy = (struct mt792x_phy *)mphy->priv;
+ struct mt792x_phy *phy = mphy->priv;
spin_lock_bh(&dev->mt76.lock);
__skb_queue_tail(&phy->scan_event_list, skb);
@@ -1261,15 +1261,19 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
u8 alpha2[2];
u8 type[2];
u8 env_6g;
- u8 rsvd[63];
+ u8 mtcl_conf;
+ u8 rsvd[62];
} __packed req = {
+ .ver = 1,
.idx = idx,
.env = env_cap,
.env_6g = dev->phy.power_type,
.acpi_conf = mt792x_acpi_get_flags(&dev->phy),
+ .mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, alpha2),
};
int ret, valid_cnt = 0;
- u8 i, *pos;
+ u16 buf_len = 0;
+ u8 *pos;
if (!clc)
return 0;
@@ -1279,12 +1283,15 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
if (mt76_find_power_limits_node(&dev->mt76))
req.cap |= CLC_CAP_DTS_EN;
+ buf_len = le16_to_cpu(clc->len) - sizeof(*clc);
pos = clc->data;
- for (i = 0; i < clc->nr_country; i++) {
+ while (buf_len > 16) {
struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos;
u16 len = le16_to_cpu(rule->len);
+ u16 offset = len + sizeof(*rule);
- pos += len + sizeof(*rule);
+ pos += offset;
+ buf_len -= offset;
if (rule->alpha2[0] != alpha2[0] ||
rule->alpha2[1] != alpha2[1])
continue;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index f28621121927..1cb21133992b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -12,7 +12,8 @@
#define MT7921_TX_FWDL_RING_SIZE 128
#define MT7921_RX_RING_SIZE 1536
-#define MT7921_RX_MCU_RING_SIZE 512
+#define MT7921_RX_MCU_RING_SIZE 8
+#define MT7921_RX_MCU_WA_RING_SIZE 512
#define MT7921_EEPROM_SIZE 3584
#define MT7921_TOKEN_SIZE 8192
@@ -233,6 +234,7 @@ mt7921_l1_rmw(struct mt792x_dev *dev, u32 addr, u32 mask, u32 val)
#define mt7921_l1_set(dev, addr, val) mt7921_l1_rmw(dev, addr, 0, val)
#define mt7921_l1_clear(dev, addr, val) mt7921_l1_rmw(dev, addr, val, 0)
+void mt7921_regd_update(struct mt792x_dev *dev);
int mt7921_mac_init(struct mt792x_dev *dev);
bool mt7921_mac_wtbl_update(struct mt792x_dev *dev, int idx, u32 mask);
int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index f04e7095e181..57903c6e4f11 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -171,7 +171,7 @@ static int mt7921_dma_init(struct mt792x_dev *dev)
/* init tx queue */
ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0,
MT7921_TX_RING_SIZE,
- MT_TX_RING_BASE, 0);
+ MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
@@ -200,7 +200,7 @@ static int mt7921_dma_init(struct mt792x_dev *dev)
/* Change mcu queue after firmware download */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
MT7921_RXQ_MCU_WM,
- MT7921_RX_MCU_RING_SIZE,
+ MT7921_RX_MCU_WA_RING_SIZE,
MT_RX_BUF_SIZE, MT_WFDMA0(0x540));
if (ret)
return ret;
@@ -507,6 +507,9 @@ static int mt7921_pci_resume(struct device *device)
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
+
+ mt7921_regd_update(dev);
+
failed:
pm->suspended = false;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
index dc1beb76df3e..7591e54d2897 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
@@ -228,7 +228,7 @@ static int mt7921s_suspend(struct device *__dev)
mt76_txq_schedule_all(&dev->mphy);
mt76_worker_disable(&mdev->tx_worker);
mt76_worker_disable(&mdev->sdio.status_worker);
- cancel_work_sync(&mdev->sdio.stat_work);
+ mt76_worker_disable(&mdev->sdio.stat_worker);
clear_bit(MT76_READING_STATS, &dev->mphy.state);
mt76_tx_status_check(mdev, true);
@@ -260,6 +260,7 @@ restore_txrx_worker:
restore_worker:
mt76_worker_enable(&mdev->tx_worker);
mt76_worker_enable(&mdev->sdio.status_worker);
+ mt76_worker_enable(&mdev->sdio.stat_worker);
if (!pm->ds_enable)
mt76_connac_mcu_set_deep_sleep(mdev, false);
@@ -292,6 +293,7 @@ static int mt7921s_resume(struct device *__dev)
mt76_worker_enable(&mdev->sdio.txrx_worker);
mt76_worker_enable(&mdev->sdio.status_worker);
mt76_worker_enable(&mdev->sdio.net_worker);
+ mt76_worker_enable(&mdev->sdio.stat_worker);
/* restore previous ds setting */
if (!pm->ds_enable)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c
index 8edd0291c128..389eb0903807 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c
@@ -107,7 +107,7 @@ int mt7921s_mac_reset(struct mt792x_dev *dev)
mt76_worker_disable(&dev->mt76.sdio.txrx_worker);
mt76_worker_disable(&dev->mt76.sdio.status_worker);
mt76_worker_disable(&dev->mt76.sdio.net_worker);
- cancel_work_sync(&dev->mt76.sdio.stat_work);
+ mt76_worker_disable(&dev->mt76.sdio.stat_worker);
mt7921s_disable_irq(&dev->mt76);
mt7921s_wfsys_reset(dev);
@@ -115,6 +115,7 @@ int mt7921s_mac_reset(struct mt792x_dev *dev)
mt76_worker_enable(&dev->mt76.sdio.txrx_worker);
mt76_worker_enable(&dev->mt76.sdio.status_worker);
mt76_worker_enable(&dev->mt76.sdio.net_worker);
+ mt76_worker_enable(&dev->mt76.sdio.stat_worker);
dev->fw_assert = false;
clear_bit(MT76_MCU_RESET, &dev->mphy.state);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index aa918b9b0469..8f1075da4903 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -154,8 +154,7 @@ mt7925_init_he_caps(struct mt792x_phy *phy, enum nl80211_band band,
static void
mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
- struct ieee80211_sband_iftype_data *data,
- enum nl80211_iftype iftype)
+ struct ieee80211_sband_iftype_data *data)
{
struct ieee80211_sta_eht_cap *eht_cap = &data->eht_cap;
struct ieee80211_eht_cap_elem_fixed *eht_cap_elem = &eht_cap->eht_cap_elem;
@@ -256,7 +255,7 @@ __mt7925_set_stream_he_eht_caps(struct mt792x_phy *phy,
data[n].types_mask = BIT(i);
mt7925_init_he_caps(phy, band, &data[n], i);
- mt7925_init_eht_caps(phy, band, &data[n], i);
+ mt7925_init_eht_caps(phy, band, &data[n]);
n++;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index 9c0e397537ac..c5fd7116929b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -345,7 +345,7 @@ static void
mt7925_mcu_scan_event(struct mt792x_dev *dev, struct sk_buff *skb)
{
struct mt76_phy *mphy = &dev->mt76.phy;
- struct mt792x_phy *phy = (struct mt792x_phy *)mphy->priv;
+ struct mt792x_phy *phy = mphy->priv;
spin_lock_bh(&dev->mt76.lock);
__skb_queue_tail(&phy->scan_event_list, skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index 08ef75e24e1c..734f31ee40d3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -218,7 +218,7 @@ static int mt7925_dma_init(struct mt792x_dev *dev)
/* init tx queue */
ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7925_TXQ_BAND0,
MT7925_TX_RING_SIZE,
- MT_TX_RING_BASE, 0);
+ MT_TX_RING_BASE, NULL, 0);
if (ret)
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h
index 36fae736dd19..3c897b34aaa7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x.h
@@ -382,6 +382,7 @@ int mt792xe_mcu_fw_pmctrl(struct mt792x_dev *dev);
int mt792x_init_acpi_sar(struct mt792x_dev *dev);
int mt792x_init_acpi_sar_power(struct mt792x_phy *phy, bool set_default);
u8 mt792x_acpi_get_flags(struct mt792x_phy *phy);
+u8 mt792x_acpi_get_mtcl_conf(struct mt792x_phy *phy, char *alpha2);
#else
static inline int mt792x_init_acpi_sar(struct mt792x_dev *dev)
{
@@ -398,6 +399,11 @@ static inline u8 mt792x_acpi_get_flags(struct mt792x_phy *phy)
{
return 0;
}
+
+static inline u8 mt792x_acpi_get_mtcl_conf(struct mt792x_phy *phy, char *alpha2)
+{
+ return 0xf;
+}
#endif
#endif /* __MT7925_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
index 303c0f5c9c66..e7afea87e82e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
@@ -348,3 +348,56 @@ u8 mt792x_acpi_get_flags(struct mt792x_phy *phy)
return flags;
}
EXPORT_SYMBOL_GPL(mt792x_acpi_get_flags);
+
+static u8
+mt792x_acpi_get_mtcl_map(int row, int column, struct mt792x_asar_cl *cl)
+{
+ u8 config = 0;
+
+ if (cl->cl6g[row] & BIT(column))
+ config |= (cl->mode_6g & 0x3) << 2;
+ if (cl->version > 1 && cl->cl5g9[row] & BIT(column))
+ config |= (cl->mode_5g9 & 0x3);
+
+ return config;
+}
+
+u8 mt792x_acpi_get_mtcl_conf(struct mt792x_phy *phy, char *alpha2)
+{
+ static const char * const cc_list_all[] = {
+ "00", "EU", "AR", "AU", "AZ", "BY", "BO", "BR",
+ "CA", "CL", "CN", "ID", "JP", "MY", "MX", "ME",
+ "MA", "NZ", "NG", "PH", "RU", "RS", "SG", "KR",
+ "TW", "TH", "UA", "GB", "US", "VN", "KH", "PY",
+ };
+ static const char * const cc_list_eu[] = {
+ "AT", "BE", "BG", "CY", "CZ", "HR", "DK", "EE",
+ "FI", "FR", "DE", "GR", "HU", "IS", "IE", "IT",
+ "LV", "LI", "LT", "LU", "MT", "NL", "NO", "PL",
+ "PT", "RO", "MT", "SK", "SI", "ES", "CH",
+ };
+ struct mt792x_acpi_sar *sar = phy->acpisar;
+ struct mt792x_asar_cl *cl;
+ int col, row, i;
+
+ if (!sar)
+ return 0xf;
+
+ cl = sar->countrylist;
+ if (!cl)
+ return 0xc;
+
+ for (i = 0; i < ARRAY_SIZE(cc_list_all); i++) {
+ col = 7 - i % 8;
+ row = i / 8;
+ if (!memcmp(cc_list_all[i], alpha2, 2))
+ return mt792x_acpi_get_mtcl_map(row, col, cl);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(cc_list_eu); i++)
+ if (!memcmp(cc_list_eu[i], alpha2, 2))
+ return mt792x_acpi_get_mtcl_map(0, 6, cl);
+
+ return mt792x_acpi_get_mtcl_map(0, 7, cl);
+}
+EXPORT_SYMBOL_GPL(mt792x_acpi_get_mtcl_conf);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h
index d6d332e863ba..2298983b6342 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h
@@ -77,6 +77,8 @@ struct mt792x_asar_cl {
u8 version;
u8 mode_6g;
u8 cl6g[6];
+ u8 mode_5g9;
+ u8 cl5g9[6];
} __packed;
struct mt792x_asar_fg {
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_mac.c b/drivers/net/wireless/mediatek/mt76/mt792x_mac.c
index 5d1f8229fdc1..eb29434abee1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_mac.c
@@ -223,7 +223,7 @@ static void
mt792x_phy_update_channel(struct mt76_phy *mphy, int idx)
{
struct mt792x_dev *dev = container_of(mphy->dev, struct mt792x_dev, mt76);
- struct mt792x_phy *phy = (struct mt792x_phy *)mphy->priv;
+ struct mt792x_phy *phy = mphy->priv;
struct mt76_channel_state *state;
u64 busy_time, tx_time, rx_time, obss_time;
int nf;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c
index 4d40ec7ff57f..9bd953586b04 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c
@@ -476,7 +476,7 @@ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
{
struct mt76_mib_stats *mib = &phy->mib;
static const char * const bw[] = {
- "BW20", "BW40", "BW80", "BW160"
+ "BW20", "BW40", "BW80", "BW160", "BW320"
};
/* Tx Beamformer monitor */
@@ -489,8 +489,9 @@ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
/* Tx Beamformer Rx feedback monitor */
seq_puts(s, "Tx Beamformer Rx feedback statistics: ");
- seq_printf(s, "All: %d, HE: %d, VHT: %d, HT: %d, ",
+ seq_printf(s, "All: %d, EHT: %d, HE: %d, VHT: %d, HT: %d, ",
mib->tx_bf_rx_fb_all_cnt,
+ mib->tx_bf_rx_fb_eht_cnt,
mib->tx_bf_rx_fb_he_cnt,
mib->tx_bf_rx_fb_vht_cnt,
mib->tx_bf_rx_fb_ht_cnt);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
index 586e247a1e06..483ad81b6eec 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
@@ -7,6 +7,26 @@
#include "../dma.h"
#include "mac.h"
+int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx, int n_desc,
+ int ring_base, struct mtk_wed_device *wed)
+{
+ struct mt7996_dev *dev = phy->dev;
+ u32 flags = 0;
+
+ if (mtk_wed_device_active(wed)) {
+ ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
+ idx -= MT_TXQ_ID(0);
+
+ if (phy->mt76->band_idx == MT_BAND2)
+ flags = MT_WED_Q_TX(0);
+ else
+ flags = MT_WED_Q_TX(idx);
+ }
+
+ return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc,
+ ring_base, wed, flags);
+}
+
static int mt7996_poll_tx(struct napi_struct *napi, int budget)
{
struct mt7996_dev *dev;
@@ -37,18 +57,51 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
RXQ_CONFIG(MT_RXQ_MCU, WFDMA0, MT_INT_RX_DONE_WM, MT7996_RXQ_MCU_WM);
RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_RX_DONE_WA, MT7996_RXQ_MCU_WA);
- /* band0/band1 */
+ /* mt7996: band0 and band1, mt7992: band0 */
RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0, MT7996_RXQ_BAND0);
RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_RX_DONE_WA_MAIN, MT7996_RXQ_MCU_WA_MAIN);
- /* band2 */
- RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
- RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
+ if (is_mt7996(&dev->mt76)) {
+ /* mt7996 band2 */
+ RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
+ RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
+ } else {
+ /* mt7992 band1 */
+ RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1, MT7996_RXQ_BAND1);
+ RXQ_CONFIG(MT_RXQ_BAND1_WA, WFDMA0, MT_INT_RX_DONE_WA_EXT, MT7996_RXQ_MCU_WA_EXT);
+ }
+
+ if (dev->has_rro) {
+ /* band0 */
+ RXQ_CONFIG(MT_RXQ_RRO_BAND0, WFDMA0, MT_INT_RX_DONE_RRO_BAND0,
+ MT7996_RXQ_RRO_BAND0);
+ RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND0, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND0,
+ MT7996_RXQ_MSDU_PG_BAND0);
+ RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0, MT_INT_RX_TXFREE_MAIN,
+ MT7996_RXQ_TXFREE0);
+ /* band1 */
+ RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND1,
+ MT7996_RXQ_MSDU_PG_BAND1);
+ /* band2 */
+ RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0, MT_INT_RX_DONE_RRO_BAND2,
+ MT7996_RXQ_RRO_BAND2);
+ RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND2,
+ MT7996_RXQ_MSDU_PG_BAND2);
+ RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0, MT_INT_RX_TXFREE_TRI,
+ MT7996_RXQ_TXFREE2);
+
+ RXQ_CONFIG(MT_RXQ_RRO_IND, WFDMA0, MT_INT_RX_DONE_RRO_IND,
+ MT7996_RXQ_RRO_IND);
+ }
/* data tx queue */
TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7996_TXQ_BAND0);
- TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
- TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
+ if (is_mt7996(&dev->mt76)) {
+ TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
+ TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
+ } else {
+ TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
+ }
/* mcu tx queue */
MCUQ_CONFIG(MT_MCUQ_WM, WFDMA0, MT_INT_TX_DONE_MCU_WM, MT7996_TXQ_MCU_WM);
@@ -56,22 +109,57 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA0, MT_INT_TX_DONE_FWDL, MT7996_TXQ_FWDL);
}
+static u32 __mt7996_dma_prefetch_base(u16 *base, u8 depth)
+{
+ u32 ret = *base << 16 | depth;
+
+ *base = *base + (depth << 4);
+
+ return ret;
+}
+
static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
{
-#define PREFETCH(_base, _depth) ((_base) << 16 | (_depth))
+ u16 base = 0;
+ u8 queue;
+
+#define PREFETCH(_depth) (__mt7996_dma_prefetch_base(&base, (_depth)))
/* prefetch SRAM wrapping boundary for tx/rx ring. */
- mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_FWDL) + ofs, PREFETCH(0x0, 0x2));
- mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WM) + ofs, PREFETCH(0x20, 0x2));
- mt76_wr(dev, MT_TXQ_EXT_CTRL(0) + ofs, PREFETCH(0x40, 0x4));
- mt76_wr(dev, MT_TXQ_EXT_CTRL(1) + ofs, PREFETCH(0x80, 0x4));
- mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, PREFETCH(0xc0, 0x2));
- mt76_wr(dev, MT_TXQ_EXT_CTRL(2) + ofs, PREFETCH(0xe0, 0x4));
- mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, PREFETCH(0x120, 0x2));
- mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, PREFETCH(0x140, 0x2));
- mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, PREFETCH(0x160, 0x2));
- mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x180, 0x2));
- mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x1a0, 0x10));
- mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x2a0, 0x10));
+ mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_FWDL) + ofs, PREFETCH(0x2));
+ mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WM) + ofs, PREFETCH(0x2));
+ mt76_wr(dev, MT_TXQ_EXT_CTRL(0) + ofs, PREFETCH(0x8));
+ mt76_wr(dev, MT_TXQ_EXT_CTRL(1) + ofs, PREFETCH(0x8));
+ mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, PREFETCH(0x2));
+ mt76_wr(dev, MT_TXQ_EXT_CTRL(2) + ofs, PREFETCH(0x8));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, PREFETCH(0x2));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, PREFETCH(0x2));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, PREFETCH(0x2));
+
+ queue = is_mt7996(&dev->mt76) ? MT_RXQ_BAND2_WA : MT_RXQ_BAND1_WA;
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(queue) + ofs, PREFETCH(0x2));
+
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x10));
+
+ queue = is_mt7996(&dev->mt76) ? MT_RXQ_BAND2 : MT_RXQ_BAND1;
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(queue) + ofs, PREFETCH(0x10));
+
+ if (dev->has_rro) {
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
+ PREFETCH(0x10));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
+ PREFETCH(0x10));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND0) + ofs,
+ PREFETCH(0x4));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND1) + ofs,
+ PREFETCH(0x4));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND2) + ofs,
+ PREFETCH(0x4));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND0) + ofs,
+ PREFETCH(0x4));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
+ PREFETCH(0x4));
+ }
+#undef PREFETCH
mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
}
@@ -128,8 +216,9 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
}
}
-void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
+void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
{
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
u32 hif1_ofs = 0;
u32 irq_mask;
@@ -138,37 +227,49 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
/* enable WFDMA Tx/Rx */
if (!reset) {
- mt76_set(dev, MT_WFDMA0_GLO_CFG,
- MT_WFDMA0_GLO_CFG_TX_DMA_EN |
- MT_WFDMA0_GLO_CFG_RX_DMA_EN |
- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+ if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed))
+ mt76_set(dev, MT_WFDMA0_GLO_CFG,
+ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+ MT_WFDMA0_GLO_CFG_EXT_EN);
+ else
+ mt76_set(dev, MT_WFDMA0_GLO_CFG,
+ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+ MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
if (dev->hif2)
mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
MT_WFDMA0_GLO_CFG_TX_DMA_EN |
MT_WFDMA0_GLO_CFG_RX_DMA_EN |
MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 |
+ MT_WFDMA0_GLO_CFG_EXT_EN);
}
/* enable interrupts for TX/RX rings */
- irq_mask = MT_INT_MCU_CMD;
- if (reset)
- goto done;
+ irq_mask = MT_INT_MCU_CMD | MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
- irq_mask = MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
-
- if (!dev->mphy.band_idx)
+ if (mt7996_band_valid(dev, MT_BAND0))
irq_mask |= MT_INT_BAND0_RX_DONE;
- if (dev->dbdc_support)
+ if (mt7996_band_valid(dev, MT_BAND1))
irq_mask |= MT_INT_BAND1_RX_DONE;
- if (dev->tbtc_support)
+ if (mt7996_band_valid(dev, MT_BAND2))
irq_mask |= MT_INT_BAND2_RX_DONE;
-done:
+ if (mtk_wed_device_active(wed) && wed_reset) {
+ u32 wed_irq_mask = irq_mask;
+
+ wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
+ mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
+ mtk_wed_device_start(wed, wed_irq_mask);
+ }
+
+ irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
+
mt7996_irq_enable(dev, irq_mask);
mt7996_irq_disable(dev, 0);
}
@@ -223,6 +324,12 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1,
WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
+ /* WFDMA rx threshold */
+ mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_45_TH, 0xc000c);
+ mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_67_TH, 0x10008);
+ mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_89_TH, 0x10008);
+ mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_RRO_TH, 0x20);
+
if (dev->hif2) {
/* GLO_CFG_EXT0 */
mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
@@ -234,24 +341,108 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
mt76_set(dev, MT_WFDMA_HOST_CONFIG,
- MT_WFDMA_HOST_CONFIG_PDMA_BAND);
+ MT_WFDMA_HOST_CONFIG_PDMA_BAND |
+ MT_WFDMA_HOST_CONFIG_BAND2_PCIE1);
+
+ /* AXI read outstanding number */
+ mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL,
+ MT_WFDMA_AXI_R2A_CTRL_OUTSTAND_MASK, 0x14);
+
+ /* WFDMA rx threshold */
+ mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_45_TH + hif1_ofs, 0xc000c);
+ mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_67_TH + hif1_ofs, 0x10008);
+ mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_89_TH + hif1_ofs, 0x10008);
+ mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_RRO_TH + hif1_ofs, 0x20);
}
if (dev->hif2) {
/* fix hardware limitation, pcie1's rx ring3 is not available
* so, redirect pcie0 rx ring3 interrupt to pcie1
*/
- mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
- MT_WFDMA0_RX_INT_SEL_RING3);
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+ dev->has_rro)
+ mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
+ MT_WFDMA0_RX_INT_SEL_RING6);
+ else
+ mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
+ MT_WFDMA0_RX_INT_SEL_RING3);
+ }
+
+ mt7996_dma_start(dev, reset, true);
+}
+
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+int mt7996_dma_rro_init(struct mt7996_dev *dev)
+{
+ struct mt76_dev *mdev = &dev->mt76;
+ u32 irq_mask;
+ int ret;
- /* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
+ /* ind cmd */
+ mdev->q_rx[MT_RXQ_RRO_IND].flags = MT_WED_RRO_Q_IND;
+ mdev->q_rx[MT_RXQ_RRO_IND].wed = &mdev->mmio.wed;
+ ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_RRO_IND],
+ MT_RXQ_ID(MT_RXQ_RRO_IND),
+ MT7996_RX_RING_SIZE,
+ 0, MT_RXQ_RRO_IND_RING_BASE);
+ if (ret)
+ return ret;
+
+ /* rx msdu page queue for band0 */
+ mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags =
+ MT_WED_RRO_Q_MSDU_PG(0) | MT_QFLAG_WED_RRO_EN;
+ mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0].wed = &mdev->mmio.wed;
+ ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0],
+ MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND0),
+ MT7996_RX_RING_SIZE,
+ MT7996_RX_MSDU_PAGE_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND0));
+ if (ret)
+ return ret;
+
+ if (mt7996_band_valid(dev, MT_BAND1)) {
+ /* rx msdu page queue for band1 */
+ mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags =
+ MT_WED_RRO_Q_MSDU_PG(1) | MT_QFLAG_WED_RRO_EN;
+ mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].wed = &mdev->mmio.wed;
+ ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1],
+ MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND1),
+ MT7996_RX_RING_SIZE,
+ MT7996_RX_MSDU_PAGE_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND1));
+ if (ret)
+ return ret;
}
- mt7996_dma_start(dev, reset);
+ if (mt7996_band_valid(dev, MT_BAND2)) {
+ /* rx msdu page queue for band2 */
+ mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags =
+ MT_WED_RRO_Q_MSDU_PG(2) | MT_QFLAG_WED_RRO_EN;
+ mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].wed = &mdev->mmio.wed;
+ ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2],
+ MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND2),
+ MT7996_RX_RING_SIZE,
+ MT7996_RX_MSDU_PAGE_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND2));
+ if (ret)
+ return ret;
+ }
+
+ irq_mask = mdev->mmio.irqmask | MT_INT_RRO_RX_DONE |
+ MT_INT_TX_DONE_BAND2;
+ mt76_wr(dev, MT_INT_MASK_CSR, irq_mask);
+ mtk_wed_device_start_hw_rro(&mdev->mmio.wed, irq_mask, false);
+ mt7996_irq_enable(dev, irq_mask);
+
+ return 0;
}
+#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
int mt7996_dma_init(struct mt7996_dev *dev)
{
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
+ u32 rx_base;
u32 hif1_ofs = 0;
int ret;
@@ -265,10 +456,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
mt7996_dma_disable(dev, true);
/* init tx queue */
- ret = mt76_connac_init_tx_queues(dev->phy.mt76,
- MT_TXQ_ID(dev->mphy.band_idx),
- MT7996_TX_RING_SIZE,
- MT_TXQ_RING_BASE(0), 0);
+ ret = mt7996_init_tx_queues(&dev->phy,
+ MT_TXQ_ID(dev->mphy.band_idx),
+ MT7996_TX_RING_SIZE,
+ MT_TXQ_RING_BASE(0),
+ wed);
if (ret)
return ret;
@@ -314,7 +506,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
if (ret)
return ret;
- /* rx data queue for band0 and band1 */
+ /* rx data queue for band0 and mt7996 band1 */
+ if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed)) {
+ dev->mt76.q_rx[MT_RXQ_MAIN].flags = MT_WED_Q_RX(0);
+ dev->mt76.q_rx[MT_RXQ_MAIN].wed = wed;
+ }
+
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
MT_RXQ_ID(MT_RXQ_MAIN),
MT7996_RX_RING_SIZE,
@@ -324,6 +521,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
return ret;
/* tx free notify event from WA for band0 */
+ if (mtk_wed_device_active(wed) && !dev->has_rro) {
+ dev->mt76.q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
+ dev->mt76.q_rx[MT_RXQ_MAIN_WA].wed = wed;
+ }
+
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN_WA],
MT_RXQ_ID(MT_RXQ_MAIN_WA),
MT7996_RX_MCU_RING_SIZE,
@@ -332,19 +534,25 @@ int mt7996_dma_init(struct mt7996_dev *dev)
if (ret)
return ret;
- if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
- /* rx data queue for band2 */
+ if (mt7996_band_valid(dev, MT_BAND2)) {
+ /* rx data queue for mt7996 band2 */
+ rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
MT_RXQ_ID(MT_RXQ_BAND2),
MT7996_RX_RING_SIZE,
MT_RX_BUF_SIZE,
- MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs);
+ rx_base);
if (ret)
return ret;
- /* tx free notify event from WA for band2
+ /* tx free notify event from WA for mt7996 band2
* use pcie0's rx ring3, but, redirect pcie0 rx ring3 interrupt to pcie1
*/
+ if (mtk_wed_device_active(wed_hif2) && !dev->has_rro) {
+ dev->mt76.q_rx[MT_RXQ_BAND2_WA].flags = MT_WED_Q_TXFREE;
+ dev->mt76.q_rx[MT_RXQ_BAND2_WA].wed = wed_hif2;
+ }
+
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2_WA],
MT_RXQ_ID(MT_RXQ_BAND2_WA),
MT7996_RX_MCU_RING_SIZE,
@@ -352,6 +560,80 @@ int mt7996_dma_init(struct mt7996_dev *dev)
MT_RXQ_RING_BASE(MT_RXQ_BAND2_WA));
if (ret)
return ret;
+ } else if (mt7996_band_valid(dev, MT_BAND1)) {
+ /* rx data queue for mt7992 band1 */
+ rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1) + hif1_ofs;
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1],
+ MT_RXQ_ID(MT_RXQ_BAND1),
+ MT7996_RX_RING_SIZE,
+ MT_RX_BUF_SIZE,
+ rx_base);
+ if (ret)
+ return ret;
+
+ /* tx free notify event from WA for mt7992 band1 */
+ rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1_WA) + hif1_ofs;
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1_WA],
+ MT_RXQ_ID(MT_RXQ_BAND1_WA),
+ MT7996_RX_MCU_RING_SIZE,
+ MT_RX_BUF_SIZE,
+ rx_base);
+ if (ret)
+ return ret;
+ }
+
+ if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed) &&
+ dev->has_rro) {
+ /* rx rro data queue for band0 */
+ dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags =
+ MT_WED_RRO_Q_DATA(0) | MT_QFLAG_WED_RRO_EN;
+ dev->mt76.q_rx[MT_RXQ_RRO_BAND0].wed = wed;
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
+ MT_RXQ_ID(MT_RXQ_RRO_BAND0),
+ MT7996_RX_RING_SIZE,
+ MT7996_RX_BUF_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND0));
+ if (ret)
+ return ret;
+
+ /* tx free notify event from WA for band0 */
+ dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
+ dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].wed = wed;
+
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
+ MT_RXQ_ID(MT_RXQ_TXFREE_BAND0),
+ MT7996_RX_MCU_RING_SIZE,
+ MT7996_RX_BUF_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND0));
+ if (ret)
+ return ret;
+
+ if (mt7996_band_valid(dev, MT_BAND2)) {
+ /* rx rro data queue for band2 */
+ dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags =
+ MT_WED_RRO_Q_DATA(1) | MT_QFLAG_WED_RRO_EN;
+ dev->mt76.q_rx[MT_RXQ_RRO_BAND2].wed = wed;
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
+ MT_RXQ_ID(MT_RXQ_RRO_BAND2),
+ MT7996_RX_RING_SIZE,
+ MT7996_RX_BUF_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND2) + hif1_ofs);
+ if (ret)
+ return ret;
+
+ /* tx free notify event from MAC for band2 */
+ if (mtk_wed_device_active(wed_hif2)) {
+ dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].flags = MT_WED_Q_TXFREE;
+ dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].wed = wed_hif2;
+ }
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2],
+ MT_RXQ_ID(MT_RXQ_TXFREE_BAND2),
+ MT7996_RX_MCU_RING_SIZE,
+ MT7996_RX_BUF_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND2) + hif1_ofs);
+ if (ret)
+ return ret;
+ }
}
ret = mt76_init_queues(dev, mt76_dma_rx_poll);
@@ -405,21 +687,33 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
if (force)
mt7996_wfsys_reset(dev);
+ if (dev->hif2 && mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
+ mtk_wed_device_dma_reset(&dev->mt76.mmio.wed_hif2);
+
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
+ mtk_wed_device_dma_reset(&dev->mt76.mmio.wed);
+
mt7996_dma_disable(dev, force);
+ mt76_dma_wed_reset(&dev->mt76);
/* reset hw queues */
for (i = 0; i < __MT_TXQ_MAX; i++) {
- mt76_queue_reset(dev, dev->mphy.q_tx[i]);
+ mt76_dma_reset_tx_queue(&dev->mt76, dev->mphy.q_tx[i]);
if (phy2)
- mt76_queue_reset(dev, phy2->q_tx[i]);
+ mt76_dma_reset_tx_queue(&dev->mt76, phy2->q_tx[i]);
if (phy3)
- mt76_queue_reset(dev, phy3->q_tx[i]);
+ mt76_dma_reset_tx_queue(&dev->mt76, phy3->q_tx[i]);
}
for (i = 0; i < __MT_MCUQ_MAX; i++)
mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
mt76_for_each_q_rx(&dev->mt76, i) {
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
+ if (mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]) ||
+ mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i]))
+ continue;
+
mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
index 544b6c6f1ea3..4a8237118287 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
@@ -14,7 +14,9 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
switch (val) {
case 0x7990:
- return 0;
+ return is_mt7996(&dev->mt76) ? 0 : -EINVAL;
+ case 0x7992:
+ return is_mt7992(&dev->mt76) ? 0 : -EINVAL;
default:
return -EINVAL;
}
@@ -22,8 +24,14 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
static char *mt7996_eeprom_name(struct mt7996_dev *dev)
{
- /* reserve for future variants */
- return MT7996_EEPROM_DEFAULT;
+ switch (mt76_chip(&dev->mt76)) {
+ case 0x7990:
+ return MT7996_EEPROM_DEFAULT;
+ case 0x7992:
+ return MT7992_EEPROM_DEFAULT;
+ default:
+ return MT7996_EEPROM_DEFAULT;
+ }
}
static int
@@ -103,7 +111,8 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
dev->wtbl_size_group = u32_get_bits(cap, WTBL_SIZE_GROUP);
}
- if (dev->wtbl_size_group < 2 || dev->wtbl_size_group > 4)
+ if (dev->wtbl_size_group < 2 || dev->wtbl_size_group > 4 ||
+ is_mt7992(&dev->mt76))
dev->wtbl_size_group = 2; /* set default */
return 0;
@@ -148,36 +157,49 @@ static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
{
- u8 path, nss, band_idx = phy->mt76->band_idx;
+ u8 path, rx_path, nss, band_idx = phy->mt76->band_idx;
u8 *eeprom = dev->mt76.eeprom.data;
struct mt76_phy *mphy = phy->mt76;
+ int max_path = 5, max_nss = 4;
int ret;
switch (band_idx) {
case MT_BAND1:
path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND1,
eeprom[MT_EE_WIFI_CONF + 2]);
+ rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND1,
+ eeprom[MT_EE_WIFI_CONF + 3]);
nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND1,
eeprom[MT_EE_WIFI_CONF + 5]);
break;
case MT_BAND2:
path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND2,
eeprom[MT_EE_WIFI_CONF + 2]);
+ rx_path = FIELD_GET(MT_EE_WIFI_CONF4_RX_PATH_BAND2,
+ eeprom[MT_EE_WIFI_CONF + 4]);
nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND2,
eeprom[MT_EE_WIFI_CONF + 5]);
break;
default:
path = FIELD_GET(MT_EE_WIFI_CONF1_TX_PATH_BAND0,
eeprom[MT_EE_WIFI_CONF + 1]);
+ rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND0,
+ eeprom[MT_EE_WIFI_CONF + 3]);
nss = FIELD_GET(MT_EE_WIFI_CONF4_STREAM_NUM_BAND0,
eeprom[MT_EE_WIFI_CONF + 4]);
break;
}
- if (!path || path > 4)
- path = 4;
+ if (!path || path > max_path)
+ path = max_path;
+
+ if (!nss || nss > max_nss)
+ nss = max_nss;
+
+ nss = min_t(u8, nss, path);
- nss = min_t(u8, min_t(u8, 4, nss), path);
+ if (path != rx_path)
+ phy->has_aux_rx = true;
mphy->antenna_mask = BIT(nss) - 1;
mphy->chainmask = (BIT(path) - 1) << dev->chainshift[band_idx];
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h
index 0c749774f6b1..412d6e2f8014 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h
@@ -33,6 +33,9 @@ enum mt7996_eeprom_field {
#define MT_EE_WIFI_CONF1_TX_PATH_BAND0 GENMASK(5, 3)
#define MT_EE_WIFI_CONF2_TX_PATH_BAND1 GENMASK(2, 0)
#define MT_EE_WIFI_CONF2_TX_PATH_BAND2 GENMASK(5, 3)
+#define MT_EE_WIFI_CONF3_RX_PATH_BAND0 GENMASK(2, 0)
+#define MT_EE_WIFI_CONF3_RX_PATH_BAND1 GENMASK(5, 3)
+#define MT_EE_WIFI_CONF4_RX_PATH_BAND2 GENMASK(2, 0)
#define MT_EE_WIFI_CONF4_STREAM_NUM_BAND0 GENMASK(5, 3)
#define MT_EE_WIFI_CONF5_STREAM_NUM_BAND1 GENMASK(2, 0)
#define MT_EE_WIFI_CONF5_STREAM_NUM_BAND2 GENMASK(5, 3)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
index 55cb1770fa34..0cf0d1fe420a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -5,6 +5,8 @@
#include <linux/etherdevice.h>
#include <linux/of.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/thermal.h>
#include "mt7996.h"
#include "mac.h"
@@ -43,6 +45,183 @@ static const struct ieee80211_iface_combination if_comb[] = {
}
};
+static ssize_t mt7996_thermal_temp_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct mt7996_phy *phy = dev_get_drvdata(dev);
+ int i = to_sensor_dev_attr(attr)->index;
+ int temperature;
+
+ switch (i) {
+ case 0:
+ temperature = mt7996_mcu_get_temperature(phy);
+ if (temperature < 0)
+ return temperature;
+ /* display in millidegree celcius */
+ return sprintf(buf, "%u\n", temperature * 1000);
+ case 1:
+ case 2:
+ return sprintf(buf, "%u\n",
+ phy->throttle_temp[i - 1] * 1000);
+ case 3:
+ return sprintf(buf, "%hhu\n", phy->throttle_state);
+ default:
+ return -EINVAL;
+ }
+}
+
+static ssize_t mt7996_thermal_temp_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct mt7996_phy *phy = dev_get_drvdata(dev);
+ int ret, i = to_sensor_dev_attr(attr)->index;
+ long val;
+
+ ret = kstrtol(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&phy->dev->mt76.mutex);
+ val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 40, 130);
+
+ /* add a safety margin ~10 */
+ if ((i - 1 == MT7996_CRIT_TEMP_IDX &&
+ val > phy->throttle_temp[MT7996_MAX_TEMP_IDX] - 10) ||
+ (i - 1 == MT7996_MAX_TEMP_IDX &&
+ val - 10 < phy->throttle_temp[MT7996_CRIT_TEMP_IDX])) {
+ dev_err(phy->dev->mt76.dev,
+ "temp1_max shall be 10 degrees higher than temp1_crit.");
+ mutex_unlock(&phy->dev->mt76.mutex);
+ return -EINVAL;
+ }
+
+ phy->throttle_temp[i - 1] = val;
+ mutex_unlock(&phy->dev->mt76.mutex);
+
+ ret = mt7996_mcu_set_thermal_protect(phy, true);
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7996_thermal_temp, 0);
+static SENSOR_DEVICE_ATTR_RW(temp1_crit, mt7996_thermal_temp, 1);
+static SENSOR_DEVICE_ATTR_RW(temp1_max, mt7996_thermal_temp, 2);
+static SENSOR_DEVICE_ATTR_RO(throttle1, mt7996_thermal_temp, 3);
+
+static struct attribute *mt7996_hwmon_attrs[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_crit.dev_attr.attr,
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ &sensor_dev_attr_throttle1.dev_attr.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(mt7996_hwmon);
+
+static int
+mt7996_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ *state = MT7996_CDEV_THROTTLE_MAX;
+
+ return 0;
+}
+
+static int
+mt7996_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ struct mt7996_phy *phy = cdev->devdata;
+
+ *state = phy->cdev_state;
+
+ return 0;
+}
+
+static int
+mt7996_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
+{
+ struct mt7996_phy *phy = cdev->devdata;
+ u8 throttling = MT7996_THERMAL_THROTTLE_MAX - state;
+ int ret;
+
+ if (state > MT7996_CDEV_THROTTLE_MAX) {
+ dev_err(phy->dev->mt76.dev,
+ "please specify a valid throttling state\n");
+ return -EINVAL;
+ }
+
+ if (state == phy->cdev_state)
+ return 0;
+
+ /* cooling_device convention: 0 = no cooling, more = more cooling
+ * mcu convention: 1 = max cooling, more = less cooling
+ */
+ ret = mt7996_mcu_set_thermal_throttling(phy, throttling);
+ if (ret)
+ return ret;
+
+ phy->cdev_state = state;
+
+ return 0;
+}
+
+static const struct thermal_cooling_device_ops mt7996_thermal_ops = {
+ .get_max_state = mt7996_thermal_get_max_throttle_state,
+ .get_cur_state = mt7996_thermal_get_cur_throttle_state,
+ .set_cur_state = mt7996_thermal_set_cur_throttle_state,
+};
+
+static void mt7996_unregister_thermal(struct mt7996_phy *phy)
+{
+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
+
+ if (!phy->cdev)
+ return;
+
+ sysfs_remove_link(&wiphy->dev.kobj, "cooling_device");
+ thermal_cooling_device_unregister(phy->cdev);
+}
+
+static int mt7996_thermal_init(struct mt7996_phy *phy)
+{
+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
+ struct thermal_cooling_device *cdev;
+ struct device *hwmon;
+ const char *name;
+
+ name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7996_%s",
+ wiphy_name(wiphy));
+
+ cdev = thermal_cooling_device_register(name, phy, &mt7996_thermal_ops);
+ if (!IS_ERR(cdev)) {
+ if (sysfs_create_link(&wiphy->dev.kobj, &cdev->device.kobj,
+ "cooling_device") < 0)
+ thermal_cooling_device_unregister(cdev);
+ else
+ phy->cdev = cdev;
+ }
+
+ /* initialize critical/maximum high temperature */
+ phy->throttle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP;
+ phy->throttle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP;
+
+ if (!IS_REACHABLE(CONFIG_HWMON))
+ return 0;
+
+ hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,
+ mt7996_hwmon_groups);
+
+ if (IS_ERR(hwmon))
+ return PTR_ERR(hwmon);
+
+ return 0;
+}
+
static void mt7996_led_set_config(struct led_classdev *led_cdev,
u8 delay_on, u8 delay_off)
{
@@ -109,10 +288,11 @@ static void mt7996_led_set_brightness(struct led_classdev *led_cdev,
mt7996_led_set_config(led_cdev, 0xff, 0);
}
-void mt7996_init_txpower(struct mt7996_dev *dev,
- struct ieee80211_supported_band *sband)
+static void __mt7996_init_txpower(struct mt7996_phy *phy,
+ struct ieee80211_supported_band *sband)
{
- int i, nss = hweight8(dev->mphy.antenna_mask);
+ struct mt7996_dev *dev = phy->dev;
+ int i, nss = hweight16(phy->mt76->chainmask);
int nss_delta = mt76_tx_power_nss_delta(nss);
int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);
struct mt76_power_limits limits;
@@ -122,7 +302,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
int target_power = mt7996_eeprom_get_target_power(dev, chan);
target_power += pwr_delta;
- target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
+ target_power = mt76_get_rate_power_limits(phy->mt76, chan,
&limits,
target_power);
target_power += nss_delta;
@@ -133,6 +313,19 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
}
}
+void mt7996_init_txpower(struct mt7996_phy *phy)
+{
+ if (!phy)
+ return;
+
+ if (phy->mt76->cap.has_2ghz)
+ __mt7996_init_txpower(phy, &phy->mt76->sband_2g.sband);
+ if (phy->mt76->cap.has_5ghz)
+ __mt7996_init_txpower(phy, &phy->mt76->sband_5g.sband);
+ if (phy->mt76->cap.has_6ghz)
+ __mt7996_init_txpower(phy, &phy->mt76->sband_6g.sband);
+}
+
static void
mt7996_regd_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
@@ -147,16 +340,14 @@ mt7996_regd_notifier(struct wiphy *wiphy,
if (dev->mt76.region == NL80211_DFS_UNSET)
mt7996_mcu_rdd_background_enable(phy, NULL);
- mt7996_init_txpower(dev, &phy->mt76->sband_2g.sband);
- mt7996_init_txpower(dev, &phy->mt76->sband_5g.sband);
- mt7996_init_txpower(dev, &phy->mt76->sband_6g.sband);
+ mt7996_init_txpower(phy);
phy->mt76->dfs_state = MT_DFS_STATE_UNKNOWN;
mt7996_dfs_init_radar_detector(phy);
}
static void
-mt7996_init_wiphy(struct ieee80211_hw *hw)
+mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
{
struct mt7996_phy *phy = mt7996_hw_phy(hw);
struct mt76_dev *mdev = &phy->dev->mt76;
@@ -168,11 +359,14 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
hw->max_rx_aggregation_subframes = max_subframes;
hw->max_tx_aggregation_subframes = max_subframes;
hw->netdev_features = NETIF_F_RXCSUM;
+ if (mtk_wed_device_active(wed))
+ hw->netdev_features |= NETIF_F_HW_TC;
hw->radiotap_timestamp.units_pos =
IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
phy->slottime = 9;
+ phy->beacon_rate = -1;
hw->sta_data_size = sizeof(struct mt7996_sta);
hw->vif_data_size = sizeof(struct mt7996_vif);
@@ -242,6 +436,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
mt76_set_stream_caps(phy->mt76, true);
mt7996_set_stream_vht_txbf_caps(phy);
mt7996_set_stream_he_eht_caps(phy);
+ mt7996_init_txpower(phy);
wiphy->available_antennas_rx = phy->mt76->antenna_mask;
wiphy->available_antennas_tx = phy->mt76->antenna_mask;
@@ -287,11 +482,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
u16 rate = mt76_rates[i].hw_value;
- u16 idx = MT7996_BASIC_RATES_TBL + i;
+ /* odd index for driver, even index for firmware */
+ u16 idx = MT7996_BASIC_RATES_TBL + 2 * i;
rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |
FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));
- mt7996_mac_set_fixed_rate_table(dev, idx, rate);
+ mt7996_mcu_set_fixed_rate_table(&dev->phy, idx, rate, false);
}
}
@@ -317,9 +513,23 @@ void mt7996_mac_init(struct mt7996_dev *dev)
mt76_rmw_field(dev, MT_DMA_TCRF1(2), MT_DMA_TCRF1_QIDX, 0);
/* rro module init */
- mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
- mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
- mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
+ if (is_mt7996(&dev->mt76))
+ mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
+ else
+ mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE,
+ dev->hif2 ? 7 : 0);
+
+ if (dev->has_rro) {
+ u16 timeout;
+
+ timeout = mt76_rr(dev, MT_HW_REV) == MT_HW_REV1 ? 512 : 128;
+ mt7996_mcu_set_rro(dev, UNI_RRO_SET_FLUSH_TIMEOUT, timeout);
+ mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 1);
+ mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 0);
+ } else {
+ mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
+ mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
+ }
mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
MCU_WA_PARAM_HW_PATH_HIF_VER,
@@ -335,7 +545,8 @@ int mt7996_txbf_init(struct mt7996_dev *dev)
{
int ret;
- if (dev->dbdc_support) {
+ if (mt7996_band_valid(dev, MT_BAND1) ||
+ mt7996_band_valid(dev, MT_BAND2)) {
ret = mt7996_mcu_set_txbf(dev, BF_MOD_EN_CTRL);
if (ret)
return ret;
@@ -356,19 +567,18 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
struct mt76_phy *mphy;
u32 mac_ofs, hif1_ofs = 0;
int ret;
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- if (band != MT_BAND1 && band != MT_BAND2)
- return 0;
-
- if ((band == MT_BAND1 && !dev->dbdc_support) ||
- (band == MT_BAND2 && !dev->tbtc_support))
+ if (!mt7996_band_valid(dev, band) || band == MT_BAND0)
return 0;
if (phy)
return 0;
- if (band == MT_BAND2 && dev->hif2)
+ if (is_mt7996(&dev->mt76) && band == MT_BAND2 && dev->hif2) {
hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
+ wed = &dev->mt76.mmio.wed_hif2;
+ }
mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7996_ops, band);
if (!mphy)
@@ -401,11 +611,12 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
mt76_eeprom_override(mphy);
/* init wiphy according to mphy and phy */
- mt7996_init_wiphy(mphy->hw);
- ret = mt76_connac_init_tx_queues(phy->mt76,
- MT_TXQ_ID(band),
- MT7996_TX_RING_SIZE,
- MT_TXQ_RING_BASE(band) + hif1_ofs, 0);
+ mt7996_init_wiphy(mphy->hw, wed);
+ ret = mt7996_init_tx_queues(mphy->priv,
+ MT_TXQ_ID(band),
+ MT7996_TX_RING_SIZE,
+ MT_TXQ_RING_BASE(band) + hif1_ofs,
+ wed);
if (ret)
goto error;
@@ -414,10 +625,21 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
if (ret)
goto error;
+ ret = mt7996_thermal_init(phy);
+ if (ret)
+ goto error;
+
ret = mt7996_init_debugfs(phy);
if (ret)
goto error;
+ if (wed == &dev->mt76.mmio.wed_hif2 && mtk_wed_device_active(wed)) {
+ u32 irq_mask = dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2;
+
+ mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask);
+ mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask);
+ }
+
return 0;
error:
@@ -434,6 +656,8 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
if (!phy)
return;
+ mt7996_unregister_thermal(phy);
+
mphy = phy->dev->mt76.phys[band];
mt76_unregister_phy(mphy);
ieee80211_free_hw(mphy->hw);
@@ -447,9 +671,6 @@ static void mt7996_init_work(struct work_struct *work)
mt7996_mcu_set_eeprom(dev);
mt7996_mac_init(dev);
- mt7996_init_txpower(dev, &dev->mphy.sband_2g.sband);
- mt7996_init_txpower(dev, &dev->mphy.sband_5g.sband);
- mt7996_init_txpower(dev, &dev->mphy.sband_6g.sband);
mt7996_txbf_init(dev);
}
@@ -462,16 +683,225 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
msleep(20);
}
+static int mt7996_wed_rro_init(struct mt7996_dev *dev)
+{
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ u32 reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;
+ struct mt7996_wed_rro_addr *addr;
+ void *ptr;
+ int i;
+
+ if (!dev->has_rro)
+ return 0;
+
+ if (!mtk_wed_device_active(wed))
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(dev->wed_rro.ba_bitmap); i++) {
+ ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
+ MT7996_RRO_BA_BITMAP_CR_SIZE,
+ &dev->wed_rro.ba_bitmap[i].phy_addr,
+ GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ dev->wed_rro.ba_bitmap[i].ptr = ptr;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
+ int j;
+
+ ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
+ MT7996_RRO_WINDOW_MAX_SIZE * sizeof(*addr),
+ &dev->wed_rro.addr_elem[i].phy_addr,
+ GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ dev->wed_rro.addr_elem[i].ptr = ptr;
+ memset(dev->wed_rro.addr_elem[i].ptr, 0,
+ MT7996_RRO_WINDOW_MAX_SIZE * sizeof(*addr));
+
+ addr = dev->wed_rro.addr_elem[i].ptr;
+ for (j = 0; j < MT7996_RRO_WINDOW_MAX_SIZE; j++) {
+ addr->signature = 0xff;
+ addr++;
+ }
+
+ wed->wlan.ind_cmd.addr_elem_phys[i] =
+ dev->wed_rro.addr_elem[i].phy_addr;
+ }
+
+ ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
+ MT7996_RRO_WINDOW_MAX_LEN * sizeof(*addr),
+ &dev->wed_rro.session.phy_addr,
+ GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ dev->wed_rro.session.ptr = ptr;
+ addr = dev->wed_rro.session.ptr;
+ for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {
+ addr->signature = 0xff;
+ addr++;
+ }
+
+ /* rro hw init */
+ /* TODO: remove line after WM has set */
+ mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
+
+ /* setup BA bitmap cache address */
+ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
+ dev->wed_rro.ba_bitmap[0].phy_addr);
+ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
+ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
+ dev->wed_rro.ba_bitmap[1].phy_addr);
+ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
+
+ /* setup Address element address */
+ for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
+ mt76_wr(dev, reg, dev->wed_rro.addr_elem[i].phy_addr >> 4);
+ reg += 4;
+ }
+
+ /* setup Address element address - separate address segment mode */
+ mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
+ MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
+
+ wed->wlan.ind_cmd.win_size = ffs(MT7996_RRO_WINDOW_MAX_LEN) - 6;
+ wed->wlan.ind_cmd.particular_sid = MT7996_RRO_MAX_SESSION;
+ wed->wlan.ind_cmd.particular_se_phys = dev->wed_rro.session.phy_addr;
+ wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_LEN;
+ wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
+
+ mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
+ mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
+ MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
+
+ /* particular session configure */
+ /* use max session idx + 1 as particular session id */
+ mt76_wr(dev, MT_RRO_PARTICULAR_CFG0, dev->wed_rro.session.phy_addr);
+ mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
+ MT_RRO_PARTICULAR_CONFG_EN |
+ FIELD_PREP(MT_RRO_PARTICULAR_SID, MT7996_RRO_MAX_SESSION));
+
+ /* interrupt enable */
+ mt76_wr(dev, MT_RRO_HOST_INT_ENA,
+ MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
+
+ /* rro ind cmd queue init */
+ return mt7996_dma_rro_init(dev);
+#else
+ return 0;
+#endif
+}
+
+static void mt7996_wed_rro_free(struct mt7996_dev *dev)
+{
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ int i;
+
+ if (!dev->has_rro)
+ return;
+
+ if (!mtk_wed_device_active(&dev->mt76.mmio.wed))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(dev->wed_rro.ba_bitmap); i++) {
+ if (!dev->wed_rro.ba_bitmap[i].ptr)
+ continue;
+
+ dmam_free_coherent(dev->mt76.dma_dev,
+ MT7996_RRO_BA_BITMAP_CR_SIZE,
+ dev->wed_rro.ba_bitmap[i].ptr,
+ dev->wed_rro.ba_bitmap[i].phy_addr);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
+ if (!dev->wed_rro.addr_elem[i].ptr)
+ continue;
+
+ dmam_free_coherent(dev->mt76.dma_dev,
+ MT7996_RRO_WINDOW_MAX_SIZE *
+ sizeof(struct mt7996_wed_rro_addr),
+ dev->wed_rro.addr_elem[i].ptr,
+ dev->wed_rro.addr_elem[i].phy_addr);
+ }
+
+ if (!dev->wed_rro.session.ptr)
+ return;
+
+ dmam_free_coherent(dev->mt76.dma_dev,
+ MT7996_RRO_WINDOW_MAX_LEN *
+ sizeof(struct mt7996_wed_rro_addr),
+ dev->wed_rro.session.ptr,
+ dev->wed_rro.session.phy_addr);
+#endif
+}
+
+static void mt7996_wed_rro_work(struct work_struct *work)
+{
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ struct mt7996_dev *dev;
+ LIST_HEAD(list);
+
+ dev = (struct mt7996_dev *)container_of(work, struct mt7996_dev,
+ wed_rro.work);
+
+ spin_lock_bh(&dev->wed_rro.lock);
+ list_splice_init(&dev->wed_rro.poll_list, &list);
+ spin_unlock_bh(&dev->wed_rro.lock);
+
+ while (!list_empty(&list)) {
+ struct mt7996_wed_rro_session_id *e;
+ int i;
+
+ e = list_first_entry(&list, struct mt7996_wed_rro_session_id,
+ list);
+ list_del_init(&e->list);
+
+ for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {
+ void *ptr = dev->wed_rro.session.ptr;
+ struct mt7996_wed_rro_addr *elem;
+ u32 idx, elem_id = i;
+
+ if (e->id == MT7996_RRO_MAX_SESSION)
+ goto reset;
+
+ idx = e->id / MT7996_RRO_BA_BITMAP_SESSION_SIZE;
+ if (idx >= ARRAY_SIZE(dev->wed_rro.addr_elem))
+ goto out;
+
+ ptr = dev->wed_rro.addr_elem[idx].ptr;
+ elem_id +=
+ (e->id % MT7996_RRO_BA_BITMAP_SESSION_SIZE) *
+ MT7996_RRO_WINDOW_MAX_LEN;
+reset:
+ elem = ptr + elem_id * sizeof(*elem);
+ elem->signature = 0xff;
+ }
+ mt7996_mcu_wed_rro_reset_sessions(dev, e->id);
+out:
+ kfree(e);
+ }
+#endif
+}
+
static int mt7996_init_hardware(struct mt7996_dev *dev)
{
int ret, idx;
mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
+ if (is_mt7992(&dev->mt76)) {
+ mt76_rmw(dev, MT_AFE_CTL_BAND_PLL_03(MT_BAND0), MT_AFE_CTL_BAND_PLL_03_MSB_EN, 0);
+ mt76_rmw(dev, MT_AFE_CTL_BAND_PLL_03(MT_BAND1), MT_AFE_CTL_BAND_PLL_03_MSB_EN, 0);
+ }
INIT_WORK(&dev->init_work, mt7996_init_work);
-
- dev->dbdc_support = true;
- dev->tbtc_support = true;
+ INIT_WORK(&dev->wed_rro.work, mt7996_wed_rro_work);
+ INIT_LIST_HEAD(&dev->wed_rro.poll_list);
+ spin_lock_init(&dev->wed_rro.lock);
ret = mt7996_dma_init(dev);
if (ret)
@@ -483,6 +913,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
if (ret)
return ret;
+ ret = mt7996_wed_rro_init(dev);
+ if (ret)
+ return ret;
+
ret = mt7996_eeprom_init(dev);
if (ret < 0)
return ret;
@@ -889,14 +1323,16 @@ int mt7996_register_device(struct mt7996_dev *dev)
if (ret)
return ret;
- mt7996_init_wiphy(hw);
+ mt7996_init_wiphy(hw, &dev->mt76.mmio.wed);
ret = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (ret)
return ret;
- ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
+ ret = mt7996_thermal_init(&dev->phy);
+ if (ret)
+ return ret;
ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
if (ret)
@@ -906,21 +1342,35 @@ int mt7996_register_device(struct mt7996_dev *dev)
if (ret)
return ret;
+ ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
+
dev->recovery.hw_init_done = true;
ret = mt7996_init_debugfs(&dev->phy);
if (ret)
- return ret;
+ goto error;
+
+ ret = mt7996_coredump_register(dev);
+ if (ret)
+ goto error;
- return mt7996_coredump_register(dev);
+ return 0;
+
+error:
+ cancel_work_sync(&dev->init_work);
+
+ return ret;
}
void mt7996_unregister_device(struct mt7996_dev *dev)
{
+ cancel_work_sync(&dev->wed_rro.work);
mt7996_unregister_phy(mt7996_phy3(dev), MT_BAND2);
mt7996_unregister_phy(mt7996_phy2(dev), MT_BAND1);
+ mt7996_unregister_thermal(&dev->phy);
mt7996_coredump_unregister(dev);
mt76_unregister_device(&dev->mt76);
+ mt7996_wed_rro_free(dev);
mt7996_mcu_exit(dev);
mt7996_tx_token_put(dev);
mt7996_dma_cleanup(dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 04540833485f..53258488d49f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -102,7 +102,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
};
struct ieee80211_sta *sta;
struct mt7996_sta *msta;
- struct rate_info *rate;
u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
LIST_HEAD(sta_poll_list);
int i;
@@ -118,7 +117,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
u32 addr, val;
u16 idx;
s8 rssi[4];
- u8 bw;
spin_lock_bh(&dev->mt76.sta_poll_lock);
if (list_empty(&sta_poll_list)) {
@@ -174,49 +172,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
ieee80211_sta_register_airtime(sta, tid, tx_cur, rx_cur);
}
- /* We don't support reading GI info from txs packets.
- * For accurate tx status reporting and AQL improvement,
- * we need to make sure that flags match so polling GI
- * from per-sta counters directly.
- */
- rate = &msta->wcid.rate;
-
- switch (rate->bw) {
- case RATE_INFO_BW_320:
- bw = IEEE80211_STA_RX_BW_320;
- break;
- case RATE_INFO_BW_160:
- bw = IEEE80211_STA_RX_BW_160;
- break;
- case RATE_INFO_BW_80:
- bw = IEEE80211_STA_RX_BW_80;
- break;
- case RATE_INFO_BW_40:
- bw = IEEE80211_STA_RX_BW_40;
- break;
- default:
- bw = IEEE80211_STA_RX_BW_20;
- break;
- }
-
- addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 6);
- val = mt76_rr(dev, addr);
- if (rate->flags & RATE_INFO_FLAGS_EHT_MCS) {
- addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 5);
- val = mt76_rr(dev, addr);
- rate->eht_gi = FIELD_GET(GENMASK(25, 24), val);
- } else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) {
- u8 offs = 24 + 2 * bw;
-
- rate->he_gi = (val & (0x3 << offs)) >> offs;
- } else if (rate->flags &
- (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_MCS)) {
- if (val & BIT(12 + bw))
- rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
- else
- rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
- }
-
/* get signal strength of resp frames (CTS/BA/ACK) */
addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
val = mt76_rr(dev, addr);
@@ -248,17 +203,6 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
mt76_clear(dev, addr, BIT(5));
}
-void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
- u8 tbl_idx, u16 rate_idx)
-{
- u32 ctrl = MT_WTBL_ITCR_WR | MT_WTBL_ITCR_EXEC | tbl_idx;
-
- mt76_wr(dev, MT_WTBL_ITDR0, rate_idx);
- /* use wtbl spe idx */
- mt76_wr(dev, MT_WTBL_ITDR1, MT_WTBL_SPE_IDX_SEL);
- mt76_wr(dev, MT_WTBL_ITCR, ctrl);
-}
-
/* The HW does not translate the mac header to 802.3 for mesh point */
static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
{
@@ -449,8 +393,36 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
return 0;
}
+static void
+mt7996_wed_check_ppe(struct mt7996_dev *dev, struct mt76_queue *q,
+ struct mt7996_sta *msta, struct sk_buff *skb,
+ u32 info)
+{
+ struct ieee80211_vif *vif;
+ struct wireless_dev *wdev;
+
+ if (!msta || !msta->vif)
+ return;
+
+ if (!mt76_queue_is_wed_rx(q))
+ return;
+
+ if (!(info & MT_DMA_INFO_PPE_VLD))
+ return;
+
+ vif = container_of((void *)msta->vif, struct ieee80211_vif,
+ drv_priv);
+ wdev = ieee80211_vif_to_wdev(vif);
+ skb->dev = wdev->netdev;
+
+ mtk_wed_device_ppe_check(&dev->mt76.mmio.wed, skb,
+ FIELD_GET(MT_DMA_PPE_CPU_REASON, info),
+ FIELD_GET(MT_DMA_PPE_ENTRY, info));
+}
+
static int
-mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
+ struct sk_buff *skb, u32 *info)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
struct mt76_phy *mphy = &dev->mt76.phy;
@@ -475,7 +447,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
u16 seq_ctrl = 0;
__le16 fc = 0;
int idx;
+ u8 hw_aggr = false;
+ struct mt7996_sta *msta = NULL;
+ hw_aggr = status->aggr;
memset(status, 0, sizeof(*status));
band_idx = FIELD_GET(MT_RXD1_NORMAL_BAND_IDX, rxd1);
@@ -502,8 +477,6 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
status->wcid = mt7996_rx_get_wcid(dev, idx, unicast);
if (status->wcid) {
- struct mt7996_sta *msta;
-
msta = container_of(status->wcid, struct mt7996_sta, wcid);
spin_lock_bh(&dev->mt76.sta_poll_lock);
if (list_empty(&msta->wcid.poll_list))
@@ -708,12 +681,14 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
}
} else {
status->flag |= RX_FLAG_8023;
+ mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
+ *info);
}
if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode);
- if (!status->wcid || !ieee80211_is_data_qos(fc))
+ if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr)
return 0;
status->aggr = unicast &&
@@ -840,10 +815,10 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
struct mt76_vif *mvif;
u16 tx_count = 15;
u32 val;
- bool beacon = !!(changed & (BSS_CHANGED_BEACON |
- BSS_CHANGED_BEACON_ENABLED));
bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
BSS_CHANGED_FILS_DISCOVERY));
+ bool beacon = !!(changed & (BSS_CHANGED_BEACON |
+ BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc);
mvif = vif ? (struct mt76_vif *)vif->drv_priv : NULL;
if (mvif) {
@@ -898,8 +873,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
val |= MT_TXD5_TX_STATUS_HOST;
txwi[5] = cpu_to_le32(val);
- val = MT_TXD6_DIS_MAT | MT_TXD6_DAS |
- FIELD_PREP(MT_TXD6_MSDU_CNT, 1);
+ val = MT_TXD6_DIS_MAT | MT_TXD6_DAS;
+ if (is_mt7996(&dev->mt76))
+ val |= FIELD_PREP(MT_TXD6_MSDU_CNT, 1);
+ else
+ val |= FIELD_PREP(MT_TXD6_MSDU_CNT_V2, 1);
txwi[6] = cpu_to_le32(val);
txwi[7] = 0;
@@ -923,7 +901,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
idx = mvif->basic_rates_idx;
}
- txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE, idx));
+ val = FIELD_PREP(MT_TXD6_TX_RATE, idx) | MT_TXD6_FIXED_BW;
+ txwi[6] |= cpu_to_le32(val);
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
}
}
@@ -963,8 +942,16 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
txp = (struct mt76_connac_txp_common *)(txwi + MT_TXD_SIZE);
for (i = 0; i < nbuf; i++) {
+ u16 len;
+
+ len = FIELD_PREP(MT_TXP_BUF_LEN, tx_info->buf[i + 1].len);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ len |= FIELD_PREP(MT_TXP_DMA_ADDR_H,
+ tx_info->buf[i + 1].addr >> 32);
+#endif
+
txp->fw.buf[i] = cpu_to_le32(tx_info->buf[i + 1].addr);
- txp->fw.len[i] = cpu_to_le16(tx_info->buf[i + 1].len);
+ txp->fw.len[i] = cpu_to_le16(len);
}
txp->fw.nbuf = nbuf;
@@ -996,6 +983,29 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
return 0;
}
+u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
+{
+ struct mt76_connac_fw_txp *txp = ptr + MT_TXD_SIZE;
+ __le32 *txwi = ptr;
+ u32 val;
+
+ memset(ptr, 0, MT_TXD_SIZE + sizeof(*txp));
+
+ val = FIELD_PREP(MT_TXD0_TX_BYTES, MT_TXD_SIZE) |
+ FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CT);
+ txwi[0] = cpu_to_le32(val);
+
+ val = BIT(31) |
+ FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3);
+ txwi[1] = cpu_to_le32(val);
+
+ txp->token = cpu_to_le16(token_id);
+ txp->nbuf = 1;
+ txp->buf[0] = cpu_to_le32(phys + MT_TXD_SIZE + sizeof(*txp));
+
+ return MT_TXD_SIZE + sizeof(*txp);
+}
+
static void
mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
{
@@ -1074,7 +1084,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
struct mt76_phy *phy3 = mdev->phys[MT_BAND2];
struct mt76_txwi_cache *txwi;
struct ieee80211_sta *sta = NULL;
- struct mt76_wcid *wcid;
+ struct mt76_wcid *wcid = NULL;
LIST_HEAD(free_list);
struct sk_buff *skb, *tmp;
void *end = data + len;
@@ -1254,6 +1264,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
goto out;
rate.flags = RATE_INFO_FLAGS_VHT_MCS;
+ if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
+ rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
break;
case MT_PHY_TYPE_HE_SU:
case MT_PHY_TYPE_HE_EXT_SU:
@@ -1403,6 +1415,12 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2) &&
+ q == MT_RXQ_TXFREE_BAND2) {
+ dev_kfree_skb(skb);
+ break;
+ }
+
mt7996_mac_tx_free(dev, skb->data, skb->len);
napi_consume_skb(skb, 1);
break;
@@ -1419,7 +1437,7 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
dev_kfree_skb(skb);
break;
case PKT_TYPE_NORMAL:
- if (!mt7996_mac_fill_rx(dev, skb)) {
+ if (!mt7996_mac_fill_rx(dev, q, skb, info)) {
mt76_rx(&dev->mt76, q, skb);
return;
}
@@ -1525,7 +1543,7 @@ mt7996_phy_get_nf(struct mt7996_phy *phy, u8 band_idx)
void mt7996_update_channel(struct mt76_phy *mphy)
{
- struct mt7996_phy *phy = (struct mt7996_phy *)mphy->priv;
+ struct mt7996_phy *phy = mphy->priv;
struct mt76_channel_state *state = mphy->chan_state;
int nf;
@@ -1652,6 +1670,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
/* disable all tx/rx napi */
mt76_worker_disable(&dev->mt76.tx_worker);
mt76_for_each_q_rx(mdev, i) {
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+ mt76_queue_is_wed_rro(&mdev->q_rx[i]))
+ continue;
+
if (mdev->q_rx[i].ndesc)
napi_disable(&dev->mt76.napi[i]);
}
@@ -1665,6 +1687,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
local_bh_disable();
mt76_for_each_q_rx(mdev, i) {
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+ mt76_queue_is_wed_rro(&mdev->q_rx[i]))
+ continue;
+
if (mdev->q_rx[i].ndesc) {
napi_enable(&dev->mt76.napi[i]);
napi_schedule(&dev->mt76.napi[i]);
@@ -1697,9 +1723,9 @@ mt7996_mac_restart(struct mt7996_dev *dev)
goto out;
mt7996_mac_init(dev);
- mt7996_init_txpower(dev, &dev->mphy.sband_2g.sband);
- mt7996_init_txpower(dev, &dev->mphy.sband_5g.sband);
- mt7996_init_txpower(dev, &dev->mphy.sband_6g.sband);
+ mt7996_init_txpower(&dev->phy);
+ mt7996_init_txpower(phy2);
+ mt7996_init_txpower(phy3);
ret = mt7996_txbf_init(dev);
if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
@@ -1754,6 +1780,7 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
if (phy3)
ieee80211_stop_queues(phy3->mt76->hw);
+ cancel_work_sync(&dev->wed_rro.work);
cancel_delayed_work_sync(&dev->mphy.mac_work);
if (phy2)
cancel_delayed_work_sync(&phy2->mt76->mac_work);
@@ -1836,6 +1863,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
dev_info(dev->mt76.dev,"\n%s L1 SER recovery start.",
wiphy_name(dev->mt76.hw->wiphy));
+
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
+ mtk_wed_device_stop(&dev->mt76.mmio.wed_hif2);
+
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
+ mtk_wed_device_stop(&dev->mt76.mmio.wed);
+
ieee80211_stop_queues(mt76_hw(dev));
if (phy2)
ieee80211_stop_queues(phy2->mt76->hw);
@@ -1845,6 +1879,8 @@ void mt7996_mac_reset_work(struct work_struct *work)
set_bit(MT76_RESET, &dev->mphy.state);
set_bit(MT76_MCU_RESET, &dev->mphy.state);
wake_up(&dev->mt76.mcu.wait);
+
+ cancel_work_sync(&dev->wed_rro.work);
cancel_delayed_work_sync(&dev->mphy.mac_work);
if (phy2) {
set_bit(MT76_RESET, &phy2->mt76->state);
@@ -1855,8 +1891,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
cancel_delayed_work_sync(&phy3->mt76->mac_work);
}
mt76_worker_disable(&dev->mt76.tx_worker);
- mt76_for_each_q_rx(&dev->mt76, i)
+ mt76_for_each_q_rx(&dev->mt76, i) {
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+ mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]))
+ continue;
+
napi_disable(&dev->mt76.napi[i]);
+ }
napi_disable(&dev->mt76.tx_napi);
mutex_lock(&dev->mt76.mutex);
@@ -1877,7 +1918,28 @@ void mt7996_mac_reset_work(struct work_struct *work)
mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
/* enable DMA Tx/Tx and interrupt */
- mt7996_dma_start(dev, false);
+ mt7996_dma_start(dev, false, false);
+
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+ u32 wed_irq_mask = MT_INT_RRO_RX_DONE | MT_INT_TX_DONE_BAND2 |
+ dev->mt76.mmio.irqmask;
+
+ if (mtk_wed_get_rx_capa(&dev->mt76.mmio.wed))
+ wed_irq_mask &= ~MT_INT_RX_DONE_RRO_IND;
+
+ mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
+
+ mtk_wed_device_start_hw_rro(&dev->mt76.mmio.wed, wed_irq_mask,
+ true);
+ mt7996_irq_enable(dev, wed_irq_mask);
+ mt7996_irq_disable(dev, 0);
+ }
+
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) {
+ mt76_wr(dev, MT_INT_PCIE1_MASK_CSR, MT_INT_TX_RX_DONE_EXT);
+ mtk_wed_device_start(&dev->mt76.mmio.wed_hif2,
+ MT_INT_TX_RX_DONE_EXT);
+ }
clear_bit(MT76_MCU_RESET, &dev->mphy.state);
clear_bit(MT76_RESET, &dev->mphy.state);
@@ -1888,6 +1950,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
local_bh_disable();
mt76_for_each_q_rx(&dev->mt76, i) {
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+ mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]))
+ continue;
+
napi_enable(&dev->mt76.napi[i]);
napi_schedule(&dev->mt76.napi[i]);
}
@@ -2187,7 +2253,9 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
IEEE80211_RC_BW_CHANGED))
mt7996_mcu_add_rate_ctrl(dev, vif, sta, true);
- /* TODO: smps change */
+ if (changed & IEEE80211_RC_SMPS_CHANGED)
+ mt7996_mcu_set_fixed_field(dev, vif, sta, NULL,
+ RATE_PARAM_MMPS_UPDATE);
spin_lock_bh(&dev->mt76.sta_poll_lock);
}
@@ -2212,6 +2280,7 @@ void mt7996_mac_work(struct work_struct *work)
mt7996_mac_update_stats(phy);
+ mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_RATE);
if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 09c7a28a3d51..51deea84b642 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -51,6 +51,14 @@ int mt7996_run(struct ieee80211_hw *hw)
if (ret)
goto out;
+ ret = mt7996_mcu_set_thermal_throttling(phy, MT7996_THERMAL_THROTTLE_MAX);
+ if (ret)
+ goto out;
+
+ ret = mt7996_mcu_set_thermal_protect(phy, true);
+ if (ret)
+ goto out;
+
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
@@ -342,6 +350,8 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
case WLAN_CIPHER_SUITE_SMS4:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
break;
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
@@ -365,9 +375,13 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}
mt76_wcid_key_setup(&dev->mt76, wcid, key);
- err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip,
- key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
- &msta->wcid, cmd);
+
+ if (key->keyidx == 6 || key->keyidx == 7)
+ err = mt7996_mcu_bcn_prot_enable(dev, vif, key);
+ else
+ err = mt7996_mcu_add_key(&dev->mt76, vif, key,
+ MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
+ &msta->wcid, cmd);
out:
mutex_unlock(&dev->mt76.mutex);
@@ -388,6 +402,13 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
ieee80211_wake_queues(hw);
}
+ if (changed & (IEEE80211_CONF_CHANGE_POWER |
+ IEEE80211_CONF_CHANGE_CHANNEL)) {
+ ret = mt7996_mcu_set_txpower_sku(phy);
+ if (ret)
+ return ret;
+ }
+
mutex_lock(&dev->mt76.mutex);
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
@@ -514,24 +535,25 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
struct mt76_phy *mphy = hw->priv;
u16 rate;
- u8 i, idx, ht;
+ u8 i, idx;
rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, mcast);
- ht = FIELD_GET(MT_TX_RATE_MODE, rate) > MT_PHY_TYPE_OFDM;
- if (beacon && ht) {
- struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ if (beacon) {
+ struct mt7996_phy *phy = mphy->priv;
+
+ /* odd index for driver, even index for firmware */
+ idx = MT7996_BEACON_RATES_TBL + 2 * phy->mt76->band_idx;
+ if (phy->beacon_rate != rate)
+ mt7996_mcu_set_fixed_rate_table(phy, idx, rate, beacon);
- /* must odd index */
- idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->idx % 20);
- mt7996_mac_set_fixed_rate_table(dev, idx, rate);
return idx;
}
idx = FIELD_GET(MT_TX_RATE_IDX, rate);
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++)
if ((mt76_rates[i].hw_value & GENMASK(7, 0)) == idx)
- return MT7996_BASIC_RATES_TBL + i;
+ return MT7996_BASIC_RATES_TBL + 2 * i;
return mvif->basic_rates_idx;
}
@@ -956,8 +978,8 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
mt76_set_stream_caps(phy->mt76, true);
mt7996_set_stream_vht_txbf_caps(phy);
mt7996_set_stream_he_eht_caps(phy);
+ mt7996_mcu_set_txpower_sku(phy);
- /* TODO: update bmc_wtbl spe_idx when antenna changes */
mutex_unlock(&dev->mt76.mutex);
return 0;
@@ -982,6 +1004,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
sinfo->txrate.he_gi = txrate->he_gi;
sinfo->txrate.he_dcm = txrate->he_dcm;
sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
+ sinfo->txrate.eht_gi = txrate->eht_gi;
}
sinfo->txrate.flags = txrate->flags;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
@@ -1388,6 +1411,44 @@ out:
return ret;
}
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+static int
+mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct net_device_path_ctx *ctx,
+ struct net_device_path *path)
+{
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+
+ if (phy != &dev->phy && phy->mt76->band_idx == MT_BAND2)
+ wed = &dev->mt76.mmio.wed_hif2;
+
+ if (!mtk_wed_device_active(wed))
+ return -ENODEV;
+
+ if (msta->wcid.idx > MT7996_WTBL_STA)
+ return -EIO;
+
+ path->type = DEV_PATH_MTK_WDMA;
+ path->dev = ctx->dev;
+ path->mtk_wdma.wdma_idx = wed->wdma_idx;
+ path->mtk_wdma.bss = mvif->mt76.idx;
+ path->mtk_wdma.queue = 0;
+ path->mtk_wdma.wcid = msta->wcid.idx;
+
+ path->mtk_wdma.amsdu = mtk_wed_is_amsdu_supported(wed);
+ ctx->dev = NULL;
+
+ return 0;
+}
+
+#endif
+
const struct ieee80211_ops mt7996_ops = {
.tx = mt7996_tx,
.start = mt7996_start,
@@ -1432,4 +1493,8 @@ const struct ieee80211_ops mt7996_ops = {
.sta_add_debugfs = mt7996_sta_add_debugfs,
#endif
.set_radar_background = mt7996_set_radar_background,
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ .net_fill_forward_path = mt7996_net_fill_forward_path,
+ .net_setup_tc = mt76_net_setup_tc,
+#endif
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index bf917beb9439..3c729b563edc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -10,6 +10,20 @@
#include "mac.h"
#include "eeprom.h"
+#define fw_name(_dev, name, ...) ({ \
+ char *_fw; \
+ switch (mt76_chip(&(_dev)->mt76)) { \
+ case 0x7992: \
+ _fw = MT7992_##name; \
+ break; \
+ case 0x7990: \
+ default: \
+ _fw = MT7996_##name; \
+ break; \
+ } \
+ _fw; \
+})
+
struct mt7996_patch_hdr {
char build_date[16];
char platform[4];
@@ -449,6 +463,43 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
}
}
+static int
+mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rate)
+{
+ switch (mcu_rate->tx_mode) {
+ case MT_PHY_TYPE_CCK:
+ case MT_PHY_TYPE_OFDM:
+ break;
+ case MT_PHY_TYPE_HT:
+ case MT_PHY_TYPE_HT_GF:
+ case MT_PHY_TYPE_VHT:
+ if (mcu_rate->tx_gi)
+ rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
+ else
+ rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
+ break;
+ case MT_PHY_TYPE_HE_SU:
+ case MT_PHY_TYPE_HE_EXT_SU:
+ case MT_PHY_TYPE_HE_TB:
+ case MT_PHY_TYPE_HE_MU:
+ if (mcu_rate->tx_gi > NL80211_RATE_INFO_HE_GI_3_2)
+ return -EINVAL;
+ rate->he_gi = mcu_rate->tx_gi;
+ break;
+ case MT_PHY_TYPE_EHT_SU:
+ case MT_PHY_TYPE_EHT_TRIG:
+ case MT_PHY_TYPE_EHT_MU:
+ if (mcu_rate->tx_gi > NL80211_RATE_INFO_EHT_GI_3_2)
+ return -EINVAL;
+ rate->eht_gi = mcu_rate->tx_gi;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static void
mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
{
@@ -465,6 +516,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
struct mt76_wcid *wcid;
switch (le16_to_cpu(res->tag)) {
+ case UNI_ALL_STA_TXRX_RATE:
+ wlan_idx = le16_to_cpu(res->rate[i].wlan_idx);
+ wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
+
+ if (!wcid)
+ break;
+
+ if (mt7996_mcu_update_tx_gi(&wcid->rate, &res->rate[i]))
+ dev_err(dev->mt76.dev, "Failed to update TX GI\n");
+ break;
case UNI_ALL_STA_TXRX_ADM_STAT:
wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx);
wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
@@ -498,6 +559,34 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
}
static void
+mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
+{
+#define THERMAL_NOTIFY_TAG 0x4
+#define THERMAL_NOTIFY 0x2
+ struct mt76_phy *mphy = &dev->mt76.phy;
+ struct mt7996_mcu_thermal_notify *n;
+ struct mt7996_phy *phy;
+
+ n = (struct mt7996_mcu_thermal_notify *)skb->data;
+
+ if (le16_to_cpu(n->tag) != THERMAL_NOTIFY_TAG)
+ return;
+
+ if (n->event_id != THERMAL_NOTIFY)
+ return;
+
+ if (n->band_idx > MT_BAND2)
+ return;
+
+ mphy = dev->mt76.phys[n->band_idx];
+ if (!mphy)
+ return;
+
+ phy = (struct mt7996_phy *)mphy->priv;
+ phy->throttle_state = n->duty_percent;
+}
+
+static void
mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb)
{
struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;
@@ -520,6 +609,9 @@ mt7996_mcu_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
case MCU_EVENT_EXT:
mt7996_mcu_rx_ext_event(dev, skb);
break;
+ case MCU_UNI_EVENT_THERMAL:
+ mt7996_mcu_rx_thermal_notify(dev, skb);
+ break;
default:
break;
}
@@ -527,6 +619,73 @@ mt7996_mcu_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
}
static void
+mt7996_mcu_wed_rro_event(struct mt7996_dev *dev, struct sk_buff *skb)
+{
+ struct mt7996_mcu_wed_rro_event *event = (void *)skb->data;
+
+ if (!dev->has_rro)
+ return;
+
+ skb_pull(skb, sizeof(struct mt7996_mcu_rxd) + 4);
+
+ switch (le16_to_cpu(event->tag)) {
+ case UNI_WED_RRO_BA_SESSION_STATUS: {
+ struct mt7996_mcu_wed_rro_ba_event *e;
+
+ while (skb->len >= sizeof(*e)) {
+ struct mt76_rx_tid *tid;
+ struct mt76_wcid *wcid;
+ u16 idx;
+
+ e = (void *)skb->data;
+ idx = le16_to_cpu(e->wlan_id);
+ if (idx >= ARRAY_SIZE(dev->mt76.wcid))
+ break;
+
+ wcid = rcu_dereference(dev->mt76.wcid[idx]);
+ if (!wcid || !wcid->sta)
+ break;
+
+ if (e->tid >= ARRAY_SIZE(wcid->aggr))
+ break;
+
+ tid = rcu_dereference(wcid->aggr[e->tid]);
+ if (!tid)
+ break;
+
+ tid->id = le16_to_cpu(e->id);
+ skb_pull(skb, sizeof(*e));
+ }
+ break;
+ }
+ case UNI_WED_RRO_BA_SESSION_DELETE: {
+ struct mt7996_mcu_wed_rro_ba_delete_event *e;
+
+ while (skb->len >= sizeof(*e)) {
+ struct mt7996_wed_rro_session_id *session;
+
+ e = (void *)skb->data;
+ session = kzalloc(sizeof(*session), GFP_ATOMIC);
+ if (!session)
+ break;
+
+ session->id = le16_to_cpu(e->session_id);
+
+ spin_lock_bh(&dev->wed_rro.lock);
+ list_add_tail(&session->list, &dev->wed_rro.poll_list);
+ spin_unlock_bh(&dev->wed_rro.lock);
+
+ ieee80211_queue_work(mt76_hw(dev), &dev->wed_rro.work);
+ skb_pull(skb, sizeof(*e));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void
mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
{
struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;
@@ -544,6 +703,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
case MCU_UNI_EVENT_ALL_STA_INFO:
mt7996_mcu_rx_all_sta_info_event(dev, skb);
break;
+ case MCU_UNI_EVENT_WED_RRO:
+ mt7996_mcu_wed_rro_event(dev, skb);
+ break;
default:
break;
}
@@ -963,7 +1125,7 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
}
static int
-mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
+mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif *mvif,
struct ieee80211_ampdu_params *params,
bool enable, bool tx)
{
@@ -972,7 +1134,7 @@ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
struct sk_buff *skb;
struct tlv *tlv;
- skb = __mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid,
+ skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, mvif, wcid,
MT7996_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
@@ -986,8 +1148,9 @@ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
ba->ba_en = enable << params->tid;
ba->amsdu = params->amsdu;
ba->tid = params->tid;
+ ba->ba_rdd_rro = !tx && enable && dev->has_rro;
- return mt76_mcu_skb_send_msg(dev, skb,
+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
}
@@ -1002,8 +1165,7 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
if (enable && !params->amsdu)
msta->wcid.amsdu = false;
- return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
- enable, true);
+ return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, true);
}
int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
@@ -1013,8 +1175,7 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
struct mt7996_sta *msta = (struct mt7996_sta *)params->sta->drv_priv;
struct mt7996_vif *mvif = msta->vif;
- return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
- enable, false);
+ return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, false);
}
static void
@@ -1108,7 +1269,7 @@ mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
static void
mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
{
- struct sta_rec_ht *ht;
+ struct sta_rec_ht_uni *ht;
struct tlv *tlv;
if (!sta->deflink.ht_cap.ht_supported)
@@ -1116,8 +1277,12 @@ mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
- ht = (struct sta_rec_ht *)tlv;
+ ht = (struct sta_rec_ht_uni *)tlv;
ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap);
+ ht->ampdu_param = u8_encode_bits(sta->deflink.ht_cap.ampdu_factor,
+ IEEE80211_HT_AMPDU_PARM_FACTOR) |
+ u8_encode_bits(sta->deflink.ht_cap.ampdu_density,
+ IEEE80211_HT_AMPDU_PARM_DENSITY);
}
static void
@@ -1575,44 +1740,6 @@ mt7996_mcu_sta_bfee_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
}
static void
-mt7996_mcu_sta_phy_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta)
-{
- struct sta_rec_phy *phy;
- struct tlv *tlv;
- u8 af = 0, mm = 0;
-
- if (!sta->deflink.ht_cap.ht_supported && !sta->deflink.he_6ghz_capa.capa)
- return;
-
- tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
-
- phy = (struct sta_rec_phy *)tlv;
- if (sta->deflink.ht_cap.ht_supported) {
- af = sta->deflink.ht_cap.ampdu_factor;
- mm = sta->deflink.ht_cap.ampdu_density;
- }
-
- if (sta->deflink.vht_cap.vht_supported) {
- u8 vht_af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
- sta->deflink.vht_cap.cap);
-
- af = max_t(u8, af, vht_af);
- }
-
- if (sta->deflink.he_6ghz_capa.capa) {
- af = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
- IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
- mm = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
- IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
- }
-
- phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR, af) |
- FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, mm);
- phy->max_ampdu_len = af;
-}
-
-static void
mt7996_mcu_sta_hdrt_tlv(struct mt7996_dev *dev, struct sk_buff *skb)
{
struct sta_rec_hdrt *hdrt;
@@ -1700,14 +1827,13 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
MCU_WM_UNI_CMD(RA), true);
}
-static int
-mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, void *data, u32 field)
+int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, void *data, u32 field)
{
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
- struct sta_phy *phy = data;
- struct sta_rec_ra_fixed *ra;
+ struct sta_phy_uni *phy = data;
+ struct sta_rec_ra_fixed_uni *ra;
struct sk_buff *skb;
struct tlv *tlv;
@@ -1718,7 +1844,7 @@ mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
return PTR_ERR(skb);
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
- ra = (struct sta_rec_ra_fixed *)tlv;
+ ra = (struct sta_rec_ra_fixed_uni *)tlv;
switch (field) {
case RATE_PARAM_AUTO:
@@ -1730,6 +1856,9 @@ mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
if (phy)
ra->phy = *phy;
break;
+ case RATE_PARAM_MMPS_UPDATE:
+ ra->mmps_mode = mt7996_mcu_get_mmps_mode(sta->deflink.smps_mode);
+ break;
default:
break;
}
@@ -1747,7 +1876,7 @@ mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev, struct ieee80211_vif *vif
struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
enum nl80211_band band = chandef->chan->band;
- struct sta_phy phy = {};
+ struct sta_phy_uni phy = {};
int ret, nrates = 0;
#define __sta_phy_bitrate_mask_check(_mcs, _gi, _ht, _he) \
@@ -1835,13 +1964,13 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
struct cfg80211_chan_def *chandef = &mphy->chandef;
struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
enum nl80211_band band = chandef->chan->band;
- struct sta_rec_ra *ra;
+ struct sta_rec_ra_uni *ra;
struct tlv *tlv;
u32 supp_rate = sta->deflink.supp_rates[band];
u32 cap = sta->wme ? STA_CAP_WMM : 0;
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra));
- ra = (struct sta_rec_ra *)tlv;
+ ra = (struct sta_rec_ra_uni *)tlv;
ra->valid = true;
ra->auto_rate = true;
@@ -2018,8 +2147,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
/* tag order is in accordance with firmware dependency. */
if (sta) {
- /* starec phy */
- mt7996_mcu_sta_phy_tlv(dev, skb, vif, sta);
/* starec hdrt mode */
mt7996_mcu_sta_hdrt_tlv(dev, skb);
/* starec bfer */
@@ -2058,7 +2185,6 @@ out:
static int
mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
- struct mt76_connac_sta_key_conf *sta_key_conf,
struct sk_buff *skb,
struct ieee80211_key_conf *key,
enum set_key_cmd cmd)
@@ -2079,43 +2205,22 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
return -EOPNOTSUPP;
sec_key = &sec->key[0];
+ sec_key->wlan_idx = cpu_to_le16(wcid->idx);
+ sec_key->mgmt_prot = 0;
+ sec_key->cipher_id = cipher;
sec_key->cipher_len = sizeof(*sec_key);
-
- if (cipher == MCU_CIPHER_BIP_CMAC_128) {
- sec_key->wlan_idx = cpu_to_le16(wcid->idx);
- sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
- sec_key->key_id = sta_key_conf->keyidx;
- sec_key->key_len = 16;
- memcpy(sec_key->key, sta_key_conf->key, 16);
-
- sec_key = &sec->key[1];
- sec_key->wlan_idx = cpu_to_le16(wcid->idx);
- sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
- sec_key->cipher_len = sizeof(*sec_key);
- sec_key->key_len = 16;
- memcpy(sec_key->key, key->key, 16);
- sec->n_cipher = 2;
- } else {
- sec_key->wlan_idx = cpu_to_le16(wcid->idx);
- sec_key->cipher_id = cipher;
- sec_key->key_id = key->keyidx;
- sec_key->key_len = key->keylen;
- memcpy(sec_key->key, key->key, key->keylen);
-
- if (cipher == MCU_CIPHER_TKIP) {
- /* Rx/Tx MIC keys are swapped */
- memcpy(sec_key->key + 16, key->key + 24, 8);
- memcpy(sec_key->key + 24, key->key + 16, 8);
- }
-
- /* store key_conf for BIP batch update */
- if (cipher == MCU_CIPHER_AES_CCMP) {
- memcpy(sta_key_conf->key, key->key, key->keylen);
- sta_key_conf->keyidx = key->keyidx;
- }
-
- sec->n_cipher = 1;
+ sec_key->key_id = key->keyidx;
+ sec_key->key_len = key->keylen;
+ sec_key->need_resp = 0;
+ memcpy(sec_key->key, key->key, key->keylen);
+
+ if (cipher == MCU_CIPHER_TKIP) {
+ /* Rx/Tx MIC keys are swapped */
+ memcpy(sec_key->key + 16, key->key + 24, 8);
+ memcpy(sec_key->key + 24, key->key + 16, 8);
}
+
+ sec->n_cipher = 1;
} else {
sec->n_cipher = 0;
}
@@ -2124,7 +2229,6 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
}
int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
- struct mt76_connac_sta_key_conf *sta_key_conf,
struct ieee80211_key_conf *key, int mcu_cmd,
struct mt76_wcid *wcid, enum set_key_cmd cmd)
{
@@ -2137,13 +2241,99 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
if (IS_ERR(skb))
return PTR_ERR(skb);
- ret = mt7996_mcu_sta_key_tlv(wcid, sta_key_conf, skb, key, cmd);
+ ret = mt7996_mcu_sta_key_tlv(wcid, skb, key, cmd);
if (ret)
return ret;
return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
}
+static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ u8 *pn)
+{
+#define TSC_TYPE_BIGTK_PN 2
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct sta_rec_pn_info *pn_info;
+ struct sk_buff *skb, *rskb;
+ struct tlv *tlv;
+ int ret;
+
+ skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PN_INFO, sizeof(*pn_info));
+ pn_info = (struct sta_rec_pn_info *)tlv;
+
+ pn_info->tsc_type = TSC_TYPE_BIGTK_PN;
+ ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb,
+ MCU_WM_UNI_CMD_QUERY(STA_REC_UPDATE),
+ true, &rskb);
+ if (ret)
+ return ret;
+
+ skb_pull(rskb, 4);
+
+ pn_info = (struct sta_rec_pn_info *)rskb->data;
+ if (le16_to_cpu(pn_info->tag) == STA_REC_PN_INFO)
+ memcpy(pn, pn_info->pn, 6);
+
+ dev_kfree_skb(rskb);
+ return 0;
+}
+
+int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *key)
+{
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt7996_mcu_bcn_prot_tlv *bcn_prot;
+ struct sk_buff *skb;
+ struct tlv *tlv;
+ u8 pn[6] = {};
+ int len = sizeof(struct bss_req_hdr) +
+ sizeof(struct mt7996_mcu_bcn_prot_tlv);
+ int ret;
+
+ skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BCN_PROT, sizeof(*bcn_prot));
+
+ bcn_prot = (struct mt7996_mcu_bcn_prot_tlv *)tlv;
+
+ ret = mt7996_mcu_get_pn(dev, vif, pn);
+ if (ret) {
+ dev_kfree_skb(skb);
+ return ret;
+ }
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_128;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_128;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+ default:
+ dev_err(dev->mt76.dev, "Not supported Bigtk Cipher\n");
+ dev_kfree_skb(skb);
+ return -EOPNOTSUPP;
+ }
+
+ pn[0]++;
+ memcpy(bcn_prot->pn, pn, 6);
+ bcn_prot->enable = BP_SW_MODE;
+ memcpy(bcn_prot->key, key->key, WLAN_MAX_KEY_LEN);
+ bcn_prot->key_id = key->keyidx;
+
+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
+}
int mt7996_mcu_add_dev_info(struct mt7996_phy *phy,
struct ieee80211_vif *vif, bool enable)
{
@@ -2463,7 +2653,7 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
return -EAGAIN;
}
- ret = request_firmware(&fw, MT7996_ROM_PATCH, dev->mt76.dev);
+ ret = request_firmware(&fw, fw_name(dev, ROM_PATCH), dev->mt76.dev);
if (ret)
goto out;
@@ -2626,17 +2816,17 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
{
int ret;
- ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
+ ret = __mt7996_load_ram(dev, "WM", fw_name(dev, FIRMWARE_WM),
MT7996_RAM_TYPE_WM);
if (ret)
return ret;
- ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP,
+ ret = __mt7996_load_ram(dev, "DSP", fw_name(dev, FIRMWARE_DSP),
MT7996_RAM_TYPE_DSP);
if (ret)
return ret;
- return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA,
+ return __mt7996_load_ram(dev, "WA", fw_name(dev, FIRMWARE_WA),
MT7996_RAM_TYPE_WA);
}
@@ -2788,9 +2978,10 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
{
struct uni_header hdr = {};
struct sk_buff *skb;
- int len, num;
+ int len, num, i;
- num = 2 + 2 * (dev->dbdc_support + dev->tbtc_support);
+ num = 2 + 2 * (mt7996_band_valid(dev, MT_BAND1) +
+ mt7996_band_valid(dev, MT_BAND2));
len = sizeof(hdr) + num * sizeof(struct vow_rx_airtime);
skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);
if (!skb)
@@ -2798,13 +2989,10 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
skb_put_data(skb, &hdr, sizeof(hdr));
- mt7996_add_rx_airtime_tlv(skb, dev->mt76.phy.band_idx);
-
- if (dev->dbdc_support)
- mt7996_add_rx_airtime_tlv(skb, MT_BAND1);
-
- if (dev->tbtc_support)
- mt7996_add_rx_airtime_tlv(skb, MT_BAND2);
+ for (i = 0; i < __MT_MAX_BAND; i++) {
+ if (mt7996_band_valid(dev, i))
+ mt7996_add_rx_airtime_tlv(skb, i);
+ }
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_WM_UNI_CMD(VOW), true);
@@ -3230,7 +3418,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
.center_ch = ieee80211_frequency_to_channel(freq1),
.bw = mt76_connac_chan_bw(chandef),
.tx_path_num = hweight16(phy->mt76->chainmask),
- .rx_path = phy->mt76->chainmask >> dev->chainshift[band_idx],
+ .rx_path = mt7996_rx_chainmask(phy) >> dev->chainshift[band_idx],
.band_idx = band_idx,
.channel_band = ch_band[chandef->chan->band],
};
@@ -3502,6 +3690,121 @@ out:
return 0;
}
+int mt7996_mcu_get_temperature(struct mt7996_phy *phy)
+{
+#define TEMPERATURE_QUERY 0
+#define GET_TEMPERATURE 0
+ struct {
+ u8 _rsv[4];
+
+ __le16 tag;
+ __le16 len;
+
+ u8 rsv1;
+ u8 action;
+ u8 band_idx;
+ u8 rsv2;
+ } req = {
+ .tag = cpu_to_le16(TEMPERATURE_QUERY),
+ .len = cpu_to_le16(sizeof(req) - 4),
+ .action = GET_TEMPERATURE,
+ .band_idx = phy->mt76->band_idx,
+ };
+ struct mt7996_mcu_thermal {
+ u8 _rsv[4];
+
+ __le16 tag;
+ __le16 len;
+
+ __le32 rsv;
+ __le32 temperature;
+ } __packed * res;
+ struct sk_buff *skb;
+ int ret;
+
+ ret = mt76_mcu_send_and_get_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
+ &req, sizeof(req), true, &skb);
+ if (ret)
+ return ret;
+
+ res = (void *)skb->data;
+
+ return le32_to_cpu(res->temperature);
+}
+
+int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state)
+{
+ struct {
+ u8 _rsv[4];
+
+ __le16 tag;
+ __le16 len;
+
+ struct mt7996_mcu_thermal_ctrl ctrl;
+ } __packed req = {
+ .tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG),
+ .len = cpu_to_le16(sizeof(req) - 4),
+ .ctrl = {
+ .band_idx = phy->mt76->band_idx,
+ },
+ };
+ int level, ret;
+
+ /* set duty cycle and level */
+ for (level = 0; level < 4; level++) {
+ req.ctrl.duty.duty_level = level;
+ req.ctrl.duty.duty_cycle = state;
+ state /= 2;
+
+ ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
+ &req, sizeof(req), false);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable)
+{
+#define SUSTAIN_PERIOD 10
+ struct {
+ u8 _rsv[4];
+
+ __le16 tag;
+ __le16 len;
+
+ struct mt7996_mcu_thermal_ctrl ctrl;
+ struct mt7996_mcu_thermal_enable enable;
+ } __packed req = {
+ .len = cpu_to_le16(sizeof(req) - 4 - sizeof(req.enable)),
+ .ctrl = {
+ .band_idx = phy->mt76->band_idx,
+ .type.protect_type = 1,
+ .type.trigger_type = 1,
+ },
+ };
+ int ret;
+
+ req.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_DISABLE);
+
+ ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
+ &req, sizeof(req) - sizeof(req.enable), false);
+ if (ret || !enable)
+ return ret;
+
+ /* set high-temperature trigger threshold */
+ req.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_ENABLE);
+ req.enable.restore_temp = cpu_to_le32(phy->throttle_temp[0]);
+ req.enable.trigger_temp = cpu_to_le32(phy->throttle_temp[1]);
+ req.enable.sustain_time = cpu_to_le16(SUSTAIN_PERIOD);
+
+ req.len = cpu_to_le16(sizeof(req) - 4);
+
+ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
+ &req, sizeof(req), false);
+}
+
int mt7996_mcu_set_ser(struct mt7996_dev *dev, u8 action, u8 val, u8 band)
{
struct {
@@ -3964,6 +4267,35 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
}
+int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
+ u16 rate_idx, bool beacon)
+{
+#define UNI_FIXED_RATE_TABLE_SET 0
+#define SPE_IXD_SELECT_TXD 0
+#define SPE_IXD_SELECT_BMC_WTBL 1
+ struct mt7996_dev *dev = phy->dev;
+ struct fixed_rate_table_ctrl req = {
+ .tag = cpu_to_le16(UNI_FIXED_RATE_TABLE_SET),
+ .len = cpu_to_le16(sizeof(req) - 4),
+ .table_idx = table_idx,
+ .rate_idx = cpu_to_le16(rate_idx),
+ .gi = 1,
+ .he_ltf = 1,
+ };
+ u8 band_idx = phy->mt76->band_idx;
+
+ if (beacon) {
+ req.spe_idx_sel = SPE_IXD_SELECT_TXD;
+ req.spe_idx = 24 + band_idx;
+ phy->beacon_rate = rate_idx;
+ } else {
+ req.spe_idx_sel = SPE_IXD_SELECT_BMC_WTBL;
+ }
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(FIXED_RATE_TABLE),
+ &req, sizeof(req), false);
+}
+
int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
{
struct {
@@ -4019,14 +4351,12 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev)
&req, sizeof(req), false);
}
-int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
+int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val)
{
struct {
u8 __rsv1[4];
-
__le16 tag;
__le16 len;
-
union {
struct {
u8 type;
@@ -4041,6 +4371,11 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
u8 path;
u8 __rsv2[3];
} __packed txfree_path;
+ struct {
+ __le16 flush_one;
+ __le16 flush_all;
+ u8 __rsv2[4];
+ } __packed timeout;
};
} __packed req = {
.tag = cpu_to_le16(tag),
@@ -4057,6 +4392,10 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
case UNI_RRO_SET_TXFREE_PATH:
req.txfree_path.path = val;
break;
+ case UNI_RRO_SET_FLUSH_TIMEOUT:
+ req.timeout.flush_one = cpu_to_le16(val);
+ req.timeout.flush_all = cpu_to_le16(2 * val);
+ break;
default:
return -EINVAL;
}
@@ -4081,3 +4420,80 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO),
&req, sizeof(req), false);
}
+
+int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id)
+{
+ struct {
+ u8 __rsv[4];
+
+ __le16 tag;
+ __le16 len;
+ __le16 session_id;
+ u8 pad[4];
+ } __packed req = {
+ .tag = cpu_to_le16(UNI_RRO_DEL_BA_SESSION),
+ .len = cpu_to_le16(sizeof(req) - 4),
+ .session_id = cpu_to_le16(id),
+ };
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO), &req,
+ sizeof(req), true);
+}
+
+int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+{
+#define TX_POWER_LIMIT_TABLE_RATE 0
+ struct mt7996_dev *dev = phy->dev;
+ struct mt76_phy *mphy = phy->mt76;
+ struct ieee80211_hw *hw = mphy->hw;
+ struct tx_power_limit_table_ctrl {
+ u8 __rsv1[4];
+
+ __le16 tag;
+ __le16 len;
+ u8 power_ctrl_id;
+ u8 power_limit_type;
+ u8 band_idx;
+ } __packed req = {
+ .tag = cpu_to_le16(UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL),
+ .len = cpu_to_le16(sizeof(req) + MT7996_SKU_RATE_NUM - 4),
+ .power_ctrl_id = UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL,
+ .power_limit_type = TX_POWER_LIMIT_TABLE_RATE,
+ .band_idx = phy->mt76->band_idx,
+ };
+ struct mt76_power_limits la = {};
+ struct sk_buff *skb;
+ int i, tx_power;
+
+ tx_power = mt7996_get_power_bound(phy, hw->conf.power_level);
+ tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
+ &la, tx_power);
+ mphy->txpower_cur = tx_power;
+
+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
+ sizeof(req) + MT7996_SKU_RATE_NUM);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put_data(skb, &req, sizeof(req));
+ /* cck and ofdm */
+ skb_put_data(skb, &la.cck, sizeof(la.cck) + sizeof(la.ofdm));
+ /* ht20 */
+ skb_put_data(skb, &la.mcs[0], 8);
+ /* ht40 */
+ skb_put_data(skb, &la.mcs[1], 9);
+
+ /* vht */
+ for (i = 0; i < 4; i++) {
+ skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));
+ skb_put_zero(skb, 2); /* padding */
+ }
+
+ /* he */
+ skb_put_data(skb, &la.ru[0], sizeof(la.ru));
+ /* eht */
+ skb_put_data(skb, &la.eht[0], sizeof(la.eht));
+
+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_WM_UNI_CMD(TXPOWER), true);
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
index a88f6af323da..36cacc495c75 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
@@ -30,6 +30,28 @@ struct mt7996_mcu_uni_event {
__le32 status; /* 0: success, others: fail */
} __packed;
+struct mt7996_mcu_thermal_ctrl {
+ u8 ctrl_id;
+ u8 band_idx;
+ union {
+ struct {
+ u8 protect_type; /* 1: duty admit, 2: radio off */
+ u8 trigger_type; /* 0: low, 1: high */
+ } __packed type;
+ struct {
+ u8 duty_level; /* level 0~3 */
+ u8 duty_cycle;
+ } __packed duty;
+ };
+} __packed;
+
+struct mt7996_mcu_thermal_enable {
+ __le32 trigger_temp;
+ __le32 restore_temp;
+ __le16 sustain_time;
+ u8 rsv[2];
+} __packed;
+
struct mt7996_mcu_csa_notify {
struct mt7996_mcu_rxd rxd;
@@ -153,6 +175,27 @@ struct mt7996_mcu_mib {
__le64 data;
} __packed;
+struct all_sta_trx_rate {
+ __le16 wlan_idx;
+ u8 __rsv1[2];
+ u8 tx_mode;
+ u8 flags;
+ u8 tx_stbc;
+ u8 tx_gi;
+ u8 tx_bw;
+ u8 tx_ldpc;
+ u8 tx_mcs;
+ u8 tx_nss;
+ u8 rx_rate;
+ u8 rx_mode;
+ u8 rx_nsts;
+ u8 rx_gi;
+ u8 rx_coding;
+ u8 rx_stbc;
+ u8 rx_bw;
+ u8 __rsv2;
+} __packed;
+
struct mt7996_mcu_all_sta_info_event {
u8 rsv[4];
__le16 tag;
@@ -160,23 +203,75 @@ struct mt7996_mcu_all_sta_info_event {
u8 more;
u8 rsv2;
__le16 sta_num;
- u8 rsv3[2];
+ u8 rsv3[4];
union {
- struct {
+ DECLARE_FLEX_ARRAY(struct all_sta_trx_rate, rate);
+ DECLARE_FLEX_ARRAY(struct {
__le16 wlan_idx;
u8 rsv[2];
__le32 tx_bytes[IEEE80211_NUM_ACS];
__le32 rx_bytes[IEEE80211_NUM_ACS];
- } adm_stat[0];
+ } __packed, adm_stat);
- struct {
+ DECLARE_FLEX_ARRAY(struct {
__le16 wlan_idx;
u8 rsv[2];
__le32 tx_msdu_cnt;
__le32 rx_msdu_cnt;
- } msdu_cnt[0];
- };
+ } __packed, msdu_cnt);
+ } __packed;
+} __packed;
+
+struct mt7996_mcu_wed_rro_event {
+ struct mt7996_mcu_rxd rxd;
+
+ u8 __rsv1[4];
+
+ __le16 tag;
+ __le16 len;
+} __packed;
+
+struct mt7996_mcu_wed_rro_ba_event {
+ __le16 tag;
+ __le16 len;
+
+ __le16 wlan_id;
+ u8 tid;
+ u8 __rsv1;
+ __le32 status;
+ __le16 id;
+ u8 __rsv2[2];
+} __packed;
+
+struct mt7996_mcu_wed_rro_ba_delete_event {
+ __le16 tag;
+ __le16 len;
+
+ __le16 session_id;
+ u8 __rsv2[2];
+} __packed;
+
+enum {
+ UNI_WED_RRO_BA_SESSION_STATUS,
+ UNI_WED_RRO_BA_SESSION_TBL,
+ UNI_WED_RRO_BA_SESSION_DELETE,
+};
+
+struct mt7996_mcu_thermal_notify {
+ struct mt7996_mcu_rxd rxd;
+
+ u8 __rsv1[4];
+
+ __le16 tag;
+ __le16 len;
+
+ u8 event_id;
+ u8 band_idx;
+ u8 level_idx;
+ u8 duty_percent;
+ __le32 restore_temp;
+ u8 __rsv2[4];
} __packed;
enum mt7996_chan_mib_offs {
@@ -247,7 +342,24 @@ struct bss_rate_tlv {
u8 short_preamble;
u8 bc_fixed_rate;
u8 mc_fixed_rate;
- u8 __rsv2[1];
+ u8 __rsv2[9];
+} __packed;
+
+enum {
+ BP_DISABLE,
+ BP_SW_MODE,
+ BP_HW_MODE,
+};
+
+struct mt7996_mcu_bcn_prot_tlv {
+ __le16 tag;
+ __le16 len;
+ u8 pn[6];
+ u8 enable;
+ u8 cipher_id;
+ u8 key[WLAN_MAX_KEY_LEN];
+ u8 key_id;
+ u8 __rsv[3];
} __packed;
struct bss_ra_tlv {
@@ -372,6 +484,15 @@ struct bss_mld_tlv {
u8 __rsv[3];
} __packed;
+struct sta_rec_ht_uni {
+ __le16 tag;
+ __le16 len;
+ __le16 ht_cap;
+ __le16 ht_cap_ext;
+ u8 ampdu_param;
+ u8 _rsv[3];
+} __packed;
+
struct sta_rec_ba_uni {
__le16 tag;
__le16 len;
@@ -421,6 +542,73 @@ struct sta_rec_sec_uni {
struct sec_key_uni key[2];
} __packed;
+struct sta_phy_uni {
+ u8 type;
+ u8 flag;
+ u8 stbc;
+ u8 sgi;
+ u8 bw;
+ u8 ldpc;
+ u8 mcs;
+ u8 nss;
+ u8 he_ltf;
+ u8 rsv[3];
+};
+
+struct sta_rec_ra_uni {
+ __le16 tag;
+ __le16 len;
+
+ u8 valid;
+ u8 auto_rate;
+ u8 phy_mode;
+ u8 channel;
+ u8 bw;
+ u8 disable_cck;
+ u8 ht_mcs32;
+ u8 ht_gf;
+ u8 ht_mcs[4];
+ u8 mmps_mode;
+ u8 gband_256;
+ u8 af;
+ u8 auth_wapi_mode;
+ u8 rate_len;
+
+ u8 supp_mode;
+ u8 supp_cck_rate;
+ u8 supp_ofdm_rate;
+ __le32 supp_ht_mcs;
+ __le16 supp_vht_mcs[4];
+
+ u8 op_mode;
+ u8 op_vht_chan_width;
+ u8 op_vht_rx_nss;
+ u8 op_vht_rx_nss_type;
+
+ __le32 sta_cap;
+
+ struct sta_phy_uni phy;
+ u8 rx_rcpi[4];
+} __packed;
+
+struct sta_rec_ra_fixed_uni {
+ __le16 tag;
+ __le16 len;
+
+ __le32 field;
+ u8 op_mode;
+ u8 op_vht_chan_width;
+ u8 op_vht_rx_nss;
+ u8 op_vht_rx_nss_type;
+
+ struct sta_phy_uni phy;
+
+ u8 spe_idx;
+ u8 short_preamble;
+ u8 is_5g;
+ u8 mmps_mode;
+} __packed;
+
struct sta_rec_hdrt {
__le16 tag;
__le16 len;
@@ -596,17 +784,16 @@ enum {
#define MT7996_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
sizeof(struct sta_rec_basic) + \
sizeof(struct sta_rec_bf) + \
- sizeof(struct sta_rec_ht) + \
+ sizeof(struct sta_rec_ht_uni) + \
sizeof(struct sta_rec_he_v2) + \
sizeof(struct sta_rec_ba_uni) + \
sizeof(struct sta_rec_vht) + \
sizeof(struct sta_rec_uapsd) + \
sizeof(struct sta_rec_amsdu) + \
sizeof(struct sta_rec_bfee) + \
- sizeof(struct sta_rec_phy) + \
- sizeof(struct sta_rec_ra) + \
+ sizeof(struct sta_rec_ra_uni) + \
sizeof(struct sta_rec_sec) + \
- sizeof(struct sta_rec_ra_fixed) + \
+ sizeof(struct sta_rec_ra_fixed_uni) + \
sizeof(struct sta_rec_he_6g_capa) + \
sizeof(struct sta_rec_eht) + \
sizeof(struct sta_rec_hdrt) + \
@@ -622,6 +809,18 @@ enum {
#define MT7996_MAX_BSS_OFFLOAD_SIZE (MT7996_MAX_BEACON_SIZE + \
MT7996_BEACON_UPDATE_SIZE)
+static inline s8
+mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
+{
+ struct mt76_phy *mphy = phy->mt76;
+ int n_chains = hweight16(mphy->chainmask);
+
+ txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * 2);
+ txpower -= mt76_tx_power_nss_delta(n_chains);
+
+ return txpower;
+}
+
enum {
UNI_BAND_CONFIG_RADIO_ENABLE,
UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
@@ -669,6 +868,8 @@ enum {
UNI_RRO_GET_BA_SESSION_TABLE,
UNI_RRO_SET_BYPASS_MODE,
UNI_RRO_SET_TXFREE_PATH,
+ UNI_RRO_DEL_BA_SESSION,
+ UNI_RRO_SET_FLUSH_TIMEOUT
};
enum{
@@ -683,6 +884,16 @@ enum{
};
enum {
+ UNI_CMD_THERMAL_PROTECT_ENABLE = 0x6,
+ UNI_CMD_THERMAL_PROTECT_DISABLE,
+ UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG,
+};
+
+enum {
+ UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4,
+};
+
+enum {
UNI_CMD_ACCESS_REG_BASIC = 0x0,
UNI_CMD_ACCESS_RF_REG_BASIC,
};
@@ -720,4 +931,24 @@ enum {
#define MT7996_SEC_KEY_IDX GENMASK(2, 1)
#define MT7996_SEC_IV BIT(3)
+struct fixed_rate_table_ctrl {
+ u8 _rsv[4];
+
+ __le16 tag;
+ __le16 len;
+
+ u8 table_idx;
+ u8 antenna_idx;
+ __le16 rate_idx;
+ u8 spe_idx_sel;
+ u8 spe_idx;
+ u8 gi;
+ u8 he_ltf;
+ bool ldpc;
+ bool txbf;
+ bool dynamic_bw;
+
+ u8 _rsv2;
+} __packed;
+
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
index 3a591a7b47ae..c50d89a445e9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
@@ -6,10 +6,16 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/rtnetlink.h>
#include "mt7996.h"
#include "mac.h"
+#include "mcu.h"
#include "../trace.h"
+#include "../dma.h"
+
+static bool wed_enable;
+module_param(wed_enable, bool, 0644);
static const struct __base mt7996_reg_base[] = {
[WF_AGG_BASE] = { { 0x820e2000, 0x820f2000, 0x830e2000 } },
@@ -24,6 +30,58 @@ static const struct __base mt7996_reg_base[] = {
[WF_RATE_BASE] = { { 0x820ee000, 0x820fe000, 0x830ee000 } },
};
+static const u32 mt7996_offs[] = {
+ [MIB_RVSR0] = 0x720,
+ [MIB_RVSR1] = 0x724,
+ [MIB_BTSCR5] = 0x788,
+ [MIB_BTSCR6] = 0x798,
+ [MIB_RSCR1] = 0x7ac,
+ [MIB_RSCR27] = 0x954,
+ [MIB_RSCR28] = 0x958,
+ [MIB_RSCR29] = 0x95c,
+ [MIB_RSCR30] = 0x960,
+ [MIB_RSCR31] = 0x964,
+ [MIB_RSCR33] = 0x96c,
+ [MIB_RSCR35] = 0x974,
+ [MIB_RSCR36] = 0x978,
+ [MIB_BSCR0] = 0x9cc,
+ [MIB_BSCR1] = 0x9d0,
+ [MIB_BSCR2] = 0x9d4,
+ [MIB_BSCR3] = 0x9d8,
+ [MIB_BSCR4] = 0x9dc,
+ [MIB_BSCR5] = 0x9e0,
+ [MIB_BSCR6] = 0x9e4,
+ [MIB_BSCR7] = 0x9e8,
+ [MIB_BSCR17] = 0xa10,
+ [MIB_TRDR1] = 0xa28,
+};
+
+static const u32 mt7992_offs[] = {
+ [MIB_RVSR0] = 0x760,
+ [MIB_RVSR1] = 0x764,
+ [MIB_BTSCR5] = 0x7c8,
+ [MIB_BTSCR6] = 0x7d8,
+ [MIB_RSCR1] = 0x7f0,
+ [MIB_RSCR27] = 0x998,
+ [MIB_RSCR28] = 0x99c,
+ [MIB_RSCR29] = 0x9a0,
+ [MIB_RSCR30] = 0x9a4,
+ [MIB_RSCR31] = 0x9a8,
+ [MIB_RSCR33] = 0x9b0,
+ [MIB_RSCR35] = 0x9b8,
+ [MIB_RSCR36] = 0x9bc,
+ [MIB_BSCR0] = 0xac8,
+ [MIB_BSCR1] = 0xacc,
+ [MIB_BSCR2] = 0xad0,
+ [MIB_BSCR3] = 0xad4,
+ [MIB_BSCR4] = 0xad8,
+ [MIB_BSCR5] = 0xadc,
+ [MIB_BSCR6] = 0xae0,
+ [MIB_BSCR7] = 0xae4,
+ [MIB_BSCR17] = 0xb0c,
+ [MIB_TRDR1] = 0xb24,
+};
+
static const struct __map mt7996_reg_map[] = {
{ 0x54000000, 0x02000, 0x1000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */
{ 0x55000000, 0x03000, 0x1000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */
@@ -191,6 +249,169 @@ static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
return dev->bus_ops->rmw(mdev, __mt7996_reg_addr(dev, offset), mask, val);
}
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+static int mt7996_mmio_wed_reset(struct mtk_wed_device *wed)
+{
+ struct mt76_dev *mdev = container_of(wed, struct mt76_dev, mmio.wed);
+ struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
+ struct mt76_phy *mphy = &dev->mphy;
+ int ret;
+
+ ASSERT_RTNL();
+
+ if (test_and_set_bit(MT76_STATE_WED_RESET, &mphy->state))
+ return -EBUSY;
+
+ ret = mt7996_mcu_set_ser(dev, UNI_CMD_SER_TRIGGER, UNI_CMD_SER_SET_RECOVER_L1,
+ mphy->band_idx);
+ if (ret)
+ goto out;
+
+ rtnl_unlock();
+ if (!wait_for_completion_timeout(&mdev->mmio.wed_reset, 20 * HZ)) {
+ dev_err(mdev->dev, "wed reset timeout\n");
+ ret = -ETIMEDOUT;
+ }
+ rtnl_lock();
+out:
+ clear_bit(MT76_STATE_WED_RESET, &mphy->state);
+
+ return ret;
+}
+#endif
+
+int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ bool hif2, int *irq)
+{
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ struct pci_dev *pci_dev = pdev_ptr;
+ u32 hif1_ofs = 0;
+
+ if (!wed_enable)
+ return 0;
+
+ dev->has_rro = true;
+
+ hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
+
+ if (hif2)
+ wed = &dev->mt76.mmio.wed_hif2;
+
+ wed->wlan.pci_dev = pci_dev;
+ wed->wlan.bus_type = MTK_WED_BUS_PCIE;
+
+ wed->wlan.base = devm_ioremap(dev->mt76.dev,
+ pci_resource_start(pci_dev, 0),
+ pci_resource_len(pci_dev, 0));
+ wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
+
+ if (hif2) {
+ wed->wlan.wpdma_int = wed->wlan.phy_base +
+ MT_INT_PCIE1_SOURCE_CSR_EXT;
+ wed->wlan.wpdma_mask = wed->wlan.phy_base +
+ MT_INT_PCIE1_MASK_CSR;
+ wed->wlan.wpdma_tx = wed->wlan.phy_base + hif1_ofs +
+ MT_TXQ_RING_BASE(0) +
+ MT7996_TXQ_BAND2 * MT_RING_SIZE;
+ if (dev->has_rro) {
+ wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
+ MT_RXQ_RING_BASE(0) +
+ MT7996_RXQ_TXFREE2 * MT_RING_SIZE;
+ wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_EXT) - 1;
+ } else {
+ wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
+ MT_RXQ_RING_BASE(0) +
+ MT7996_RXQ_MCU_WA_TRI * MT_RING_SIZE;
+ wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
+ }
+
+ wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
+ wed->wlan.wpdma_rx = wed->wlan.phy_base + hif1_ofs +
+ MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
+ MT7996_RXQ_BAND0 * MT_RING_SIZE;
+
+ wed->wlan.id = 0x7991;
+ wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
+ } else {
+ wed->wlan.hw_rro = dev->has_rro; /* default on */
+ wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
+ wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
+ wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
+ MT7996_TXQ_BAND0 * MT_RING_SIZE;
+
+ wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
+
+ wed->wlan.wpdma_rx = wed->wlan.phy_base +
+ MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
+ MT7996_RXQ_BAND0 * MT_RING_SIZE;
+
+ wed->wlan.wpdma_rx_rro[0] = wed->wlan.phy_base +
+ MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND0) +
+ MT7996_RXQ_RRO_BAND0 * MT_RING_SIZE;
+ wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
+ MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
+ MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
+ wed->wlan.wpdma_rx_pg = wed->wlan.phy_base +
+ MT_RXQ_RING_BASE(MT7996_RXQ_MSDU_PG_BAND0) +
+ MT7996_RXQ_MSDU_PG_BAND0 * MT_RING_SIZE;
+
+ wed->wlan.rx_nbuf = 65536;
+ wed->wlan.rx_npkt = dev->hif2 ? 32768 : 24576;
+ wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
+
+ wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
+ wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
+
+ wed->wlan.rro_rx_tbit[0] = ffs(MT_INT_RX_DONE_RRO_BAND0) - 1;
+ wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND2) - 1;
+
+ wed->wlan.rx_pg_tbit[0] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND0) - 1;
+ wed->wlan.rx_pg_tbit[1] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND1) - 1;
+ wed->wlan.rx_pg_tbit[2] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND2) - 1;
+
+ wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
+ wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
+ if (dev->has_rro) {
+ wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
+ MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
+ wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
+ } else {
+ wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
+ wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
+ MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
+ }
+ dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
+ }
+
+ wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE;
+ wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf;
+
+ wed->wlan.amsdu_max_subframes = 8;
+ wed->wlan.amsdu_max_len = 1536;
+
+ wed->wlan.init_buf = mt7996_wed_init_buf;
+ wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
+ wed->wlan.release_rx_buf = mt76_mmio_wed_release_rx_buf;
+ wed->wlan.offload_enable = mt76_mmio_wed_offload_enable;
+ wed->wlan.offload_disable = mt76_mmio_wed_offload_disable;
+ if (!hif2) {
+ wed->wlan.reset = mt7996_mmio_wed_reset;
+ wed->wlan.reset_complete = mt76_mmio_wed_reset_complete;
+ }
+
+ if (mtk_wed_device_attach(wed))
+ return 0;
+
+ *irq = wed->irq;
+ dev->mt76.dma_dev = wed->dev;
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
static int mt7996_mmio_init(struct mt76_dev *mdev,
void __iomem *mem_base,
u32 device_id)
@@ -204,6 +425,13 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
switch (device_id) {
case 0x7990:
dev->reg.base = mt7996_reg_base;
+ dev->reg.offs_rev = mt7996_offs;
+ dev->reg.map = mt7996_reg_map;
+ dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
+ break;
+ case 0x7992:
+ dev->reg.base = mt7996_reg_base;
+ dev->reg.offs_rev = mt7992_offs;
dev->reg.map = mt7996_reg_map;
dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
break;
@@ -241,8 +469,17 @@ void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
mdev->mmio.irqmask |= set;
if (write_reg) {
- mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
- mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
+ if (mtk_wed_device_active(&mdev->mmio.wed)) {
+ mtk_wed_device_irq_set_mask(&mdev->mmio.wed,
+ mdev->mmio.irqmask);
+ if (mtk_wed_device_active(&mdev->mmio.wed_hif2)) {
+ mtk_wed_device_irq_set_mask(&mdev->mmio.wed_hif2,
+ mdev->mmio.irqmask);
+ }
+ } else {
+ mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
+ mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
+ }
}
spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);
@@ -260,22 +497,36 @@ static void mt7996_rx_poll_complete(struct mt76_dev *mdev,
static void mt7996_irq_tasklet(struct tasklet_struct *t)
{
struct mt7996_dev *dev = from_tasklet(dev, t, mt76.irq_tasklet);
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
u32 i, intr, mask, intr1;
- mt76_wr(dev, MT_INT_MASK_CSR, 0);
- if (dev->hif2)
- mt76_wr(dev, MT_INT1_MASK_CSR, 0);
-
- intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
- intr &= dev->mt76.mmio.irqmask;
- mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
-
- if (dev->hif2) {
- intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
- intr1 &= dev->mt76.mmio.irqmask;
- mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
+ if (dev->hif2 && mtk_wed_device_active(wed_hif2)) {
+ mtk_wed_device_irq_set_mask(wed_hif2, 0);
+ intr1 = mtk_wed_device_irq_get(wed_hif2,
+ dev->mt76.mmio.irqmask);
+ if (intr1 & MT_INT_RX_TXFREE_EXT)
+ napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
+ }
- intr |= intr1;
+ if (mtk_wed_device_active(wed)) {
+ mtk_wed_device_irq_set_mask(wed, 0);
+ intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
+ intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
+ } else {
+ mt76_wr(dev, MT_INT_MASK_CSR, 0);
+ if (dev->hif2)
+ mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+
+ intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
+ intr &= dev->mt76.mmio.irqmask;
+ mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
+ if (dev->hif2) {
+ intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
+ intr1 &= dev->mt76.mmio.irqmask;
+ mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
+ intr |= intr1;
+ }
}
trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
@@ -308,9 +559,17 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
{
struct mt7996_dev *dev = dev_instance;
- mt76_wr(dev, MT_INT_MASK_CSR, 0);
- if (dev->hif2)
- mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
+ mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed, 0);
+ else
+ mt76_wr(dev, MT_INT_MASK_CSR, 0);
+
+ if (dev->hif2) {
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
+ mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed_hif2, 0);
+ else
+ mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+ }
if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
return IRQ_NONE;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index e53cf6a3704c..bc73bcb47bf0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -13,6 +13,7 @@
#define MT7996_MAX_INTERFACES 19 /* per-band */
#define MT7996_MAX_WMM_SETS 4
+#define MT7996_WTBL_BMC_SIZE (is_mt7992(&dev->mt76) ? 32 : 64)
#define MT7996_WTBL_RESERVED (mt7996_wtbl_size(dev) - 1)
#define MT7996_WTBL_STA (MT7996_WTBL_RESERVED - \
mt7996_max_interface_num(dev))
@@ -33,22 +34,54 @@
#define MT7996_FIRMWARE_DSP "mediatek/mt7996/mt7996_dsp.bin"
#define MT7996_ROM_PATCH "mediatek/mt7996/mt7996_rom_patch.bin"
+#define MT7992_FIRMWARE_WA "mediatek/mt7996/mt7992_wa.bin"
+#define MT7992_FIRMWARE_WM "mediatek/mt7996/mt7992_wm.bin"
+#define MT7992_FIRMWARE_DSP "mediatek/mt7996/mt7992_dsp.bin"
+#define MT7992_ROM_PATCH "mediatek/mt7996/mt7992_rom_patch.bin"
+
#define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin"
+#define MT7992_EEPROM_DEFAULT "mediatek/mt7996/mt7992_eeprom.bin"
#define MT7996_EEPROM_SIZE 7680
#define MT7996_EEPROM_BLOCK_SIZE 16
#define MT7996_TOKEN_SIZE 16384
+#define MT7996_HW_TOKEN_SIZE 8192
#define MT7996_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
#define MT7996_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
+#define MT7996_SKU_RATE_NUM 417
+
#define MT7996_MAX_TWT_AGRT 16
#define MT7996_MAX_STA_TWT_AGRT 8
#define MT7996_MAX_QUEUE (__MT_RXQ_MAX + __MT_MCUQ_MAX + 3)
/* NOTE: used to map mt76_rates. idx may change if firmware expands table */
-#define MT7996_BASIC_RATES_TBL 11
+#define MT7996_BASIC_RATES_TBL 31
#define MT7996_BEACON_RATES_TBL 25
+#define MT7996_THERMAL_THROTTLE_MAX 100
+#define MT7996_CDEV_THROTTLE_MAX 99
+#define MT7996_CRIT_TEMP_IDX 0
+#define MT7996_MAX_TEMP_IDX 1
+#define MT7996_CRIT_TEMP 110
+#define MT7996_MAX_TEMP 120
+
+#define MT7996_RRO_MAX_SESSION 1024
+#define MT7996_RRO_WINDOW_MAX_LEN 1024
+#define MT7996_RRO_ADDR_ELEM_LEN 128
+#define MT7996_RRO_BA_BITMAP_LEN 2
+#define MT7996_RRO_BA_BITMAP_CR_SIZE ((MT7996_RRO_MAX_SESSION * 128) / \
+ MT7996_RRO_BA_BITMAP_LEN)
+#define MT7996_RRO_BA_BITMAP_SESSION_SIZE (MT7996_RRO_MAX_SESSION / \
+ MT7996_RRO_ADDR_ELEM_LEN)
+#define MT7996_RRO_WINDOW_MAX_SIZE (MT7996_RRO_WINDOW_MAX_LEN * \
+ MT7996_RRO_BA_BITMAP_SESSION_SIZE)
+
+#define MT7996_RX_BUF_SIZE (1800 + \
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+#define MT7996_RX_MSDU_PAGE_SIZE (128 + \
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+
struct mt7996_vif;
struct mt7996_sta;
struct mt7996_dfs_pulse;
@@ -73,11 +106,21 @@ enum mt7996_rxq_id {
MT7996_RXQ_MCU_WM = 0,
MT7996_RXQ_MCU_WA,
MT7996_RXQ_MCU_WA_MAIN = 2,
- MT7996_RXQ_MCU_WA_EXT = 2,/* unused */
+ MT7996_RXQ_MCU_WA_EXT = 3, /* for mt7992 */
MT7996_RXQ_MCU_WA_TRI = 3,
MT7996_RXQ_BAND0 = 4,
- MT7996_RXQ_BAND1 = 4,/* unused */
+ MT7996_RXQ_BAND1 = 5, /* for mt7992 */
MT7996_RXQ_BAND2 = 5,
+ MT7996_RXQ_RRO_BAND0 = 8,
+ MT7996_RXQ_RRO_BAND1 = 8,/* unused */
+ MT7996_RXQ_RRO_BAND2 = 6,
+ MT7996_RXQ_MSDU_PG_BAND0 = 10,
+ MT7996_RXQ_MSDU_PG_BAND1 = 11,
+ MT7996_RXQ_MSDU_PG_BAND2 = 12,
+ MT7996_RXQ_TXFREE0 = 9,
+ MT7996_RXQ_TXFREE1 = 9,
+ MT7996_RXQ_TXFREE2 = 7,
+ MT7996_RXQ_RRO_IND = 0,
};
struct mt7996_twt_flow {
@@ -146,6 +189,20 @@ struct mt7996_hif {
int irq;
};
+struct mt7996_wed_rro_addr {
+ u32 head_low;
+ u32 head_high : 4;
+ u32 count: 11;
+ u32 oor: 1;
+ u32 rsv : 8;
+ u32 signature : 8;
+};
+
+struct mt7996_wed_rro_session_id {
+ struct list_head list;
+ u16 id;
+};
+
struct mt7996_phy {
struct mt76_phy *mt76;
struct mt7996_dev *dev;
@@ -154,6 +211,11 @@ struct mt7996_phy {
struct ieee80211_vif *monitor_vif;
+ struct thermal_cooling_device *cdev;
+ u8 cdev_state;
+ u8 throttle_state;
+ u32 throttle_temp[2]; /* 0: critical high, 1: maximum */
+
u32 rxfilter;
u64 omac_mask;
@@ -164,11 +226,15 @@ struct mt7996_phy {
u8 rdd_state;
+ u16 beacon_rate;
+
u32 rx_ampdu_ts;
u32 ampdu_ref;
struct mt76_mib_stats mib;
struct mt76_channel_state state_ts;
+
+ bool has_aux_rx;
};
struct mt7996_dev {
@@ -221,10 +287,28 @@ struct mt7996_dev {
u32 hw_pattern;
- bool dbdc_support:1;
- bool tbtc_support:1;
bool flash_mode:1;
bool has_eht:1;
+ bool has_rro:1;
+
+ struct {
+ struct {
+ void *ptr;
+ dma_addr_t phy_addr;
+ } ba_bitmap[MT7996_RRO_BA_BITMAP_LEN];
+ struct {
+ void *ptr;
+ dma_addr_t phy_addr;
+ } addr_elem[MT7996_RRO_ADDR_ELEM_LEN];
+ struct {
+ void *ptr;
+ dma_addr_t phy_addr;
+ } session;
+
+ struct work_struct work;
+ struct list_head poll_list;
+ spinlock_t lock;
+ } wed_rro;
bool ibf;
u8 fw_debug_wm;
@@ -314,6 +398,20 @@ mt7996_phy3(struct mt7996_dev *dev)
return __mt7996_phy(dev, MT_BAND2);
}
+static inline bool
+mt7996_band_valid(struct mt7996_dev *dev, u8 band)
+{
+ if (is_mt7992(&dev->mt76))
+ return band <= MT_BAND1;
+
+ /* tri-band support */
+ if (band <= MT_BAND2 &&
+ mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1)
+ return true;
+
+ return band == MT_BAND0 || band == MT_BAND2;
+}
+
extern const struct ieee80211_ops mt7996_ops;
extern struct pci_driver mt7996_pci_driver;
extern struct pci_driver mt7996_hif_driver;
@@ -334,9 +432,10 @@ int mt7996_dma_init(struct mt7996_dev *dev);
void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
void mt7996_dma_prefetch(struct mt7996_dev *dev);
void mt7996_dma_cleanup(struct mt7996_dev *dev);
-void mt7996_dma_start(struct mt7996_dev *dev, bool reset);
-void mt7996_init_txpower(struct mt7996_dev *dev,
- struct ieee80211_supported_band *sband);
+void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset);
+int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
+ int n_desc, int ring_base, struct mtk_wed_device *wed);
+void mt7996_init_txpower(struct mt7996_phy *phy);
int mt7996_txbf_init(struct mt7996_dev *dev);
void mt7996_reset(struct mt7996_dev *dev);
int mt7996_run(struct ieee80211_hw *hw);
@@ -373,6 +472,8 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag);
int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif);
int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
void *data, u16 version);
+int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, void *data, u32 field);
int mt7996_mcu_set_eeprom(struct mt7996_dev *dev);
int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset);
int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num);
@@ -388,13 +489,19 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif);
int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);
+int mt7996_mcu_get_temperature(struct mt7996_phy *phy);
+int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state);
+int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable);
+int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
u8 rx_sel, u8 val);
int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
struct cfg80211_chan_def *chandef);
+int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
+ u16 rate_idx, bool beacon);
int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
-int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
+int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val);
int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
@@ -402,15 +509,18 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
void mt7996_mcu_exit(struct mt7996_dev *dev);
int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
+int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id);
static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
{
- return MT7996_MAX_INTERFACES * (1 + dev->dbdc_support + dev->tbtc_support);
+ return min(MT7996_MAX_INTERFACES * (1 + mt7996_band_valid(dev, MT_BAND1) +
+ mt7996_band_valid(dev, MT_BAND2)),
+ MT7996_WTBL_BMC_SIZE);
}
static inline u16 mt7996_wtbl_size(struct mt7996_dev *dev)
{
- return (dev->wtbl_size_group << 8) + 64;
+ return (dev->wtbl_size_group << 8) + MT7996_WTBL_BMC_SIZE;
}
void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
@@ -437,6 +547,18 @@ static inline void mt7996_irq_disable(struct mt7996_dev *dev, u32 mask)
void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
size_t len);
+static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy)
+{
+ int max_nss = hweight8(phy->mt76->hw->wiphy->available_antennas_tx);
+ int cur_nss = hweight8(phy->mt76->antenna_mask);
+ u16 tx_chainmask = phy->mt76->chainmask;
+
+ if (cur_nss != max_nss)
+ return tx_chainmask;
+
+ return tx_chainmask | (BIT(fls(tx_chainmask)) * phy->has_aux_rx);
+}
+
void mt7996_mac_init(struct mt7996_dev *dev);
u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw);
bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask);
@@ -445,8 +567,6 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
struct ieee80211_vif *vif, bool enable);
-void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
- u8 tbl_idx, u16 rate_idx);
void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_key_conf *key, int pid,
@@ -485,9 +605,10 @@ int mt7996_init_debugfs(struct mt7996_phy *phy);
void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int len);
bool mt7996_debugfs_rx_log(struct mt7996_dev *dev, const void *data, int len);
int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
- struct mt76_connac_sta_key_conf *sta_key_conf,
struct ieee80211_key_conf *key, int mcu_cmd,
struct mt76_wcid *wcid, enum set_key_cmd cmd);
+int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *key);
int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
@@ -495,5 +616,16 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct dentry *dir);
#endif
+int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ bool hif2, int *irq);
+u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+
+#ifdef CONFIG_MTK_DEBUG
+int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
+#endif
+
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
+int mt7996_dma_rro_init(struct mt7996_dev *dev);
+#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/pci.c b/drivers/net/wireless/mediatek/mt76/mt7996/pci.c
index c5301050ff8b..04056181368a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/pci.c
@@ -17,11 +17,13 @@ static u32 hif_idx;
static const struct pci_device_id mt7996_pci_device_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7990) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7992) },
{ },
};
static const struct pci_device_id mt7996_hif_device_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7991) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x799a) },
{ },
};
@@ -60,7 +62,9 @@ static void mt7996_put_hif2(struct mt7996_hif *hif)
static struct mt7996_hif *mt7996_pci_init_hif2(struct pci_dev *pdev)
{
hif_idx++;
- if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL))
+
+ if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL) &&
+ !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x799a, NULL))
return NULL;
writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
@@ -92,10 +96,10 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct pci_dev *hif2_dev;
+ struct mt7996_hif *hif2;
struct mt7996_dev *dev;
+ int irq, hif2_irq, ret;
struct mt76_dev *mdev;
- struct mt7996_hif *hif2;
- int irq, ret;
ret = pcim_enable_device(pdev);
if (ret)
@@ -107,13 +111,17 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
pci_set_master(pdev);
- ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
+ if (ret)
+ return ret;
+
+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (ret)
return ret;
mt76_pci_disable_aspm(pdev);
- if (id->device == 0x7991)
+ if (id->device == 0x7991 || id->device == 0x799a)
return mt7996_pci_hif2_probe(pdev);
dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],
@@ -125,15 +133,22 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
mt7996_wfsys_reset(dev);
hif2 = mt7996_pci_init_hif2(pdev);
- ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+ ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
if (ret < 0)
- goto free_device;
+ goto free_wed_or_irq_vector;
+
+ if (!ret) {
+ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+ if (ret < 0)
+ goto free_device;
+
+ irq = pdev->irq;
+ }
- irq = pdev->irq;
ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
IRQF_SHARED, KBUILD_MODNAME, dev);
if (ret)
- goto free_irq_vector;
+ goto free_wed_or_irq_vector;
mt76_wr(dev, MT_INT_MASK_CSR, 0);
/* master switch of PCIe tnterrupt enable */
@@ -143,16 +158,25 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
hif2_dev = container_of(hif2->dev, struct pci_dev, dev);
dev->hif2 = hif2;
- ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
+ ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &hif2_irq);
if (ret < 0)
- goto free_hif2;
+ goto free_hif2_wed_irq_vector;
+
+ if (!ret) {
+ ret = pci_alloc_irq_vectors(hif2_dev, 1, 1,
+ PCI_IRQ_ALL_TYPES);
+ if (ret < 0)
+ goto free_hif2;
- dev->hif2->irq = hif2_dev->irq;
- ret = devm_request_irq(mdev->dev, dev->hif2->irq,
- mt7996_irq_handler, IRQF_SHARED,
- KBUILD_MODNAME "-hif", dev);
+ dev->hif2->irq = hif2_dev->irq;
+ hif2_irq = dev->hif2->irq;
+ }
+
+ ret = devm_request_irq(mdev->dev, hif2_irq, mt7996_irq_handler,
+ IRQF_SHARED, KBUILD_MODNAME "-hif",
+ dev);
if (ret)
- goto free_hif2_irq_vector;
+ goto free_hif2_wed_irq_vector;
mt76_wr(dev, MT_INT1_MASK_CSR, 0);
/* master switch of PCIe tnterrupt enable */
@@ -167,16 +191,23 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
free_hif2_irq:
if (dev->hif2)
- devm_free_irq(mdev->dev, dev->hif2->irq, dev);
-free_hif2_irq_vector:
- if (dev->hif2)
- pci_free_irq_vectors(hif2_dev);
+ devm_free_irq(mdev->dev, hif2_irq, dev);
+free_hif2_wed_irq_vector:
+ if (dev->hif2) {
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
+ mtk_wed_device_detach(&dev->mt76.mmio.wed_hif2);
+ else
+ pci_free_irq_vectors(hif2_dev);
+ }
free_hif2:
if (dev->hif2)
put_device(dev->hif2->dev);
devm_free_irq(mdev->dev, irq, dev);
-free_irq_vector:
- pci_free_irq_vectors(pdev);
+free_wed_or_irq_vector:
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
+ mtk_wed_device_detach(&dev->mt76.mmio.wed);
+ else
+ pci_free_irq_vectors(pdev);
free_device:
mt76_free_device(&dev->mt76);
@@ -221,3 +252,7 @@ MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
MODULE_FIRMWARE(MT7996_ROM_PATCH);
+MODULE_FIRMWARE(MT7992_FIRMWARE_WA);
+MODULE_FIRMWARE(MT7992_FIRMWARE_WM);
+MODULE_FIRMWARE(MT7992_FIRMWARE_DSP);
+MODULE_FIRMWARE(MT7992_ROM_PATCH);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h
index 0086a7866657..47b429d8bfbe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h
@@ -19,6 +19,7 @@ struct __base {
/* used to differentiate between generations */
struct mt7996_reg_desc {
const struct __base *base;
+ const u32 *offs_rev;
const struct __map *map;
u32 map_size;
};
@@ -39,6 +40,73 @@ enum base_rev {
#define __BASE(_id, _band) (dev->reg.base[(_id)].band_base[(_band)])
+enum offs_rev {
+ MIB_RVSR0,
+ MIB_RVSR1,
+ MIB_BTSCR5,
+ MIB_BTSCR6,
+ MIB_RSCR1,
+ MIB_RSCR27,
+ MIB_RSCR28,
+ MIB_RSCR29,
+ MIB_RSCR30,
+ MIB_RSCR31,
+ MIB_RSCR33,
+ MIB_RSCR35,
+ MIB_RSCR36,
+ MIB_BSCR0,
+ MIB_BSCR1,
+ MIB_BSCR2,
+ MIB_BSCR3,
+ MIB_BSCR4,
+ MIB_BSCR5,
+ MIB_BSCR6,
+ MIB_BSCR7,
+ MIB_BSCR17,
+ MIB_TRDR1,
+ __MT_OFFS_MAX,
+};
+
+#define __OFFS(id) (dev->reg.offs_rev[(id)])
+
+/* RRO TOP */
+#define MT_RRO_TOP_BASE 0xA000
+#define MT_RRO_TOP(ofs) (MT_RRO_TOP_BASE + (ofs))
+
+#define MT_RRO_BA_BITMAP_BASE0 MT_RRO_TOP(0x8)
+#define MT_RRO_BA_BITMAP_BASE1 MT_RRO_TOP(0xC)
+#define WF_RRO_AXI_MST_CFG MT_RRO_TOP(0xB8)
+#define WF_RRO_AXI_MST_CFG_DIDX_OK BIT(12)
+#define MT_RRO_ADDR_ARRAY_BASE1 MT_RRO_TOP(0x34)
+#define MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE BIT(31)
+
+#define MT_RRO_IND_CMD_SIGNATURE_BASE0 MT_RRO_TOP(0x38)
+#define MT_RRO_IND_CMD_SIGNATURE_BASE1 MT_RRO_TOP(0x3C)
+#define MT_RRO_IND_CMD_0_CTRL0 MT_RRO_TOP(0x40)
+#define MT_RRO_IND_CMD_SIGNATURE_BASE1_EN BIT(31)
+
+#define MT_RRO_PARTICULAR_CFG0 MT_RRO_TOP(0x5C)
+#define MT_RRO_PARTICULAR_CFG1 MT_RRO_TOP(0x60)
+#define MT_RRO_PARTICULAR_CONFG_EN BIT(31)
+#define MT_RRO_PARTICULAR_SID GENMASK(30, 16)
+
+#define MT_RRO_BA_BITMAP_BASE_EXT0 MT_RRO_TOP(0x70)
+#define MT_RRO_BA_BITMAP_BASE_EXT1 MT_RRO_TOP(0x74)
+#define MT_RRO_HOST_INT_ENA MT_RRO_TOP(0x204)
+#define MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA BIT(0)
+
+#define MT_RRO_ADDR_ELEM_SEG_ADDR0 MT_RRO_TOP(0x400)
+
+#define MT_RRO_ACK_SN_CTRL MT_RRO_TOP(0x50)
+#define MT_RRO_ACK_SN_CTRL_SN_MASK GENMASK(27, 16)
+#define MT_RRO_ACK_SN_CTRL_SESSION_MASK GENMASK(11, 0)
+
+#define MT_RRO_DBG_RD_CTRL MT_RRO_TOP(0xe0)
+#define MT_RRO_DBG_RD_ADDR GENMASK(15, 0)
+#define MT_RRO_DBG_RD_EXEC BIT(31)
+
+#define MT_RRO_DBG_RDAT_DW(_n) MT_RRO_TOP(0xf0 + (_n) * 0x4)
+
#define MT_MCU_INT_EVENT 0x2108
#define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0)
#define MT_MCU_INT_EVENT_DMA_INIT BIT(1)
@@ -140,32 +208,32 @@ enum base_rev {
#define MT_WF_MIB_BASE(_band) __BASE(WF_MIB_BASE, (_band))
#define MT_WF_MIB(_band, ofs) (MT_WF_MIB_BASE(_band) + (ofs))
-#define MT_MIB_BSCR0(_band) MT_WF_MIB(_band, 0x9cc)
-#define MT_MIB_BSCR1(_band) MT_WF_MIB(_band, 0x9d0)
-#define MT_MIB_BSCR2(_band) MT_WF_MIB(_band, 0x9d4)
-#define MT_MIB_BSCR3(_band) MT_WF_MIB(_band, 0x9d8)
-#define MT_MIB_BSCR4(_band) MT_WF_MIB(_band, 0x9dc)
-#define MT_MIB_BSCR5(_band) MT_WF_MIB(_band, 0x9e0)
-#define MT_MIB_BSCR6(_band) MT_WF_MIB(_band, 0x9e4)
-#define MT_MIB_BSCR7(_band) MT_WF_MIB(_band, 0x9e8)
-#define MT_MIB_BSCR17(_band) MT_WF_MIB(_band, 0xa10)
+#define MT_MIB_BSCR0(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR0))
+#define MT_MIB_BSCR1(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR1))
+#define MT_MIB_BSCR2(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR2))
+#define MT_MIB_BSCR3(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR3))
+#define MT_MIB_BSCR4(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR4))
+#define MT_MIB_BSCR5(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR5))
+#define MT_MIB_BSCR6(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR6))
+#define MT_MIB_BSCR7(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR7))
+#define MT_MIB_BSCR17(_band) MT_WF_MIB(_band, __OFFS(MIB_BSCR17))
#define MT_MIB_TSCR5(_band) MT_WF_MIB(_band, 0x6c4)
#define MT_MIB_TSCR6(_band) MT_WF_MIB(_band, 0x6c8)
#define MT_MIB_TSCR7(_band) MT_WF_MIB(_band, 0x6d0)
-#define MT_MIB_RSCR1(_band) MT_WF_MIB(_band, 0x7ac)
+#define MT_MIB_RSCR1(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR1))
/* rx mpdu counter, full 32 bits */
-#define MT_MIB_RSCR31(_band) MT_WF_MIB(_band, 0x964)
-#define MT_MIB_RSCR33(_band) MT_WF_MIB(_band, 0x96c)
+#define MT_MIB_RSCR31(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR31))
+#define MT_MIB_RSCR33(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR33))
#define MT_MIB_SDR6(_band) MT_WF_MIB(_band, 0x020)
#define MT_MIB_SDR6_CHANNEL_IDL_CNT_MASK GENMASK(15, 0)
-#define MT_MIB_RVSR0(_band) MT_WF_MIB(_band, 0x720)
+#define MT_MIB_RVSR0(_band) MT_WF_MIB(_band, __OFFS(MIB_RVSR0))
-#define MT_MIB_RSCR35(_band) MT_WF_MIB(_band, 0x974)
-#define MT_MIB_RSCR36(_band) MT_WF_MIB(_band, 0x978)
+#define MT_MIB_RSCR35(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR35))
+#define MT_MIB_RSCR36(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR36))
/* tx ampdu cnt, full 32 bits */
#define MT_MIB_TSCR0(_band) MT_WF_MIB(_band, 0x6b0)
@@ -178,16 +246,16 @@ enum base_rev {
#define MT_MIB_TSCR4(_band) MT_WF_MIB(_band, 0x6c0)
/* rx ampdu count, 32-bit */
-#define MT_MIB_RSCR27(_band) MT_WF_MIB(_band, 0x954)
+#define MT_MIB_RSCR27(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR27))
/* rx ampdu bytes count, 32-bit */
-#define MT_MIB_RSCR28(_band) MT_WF_MIB(_band, 0x958)
+#define MT_MIB_RSCR28(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR28))
/* rx ampdu valid subframe count */
-#define MT_MIB_RSCR29(_band) MT_WF_MIB(_band, 0x95c)
+#define MT_MIB_RSCR29(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR29))
/* rx ampdu valid subframe bytes count, 32bits */
-#define MT_MIB_RSCR30(_band) MT_WF_MIB(_band, 0x960)
+#define MT_MIB_RSCR30(_band) MT_WF_MIB(_band, __OFFS(MIB_RSCR30))
/* remaining windows protected stats */
#define MT_MIB_SDR27(_band) MT_WF_MIB(_band, 0x080)
@@ -196,18 +264,18 @@ enum base_rev {
#define MT_MIB_SDR28(_band) MT_WF_MIB(_band, 0x084)
#define MT_MIB_SDR28_TX_RWP_NEED_CNT GENMASK(15, 0)
-#define MT_MIB_RVSR1(_band) MT_WF_MIB(_band, 0x724)
+#define MT_MIB_RVSR1(_band) MT_WF_MIB(_band, __OFFS(MIB_RVSR1))
/* rx blockack count, 32 bits */
#define MT_MIB_TSCR1(_band) MT_WF_MIB(_band, 0x6b4)
#define MT_MIB_BTSCR0(_band) MT_WF_MIB(_band, 0x5e0)
-#define MT_MIB_BTSCR5(_band) MT_WF_MIB(_band, 0x788)
-#define MT_MIB_BTSCR6(_band) MT_WF_MIB(_band, 0x798)
+#define MT_MIB_BTSCR5(_band) MT_WF_MIB(_band, __OFFS(MIB_BTSCR5))
+#define MT_MIB_BTSCR6(_band) MT_WF_MIB(_band, __OFFS(MIB_BTSCR6))
#define MT_MIB_BFTFCR(_band) MT_WF_MIB(_band, 0x5d0)
-#define MT_TX_AGG_CNT(_band, n) MT_WF_MIB(_band, 0xa28 + ((n) << 2))
+#define MT_TX_AGG_CNT(_band, n) MT_WF_MIB(_band, __OFFS(MIB_TRDR1) + ((n) << 2))
#define MT_MIB_ARNG(_band, n) MT_WF_MIB(_band, 0x0b0 + ((n) << 2))
#define MT_MIB_ARNCR_RANGE(val, n) (((val) >> ((n) << 4)) & GENMASK(9, 0))
@@ -330,15 +398,22 @@ enum base_rev {
#define MT_WFDMA0_RX_INT_PCIE_SEL MT_WFDMA0(0x154)
#define MT_WFDMA0_RX_INT_SEL_RING3 BIT(3)
+#define MT_WFDMA0_RX_INT_SEL_RING6 BIT(6)
#define MT_WFDMA0_MCU_HOST_INT_ENA MT_WFDMA0(0x1f4)
#define MT_WFDMA0_GLO_CFG MT_WFDMA0(0x208)
#define MT_WFDMA0_GLO_CFG_TX_DMA_EN BIT(0)
#define MT_WFDMA0_GLO_CFG_RX_DMA_EN BIT(2)
-#define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO BIT(28)
-#define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO BIT(27)
#define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 BIT(21)
+#define MT_WFDMA0_GLO_CFG_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_PAUSE_RX_Q_45_TH MT_WFDMA0(0x268)
+#define MT_WFDMA0_PAUSE_RX_Q_67_TH MT_WFDMA0(0x26c)
+#define MT_WFDMA0_PAUSE_RX_Q_89_TH MT_WFDMA0(0x270)
+#define MT_WFDMA0_PAUSE_RX_Q_RRO_TH MT_WFDMA0(0x27c)
#define WF_WFDMA0_GLO_CFG_EXT0 MT_WFDMA0(0x2b0)
#define WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD BIT(18)
@@ -362,10 +437,14 @@ enum base_rev {
#define MT_WFDMA_HOST_CONFIG MT_WFDMA_EXT_CSR(0x30)
#define MT_WFDMA_HOST_CONFIG_PDMA_BAND BIT(0)
+#define MT_WFDMA_HOST_CONFIG_BAND2_PCIE1 BIT(22)
#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_AXI_R2A_CTRL MT_WFDMA_EXT_CSR(0x500)
+#define MT_WFDMA_AXI_R2A_CTRL_OUTSTAND_MASK GENMASK(4, 0)
+
#define MT_PCIE_RECOG_ID 0xd7090
#define MT_PCIE_RECOG_ID_MASK GENMASK(30, 0)
#define MT_PCIE_RECOG_ID_SEM BIT(31)
@@ -374,6 +453,9 @@ enum base_rev {
#define MT_WFDMA0_PCIE1_BASE 0xd8000
#define MT_WFDMA0_PCIE1(ofs) (MT_WFDMA0_PCIE1_BASE + (ofs))
+#define MT_INT_PCIE1_SOURCE_CSR_EXT MT_WFDMA0_PCIE1(0x118)
+#define MT_INT_PCIE1_MASK_CSR MT_WFDMA0_PCIE1(0x11c)
+
#define MT_WFDMA0_PCIE1_BUSY_ENA MT_WFDMA0_PCIE1(0x13c)
#define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0 BIT(0)
#define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1 BIT(1)
@@ -394,6 +476,7 @@ enum base_rev {
#define MT_MCUQ_RING_BASE(q) (MT_Q_BASE(q) + 0x300)
#define MT_TXQ_RING_BASE(q) (MT_Q_BASE(__TXQ(q)) + 0x300)
#define MT_RXQ_RING_BASE(q) (MT_Q_BASE(__RXQ(q)) + 0x500)
+#define MT_RXQ_RRO_IND_RING_BASE MT_RRO_TOP(0x40)
#define MT_MCUQ_EXT_CTRL(q) (MT_Q_BASE(q) + 0x600 + \
MT_MCUQ_ID(q) * 0x4)
@@ -409,17 +492,27 @@ enum base_rev {
#define MT_INT1_MASK_CSR MT_WFDMA0_PCIE1(0x204)
#define MT_INT_RX_DONE_BAND0 BIT(12)
-#define MT_INT_RX_DONE_BAND1 BIT(12)
+#define MT_INT_RX_DONE_BAND1 BIT(13) /* for mt7992 */
#define MT_INT_RX_DONE_BAND2 BIT(13)
#define MT_INT_RX_DONE_WM BIT(0)
#define MT_INT_RX_DONE_WA BIT(1)
#define MT_INT_RX_DONE_WA_MAIN BIT(2)
-#define MT_INT_RX_DONE_WA_EXT BIT(2)
+#define MT_INT_RX_DONE_WA_EXT BIT(3) /* for mt7992 */
#define MT_INT_RX_DONE_WA_TRI BIT(3)
#define MT_INT_RX_TXFREE_MAIN BIT(17)
#define MT_INT_RX_TXFREE_TRI BIT(15)
+#define MT_INT_RX_DONE_BAND2_EXT BIT(23)
+#define MT_INT_RX_TXFREE_EXT BIT(26)
#define MT_INT_MCU_CMD BIT(29)
+#define MT_INT_RX_DONE_RRO_BAND0 BIT(16)
+#define MT_INT_RX_DONE_RRO_BAND1 BIT(16)
+#define MT_INT_RX_DONE_RRO_BAND2 BIT(14)
+#define MT_INT_RX_DONE_RRO_IND BIT(11)
+#define MT_INT_RX_DONE_MSDU_PG_BAND0 BIT(18)
+#define MT_INT_RX_DONE_MSDU_PG_BAND1 BIT(19)
+#define MT_INT_RX_DONE_MSDU_PG_BAND2 BIT(23)
+
#define MT_INT_RX(q) (dev->q_int_mask[__RXQ(q)])
#define MT_INT_TX_MCU(q) (dev->q_int_mask[(q)])
@@ -427,20 +520,31 @@ enum base_rev {
MT_INT_RX(MT_RXQ_MCU_WA))
#define MT_INT_BAND0_RX_DONE (MT_INT_RX(MT_RXQ_MAIN) | \
- MT_INT_RX(MT_RXQ_MAIN_WA))
+ MT_INT_RX(MT_RXQ_MAIN_WA) | \
+ MT_INT_RX(MT_RXQ_TXFREE_BAND0))
#define MT_INT_BAND1_RX_DONE (MT_INT_RX(MT_RXQ_BAND1) | \
MT_INT_RX(MT_RXQ_BAND1_WA) | \
- MT_INT_RX(MT_RXQ_MAIN_WA))
+ MT_INT_RX(MT_RXQ_MAIN_WA) | \
+ MT_INT_RX(MT_RXQ_TXFREE_BAND0))
#define MT_INT_BAND2_RX_DONE (MT_INT_RX(MT_RXQ_BAND2) | \
MT_INT_RX(MT_RXQ_BAND2_WA) | \
- MT_INT_RX(MT_RXQ_MAIN_WA))
+ MT_INT_RX(MT_RXQ_MAIN_WA) | \
+ MT_INT_RX(MT_RXQ_TXFREE_BAND0))
+
+#define MT_INT_RRO_RX_DONE (MT_INT_RX(MT_RXQ_RRO_BAND0) | \
+ MT_INT_RX(MT_RXQ_RRO_BAND1) | \
+ MT_INT_RX(MT_RXQ_RRO_BAND2) | \
+ MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND0) | \
+ MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND1) | \
+ MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND2))
#define MT_INT_RX_DONE_ALL (MT_INT_RX_DONE_MCU | \
MT_INT_BAND0_RX_DONE | \
MT_INT_BAND1_RX_DONE | \
- MT_INT_BAND2_RX_DONE)
+ MT_INT_BAND2_RX_DONE | \
+ MT_INT_RRO_RX_DONE)
#define MT_INT_TX_DONE_FWDL BIT(26)
#define MT_INT_TX_DONE_MCU_WM BIT(27)
@@ -449,6 +553,10 @@ enum base_rev {
#define MT_INT_TX_DONE_BAND1 BIT(31)
#define MT_INT_TX_DONE_BAND2 BIT(15)
+#define MT_INT_TX_RX_DONE_EXT (MT_INT_TX_DONE_BAND2 | \
+ MT_INT_RX_DONE_BAND2_EXT | \
+ MT_INT_RX_TXFREE_EXT)
+
#define MT_INT_TX_DONE_MCU (MT_INT_TX_MCU(MT_MCUQ_WA) | \
MT_INT_TX_MCU(MT_MCUQ_WM) | \
MT_INT_TX_MCU(MT_MCUQ_FWDL))
@@ -552,7 +660,12 @@ enum base_rev {
#define MT_TOP_MISC MT_TOP(0xf0)
#define MT_TOP_MISC_FW_STATE GENMASK(2, 0)
+#define MT_PAD_GPIO 0x700056f0
+#define MT_PAD_GPIO_ADIE_COMB GENMASK(16, 15)
+
#define MT_HW_REV 0x70010204
+#define MT_HW_REV1 0x8a00
+
#define MT_WF_SUBSYS_RST 0x70028600
/* PCIE MAC */
@@ -601,4 +714,11 @@ enum base_rev {
#define MT_MCU_WM_EXCP_LR_CTRL MT_MCU_WM_EXCP(0x200)
#define MT_MCU_WM_EXCP_LR_LOG MT_MCU_WM_EXCP(0x204)
+/* CONN AFE CTL CON */
+#define MT_AFE_CTL_BASE 0x18043000
+#define MT_AFE_CTL_BAND(_band, ofs) (MT_AFE_CTL_BASE + \
+ ((_band) * 0x1000) + (ofs))
+#define MT_AFE_CTL_BAND_PLL_03(_band) MT_AFE_CTL_BAND(_band, 0x2c)
+#define MT_AFE_CTL_BAND_PLL_03_MSB_EN BIT(1)
+
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index 419723118ded..c52d550f0c32 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -481,21 +481,21 @@ static void mt76s_status_worker(struct mt76_worker *w)
if (dev->drv->tx_status_data && ndata_frames > 0 &&
!test_and_set_bit(MT76_READING_STATS, &dev->phy.state) &&
!test_bit(MT76_STATE_SUSPEND, &dev->phy.state))
- ieee80211_queue_work(dev->hw, &dev->sdio.stat_work);
+ mt76_worker_schedule(&sdio->stat_worker);
} while (nframes > 0);
if (resched)
mt76_worker_schedule(&dev->tx_worker);
}
-static void mt76s_tx_status_data(struct work_struct *work)
+static void mt76s_tx_status_data(struct mt76_worker *worker)
{
struct mt76_sdio *sdio;
struct mt76_dev *dev;
u8 update = 1;
u16 count = 0;
- sdio = container_of(work, struct mt76_sdio, stat_work);
+ sdio = container_of(worker, struct mt76_sdio, stat_worker);
dev = container_of(sdio, struct mt76_dev, sdio);
while (true) {
@@ -508,7 +508,7 @@ static void mt76s_tx_status_data(struct work_struct *work)
}
if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state))
- ieee80211_queue_work(dev->hw, &sdio->stat_work);
+ mt76_worker_schedule(&sdio->status_worker);
else
clear_bit(MT76_READING_STATS, &dev->phy.state);
}
@@ -600,8 +600,8 @@ void mt76s_deinit(struct mt76_dev *dev)
mt76_worker_teardown(&sdio->txrx_worker);
mt76_worker_teardown(&sdio->status_worker);
mt76_worker_teardown(&sdio->net_worker);
+ mt76_worker_teardown(&sdio->stat_worker);
- cancel_work_sync(&sdio->stat_work);
clear_bit(MT76_READING_STATS, &dev->phy.state);
mt76_tx_status_check(dev, true);
@@ -644,10 +644,14 @@ int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,
if (err)
return err;
+ err = mt76_worker_setup(dev->hw, &sdio->stat_worker, mt76s_tx_status_data,
+ "sdio-sta");
+ if (err)
+ return err;
+
sched_set_fifo_low(sdio->status_worker.task);
sched_set_fifo_low(sdio->net_worker.task);
-
- INIT_WORK(&sdio->stat_work, mt76s_tx_status_data);
+ sched_set_fifo_low(sdio->stat_worker.task);
dev->queue_ops = &sdio_queue_ops;
dev->bus = bus_ops;
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 84b218adbaaf..aaf31857ae1e 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -1328,8 +1328,8 @@ static bool rt2800_watchdog_dma_busy(struct rt2x00_dev *rt2x00dev)
else
rt2x00dev->txdma_busy = 0;
- busy_rx = rt2x00dev->rxdma_busy > 30 ? true : false;
- busy_tx = rt2x00dev->txdma_busy > 30 ? true : false;
+ busy_rx = rt2x00dev->rxdma_busy > 30;
+ busy_tx = rt2x00dev->txdma_busy > 30;
if (!busy_rx && !busy_tx)
return false;
@@ -1353,10 +1353,10 @@ void rt2800_watchdog(struct rt2x00_dev *rt2x00dev)
if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
return;
- if (modparam_watchdog & RT2800_WATCHDOG_DMA_BUSY)
+ if (rt2x00dev->link.watchdog & RT2800_WATCHDOG_DMA_BUSY)
reset = rt2800_watchdog_dma_busy(rt2x00dev);
- if (modparam_watchdog & RT2800_WATCHDOG_HANG)
+ if (rt2x00dev->link.watchdog & RT2800_WATCHDOG_HANG)
reset = rt2800_watchdog_hung(rt2x00dev) || reset;
if (reset)
@@ -12065,14 +12065,13 @@ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
__set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
}
+ rt2x00dev->link.watchdog = modparam_watchdog;
/* USB NICs don't support DMA watchdog as INT_SOURCE_CSR is invalid */
if (rt2x00_is_usb(rt2x00dev))
- modparam_watchdog &= ~RT2800_WATCHDOG_DMA_BUSY;
- if (modparam_watchdog) {
+ rt2x00dev->link.watchdog &= ~RT2800_WATCHDOG_DMA_BUSY;
+ if (rt2x00dev->link.watchdog) {
__set_bit(CAPABILITY_RESTART_HW, &rt2x00dev->cap_flags);
rt2x00dev->link.watchdog_interval = msecs_to_jiffies(100);
- } else {
- rt2x00dev->link.watchdog_disabled = true;
}
/*
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
index 62fed38f41c0..82af01448a0a 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -334,7 +334,7 @@ struct link {
*/
struct delayed_work watchdog_work;
unsigned int watchdog_interval;
- bool watchdog_disabled;
+ unsigned int watchdog;
/*
* Work structure for scheduling periodic AGC adjustments.
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00link.c b/drivers/net/wireless/ralink/rt2x00/rt2x00link.c
index 6cf7e7c997c2..fb23d409fba8 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00link.c
@@ -384,7 +384,7 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
struct link *link = &rt2x00dev->link;
if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
- rt2x00dev->ops->lib->watchdog && !link->watchdog_disabled)
+ rt2x00dev->ops->lib->watchdog && link->watchdog)
ieee80211_queue_delayed_work(rt2x00dev->hw,
&link->watchdog_work,
link->watchdog_interval);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
index 98df0aef8168..013003777fee 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
@@ -416,9 +416,6 @@ static void rt2x00queue_create_tx_descriptor(struct rt2x00_dev *rt2x00dev,
__set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags);
else
__set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags);
- if (tx_info->control.rts_cts_rate_idx >= 0)
- rate =
- ieee80211_get_rts_cts_rate(rt2x00dev->hw, tx_info);
}
/*
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index b163a069660b..96ce05bcf0b3 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -64,7 +64,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
- u8 init_aspm;
+ u16 init_aspm;
ppsc->reg_rfps_level = 0;
ppsc->support_aspm = false;
@@ -150,9 +150,10 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
/* toshiba aspm issue, toshiba will set aspm selfly
* so we should not set aspm in driver
*/
- pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm);
+ pcie_capability_read_word(rtlpci->pdev, PCI_EXP_LNKCTL, &init_aspm);
if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE &&
- init_aspm == 0x43)
+ ((u8)init_aspm) == (PCI_EXP_LNKCTL_ASPM_L0S |
+ PCI_EXP_LNKCTL_ASPM_L1 | PCI_EXP_LNKCTL_CCC))
ppsc->support_aspm = false;
}
@@ -163,21 +164,29 @@ static bool _rtl_pci_platform_switch_device_pci_aspm(
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ value &= PCI_EXP_LNKCTL_ASPMC;
+
if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)
- value |= 0x40;
+ value |= PCI_EXP_LNKCTL_CCC;
- pci_write_config_byte(rtlpci->pdev, 0x80, value);
+ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_ASPMC | value,
+ value);
return false;
}
-/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
-static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
+/* @value is PCI_EXP_LNKCTL_CLKREQ_EN or 0 to enable/disable clk request. */
+static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- pci_write_config_byte(rtlpci->pdev, 0x81, value);
+ value &= PCI_EXP_LNKCTL_CLKREQ_EN;
+
+ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_CLKREQ_EN,
+ value);
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
udelay(100);
@@ -191,13 +200,10 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
- u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
/*Retrieve original configuration settings. */
u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg;
- u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
- pcibridge_linkctrlreg;
u16 aspmlevel = 0;
- u8 tmp_u1b = 0;
+ u16 tmp_u1b = 0;
if (!ppsc->support_aspm)
return;
@@ -215,21 +221,13 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
}
/*for promising device will in L0 state after an I/O. */
- pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
+ pcie_capability_read_word(rtlpci->pdev, PCI_EXP_LNKCTL, &tmp_u1b);
/*Set corresponding value. */
- aspmlevel |= BIT(0) | BIT(1);
+ aspmlevel |= PCI_EXP_LNKCTL_ASPM_L0S | PCI_EXP_LNKCTL_ASPM_L1;
linkctrl_reg &= ~aspmlevel;
- pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1));
_rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg);
- udelay(50);
-
- /*4 Disable Pci Bridge ASPM */
- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
- pcibridge_linkctrlreg);
-
- udelay(50);
}
/*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for
@@ -244,9 +242,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
- u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
u16 aspmlevel;
- u8 u_pcibridge_aspmsetting;
u8 u_device_aspmsetting;
if (!ppsc->support_aspm)
@@ -258,25 +254,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
return;
}
- /*4 Enable Pci Bridge ASPM */
-
- u_pcibridge_aspmsetting =
- pcipriv->ndis_adapter.pcibridge_linkctrlreg |
- rtlpci->const_hostpci_aspm_setting;
-
- if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
- u_pcibridge_aspmsetting &= ~BIT(0);
-
- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
- u_pcibridge_aspmsetting);
-
- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
- "PlatformEnableASPM(): Write reg[%x] = %x\n",
- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
- u_pcibridge_aspmsetting);
-
- udelay(50);
-
/*Get ASPM level (with/without Clock Req) */
aspmlevel = rtlpci->const_devicepci_aspm_setting;
u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg;
@@ -290,7 +267,8 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
_rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level &
- RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
+ RT_RF_OFF_LEVL_CLK_REQ) ?
+ PCI_EXP_LNKCTL_CLKREQ_EN : 0);
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
}
udelay(100);
@@ -357,22 +335,6 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw,
return tpriv != NULL;
}
-static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
-{
- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
- struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
- u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
- u8 linkctrl_reg;
- u8 num4bbytes;
-
- num4bbytes = (capabilityoffset + 0x10) / 4;
-
- /*Read Link Control Register */
- pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg);
-
- pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
-}
-
static void rtl_pci_parse_configuration(struct pci_dev *pdev,
struct ieee80211_hw *hw)
{
@@ -389,9 +351,8 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n",
pcipriv->ndis_adapter.linkctrl_reg);
- pci_read_config_byte(pdev, 0x98, &tmp);
- tmp |= BIT(4);
- pci_write_config_byte(pdev, 0x98, tmp);
+ pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2,
+ PCI_EXP_DEVCTL2_COMP_TMOUT_DIS);
tmp = 0x17;
pci_write_config_byte(pdev, 0x70f, tmp);
@@ -2007,7 +1968,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
*/
if (bridge_pdev) {
/*find bridge info if available */
- pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor;
for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) {
if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
pcipriv->ndis_adapter.pcibridge_vendor = tmp;
@@ -2027,12 +1987,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
PCI_SLOT(bridge_pdev->devfn);
pcipriv->ndis_adapter.pcibridge_funcnum =
PCI_FUNC(bridge_pdev->devfn);
- pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
- pci_pcie_cap(bridge_pdev);
- pcipriv->ndis_adapter.num4bytes =
- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;
-
- rtl_pci_get_linkcontrol_field(hw);
if (pcipriv->ndis_adapter.pcibridge_vendor ==
PCI_BRIDGE_VENDOR_AMD) {
@@ -2049,13 +2003,11 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg);
rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
- "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
+ "pci_bridge busnumber:devnumber:funcnumber:vendor:amd %d:%d:%d:%x:%x\n",
pcipriv->ndis_adapter.pcibridge_busnum,
pcipriv->ndis_adapter.pcibridge_devnum,
pcipriv->ndis_adapter.pcibridge_funcnum,
pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
- pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
- pcipriv->ndis_adapter.pcibridge_linkctrlreg,
pcipriv->ndis_adapter.amd_l1_patch);
rtl_pci_parse_configuration(pdev, hw);
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h
index 4725d43609fd..e8fa022df8b4 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.h
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.h
@@ -44,18 +44,6 @@
#define ATI_DEVICE_ID 0x7914
#define AMD_VENDOR_ID 0x1022
-#define PCI_MAX_BRIDGE_NUMBER 255
-#define PCI_MAX_DEVICES 32
-#define PCI_MAX_FUNCTION 8
-
-#define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */
-#define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */
-
-#define PCI_CLASS_BRIDGE_DEV 0x06
-#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
-#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
-#define PCI_CAP_ID_EXP 0x10
-
#define U1DONTCARE 0xFF
#define U2DONTCARE 0xFFFF
#define U4DONTCARE 0xFFFFFFFF
@@ -113,11 +101,6 @@ enum pci_bridge_vendor {
PCI_BRIDGE_VENDOR_MAX,
};
-struct rtl_pci_capabilities_header {
- u8 capability_id;
- u8 next;
-};
-
/* In new TRX flow, Buffer_desc is new concept
* But TX wifi info == TX descriptor in old flow
* RX wifi info == RX descriptor in old flow
@@ -232,13 +215,6 @@ struct mp_adapter {
u8 pcibridge_funcnum;
u8 pcibridge_vendor;
- u16 pcibridge_vendorid;
- u16 pcibridge_deviceid;
-
- u8 num4bytes;
-
- u8 pcibridge_pciehdr_offset;
- u8 pcibridge_linkctrlreg;
bool amd_l1_patch;
};
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
index 1633328bc3d1..f4b232f038a9 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
@@ -2270,67 +2270,27 @@ static void _rtl8821ae_clear_pci_pme_status(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
- u16 cap_hdr;
- u8 cap_pointer;
- u8 cap_id = 0xff;
- u8 pmcs_reg;
- u8 cnt = 0;
+ struct pci_dev *pdev = rtlpci->pdev;
+ u16 pmcs_reg;
+ u8 pm_cap;
- /* Get the Capability pointer first,
- * the Capability Pointer is located at
- * offset 0x34 from the Function Header */
-
- pci_read_config_byte(rtlpci->pdev, 0x34, &cap_pointer);
- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
- "PCI configuration 0x34 = 0x%2x\n", cap_pointer);
-
- do {
- pci_read_config_word(rtlpci->pdev, cap_pointer, &cap_hdr);
- cap_id = cap_hdr & 0xFF;
-
- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
- "in pci configuration, cap_pointer%x = %x\n",
- cap_pointer, cap_id);
-
- if (cap_id == 0x01) {
- break;
- } else {
- /* point to next Capability */
- cap_pointer = (cap_hdr >> 8) & 0xFF;
- /* 0: end of pci capability, 0xff: invalid value */
- if (cap_pointer == 0x00 || cap_pointer == 0xff) {
- cap_id = 0xff;
- break;
- }
- }
- } while (cnt++ < 200);
-
- if (cap_id == 0x01) {
- /* Get the PM CSR (Control/Status Register),
- * The PME_Status is located at PM Capatibility offset 5, bit 7
- */
- pci_read_config_byte(rtlpci->pdev, cap_pointer + 5, &pmcs_reg);
-
- if (pmcs_reg & BIT(7)) {
- /* PME event occured, clear the PM_Status by write 1 */
- pmcs_reg = pmcs_reg | BIT(7);
-
- pci_write_config_byte(rtlpci->pdev, cap_pointer + 5,
- pmcs_reg);
- /* Read it back to check */
- pci_read_config_byte(rtlpci->pdev, cap_pointer + 5,
- &pmcs_reg);
- rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
- "Clear PME status 0x%2x to 0x%2x\n",
- cap_pointer + 5, pmcs_reg);
- } else {
- rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
- "PME status(0x%2x) = 0x%2x\n",
- cap_pointer + 5, pmcs_reg);
- }
- } else {
+ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+ if (!pm_cap) {
rtl_dbg(rtlpriv, COMP_INIT, DBG_WARNING,
"Cannot find PME Capability\n");
+ return;
+ }
+
+ pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pmcs_reg);
+ if (pmcs_reg & PCI_PM_CTRL_PME_STATUS) {
+ /* Clear PME_Status with write */
+ pci_write_config_word(pdev, pm_cap + PCI_PM_CTRL, pmcs_reg);
+ pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pmcs_reg);
+ rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
+ "Cleared PME status, PMCS reg = 0x%4x\n", pmcs_reg);
+ } else {
+ rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
+ "PMCS reg = 0x%4x\n", pmcs_reg);
}
}
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
index 5323ead30db0..68c3fb0395ce 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
@@ -29,9 +29,10 @@ static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
u32 data);
static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask)
{
- u32 i = ffs(bitmask);
+ if (WARN_ON_ONCE(!bitmask))
+ return 0;
- return i ? i - 1 : 32;
+ return __ffs(bitmask);
}
static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw);
/*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/
@@ -2038,15 +2039,9 @@ static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
/*don't need the hw_body*/
if (!_rtl8821ae_check_condition(hw, v1)) {
i += 2; /* skip the pair of expression*/
- v1 = array[i];
v2 = array[i+1];
- v3 = array[i+2];
- while (v2 != 0xDEAD) {
+ while (v2 != 0xDEAD)
i += 3;
- v1 = array[i];
- v2 = array[i+1];
- v3 = array[i+2];
- }
}
}
}
@@ -3543,7 +3538,6 @@ u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
struct rtl_phy *rtlphy = &rtlpriv->phy;
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u32 timeout = 1000, timecount = 0;
- u8 channel = rtlphy->current_channel;
if (rtlphy->sw_chnl_inprogress)
return 0;
@@ -3566,8 +3560,6 @@ u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
rtlphy->sw_chnl_inprogress = true;
- if (channel == 0)
- channel = 1;
rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
"switch to channel%d, band type is %d\n",
diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index 35bc37a3c469..1b2ad81838be 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -1314,8 +1314,8 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
#ifdef CONFIG_RTW88_DEBUG
-void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,
- const char *fmt, ...)
+void rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,
+ const char *fmt, ...)
{
struct va_format vaf = {
.fmt = fmt,
@@ -1330,6 +1330,6 @@ void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,
va_end(args);
}
-EXPORT_SYMBOL(__rtw_dbg);
+EXPORT_SYMBOL(rtw_dbg);
#endif /* CONFIG_RTW88_DEBUG */
diff --git a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h
index a03ced11bbe0..f20c0471c82a 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.h
+++ b/drivers/net/wireless/realtek/rtw88/debug.h
@@ -43,10 +43,8 @@ static inline void rtw_debugfs_init(struct rtw_dev *rtwdev) {}
#ifdef CONFIG_RTW88_DEBUG
__printf(3, 4)
-void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,
- const char *fmt, ...);
-
-#define rtw_dbg(rtwdev, a...) __rtw_dbg(rtwdev, ##a)
+void rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,
+ const char *fmt, ...);
static inline bool rtw_dbg_is_enabled(struct rtw_dev *rtwdev,
enum rtw_debug_mask mask)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 4a33d2e47f33..6d22628129d0 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -2008,6 +2008,11 @@ static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev)
efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0;
efuse->ext_lna_2g = efuse->lna_type_5g & BIT(3) ? 1 : 0;
+ if (!is_valid_ether_addr(efuse->addr)) {
+ eth_random_addr(efuse->addr);
+ dev_warn(rtwdev->dev, "efuse MAC invalid, using random\n");
+ }
+
out_disable:
rtw_chip_efuse_disable(rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index 2c1fb2dabd40..0cae5746f540 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -500,19 +500,40 @@ static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size,
static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count)
{
struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
+ struct mmc_host *host = rtwsdio->sdio_func->card->host;
bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio);
u32 rxaddr = rtwsdio->rx_addr++;
- int ret;
+ int ret = 0, err;
+ size_t bytes;
if (bus_claim)
sdio_claim_host(rtwsdio->sdio_func);
- ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
- RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count);
- if (ret)
- rtw_warn(rtwdev,
- "Failed to read %zu byte(s) from SDIO port 0x%08x",
- count, rxaddr);
+ while (count > 0) {
+ bytes = min_t(size_t, host->max_req_size, count);
+
+ err = sdio_memcpy_fromio(rtwsdio->sdio_func, buf,
+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr),
+ bytes);
+ if (err) {
+ rtw_warn(rtwdev,
+ "Failed to read %zu byte(s) from SDIO port 0x%08x: %d",
+ bytes, rxaddr, err);
+
+ /* Signal to the caller that reading did not work and
+ * that the data in the buffer is short/corrupted.
+ */
+ ret = err;
+
+ /* Don't stop here - instead drain the remaining data
+ * from the card's buffer, else the card will return
+ * corrupt data for the next rtw_sdio_read_port() call.
+ */
+ }
+
+ count -= bytes;
+ buf += bytes;
+ }
if (bus_claim)
sdio_release_host(rtwsdio->sdio_func);
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index b842cd9a86f8..9c0db35d3e13 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -5352,6 +5352,10 @@ void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): phy_idx=%d, band=%d\n",
__func__, phy_idx, band);
+
+ if (phy_idx >= RTW89_PHY_MAX)
+ return;
+
btc->dm.cnt_notify[BTC_NCNT_SCAN_START]++;
wl->status.map.scan = true;
wl->scan_info.band[phy_idx] = band;
@@ -5396,6 +5400,10 @@ void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): phy_idx=%d, band=%d\n",
__func__, phy_idx, band);
+
+ if (phy_idx >= RTW89_PHY_MAX)
+ return;
+
btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++;
wl->scan_info.band[phy_idx] = band;
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 74bf29643823..fd527a249996 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2883,9 +2883,6 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
lockdep_assert_held(&rtwdev->mutex);
- ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work,
- msecs_to_jiffies(rtwvif->roc.duration));
-
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC);
@@ -2907,6 +2904,9 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);
ieee80211_ready_on_channel(hw);
+ cancel_delayed_work(&rtwvif->roc.roc_work);
+ ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work,
+ msecs_to_jiffies(rtwvif->roc.duration));
}
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
@@ -3129,6 +3129,7 @@ static void rtw89_track_work(struct work_struct *work)
rtw89_phy_tx_path_div_track(rtwdev);
rtw89_phy_antdiv_track(rtwdev);
rtw89_phy_ul_tb_ctrl_track(rtwdev);
+ rtw89_phy_edcca_track(rtwdev);
rtw89_tas_track(rtwdev);
rtw89_chanctx_track(rtwdev);
@@ -3955,10 +3956,7 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
/* efuse process */
/* pre-config BB/RF, BB reset/RFC reset */
- ret = rtw89_chip_disable_bb_rf(rtwdev);
- if (ret)
- return ret;
- ret = rtw89_chip_enable_bb_rf(rtwdev);
+ ret = rtw89_chip_reset_bb_rf(rtwdev);
if (ret)
return ret;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 6948ffe0f206..21421980fd06 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -17,6 +17,8 @@ struct rtw89_pci_info;
struct rtw89_mac_gen_def;
struct rtw89_phy_gen_def;
struct rtw89_efuse_block_cfg;
+struct rtw89_fw_txpwr_track_cfg;
+struct rtw89_phy_rfk_log_fmt;
extern const struct ieee80211_ops rtw89_ops;
@@ -38,6 +40,8 @@ extern const struct ieee80211_ops rtw89_ops;
#define RSSI_FACTOR 1
#define RTW89_RSSI_RAW_TO_DBM(rssi) ((s8)((rssi) >> RSSI_FACTOR) - MAX_RSSI)
#define RTW89_TX_DIV_RSSI_RAW_TH (2 << RSSI_FACTOR)
+#define DELTA_SWINGIDX_SIZE 30
+
#define RTW89_RADIOTAP_ROOM_HE sizeof(struct ieee80211_radiotap_he)
#define RTW89_RADIOTAP_ROOM_EHT \
(sizeof(struct ieee80211_radiotap_tlv) + \
@@ -3292,6 +3296,8 @@ struct rtw89_dle_size {
u16 pge_size;
u16 lnk_pge_num;
u16 unlnk_pge_num;
+ /* for WiFi 7 chips below */
+ u32 srt_ofst;
};
struct rtw89_wde_quota {
@@ -3314,6 +3320,26 @@ struct rtw89_ple_quota {
u16 wd_rel;
u16 cpu_io;
u16 tx_rpt;
+ /* for WiFi 7 chips below */
+ u16 h2d;
+};
+
+struct rtw89_rsvd_quota {
+ u16 mpdu_info_tbl;
+ u16 b0_csi;
+ u16 b1_csi;
+ u16 b0_lmr;
+ u16 b1_lmr;
+ u16 b0_ftm;
+ u16 b1_ftm;
+ u16 b0_smr;
+ u16 b1_smr;
+ u16 others;
+};
+
+struct rtw89_dle_rsvd_size {
+ u32 srt_ofst;
+ u32 size;
};
struct rtw89_dle_mem {
@@ -3324,6 +3350,10 @@ struct rtw89_dle_mem {
const struct rtw89_wde_quota *wde_max_qt;
const struct rtw89_ple_quota *ple_min_qt;
const struct rtw89_ple_quota *ple_max_qt;
+ /* for WiFi 7 chips below */
+ const struct rtw89_rsvd_quota *rsvd_qt;
+ const struct rtw89_dle_rsvd_size *rsvd0_size;
+ const struct rtw89_dle_rsvd_size *rsvd1_size;
};
struct rtw89_reg_def {
@@ -3350,6 +3380,12 @@ struct rtw89_reg5_def {
u32 data;
};
+struct rtw89_reg_imr {
+ u32 addr;
+ u32 clr;
+ u32 set;
+};
+
struct rtw89_phy_table {
const struct rtw89_reg2_def *regs;
u32 n_regs;
@@ -3559,6 +3595,11 @@ struct rtw89_imr_info {
u32 tmac_imr_set;
};
+struct rtw89_imr_table {
+ const struct rtw89_reg_imr *regs;
+ u32 n_regs;
+};
+
struct rtw89_xtal_info {
u32 xcap_reg;
u32 sc_xo_mask;
@@ -3590,6 +3631,22 @@ struct rtw89_dig_regs {
struct rtw89_reg_def p1_s20_pagcugc_en;
};
+struct rtw89_edcca_regs {
+ u32 edcca_level;
+ u32 edcca_mask;
+ u32 edcca_p_mask;
+ u32 ppdu_level;
+ u32 ppdu_mask;
+ u32 rpt_a;
+ u32 rpt_b;
+ u32 rpt_sel;
+ u32 rpt_sel_mask;
+ u32 rpt_sel_be;
+ u32 rpt_sel_be_mask;
+ u32 tx_collision_t2r_st;
+ u32 tx_collision_t2r_st_mask;
+};
+
struct rtw89_phy_ul_tb_info {
bool dyn_tb_tri_en;
u8 def_if_bandedge;
@@ -3650,8 +3707,8 @@ struct rtw89_chip_info {
u32 rsvd_ple_ofst;
const struct rtw89_hfc_param_ini *hfc_param_ini;
const struct rtw89_dle_mem *dle_mem;
- u8 wde_qempty_acq_num;
- u8 wde_qempty_mgq_sel;
+ u8 wde_qempty_acq_grpnum;
+ u8 wde_qempty_mgq_grpsel;
u32 rf_base_addr[2];
u8 support_chanctx_num;
u8 support_bands;
@@ -3737,11 +3794,13 @@ struct rtw89_chip_info {
const struct rtw89_reg_def *dcfo_comp;
u8 dcfo_comp_sft;
const struct rtw89_imr_info *imr_info;
+ const struct rtw89_imr_table *imr_dmac_table;
+ const struct rtw89_imr_table *imr_cmac_table;
const struct rtw89_rrsr_cfgs *rrsr_cfgs;
struct rtw89_reg_def bss_clr_vld;
u32 bss_clr_map_reg;
u32 dma_ch_mask;
- u32 edcca_lvl_reg;
+ const struct rtw89_edcca_regs *edcca_regs;
const struct wiphy_wowlan_support *wowlan_stub;
const struct rtw89_xtal_info *xtal_info;
};
@@ -3765,8 +3824,10 @@ enum rtw89_hcifc_mode {
};
struct rtw89_dle_info {
+ const struct rtw89_rsvd_quota *rsvd_qt;
enum rtw89_qta_mode qta_mode;
u16 ple_pg_size;
+ u16 ple_free_pg;
u16 c0_rx_qta;
u16 c1_rx_qta;
};
@@ -3891,6 +3952,8 @@ struct rtw89_fw_elm_info {
struct rtw89_phy_table *bb_gain;
struct rtw89_phy_table *rf_radio[RF_PATH_MAX];
struct rtw89_phy_table *rf_nctl;
+ struct rtw89_fw_txpwr_track_cfg *txpwr_trk;
+ struct rtw89_phy_rfk_log_fmt *rfk_log_fmt;
};
struct rtw89_fw_info {
@@ -4010,6 +4073,17 @@ struct rtw89_sub_entity {
struct rtw89_chanctx_cfg *cfg;
};
+struct rtw89_edcca_bak {
+ u8 a;
+ u8 p;
+ u8 ppdu;
+ u8 th_old;
+};
+
+enum rtw89_dm_type {
+ RTW89_DM_DYNAMIC_EDCCA,
+};
+
struct rtw89_hal {
u32 rx_fltr;
u8 cv;
@@ -4034,7 +4108,8 @@ struct rtw89_hal {
bool entity_pause;
enum rtw89_entity_mode entity_mode;
- u32 edcca_bak;
+ struct rtw89_edcca_bak edcca_bak;
+ u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */
};
#define RTW89_MAX_MAC_ID_NUM 128
@@ -4042,6 +4117,9 @@ struct rtw89_hal {
enum rtw89_flags {
RTW89_FLAG_POWERON,
+ RTW89_FLAG_DMAC_FUNC,
+ RTW89_FLAG_CMAC0_FUNC,
+ RTW89_FLAG_CMAC1_FUNC,
RTW89_FLAG_FW_RDY,
RTW89_FLAG_RUNNING,
RTW89_FLAG_BFEE_MON,
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index a3f795d240ea..44829a148185 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -3330,13 +3330,14 @@ out:
static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_cpuio_ctrl ctrl_para = {0};
u16 pkt_id;
int ret;
rtw89_leave_ps_mode(rtwdev);
- ret = rtw89_mac_dle_buf_req(rtwdev, 0x20, true, &pkt_id);
+ ret = mac->dle_buf_req(rtwdev, 0x20, true, &pkt_id);
if (ret)
return ret;
@@ -3348,7 +3349,7 @@ static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev)
ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS;
ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT;
- if (rtw89_mac_set_cpuio(rtwdev, &ctrl_para, true))
+ if (mac->set_cpuio(rtwdev, &ctrl_para, true))
return -EFAULT;
return 0;
@@ -3770,6 +3771,58 @@ static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
return 0;
}
+#define DM_INFO(type) {RTW89_DM_ ## type, #type}
+
+static const struct rtw89_disabled_dm_info {
+ enum rtw89_dm_type type;
+ const char *name;
+} rtw89_disabled_dm_infos[] = {
+ DM_INFO(DYNAMIC_EDCCA),
+};
+
+static int
+rtw89_debug_priv_disable_dm_get(struct seq_file *m, void *v)
+{
+ struct rtw89_debugfs_priv *debugfs_priv = m->private;
+ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ const struct rtw89_disabled_dm_info *info;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u32 disabled;
+ int i;
+
+ seq_printf(m, "Disabled DM: 0x%x\n", hal->disabled_dm_bitmap);
+
+ for (i = 0; i < ARRAY_SIZE(rtw89_disabled_dm_infos); i++) {
+ info = &rtw89_disabled_dm_infos[i];
+ disabled = BIT(info->type) & hal->disabled_dm_bitmap;
+
+ seq_printf(m, "[%d] %s: %c\n", info->type, info->name,
+ disabled ? 'X' : 'O');
+ }
+
+ return 0;
+}
+
+static ssize_t
+rtw89_debug_priv_disable_dm_set(struct file *filp, const char __user *user_buf,
+ size_t count, loff_t *loff)
+{
+ struct seq_file *m = (struct seq_file *)filp->private_data;
+ struct rtw89_debugfs_priv *debugfs_priv = m->private;
+ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u32 conf;
+ int ret;
+
+ ret = kstrtou32_from_user(user_buf, count, 0, &conf);
+ if (ret)
+ return -EINVAL;
+
+ hal->disabled_dm_bitmap = conf;
+
+ return count;
+}
+
static struct rtw89_debugfs_priv rtw89_debug_priv_read_reg = {
.cb_read = rtw89_debug_priv_read_reg_get,
.cb_write = rtw89_debug_priv_read_reg_select,
@@ -3845,6 +3898,11 @@ static struct rtw89_debugfs_priv rtw89_debug_priv_stations = {
.cb_read = rtw89_debug_priv_stations_get,
};
+static struct rtw89_debugfs_priv rtw89_debug_priv_disable_dm = {
+ .cb_read = rtw89_debug_priv_disable_dm_get,
+ .cb_write = rtw89_debug_priv_disable_dm_set,
+};
+
#define rtw89_debugfs_add(name, mode, fopname, parent) \
do { \
rtw89_debug_priv_ ##name.rtwdev = rtwdev; \
@@ -3885,13 +3943,13 @@ void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
rtw89_debugfs_add_w(fw_log_manual);
rtw89_debugfs_add_r(phy_info);
rtw89_debugfs_add_r(stations);
+ rtw89_debugfs_add_rw(disable_dm);
}
#endif
#ifdef CONFIG_RTW89_DEBUGMSG
-void __rtw89_debug(struct rtw89_dev *rtwdev,
- enum rtw89_debug_mask mask,
- const char *fmt, ...)
+void rtw89_debug(struct rtw89_dev *rtwdev, enum rtw89_debug_mask mask,
+ const char *fmt, ...)
{
struct va_format vaf = {
.fmt = fmt,
@@ -3907,5 +3965,5 @@ void __rtw89_debug(struct rtw89_dev *rtwdev,
va_end(args);
}
-EXPORT_SYMBOL(__rtw89_debug);
+EXPORT_SYMBOL(rtw89_debug);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h
index b663ee24555a..800ea59873a1 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.h
+++ b/drivers/net/wireless/realtek/rtw89/debug.h
@@ -30,6 +30,7 @@ enum rtw89_debug_mask {
RTW89_DBG_UL_TB = BIT(19),
RTW89_DBG_CHAN = BIT(20),
RTW89_DBG_ACPI = BIT(21),
+ RTW89_DBG_EDCCA = BIT(22),
RTW89_DBG_UNEXP = BIT(31),
};
@@ -58,12 +59,10 @@ static inline void rtw89_debugfs_init(struct rtw89_dev *rtwdev) {}
#ifdef CONFIG_RTW89_DEBUGMSG
extern unsigned int rtw89_debug_mask;
-#define rtw89_debug(rtwdev, a...) __rtw89_debug(rtwdev, ##a)
__printf(3, 4)
-void __rtw89_debug(struct rtw89_dev *rtwdev,
- enum rtw89_debug_mask mask,
- const char *fmt, ...);
+void rtw89_debug(struct rtw89_dev *rtwdev, enum rtw89_debug_mask mask,
+ const char *fmt, ...);
static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev,
enum rtw89_debug_mask mask,
const char *prefix_str,
@@ -74,6 +73,12 @@ static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev,
print_hex_dump_bytes(prefix_str, DUMP_PREFIX_OFFSET, buf, len);
}
+
+static inline bool rtw89_debug_is_enabled(struct rtw89_dev *rtwdev,
+ enum rtw89_debug_mask mask)
+{
+ return !!(rtw89_debug_mask & mask);
+}
#else
static inline void rtw89_debug(struct rtw89_dev *rtwdev,
enum rtw89_debug_mask mask,
@@ -82,6 +87,11 @@ static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev,
enum rtw89_debug_mask mask,
const char *prefix_str,
const void *buf, size_t len) {}
+static inline bool rtw89_debug_is_enabled(struct rtw89_dev *rtwdev,
+ enum rtw89_debug_mask mask)
+{
+ return false;
+}
#endif
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index a732c22a2d54..09684cea9731 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -401,10 +401,14 @@ int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev,
const union rtw89_fw_element_arg arg)
{
enum rtw89_fw_type type = arg.fw_type;
+ struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_fw_suit *fw_suit;
+ if (hal->cv != elm->u.bbmcu.cv)
+ return 1; /* ignore this element */
+
fw_suit = rtw89_fw_suit_get(rtwdev, type);
- fw_suit->data = elm->u.common.contents;
+ fw_suit->data = elm->u.bbmcu.contents;
fw_suit->size = le32_to_cpu(elm->size);
return rtw89_fw_update_ver(rtwdev, type, fw_suit);
@@ -453,6 +457,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER),
};
static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
@@ -658,6 +663,97 @@ setup:
return 0;
}
+static
+int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_element_hdr *elm,
+ const union rtw89_fw_element_arg arg)
+{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u32 needed_bitmap = 0;
+ u32 offset = 0;
+ int subband;
+ u32 bitmap;
+ int type;
+
+ if (chip->support_bands & BIT(NL80211_BAND_6GHZ))
+ needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ;
+ if (chip->support_bands & BIT(NL80211_BAND_5GHZ))
+ needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ;
+ if (chip->support_bands & BIT(NL80211_BAND_2GHZ))
+ needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ;
+
+ bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
+
+ if ((bitmap & needed_bitmap) != needed_bitmap) {
+ rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %0x8x\n",
+ needed_bitmap, bitmap);
+ return -ENOENT;
+ }
+
+ elm_info->txpwr_trk = kzalloc(sizeof(*elm_info->txpwr_trk), GFP_KERNEL);
+ if (!elm_info->txpwr_trk)
+ return -ENOMEM;
+
+ for (type = 0; bitmap; type++, bitmap >>= 1) {
+ if (!(bitmap & BIT(0)))
+ continue;
+
+ if (type >= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START &&
+ type <= __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX)
+ subband = 4;
+ else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START &&
+ type <= __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX)
+ subband = 3;
+ else if (type >= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START &&
+ type <= __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX)
+ subband = 1;
+ else
+ break;
+
+ elm_info->txpwr_trk->delta[type] = &elm->u.txpwr_trk.contents[offset];
+
+ offset += subband;
+ if (offset * DELTA_SWINGIDX_SIZE > le32_to_cpu(elm->size))
+ goto err;
+ }
+
+ return 0;
+
+err:
+ rtw89_warn(rtwdev, "unexpected txpwr trk offset %d over size %d\n",
+ offset, le32_to_cpu(elm->size));
+ kfree(elm_info->txpwr_trk);
+ elm_info->txpwr_trk = NULL;
+
+ return -EFAULT;
+}
+
+static
+int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_element_hdr *elm,
+ const union rtw89_fw_element_arg arg)
+{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ u8 rfk_id;
+
+ if (elm_info->rfk_log_fmt)
+ goto allocated;
+
+ elm_info->rfk_log_fmt = kzalloc(sizeof(*elm_info->rfk_log_fmt), GFP_KERNEL);
+ if (!elm_info->rfk_log_fmt)
+ return 1; /* this is an optional element, so just ignore this */
+
+allocated:
+ rfk_id = elm->u.rfk_log_fmt.rfk_id;
+ if (rfk_id >= RTW89_PHY_C2H_RFK_LOG_FUNC_NUM)
+ return 1;
+
+ elm_info->rfk_log_fmt->elm[rfk_id] = elm;
+
+ return 0;
+}
+
static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
{ .fw_type = RTW89_FW_BBMCU0 }, NULL},
@@ -710,6 +806,12 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
rtw89_fw_recognize_txpwr_from_elm,
{ .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt_ru.conf) }, NULL,
},
+ [RTW89_FW_ELEMENT_ID_TXPWR_TRK] = {
+ rtw89_build_txpwr_trk_tbl_from_elm, {}, "PWR_TRK",
+ },
+ [RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = {
+ rtw89_build_rfk_log_fmt_from_elm, {}, NULL,
+ },
};
int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
@@ -750,6 +852,8 @@ int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
goto next;
ret = handler->fn(rtwdev, hdr, handler->arg);
+ if (ret == 1) /* ignore this element */
+ goto next;
if (ret)
return ret;
@@ -956,16 +1060,24 @@ static int rtw89_fw_download_main(struct rtw89_dev *rtwdev,
static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev)
{
+ enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
+ u32 addr = R_AX_DBG_PORT_SEL;
u32 val32;
u16 index;
+ if (chip_gen == RTW89_CHIP_BE) {
+ addr = R_BE_WLCPU_PORT_PC;
+ goto dump;
+ }
+
rtw89_write32(rtwdev, R_AX_DBG_CTRL,
FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) |
FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL));
rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL);
+dump:
for (index = 0; index < 15; index++) {
- val32 = rtw89_read32(rtwdev, R_AX_DBG_PORT_SEL);
+ val32 = rtw89_read32(rtwdev, addr);
rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32);
fsleep(10);
}
@@ -1135,6 +1247,9 @@ static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev)
for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++)
rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]);
rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl);
+
+ kfree(elm_info->txpwr_trk);
+ kfree(elm_info->rfk_log_fmt);
}
void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
@@ -2215,6 +2330,41 @@ fail:
return ret;
}
+int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en)
+{
+ struct rtw89_h2c_notify_dbcc *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c notify dbcc\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_notify_dbcc *)skb->data;
+
+ h2c->w0 = le32_encode_bits(en, RTW89_H2C_NOTIFY_DBCC_EN);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
+ H2C_FUNC_NOTIFY_DBCC, 0, 1,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
bool pause)
{
@@ -3451,6 +3601,8 @@ static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev,
return false;
case RTW89_C2H_CAT_MAC:
return rtw89_mac_c2h_chk_atomic(rtwdev, class, func);
+ case RTW89_C2H_CAT_OUTSRC:
+ return rtw89_phy_c2h_chk_atomic(rtwdev, class, func);
}
}
@@ -3867,6 +4019,8 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
if (info->channel_6ghz &&
ch_info->pri_ch != info->channel_6ghz)
continue;
+ else if (info->channel_6ghz && probe_count != 0)
+ ch_info->period += RTW89_CHANNEL_TIME_6G;
ch_info->pkt_id[probe_count++] = info->id;
if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
break;
@@ -4043,6 +4197,7 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
rtw89_core_scan_complete(rtwdev, vif, true);
ieee80211_scan_completed(rtwdev->hw, &info);
ieee80211_wake_queues(rtwdev->hw);
+ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
rtw89_release_pkt_list(rtwdev);
rtwvif = (struct rtw89_vif *)vif->drv_priv;
@@ -4060,6 +4215,19 @@ void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
rtw89_hw_scan_complete(rtwdev, vif, true);
}
+static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_vif *rtwvif;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ /* This variable implies connected or during attempt to connect */
+ if (!is_zero_ether_addr(rtwvif->bssid))
+ return true;
+ }
+
+ return false;
+}
+
int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
bool enable)
{
@@ -4072,8 +4240,7 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
if (!rtwvif)
return -EINVAL;
- /* This variable implies connected or during attempt to connect */
- connected = !is_zero_ether_addr(rtwvif->bssid);
+ connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
opt.enable = enable;
opt.target_ch_mode = connected;
if (enable) {
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index d4db9ab0b5e8..01016588b1fc 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -1685,6 +1685,12 @@ static inline void SET_JOININFO_SELF_ROLE(void *h2c, u32 val)
le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 30));
}
+struct rtw89_h2c_notify_dbcc {
+ __le32 w0;
+} __packed;
+
+#define RTW89_H2C_NOTIFY_DBCC_EN BIT(0)
+
static inline void SET_GENERAL_PKT_MACID(void *h2c, u32 val)
{
le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0));
@@ -3426,6 +3432,8 @@ enum rtw89_fw_element_id {
RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ = 15,
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT = 16,
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU = 17,
+ RTW89_FW_ELEMENT_ID_TXPWR_TRK = 18,
+ RTW89_FW_ELEMENT_ID_RFKLOG_FMT = 19,
RTW89_FW_ELEMENT_ID_NUM,
};
@@ -3446,6 +3454,7 @@ enum rtw89_fw_element_id {
BIT(RTW89_FW_ELEMENT_ID_RADIO_A) | \
BIT(RTW89_FW_ELEMENT_ID_RADIO_B) | \
BIT(RTW89_FW_ELEMENT_ID_RF_NCTL) | \
+ BIT(RTW89_FW_ELEMENT_ID_TXPWR_TRK) | \
BITS_OF_RTW89_TXPWR_FW_ELEMENTS)
struct __rtw89_fw_txpwr_element {
@@ -3457,6 +3466,59 @@ struct __rtw89_fw_txpwr_element {
u8 content[];
} __packed;
+enum rtw89_fw_txpwr_trk_type {
+ __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START = 0,
+ RTW89_FW_TXPWR_TRK_TYPE_6GB_N = 0,
+ RTW89_FW_TXPWR_TRK_TYPE_6GB_P = 1,
+ RTW89_FW_TXPWR_TRK_TYPE_6GA_N = 2,
+ RTW89_FW_TXPWR_TRK_TYPE_6GA_P = 3,
+ __RTW89_FW_TXPWR_TRK_TYPE_6GHZ_MAX = 3,
+
+ __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_START = 4,
+ RTW89_FW_TXPWR_TRK_TYPE_5GB_N = 4,
+ RTW89_FW_TXPWR_TRK_TYPE_5GB_P = 5,
+ RTW89_FW_TXPWR_TRK_TYPE_5GA_N = 6,
+ RTW89_FW_TXPWR_TRK_TYPE_5GA_P = 7,
+ __RTW89_FW_TXPWR_TRK_TYPE_5GHZ_MAX = 7,
+
+ __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_START = 8,
+ RTW89_FW_TXPWR_TRK_TYPE_2GB_N = 8,
+ RTW89_FW_TXPWR_TRK_TYPE_2GB_P = 9,
+ RTW89_FW_TXPWR_TRK_TYPE_2GA_N = 10,
+ RTW89_FW_TXPWR_TRK_TYPE_2GA_P = 11,
+ RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N = 12,
+ RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P = 13,
+ RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N = 14,
+ RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P = 15,
+ __RTW89_FW_TXPWR_TRK_TYPE_2GHZ_MAX = 15,
+
+ RTW89_FW_TXPWR_TRK_TYPE_NR,
+};
+
+struct rtw89_fw_txpwr_track_cfg {
+ const s8 (*delta[RTW89_FW_TXPWR_TRK_TYPE_NR])[DELTA_SWINGIDX_SIZE];
+};
+
+#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ \
+ (BIT(RTW89_FW_TXPWR_TRK_TYPE_6GB_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_6GB_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_6GA_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_6GA_P))
+#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ \
+ (BIT(RTW89_FW_TXPWR_TRK_TYPE_5GB_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_5GB_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_5GA_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_5GA_P))
+#define RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ \
+ (BIT(RTW89_FW_TXPWR_TRK_TYPE_2GB_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2GB_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2GA_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2GA_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_B_P) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_N) | \
+ BIT(RTW89_FW_TXPWR_TRK_TYPE_2G_CCK_A_P))
+
struct rtw89_fw_element_hdr {
__le32 id; /* enum rtw89_fw_element_id */
__le32 size; /* exclude header size */
@@ -3477,6 +3539,23 @@ struct rtw89_fw_element_hdr {
__le32 data;
} __packed regs[];
} __packed reg2;
+ struct {
+ u8 cv;
+ u8 priv[7];
+ u8 contents[];
+ } __packed bbmcu;
+ struct {
+ __le32 bitmap; /* bitmap of enum rtw89_fw_txpwr_trk_type */
+ __le32 rsvd;
+ s8 contents[][DELTA_SWINGIDX_SIZE];
+ } __packed txpwr_trk;
+ struct {
+ u8 nr;
+ u8 rsvd[3];
+ u8 rfk_id; /* enum rtw89_phy_c2h_rfk_log_func */
+ u8 rsvd1[3];
+ __le16 offset[];
+ } __packed rfk_log_fmt;
struct __rtw89_fw_txpwr_element txpwr;
} __packed u;
} __packed;
@@ -3577,6 +3656,7 @@ struct rtw89_fw_h2c_rf_reg_info {
#define H2C_CL_MAC_MEDIA_RPT 0x8
#define H2C_FUNC_MAC_JOININFO 0x0
#define H2C_FUNC_MAC_FWROLE_MAINTAIN 0x4
+#define H2C_FUNC_NOTIFY_DBCC 0x5
/* CLASS 9 - FW offload */
#define H2C_CL_MAC_FW_OFLD 0x9
@@ -3649,9 +3729,78 @@ struct rtw89_fw_h2c_rf_get_mccch {
__le32 current_band_type;
} __packed;
-#define RTW89_FW_RSVD_PLE_SIZE 0x800
+enum rtw89_rf_log_type {
+ RTW89_RF_RUN_LOG = 0,
+ RTW89_RF_RPT_LOG = 1,
+};
-#define RTW89_WCPU_BASE_MASK GENMASK(27, 0)
+struct rtw89_c2h_rf_log_hdr {
+ u8 type; /* enum rtw89_rf_log_type */
+ __le16 len;
+ u8 content[];
+} __packed;
+
+struct rtw89_c2h_rf_run_log {
+ __le32 fmt_idx;
+ __le32 arg[4];
+} __packed;
+
+struct rtw89_c2h_rf_dpk_rpt_log {
+ u8 ver;
+ u8 idx[2];
+ u8 band[2];
+ u8 bw[2];
+ u8 ch[2];
+ u8 path_ok[2];
+ u8 txagc[2];
+ u8 ther[2];
+ u8 gs[2];
+ u8 dc_i[4];
+ u8 dc_q[4];
+ u8 corr_val[2];
+ u8 corr_idx[2];
+ u8 is_timeout[2];
+ u8 rxbb_ov[2];
+ u8 rsvd;
+} __packed;
+
+struct rtw89_c2h_rf_dack_rpt_log {
+ u8 fwdack_ver;
+ u8 fwdack_rpt_ver;
+ u8 msbk_d[2][2][16];
+ u8 dadck_d[2][2];
+ u8 cdack_d[2][2][2];
+ __le16 addck2_d[2][2][2];
+ u8 adgaink_d[2][2];
+ __le16 biask_d[2][2];
+ u8 addck_timeout;
+ u8 cdack_timeout;
+ u8 dadck_timeout;
+ u8 msbk_timeout;
+ u8 adgaink_timeout;
+ u8 dack_fail;
+} __packed;
+
+struct rtw89_c2h_rf_rxdck_rpt_log {
+ u8 ver;
+ u8 band[2];
+ u8 bw[2];
+ u8 ch[2];
+ u8 timeout[2];
+} __packed;
+
+struct rtw89_c2h_rf_txgapk_rpt_log {
+ __le32 r0x8010[2];
+ __le32 chk_cnt;
+ u8 track_d[2][17];
+ u8 power_d[2][17];
+ u8 is_txgapk_ok;
+ u8 chk_id;
+ u8 ver;
+ u8 rsv1;
+} __packed;
+
+#define RTW89_FW_RSVD_PLE_SIZE 0x800
#define RTW89_FW_BACKTRACE_INFO_SIZE 8
#define RTW89_VALID_FW_BACKTRACE_SIZE(_size) \
@@ -3704,6 +3853,7 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
enum rtw89_upd_mode upd_mode);
int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, bool dis_conn);
+int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en);
int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
bool pause);
int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 9ec307051611..80ab5fdfdaa0 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -57,8 +57,8 @@ static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset,
return rtw89_read32(rtwdev, mac->indir_access_addr);
}
-int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx,
- enum rtw89_mac_hwmod_sel sel)
+static int rtw89_mac_check_mac_en_ax(struct rtw89_dev *rtwdev, u8 mac_idx,
+ enum rtw89_mac_hwmod_sel sel)
{
u32 val, r_val;
@@ -113,8 +113,7 @@ int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val)
return ret;
}
-static
-int dle_dfi_ctrl(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl)
+int rtw89_mac_dle_dfi_cfg(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl)
{
u32 ctrl_reg, data_reg, ctrl_data;
u32 val;
@@ -154,8 +153,8 @@ int dle_dfi_ctrl(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl)
return 0;
}
-static int dle_dfi_quota(struct rtw89_dev *rtwdev,
- struct rtw89_mac_dle_dfi_quota *quota)
+int rtw89_mac_dle_dfi_quota_cfg(struct rtw89_dev *rtwdev,
+ struct rtw89_mac_dle_dfi_quota *quota)
{
struct rtw89_mac_dle_dfi_ctrl ctrl;
int ret;
@@ -163,9 +162,9 @@ static int dle_dfi_quota(struct rtw89_dev *rtwdev,
ctrl.type = quota->dle_type;
ctrl.target = DLE_DFI_TYPE_QUOTA;
ctrl.addr = quota->qtaid;
- ret = dle_dfi_ctrl(rtwdev, &ctrl);
+ ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl);
if (ret) {
- rtw89_warn(rtwdev, "[ERR]dle_dfi_ctrl %d\n", ret);
+ rtw89_warn(rtwdev, "[ERR] dle dfi quota %d\n", ret);
return ret;
}
@@ -174,8 +173,8 @@ static int dle_dfi_quota(struct rtw89_dev *rtwdev,
return 0;
}
-static int dle_dfi_qempty(struct rtw89_dev *rtwdev,
- struct rtw89_mac_dle_dfi_qempty *qempty)
+int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev,
+ struct rtw89_mac_dle_dfi_qempty *qempty)
{
struct rtw89_mac_dle_dfi_ctrl ctrl;
u32 ret;
@@ -183,9 +182,9 @@ static int dle_dfi_qempty(struct rtw89_dev *rtwdev,
ctrl.type = qempty->dle_type;
ctrl.target = DLE_DFI_TYPE_QEMPTY;
ctrl.addr = qempty->grpsel;
- ret = dle_dfi_ctrl(rtwdev, &ctrl);
+ ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl);
if (ret) {
- rtw89_warn(rtwdev, "[ERR]dle_dfi_ctrl %d\n", ret);
+ rtw89_warn(rtwdev, "[ERR] dle dfi qempty %d\n", ret);
return ret;
}
@@ -193,7 +192,7 @@ static int dle_dfi_qempty(struct rtw89_dev *rtwdev,
return 0;
}
-static void dump_err_status_dispatcher(struct rtw89_dev *rtwdev)
+static void dump_err_status_dispatcher_ax(struct rtw89_dev *rtwdev)
{
rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_IMR=0x%08x ",
rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
@@ -209,7 +208,7 @@ static void dump_err_status_dispatcher(struct rtw89_dev *rtwdev)
rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
}
-static void rtw89_mac_dump_qta_lost(struct rtw89_dev *rtwdev)
+static void rtw89_mac_dump_qta_lost_ax(struct rtw89_dev *rtwdev)
{
struct rtw89_mac_dle_dfi_qempty qempty;
struct rtw89_mac_dle_dfi_quota quota;
@@ -220,7 +219,7 @@ static void rtw89_mac_dump_qta_lost(struct rtw89_dev *rtwdev)
qempty.dle_type = DLE_CTRL_TYPE_PLE;
qempty.grpsel = 0;
qempty.qempty = ~(u32)0;
- ret = dle_dfi_qempty(rtwdev, &qempty);
+ ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
if (ret)
rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
else
@@ -232,19 +231,19 @@ static void rtw89_mac_dump_qta_lost(struct rtw89_dev *rtwdev)
ctrl.type = DLE_CTRL_TYPE_PLE;
ctrl.target = DLE_DFI_TYPE_QLNKTBL;
ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) |
- FIELD_PREP(QLNKTBL_ADDR_TBL_IDX_MASK, i);
- ret = dle_dfi_ctrl(rtwdev, &ctrl);
+ u32_encode_bits(i, QLNKTBL_ADDR_TBL_IDX_MASK);
+ ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl);
if (ret)
rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
else
- rtw89_info(rtwdev, "qidx%d pktcnt = %ld\n", i,
- FIELD_GET(QLNKTBL_DATA_SEL1_PKT_CNT_MASK,
- ctrl.out_data));
+ rtw89_info(rtwdev, "qidx%d pktcnt = %d\n", i,
+ u32_get_bits(ctrl.out_data,
+ QLNKTBL_DATA_SEL1_PKT_CNT_MASK));
}
quota.dle_type = DLE_CTRL_TYPE_PLE;
quota.qtaid = 6;
- ret = dle_dfi_quota(rtwdev, &quota);
+ ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, &quota);
if (ret)
rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
else
@@ -252,33 +251,74 @@ static void rtw89_mac_dump_qta_lost(struct rtw89_dev *rtwdev)
quota.rsv_pgnum, quota.use_pgnum);
val = rtw89_read32(rtwdev, R_AX_PLE_QTA6_CFG);
- rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%lx\n",
- FIELD_GET(B_AX_PLE_Q6_MIN_SIZE_MASK, val));
- rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%lx\n",
- FIELD_GET(B_AX_PLE_Q6_MAX_SIZE_MASK, val));
+ rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%x\n",
+ u32_get_bits(val, B_AX_PLE_Q6_MIN_SIZE_MASK));
+ rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%x\n",
+ u32_get_bits(val, B_AX_PLE_Q6_MAX_SIZE_MASK));
+ val = rtw89_read32(rtwdev, R_AX_RX_FLTR_OPT);
+ rtw89_info(rtwdev, "[PLE][CMAC0_RX]B_AX_RX_MPDU_MAX_LEN=0x%x\n",
+ u32_get_bits(val, B_AX_RX_MPDU_MAX_LEN_MASK));
+ rtw89_info(rtwdev, "R_AX_RSP_CHK_SIG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RSP_CHK_SIG));
+ rtw89_info(rtwdev, "R_AX_TRXPTCL_RESP_0=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_TRXPTCL_RESP_0));
+ rtw89_info(rtwdev, "R_AX_CCA_CONTROL=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_CCA_CONTROL));
+
+ if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) {
+ quota.dle_type = DLE_CTRL_TYPE_PLE;
+ quota.qtaid = 7;
+ ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, &quota);
+ if (ret)
+ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
+ else
+ rtw89_info(rtwdev, "quota7 rsv/use: 0x%x/0x%x\n",
+ quota.rsv_pgnum, quota.use_pgnum);
+
+ val = rtw89_read32(rtwdev, R_AX_PLE_QTA7_CFG);
+ rtw89_info(rtwdev, "[PLE][CMAC1_RX]min_pgnum=0x%x\n",
+ u32_get_bits(val, B_AX_PLE_Q7_MIN_SIZE_MASK));
+ rtw89_info(rtwdev, "[PLE][CMAC1_RX]max_pgnum=0x%x\n",
+ u32_get_bits(val, B_AX_PLE_Q7_MAX_SIZE_MASK));
+ val = rtw89_read32(rtwdev, R_AX_RX_FLTR_OPT_C1);
+ rtw89_info(rtwdev, "[PLE][CMAC1_RX]B_AX_RX_MPDU_MAX_LEN=0x%x\n",
+ u32_get_bits(val, B_AX_RX_MPDU_MAX_LEN_MASK));
+ rtw89_info(rtwdev, "R_AX_RSP_CHK_SIG_C1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RSP_CHK_SIG_C1));
+ rtw89_info(rtwdev, "R_AX_TRXPTCL_RESP_0_C1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_TRXPTCL_RESP_0_C1));
+ rtw89_info(rtwdev, "R_AX_CCA_CONTROL_C1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_CCA_CONTROL_C1));
+ }
+
+ rtw89_info(rtwdev, "R_AX_DLE_EMPTY0=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_DLE_EMPTY0));
+ rtw89_info(rtwdev, "R_AX_DLE_EMPTY1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_DLE_EMPTY1));
- dump_err_status_dispatcher(rtwdev);
+ dump_err_status_dispatcher_ax(rtwdev);
}
-static void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev,
- enum mac_ax_err_info err)
+void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev,
+ enum mac_ax_err_info err)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 dbg, event;
dbg = rtw89_read32(rtwdev, R_AX_SER_DBG_INFO);
- event = FIELD_GET(B_AX_L0_TO_L1_EVENT_MASK, dbg);
+ event = u32_get_bits(dbg, B_AX_L0_TO_L1_EVENT_MASK);
switch (event) {
case MAC_AX_L0_TO_L1_RX_QTA_LOST:
rtw89_info(rtwdev, "quota lost!\n");
- rtw89_mac_dump_qta_lost(rtwdev);
+ mac->dump_qta_lost(rtwdev);
break;
default:
break;
}
}
-static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
+void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 dmac_err;
@@ -358,6 +398,21 @@ static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
rtw89_info(rtwdev, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n",
i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2));
}
+ } else if (chip->chip_id == RTL8922A) {
+ rtw89_info(rtwdev, "R_BE_SEC_ERROR_FLAG=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SEC_ERROR_FLAG));
+ rtw89_info(rtwdev, "R_BE_SEC_ERROR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SEC_ERROR_IMR));
+ rtw89_info(rtwdev, "R_BE_SEC_ENG_CTRL=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SEC_ENG_CTRL));
+ rtw89_info(rtwdev, "R_BE_SEC_MPDU_PROC=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SEC_MPDU_PROC));
+ rtw89_info(rtwdev, "R_BE_SEC_CAM_ACCESS=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SEC_CAM_ACCESS));
+ rtw89_info(rtwdev, "R_BE_SEC_CAM_RDATA=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SEC_CAM_RDATA));
+ rtw89_info(rtwdev, "R_BE_SEC_DEBUG2=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SEC_DEBUG2));
} else {
rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_SEC_DEBUG));
@@ -394,10 +449,17 @@ static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
}
if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) {
- rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR));
- rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));
+ if (chip->chip_id == RTL8922A) {
+ rtw89_info(rtwdev, "R_BE_INTERRUPT_MASK_REG=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_INTERRUPT_MASK_REG));
+ rtw89_info(rtwdev, "R_BE_INTERRUPT_STS_REG=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_INTERRUPT_STS_REG));
+ } else {
+ rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR));
+ rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));
+ }
}
if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) {
@@ -412,7 +474,7 @@ static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
}
if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) {
- if (chip->chip_id == RTL8852C) {
+ if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A) {
rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR));
rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n",
@@ -444,30 +506,41 @@ static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1));
rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_2=0x%08x\n",
rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2));
- rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS));
rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_0=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0));
rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_1=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1));
rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_2=0x%08x\n",
rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2));
- rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));
- if (chip->chip_id == RTL8852C) {
- rtw89_info(rtwdev, "R_AX_RX_CTRL0=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RX_CTRL0));
- rtw89_info(rtwdev, "R_AX_RX_CTRL1=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RX_CTRL1));
- rtw89_info(rtwdev, "R_AX_RX_CTRL2=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RX_CTRL2));
+ if (chip->chip_id == RTL8922A) {
+ rtw89_info(rtwdev, "R_BE_WD_CPUQ_OP_3=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_WD_CPUQ_OP_3));
+ rtw89_info(rtwdev, "R_BE_WD_CPUQ_OP_STATUS=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_WD_CPUQ_OP_STATUS));
+ rtw89_info(rtwdev, "R_BE_PLE_CPUQ_OP_3=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_PL_CPUQ_OP_3));
+ rtw89_info(rtwdev, "R_BE_PL_CPUQ_OP_STATUS=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_PL_CPUQ_OP_STATUS));
} else {
- rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0));
- rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1));
- rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));
+ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS));
+ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));
+ if (chip->chip_id == RTL8852C) {
+ rtw89_info(rtwdev, "R_AX_RX_CTRL0=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RX_CTRL0));
+ rtw89_info(rtwdev, "R_AX_RX_CTRL1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RX_CTRL1));
+ rtw89_info(rtwdev, "R_AX_RX_CTRL2=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RX_CTRL2));
+ } else {
+ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0));
+ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1));
+ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));
+ }
}
}
@@ -479,22 +552,37 @@ static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
}
if (dmac_err & B_AX_DISPATCH_ERR_FLAG) {
- rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
- rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
- rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
- rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
- rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
- rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
+ if (chip->chip_id == RTL8922A) {
+ rtw89_info(rtwdev, "R_BE_DISP_HOST_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_HOST_IMR));
+ rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR1));
+ rtw89_info(rtwdev, "R_BE_DISP_CPU_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_CPU_IMR));
+ rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR2=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR2));
+ rtw89_info(rtwdev, "R_BE_DISP_OTHER_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_OTHER_IMR));
+ rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR0=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR0));
+ } else {
+ rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
+ rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
+ rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
+ rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
+ rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
+ rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
+ }
}
if (dmac_err & B_AX_BBRPT_ERR_FLAG) {
- if (chip->chip_id == RTL8852C) {
+ if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A) {
rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR));
rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n",
@@ -519,18 +607,54 @@ static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
}
+ if (chip->chip_id == RTL8922A) {
+ rtw89_info(rtwdev, "R_BE_LA_ERRFLAG_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_LA_ERRFLAG_IMR));
+ rtw89_info(rtwdev, "R_BE_LA_ERRFLAG_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_LA_ERRFLAG_ISR));
+ }
+ }
+
+ if (dmac_err & B_AX_HAXIDMA_ERR_FLAG) {
+ if (chip->chip_id == RTL8922A) {
+ rtw89_info(rtwdev, "R_BE_HAXI_IDCT_MSK=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_HAXI_IDCT_MSK));
+ rtw89_info(rtwdev, "R_BE_HAXI_IDCT=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_HAXI_IDCT));
+ } else if (chip->chip_id == RTL8852C) {
+ rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK));
+ rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_HAXI_IDCT));
+ }
+ }
+
+ if (dmac_err & B_BE_P_AXIDMA_ERR_INT) {
+ rtw89_info(rtwdev, "R_BE_PL_AXIDMA_IDCT_MSK=0x%08x\n",
+ rtw89_mac_mem_read(rtwdev, R_BE_PL_AXIDMA_IDCT_MSK,
+ RTW89_MAC_MEM_AXIDMA));
+ rtw89_info(rtwdev, "R_BE_PL_AXIDMA_IDCT=0x%08x\n",
+ rtw89_mac_mem_read(rtwdev, R_BE_PL_AXIDMA_IDCT,
+ RTW89_MAC_MEM_AXIDMA));
+ }
+
+ if (dmac_err & B_BE_MLO_ERR_INT) {
+ rtw89_info(rtwdev, "R_BE_MLO_ERR_IDCT_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_MLO_ERR_IDCT_IMR));
+ rtw89_info(rtwdev, "R_BE_PKTIN_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_MLO_ERR_IDCT_ISR));
}
- if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) {
- rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK));
- rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_HAXI_IDCT));
+ if (dmac_err & B_BE_PLRLS_ERR_INT) {
+ rtw89_info(rtwdev, "R_BE_PLRLS_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_PLRLS_ERR_IMR));
+ rtw89_info(rtwdev, "R_BE_PLRLS_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_PLRLS_ERR_ISR));
}
}
-static void rtw89_mac_dump_cmac_err_status(struct rtw89_dev *rtwdev,
- u8 band)
+static void rtw89_mac_dump_cmac_err_status_ax(struct rtw89_dev *rtwdev,
+ u8 band)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 offset = 0;
@@ -620,8 +744,8 @@ static void rtw89_mac_dump_cmac_err_status(struct rtw89_dev *rtwdev,
rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset));
}
-static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev,
- enum mac_ax_err_info err)
+static void rtw89_mac_dump_err_status_ax(struct rtw89_dev *rtwdev,
+ enum mac_ax_err_info err)
{
if (err != MAC_AX_ERR_L1_ERR_DMAC &&
err != MAC_AX_ERR_L0_PROMOTE_TO_L1 &&
@@ -633,11 +757,16 @@ static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev,
rtw89_info(rtwdev, "--->\nerr=0x%x\n", err);
rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n",
rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
+ rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
+ rtw89_info(rtwdev, "DBG Counter 1 (R_AX_DRV_FW_HSK_4)=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_DRV_FW_HSK_4));
+ rtw89_info(rtwdev, "DBG Counter 2 (R_AX_DRV_FW_HSK_5)=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_DRV_FW_HSK_5));
rtw89_mac_dump_dmac_err_status(rtwdev);
- rtw89_mac_dump_cmac_err_status(rtwdev, RTW89_MAC_0);
- if (rtwdev->dbcc_en)
- rtw89_mac_dump_cmac_err_status(rtwdev, RTW89_MAC_1);
+ rtw89_mac_dump_cmac_err_status_ax(rtwdev, RTW89_MAC_0);
+ rtw89_mac_dump_cmac_err_status_ax(rtwdev, RTW89_MAC_1);
rtwdev->hci.ops->dump_err_status(rtwdev);
@@ -682,6 +811,7 @@ static bool rtw89_mac_suppress_log(struct rtw89_dev *rtwdev, u32 err)
u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 err, err_scnr;
int ret;
@@ -707,7 +837,7 @@ u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev)
return err;
rtw89_fw_st_dbg_dump(rtwdev);
- rtw89_mac_dump_err_status(rtwdev, err);
+ mac->dump_err_status(rtwdev, err);
return err;
}
@@ -901,7 +1031,7 @@ static int hfc_pub_ctrl(struct rtw89_dev *rtwdev)
return 0;
}
-static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
+static void hfc_get_mix_info_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_page_regs *regs = chip->page_regs;
@@ -910,11 +1040,6 @@ static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
struct rtw89_hfc_pub_info *info = &param->pub_info;
u32 val;
- int ret;
-
- ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
- if (ret)
- return ret;
val = rtw89_read32(rtwdev, regs->pub_page_info1);
info->g0_used = u32_get_bits(val, B_AX_G0_USE_PG_MASK);
@@ -959,6 +1084,19 @@ static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
val = rtw89_read32(rtwdev, regs->pub_page_ctrl1);
pub_cfg->grp0 = u32_get_bits(val, B_AX_PUBPG_G0_MASK);
pub_cfg->grp1 = u32_get_bits(val, B_AX_PUBPG_G1_MASK);
+}
+
+static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
+ int ret;
+
+ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
+ if (ret)
+ return ret;
+
+ mac->hfc_get_mix_info(rtwdev);
ret = hfc_pub_info_chk(rtwdev);
if (param->en && ret)
@@ -967,7 +1105,7 @@ static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
return 0;
}
-static void hfc_h2c_cfg(struct rtw89_dev *rtwdev)
+static void hfc_h2c_cfg_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_page_regs *regs = chip->page_regs;
@@ -983,7 +1121,7 @@ static void hfc_h2c_cfg(struct rtw89_dev *rtwdev)
prec_cfg->h2c_full_cond);
}
-static void hfc_mix_cfg(struct rtw89_dev *rtwdev)
+static void hfc_mix_cfg_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_page_regs *regs = chip->page_regs;
@@ -1018,7 +1156,7 @@ static void hfc_mix_cfg(struct rtw89_dev *rtwdev)
rtw89_write32(rtwdev, regs->hci_fc_ctrl, val);
}
-static void hfc_func_en(struct rtw89_dev *rtwdev, bool en, bool h2c_en)
+static void hfc_func_en_ax(struct rtw89_dev *rtwdev, bool en, bool h2c_en)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_page_regs *regs = chip->page_regs;
@@ -1034,8 +1172,9 @@ static void hfc_func_en(struct rtw89_dev *rtwdev, bool en, bool h2c_en)
rtw89_write32(rtwdev, regs->hci_fc_ctrl, val);
}
-static int hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en)
+int rtw89_mac_hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 dma_ch_mask = chip->dma_ch_mask;
u8 ch;
@@ -1050,11 +1189,11 @@ static int hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en)
if (ret)
return ret;
- hfc_func_en(rtwdev, false, false);
+ mac->hfc_func_en(rtwdev, false, false);
if (!en && h2c_en) {
- hfc_h2c_cfg(rtwdev);
- hfc_func_en(rtwdev, en, h2c_en);
+ mac->hfc_h2c_cfg(rtwdev);
+ mac->hfc_func_en(rtwdev, en, h2c_en);
return ret;
}
@@ -1070,9 +1209,9 @@ static int hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en)
if (ret)
return ret;
- hfc_mix_cfg(rtwdev);
+ mac->hfc_mix_cfg(rtwdev);
if (en || h2c_en) {
- hfc_func_en(rtwdev, en, h2c_en);
+ mac->hfc_func_en(rtwdev, en, h2c_en);
udelay(10);
}
for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) {
@@ -1334,9 +1473,14 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
if (on) {
set_bit(RTW89_FLAG_POWERON, rtwdev->flags);
+ set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
+ set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_TP_MAJOR);
} else {
clear_bit(RTW89_FLAG_POWERON, rtwdev->flags);
+ clear_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
+ clear_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
+ clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR);
rtw89_set_entity_state(rtwdev, false);
@@ -1351,7 +1495,7 @@ void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev)
rtw89_mac_power_switch(rtwdev, false);
}
-static int cmac_func_en(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
+static int cmac_func_en_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
{
u32 func_en = 0;
u32 ck_en = 0;
@@ -1397,7 +1541,7 @@ static int cmac_func_en(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
return 0;
}
-static int dmac_func_en(struct rtw89_dev *rtwdev)
+static int dmac_func_en_ax(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 val32;
@@ -1429,7 +1573,7 @@ static int dmac_func_en(struct rtw89_dev *rtwdev)
return 0;
}
-static int chip_func_en(struct rtw89_dev *rtwdev)
+static int chip_func_en_ax(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
@@ -1440,19 +1584,19 @@ static int chip_func_en(struct rtw89_dev *rtwdev)
return 0;
}
-static int rtw89_mac_sys_init(struct rtw89_dev *rtwdev)
+static int sys_init_ax(struct rtw89_dev *rtwdev)
{
int ret;
- ret = dmac_func_en(rtwdev);
+ ret = dmac_func_en_ax(rtwdev);
if (ret)
return ret;
- ret = cmac_func_en(rtwdev, 0, true);
+ ret = cmac_func_en_ax(rtwdev, 0, true);
if (ret)
return ret;
- ret = chip_func_en(rtwdev);
+ ret = chip_func_en_ax(rtwdev);
if (ret)
return ret;
@@ -1461,10 +1605,14 @@ static int rtw89_mac_sys_init(struct rtw89_dev *rtwdev)
const struct rtw89_mac_size_set rtw89_mac_size = {
.hfc_preccfg_pcie = {2, 40, 0, 0, 1, 0, 0, 0},
+ .hfc_prec_cfg_c0 = {2, 32, 0, 0, 0, 0, 0, 0},
+ .hfc_prec_cfg_c2 = {0, 256, 0, 0, 0, 0, 0, 0},
/* PCIE 64 */
.wde_size0 = {RTW89_WDE_PG_64, 4095, 1,},
+ .wde_size0_v1 = {RTW89_WDE_PG_64, 3328, 0, 0,},
/* DLFW */
.wde_size4 = {RTW89_WDE_PG_64, 0, 4096,},
+ .wde_size4_v1 = {RTW89_WDE_PG_64, 0, 3328, 0,},
/* PCIE 64 */
.wde_size6 = {RTW89_WDE_PG_64, 512, 0,},
/* 8852B PCIE SCC */
@@ -1477,6 +1625,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.wde_size19 = {RTW89_WDE_PG_64, 3328, 0,},
/* PCIE */
.ple_size0 = {RTW89_PLE_PG_128, 1520, 16,},
+ .ple_size0_v1 = {RTW89_PLE_PG_128, 2672, 256, 212992,},
+ .ple_size3_v1 = {RTW89_PLE_PG_128, 2928, 0, 212992,},
/* DLFW */
.ple_size4 = {RTW89_PLE_PG_128, 64, 1472,},
/* PCIE 64 */
@@ -1489,6 +1639,7 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.ple_size19 = {RTW89_PLE_PG_128, 1904, 16,},
/* PCIE 64 */
.wde_qt0 = {3792, 196, 0, 107,},
+ .wde_qt0_v1 = {3302, 6, 0, 20,},
/* DLFW */
.wde_qt4 = {0, 0, 0, 0,},
/* PCIE 64 */
@@ -1499,10 +1650,13 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.wde_qt17 = {0, 0, 0, 0,},
/* 8852C PCIE SCC */
.wde_qt18 = {3228, 60, 0, 40,},
+ .ple_qt0 = {320, 0, 32, 16, 13, 13, 292, 0, 32, 18, 1, 4, 0,},
+ .ple_qt1 = {320, 0, 32, 16, 1944, 1944, 2223, 0, 1963, 1949, 1, 1935, 0,},
/* PCIE SCC */
.ple_qt4 = {264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8,},
/* PCIE SCC */
.ple_qt5 = {264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120,},
+ .ple_qt9 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 1, 0, 0,},
/* DLFW */
.ple_qt13 = {0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0,},
/* PCIE 64 */
@@ -1523,6 +1677,10 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.ple_qt_52b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,},
/* 8851B PCIE WOW */
.ple_qt_51b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,},
+ .ple_rsvd_qt0 = {2, 112, 56, 6, 6, 6, 6, 0, 0, 62,},
+ .ple_rsvd_qt1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
+ .rsvd0_size0 = {212992, 0,},
+ .rsvd1_size0 = {587776, 2048,},
};
EXPORT_SYMBOL(rtw89_mac_size);
@@ -1541,7 +1699,9 @@ static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev,
return NULL;
}
+ mac->dle_info.rsvd_qt = cfg->rsvd_qt;
mac->dle_info.ple_pg_size = cfg->ple_size->pge_size;
+ mac->dle_info.ple_free_pg = cfg->ple_size->lnk_pge_num;
mac->dle_info.qta_mode = mode;
mac->dle_info.c0_rx_qta = cfg->ple_min_qt->cma0_dma;
mac->dle_info.c1_rx_qta = cfg->ple_min_qt->cma1_dma;
@@ -1549,33 +1709,86 @@ static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev,
return cfg;
}
-static bool mac_is_txq_empty(struct rtw89_dev *rtwdev)
+int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_dle_rsvd_qt_type type,
+ struct rtw89_mac_dle_rsvd_qt_cfg *cfg)
+{
+ struct rtw89_dle_info *dle_info = &rtwdev->mac.dle_info;
+ const struct rtw89_rsvd_quota *rsvd_qt = dle_info->rsvd_qt;
+
+ switch (type) {
+ case DLE_RSVD_QT_MPDU_INFO:
+ cfg->pktid = dle_info->ple_free_pg;
+ cfg->pg_num = rsvd_qt->mpdu_info_tbl;
+ break;
+ case DLE_RSVD_QT_B0_CSI:
+ cfg->pktid = dle_info->ple_free_pg + rsvd_qt->mpdu_info_tbl;
+ cfg->pg_num = rsvd_qt->b0_csi;
+ break;
+ case DLE_RSVD_QT_B1_CSI:
+ cfg->pktid = dle_info->ple_free_pg +
+ rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi;
+ cfg->pg_num = rsvd_qt->b1_csi;
+ break;
+ case DLE_RSVD_QT_B0_LMR:
+ cfg->pktid = dle_info->ple_free_pg +
+ rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi;
+ cfg->pg_num = rsvd_qt->b0_lmr;
+ break;
+ case DLE_RSVD_QT_B1_LMR:
+ cfg->pktid = dle_info->ple_free_pg +
+ rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi +
+ rsvd_qt->b0_lmr;
+ cfg->pg_num = rsvd_qt->b1_lmr;
+ break;
+ case DLE_RSVD_QT_B0_FTM:
+ cfg->pktid = dle_info->ple_free_pg +
+ rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi +
+ rsvd_qt->b0_lmr + rsvd_qt->b1_lmr;
+ cfg->pg_num = rsvd_qt->b0_ftm;
+ break;
+ case DLE_RSVD_QT_B1_FTM:
+ cfg->pktid = dle_info->ple_free_pg +
+ rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi +
+ rsvd_qt->b0_lmr + rsvd_qt->b1_lmr + rsvd_qt->b0_ftm;
+ cfg->pg_num = rsvd_qt->b1_ftm;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ cfg->size = (u32)cfg->pg_num * dle_info->ple_pg_size;
+
+ return 0;
+}
+
+static bool mac_is_txq_empty_ax(struct rtw89_dev *rtwdev)
{
struct rtw89_mac_dle_dfi_qempty qempty;
- u32 qnum, qtmp, val32, msk32;
+ u32 grpnum, qtmp, val32, msk32;
int i, j, ret;
- qnum = rtwdev->chip->wde_qempty_acq_num;
+ grpnum = rtwdev->chip->wde_qempty_acq_grpnum;
qempty.dle_type = DLE_CTRL_TYPE_WDE;
- for (i = 0; i < qnum; i++) {
+ for (i = 0; i < grpnum; i++) {
qempty.grpsel = i;
- ret = dle_dfi_qempty(rtwdev, &qempty);
+ ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
if (ret) {
rtw89_warn(rtwdev, "dle dfi acq empty %d\n", ret);
return false;
}
qtmp = qempty.qempty;
for (j = 0 ; j < QEMP_ACQ_GRP_MACID_NUM; j++) {
- val32 = FIELD_GET(QEMP_ACQ_GRP_QSEL_MASK, qtmp);
+ val32 = u32_get_bits(qtmp, QEMP_ACQ_GRP_QSEL_MASK);
if (val32 != QEMP_ACQ_GRP_QSEL_MASK)
return false;
qtmp >>= QEMP_ACQ_GRP_QSEL_SH;
}
}
- qempty.grpsel = rtwdev->chip->wde_qempty_mgq_sel;
- ret = dle_dfi_qempty(rtwdev, &qempty);
+ qempty.grpsel = rtwdev->chip->wde_qempty_mgq_grpsel;
+ ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
if (ret) {
rtw89_warn(rtwdev, "dle dfi mgq empty %d\n", ret);
return false;
@@ -1603,11 +1816,21 @@ static bool mac_is_txq_empty(struct rtw89_dev *rtwdev)
return (val32 & msk32) == msk32;
}
-static inline u32 dle_used_size(const struct rtw89_dle_size *wde,
- const struct rtw89_dle_size *ple)
+static inline u32 dle_used_size(const struct rtw89_dle_mem *cfg)
{
- return wde->pge_size * (wde->lnk_pge_num + wde->unlnk_pge_num) +
+ const struct rtw89_dle_size *wde = cfg->wde_size;
+ const struct rtw89_dle_size *ple = cfg->ple_size;
+ u32 used;
+
+ used = wde->pge_size * (wde->lnk_pge_num + wde->unlnk_pge_num) +
ple->pge_size * (ple->lnk_pge_num + ple->unlnk_pge_num);
+
+ if (cfg->rsvd0_size && cfg->rsvd1_size) {
+ used += cfg->rsvd0_size->size;
+ used += cfg->rsvd1_size->size;
+ }
+
+ return used;
}
static u32 dle_expected_used_size(struct rtw89_dev *rtwdev,
@@ -1621,7 +1844,7 @@ static u32 dle_expected_used_size(struct rtw89_dev *rtwdev,
return size;
}
-static void dle_func_en(struct rtw89_dev *rtwdev, bool enable)
+static void dle_func_en_ax(struct rtw89_dev *rtwdev, bool enable)
{
if (enable)
rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
@@ -1631,7 +1854,7 @@ static void dle_func_en(struct rtw89_dev *rtwdev, bool enable)
B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN);
}
-static void dle_clk_en(struct rtw89_dev *rtwdev, bool enable)
+static void dle_clk_en_ax(struct rtw89_dev *rtwdev, bool enable)
{
u32 val = B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN;
@@ -1644,7 +1867,7 @@ static void dle_clk_en(struct rtw89_dev *rtwdev, bool enable)
}
}
-static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg)
+static int dle_mix_cfg_ax(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg)
{
const struct rtw89_dle_size *size_cfg;
u32 val;
@@ -1701,6 +1924,23 @@ static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg
return 0;
}
+static int chk_dle_rdy_ax(struct rtw89_dev *rtwdev, bool wde_or_ple)
+{
+ u32 reg, mask;
+ u32 ini;
+
+ if (wde_or_ple) {
+ reg = R_AX_WDE_INI_STATUS;
+ mask = WDE_MGN_INI_RDY;
+ } else {
+ reg = R_AX_PLE_INI_STATUS;
+ mask = PLE_MGN_INI_RDY;
+ }
+
+ return read_poll_timeout(rtw89_read32, ini, (ini & mask) == mask, 1,
+ 2000, false, rtwdev, reg);
+}
+
#define INVALID_QT_WCPU U16_MAX
#define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx) \
do { \
@@ -1713,10 +1953,10 @@ static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg
#define SET_QUOTA(_x, _module, _idx) \
SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx)
-static void wde_quota_cfg(struct rtw89_dev *rtwdev,
- const struct rtw89_wde_quota *min_cfg,
- const struct rtw89_wde_quota *max_cfg,
- u16 ext_wde_min_qt_wcpu)
+static void wde_quota_cfg_ax(struct rtw89_dev *rtwdev,
+ const struct rtw89_wde_quota *min_cfg,
+ const struct rtw89_wde_quota *max_cfg,
+ u16 ext_wde_min_qt_wcpu)
{
u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ?
ext_wde_min_qt_wcpu : min_cfg->wcpu;
@@ -1728,9 +1968,9 @@ static void wde_quota_cfg(struct rtw89_dev *rtwdev,
SET_QUOTA(cpu_io, WDE, 4);
}
-static void ple_quota_cfg(struct rtw89_dev *rtwdev,
- const struct rtw89_ple_quota *min_cfg,
- const struct rtw89_ple_quota *max_cfg)
+static void ple_quota_cfg_ax(struct rtw89_dev *rtwdev,
+ const struct rtw89_ple_quota *min_cfg,
+ const struct rtw89_ple_quota *max_cfg)
{
u32 val;
@@ -1795,17 +2035,19 @@ static void dle_quota_cfg(struct rtw89_dev *rtwdev,
const struct rtw89_dle_mem *cfg,
u16 ext_wde_min_qt_wcpu)
{
- wde_quota_cfg(rtwdev, cfg->wde_min_qt, cfg->wde_max_qt, ext_wde_min_qt_wcpu);
- ple_quota_cfg(rtwdev, cfg->ple_min_qt, cfg->ple_max_qt);
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ mac->wde_quota_cfg(rtwdev, cfg->wde_min_qt, cfg->wde_max_qt, ext_wde_min_qt_wcpu);
+ mac->ple_quota_cfg(rtwdev, cfg->ple_min_qt, cfg->ple_max_qt);
}
-static int dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
- enum rtw89_qta_mode ext_mode)
+int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
+ enum rtw89_qta_mode ext_mode)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_dle_mem *cfg, *ext_cfg;
u16 ext_wde_min_qt_wcpu = INVALID_QT_WCPU;
- int ret = 0;
- u32 ini;
+ int ret;
ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
if (ret)
@@ -1829,36 +2071,31 @@ static int dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
ext_wde_min_qt_wcpu = ext_cfg->wde_min_qt->wcpu;
}
- if (dle_used_size(cfg->wde_size, cfg->ple_size) !=
- dle_expected_used_size(rtwdev, mode)) {
+ if (dle_used_size(cfg) != dle_expected_used_size(rtwdev, mode)) {
rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n");
ret = -EINVAL;
goto error;
}
- dle_func_en(rtwdev, false);
- dle_clk_en(rtwdev, true);
+ mac->dle_func_en(rtwdev, false);
+ mac->dle_clk_en(rtwdev, true);
- ret = dle_mix_cfg(rtwdev, cfg);
+ ret = mac->dle_mix_cfg(rtwdev, cfg);
if (ret) {
rtw89_err(rtwdev, "[ERR] dle mix cfg\n");
goto error;
}
dle_quota_cfg(rtwdev, cfg, ext_wde_min_qt_wcpu);
- dle_func_en(rtwdev, true);
+ mac->dle_func_en(rtwdev, true);
- ret = read_poll_timeout(rtw89_read32, ini,
- (ini & WDE_MGN_INI_RDY) == WDE_MGN_INI_RDY, 1,
- 2000, false, rtwdev, R_AX_WDE_INI_STATUS);
+ ret = mac->chk_dle_rdy(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "[ERR]WDE cfg ready\n");
return ret;
}
- ret = read_poll_timeout(rtw89_read32, ini,
- (ini & WDE_MGN_INI_RDY) == WDE_MGN_INI_RDY, 1,
- 2000, false, rtwdev, R_AX_PLE_INI_STATUS);
+ ret = mac->chk_dle_rdy(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "[ERR]PLE cfg ready\n");
return ret;
@@ -1866,7 +2103,7 @@ static int dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
return 0;
error:
- dle_func_en(rtwdev, false);
+ mac->dle_func_en(rtwdev, false);
rtw89_err(rtwdev, "[ERR]trxcfg wde 0x8900 = %x\n",
rtw89_read32(rtwdev, R_AX_WDE_INI_STATUS));
rtw89_err(rtwdev, "[ERR]trxcfg ple 0x8D00 = %x\n",
@@ -1901,8 +2138,8 @@ static bool is_qta_poh(struct rtw89_dev *rtwdev)
return rtwdev->hci.type == RTW89_HCI_TYPE_PCIE;
}
-static int preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx,
- enum rtw89_qta_mode mode)
+int rtw89_mac_preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx,
+ enum rtw89_qta_mode mode)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -1951,7 +2188,7 @@ static void _patch_ss2f_path(struct rtw89_dev *rtwdev)
SS2F_PATH_WLCPU);
}
-static int sta_sch_init(struct rtw89_dev *rtwdev)
+static int sta_sch_init_ax(struct rtw89_dev *rtwdev)
{
u32 p_val;
u8 val;
@@ -1980,7 +2217,7 @@ static int sta_sch_init(struct rtw89_dev *rtwdev)
return 0;
}
-static int mpdu_proc_init(struct rtw89_dev *rtwdev)
+static int mpdu_proc_init_ax(struct rtw89_dev *rtwdev)
{
int ret;
@@ -1997,7 +2234,7 @@ static int mpdu_proc_init(struct rtw89_dev *rtwdev)
return 0;
}
-static int sec_eng_init(struct rtw89_dev *rtwdev)
+static int sec_eng_init_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 val = 0;
@@ -2032,41 +2269,41 @@ static int sec_eng_init(struct rtw89_dev *rtwdev)
return 0;
}
-static int dmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int dmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
int ret;
- ret = dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID);
+ ret = rtw89_mac_dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID);
if (ret) {
rtw89_err(rtwdev, "[ERR]DLE init %d\n", ret);
return ret;
}
- ret = preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode);
+ ret = rtw89_mac_preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode);
if (ret) {
rtw89_err(rtwdev, "[ERR]preload init %d\n", ret);
return ret;
}
- ret = hfc_init(rtwdev, true, true, true);
+ ret = rtw89_mac_hfc_init(rtwdev, true, true, true);
if (ret) {
rtw89_err(rtwdev, "[ERR]HCI FC init %d\n", ret);
return ret;
}
- ret = sta_sch_init(rtwdev);
+ ret = sta_sch_init_ax(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR]STA SCH init %d\n", ret);
return ret;
}
- ret = mpdu_proc_init(rtwdev);
+ ret = mpdu_proc_init_ax(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR]MPDU Proc init %d\n", ret);
return ret;
}
- ret = sec_eng_init(rtwdev);
+ ret = sec_eng_init_ax(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR]Security Engine init %d\n", ret);
return ret;
@@ -2075,7 +2312,7 @@ static int dmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return ret;
}
-static int addr_cam_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int addr_cam_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
u32 val, reg;
u16 p_val;
@@ -2102,7 +2339,7 @@ static int addr_cam_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int scheduler_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
u32 ret;
u32 reg;
@@ -2143,10 +2380,10 @@ static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev,
- enum rtw89_machdr_frame_type type,
- enum rtw89_mac_fwd_target fwd_target,
- u8 mac_idx)
+static int rtw89_mac_typ_fltr_opt_ax(struct rtw89_dev *rtwdev,
+ enum rtw89_machdr_frame_type type,
+ enum rtw89_mac_fwd_target fwd_target,
+ u8 mac_idx)
{
u32 reg;
u32 val;
@@ -2185,7 +2422,7 @@ int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev,
return 0;
}
-static int rx_fltr_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int rx_fltr_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
int ret, i;
u32 mac_ftlr, plcp_ftlr;
@@ -2195,8 +2432,8 @@ static int rx_fltr_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return ret;
for (i = RTW89_MGNT; i <= RTW89_DATA; i++) {
- ret = rtw89_mac_typ_fltr_opt(rtwdev, i, RTW89_FWD_TO_HOST,
- mac_idx);
+ ret = rtw89_mac_typ_fltr_opt_ax(rtwdev, i, RTW89_FWD_TO_HOST,
+ mac_idx);
if (ret)
return ret;
}
@@ -2247,7 +2484,7 @@ static void _patch_dis_resp_chk(struct rtw89_dev *rtwdev, u8 mac_idx)
}
}
-static int cca_ctrl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int cca_ctrl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
u32 val, reg;
int ret;
@@ -2279,7 +2516,7 @@ static int cca_ctrl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-static int nav_ctrl_init(struct rtw89_dev *rtwdev)
+static int nav_ctrl_init_ax(struct rtw89_dev *rtwdev)
{
rtw89_write32_set(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_PLCP_UP_NAV_EN |
B_AX_WMAC_TF_UP_NAV_EN |
@@ -2289,7 +2526,7 @@ static int nav_ctrl_init(struct rtw89_dev *rtwdev)
return 0;
}
-static int spatial_reuse_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int spatial_reuse_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
u32 reg;
int ret;
@@ -2303,7 +2540,7 @@ static int spatial_reuse_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-static int tmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int tmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
u32 reg;
int ret;
@@ -2325,7 +2562,7 @@ static int tmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-static int trxptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int trxptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_rrsr_cfgs *rrsr = chip->rrsr_cfgs;
@@ -2382,7 +2619,7 @@ static void rst_bacam(struct rtw89_dev *rtwdev)
rtw89_warn(rtwdev, "failed to reset BA CAM\n");
}
-static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int rmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
#define TRXCFG_RMAC_CCA_TO 32
#define TRXCFG_RMAC_DATA_TO 15
@@ -2440,7 +2677,7 @@ static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return ret;
}
-static int cmac_com_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int cmac_com_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 val, reg;
@@ -2465,7 +2702,7 @@ static int cmac_com_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-static bool is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
+bool rtw89_mac_is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
{
const struct rtw89_dle_mem *cfg;
@@ -2478,7 +2715,7 @@ static bool is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
return (cfg->ple_min_qt->cma1_dma && cfg->ple_max_qt->cma1_dma);
}
-static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int ptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
u32 val, reg;
int ret;
@@ -2521,7 +2758,7 @@ static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-static int cmac_dma_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int cmac_dma_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 reg;
@@ -2540,82 +2777,82 @@ static int cmac_dma_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-static int cmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
+static int cmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
int ret;
- ret = scheduler_init(rtwdev, mac_idx);
+ ret = scheduler_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d SCH init %d\n", mac_idx, ret);
return ret;
}
- ret = addr_cam_init(rtwdev, mac_idx);
+ ret = addr_cam_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d ADDR_CAM reset %d\n", mac_idx,
ret);
return ret;
}
- ret = rx_fltr_init(rtwdev, mac_idx);
+ ret = rx_fltr_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d RX filter init %d\n", mac_idx,
ret);
return ret;
}
- ret = cca_ctrl_init(rtwdev, mac_idx);
+ ret = cca_ctrl_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d CCA CTRL init %d\n", mac_idx,
ret);
return ret;
}
- ret = nav_ctrl_init(rtwdev);
+ ret = nav_ctrl_init_ax(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d NAV CTRL init %d\n", mac_idx,
ret);
return ret;
}
- ret = spatial_reuse_init(rtwdev, mac_idx);
+ ret = spatial_reuse_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n",
mac_idx, ret);
return ret;
}
- ret = tmac_init(rtwdev, mac_idx);
+ ret = tmac_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d TMAC init %d\n", mac_idx, ret);
return ret;
}
- ret = trxptcl_init(rtwdev, mac_idx);
+ ret = trxptcl_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d TRXPTCL init %d\n", mac_idx, ret);
return ret;
}
- ret = rmac_init(rtwdev, mac_idx);
+ ret = rmac_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d RMAC init %d\n", mac_idx, ret);
return ret;
}
- ret = cmac_com_init(rtwdev, mac_idx);
+ ret = cmac_com_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d Com init %d\n", mac_idx, ret);
return ret;
}
- ret = ptcl_init(rtwdev, mac_idx);
+ ret = ptcl_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d PTCL init %d\n", mac_idx, ret);
return ret;
}
- ret = cmac_dma_init(rtwdev, mac_idx);
+ ret = cmac_dma_init_ax(rtwdev, mac_idx);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d DMA init %d\n", mac_idx, ret);
return ret;
@@ -2878,7 +3115,7 @@ int rtw89_mac_resume_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
}
EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v1);
-int rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id)
+static int dle_buf_req_ax(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id)
{
u32 val, reg;
int ret;
@@ -2902,7 +3139,7 @@ int rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *p
return 0;
}
-int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev,
+static int set_cpuio_ax(struct rtw89_dev *rtwdev,
struct rtw89_cpuio_ctrl *ctrl_para, bool wd)
{
u32 val, cmd_type, reg;
@@ -2955,8 +3192,9 @@ int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev,
return 0;
}
-static int dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
+int rtw89_mac_dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_dle_mem *cfg;
struct rtw89_cpuio_ctrl ctrl_para = {0};
u16 pkt_id;
@@ -2968,15 +3206,14 @@ static int dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
return -EINVAL;
}
- if (dle_used_size(cfg->wde_size, cfg->ple_size) !=
- dle_expected_used_size(rtwdev, mode)) {
+ if (dle_used_size(cfg) != dle_expected_used_size(rtwdev, mode)) {
rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n");
return -EINVAL;
}
dle_quota_cfg(rtwdev, cfg, INVALID_QT_WCPU);
- ret = rtw89_mac_dle_buf_req(rtwdev, 0x20, true, &pkt_id);
+ ret = mac->dle_buf_req(rtwdev, 0x20, true, &pkt_id);
if (ret) {
rtw89_err(rtwdev, "[ERR]WDE DLE buf req\n");
return ret;
@@ -2988,13 +3225,13 @@ static int dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
ctrl_para.pkt_num = 0;
ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS;
ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT;
- ret = rtw89_mac_set_cpuio(rtwdev, &ctrl_para, true);
+ ret = mac->set_cpuio(rtwdev, &ctrl_para, true);
if (ret) {
rtw89_err(rtwdev, "[ERR]WDE DLE enqueue to head\n");
return -EFAULT;
}
- ret = rtw89_mac_dle_buf_req(rtwdev, 0x20, false, &pkt_id);
+ ret = mac->dle_buf_req(rtwdev, 0x20, false, &pkt_id);
if (ret) {
rtw89_err(rtwdev, "[ERR]PLE DLE buf req\n");
return ret;
@@ -3006,7 +3243,7 @@ static int dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
ctrl_para.pkt_num = 0;
ctrl_para.dst_pid = PLE_DLE_PORT_ID_PLRLS;
ctrl_para.dst_qid = PLE_DLE_QUEID_NO_REPORT;
- ret = rtw89_mac_set_cpuio(rtwdev, &ctrl_para, false);
+ ret = mac->set_cpuio(rtwdev, &ctrl_para, false);
if (ret) {
rtw89_err(rtwdev, "[ERR]PLE DLE enqueue to head\n");
return -EFAULT;
@@ -3038,7 +3275,7 @@ static int band_idle_ck_b(struct rtw89_dev *rtwdev, u8 mac_idx)
return 0;
}
-static int band1_enable(struct rtw89_dev *rtwdev)
+static int band1_enable_ax(struct rtw89_dev *rtwdev)
{
int ret, i;
u32 sleep_bak[4] = {0};
@@ -3064,7 +3301,7 @@ static int band1_enable(struct rtw89_dev *rtwdev)
return ret;
}
- ret = dle_quota_change(rtwdev, rtwdev->mac.qta_mode);
+ ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode);
if (ret) {
rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret);
return ret;
@@ -3081,13 +3318,13 @@ static int band1_enable(struct rtw89_dev *rtwdev)
return ret;
}
- ret = cmac_func_en(rtwdev, 1, true);
+ ret = cmac_func_en_ax(rtwdev, 1, true);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC1 func en %d\n", ret);
return ret;
}
- ret = cmac_init(rtwdev, 1);
+ ret = cmac_init_ax(rtwdev, 1);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC1 init %d\n", ret);
return ret;
@@ -3296,8 +3533,8 @@ static void rtw89_tmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
rtw89_write32_set(rtwdev, reg, imr->tmac_imr_set);
}
-static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx,
- enum rtw89_mac_hwmod_sel sel)
+static int enable_imr_ax(struct rtw89_dev *rtwdev, u8 mac_idx,
+ enum rtw89_mac_hwmod_sel sel)
{
int ret;
@@ -3334,7 +3571,7 @@ static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx,
return 0;
}
-static void rtw89_mac_err_imr_ctrl(struct rtw89_dev *rtwdev, bool en)
+static void err_imr_ctrl_ax(struct rtw89_dev *rtwdev, bool en)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
@@ -3347,18 +3584,18 @@ static void rtw89_mac_err_imr_ctrl(struct rtw89_dev *rtwdev, bool en)
en ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS);
}
-static int rtw89_mac_dbcc_enable(struct rtw89_dev *rtwdev, bool enable)
+static int dbcc_enable_ax(struct rtw89_dev *rtwdev, bool enable)
{
int ret = 0;
if (enable) {
- ret = band1_enable(rtwdev);
+ ret = band1_enable_ax(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR] band1_enable %d\n", ret);
return ret;
}
- ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL);
+ ret = enable_imr_ax(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL);
if (ret) {
rtw89_err(rtwdev, "[ERR] enable CMAC1 IMR %d\n", ret);
return ret;
@@ -3371,7 +3608,7 @@ static int rtw89_mac_dbcc_enable(struct rtw89_dev *rtwdev, bool enable)
return 0;
}
-static int set_host_rpr(struct rtw89_dev *rtwdev)
+static int set_host_rpr_ax(struct rtw89_dev *rtwdev)
{
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG,
@@ -3391,46 +3628,46 @@ static int set_host_rpr(struct rtw89_dev *rtwdev)
return 0;
}
-static int rtw89_mac_trx_init(struct rtw89_dev *rtwdev)
+static int trx_init_ax(struct rtw89_dev *rtwdev)
{
enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode;
int ret;
- ret = dmac_init(rtwdev, 0);
+ ret = dmac_init_ax(rtwdev, 0);
if (ret) {
rtw89_err(rtwdev, "[ERR]DMAC init %d\n", ret);
return ret;
}
- ret = cmac_init(rtwdev, 0);
+ ret = cmac_init_ax(rtwdev, 0);
if (ret) {
rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", 0, ret);
return ret;
}
- if (is_qta_dbcc(rtwdev, qta_mode)) {
- ret = rtw89_mac_dbcc_enable(rtwdev, true);
+ if (rtw89_mac_is_qta_dbcc(rtwdev, qta_mode)) {
+ ret = dbcc_enable_ax(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "[ERR]dbcc_enable init %d\n", ret);
return ret;
}
}
- ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
+ ret = enable_imr_ax(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
if (ret) {
rtw89_err(rtwdev, "[ERR] enable DMAC IMR %d\n", ret);
return ret;
}
- ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL);
+ ret = enable_imr_ax(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL);
if (ret) {
rtw89_err(rtwdev, "[ERR] to enable CMAC0 IMR %d\n", ret);
return ret;
}
- rtw89_mac_err_imr_ctrl(rtwdev, true);
+ err_imr_ctrl_ax(rtwdev, true);
- ret = set_host_rpr(rtwdev);
+ ret = set_host_rpr_ax(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret);
return ret;
@@ -3521,11 +3758,10 @@ static int rtw89_mac_enable_cpu_ax(struct rtw89_dev *rtwdev, u8 boot_reason,
return 0;
}
-static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev)
+static void rtw89_mac_hci_func_en_ax(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 val;
- int ret;
if (chip_id == RTL8852C)
val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN |
@@ -3534,6 +3770,12 @@ static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev)
val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN |
B_AX_PKT_BUF_EN;
rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val);
+}
+
+static void rtw89_mac_dmac_func_pre_en_ax(struct rtw89_dev *rtwdev)
+{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+ u32 val;
if (chip_id == RTL8851B)
val = B_AX_DISPATCHER_CLK_EN | B_AX_AXIDMA_CLK_EN;
@@ -3542,7 +3784,7 @@ static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev)
rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val);
if (chip_id != RTL8852C)
- goto dle;
+ return;
val = rtw89_read32(rtwdev, R_AX_HAXI_INIT_CFG1);
val &= ~(B_AX_DMA_MODE_MASK | B_AX_STOP_AXI_MST);
@@ -3557,15 +3799,23 @@ static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev)
B_AX_STOP_CH12 | B_AX_STOP_ACH2);
rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP2, B_AX_STOP_CH10 | B_AX_STOP_CH11);
rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_AXIDMA_EN);
+}
+
+static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ int ret;
-dle:
- ret = dle_init(rtwdev, RTW89_QTA_DLFW, rtwdev->mac.qta_mode);
+ mac->hci_func_en(rtwdev);
+ mac->dmac_func_pre_en(rtwdev);
+
+ ret = rtw89_mac_dle_init(rtwdev, RTW89_QTA_DLFW, rtwdev->mac.qta_mode);
if (ret) {
rtw89_err(rtwdev, "[ERR]DLE pre init %d\n", ret);
return ret;
}
- ret = hfc_init(rtwdev, true, false, true);
+ ret = rtw89_mac_hfc_init(rtwdev, true, false, true);
if (ret) {
rtw89_err(rtwdev, "[ERR]HCI FC pre init %d\n", ret);
return ret;
@@ -3639,6 +3889,7 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb)
int rtw89_mac_init(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_chip_info *chip = rtwdev->chip;
bool include_bb = !!chip->bbmcu_nr;
int ret;
@@ -3651,11 +3902,11 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
if (ret)
goto fail;
- ret = rtw89_mac_sys_init(rtwdev);
+ ret = mac->sys_init(rtwdev);
if (ret)
goto fail;
- ret = rtw89_mac_trx_init(rtwdev);
+ ret = mac->trx_init(rtwdev);
if (ret)
goto fail;
@@ -3754,6 +4005,50 @@ static const struct rtw89_port_reg rtw89_port_base_ax = {
R_AX_PORT_HGQ_WINDOW_CFG + 3},
};
+static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif, u8 type)
+{
+ u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif->port);
+ u32 reg_info, reg_ctrl;
+ u32 val;
+ int ret;
+
+ reg_info = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_DBG_INFO, rtwvif->mac_idx);
+ reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_DBG, rtwvif->mac_idx);
+
+ rtw89_write32_mask(rtwdev, reg_ctrl, B_AX_PTCL_DBG_SEL_MASK, type);
+ rtw89_write32_set(rtwdev, reg_ctrl, B_AX_PTCL_DBG_EN);
+ fsleep(100);
+
+ ret = read_poll_timeout(rtw89_read32_mask, val, val == 0, 1000, 100000,
+ true, rtwdev, reg_info, mask);
+ if (ret)
+ rtw89_warn(rtwdev, "Polling beacon packet empty fail\n");
+}
+
+static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ const struct rtw89_port_reg *p = mac->port_base;
+
+ rtw89_write32_set(rtwdev, R_AX_BCN_DROP_ALL0, BIT(rtwvif->port));
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, 1);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, 0);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 0);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, 2);
+ rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK, 1);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, 1);
+ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
+
+ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM0);
+ if (rtwvif->port == RTW89_PORT_0)
+ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM1);
+
+ rtw89_write32_clr(rtwdev, R_AX_BCN_DROP_ALL0, BIT(rtwvif->port));
+ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TBTT_PROHIB_EN);
+ fsleep(2);
+}
+
#define BCN_INTERVAL 100
#define BCN_ERLY_DEF 160
#define BCN_SETUP_DEF 2
@@ -3769,21 +4064,36 @@ static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev,
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ bool need_backup = false;
+ u32 backup_val;
if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN))
return;
- rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1);
- rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK);
- rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK);
+ if (chip->chip_id == RTL8852A && rtwvif->port != RTW89_PORT_0) {
+ need_backup = true;
+ backup_val = rtw89_read32_port(rtwdev, rtwvif, p->tbtt_prohib);
+ }
+
+ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ rtw89_mac_bcn_drop(rtwdev, rtwvif);
- msleep(vif->bss_conf.beacon_int + 1);
+ if (chip->chip_id == RTL8852A) {
+ rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK);
+ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1);
+ rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK);
+ rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK);
+ }
+ msleep(vif->bss_conf.beacon_int + 1);
rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN |
B_AX_BRK_SETUP);
rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST);
rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0);
+
+ if (need_backup)
+ rtw89_write32_port(rtwdev, rtwvif, p->tbtt_prohib, backup_val);
}
static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev,
@@ -3864,12 +4174,10 @@ static void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif *rtwvif, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ||
- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
if (en)
rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
@@ -3877,6 +4185,24 @@ static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev,
rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
}
+static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif)
+{
+ bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ||
+ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
+
+ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en);
+}
+
+void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en)
+{
+ struct rtw89_vif *rtwvif;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif)
+ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en);
+}
+
static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
{
@@ -4183,7 +4509,7 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif);
rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif);
rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif);
+ rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif);
rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif);
rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif);
rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif);
@@ -4268,7 +4594,7 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
- rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, false);
+ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif);
}
int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
@@ -4345,8 +4671,10 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
switch (reason) {
case RTW89_SCAN_LEAVE_CH_NOTIFY:
- if (rtw89_is_op_chan(rtwdev, band, chan))
+ if (rtw89_is_op_chan(rtwdev, band, chan)) {
+ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, false);
ieee80211_stop_queues(rtwdev->hw);
+ }
return;
case RTW89_SCAN_END_SCAN_NOTIFY:
if (rtwvif && rtwvif->scan_req &&
@@ -4364,6 +4692,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
if (rtw89_is_op_chan(rtwdev, band, chan)) {
rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx,
&rtwdev->scan_info.op_chan);
+ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
ieee80211_wake_queues(rtwdev->hw);
} else {
rtw89_chan_create(&new, chan, chan, band,
@@ -5623,7 +5952,8 @@ int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
return 0;
}
-int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask)
+static
+int rtw89_mac_write_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask)
{
u32 val32;
int ret;
@@ -5645,9 +5975,9 @@ int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask
return 0;
}
-EXPORT_SYMBOL(rtw89_mac_write_xtal_si);
-int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
+static
+int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
{
u32 val32;
int ret;
@@ -5670,7 +6000,6 @@ int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
return 0;
}
-EXPORT_SYMBOL(rtw89_mac_read_xtal_si);
static
void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
@@ -5720,6 +6049,7 @@ void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_mac_idx band)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_pkt_drop_params params = {0};
bool empty;
int i, ret = 0, try_cnt = 3;
@@ -5728,7 +6058,7 @@ int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
params.sel = RTW89_PKT_DROP_SEL_BAND_ONCE;
for (i = 0; i < try_cnt; i++) {
- ret = read_poll_timeout(mac_is_txq_empty, empty, empty, 50,
+ ret = read_poll_timeout(mac->is_txq_empty, empty, empty, 50,
50000, false, rtwdev);
if (ret && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw))
rtw89_fw_h2c_pkt_drop(rtwdev, &params);
@@ -5776,8 +6106,28 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
B_AX_BFMEE_HE_NDPA_EN,
},
+ .check_mac_en = rtw89_mac_check_mac_en_ax,
+ .sys_init = sys_init_ax,
+ .trx_init = trx_init_ax,
+ .hci_func_en = rtw89_mac_hci_func_en_ax,
+ .dmac_func_pre_en = rtw89_mac_dmac_func_pre_en_ax,
+ .dle_func_en = dle_func_en_ax,
+ .dle_clk_en = dle_clk_en_ax,
.bf_assoc = rtw89_mac_bf_assoc_ax,
+ .typ_fltr_opt = rtw89_mac_typ_fltr_opt_ax,
+
+ .dle_mix_cfg = dle_mix_cfg_ax,
+ .chk_dle_rdy = chk_dle_rdy_ax,
+ .dle_buf_req = dle_buf_req_ax,
+ .hfc_func_en = hfc_func_en_ax,
+ .hfc_h2c_cfg = hfc_h2c_cfg_ax,
+ .hfc_mix_cfg = hfc_mix_cfg_ax,
+ .hfc_get_mix_info = hfc_get_mix_info_ax,
+ .wde_quota_cfg = wde_quota_cfg_ax,
+ .ple_quota_cfg = ple_quota_cfg_ax,
+ .set_cpuio = set_cpuio_ax,
+
.disable_cpu = rtw89_mac_disable_cpu_ax,
.fwdl_enable_wcpu = rtw89_mac_enable_cpu_ax,
.fwdl_get_status = rtw89_fw_get_rdy_ax,
@@ -5787,5 +6137,13 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.cnv_efuse_state = rtw89_cnv_efuse_state_ax,
.get_txpwr_cr = rtw89_mac_get_txpwr_cr_ax,
+
+ .write_xtal_si = rtw89_mac_write_xtal_si_ax,
+ .read_xtal_si = rtw89_mac_read_xtal_si_ax,
+
+ .dump_qta_lost = rtw89_mac_dump_qta_lost_ax,
+ .dump_err_status = rtw89_mac_dump_err_status_ax,
+
+ .is_txq_empty = mac_is_txq_empty_ax,
};
EXPORT_SYMBOL(rtw89_mac_gen_ax);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index f47a42387a6a..ed98b49809a4 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -537,6 +537,9 @@ enum rtw89_mac_bf_rrsc_rate {
#define B_CMAC1_MGQ_NO_PWRSAV BIT(11)
#define B_CMAC1_CPUMGQ BIT(12)
+#define B_CMAC0_MGQ_NORMAL_BE BIT(2)
+#define B_CMAC1_MGQ_NORMAL_BE BIT(30)
+
#define QEMP_ACQ_GRP_MACID_NUM 8
#define QEMP_ACQ_GRP_QSEL_SH 4
#define QEMP_ACQ_GRP_QSEL_MASK 0xF
@@ -650,6 +653,22 @@ struct rtw89_mac_dle_dfi_qempty {
u32 qempty;
};
+enum rtw89_mac_dle_rsvd_qt_type {
+ DLE_RSVD_QT_MPDU_INFO,
+ DLE_RSVD_QT_B0_CSI,
+ DLE_RSVD_QT_B1_CSI,
+ DLE_RSVD_QT_B0_LMR,
+ DLE_RSVD_QT_B1_LMR,
+ DLE_RSVD_QT_B0_FTM,
+ DLE_RSVD_QT_B1_FTM,
+};
+
+struct rtw89_mac_dle_rsvd_qt_cfg {
+ u16 pktid;
+ u16 pg_num;
+ u32 size;
+};
+
enum rtw89_mac_error_scenario {
RTW89_RXI300_ERROR = 1,
RTW89_WCPU_CPU_EXCEPTION = 2,
@@ -818,27 +837,37 @@ enum mac_ax_err_info {
struct rtw89_mac_size_set {
const struct rtw89_hfc_prec_cfg hfc_preccfg_pcie;
+ const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c0;
+ const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c2;
const struct rtw89_dle_size wde_size0;
+ const struct rtw89_dle_size wde_size0_v1;
const struct rtw89_dle_size wde_size4;
+ const struct rtw89_dle_size wde_size4_v1;
const struct rtw89_dle_size wde_size6;
const struct rtw89_dle_size wde_size7;
const struct rtw89_dle_size wde_size9;
const struct rtw89_dle_size wde_size18;
const struct rtw89_dle_size wde_size19;
const struct rtw89_dle_size ple_size0;
+ const struct rtw89_dle_size ple_size0_v1;
+ const struct rtw89_dle_size ple_size3_v1;
const struct rtw89_dle_size ple_size4;
const struct rtw89_dle_size ple_size6;
const struct rtw89_dle_size ple_size8;
const struct rtw89_dle_size ple_size18;
const struct rtw89_dle_size ple_size19;
const struct rtw89_wde_quota wde_qt0;
+ const struct rtw89_wde_quota wde_qt0_v1;
const struct rtw89_wde_quota wde_qt4;
const struct rtw89_wde_quota wde_qt6;
const struct rtw89_wde_quota wde_qt7;
const struct rtw89_wde_quota wde_qt17;
const struct rtw89_wde_quota wde_qt18;
+ const struct rtw89_ple_quota ple_qt0;
+ const struct rtw89_ple_quota ple_qt1;
const struct rtw89_ple_quota ple_qt4;
const struct rtw89_ple_quota ple_qt5;
+ const struct rtw89_ple_quota ple_qt9;
const struct rtw89_ple_quota ple_qt13;
const struct rtw89_ple_quota ple_qt18;
const struct rtw89_ple_quota ple_qt44;
@@ -849,6 +878,10 @@ struct rtw89_mac_size_set {
const struct rtw89_ple_quota ple_qt_52a_wow;
const struct rtw89_ple_quota ple_qt_52b_wow;
const struct rtw89_ple_quota ple_qt_51b_wow;
+ const struct rtw89_rsvd_quota ple_rsvd_qt0;
+ const struct rtw89_rsvd_quota ple_rsvd_qt1;
+ const struct rtw89_dle_rsvd_size rsvd0_size0;
+ const struct rtw89_dle_rsvd_size rsvd1_size0;
};
extern const struct rtw89_mac_size_set rtw89_mac_size;
@@ -865,9 +898,39 @@ struct rtw89_mac_gen_def {
struct rtw89_reg_def muedca_ctrl;
struct rtw89_reg_def bfee_ctrl;
+ int (*check_mac_en)(struct rtw89_dev *rtwdev, u8 band,
+ enum rtw89_mac_hwmod_sel sel);
+ int (*sys_init)(struct rtw89_dev *rtwdev);
+ int (*trx_init)(struct rtw89_dev *rtwdev);
+ void (*hci_func_en)(struct rtw89_dev *rtwdev);
+ void (*dmac_func_pre_en)(struct rtw89_dev *rtwdev);
+ void (*dle_func_en)(struct rtw89_dev *rtwdev, bool enable);
+ void (*dle_clk_en)(struct rtw89_dev *rtwdev, bool enable);
void (*bf_assoc)(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
+ int (*typ_fltr_opt)(struct rtw89_dev *rtwdev,
+ enum rtw89_machdr_frame_type type,
+ enum rtw89_mac_fwd_target fwd_target,
+ u8 mac_idx);
+
+ int (*dle_mix_cfg)(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg);
+ int (*chk_dle_rdy)(struct rtw89_dev *rtwdev, bool wde_or_ple);
+ int (*dle_buf_req)(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id);
+ void (*hfc_func_en)(struct rtw89_dev *rtwdev, bool en, bool h2c_en);
+ void (*hfc_h2c_cfg)(struct rtw89_dev *rtwdev);
+ void (*hfc_mix_cfg)(struct rtw89_dev *rtwdev);
+ void (*hfc_get_mix_info)(struct rtw89_dev *rtwdev);
+ void (*wde_quota_cfg)(struct rtw89_dev *rtwdev,
+ const struct rtw89_wde_quota *min_cfg,
+ const struct rtw89_wde_quota *max_cfg,
+ u16 ext_wde_min_qt_wcpu);
+ void (*ple_quota_cfg)(struct rtw89_dev *rtwdev,
+ const struct rtw89_ple_quota *min_cfg,
+ const struct rtw89_ple_quota *max_cfg);
+ int (*set_cpuio)(struct rtw89_dev *rtwdev,
+ struct rtw89_cpuio_ctrl *ctrl_para, bool wd);
+
void (*disable_cpu)(struct rtw89_dev *rtwdev);
int (*fwdl_enable_wcpu)(struct rtw89_dev *rtwdev, u8 boot_reason,
bool dlfw, bool include_bb);
@@ -880,6 +943,15 @@ struct rtw89_mac_gen_def {
bool (*get_txpwr_cr)(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
u32 reg_base, u32 *cr);
+
+ int (*write_xtal_si)(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask);
+ int (*read_xtal_si)(struct rtw89_dev *rtwdev, u8 offset, u8 *val);
+
+ void (*dump_qta_lost)(struct rtw89_dev *rtwdev);
+ void (*dump_err_status)(struct rtw89_dev *rtwdev,
+ enum mac_ax_err_info err);
+
+ bool (*is_txq_empty)(struct rtw89_dev *rtwdev);
};
extern const struct rtw89_mac_gen_def rtw89_mac_gen_ax;
@@ -981,10 +1053,31 @@ rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev);
int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb);
int rtw89_mac_init(struct rtw89_dev *rtwdev);
+int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
+ enum rtw89_qta_mode ext_mode);
+int rtw89_mac_hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en);
+int rtw89_mac_preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx,
+ enum rtw89_qta_mode mode);
+bool rtw89_mac_is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode);
+static inline
int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 band,
- enum rtw89_mac_hwmod_sel sel);
+ enum rtw89_mac_hwmod_sel sel)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ return mac->check_mac_en(rtwdev, band, sel);
+}
+
int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val);
int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val);
+int rtw89_mac_dle_dfi_cfg(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl);
+int rtw89_mac_dle_dfi_quota_cfg(struct rtw89_dev *rtwdev,
+ struct rtw89_mac_dle_dfi_quota *quota);
+void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev);
+int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev,
+ struct rtw89_mac_dle_dfi_qempty *qempty);
+void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev,
+ enum mac_ax_err_info err);
int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
@@ -996,6 +1089,7 @@ int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif);
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en);
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev);
int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
@@ -1014,6 +1108,23 @@ static inline int rtw89_chip_disable_bb_rf(struct rtw89_dev *rtwdev)
return chip->ops->disable_bb_rf(rtwdev);
}
+static inline int rtw89_chip_reset_bb_rf(struct rtw89_dev *rtwdev)
+{
+ int ret;
+
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ return 0;
+
+ ret = rtw89_chip_disable_bb_rf(rtwdev);
+ if (ret)
+ return ret;
+ ret = rtw89_chip_enable_bb_rf(rtwdev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev);
int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err);
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
@@ -1189,6 +1300,7 @@ enum rtw89_mac_xtal_si_offset {
#define XTAL_SC_XI_MASK GENMASK(7, 0)
XTAL_SI_XTAL_SC_XO = 0x05,
#define XTAL_SC_XO_MASK GENMASK(7, 0)
+ XTAL_SI_XREF_MODE = 0x0B,
XTAL_SI_PWR_CUT = 0x10,
#define XTAL_SI_SMALL_PWR_CUT BIT(0)
#define XTAL_SI_BIG_PWR_CUT BIT(1)
@@ -1198,6 +1310,8 @@ enum rtw89_mac_xtal_si_offset {
#define XTAL_SI_LDO_LPS GENMASK(6, 4)
XTAL_SI_XTAL_XMD_4 = 0x26,
#define XTAL_SI_LPS_CAP GENMASK(3, 0)
+ XTAL_SI_XREF_RF1 = 0x2D,
+ XTAL_SI_XREF_RF2 = 0x2E,
XTAL_SI_CV = 0x41,
#define XTAL_SI_ACV_MASK GENMASK(3, 0)
XTAL_SI_LOW_ADDR = 0x62,
@@ -1225,20 +1339,34 @@ enum rtw89_mac_xtal_si_offset {
XTAL_SI_SRAM_CTRL = 0xA1,
#define XTAL_SI_SRAM_DIS BIT(1)
#define FULL_BIT_MASK GENMASK(7, 0)
+ XTAL_SI_PLL = 0xE0,
+ XTAL_SI_PLL_1 = 0xE1,
};
-int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask);
-int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val);
+static inline
+int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ return mac->write_xtal_si(rtwdev, offset, val, mask);
+}
+
+static inline
+int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ return mac->read_xtal_si(rtwdev, offset, val);
+}
+
void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
-int rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id);
-int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev,
- struct rtw89_cpuio_ctrl *ctrl_para, bool wd);
-int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev,
- enum rtw89_machdr_frame_type type,
- enum rtw89_mac_fwd_target fwd_target, u8 mac_idx);
int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow);
int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_mac_idx band);
void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool wow);
+int rtw89_mac_dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode);
+int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_dle_rsvd_qt_type type,
+ struct rtw89_mac_dle_rsvd_qt_cfg *cfg);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 31d1f7891675..93889d2fface 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -226,6 +226,7 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u32 rx_fltr;
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
@@ -272,16 +273,29 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
}
}
+ rx_fltr = rtwdev->hal.rx_fltr;
+
+ /* mac80211 doesn't configure filter when HW scan, driver need to
+ * set by itself. However, during P2P scan might have configure
+ * filter to overwrite filter that HW scan needed, so we need to
+ * check scan and append related filter
+ */
+ if (rtwdev->scanning) {
+ rx_fltr &= ~B_AX_A_BCN_CHK_EN;
+ rx_fltr &= ~B_AX_A_BC;
+ rx_fltr &= ~B_AX_A_A1_MATCH;
+ }
+
rtw89_write32_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
B_AX_RX_FLTR_CFG_MASK,
- rtwdev->hal.rx_fltr);
+ rx_fltr);
if (!rtwdev->dbcc_en)
goto out;
rtw89_write32_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1),
B_AX_RX_FLTR_CFG_MASK,
- rtwdev->hal.rx_fltr);
+ rx_fltr);
out:
mutex_unlock(&rtwdev->mutex);
@@ -477,6 +491,9 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
return -EOPNOTSUPP;
}
+ if (rtwdev->scanning)
+ rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
+
ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
rtw89_cam_bssid_changed(rtwdev, rtwvif);
rtw89_mac_port_update(rtwdev, rtwvif);
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index 1c607316f652..fa3f5ef289cb 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -57,6 +57,364 @@ static const struct rtw89_port_reg rtw89_port_base_be = {
R_BE_PORT_HGQ_WINDOW_CFG + 3},
};
+static int rtw89_mac_check_mac_en_be(struct rtw89_dev *rtwdev, u8 mac_idx,
+ enum rtw89_mac_hwmod_sel sel)
+{
+ if (sel == RTW89_DMAC_SEL &&
+ test_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags))
+ return 0;
+ if (sel == RTW89_CMAC_SEL && mac_idx == RTW89_MAC_0 &&
+ test_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags))
+ return 0;
+ if (sel == RTW89_CMAC_SEL && mac_idx == RTW89_MAC_1 &&
+ test_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags))
+ return 0;
+
+ return -EFAULT;
+}
+
+static void hfc_get_mix_info_be(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
+ struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
+ struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
+ struct rtw89_hfc_pub_info *info = &param->pub_info;
+ u32 val;
+
+ val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO1);
+ info->g0_used = u32_get_bits(val, B_BE_G0_USE_PG_MASK);
+ info->g1_used = u32_get_bits(val, B_BE_G1_USE_PG_MASK);
+
+ val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO3);
+ info->g0_aval = u32_get_bits(val, B_BE_G0_AVAL_PG_MASK);
+ info->g1_aval = u32_get_bits(val, B_BE_G1_AVAL_PG_MASK);
+ info->pub_aval = u32_get_bits(rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO2),
+ B_BE_PUB_AVAL_PG_MASK);
+ info->wp_aval = u32_get_bits(rtw89_read32(rtwdev, R_BE_WP_PAGE_INFO1),
+ B_BE_WP_AVAL_PG_MASK);
+
+ val = rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL);
+ param->en = !!(val & B_BE_HCI_FC_EN);
+ param->h2c_en = !!(val & B_BE_HCI_FC_CH12_EN);
+ param->mode = u32_get_bits(val, B_BE_HCI_FC_MODE_MASK);
+ prec_cfg->ch011_full_cond = u32_get_bits(val, B_BE_HCI_FC_WD_FULL_COND_MASK);
+ prec_cfg->h2c_full_cond = u32_get_bits(val, B_BE_HCI_FC_CH12_FULL_COND_MASK);
+ prec_cfg->wp_ch07_full_cond =
+ u32_get_bits(val, B_BE_HCI_FC_WP_CH07_FULL_COND_MASK);
+ prec_cfg->wp_ch811_full_cond =
+ u32_get_bits(val, B_BE_HCI_FC_WP_CH811_FULL_COND_MASK);
+
+ val = rtw89_read32(rtwdev, R_BE_CH_PAGE_CTRL);
+ prec_cfg->ch011_prec = u32_get_bits(val, B_BE_PREC_PAGE_CH011_V1_MASK);
+ prec_cfg->h2c_prec = u32_get_bits(val, B_BE_PREC_PAGE_CH12_V1_MASK);
+
+ val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_CTRL2);
+ pub_cfg->pub_max = u32_get_bits(val, B_BE_PUBPG_ALL_MASK);
+
+ val = rtw89_read32(rtwdev, R_BE_WP_PAGE_CTRL1);
+ prec_cfg->wp_ch07_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH07_MASK);
+ prec_cfg->wp_ch811_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH811_MASK);
+
+ val = rtw89_read32(rtwdev, R_BE_WP_PAGE_CTRL2);
+ pub_cfg->wp_thrd = u32_get_bits(val, B_BE_WP_THRD_MASK);
+
+ val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_CTRL1);
+ pub_cfg->grp0 = u32_get_bits(val, B_BE_PUBPG_G0_MASK);
+ pub_cfg->grp1 = u32_get_bits(val, B_BE_PUBPG_G1_MASK);
+}
+
+static void hfc_h2c_cfg_be(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
+ const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
+ u32 val;
+
+ val = u32_encode_bits(prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK);
+ rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, val);
+}
+
+static void hfc_mix_cfg_be(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
+ const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
+ const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
+ u32 val;
+
+ val = u32_encode_bits(prec_cfg->ch011_prec, B_BE_PREC_PAGE_CH011_V1_MASK) |
+ u32_encode_bits(prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK);
+ rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, val);
+
+ val = u32_encode_bits(pub_cfg->pub_max, B_BE_PUBPG_ALL_MASK);
+ rtw89_write32(rtwdev, R_BE_PUB_PAGE_CTRL2, val);
+
+ val = u32_encode_bits(prec_cfg->wp_ch07_prec, B_BE_PREC_PAGE_WP_CH07_MASK) |
+ u32_encode_bits(prec_cfg->wp_ch811_prec, B_BE_PREC_PAGE_WP_CH811_MASK);
+ rtw89_write32(rtwdev, R_BE_WP_PAGE_CTRL1, val);
+
+ val = u32_replace_bits(rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL),
+ param->mode, B_BE_HCI_FC_MODE_MASK);
+ val = u32_replace_bits(val, prec_cfg->ch011_full_cond,
+ B_BE_HCI_FC_WD_FULL_COND_MASK);
+ val = u32_replace_bits(val, prec_cfg->h2c_full_cond,
+ B_BE_HCI_FC_CH12_FULL_COND_MASK);
+ val = u32_replace_bits(val, prec_cfg->wp_ch07_full_cond,
+ B_BE_HCI_FC_WP_CH07_FULL_COND_MASK);
+ val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond,
+ B_BE_HCI_FC_WP_CH811_FULL_COND_MASK);
+ rtw89_write32(rtwdev, R_BE_HCI_FC_CTRL, val);
+}
+
+static void hfc_func_en_be(struct rtw89_dev *rtwdev, bool en, bool h2c_en)
+{
+ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
+ u32 val;
+
+ val = rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL);
+ param->en = en;
+ param->h2c_en = h2c_en;
+ val = en ? (val | B_BE_HCI_FC_EN) : (val & ~B_BE_HCI_FC_EN);
+ val = h2c_en ? (val | B_BE_HCI_FC_CH12_EN) :
+ (val & ~B_BE_HCI_FC_CH12_EN);
+ rtw89_write32(rtwdev, R_BE_HCI_FC_CTRL, val);
+}
+
+static void dle_func_en_be(struct rtw89_dev *rtwdev, bool enable)
+{
+ if (enable)
+ rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN,
+ B_BE_DLE_WDE_EN | B_BE_DLE_PLE_EN);
+ else
+ rtw89_write32_clr(rtwdev, R_BE_DMAC_FUNC_EN,
+ B_BE_DLE_WDE_EN | B_BE_DLE_PLE_EN);
+}
+
+static void dle_clk_en_be(struct rtw89_dev *rtwdev, bool enable)
+{
+ if (enable)
+ rtw89_write32_set(rtwdev, R_BE_DMAC_CLK_EN,
+ B_BE_DLE_WDE_CLK_EN | B_BE_DLE_PLE_CLK_EN);
+ else
+ rtw89_write32_clr(rtwdev, R_BE_DMAC_CLK_EN,
+ B_BE_DLE_WDE_CLK_EN | B_BE_DLE_PLE_CLK_EN);
+}
+
+static int dle_mix_cfg_be(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg)
+{
+ const struct rtw89_dle_size *wde_size_cfg, *ple_size_cfg;
+ u32 bound;
+ u32 val;
+
+ wde_size_cfg = cfg->wde_size;
+ ple_size_cfg = cfg->ple_size;
+
+ val = rtw89_read32(rtwdev, R_BE_WDE_PKTBUF_CFG);
+
+ switch (wde_size_cfg->pge_size) {
+ default:
+ case RTW89_WDE_PG_64:
+ val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_64,
+ B_BE_WDE_PAGE_SEL_MASK);
+ break;
+ case RTW89_WDE_PG_128:
+ val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_128,
+ B_BE_WDE_PAGE_SEL_MASK);
+ break;
+ case RTW89_WDE_PG_256:
+ rtw89_err(rtwdev, "[ERR]WDE DLE doesn't support 256 byte!\n");
+ return -EINVAL;
+ }
+
+ bound = wde_size_cfg->srt_ofst / DLE_BOUND_UNIT;
+ val = u32_replace_bits(val, bound, B_BE_WDE_START_BOUND_MASK);
+ val = u32_replace_bits(val, wde_size_cfg->lnk_pge_num,
+ B_BE_WDE_FREE_PAGE_NUM_MASK);
+ rtw89_write32(rtwdev, R_BE_WDE_PKTBUF_CFG, val);
+
+ val = rtw89_read32(rtwdev, R_BE_PLE_PKTBUF_CFG);
+
+ switch (ple_size_cfg->pge_size) {
+ default:
+ case RTW89_PLE_PG_64:
+ rtw89_err(rtwdev, "[ERR]PLE DLE doesn't support 64 byte!\n");
+ return -EINVAL;
+ case RTW89_PLE_PG_128:
+ val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_128,
+ B_BE_PLE_PAGE_SEL_MASK);
+ break;
+ case RTW89_PLE_PG_256:
+ val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_256,
+ B_BE_PLE_PAGE_SEL_MASK);
+ break;
+ }
+
+ bound = ple_size_cfg->srt_ofst / DLE_BOUND_UNIT;
+ val = u32_replace_bits(val, bound, B_BE_PLE_START_BOUND_MASK);
+ val = u32_replace_bits(val, ple_size_cfg->lnk_pge_num,
+ B_BE_PLE_FREE_PAGE_NUM_MASK);
+ rtw89_write32(rtwdev, R_BE_PLE_PKTBUF_CFG, val);
+
+ return 0;
+}
+
+static int chk_dle_rdy_be(struct rtw89_dev *rtwdev, bool wde_or_ple)
+{
+ u32 reg, mask;
+ u32 ini;
+
+ if (wde_or_ple) {
+ reg = R_AX_WDE_INI_STATUS;
+ mask = WDE_MGN_INI_RDY;
+ } else {
+ reg = R_AX_PLE_INI_STATUS;
+ mask = PLE_MGN_INI_RDY;
+ }
+
+ return read_poll_timeout(rtw89_read32, ini, (ini & mask) == mask, 1,
+ 2000, false, rtwdev, reg);
+}
+
+#define INVALID_QT_WCPU U16_MAX
+#define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx) \
+ do { \
+ val = u32_encode_bits(_min_x, B_BE_ ## _module ## _Q ## _idx ## _MIN_SIZE_MASK) | \
+ u32_encode_bits(_max_x, B_BE_ ## _module ## _Q ## _idx ## _MAX_SIZE_MASK); \
+ rtw89_write32(rtwdev, \
+ R_BE_ ## _module ## _QTA ## _idx ## _CFG, \
+ val); \
+ } while (0)
+#define SET_QUOTA(_x, _module, _idx) \
+ SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx)
+
+static void wde_quota_cfg_be(struct rtw89_dev *rtwdev,
+ const struct rtw89_wde_quota *min_cfg,
+ const struct rtw89_wde_quota *max_cfg,
+ u16 ext_wde_min_qt_wcpu)
+{
+ u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ?
+ ext_wde_min_qt_wcpu : min_cfg->wcpu;
+ u16 max_qt_wcpu = max(max_cfg->wcpu, min_qt_wcpu);
+ u32 val;
+
+ SET_QUOTA(hif, WDE, 0);
+ SET_QUOTA_VAL(min_qt_wcpu, max_qt_wcpu, WDE, 1);
+ SET_QUOTA_VAL(0, 0, WDE, 2);
+ SET_QUOTA(pkt_in, WDE, 3);
+ SET_QUOTA(cpu_io, WDE, 4);
+}
+
+static void ple_quota_cfg_be(struct rtw89_dev *rtwdev,
+ const struct rtw89_ple_quota *min_cfg,
+ const struct rtw89_ple_quota *max_cfg)
+{
+ u32 val;
+
+ SET_QUOTA(cma0_tx, PLE, 0);
+ SET_QUOTA(cma1_tx, PLE, 1);
+ SET_QUOTA(c2h, PLE, 2);
+ SET_QUOTA(h2c, PLE, 3);
+ SET_QUOTA(wcpu, PLE, 4);
+ SET_QUOTA(mpdu_proc, PLE, 5);
+ SET_QUOTA(cma0_dma, PLE, 6);
+ SET_QUOTA(cma1_dma, PLE, 7);
+ SET_QUOTA(bb_rpt, PLE, 8);
+ SET_QUOTA(wd_rel, PLE, 9);
+ SET_QUOTA(cpu_io, PLE, 10);
+ SET_QUOTA(tx_rpt, PLE, 11);
+ SET_QUOTA(h2d, PLE, 12);
+}
+
+static void rtw89_mac_hci_func_en_be(struct rtw89_dev *rtwdev)
+{
+ rtw89_write32_set(rtwdev, R_BE_HCI_FUNC_EN, B_BE_HCI_TXDMA_EN |
+ B_BE_HCI_RXDMA_EN);
+}
+
+static void rtw89_mac_dmac_func_pre_en_be(struct rtw89_dev *rtwdev)
+{
+ u32 val;
+
+ val = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);
+
+ switch (rtwdev->hci.type) {
+ case RTW89_HCI_TYPE_PCIE:
+ val = u32_replace_bits(val, S_BE_DMA_MOD_PCIE_NO_DATA_CPU,
+ B_BE_DMA_MODE_MASK);
+ break;
+ case RTW89_HCI_TYPE_USB:
+ val = u32_replace_bits(val, S_BE_DMA_MOD_USB, B_BE_DMA_MODE_MASK);
+ val = (val & ~B_BE_STOP_AXI_MST) | B_BE_TXDMA_EN | B_BE_RXDMA_EN;
+ break;
+ case RTW89_HCI_TYPE_SDIO:
+ val = u32_replace_bits(val, S_BE_DMA_MOD_SDIO, B_BE_DMA_MODE_MASK);
+ val = (val & ~B_BE_STOP_AXI_MST) | B_BE_TXDMA_EN | B_BE_RXDMA_EN;
+ break;
+ default:
+ return;
+ }
+
+ rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val);
+
+ rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1,
+ B_BE_STOP_CH0 | B_BE_STOP_CH1 | B_BE_STOP_CH2 |
+ B_BE_STOP_CH3 | B_BE_STOP_CH4 | B_BE_STOP_CH5 |
+ B_BE_STOP_CH6 | B_BE_STOP_CH7 | B_BE_STOP_CH8 |
+ B_BE_STOP_CH9 | B_BE_STOP_CH10 | B_BE_STOP_CH11 |
+ B_BE_STOP_CH12 | B_BE_STOP_CH13 | B_BE_STOP_CH14);
+
+ rtw89_write32_set(rtwdev, R_BE_DMAC_TABLE_CTRL, B_BE_DMAC_ADDR_MODE);
+}
+
+static
+int rtw89_mac_write_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask)
+{
+ u32 val32;
+ int ret;
+
+ val32 = u32_encode_bits(offset, B_BE_WL_XTAL_SI_ADDR_MASK) |
+ u32_encode_bits(val, B_BE_WL_XTAL_SI_DATA_MASK) |
+ u32_encode_bits(mask, B_BE_WL_XTAL_SI_BITMASK_MASK) |
+ u32_encode_bits(XTAL_SI_NORMAL_WRITE, B_BE_WL_XTAL_SI_MODE_MASK) |
+ u32_encode_bits(0, B_BE_WL_XTAL_SI_CHIPID_MASK) |
+ B_BE_WL_XTAL_SI_CMD_POLL;
+ rtw89_write32(rtwdev, R_BE_WLAN_XTAL_SI_CTRL, val32);
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_WL_XTAL_SI_CMD_POLL),
+ 50, 50000, false, rtwdev, R_BE_WLAN_XTAL_SI_CTRL);
+ if (ret) {
+ rtw89_warn(rtwdev, "xtal si not ready(W): offset=%x val=%x mask=%x\n",
+ offset, val, mask);
+ return ret;
+ }
+
+ return 0;
+}
+
+static
+int rtw89_mac_read_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
+{
+ u32 val32;
+ int ret;
+
+ val32 = u32_encode_bits(offset, B_BE_WL_XTAL_SI_ADDR_MASK) |
+ u32_encode_bits(0x0, B_BE_WL_XTAL_SI_DATA_MASK) |
+ u32_encode_bits(0x0, B_BE_WL_XTAL_SI_BITMASK_MASK) |
+ u32_encode_bits(XTAL_SI_NORMAL_READ, B_BE_WL_XTAL_SI_MODE_MASK) |
+ u32_encode_bits(0, B_BE_WL_XTAL_SI_CHIPID_MASK) |
+ B_BE_WL_XTAL_SI_CMD_POLL;
+ rtw89_write32(rtwdev, R_BE_WLAN_XTAL_SI_CTRL, val32);
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_WL_XTAL_SI_CMD_POLL),
+ 50, 50000, false, rtwdev, R_BE_WLAN_XTAL_SI_CTRL);
+ if (ret) {
+ rtw89_warn(rtwdev, "xtal si not ready(R): offset=%x\n", offset);
+ return ret;
+ }
+
+ *val = rtw89_read8(rtwdev, R_BE_WLAN_XTAL_SI_CTRL + 1);
+
+ return 0;
+}
+
static void rtw89_mac_disable_cpu_be(struct rtw89_dev *rtwdev)
{
u32 val32;
@@ -93,8 +451,6 @@ static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw)
u32 val32;
int ret;
- rtw89_write32_set(rtwdev, R_BE_UDM0, B_BE_UDM0_DBG_MODE_CTRL);
-
val32 = rtw89_read32(rtwdev, R_BE_HALT_C2H);
if (val32) {
rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n");
@@ -118,6 +474,10 @@ static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw)
rtw89_write32(rtwdev, R_BE_HALT_H2C_CTRL, 0);
rtw89_write32(rtwdev, R_BE_HALT_C2H_CTRL, 0);
+ val32 = rtw89_read32(rtwdev, R_BE_HISR0);
+ rtw89_write32(rtwdev, R_BE_HISR0, B_BE_HALT_C2H_INT);
+ rtw89_debug(rtwdev, RTW89_DBG_SER, "HISR0=0x%x\n", val32);
+
rtw89_write32_set(rtwdev, R_BE_SYS_CLK_CTRL, B_BE_CPU_CLK_EN);
rtw89_write32_clr(rtwdev, R_BE_SYS_CFG5,
B_BE_WDT_WAKE_PCIE_EN | B_BE_WDT_WAKE_USB_EN);
@@ -206,6 +566,90 @@ static int rtw89_fwdl_check_path_ready_be(struct rtw89_dev *rtwdev,
rtwdev, R_BE_WCPU_FW_CTRL);
}
+static int dle_buf_req_be(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id)
+{
+ u32 val, reg;
+ int ret;
+
+ reg = wd ? R_BE_WD_BUF_REQ : R_BE_PL_BUF_REQ;
+ val = buf_len;
+ val |= B_BE_WD_BUF_REQ_EXEC;
+ rtw89_write32(rtwdev, reg, val);
+
+ reg = wd ? R_BE_WD_BUF_STATUS : R_BE_PL_BUF_STATUS;
+
+ ret = read_poll_timeout(rtw89_read32, val, val & B_BE_WD_BUF_STAT_DONE,
+ 1, 2000, false, rtwdev, reg);
+ if (ret)
+ return ret;
+
+ *pkt_id = u32_get_bits(val, B_BE_WD_BUF_STAT_PKTID_MASK);
+ if (*pkt_id == S_WD_BUF_STAT_PKTID_INVALID)
+ return -ENOENT;
+
+ return 0;
+}
+
+static int set_cpuio_be(struct rtw89_dev *rtwdev,
+ struct rtw89_cpuio_ctrl *ctrl_para, bool wd)
+{
+ u32 val_op0, val_op1, val_op2, val_op3;
+ u32 val, cmd_type, reg;
+ int ret;
+
+ cmd_type = ctrl_para->cmd_type;
+
+ reg = wd ? R_BE_WD_CPUQ_OP_3 : R_BE_PL_CPUQ_OP_3;
+ val_op3 = u32_replace_bits(0, ctrl_para->start_pktid,
+ B_BE_WD_CPUQ_OP_STRT_PKTID_MASK);
+ val_op3 = u32_replace_bits(val_op3, ctrl_para->end_pktid,
+ B_BE_WD_CPUQ_OP_END_PKTID_MASK);
+ rtw89_write32(rtwdev, reg, val_op3);
+
+ reg = wd ? R_BE_WD_CPUQ_OP_1 : R_BE_PL_CPUQ_OP_1;
+ val_op1 = u32_replace_bits(0, ctrl_para->src_pid,
+ B_BE_WD_CPUQ_OP_SRC_PID_MASK);
+ val_op1 = u32_replace_bits(val_op1, ctrl_para->src_qid,
+ B_BE_WD_CPUQ_OP_SRC_QID_MASK);
+ val_op1 = u32_replace_bits(val_op1, ctrl_para->macid,
+ B_BE_WD_CPUQ_OP_SRC_MACID_MASK);
+ rtw89_write32(rtwdev, reg, val_op1);
+
+ reg = wd ? R_BE_WD_CPUQ_OP_2 : R_BE_PL_CPUQ_OP_2;
+ val_op2 = u32_replace_bits(0, ctrl_para->dst_pid,
+ B_BE_WD_CPUQ_OP_DST_PID_MASK);
+ val_op2 = u32_replace_bits(val_op2, ctrl_para->dst_qid,
+ B_BE_WD_CPUQ_OP_DST_QID_MASK);
+ val_op2 = u32_replace_bits(val_op2, ctrl_para->macid,
+ B_BE_WD_CPUQ_OP_DST_MACID_MASK);
+ rtw89_write32(rtwdev, reg, val_op2);
+
+ reg = wd ? R_BE_WD_CPUQ_OP_0 : R_BE_PL_CPUQ_OP_0;
+ val_op0 = u32_replace_bits(0, cmd_type,
+ B_BE_WD_CPUQ_OP_CMD_TYPE_MASK);
+ val_op0 = u32_replace_bits(val_op0, ctrl_para->pkt_num,
+ B_BE_WD_CPUQ_OP_PKTNUM_MASK);
+ val_op0 |= B_BE_WD_CPUQ_OP_EXEC;
+ rtw89_write32(rtwdev, reg, val_op0);
+
+ reg = wd ? R_BE_WD_CPUQ_OP_STATUS : R_BE_PL_CPUQ_OP_STATUS;
+
+ ret = read_poll_timeout(rtw89_read32, val, val & B_BE_WD_CPUQ_OP_STAT_DONE,
+ 1, 2000, false, rtwdev, reg);
+ if (ret) {
+ rtw89_err(rtwdev, "[ERR]set cpuio wd timeout\n");
+ rtw89_err(rtwdev, "[ERR]op_0=0x%X, op_1=0x%X, op_2=0x%X\n",
+ val_op0, val_op1, val_op2);
+ return ret;
+ }
+
+ if (cmd_type == CPUIO_OP_CMD_GET_NEXT_PID ||
+ cmd_type == CPUIO_OP_CMD_GET_1ST_PID)
+ ctrl_para->pktid = u32_get_bits(val, B_BE_WD_CPUQ_OP_PKTID_MASK);
+
+ return 0;
+}
+
static bool rtw89_mac_get_txpwr_cr_be(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
u32 reg_base, u32 *cr)
@@ -405,6 +849,299 @@ static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev,
}
}
+static void dump_err_status_dispatcher_be(struct rtw89_dev *rtwdev)
+{
+ rtw89_info(rtwdev, "R_BE_DISP_HOST_IMR=0x%08x ",
+ rtw89_read32(rtwdev, R_BE_DISP_HOST_IMR));
+ rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR1));
+ rtw89_info(rtwdev, "R_BE_DISP_CPU_IMR=0x%08x ",
+ rtw89_read32(rtwdev, R_BE_DISP_CPU_IMR));
+ rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR2=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR2));
+ rtw89_info(rtwdev, "R_BE_DISP_OTHER_IMR=0x%08x ",
+ rtw89_read32(rtwdev, R_BE_DISP_OTHER_IMR));
+ rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR0=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR0));
+}
+
+static void rtw89_mac_dump_qta_lost_be(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_mac_dle_dfi_qempty qempty;
+ struct rtw89_mac_dle_dfi_quota quota;
+ struct rtw89_mac_dle_dfi_ctrl ctrl;
+ u32 val, not_empty, i;
+ int ret;
+
+ qempty.dle_type = DLE_CTRL_TYPE_PLE;
+ qempty.grpsel = 0;
+ qempty.qempty = ~(u32)0;
+ ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
+ if (ret)
+ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
+ else
+ rtw89_info(rtwdev, "DLE group0 empty: 0x%x\n", qempty.qempty);
+
+ for (not_empty = ~qempty.qempty, i = 0; not_empty != 0; not_empty >>= 1, i++) {
+ if (!(not_empty & BIT(0)))
+ continue;
+ ctrl.type = DLE_CTRL_TYPE_PLE;
+ ctrl.target = DLE_DFI_TYPE_QLNKTBL;
+ ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) |
+ u32_encode_bits(i, QLNKTBL_ADDR_TBL_IDX_MASK);
+ ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl);
+ if (ret)
+ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
+ else
+ rtw89_info(rtwdev, "qidx%d pktcnt = %d\n", i,
+ u32_get_bits(ctrl.out_data,
+ QLNKTBL_DATA_SEL1_PKT_CNT_MASK));
+ }
+
+ quota.dle_type = DLE_CTRL_TYPE_PLE;
+ quota.qtaid = 6;
+ ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, &quota);
+ if (ret)
+ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
+ else
+ rtw89_info(rtwdev, "quota6 rsv/use: 0x%x/0x%x\n",
+ quota.rsv_pgnum, quota.use_pgnum);
+
+ val = rtw89_read32(rtwdev, R_BE_PLE_QTA6_CFG);
+ rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%x\n",
+ u32_get_bits(val, B_BE_PLE_Q6_MIN_SIZE_MASK));
+ rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%x\n",
+ u32_get_bits(val, B_BE_PLE_Q6_MAX_SIZE_MASK));
+ val = rtw89_read32(rtwdev, R_BE_RX_FLTR_OPT);
+ rtw89_info(rtwdev, "[PLE][CMAC0_RX]B_BE_RX_MPDU_MAX_LEN=0x%x\n",
+ u32_get_bits(val, B_BE_RX_MPDU_MAX_LEN_MASK));
+ rtw89_info(rtwdev, "R_BE_RSP_CHK_SIG=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_RSP_CHK_SIG));
+ rtw89_info(rtwdev, "R_BE_TRXPTCL_RESP_0=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_TRXPTCL_RESP_0));
+
+ if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) {
+ quota.dle_type = DLE_CTRL_TYPE_PLE;
+ quota.qtaid = 7;
+ ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, &quota);
+ if (ret)
+ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
+ else
+ rtw89_info(rtwdev, "quota7 rsv/use: 0x%x/0x%x\n",
+ quota.rsv_pgnum, quota.use_pgnum);
+
+ val = rtw89_read32(rtwdev, R_BE_PLE_QTA7_CFG);
+ rtw89_info(rtwdev, "[PLE][CMAC1_RX]min_pgnum=0x%x\n",
+ u32_get_bits(val, B_BE_PLE_Q7_MIN_SIZE_MASK));
+ rtw89_info(rtwdev, "[PLE][CMAC1_RX]max_pgnum=0x%x\n",
+ u32_get_bits(val, B_BE_PLE_Q7_MAX_SIZE_MASK));
+ val = rtw89_read32(rtwdev, R_BE_RX_FLTR_OPT_C1);
+ rtw89_info(rtwdev, "[PLE][CMAC1_RX]B_BE_RX_MPDU_MAX_LEN=0x%x\n",
+ u32_get_bits(val, B_BE_RX_MPDU_MAX_LEN_MASK));
+ rtw89_info(rtwdev, "R_BE_RSP_CHK_SIG_C1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_RSP_CHK_SIG_C1));
+ rtw89_info(rtwdev, "R_BE_TRXPTCL_RESP_0_C1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_TRXPTCL_RESP_0_C1));
+ }
+
+ rtw89_info(rtwdev, "R_BE_DLE_EMPTY0=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DLE_EMPTY0));
+ rtw89_info(rtwdev, "R_BE_DLE_EMPTY1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_DLE_EMPTY1));
+
+ dump_err_status_dispatcher_be(rtwdev);
+}
+
+static void rtw89_mac_dump_cmac_err_status_be(struct rtw89_dev *rtwdev,
+ u8 band)
+{
+ u32 offset = 0;
+ u32 cmac_err;
+ int ret;
+
+ ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
+ if (ret) {
+ rtw89_info(rtwdev, "[CMAC] : CMAC%d not enabled\n", band);
+ return;
+ }
+
+ if (band)
+ offset = RTW89_MAC_BE_BAND_REG_OFFSET;
+
+ cmac_err = rtw89_read32(rtwdev, R_BE_CMAC_ERR_ISR + offset);
+ rtw89_info(rtwdev, "R_BE_CMAC_ERR_ISR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_CMAC_ERR_ISR + offset));
+ rtw89_info(rtwdev, "R_BE_CMAC_FUNC_EN [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_CMAC_FUNC_EN + offset));
+ rtw89_info(rtwdev, "R_BE_CK_EN [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_CK_EN + offset));
+
+ if (cmac_err & B_BE_SCHEDULE_TOP_ERR_IND) {
+ rtw89_info(rtwdev, "R_BE_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_SCHEDULE_ERR_IMR + offset));
+ rtw89_info(rtwdev, "R_BE_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_SCHEDULE_ERR_ISR + offset));
+ }
+
+ if (cmac_err & B_BE_PTCL_TOP_ERR_IND) {
+ rtw89_info(rtwdev, "R_BE_PTCL_IMR0 [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_PTCL_IMR0 + offset));
+ rtw89_info(rtwdev, "R_BE_PTCL_ISR0 [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_PTCL_ISR0 + offset));
+ rtw89_info(rtwdev, "R_BE_PTCL_IMR1 [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_PTCL_IMR1 + offset));
+ rtw89_info(rtwdev, "R_BE_PTCL_ISR1 [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_PTCL_ISR1 + offset));
+ }
+
+ if (cmac_err & B_BE_DMA_TOP_ERR_IND) {
+ rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_IMR + offset));
+ rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG + offset));
+ rtw89_info(rtwdev, "R_BE_TX_ERROR_FLAG_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_TX_ERROR_FLAG_IMR + offset));
+ rtw89_info(rtwdev, "R_BE_TX_ERROR_FLAG [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_TX_ERROR_FLAG + offset));
+ rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_IMR_1 [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_IMR_1 + offset));
+ rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_1 [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_1 + offset));
+ }
+
+ if (cmac_err & B_BE_PHYINTF_ERR_IND) {
+ rtw89_info(rtwdev, "R_BE_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_PHYINFO_ERR_IMR_V1 + offset));
+ rtw89_info(rtwdev, "R_BE_PHYINFO_ERR_ISR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_PHYINFO_ERR_ISR + offset));
+ }
+
+ if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) {
+ rtw89_info(rtwdev, "R_BE_TXPWR_ERR_FLAG [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_TXPWR_ERR_FLAG + offset));
+ rtw89_info(rtwdev, "R_BE_TXPWR_ERR_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_TXPWR_ERR_IMR + offset));
+ }
+
+ if (cmac_err & (B_BE_WMAC_RX_ERR_IND | B_BE_WMAC_TX_ERR_IND |
+ B_BE_WMAC_RX_IDLETO_IDCT | B_BE_PTCL_TX_IDLETO_IDCT)) {
+ rtw89_info(rtwdev, "R_BE_DBGSEL_TRXPTCL [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_DBGSEL_TRXPTCL + offset));
+ rtw89_info(rtwdev, "R_BE_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_TRXPTCL_ERROR_INDICA_MASK + offset));
+ rtw89_info(rtwdev, "R_BE_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_TRXPTCL_ERROR_INDICA + offset));
+ rtw89_info(rtwdev, "R_BE_RX_ERR_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_RX_ERR_IMR + offset));
+ rtw89_info(rtwdev, "R_BE_RX_ERR_ISR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_RX_ERR_ISR + offset));
+ }
+
+ rtw89_info(rtwdev, "R_BE_CMAC_ERR_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_BE_CMAC_ERR_IMR + offset));
+}
+
+static void rtw89_mac_dump_err_status_be(struct rtw89_dev *rtwdev,
+ enum mac_ax_err_info err)
+{
+ if (err != MAC_AX_ERR_L1_ERR_DMAC &&
+ err != MAC_AX_ERR_L0_PROMOTE_TO_L1 &&
+ err != MAC_AX_ERR_L0_ERR_CMAC0 &&
+ err != MAC_AX_ERR_L0_ERR_CMAC1 &&
+ err != MAC_AX_ERR_RXI300)
+ return;
+
+ rtw89_info(rtwdev, "--->\nerr=0x%x\n", err);
+ rtw89_info(rtwdev, "R_BE_SER_DBG_INFO=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_DBG_INFO));
+ rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT));
+ rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT1));
+ rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT2=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT2));
+ rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT3=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT3));
+ if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) {
+ rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT_C1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT_C1));
+ rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT1_C1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT1_C1));
+ }
+ rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_0=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_0));
+ rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_1=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_1));
+ rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_2=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_2));
+ rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_3=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_3));
+ rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_4=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_4));
+ rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_5=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_5));
+ rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_6=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_6));
+ rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_7=0x%08x\n",
+ rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_7));
+
+ rtw89_mac_dump_dmac_err_status(rtwdev);
+ rtw89_mac_dump_cmac_err_status_be(rtwdev, RTW89_MAC_0);
+ rtw89_mac_dump_cmac_err_status_be(rtwdev, RTW89_MAC_1);
+
+ rtwdev->hci.ops->dump_err_status(rtwdev);
+
+ if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1)
+ rtw89_mac_dump_l0_to_l1(rtwdev, err);
+
+ rtw89_info(rtwdev, "<---\n");
+}
+
+static bool mac_is_txq_empty_be(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_mac_dle_dfi_qempty qempty;
+ u32 val32, msk32;
+ u32 grpnum;
+ int ret;
+ int i;
+
+ grpnum = rtwdev->chip->wde_qempty_acq_grpnum;
+ qempty.dle_type = DLE_CTRL_TYPE_WDE;
+
+ for (i = 0; i < grpnum; i++) {
+ qempty.grpsel = i;
+ ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
+ if (ret) {
+ rtw89_warn(rtwdev,
+ "%s: failed to dle dfi acq empty: %d\n",
+ __func__, ret);
+ return false;
+ }
+
+ /* Each acq group contains 32 queues (8 macid * 4 acq),
+ * but here, we can simply check if all bits are set.
+ */
+ if (qempty.qempty != MASKDWORD)
+ return false;
+ }
+
+ qempty.grpsel = rtwdev->chip->wde_qempty_mgq_grpsel;
+ ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
+ if (ret) {
+ rtw89_warn(rtwdev, "%s: failed to dle dfi mgq empty: %d\n",
+ __func__, ret);
+ return false;
+ }
+
+ msk32 = B_CMAC0_MGQ_NORMAL_BE | B_CMAC1_MGQ_NORMAL_BE;
+ if ((qempty.qempty & msk32) != msk32)
+ return false;
+
+ msk32 = B_BE_WDE_EMPTY_QUE_OTHERS;
+ val32 = rtw89_read32(rtwdev, R_BE_DLE_EMPTY0);
+ return (val32 & msk32) == msk32;
+}
+
const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.band1_offset = RTW89_MAC_BE_BAND_REG_OFFSET,
.filter_model_addr = R_BE_FILTER_MODEL_ADDR,
@@ -424,8 +1161,24 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
B_BE_BFMEE_HE_NDPA_EN | B_BE_BFMEE_EHT_NDPA_EN,
},
+ .check_mac_en = rtw89_mac_check_mac_en_be,
+ .hci_func_en = rtw89_mac_hci_func_en_be,
+ .dmac_func_pre_en = rtw89_mac_dmac_func_pre_en_be,
+ .dle_func_en = dle_func_en_be,
+ .dle_clk_en = dle_clk_en_be,
.bf_assoc = rtw89_mac_bf_assoc_be,
+ .dle_mix_cfg = dle_mix_cfg_be,
+ .chk_dle_rdy = chk_dle_rdy_be,
+ .dle_buf_req = dle_buf_req_be,
+ .hfc_func_en = hfc_func_en_be,
+ .hfc_h2c_cfg = hfc_h2c_cfg_be,
+ .hfc_mix_cfg = hfc_mix_cfg_be,
+ .hfc_get_mix_info = hfc_get_mix_info_be,
+ .wde_quota_cfg = wde_quota_cfg_be,
+ .ple_quota_cfg = ple_quota_cfg_be,
+ .set_cpuio = set_cpuio_be,
+
.disable_cpu = rtw89_mac_disable_cpu_be,
.fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be,
.fwdl_get_status = fwdl_get_status_be,
@@ -435,5 +1188,13 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.cnv_efuse_state = rtw89_cnv_efuse_state_be,
.get_txpwr_cr = rtw89_mac_get_txpwr_cr_be,
+
+ .write_xtal_si = rtw89_mac_write_xtal_si_be,
+ .read_xtal_si = rtw89_mac_read_xtal_si_be,
+
+ .dump_qta_lost = rtw89_mac_dump_qta_lost_be,
+ .dump_err_status = rtw89_mac_dump_err_status_be,
+
+ .is_txq_empty = mac_is_txq_empty_be,
};
EXPORT_SYMBOL(rtw89_mac_gen_be);
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 0ca07ae63594..769f1ce62ebc 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -3826,12 +3826,22 @@ static int rtw89_pci_ops_mac_lv1_recovery(struct rtw89_dev *rtwdev,
static void rtw89_pci_ops_dump_err_status(struct rtw89_dev *rtwdev)
{
- rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX =0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));
- rtw89_info(rtwdev, "R_AX_DBG_ERR_FLAG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG));
- rtw89_info(rtwdev, "R_AX_LBC_WATCHDOG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG));
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ return;
+
+ if (rtwdev->chip->chip_id == RTL8852C) {
+ rtw89_info(rtwdev, "R_AX_DBG_ERR_FLAG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG_V1));
+ rtw89_info(rtwdev, "R_AX_LBC_WATCHDOG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG_V1));
+ } else {
+ rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX =0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));
+ rtw89_info(rtwdev, "R_AX_DBG_ERR_FLAG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG));
+ rtw89_info(rtwdev, "R_AX_LBC_WATCHDOG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG));
+ }
}
static int rtw89_pci_napi_poll(struct napi_struct *napi, int budget)
diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h
index e2d8eef52b20..ca5de77fee90 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.h
+++ b/drivers/net/wireless/realtek/rtw89/pci.h
@@ -812,6 +812,8 @@
#define B_AX_RXCOUNTER_MATCH_MASK GENMASK(15, 8)
#define B_AX_RXTIMER_MATCH_MASK GENMASK(7, 0)
+#define R_AX_DBG_ERR_FLAG_V1 0x1104
+
#define R_AX_INT_MIT_RX_V1 0x1184
#define B_AX_RXMIT_RXP2_SEL_V1 BIT(19)
#define B_AX_RXMIT_RXP1_SEL_V1 BIT(18)
@@ -857,6 +859,8 @@
#define R_AX_PCIE_HRPWM_V1 0x30C0
#define R_AX_PCIE_CRPWM 0x30C4
+#define R_AX_LBC_WATCHDOG_V1 0x30D8
+
#define R_BE_PCIE_HRPWM 0x30C0
#define R_BE_PCIE_CRPWM 0x30C4
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 17ccc9efed28..bafc7b1cc104 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -2445,6 +2445,298 @@ void (* const rtw89_phy_c2h_ra_handler[])(struct rtw89_dev *rtwdev,
[RTW89_PHY_C2H_FUNC_TXSTS] = NULL,
};
+static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_c2h_rfk_log_func func,
+ void *content, u16 len)
+{
+ struct rtw89_c2h_rf_txgapk_rpt_log *txgapk;
+ struct rtw89_c2h_rf_rxdck_rpt_log *rxdck;
+ struct rtw89_c2h_rf_dack_rpt_log *dack;
+ struct rtw89_c2h_rf_dpk_rpt_log *dpk;
+
+ switch (func) {
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK:
+ if (len != sizeof(*dpk))
+ goto out;
+
+ dpk = content;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "DPK ver:%d idx:%2ph band:%2ph bw:%2ph ch:%2ph path:%2ph\n",
+ dpk->ver, dpk->idx, dpk->band, dpk->bw, dpk->ch, dpk->path_ok);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "DPK txagc:%2ph ther:%2ph gs:%2ph dc_i:%4ph dc_q:%4ph\n",
+ dpk->txagc, dpk->ther, dpk->gs, dpk->dc_i, dpk->dc_q);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "DPK corr_v:%2ph corr_i:%2ph to:%2ph ov:%2ph\n",
+ dpk->corr_val, dpk->corr_idx, dpk->is_timeout, dpk->rxbb_ov);
+ return;
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_DACK:
+ if (len != sizeof(*dack))
+ goto out;
+
+ dack = content;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ver=0x%x 0x%x\n",
+ dack->fwdack_ver, dack->fwdack_rpt_ver);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK ic = [0x%x, 0x%x]\n",
+ dack->cdack_d[0][0][0], dack->cdack_d[0][0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK qc = [0x%x, 0x%x]\n",
+ dack->cdack_d[0][1][0], dack->cdack_d[0][1][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 CDACK ic = [0x%x, 0x%x]\n",
+ dack->cdack_d[1][0][0], dack->cdack_d[1][0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 CDACK qc = [0x%x, 0x%x]\n",
+ dack->cdack_d[1][1][0], dack->cdack_d[1][1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = [0x%x, 0x%x]\n",
+ dack->addck2_d[0][0][0], dack->addck2_d[0][0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK qc = [0x%x, 0x%x]\n",
+ dack->addck2_d[0][1][0], dack->addck2_d[0][1][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK ic = [0x%x, 0x%x]\n",
+ dack->addck2_d[1][0][0], dack->addck2_d[1][0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK qc = [0x%x, 0x%x]\n",
+ dack->addck2_d[1][1][0], dack->addck2_d[1][1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_GAINK ic = 0x%x, qc = 0x%x\n",
+ dack->adgaink_d[0][0], dack->adgaink_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_GAINK ic = 0x%x, qc = 0x%x\n",
+ dack->adgaink_d[1][0], dack->adgaink_d[1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n",
+ dack->dadck_d[0][0], dack->dadck_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n",
+ dack->dadck_d[1][0], dack->dadck_d[1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask iqc = 0x%x\n",
+ dack->biask_d[0][0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 biask iqc = 0x%x\n",
+ dack->biask_d[1][0]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic: %*ph\n",
+ (int)sizeof(dack->msbk_d[0][0]), dack->msbk_d[0][0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc: %*ph\n",
+ (int)sizeof(dack->msbk_d[0][1]), dack->msbk_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic: %*ph\n",
+ (int)sizeof(dack->msbk_d[1][0]), dack->msbk_d[1][0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc: %*ph\n",
+ (int)sizeof(dack->msbk_d[1][1]), dack->msbk_d[1][1]);
+ return;
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK:
+ if (len != sizeof(*rxdck))
+ goto out;
+
+ rxdck = content;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "RXDCK ver:%d band:%2ph bw:%2ph ch:%2ph to:%2ph\n",
+ rxdck->ver, rxdck->band, rxdck->bw, rxdck->ch,
+ rxdck->timeout);
+ return;
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK:
+ if (len != sizeof(*txgapk))
+ goto out;
+
+ txgapk = content;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TXGAPK]rpt r0x8010[0]=0x%x, r0x8010[1]=0x%x\n",
+ le32_to_cpu(txgapk->r0x8010[0]),
+ le32_to_cpu(txgapk->r0x8010[1]));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt chk_id = %d\n",
+ txgapk->chk_id);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt chk_cnt = %d\n",
+ le32_to_cpu(txgapk->chk_cnt));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt ver = 0x%x\n",
+ txgapk->ver);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt rsv1 = %d\n",
+ txgapk->rsv1);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[0] = %*ph\n",
+ (int)sizeof(txgapk->track_d[0]), txgapk->track_d[0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt power_d[0] = %*ph\n",
+ (int)sizeof(txgapk->power_d[0]), txgapk->power_d[0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[1] = %*ph\n",
+ (int)sizeof(txgapk->track_d[1]), txgapk->track_d[1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt power_d[1] = %*ph\n",
+ (int)sizeof(txgapk->power_d[1]), txgapk->power_d[1]);
+ return;
+ default:
+ break;
+ }
+
+out:
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "unexpected RFK func %d report log with length %d\n", func, len);
+}
+
+static bool rtw89_phy_c2h_rfk_run_log(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_c2h_rfk_log_func func,
+ void *content, u16 len)
+{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ const struct rtw89_c2h_rf_run_log *log = content;
+ const struct rtw89_fw_element_hdr *elm;
+ u32 fmt_idx;
+ u16 offset;
+
+ if (sizeof(*log) != len)
+ return false;
+
+ if (!elm_info->rfk_log_fmt)
+ return false;
+
+ elm = elm_info->rfk_log_fmt->elm[func];
+ fmt_idx = le32_to_cpu(log->fmt_idx);
+ if (!elm || fmt_idx >= elm->u.rfk_log_fmt.nr)
+ return false;
+
+ offset = le16_to_cpu(elm->u.rfk_log_fmt.offset[fmt_idx]);
+ if (offset == 0)
+ return false;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, &elm->u.common.contents[offset],
+ le32_to_cpu(log->arg[0]), le32_to_cpu(log->arg[1]),
+ le32_to_cpu(log->arg[2]), le32_to_cpu(log->arg[3]));
+
+ return true;
+}
+
+static void rtw89_phy_c2h_rfk_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
+ u32 len, enum rtw89_phy_c2h_rfk_log_func func,
+ const char *rfk_name)
+{
+ struct rtw89_c2h_hdr *c2h_hdr = (struct rtw89_c2h_hdr *)c2h->data;
+ struct rtw89_c2h_rf_log_hdr *log_hdr;
+ void *log_ptr = c2h_hdr;
+ u16 content_len;
+ u16 chunk_len;
+ bool handled;
+
+ if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK))
+ return;
+
+ log_ptr += sizeof(*c2h_hdr);
+ len -= sizeof(*c2h_hdr);
+
+ while (len > sizeof(*log_hdr)) {
+ log_hdr = log_ptr;
+ content_len = le16_to_cpu(log_hdr->len);
+ chunk_len = content_len + sizeof(*log_hdr);
+
+ if (chunk_len > len)
+ break;
+
+ switch (log_hdr->type) {
+ case RTW89_RF_RUN_LOG:
+ handled = rtw89_phy_c2h_rfk_run_log(rtwdev, func,
+ log_hdr->content, content_len);
+ if (handled)
+ break;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s run: %*ph\n",
+ rfk_name, content_len, log_hdr->content);
+ break;
+ case RTW89_RF_RPT_LOG:
+ rtw89_phy_c2h_rfk_rpt_log(rtwdev, func,
+ log_hdr->content, content_len);
+ break;
+ default:
+ return;
+ }
+
+ log_ptr += chunk_len;
+ len -= chunk_len;
+ }
+}
+
+static void
+rtw89_phy_c2h_rfk_log_iqk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_IQK, "IQK");
+}
+
+static void
+rtw89_phy_c2h_rfk_log_dpk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_DPK, "DPK");
+}
+
+static void
+rtw89_phy_c2h_rfk_log_dack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_DACK, "DACK");
+}
+
+static void
+rtw89_phy_c2h_rfk_log_rxdck(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK, "RX_DCK");
+}
+
+static void
+rtw89_phy_c2h_rfk_log_tssi(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI, "TSSI");
+}
+
+static void
+rtw89_phy_c2h_rfk_log_txgapk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK, "TXGAPK");
+}
+
+static
+void (* const rtw89_phy_c2h_rfk_log_handler[])(struct rtw89_dev *rtwdev,
+ struct sk_buff *c2h, u32 len) = {
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_IQK] = rtw89_phy_c2h_rfk_log_iqk,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_DPK] = rtw89_phy_c2h_rfk_log_dpk,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_DACK] = rtw89_phy_c2h_rfk_log_dack,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK] = rtw89_phy_c2h_rfk_log_rxdck,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI] = rtw89_phy_c2h_rfk_log_tssi,
+ [RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK] = rtw89_phy_c2h_rfk_log_txgapk,
+};
+
+static void
+rtw89_phy_c2h_rfk_report_state(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static
+void (* const rtw89_phy_c2h_rfk_report_handler[])(struct rtw89_dev *rtwdev,
+ struct sk_buff *c2h, u32 len) = {
+ [RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE] = rtw89_phy_c2h_rfk_report_state,
+};
+
+bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func)
+{
+ switch (class) {
+ case RTW89_PHY_C2H_RFK_LOG:
+ switch (func) {
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_DACK:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI:
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK:
+ return true;
+ default:
+ return false;
+ }
+ case RTW89_PHY_C2H_RFK_REPORT:
+ switch (func) {
+ case RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE:
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+
void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func)
{
@@ -2456,6 +2748,14 @@ void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (func < RTW89_PHY_C2H_FUNC_RA_MAX)
handler = rtw89_phy_c2h_ra_handler[func];
break;
+ case RTW89_PHY_C2H_RFK_LOG:
+ if (func < ARRAY_SIZE(rtw89_phy_c2h_rfk_log_handler))
+ handler = rtw89_phy_c2h_rfk_log_handler[func];
+ break;
+ case RTW89_PHY_C2H_RFK_REPORT:
+ if (func < ARRAY_SIZE(rtw89_phy_c2h_rfk_report_handler))
+ handler = rtw89_phy_c2h_rfk_report_handler[func];
+ break;
case RTW89_PHY_C2H_CLASS_DM:
if (func == RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY)
return;
@@ -4620,6 +4920,29 @@ static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev)
rtw89_phy_ifs_clm_setting_init(rtwdev);
}
+static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
+ struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak;
+
+ memset(edcca_bak, 0, sizeof(*edcca_bak));
+
+ if (rtwdev->chip->chip_id == RTL8922A && rtwdev->hal.cv == CHIP_CAV) {
+ rtw89_phy_set_phy_regs(rtwdev, R_TXGATING, B_TXGATING_EN, 0);
+ rtw89_phy_set_phy_regs(rtwdev, R_CTLTOP, B_CTLTOP_VAL, 2);
+ rtw89_phy_set_phy_regs(rtwdev, R_CTLTOP, B_CTLTOP_ON, 1);
+ rtw89_phy_set_phy_regs(rtwdev, R_SPOOF_CG, B_SPOOF_CG_EN, 0);
+ rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_CG_EN, 0);
+ rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_FFT_EN, 0);
+ rtw89_phy_set_phy_regs(rtwdev, R_SEGSND, B_SEGSND_EN, 0);
+ rtw89_phy_set_phy_regs(rtwdev, R_SEGSND, B_SEGSND_EN, 1);
+ rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_FFT_EN, 1);
+ }
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->tx_collision_t2r_st,
+ edcca_regs->tx_collision_t2r_st_mask, 0x29);
+}
+
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
{
rtw89_phy_stat_init(rtwdev);
@@ -4630,6 +4953,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
rtw89_physts_parsing_init(rtwdev);
rtw89_phy_dig_init(rtwdev);
rtw89_phy_cfo_init(rtwdev);
+ rtw89_phy_edcca_init(rtwdev);
rtw89_phy_ul_tb_info_init(rtwdev);
rtw89_phy_antdiv_init(rtwdev);
rtw89_chip_rfe_gpio(rtwdev);
@@ -4892,23 +5216,188 @@ void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
}
EXPORT_SYMBOL(rtw89_decode_chan_idx);
-#define EDCCA_DEFAULT 249
void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan)
{
- u32 reg = rtwdev->chip->edcca_lvl_reg;
- struct rtw89_hal *hal = &rtwdev->hal;
- u32 val;
+ const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
+ struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak;
if (scan) {
- hal->edcca_bak = rtw89_phy_read32(rtwdev, reg);
- val = hal->edcca_bak;
- u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_EDCCA_LVL_A_MSK);
- u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_EDCCA_LVL_P_MSK);
- u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_PPDU_LVL_MSK);
- rtw89_phy_write32(rtwdev, reg, val);
+ edcca_bak->a =
+ rtw89_phy_read32_mask(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_mask);
+ edcca_bak->p =
+ rtw89_phy_read32_mask(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_p_mask);
+ edcca_bak->ppdu =
+ rtw89_phy_read32_mask(rtwdev, edcca_regs->ppdu_level,
+ edcca_regs->ppdu_mask);
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_mask, EDCCA_MAX);
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_p_mask, EDCCA_MAX);
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level,
+ edcca_regs->ppdu_mask, EDCCA_MAX);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_mask,
+ edcca_bak->a);
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_p_mask,
+ edcca_bak->p);
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level,
+ edcca_regs->ppdu_mask,
+ edcca_bak->ppdu);
+ }
+}
+
+static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
+ bool flag_fb, flag_p20, flag_s20, flag_s40, flag_s80;
+ s8 pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80;
+ u8 path, per20_bitmap;
+ u8 pwdb[8];
+ u32 tmp;
+
+ if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_EDCCA))
+ return;
+
+ if (rtwdev->chip->chip_id == RTL8922A)
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
+ edcca_regs->rpt_sel_be_mask, 0);
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
+ edcca_regs->rpt_sel_mask, 0);
+ tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b);
+ path = u32_get_bits(tmp, B_EDCCA_RPT_B_PATH_MASK);
+ flag_s80 = u32_get_bits(tmp, B_EDCCA_RPT_B_S80);
+ flag_s40 = u32_get_bits(tmp, B_EDCCA_RPT_B_S40);
+ flag_s20 = u32_get_bits(tmp, B_EDCCA_RPT_B_S20);
+ flag_p20 = u32_get_bits(tmp, B_EDCCA_RPT_B_P20);
+ flag_fb = u32_get_bits(tmp, B_EDCCA_RPT_B_FB);
+ pwdb_s20 = u32_get_bits(tmp, MASKBYTE1);
+ pwdb_p20 = u32_get_bits(tmp, MASKBYTE2);
+ pwdb_fb = u32_get_bits(tmp, MASKBYTE3);
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
+ edcca_regs->rpt_sel_mask, 4);
+ tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b);
+ pwdb_s80 = u32_get_bits(tmp, MASKBYTE1);
+ pwdb_s40 = u32_get_bits(tmp, MASKBYTE2);
+
+ per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_regs->rpt_a,
+ MASKBYTE0);
+
+ if (rtwdev->chip->chip_id == RTL8922A) {
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
+ edcca_regs->rpt_sel_be_mask, 4);
+ tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b);
+ pwdb[0] = u32_get_bits(tmp, MASKBYTE3);
+ pwdb[1] = u32_get_bits(tmp, MASKBYTE2);
+ pwdb[2] = u32_get_bits(tmp, MASKBYTE1);
+ pwdb[3] = u32_get_bits(tmp, MASKBYTE0);
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
+ edcca_regs->rpt_sel_be_mask, 5);
+ tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b);
+ pwdb[4] = u32_get_bits(tmp, MASKBYTE3);
+ pwdb[5] = u32_get_bits(tmp, MASKBYTE2);
+ pwdb[6] = u32_get_bits(tmp, MASKBYTE1);
+ pwdb[7] = u32_get_bits(tmp, MASKBYTE0);
} else {
- rtw89_phy_write32(rtwdev, reg, hal->edcca_bak);
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
+ edcca_regs->rpt_sel_mask, 0);
+ tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a);
+ pwdb[0] = u32_get_bits(tmp, MASKBYTE3);
+ pwdb[1] = u32_get_bits(tmp, MASKBYTE2);
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
+ edcca_regs->rpt_sel_mask, 1);
+ tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a);
+ pwdb[2] = u32_get_bits(tmp, MASKBYTE3);
+ pwdb[3] = u32_get_bits(tmp, MASKBYTE2);
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
+ edcca_regs->rpt_sel_mask, 2);
+ tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a);
+ pwdb[4] = u32_get_bits(tmp, MASKBYTE3);
+ pwdb[5] = u32_get_bits(tmp, MASKBYTE2);
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
+ edcca_regs->rpt_sel_mask, 3);
+ tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a);
+ pwdb[6] = u32_get_bits(tmp, MASKBYTE3);
+ pwdb[7] = u32_get_bits(tmp, MASKBYTE2);
}
+
+ rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
+ "[EDCCA]: edcca_bitmap = %04x\n", per20_bitmap);
+
+ rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
+ "[EDCCA]: pwdb per20{0,1,2,3,4,5,6,7} = {%d,%d,%d,%d,%d,%d,%d,%d}(dBm)\n",
+ pwdb[0], pwdb[1], pwdb[2], pwdb[3], pwdb[4], pwdb[5],
+ pwdb[6], pwdb[7]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
+ "[EDCCA]: path=%d, flag {FB,p20,s20,s40,s80} = {%d,%d,%d,%d,%d}\n",
+ path, flag_fb, flag_p20, flag_s20, flag_s40, flag_s80);
+
+ rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
+ "[EDCCA]: pwdb {FB,p20,s20,s40,s80} = {%d,%d,%d,%d,%d}(dBm)\n",
+ pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80);
+}
+
+static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_phy_ch_info *ch_info = &rtwdev->ch_info;
+ bool is_linked = rtwdev->total_sta_assoc > 0;
+ u8 rssi_min = ch_info->rssi_min >> 1;
+ u8 edcca_thre;
+
+ if (!is_linked) {
+ edcca_thre = EDCCA_MAX;
+ } else {
+ edcca_thre = rssi_min - RSSI_UNIT_CONVER + EDCCA_UNIT_CONVER -
+ EDCCA_TH_REF;
+ edcca_thre = max_t(u8, edcca_thre, EDCCA_TH_L2H_LB);
+ }
+
+ return edcca_thre;
+}
+
+void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
+ struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak;
+ u8 th;
+
+ th = rtw89_phy_edcca_get_thre_by_rssi(rtwdev);
+ if (th == edcca_bak->th_old)
+ return;
+
+ edcca_bak->th_old = th;
+
+ rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
+ "[EDCCA]: Normal Mode, EDCCA_th = %d\n", th);
+
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_mask, th);
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_p_mask, th);
+ rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level,
+ edcca_regs->ppdu_mask, th);
+}
+
+void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+
+ if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DYNAMIC_EDCCA))
+ return;
+
+ rtw89_phy_edcca_thre_calc(rtwdev);
+ rtw89_phy_edcca_log(rtwdev);
}
static const struct rtw89_ccx_regs rtw89_ccx_regs_ax = {
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index 2d9cf5c02b92..3e379077c6ca 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -122,6 +122,13 @@
#define PHYSTS_RSVD BIT(RTW89_RX_TYPE_RSVD)
#define PPDU_FILTER_BITMAP (PHYSTS_MGNT | PHYSTS_DATA)
+#define EDCCA_MAX 249
+#define EDCCA_TH_L2H_LB 66
+#define EDCCA_TH_REF 3
+#define EDCCA_HL_DIFF_NORMAL 8
+#define RSSI_UNIT_CONVER 110
+#define EDCCA_UNIT_CONVER 128
+
enum rtw89_phy_c2h_ra_func {
RTW89_PHY_C2H_FUNC_STS_RPT,
RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT,
@@ -129,6 +136,21 @@ enum rtw89_phy_c2h_ra_func {
RTW89_PHY_C2H_FUNC_RA_MAX,
};
+enum rtw89_phy_c2h_rfk_log_func {
+ RTW89_PHY_C2H_RFK_LOG_FUNC_IQK = 0,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_DPK = 1,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_DACK = 2,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK = 3,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI = 4,
+ RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK = 5,
+
+ RTW89_PHY_C2H_RFK_LOG_FUNC_NUM,
+};
+
+enum rtw89_phy_c2h_rfk_report_func {
+ RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE = 0,
+};
+
enum rtw89_phy_c2h_dm_func {
RTW89_PHY_C2H_DM_FUNC_FW_TEST,
RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT,
@@ -142,6 +164,8 @@ enum rtw89_phy_c2h_class {
RTW89_PHY_C2H_CLASS_RUA,
RTW89_PHY_C2H_CLASS_RA,
RTW89_PHY_C2H_CLASS_DM,
+ RTW89_PHY_C2H_RFK_LOG = 0x8,
+ RTW89_PHY_C2H_RFK_REPORT = 0x9,
RTW89_PHY_C2H_CLASS_BTC_MIN = 0x10,
RTW89_PHY_C2H_CLASS_BTC_MAX = 0x17,
RTW89_PHY_C2H_CLASS_MAX,
@@ -284,8 +308,6 @@ struct rtw89_txpwr_byrate_cfg {
u32 data;
};
-#define DELTA_SWINGIDX_SIZE 30
-
struct rtw89_txpwr_track_cfg {
const s8 (*delta_swingidx_6gb_n)[DELTA_SWINGIDX_SIZE];
const s8 (*delta_swingidx_6gb_p)[DELTA_SWINGIDX_SIZE];
@@ -478,6 +500,10 @@ struct rtw89_txpwr_limit_ru_be {
s8 ru106_26[RTW89_RU_SEC_NUM_BE];
};
+struct rtw89_phy_rfk_log_fmt {
+ const struct rtw89_fw_element_hdr *elm[RTW89_PHY_C2H_RFK_LOG_FUNC_NUM];
+};
+
struct rtw89_phy_gen_def {
u32 cr_base;
const struct rtw89_ccx_regs *ccx;
@@ -780,6 +806,7 @@ void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta
void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask);
+bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func);
void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev);
@@ -807,5 +834,7 @@ u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band);
void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
u8 *ch, enum nl80211_band *band);
void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan);
+void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev);
+void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h
index aff0fba71cb0..54486e4550b6 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.h
+++ b/drivers/net/wireless/realtek/rtw89/ps.h
@@ -33,6 +33,10 @@ static inline void rtw89_enter_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;
+ /* prevent entering IPS after ROC, but it is scanning */
+ if (rtwdev->scanning)
+ return;
+
if (hw->conf.flags & IEEE80211_CONF_IDLE)
rtw89_enter_ips(rtwdev);
}
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 7a9ae6cd86e5..65d8a0f36700 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -1457,6 +1457,8 @@
#define B_AX_PLE_Q6_MAX_SIZE_MASK GENMASK(27, 16)
#define B_AX_PLE_Q6_MIN_SIZE_MASK GENMASK(11, 0)
#define R_AX_PLE_QTA7_CFG 0x905C
+#define B_AX_PLE_Q7_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_AX_PLE_Q7_MIN_SIZE_MASK GENMASK(11, 0)
#define R_AX_PLE_QTA8_CFG 0x9060
#define R_AX_PLE_QTA9_CFG 0x9064
#define R_AX_PLE_QTA10_CFG 0x9068
@@ -2376,6 +2378,14 @@
#define R_AX_TSFTR_HIGH_P4 0xC53C
#define B_AX_TSFTR_HIGH_MASK GENMASK(31, 0)
+#define R_AX_BCN_DROP_ALL0 0xC560
+#define R_AX_BCN_DROP_ALL0_C1 0xE560
+#define B_AX_BCN_DROP_ALL_P4 BIT(4)
+#define B_AX_BCN_DROP_ALL_P3 BIT(3)
+#define B_AX_BCN_DROP_ALL_P2 BIT(2)
+#define B_AX_BCN_DROP_ALL_P1 BIT(1)
+#define B_AX_BCN_DROP_ALL_P0 BIT(0)
+
#define R_AX_MBSSID_CTRL 0xC568
#define R_AX_MBSSID_CTRL_C1 0xE568
#define B_AX_P0MB_ALL_MASK GENMASK(23, 1)
@@ -2555,11 +2565,20 @@
#define R_AX_PTCL_DBG_INFO 0xC6F0
#define R_AX_PTCL_DBG_INFO_C1 0xE6F0
+#define B_AX_PTCL_DBG_INFO_MASK_BY_PORT(port) \
+({\
+ typeof(port) _port = (port); \
+ GENMASK((_port) * 2 + 1, (_port) * 2); \
+})
+
#define B_AX_PTCL_DBG_INFO_MASK GENMASK(31, 0)
#define R_AX_PTCL_DBG 0xC6F4
#define R_AX_PTCL_DBG_C1 0xE6F4
#define B_AX_PTCL_DBG_EN BIT(8)
#define B_AX_PTCL_DBG_SEL_MASK GENMASK(7, 0)
+#define AX_PTCL_DBG_BCNQ_NUM0 8
+#define AX_PTCL_DBG_BCNQ_NUM1 9
+
#define R_AX_DLE_CTRL 0xC800
#define R_AX_DLE_CTRL_C1 0xE800
@@ -3723,6 +3742,77 @@
#define B_BE_DIS_CLK_REG1_GATE BIT(1)
#define B_BE_DIS_CLK_REG0_GATE BIT(0)
+#define R_BE_ANAPAR_POW_MAC 0x0016
+#define B_BE_POW_PC_LDO_PORT1 BIT(3)
+#define B_BE_POW_PC_LDO_PORT0 BIT(2)
+#define B_BE_POW_PLL_V1 BIT(1)
+#define B_BE_POW_POWER_CUT_POW_LDO BIT(0)
+
+#define R_BE_SYS_ADIE_PAD_PWR_CTRL 0x0018
+#define B_BE_SYM_PADPDN_WL_RFC1_1P3 BIT(6)
+#define B_BE_SYM_PADPDN_WL_RFC0_1P3 BIT(5)
+
+#define R_BE_AFE_LDO_CTRL 0x0020
+#define B_BE_FORCE_MACBBBT_PWR_ON BIT(31)
+#define B_BE_R_SYM_WLPOFF_P4_PC_EN BIT(28)
+#define B_BE_R_SYM_WLPOFF_P3_PC_EN BIT(27)
+#define B_BE_R_SYM_WLPOFF_P2_PC_EN BIT(26)
+#define B_BE_R_SYM_WLPOFF_P1_PC_EN BIT(25)
+#define B_BE_R_SYM_WLPOFF_PC_EN BIT(24)
+#define B_BE_AON_OFF_PC_EN BIT(23)
+#define B_BE_R_SYM_WLPON_P3_PC_EN BIT(21)
+#define B_BE_R_SYM_WLPON_P2_PC_EN BIT(20)
+#define B_BE_R_SYM_WLPON_P1_PC_EN BIT(19)
+#define B_BE_R_SYM_WLPON_PC_EN BIT(18)
+#define B_BE_R_SYM_WLBBPON1_P1_PC_EN BIT(15)
+#define B_BE_R_SYM_WLBBPON1_PC_EN BIT(14)
+#define B_BE_R_SYM_WLBBPON_P1_PC_EN BIT(13)
+#define B_BE_R_SYM_WLBBPON_PC_EN BIT(12)
+#define B_BE_R_SYM_DIS_WPHYBBOFF_PC BIT(10)
+#define B_BE_R_SYM_WLBBOFF1_P4_PC_EN BIT(9)
+#define B_BE_R_SYM_WLBBOFF1_P3_PC_EN BIT(8)
+#define B_BE_R_SYM_WLBBOFF1_P2_PC_EN BIT(7)
+#define B_BE_R_SYM_WLBBOFF1_P1_PC_EN BIT(6)
+#define B_BE_R_SYM_WLBBOFF1_PC_EN BIT(5)
+#define B_BE_R_SYM_WLBBOFF_P4_PC_EN BIT(4)
+#define B_BE_R_SYM_WLBBOFF_P3_PC_EN BIT(3)
+#define B_BE_R_SYM_WLBBOFF_P2_PC_EN BIT(2)
+#define B_BE_R_SYM_WLBBOFF_P1_PC_EN BIT(1)
+#define B_BE_R_SYM_WLBBOFF_PC_EN BIT(0)
+
+#define R_BE_AFE_CTRL1 0x0024
+#define B_BE_R_SYM_WLCMAC0_P4_PC_EN BIT(28)
+#define B_BE_R_SYM_WLCMAC0_P3_PC_EN BIT(27)
+#define B_BE_R_SYM_WLCMAC0_P2_PC_EN BIT(26)
+#define B_BE_R_SYM_WLCMAC0_P1_PC_EN BIT(25)
+#define B_BE_R_SYM_WLCMAC0_PC_EN BIT(24)
+#define B_BE_DATAMEM_PC3_EN BIT(23)
+#define B_BE_DATAMEM_PC2_EN BIT(22)
+#define B_BE_DATAMEM_PC1_EN BIT(21)
+#define B_BE_DATAMEM_PC_EN BIT(20)
+#define B_BE_DMEM7_PC_EN BIT(19)
+#define B_BE_DMEM6_PC_EN BIT(18)
+#define B_BE_DMEM5_PC_EN BIT(17)
+#define B_BE_DMEM4_PC_EN BIT(16)
+#define B_BE_DMEM3_PC_EN BIT(15)
+#define B_BE_DMEM2_PC_EN BIT(14)
+#define B_BE_DMEM1_PC_EN BIT(13)
+#define B_BE_IMEM4_PC_EN BIT(12)
+#define B_BE_IMEM3_PC_EN BIT(11)
+#define B_BE_IMEM2_PC_EN BIT(10)
+#define B_BE_IMEM1_PC_EN BIT(9)
+#define B_BE_IMEM0_PC_EN BIT(8)
+#define B_BE_R_SYM_WLCMAC1_P4_PC_EN BIT(4)
+#define B_BE_R_SYM_WLCMAC1_P3_PC_EN BIT(3)
+#define B_BE_R_SYM_WLCMAC1_P2_PC_EN BIT(2)
+#define B_BE_R_SYM_WLCMAC1_P1_PC_EN BIT(1)
+#define B_BE_R_SYM_WLCMAC1_PC_EN BIT(0)
+#define B_BE_AFE_CTRL1_SET (B_BE_R_SYM_WLCMAC1_PC_EN | \
+ B_BE_R_SYM_WLCMAC1_P1_PC_EN | \
+ B_BE_R_SYM_WLCMAC1_P2_PC_EN | \
+ B_BE_R_SYM_WLCMAC1_P3_PC_EN | \
+ B_BE_R_SYM_WLCMAC1_P4_PC_EN)
+
#define R_BE_EFUSE_CTRL 0x0030
#define B_BE_EF_MODE_SEL_MASK GENMASK(31, 30)
#define B_BE_EF_RDY BIT(29)
@@ -3810,6 +3900,52 @@
#define B_BE_PCI_CKRDY_OPT BIT(1)
#define B_BE_PCI_VAUX_EN BIT(0)
+#define R_BE_SYS_ISO_CTRL_EXTEND 0x0080
+#define B_BE_R_SYM_ISO_DMEM62PP BIT(29)
+#define B_BE_R_SYM_ISO_DMEM52PP BIT(28)
+#define B_BE_R_SYM_ISO_DMEM42PP BIT(27)
+#define B_BE_R_SYM_ISO_DMEM32PP BIT(26)
+#define B_BE_R_SYM_ISO_DMEM22PP BIT(25)
+#define B_BE_R_SYM_ISO_DMEM12PP BIT(24)
+#define B_BE_R_SYM_ISO_IMEM42PP BIT(22)
+#define B_BE_R_SYM_ISO_IMEM32PP BIT(21)
+#define B_BE_R_SYM_ISO_IMEM22PP BIT(20)
+#define B_BE_R_SYM_ISO_IMEM12PP BIT(19)
+#define B_BE_R_SYM_ISO_IMEM02PP BIT(18)
+#define B_BE_R_SYM_ISO_AON_OFF2PP BIT(15)
+#define B_BE_R_SYM_PWC_HCILA BIT(13)
+#define B_BE_R_SYM_PWC_PD12V BIT(12)
+#define B_BE_R_SYM_PWC_UD12V BIT(11)
+#define B_BE_R_SYM_PWC_BTBRG BIT(10)
+#define B_BE_R_SYM_LDOBTSDIO_EN BIT(9)
+#define B_BE_R_SYM_LDOSPDIO_EN BIT(8)
+#define B_BE_R_SYM_ISO_HCILA BIT(4)
+#define B_BE_R_SYM_ISO_BTBRG2PP BIT(2)
+#define B_BE_R_SYM_ISO_BTSDIO2PP BIT(1)
+#define B_BE_R_SYM_ISO_SPDIO2PP BIT(0)
+
+#define R_BE_FEN_RST_ENABLE 0x0084
+#define B_BE_R_SYM_FEN_WLMACOFF BIT(31)
+#define B_BE_R_SYM_ISO_WA12PP BIT(28)
+#define B_BE_R_SYM_ISO_CMAC12PP BIT(25)
+#define B_BE_R_SYM_ISO_CMAC02PP BIT(24)
+#define B_BE_R_SYM_ISO_ADDA_P32PP BIT(23)
+#define B_BE_R_SYM_ISO_ADDA_P22PP BIT(22)
+#define B_BE_R_SYM_ISO_ADDA_P12PP BIT(21)
+#define B_BE_R_SYM_ISO_ADDA_P02PP BIT(20)
+#define B_BE_CMAC1_FEN BIT(17)
+#define B_BE_CMAC0_FEN BIT(16)
+#define B_BE_SYM_ISO_BBPON12PP BIT(13)
+#define B_BE_SYM_ISO_BB12PP BIT(12)
+#define B_BE_BOOT_RDY1 BIT(10)
+#define B_BE_FEN_BB1_IP_RSTN BIT(9)
+#define B_BE_FEN_BB1PLAT_RSTB BIT(8)
+#define B_BE_SYM_ISO_BBPON02PP BIT(5)
+#define B_BE_SYM_ISO_BB02PP BIT(4)
+#define B_BE_BOOT_RDY0 BIT(2)
+#define B_BE_FEN_BB_IP_RSTN BIT(1)
+#define B_BE_FEN_BBPLAT_RSTB BIT(0)
+
#define R_BE_PLATFORM_ENABLE 0x0088
#define B_BE_HOLD_AFTER_RESET BIT(11)
#define B_BE_SYM_WLPLT_MEM_MUX_EN BIT(10)
@@ -3823,6 +3959,51 @@
#define B_BE_WCPU_EN BIT(1)
#define B_BE_PLATFORM_EN BIT(0)
+#define R_BE_WLLPS_CTRL 0x0090
+#define B_BE_LPSOP_BBMEMDS BIT(30)
+#define B_BE_LPSOP_BBOFF BIT(29)
+#define B_BE_LPSOP_MACOFF BIT(28)
+#define B_BE_LPSOP_OFF_CAPC_EN BIT(27)
+#define B_BE_LPSOP_MEM_DS BIT(26)
+#define B_BE_LPSOP_XTALM_LPS BIT(23)
+#define B_BE_LPSOP_XTAL BIT(22)
+#define B_BE_LPSOP_ACLK_DIV_2 BIT(21)
+#define B_BE_LPSOP_ACLK_SEL BIT(20)
+#define B_BE_LPSOP_ASWRM BIT(17)
+#define B_BE_LPSOP_ASWR BIT(16)
+#define B_BE_LPSOP_DSWR_ADJ_MASK GENMASK(15, 12)
+#define B_BE_LPSOP_DSWRSD BIT(10)
+#define B_BE_LPSOP_DSWRM BIT(9)
+#define B_BE_LPSOP_DSWR BIT(8)
+#define B_BE_LPSOP_OLD_ADJ_MASK GENMASK(7, 4)
+#define B_BE_FORCE_LEAVE_LPS BIT(3)
+#define B_BE_LPSOP_OLDSD BIT(2)
+#define B_BE_DIS_WLBT_LPSEN_LOPC BIT(1)
+#define B_BE_WL_LPS_EN BIT(0)
+
+#define R_BE_WLRESUME_CTRL 0x0094
+#define B_BE_LPSROP_DMEM5_RSU_EN BIT(31)
+#define B_BE_LPSROP_DMEM4_RSU_EN BIT(30)
+#define B_BE_LPSROP_DMEM3_RSU_EN BIT(29)
+#define B_BE_LPSROP_DMEM2_RSU_EN BIT(28)
+#define B_BE_LPSROP_DMEM1_RSU_EN BIT(27)
+#define B_BE_LPSROP_DMEM0_RSU_EN BIT(26)
+#define B_BE_LPSROP_IMEM5_RSU_EN BIT(25)
+#define B_BE_LPSROP_IMEM4_RSU_EN BIT(24)
+#define B_BE_LPSROP_IMEM3_RSU_EN BIT(23)
+#define B_BE_LPSROP_IMEM2_RSU_EN BIT(22)
+#define B_BE_LPSROP_IMEM1_RSU_EN BIT(21)
+#define B_BE_LPSROP_IMEM0_RSU_EN BIT(20)
+#define B_BE_LPSROP_BB1_W_BB0 BIT(14)
+#define B_BE_LPSROP_CMAC1 BIT(13)
+#define B_BE_LPSROP_CMAC0 BIT(12)
+#define B_BE_LPSROP_XTALM BIT(11)
+#define B_BE_LPSROP_PLLM BIT(10)
+#define B_BE_LPSROP_HIOE BIT(9)
+#define B_BE_LPSROP_CPU BIT(8)
+#define B_BE_LPSROP_LOWPWRPLL BIT(7)
+#define B_BE_LPSROP_DSWRSD_SEL_MASK GENMASK(5, 4)
+
#define R_BE_EFUSE_CTRL_2_V1 0x00A4
#define B_BE_EF_ENT BIT(31)
#define B_BE_EF_TCOLUMN_EN BIT(29)
@@ -3852,6 +4033,18 @@
#define B_BE_SYSON_DIS_PMCR_BE_WRMSK BIT(2)
#define B_BE_SYSON_R_BE_ARB_MASK GENMASK(1, 0)
+#define R_BE_PCIE_MIO_INTF 0x00E4
+#define B_BE_AON_MIO_EPHY_1K_SEL_MASK GENMASK(29, 24)
+#define B_BE_PCIE_MIO_ADDR_PAGE_V1_MASK GENMASK(20, 16)
+#define B_BE_PCIE_MIO_ASIF BIT(15)
+#define B_BE_PCIE_MIO_BYIOREG BIT(13)
+#define B_BE_PCIE_MIO_RE BIT(12)
+#define B_BE_PCIE_MIO_WE_MASK GENMASK(11, 8)
+#define B_BE_PCIE_MIO_ADDR_MASK GENMASK(7, 0)
+
+#define R_BE_PCIE_MIO_INTD 0x00E8
+#define B_BE_PCIE_MIO_DATA_MASK GENMASK(31, 0)
+
#define R_BE_HALT_H2C_CTRL 0x0160
#define B_BE_HALT_H2C_TRIGGER BIT(0)
@@ -3997,6 +4190,67 @@
#define R_BE_UDM2 0x01F8
#define B_BE_UDM2_EPC_RA_MASK GENMASK(31, 0)
+#define R_BE_AFE_ON_CTRL0 0x0240
+#define B_BE_REG_LPF_R3_3_0_MASK GENMASK(31, 29)
+#define B_BE_REG_LPF_R2_MASK GENMASK(28, 24)
+#define B_BE_REG_LPF_C3_MASK GENMASK(23, 21)
+#define B_BE_REG_LPF_C2_MASK GENMASK(20, 18)
+#define B_BE_REG_LPF_C1_MASK GENMASK(17, 15)
+#define B_BE_REG_CP_ICPX2 BIT(14)
+#define B_BE_REG_CP_ICP_SEL_FAST_MASK GENMASK(13, 10)
+#define B_BE_REG_CP_ICP_SEL_MASK GENMASK(9, 6)
+#define B_BE_REG_IB_PI_MASK GENMASK(5, 4)
+#define B_BE_REG_CK_DEBUG_BT BIT(3)
+#define B_BE_EN_PC_LDO BIT(2)
+#define B_BE_LDO_VSEL_MASK GENMASK(1, 0)
+
+#define R_BE_AFE_ON_CTRL1 0x0244
+#define B_BE_REG_CK_MON_SEL_MASK GENMASK(31, 29)
+#define B_BE_REG_CK_MON_CK960M_EN BIT(28)
+#define B_BE_REG_XTAL_FREQ_SEL BIT(27)
+#define B_BE_REG_XTAL_EDGE_SEL BIT(26)
+#define B_BE_REG_VCO_KVCO BIT(25)
+#define B_BE_REG_SDM_EDGE_SEL BIT(24)
+#define B_BE_REG_SDM_CK_SEL BIT(23)
+#define B_BE_REG_SDM_CK_GATED BIT(22)
+#define B_BE_REG_PFD_RESET_GATED BIT(21)
+#define B_BE_REG_LPF_R3_FAST_MASK GENMASK(20, 16)
+#define B_BE_REG_LPF_R2_FAST_MASK GENMASK(15, 11)
+#define B_BE_REG_LPF_C3_FAST_MASK GENMASK(10, 8)
+#define B_BE_REG_LPF_C2_FAST_MASK GENMASK(7, 5)
+#define B_BE_REG_LPF_C1_FAST_MASK GENMASK(4, 2)
+#define B_BE_REG_LPF_R3_4_MASK GENMASK(1, 0)
+
+#define R_BE_AFE_ON_CTRL3 0x024C
+#define B_BE_LDO_VSEL_DA_1_MASK GENMASK(31, 30)
+#define B_BE_LDO_VSEL_DA_0_MASK GENMASK(29, 28)
+#define B_BE_LDO_VSEL_D2S_1_MASK GENMASK(27, 26)
+#define B_BE_LDO_VSEL_D2S_0_MASK GENMASK(25, 24)
+#define B_BE_LDO_VSEL_BUF_MASK GENMASK(23, 22)
+#define B_BE_REG_R2_L_MASK GENMASK(21, 19)
+#define B_BE_REG_R1_L_MASK GENMASK(18, 16)
+#define B_BE_REG_CK_DEBUG_BT_MON BIT(15)
+#define B_BE_REG_BT_CLK_BUF_POWER BIT(14)
+#define B_BE_REG_BG_OUT_BTADC_V1 BIT(13)
+#define B_BE_REG_SEL_V18 BIT(11)
+#define B_BE_REG_FRAC_EN BIT(10)
+#define B_BE_REG_CK1920M_EN BIT(9)
+#define B_BE_REG_CK1280M_EN BIT(8)
+#define B_BE_REG_12LDO_SEL_MASK GENMASK(7, 6)
+#define B_BE_REG_09LDO_SEL_MASK GENMASK(5, 4)
+#define B_BE_REG_VC_TH BIT(3)
+#define B_BE_REG_VC_TL BIT(2)
+#define B_BE_REG_CK40M_EN BIT(1)
+#define B_BE_REG_CK640M_EN BIT(0)
+
+#define R_BE_WLAN_XTAL_SI_CTRL 0x0270
+#define B_BE_WL_XTAL_SI_CMD_POLL BIT(31)
+#define B_BE_WL_XTAL_SI_CHIPID_MASK GENMASK(30, 28)
+#define B_BE_WL_XTAL_SI_MODE_MASK GENMASK(25, 24)
+#define B_BE_WL_XTAL_SI_BITMASK_MASK GENMASK(23, 16)
+#define B_BE_WL_XTAL_SI_DATA_MASK GENMASK(15, 8)
+#define B_BE_WL_XTAL_SI_ADDR_MASK GENMASK(7, 0)
+
#define R_BE_IC_PWR_STATE 0x03F0
#define B_BE_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16)
#define MAC_AX_SYS_ACT 0x220
@@ -4006,6 +4260,8 @@
#define B_BE_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2)
#define B_BE_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0)
+#define R_BE_WLCPU_PORT_PC 0x03FC
+
#define R_BE_DCPU_PLATFORM_ENABLE 0x0888
#define B_BE_DCPU_SYM_DPLT_MEM_MUX_EN BIT(10)
#define B_BE_DCPU_WARM_EN BIT(9)
@@ -4015,6 +4271,34 @@
#define B_BE_DCPU_EN BIT(1)
#define B_BE_DCPU_PLATFORM_EN BIT(0)
+#define R_BE_PL_AXIDMA_IDCT_MSK 0x0910
+#define B_BE_PL_AXIDMA_RRESP_ERR_MASK BIT(6)
+#define B_BE_PL_AXIDMA_BRESP_ERR_MASK BIT(5)
+#define B_BE_PL_AXIDMA_FC_ERR_MASK BIT(4)
+#define B_BE_PL_AXIDMA_TXBD_LEN0_MASK BIT(3)
+#define B_BE_PL_AXIDMA_TXBD_4KBOUD_LENERR_MASK BIT(2)
+#define B_BE_PL_AXIDMA_TXBD_RX_STUCK_MASK BIT(1)
+#define B_BE_PL_AXIDMA_TXBD_TX_STUCK_MASK BIT(0)
+#define B_BE_PL_AXIDMA_IDCT_MSK_CLR (B_BE_PL_AXIDMA_TXBD_TX_STUCK_MASK | \
+ B_BE_PL_AXIDMA_TXBD_RX_STUCK_MASK | \
+ B_BE_PL_AXIDMA_TXBD_LEN0_MASK | \
+ B_BE_PL_AXIDMA_FC_ERR_MASK | \
+ B_BE_PL_AXIDMA_BRESP_ERR_MASK | \
+ B_BE_PL_AXIDMA_RRESP_ERR_MASK)
+#define B_BE_PL_AXIDMA_IDCT_MSK_SET (B_BE_PL_AXIDMA_TXBD_TX_STUCK_MASK | \
+ B_BE_PL_AXIDMA_TXBD_RX_STUCK_MASK | \
+ B_BE_PL_AXIDMA_TXBD_LEN0_MASK | \
+ B_BE_PL_AXIDMA_FC_ERR_MASK)
+
+#define R_BE_PL_AXIDMA_IDCT 0x0914
+#define B_BE_PL_AXIDMA_RRESP_ERR BIT(6)
+#define B_BE_PL_AXIDMA_BRESP_ERR BIT(5)
+#define B_BE_PL_AXIDMA_FC_ERR BIT(4)
+#define B_BE_PL_AXIDMA_TXBD_LEN0 BIT(3)
+#define B_BE_PL_AXIDMA_TXBD_4KBOUD_LENERR BIT(2)
+#define B_BE_PL_AXIDMA_TXBD_RX_STUCK BIT(1)
+#define B_BE_PL_AXIDMA_TXBD_TX_STUCK BIT(0)
+
#define R_BE_FILTER_MODEL_ADDR 0x0C04
#define R_BE_WLAN_WDT 0x3050
@@ -4123,6 +4407,53 @@
#define B_BE_HCI_RXDMA_EN BIT(1)
#define B_BE_HCI_TXDMA_EN BIT(0)
+#define R_BE_DMAC_FUNC_EN 0x8400
+#define B_BE_DMAC_CRPRT BIT(31)
+#define B_BE_MAC_FUNC_EN BIT(30)
+#define B_BE_DMAC_FUNC_EN BIT(29)
+#define B_BE_MPDU_PROC_EN BIT(28)
+#define B_BE_WD_RLS_EN BIT(27)
+#define B_BE_DLE_WDE_EN BIT(26)
+#define B_BE_TXPKT_CTRL_EN BIT(25)
+#define B_BE_STA_SCH_EN BIT(24)
+#define B_BE_DLE_PLE_EN BIT(23)
+#define B_BE_PKT_BUF_EN BIT(22)
+#define B_BE_DMAC_TBL_EN BIT(21)
+#define B_BE_PKT_IN_EN BIT(20)
+#define B_BE_DLE_CPUIO_EN BIT(19)
+#define B_BE_DISPATCHER_EN BIT(18)
+#define B_BE_BBRPT_EN BIT(17)
+#define B_BE_MAC_SEC_EN BIT(16)
+#define B_BE_DMACREG_GCKEN BIT(15)
+#define B_BE_H_AXIDMA_EN BIT(14)
+#define B_BE_DMAC_MLO_EN BIT(11)
+#define B_BE_PLRLS_EN BIT(10)
+#define B_BE_P_AXIDMA_EN BIT(9)
+#define B_BE_DLE_DATACPUIO_EN BIT(8)
+#define B_BE_LTR_CTL_EN BIT(7)
+
+#define R_BE_DMAC_CLK_EN 0x8404
+#define B_BE_MAC_CKEN BIT(30)
+#define B_BE_DMAC_CKEN BIT(29)
+#define B_BE_MPDU_CKEN BIT(28)
+#define B_BE_WD_RLS_CLK_EN BIT(27)
+#define B_BE_DLE_WDE_CLK_EN BIT(26)
+#define B_BE_TXPKT_CTRL_CLK_EN BIT(25)
+#define B_BE_STA_SCH_CLK_EN BIT(24)
+#define B_BE_DLE_PLE_CLK_EN BIT(23)
+#define B_BE_PKTBUF_CKEN BIT(22)
+#define B_BE_DMAC_TABLE_CLK_EN BIT(21)
+#define B_BE_PKT_IN_CLK_EN BIT(20)
+#define B_BE_DLE_CPUIO_CLK_EN BIT(19)
+#define B_BE_DISPATCHER_CLK_EN BIT(18)
+#define B_BE_BBRPT_CLK_EN BIT(17)
+#define B_BE_MAC_SEC_CLK_EN BIT(16)
+#define B_BE_H_AXIDMA_CKEN BIT(14)
+#define B_BE_DMAC_MLO_CKEN BIT(11)
+#define B_BE_PLRLS_CKEN BIT(10)
+#define B_BE_P_AXIDMA_CKEN BIT(9)
+#define B_BE_DLE_DATACPUIO_CKEN BIT(8)
+
#define R_BE_LTR_CTRL_0 0x8410
#define B_BE_LTR_REQ_FW BIT(18)
#define B_BE_LTR_IDX_FW_MASK GENMASK(17, 16)
@@ -4144,6 +4475,725 @@
#define B_BE_LTR_CMAC1_RX_USE_PG_TH_MASK GENMASK(27, 16)
#define B_BE_LTR_CMAC0_RX_USE_PG_TH_MASK GENMASK(11, 0)
+#define R_BE_DMAC_TABLE_CTRL 0x8420
+#define B_BE_HWAMSDU_PADDING_MODE BIT(31)
+#define B_BE_MACID_MPDU_PROCESSOR_OFFSET_MASK GENMASK(26, 16)
+#define B_BE_DMAC_ADDR_MODE BIT(12)
+#define B_BE_DMAC_CTRL_INFO_SER_IO BIT(11)
+#define B_BE_DMAC_CTRL_INFO_OFFSET_MASK GENMASK(10, 0)
+
+#define R_BE_SER_DBG_INFO 0x8424
+#define B_BE_SER_L0_PROMOTE_L1_EVENT_MASK GENMASK(31, 28)
+#define B_BE_SER_L1_COUNTER_MASK GENMASK(27, 24)
+#define B_BE_RMAC_PPDU_HANG_CNT_MASK GENMASK(23, 16)
+#define B_BE_SER_L0_COUNTER_MASK GENMASK(8, 0)
+
+#define R_BE_DLE_EMPTY0 0x8430
+#define B_BE_PLE_EMPTY_QTA_DMAC_H2D BIT(27)
+#define B_BE_PLE_EMPTY_QTA_DMAC_CPUIO BIT(26)
+#define B_BE_PLE_EMPTY_QTA_DMAC_MPDU_TX BIT(25)
+#define B_BE_PLE_EMPTY_QTA_DMAC_WLAN_CPU BIT(24)
+#define B_BE_PLE_EMPTY_QTA_DMAC_H2C BIT(23)
+#define B_BE_PLE_EMPTY_QTA_DMAC_B1_TXPL BIT(22)
+#define B_BE_PLE_EMPTY_QTA_DMAC_B0_TXPL BIT(21)
+#define B_BE_WDE_EMPTY_QTA_DMAC_CPUIO BIT(20)
+#define B_BE_WDE_EMPTY_QTA_DMAC_PKTIN BIT(19)
+#define B_BE_WDE_EMPTY_QTA_DMAC_DATA_CPU BIT(18)
+#define B_BE_WDE_EMPTY_QTA_DMAC_WLAN_CPU BIT(17)
+#define B_BE_WDE_EMPTY_QTA_DMAC_HIF BIT(16)
+#define B_BE_WDE_EMPTY_QUE_CMAC_B1_HIQ BIT(15)
+#define B_BE_WDE_EMPTY_QUE_CMAC_B1_MBH BIT(14)
+#define B_BE_WDE_EMPTY_QUE_CMAC_B0_OTHERS BIT(13)
+#define B_BE_WDE_EMPTY_QUE_DMAC_MLO_ACQ BIT(12)
+#define B_BE_WDE_EMPTY_QUE_DMAC_MLO_MISC BIT(11)
+#define B_BE_WDE_EMPTY_QUE_DMAC_PKTIN BIT(10)
+#define B_BE_PLE_EMPTY_QUE_DMAC_SEC_TX BIT(9)
+#define B_BE_PLE_EMPTY_QUE_DMAC_MPDU_TX BIT(8)
+#define B_BE_WDE_EMPTY_QUE_OTHERS BIT(7)
+#define B_BE_WDE_EMPTY_QUE_CMAC_WMM3 BIT(6)
+#define B_BE_WDE_EMPTY_QUE_CMAC_WMM2 BIT(5)
+#define B_BE_WDE_EMPTY_QUE_CMAC0_WMM1 BIT(4)
+#define B_BE_WDE_EMPTY_QUE_CMAC0_WMM0 BIT(3)
+#define B_BE_WDE_EMPTY_QUE_CMAC1_MBH BIT(2)
+#define B_BE_WDE_EMPTY_QUE_CMAC0_MBH BIT(1)
+#define B_BE_WDE_EMPTY_QUE_CMAC0_ALL_AC BIT(0)
+
+#define R_BE_DLE_EMPTY1 0x8434
+#define B_BE_PLE_EMPTY_QTA_CMAC_DMA_TXRPT BIT(21)
+#define B_BE_PLE_EMPTY_QTA_DMAC_WDRLS BIT(20)
+#define B_BE_PLE_EMPTY_QTA_CMAC1_DMA_BBRPT BIT(19)
+#define B_BE_PLE_EMPTY_QTA_CMAC1_DMA_RX BIT(18)
+#define B_BE_PLE_EMPTY_QTA_CMAC0_DMA_RX BIT(17)
+#define B_BE_PLE_EMPTY_QTA_DMAC_C2H BIT(16)
+#define B_BE_PLE_EMPTY_QUE_DMAC_PLRLS BIT(5)
+#define B_BE_PLE_EMPTY_QUE_DMAC_CPUIO BIT(4)
+#define B_BE_PLE_EMPTY_QUE_DMAC_SEC_RX BIT(3)
+#define B_BE_PLE_EMPTY_QUE_DMAC_MPDU_RX BIT(2)
+#define B_BE_PLE_EMPTY_QUE_DMAC_HDP BIT(1)
+#define B_BE_WDE_EMPTY_QUE_DMAC_WDRLS BIT(0)
+
+#define R_BE_SER_L1_DBG_CNT_0 0x8440
+#define B_BE_SER_L1_WDRLS_CNT_MASK GENMASK(31, 24)
+#define B_BE_SER_L1_SEC_CNT_MASK GENMASK(23, 16)
+#define B_BE_SER_L1_MPDU_CNT_MASK GENMASK(15, 8)
+#define B_BE_SER_L1_STA_SCH_CNT_MASK GENMASK(7, 0)
+
+#define R_BE_SER_L1_DBG_CNT_1 0x8444
+#define B_BE_SER_L1_WDE_CNT_MASK GENMASK(31, 24)
+#define B_BE_SER_L1_TXPKTCTRL_CNT_MASK GENMASK(23, 16)
+#define B_BE_SER_L1_PLE_CNT_MASK GENMASK(15, 8)
+#define B_BE_SER_L1_PKTIN_CNT_MASK GENMASK(7, 0)
+
+#define R_BE_SER_L1_DBG_CNT_2 0x8448
+#define B_BE_SER_L1_DISP_CNT_MASK GENMASK(31, 24)
+#define B_BE_SER_L1_APB_BRIDGE_CNT_MASK GENMASK(23, 16)
+#define B_BE_SER_L1_DLE_W_CPUIO_CNT_MASK GENMASK(15, 8)
+#define B_BE_SER_L1_BBRPT_CNT_MASK GENMASK(7, 0)
+
+#define R_BE_SER_L1_DBG_CNT_3 0x844C
+#define B_BE_SER_L1_HCI_BUF_CNT_MASK GENMASK(31, 24)
+#define B_BE_SER_L1_P_AXIDMA_CNT_MASK GENMASK(23, 16)
+#define B_BE_SER_L1_H_AXIDMA_CNT_MASK GENMASK(15, 8)
+#define B_BE_SER_L1_MLO_ERR_CNT_MASK GENMASK(7, 0)
+
+#define R_BE_SER_L1_DBG_CNT_4 0x8450
+#define B_BE_SER_L1_PLDRLS_ERR_CNT_MASK GENMASK(31, 24)
+#define B_BE_SER_L1_DLE_D_CPUIO_CNT_MASK GENMASK(23, 16)
+
+#define R_BE_SER_L1_DBG_CNT_5 0x8454
+#define B_BE_SER_L1_DBG_0_MASK GENMASK(31, 0)
+
+#define R_BE_SER_L1_DBG_CNT_6 0x8458
+#define B_BE_SER_L1_DBG_1_MASK GENMASK(31, 0)
+
+#define R_BE_SER_L1_DBG_CNT_7 0x845C
+#define B_BE_SER_L1_DBG_2_MASK GENMASK(31, 0)
+
+#define R_BE_DMAC_ERR_IMR 0x8520
+#define B_BE_DMAC_NOTX_ERR_INT_EN BIT(21)
+#define B_BE_DMAC_NORX_ERR_INT_EN BIT(20)
+#define B_BE_DLE_DATACPUIO_ERR_INT_EN BIT(19)
+#define B_BE_PLRSL_ERR_INT_EN BIT(18)
+#define B_BE_MLO_ERR_INT_EN BIT(17)
+#define B_BE_DMAC_FW_ERR_INT_EN BIT(16)
+#define B_BE_H_AXIDMA_ERR_INT_EN BIT(14)
+#define B_BE_P_AXIDMA_ERR_INT_EN BIT(13)
+#define B_BE_HCI_BUF_ERR_INT_EN BIT(12)
+#define B_BE_BBRPT_ERR_INT_EN BIT(11)
+#define B_BE_DLE_CPUIO_ERR_INT_EN BIT(10)
+#define B_BE_APB_BRIDGE_ERR_INT_EN BIT(9)
+#define B_BE_DISPATCH_ERR_INT_EN BIT(8)
+#define B_BE_PKTIN_ERR_INT_EN BIT(7)
+#define B_BE_PLE_DLE_ERR_INT_EN BIT(6)
+#define B_BE_TXPKTCTRL_ERR_INT_EN BIT(5)
+#define B_BE_WDE_DLE_ERR_INT_EN BIT(4)
+#define B_BE_STA_SCHEDULER_ERR_INT_EN BIT(3)
+#define B_BE_MPDU_ERR_INT_EN BIT(2)
+#define B_BE_WSEC_ERR_INT_EN BIT(1)
+#define B_BE_WDRLS_ERR_INT_EN BIT(0)
+
+#define R_BE_DMAC_ERR_ISR 0x8524
+#define B_BE_DLE_DATACPUIO_ERR_INT BIT(19)
+#define B_BE_PLRLS_ERR_INT BIT(18)
+#define B_BE_MLO_ERR_INT BIT(17)
+#define B_BE_DMAC_FW_ERR_IDCT BIT(16)
+#define B_BE_H_AXIDMA_ERR_INT BIT(14)
+#define B_BE_P_AXIDMA_ERR_INT BIT(13)
+#define B_BE_HCI_BUF_ERR_FLAG BIT(12)
+#define B_BE_BBRPT_ERR_FLAG BIT(11)
+#define B_BE_DLE_CPUIO_ERR_FLAG BIT(10)
+#define B_BE_APB_BRIDGE_ERR_FLAG BIT(9)
+#define B_BE_DISPATCH_ERR_FLAG BIT(8)
+#define B_BE_PKTIN_ERR_FLAG BIT(7)
+#define B_BE_PLE_DLE_ERR_FLAG BIT(6)
+#define B_BE_TXPKTCTRL_ERR_FLAG BIT(5)
+#define B_BE_WDE_DLE_ERR_FLAG BIT(4)
+#define B_BE_STA_SCHEDULER_ERR_FLAG BIT(3)
+#define B_BE_MPDU_ERR_FLAG BIT(2)
+#define B_BE_WSEC_ERR_FLAG BIT(1)
+#define B_BE_WDRLS_ERR_FLAG BIT(0)
+
+#define R_BE_DISP_ERROR_ISR0 0x8804
+#define B_BE_REUSE_SIZE_ERR BIT(31)
+#define B_BE_REUSE_EN_ERR BIT(30)
+#define B_BE_STF_OQT_UNDERFLOW_ERR BIT(29)
+#define B_BE_STF_OQT_OVERFLOW_ERR BIT(28)
+#define B_BE_STF_WRFF_UNDERFLOW_ERR BIT(27)
+#define B_BE_STF_WRFF_OVERFLOW_ERR BIT(26)
+#define B_BE_STF_CMD_UNDERFLOW_ERR BIT(25)
+#define B_BE_STF_CMD_OVERFLOW_ERR BIT(24)
+#define B_BE_REUSE_SIZE_ZERO_ERR BIT(23)
+#define B_BE_REUSE_PKT_CNT_ERR BIT(22)
+#define B_BE_CDT_PTR_TIMEOUT_ERR BIT(21)
+#define B_BE_CDT_HCI_TIMEOUT_ERR BIT(20)
+#define B_BE_HDT_PTR_TIMEOUT_ERR BIT(19)
+#define B_BE_HDT_HCI_TIMEOUT_ERR BIT(18)
+#define B_BE_CDT_ADDR_INFO_LEN_ERR BIT(17)
+#define B_BE_HDT_ADDR_INFO_LEN_ERR BIT(16)
+#define B_BE_CDR_DMA_TIMEOUT_ERR BIT(15)
+#define B_BE_CDR_RX_TIMEOUT_ERR BIT(14)
+#define B_BE_PLE_OUTPUT_ERR BIT(12)
+#define B_BE_PLE_RESPOSE_ERR BIT(11)
+#define B_BE_PLE_BURST_NUM_ERR BIT(10)
+#define B_BE_PLE_NULL_PKT_ERR BIT(9)
+#define B_BE_PLE_FLOW_CTRL_ERR BIT(8)
+#define B_BE_HDR_DMA_TIMEOUT_ERR BIT(7)
+#define B_BE_HDR_RX_TIMEOUT_ERR BIT(6)
+#define B_BE_WDE_OUTPUT_ERR BIT(4)
+#define B_BE_WDE_RESPONSE_ERR BIT(3)
+#define B_BE_WDE_BURST_NUM_ERR BIT(2)
+#define B_BE_WDE_NULL_PKT_ERR BIT(1)
+#define B_BE_WDE_FLOW_CTRL_ERR BIT(0)
+
+#define R_BE_DISP_ERROR_ISR1 0x8808
+#define B_BE_HR_WRFF_UNDERFLOW_ERR BIT(31)
+#define B_BE_HR_WRFF_OVERFLOW_ERR BIT(30)
+#define B_BE_HR_CHKSUM_FSM_ERR BIT(29)
+#define B_BE_HR_SHIFT_DMA_CFG_ERR BIT(28)
+#define B_BE_HR_DMA_PROCESS_ERR BIT(27)
+#define B_BE_HR_TOTAL_LEN_UNDER_ERR BIT(26)
+#define B_BE_HR_SHIFT_EN_ERR BIT(25)
+#define B_BE_HR_AGG_CFG_ERR BIT(24)
+#define B_BE_HR_PLD_LEN_ZERO_ERR BIT(22)
+#define B_BE_HT_ILL_CH_ERR BIT(20)
+#define B_BE_HT_ADDR_INFO_LEN_ERR BIT(18)
+#define B_BE_HT_WD_LEN_OVER_ERR BIT(17)
+#define B_BE_HT_PLD_CMD_UNDERFLOW_ERR BIT(16)
+#define B_BE_HT_PLD_CMD_OVERFLOW_ERR BIT(15)
+#define B_BE_HT_WRFF_UNDERFLOW_ERR BIT(14)
+#define B_BE_HT_WRFF_OVERFLOW_ERR BIT(13)
+#define B_BE_HT_CHKSUM_FSM_ERR BIT(12)
+#define B_BE_HT_NON_IDLE_PKT_STR_ERR BIT(11)
+#define B_BE_HT_PRE_SUB_BE_ERR BIT(10)
+#define B_BE_HT_WD_CHKSUM_ERR BIT(9)
+#define B_BE_HT_CHANNEL_DMA_ERR BIT(8)
+#define B_BE_HT_OFFSET_UNMATCH_ERR BIT(7)
+#define B_BE_HT_PAYLOAD_UNDER_ERR BIT(6)
+#define B_BE_HT_PAYLOAD_OVER_ERR BIT(5)
+#define B_BE_HT_PERMU_FF_UNDERFLOW_ERR BIT(4)
+#define B_BE_HT_PERMU_FF_OVERFLOW_ERR BIT(3)
+#define B_BE_HT_PKT_FAIL_ERR BIT(2)
+#define B_BE_HT_CH_ID_ERR BIT(1)
+#define B_BE_HT_EP_CH_DIFF_ERR BIT(0)
+
+#define R_BE_DISP_ERROR_ISR2 0x880C
+#define B_BE_CR_PLD_LEN_ERR BIT(30)
+#define B_BE_CR_WRFF_UNDERFLOW_ERR BIT(29)
+#define B_BE_CR_WRFF_OVERFLOW_ERR BIT(28)
+#define B_BE_CR_SHIFT_DMA_CFG_ERR BIT(27)
+#define B_BE_CR_DMA_PROCESS_ERR BIT(26)
+#define B_BE_CR_SHIFT_EN_ERR BIT(24)
+#define B_BE_REUSE_FIFO_B_UNDER_ERR BIT(22)
+#define B_BE_REUSE_FIFO_B_OVER_ERR BIT(21)
+#define B_BE_REUSE_FIFO_A_UNDER_ERR BIT(20)
+#define B_BE_REUSE_FIFO_A_OVER_ERR BIT(19)
+#define B_BE_CT_ADDR_INFO_LEN_MISS_ERR BIT(17)
+#define B_BE_CT_WD_LEN_OVER_ERR BIT(16)
+#define B_BE_CT_F2P_SEQ_ERR BIT(15)
+#define B_BE_CT_F2P_QSEL_ERR BIT(14)
+#define B_BE_CT_PLD_CMD_UNDERFLOW_ERR BIT(13)
+#define B_BE_CT_PLD_CMD_OVERFLOW_ERR BIT(12)
+#define B_BE_CT_PRE_SUB_ERR BIT(11)
+#define B_BE_CT_WD_CHKSUM_ERR BIT(10)
+#define B_BE_CT_CHANNEL_DMA_ERR BIT(9)
+#define B_BE_CT_OFFSET_UNMATCH_ERR BIT(8)
+#define B_BE_F2P_TOTAL_NUM_ERR BIT(7)
+#define B_BE_CT_PAYLOAD_UNDER_ERR BIT(6)
+#define B_BE_CT_PAYLOAD_OVER_ERR BIT(5)
+#define B_BE_CT_PERMU_FF_UNDERFLOW_ERR BIT(4)
+#define B_BE_CT_PERMU_FF_OVERFLOW_ERR BIT(3)
+#define B_BE_CT_CH_ID_ERR BIT(2)
+#define B_BE_CT_EP_CH_DIFF_ERR BIT(0)
+
+#define R_BE_DISP_OTHER_IMR 0x8870
+#define B_BE_REUSE_SIZE_ERR_INT_EN BIT(31)
+#define B_BE_REUSE_EN_ERR_INT_EN BIT(30)
+#define B_BE_STF_OQT_UNDERFLOW_ERR_INT_EN BIT(29)
+#define B_BE_STF_OQT_OVERFLOW_ERR_INT_EN BIT(28)
+#define B_BE_STF_WRFF_UNDERFLOW_ERR_INT_EN BIT(27)
+#define B_BE_STF_WRFF_OVERFLOW_ERR_INT_EN BIT(26)
+#define B_BE_STF_CMD_UNDERFLOW_ERR_INT_EN BIT(25)
+#define B_BE_STF_CMD_OVERFLOW_ERR_INT_EN BIT(24)
+#define B_BE_REUSE_SIZE_ZERO_ERR_INT_EN BIT(23)
+#define B_BE_REUSE_PKT_CNT_ERR_INT_EN BIT(22)
+#define B_BE_CDT_PTR_TIMEOUT_ERR_INT_EN BIT(21)
+#define B_BE_CDT_HCI_TIMEOUT_ERR_INT_EN BIT(20)
+#define B_BE_HDT_PTR_TIMEOUT_ERR_INT_EN BIT(19)
+#define B_BE_HDT_HCI_TIMEOUT_ERR_INT_EN BIT(18)
+#define B_BE_CDT_ADDR_INFO_LEN_ERR_INT_EN BIT(17)
+#define B_BE_HDT_ADDR_INFO_LEN_ERR_INT_EN BIT(16)
+#define B_BE_CDR_DMA_TIMEOUT_ERR_INT_EN BIT(15)
+#define B_BE_CDR_RX_TIMEOUT_ERR_INT_EN BIT(14)
+#define B_BE_PLE_OUTPUT_ERR_INT_EN BIT(12)
+#define B_BE_PLE_RESPOSE_ERR_INT_EN BIT(11)
+#define B_BE_PLE_BURST_NUM_ERR_INT_EN BIT(10)
+#define B_BE_PLE_NULL_PKT_ERR_INT_EN BIT(9)
+#define B_BE_PLE_FLOW_CTRL_ERR_INT_EN BIT(8)
+#define B_BE_HDR_DMA_TIMEOUT_ERR_INT_EN BIT(7)
+#define B_BE_HDR_RX_TIMEOUT_ERR_INT_EN BIT(6)
+#define B_BE_WDE_OUTPUT_ERR_INT_EN BIT(4)
+#define B_BE_WDE_RESPONSE_ERR_INT_EN BIT(3)
+#define B_BE_WDE_BURST_NUM_ERR_INT_EN BIT(2)
+#define B_BE_WDE_NULL_PKT_ERR_INT_EN BIT(1)
+#define B_BE_WDE_FLOW_CTRL_ERR_INT_EN BIT(0)
+#define B_BE_DISP_OTHER_IMR_CLR (B_BE_WDE_FLOW_CTRL_ERR_INT_EN | \
+ B_BE_WDE_NULL_PKT_ERR_INT_EN | \
+ B_BE_WDE_BURST_NUM_ERR_INT_EN | \
+ B_BE_WDE_RESPONSE_ERR_INT_EN | \
+ B_BE_WDE_OUTPUT_ERR_INT_EN | \
+ B_BE_HDR_RX_TIMEOUT_ERR_INT_EN | \
+ B_BE_HDR_DMA_TIMEOUT_ERR_INT_EN | \
+ B_BE_PLE_FLOW_CTRL_ERR_INT_EN | \
+ B_BE_PLE_NULL_PKT_ERR_INT_EN | \
+ B_BE_PLE_BURST_NUM_ERR_INT_EN | \
+ B_BE_PLE_RESPOSE_ERR_INT_EN | \
+ B_BE_PLE_OUTPUT_ERR_INT_EN | \
+ B_BE_CDR_RX_TIMEOUT_ERR_INT_EN | \
+ B_BE_CDR_DMA_TIMEOUT_ERR_INT_EN | \
+ B_BE_HDT_ADDR_INFO_LEN_ERR_INT_EN | \
+ B_BE_CDT_ADDR_INFO_LEN_ERR_INT_EN | \
+ B_BE_HDT_HCI_TIMEOUT_ERR_INT_EN | \
+ B_BE_HDT_PTR_TIMEOUT_ERR_INT_EN | \
+ B_BE_CDT_HCI_TIMEOUT_ERR_INT_EN | \
+ B_BE_CDT_PTR_TIMEOUT_ERR_INT_EN | \
+ B_BE_REUSE_PKT_CNT_ERR_INT_EN | \
+ B_BE_REUSE_SIZE_ZERO_ERR_INT_EN | \
+ B_BE_STF_CMD_OVERFLOW_ERR_INT_EN | \
+ B_BE_STF_CMD_UNDERFLOW_ERR_INT_EN | \
+ B_BE_STF_WRFF_OVERFLOW_ERR_INT_EN | \
+ B_BE_STF_WRFF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_STF_OQT_OVERFLOW_ERR_INT_EN | \
+ B_BE_STF_OQT_UNDERFLOW_ERR_INT_EN | \
+ B_BE_REUSE_EN_ERR_INT_EN | \
+ B_BE_REUSE_SIZE_ERR_INT_EN)
+#define B_BE_DISP_OTHER_IMR_SET (B_BE_STF_CMD_OVERFLOW_ERR_INT_EN | \
+ B_BE_STF_CMD_UNDERFLOW_ERR_INT_EN | \
+ B_BE_STF_WRFF_OVERFLOW_ERR_INT_EN | \
+ B_BE_STF_WRFF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_STF_OQT_OVERFLOW_ERR_INT_EN | \
+ B_BE_STF_OQT_UNDERFLOW_ERR_INT_EN)
+
+#define R_BE_DISP_HOST_IMR 0x8874
+#define B_BE_HR_WRFF_UNDERFLOW_ERR_INT_EN BIT(31)
+#define B_BE_HR_WRFF_OVERFLOW_ERR_INT_EN BIT(30)
+#define B_BE_HR_CHKSUM_FSM_ERR_INT_EN BIT(29)
+#define B_BE_HR_SHIFT_DMA_CFG_ERR_INT_EN BIT(28)
+#define B_BE_HR_DMA_PROCESS_ERR_INT_EN BIT(27)
+#define B_BE_HR_TOTAL_LEN_UNDER_ERR_INT_EN BIT(26)
+#define B_BE_HR_SHIFT_EN_ERR_INT_EN BIT(25)
+#define B_BE_HR_AGG_CFG_ERR_INT_EN BIT(24)
+#define B_BE_HR_PLD_LEN_ZERO_ERR_INT_EN BIT(22)
+#define B_BE_HT_ILL_CH_ERR_INT_EN BIT(20)
+#define B_BE_HT_ADDR_INFO_LEN_ERR_INT_EN BIT(18)
+#define B_BE_HT_WD_LEN_OVER_ERR_INT_EN BIT(17)
+#define B_BE_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN BIT(16)
+#define B_BE_HT_PLD_CMD_OVERFLOW_ERR_INT_EN BIT(15)
+#define B_BE_HT_WRFF_UNDERFLOW_ERR_INT_EN BIT(14)
+#define B_BE_HT_WRFF_OVERFLOW_ERR_INT_EN BIT(13)
+#define B_BE_HT_CHKSUM_FSM_ERR_INT_EN BIT(12)
+#define B_BE_HT_NON_IDLE_PKT_STR_ERR_EN BIT(11)
+#define B_BE_HT_PRE_SUB_ERR_INT_EN BIT(10)
+#define B_BE_HT_WD_CHKSUM_ERR_INT_EN BIT(9)
+#define B_BE_HT_CHANNEL_DMA_ERR_INT_EN BIT(8)
+#define B_BE_HT_OFFSET_UNMATCH_ERR_INT_EN BIT(7)
+#define B_BE_HT_PAYLOAD_UNDER_ERR_INT_EN BIT(6)
+#define B_BE_HT_PAYLOAD_OVER_ERR_INT_EN BIT(5)
+#define B_BE_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN BIT(4)
+#define B_BE_HT_PERMU_FF_OVERFLOW_ERR_INT_EN BIT(3)
+#define B_BE_HT_PKT_FAIL_ERR_INT_EN BIT(2)
+#define B_BE_HT_CH_ID_ERR_INT_EN BIT(1)
+#define B_BE_HT_EP_CH_DIFF_ERR_INT_EN BIT(0)
+#define B_BE_DISP_HOST_IMR_CLR (B_BE_HT_EP_CH_DIFF_ERR_INT_EN | \
+ B_BE_HT_CH_ID_ERR_INT_EN | \
+ B_BE_HT_PKT_FAIL_ERR_INT_EN | \
+ B_BE_HT_PERMU_FF_OVERFLOW_ERR_INT_EN | \
+ B_BE_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_HT_PAYLOAD_OVER_ERR_INT_EN | \
+ B_BE_HT_PAYLOAD_UNDER_ERR_INT_EN | \
+ B_BE_HT_OFFSET_UNMATCH_ERR_INT_EN | \
+ B_BE_HT_CHANNEL_DMA_ERR_INT_EN | \
+ B_BE_HT_WD_CHKSUM_ERR_INT_EN | \
+ B_BE_HT_PRE_SUB_ERR_INT_EN | \
+ B_BE_HT_NON_IDLE_PKT_STR_ERR_EN | \
+ B_BE_HT_CHKSUM_FSM_ERR_INT_EN | \
+ B_BE_HT_WRFF_OVERFLOW_ERR_INT_EN | \
+ B_BE_HT_WRFF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_HT_PLD_CMD_OVERFLOW_ERR_INT_EN | \
+ B_BE_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \
+ B_BE_HT_WD_LEN_OVER_ERR_INT_EN | \
+ B_BE_HT_ADDR_INFO_LEN_ERR_INT_EN | \
+ B_BE_HT_ILL_CH_ERR_INT_EN | \
+ B_BE_HR_PLD_LEN_ZERO_ERR_INT_EN | \
+ B_BE_HR_AGG_CFG_ERR_INT_EN | \
+ B_BE_HR_SHIFT_EN_ERR_INT_EN | \
+ B_BE_HR_TOTAL_LEN_UNDER_ERR_INT_EN | \
+ B_BE_HR_DMA_PROCESS_ERR_INT_EN | \
+ B_BE_HR_SHIFT_DMA_CFG_ERR_INT_EN | \
+ B_BE_HR_CHKSUM_FSM_ERR_INT_EN | \
+ B_BE_HR_WRFF_OVERFLOW_ERR_INT_EN | \
+ B_BE_HR_WRFF_UNDERFLOW_ERR_INT_EN)
+#define B_BE_DISP_HOST_IMR_SET (B_BE_HT_EP_CH_DIFF_ERR_INT_EN | \
+ B_BE_HT_PERMU_FF_OVERFLOW_ERR_INT_EN | \
+ B_BE_HT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_HT_PAYLOAD_OVER_ERR_INT_EN | \
+ B_BE_HT_PAYLOAD_UNDER_ERR_INT_EN | \
+ B_BE_HT_CHANNEL_DMA_ERR_INT_EN | \
+ B_BE_HT_PRE_SUB_ERR_INT_EN | \
+ B_BE_HT_WRFF_OVERFLOW_ERR_INT_EN | \
+ B_BE_HT_WRFF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_HT_PLD_CMD_OVERFLOW_ERR_INT_EN | \
+ B_BE_HT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \
+ B_BE_HT_WD_LEN_OVER_ERR_INT_EN | \
+ B_BE_HT_ILL_CH_ERR_INT_EN | \
+ B_BE_HR_TOTAL_LEN_UNDER_ERR_INT_EN | \
+ B_BE_HR_DMA_PROCESS_ERR_INT_EN | \
+ B_BE_HR_WRFF_OVERFLOW_ERR_INT_EN | \
+ B_BE_HR_WRFF_UNDERFLOW_ERR_INT_EN)
+
+#define R_BE_DISP_CPU_IMR 0x8878
+#define B_BE_CR_PLD_LEN_ERR_INT_EN BIT(30)
+#define B_BE_CR_WRFF_UNDERFLOW_ERR_INT_EN BIT(29)
+#define B_BE_CR_WRFF_OVERFLOW_ERR_INT_EN BIT(28)
+#define B_BE_CR_SHIFT_DMA_CFG_ERR_INT_EN BIT(27)
+#define B_BE_CR_DMA_PROCESS_ERR_INT_EN BIT(26)
+#define B_BE_CR_TOTAL_LEN_UNDER_ERR_INT_EN BIT(25)
+#define B_BE_CR_SHIFT_EN_ERR_INT_EN BIT(24)
+#define B_BE_REUSE_FIFO_B_UNDER_ERR_INT_EN BIT(22)
+#define B_BE_REUSE_FIFO_B_OVER_ERR_INT_EN BIT(21)
+#define B_BE_REUSE_FIFO_A_UNDER_ERR_INT_EN BIT(20)
+#define B_BE_REUSE_FIFO_A_OVER_ERR_INT_EN BIT(19)
+#define B_BE_CT_ADDR_INFO_LEN_MISS_ERR_INT_EN BIT(17)
+#define B_BE_CT_WD_LEN_OVER_ERR_INT_EN BIT(16)
+#define B_BE_CT_F2P_SEQ_ERR_INT_EN BIT(15)
+#define B_BE_CT_F2P_QSEL_ERR_INT_EN BIT(14)
+#define B_BE_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN BIT(13)
+#define B_BE_CT_PLD_CMD_OVERFLOW_ERR_INT_EN BIT(12)
+#define B_BE_CT_PRE_SUB_ERR_INT_EN BIT(11)
+#define B_BE_CT_WD_CHKSUM_ERR_INT_EN BIT(10)
+#define B_BE_CT_CHANNEL_DMA_ERR_INT_EN BIT(9)
+#define B_BE_CT_OFFSET_UNMATCH_ERR_INT_EN BIT(8)
+#define B_BE_CT_PAYLOAD_CHKSUM_ERR_INT_EN BIT(7)
+#define B_BE_CT_PAYLOAD_UNDER_ERR_INT_EN BIT(6)
+#define B_BE_CT_PAYLOAD_OVER_ERR_INT_EN BIT(5)
+#define B_BE_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN BIT(4)
+#define B_BE_CT_PERMU_FF_OVERFLOW_ERR_INT_EN BIT(3)
+#define B_BE_CT_CH_ID_ERR_INT_EN BIT(2)
+#define B_BE_CT_PKT_FAIL_ERR_INT_EN BIT(1)
+#define B_BE_CT_EP_CH_DIFF_ERR_INT_EN BIT(0)
+#define B_BE_DISP_CPU_IMR_CLR (B_BE_CT_EP_CH_DIFF_ERR_INT_EN | \
+ B_BE_CT_CH_ID_ERR_INT_EN | \
+ B_BE_CT_PERMU_FF_OVERFLOW_ERR_INT_EN | \
+ B_BE_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_CT_PAYLOAD_OVER_ERR_INT_EN | \
+ B_BE_CT_PAYLOAD_UNDER_ERR_INT_EN | \
+ B_BE_CT_OFFSET_UNMATCH_ERR_INT_EN | \
+ B_BE_CT_CHANNEL_DMA_ERR_INT_EN | \
+ B_BE_CT_WD_CHKSUM_ERR_INT_EN | \
+ B_BE_CT_PRE_SUB_ERR_INT_EN | \
+ B_BE_CT_PLD_CMD_OVERFLOW_ERR_INT_EN | \
+ B_BE_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \
+ B_BE_CT_F2P_QSEL_ERR_INT_EN | \
+ B_BE_CT_F2P_SEQ_ERR_INT_EN | \
+ B_BE_CT_WD_LEN_OVER_ERR_INT_EN | \
+ B_BE_CT_ADDR_INFO_LEN_MISS_ERR_INT_EN | \
+ B_BE_REUSE_FIFO_A_OVER_ERR_INT_EN | \
+ B_BE_REUSE_FIFO_A_UNDER_ERR_INT_EN | \
+ B_BE_REUSE_FIFO_B_OVER_ERR_INT_EN | \
+ B_BE_REUSE_FIFO_B_UNDER_ERR_INT_EN | \
+ B_BE_CR_SHIFT_EN_ERR_INT_EN | \
+ B_BE_CR_DMA_PROCESS_ERR_INT_EN | \
+ B_BE_CR_SHIFT_DMA_CFG_ERR_INT_EN | \
+ B_BE_CR_WRFF_OVERFLOW_ERR_INT_EN | \
+ B_BE_CR_WRFF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_CR_PLD_LEN_ERR_INT_EN)
+#define B_BE_DISP_CPU_IMR_SET (B_BE_CT_EP_CH_DIFF_ERR_INT_EN | \
+ B_BE_CT_CH_ID_ERR_INT_EN | \
+ B_BE_CT_PERMU_FF_OVERFLOW_ERR_INT_EN | \
+ B_BE_CT_PERMU_FF_UNDERFLOW_ERR_INT_EN | \
+ B_BE_CT_PAYLOAD_OVER_ERR_INT_EN | \
+ B_BE_CT_PAYLOAD_UNDER_ERR_INT_EN | \
+ B_BE_CT_PRE_SUB_ERR_INT_EN | \
+ B_BE_CT_PLD_CMD_OVERFLOW_ERR_INT_EN | \
+ B_BE_CT_PLD_CMD_UNDERFLOW_ERR_INT_EN | \
+ B_BE_CT_WD_LEN_OVER_ERR_INT_EN | \
+ B_BE_REUSE_FIFO_A_OVER_ERR_INT_EN | \
+ B_BE_REUSE_FIFO_A_UNDER_ERR_INT_EN | \
+ B_BE_REUSE_FIFO_B_OVER_ERR_INT_EN | \
+ B_BE_REUSE_FIFO_B_UNDER_ERR_INT_EN | \
+ B_BE_CR_DMA_PROCESS_ERR_INT_EN | \
+ B_BE_CR_WRFF_OVERFLOW_ERR_INT_EN | \
+ B_BE_CR_WRFF_UNDERFLOW_ERR_INT_EN)
+
+#define R_BE_WDE_PKTBUF_CFG 0x8C08
+#define B_BE_WDE_FREE_PAGE_NUM_MASK GENMASK(28, 16)
+#define B_BE_WDE_START_BOUND_MASK GENMASK(14, 8)
+#define B_BE_WDE_PAGE_SEL_MASK GENMASK(1, 0)
+
+#define R_BE_WDE_ERR_IMR 0x8C38
+#define B_BE_WDE_DATCHN_CAMREQ_ERR_INT_EN BIT(29)
+#define B_BE_WDE_DATCHN_ADRERR_ERR_INT_EN BIT(28)
+#define B_BE_WDE_DATCHN_RRDY_ERR_INT_EN BIT(27)
+#define B_BE_WDE_DATCHN_FRZTO_ERR_INT_EN BIT(26)
+#define B_BE_WDE_DATCHN_NULLPG_ERR_INT_EN BIT(25)
+#define B_BE_WDE_DATCHN_ARBT_ERR_INT_EN BIT(24)
+#define B_BE_WDE_QUEMGN_FRZTO_ERR_INT_EN BIT(23)
+#define B_BE_WDE_NXTPKTLL_AD_ERR_INT_EN BIT(22)
+#define B_BE_WDE_PREPKTLLT_AD_ERR_INT_EN BIT(21)
+#define B_BE_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(20)
+#define B_BE_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(19)
+#define B_BE_WDE_QUE_SRCQUEID_ERR_INT_EN BIT(18)
+#define B_BE_WDE_QUE_DSTQUEID_ERR_INT_EN BIT(17)
+#define B_BE_WDE_QUE_CMDTYPE_ERR_INT_EN BIT(16)
+#define B_BE_WDE_BUFMGN_MRG_SZLMT_ERR_INT_EN BIT(13)
+#define B_BE_WDE_BUFMGN_MRG_QTAID_ERR_INT_EN BIT(12)
+#define B_BE_WDE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN BIT(11)
+#define B_BE_WDE_ERR_BUFMGN_MRG_STRPKTID_ERR_INT_EN BIT(10)
+#define B_BE_WDE_BUFMGN_FRZTO_ERR_INT_EN BIT(9)
+#define B_BE_WDE_GETNPG_PGOFST_ERR_INT_EN BIT(8)
+#define B_BE_WDE_GETNPG_STRPG_ERR_INT_EN BIT(7)
+#define B_BE_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN BIT(6)
+#define B_BE_WDE_BUFRTN_SIZE_ERR_INT_EN BIT(5)
+#define B_BE_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN BIT(4)
+#define B_BE_WDE_BUFREQ_UNAVAL_ERR_INT_EN BIT(3)
+#define B_BE_WDE_BUFREQ_SIZELMT_INT_EN BIT(2)
+#define B_BE_WDE_BUFREQ_SIZE0_INT_EN BIT(1)
+#define B_BE_WDE_BUFREQ_QTAID_ERR_INT_EN BIT(0)
+#define B_BE_WDE_ERR_IMR_CLR (B_BE_WDE_BUFREQ_QTAID_ERR_INT_EN | \
+ B_BE_WDE_BUFREQ_SIZE0_INT_EN | \
+ B_BE_WDE_BUFREQ_SIZELMT_INT_EN | \
+ B_BE_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \
+ B_BE_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \
+ B_BE_WDE_BUFRTN_SIZE_ERR_INT_EN | \
+ B_BE_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \
+ B_BE_WDE_GETNPG_STRPG_ERR_INT_EN | \
+ B_BE_WDE_GETNPG_PGOFST_ERR_INT_EN | \
+ B_BE_WDE_BUFMGN_FRZTO_ERR_INT_EN | \
+ B_BE_WDE_ERR_BUFMGN_MRG_STRPKTID_ERR_INT_EN | \
+ B_BE_WDE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN | \
+ B_BE_WDE_BUFMGN_MRG_QTAID_ERR_INT_EN | \
+ B_BE_WDE_BUFMGN_MRG_SZLMT_ERR_INT_EN | \
+ B_BE_WDE_QUE_CMDTYPE_ERR_INT_EN | \
+ B_BE_WDE_QUE_DSTQUEID_ERR_INT_EN | \
+ B_BE_WDE_QUE_SRCQUEID_ERR_INT_EN | \
+ B_BE_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \
+ B_BE_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \
+ B_BE_WDE_PREPKTLLT_AD_ERR_INT_EN | \
+ B_BE_WDE_NXTPKTLL_AD_ERR_INT_EN | \
+ B_BE_WDE_QUEMGN_FRZTO_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_ARBT_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_NULLPG_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_FRZTO_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_RRDY_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_ADRERR_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_CAMREQ_ERR_INT_EN)
+#define B_BE_WDE_ERR_IMR_SET (B_BE_WDE_BUFREQ_QTAID_ERR_INT_EN | \
+ B_BE_WDE_BUFREQ_SIZE0_INT_EN | \
+ B_BE_WDE_BUFREQ_SIZELMT_INT_EN | \
+ B_BE_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \
+ B_BE_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \
+ B_BE_WDE_BUFRTN_SIZE_ERR_INT_EN | \
+ B_BE_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \
+ B_BE_WDE_GETNPG_STRPG_ERR_INT_EN | \
+ B_BE_WDE_GETNPG_PGOFST_ERR_INT_EN | \
+ B_BE_WDE_BUFMGN_FRZTO_ERR_INT_EN | \
+ B_BE_WDE_ERR_BUFMGN_MRG_STRPKTID_ERR_INT_EN | \
+ B_BE_WDE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN | \
+ B_BE_WDE_BUFMGN_MRG_QTAID_ERR_INT_EN | \
+ B_BE_WDE_BUFMGN_MRG_SZLMT_ERR_INT_EN | \
+ B_BE_WDE_QUE_CMDTYPE_ERR_INT_EN | \
+ B_BE_WDE_QUE_DSTQUEID_ERR_INT_EN | \
+ B_BE_WDE_QUE_SRCQUEID_ERR_INT_EN | \
+ B_BE_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \
+ B_BE_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \
+ B_BE_WDE_PREPKTLLT_AD_ERR_INT_EN | \
+ B_BE_WDE_NXTPKTLL_AD_ERR_INT_EN | \
+ B_BE_WDE_QUEMGN_FRZTO_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_ARBT_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_NULLPG_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_FRZTO_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_RRDY_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_ADRERR_ERR_INT_EN | \
+ B_BE_WDE_DATCHN_CAMREQ_ERR_INT_EN)
+
+#define R_BE_WDE_QTA0_CFG 0x8C40
+#define B_BE_WDE_Q0_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_WDE_Q0_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_WDE_QTA1_CFG 0x8C44
+#define B_BE_WDE_Q1_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_WDE_Q1_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_WDE_QTA2_CFG 0x8C48
+#define B_BE_WDE_Q2_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_WDE_Q2_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_WDE_QTA3_CFG 0x8C4C
+#define B_BE_WDE_Q3_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_WDE_Q3_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_WDE_QTA4_CFG 0x8C50
+#define B_BE_WDE_Q4_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_WDE_Q4_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_WDE_ERR1_IMR 0x8CC0
+#define B_BE_WDE_QUEMGN_CMACACQ_DEQNTFY_INT_EN BIT(8)
+#define B_BE_WDE_ERR1_IMR_CLR B_BE_WDE_QUEMGN_CMACACQ_DEQNTFY_INT_EN
+#define B_BE_WDE_ERR1_IMR_SET B_BE_WDE_QUEMGN_CMACACQ_DEQNTFY_INT_EN
+
+#define R_BE_PLE_PKTBUF_CFG 0x9008
+#define B_BE_PLE_FREE_PAGE_NUM_MASK GENMASK(28, 16)
+#define B_BE_PLE_START_BOUND_MASK GENMASK(14, 8)
+#define B_BE_PLE_PAGE_SEL_MASK GENMASK(1, 0)
+
+#define R_BE_PLE_ERR_IMR 0x9038
+#define B_BE_PLE_DATCHN_CAMREQ_ERR_INT_EN BIT(29)
+#define B_BE_PLE_DATCHN_ADRERR_ERR_INT_EN BIT(28)
+#define B_BE_PLE_DATCHN_RRDY_ERR_INT_EN BIT(27)
+#define B_BE_PLE_DATCHN_FRZTO_ERR_INT_EN BIT(26)
+#define B_BE_PLE_DATCHN_NULLPG_ERR_INT_EN BIT(25)
+#define B_BE_PLE_DATCHN_ARBT_ERR_INT_EN BIT(24)
+#define B_BE_PLE_QUEMGN_FRZTO_ERR_INT_EN BIT(23)
+#define B_BE_PLE_NXTPKTLL_AD_ERR_INT_EN BIT(22)
+#define B_BE_PLE_PREPKTLLT_AD_ERR_INT_EN BIT(21)
+#define B_BE_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN BIT(20)
+#define B_BE_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN BIT(19)
+#define B_BE_PLE_QUE_SRCQUEID_ERR_INT_EN BIT(18)
+#define B_BE_PLE_QUE_DSTQUEID_ERR_INT_EN BIT(17)
+#define B_BE_PLE_QUE_CMDTYPE_ERR_INT_EN BIT(16)
+#define B_BE_PLE_BUFMGN_MRG_SZLMT_ERR_INT_EN BIT(13)
+#define B_BE_PLE_BUFMGN_MRG_QTAID_ERR_INT_EN BIT(12)
+#define B_BE_PLE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN BIT(11)
+#define B_BE_PLE_BUFMGN_MRG_STRPKTID_ERR_INT_EN BIT(10)
+#define B_BE_PLE_BUFMGN_FRZTO_ERR_INT_EN BIT(9)
+#define B_BE_PLE_GETNPG_PGOFST_ERR_INT_EN BIT(8)
+#define B_BE_PLE_GETNPG_STRPG_ERR_INT_EN BIT(7)
+#define B_BE_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN BIT(6)
+#define B_BE_PLE_BUFRTN_SIZE_ERR_INT_EN BIT(5)
+#define B_BE_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN BIT(4)
+#define B_BE_PLE_BUFREQ_UNAVAL_ERR_INT_EN BIT(3)
+#define B_BE_PLE_BUFREQ_SIZELMT_INT_EN BIT(2)
+#define B_BE_PLE_BUFREQ_SIZE0_INT_EN BIT(1)
+#define B_BE_PLE_BUFREQ_QTAID_ERR_INT_EN BIT(0)
+#define B_BE_PLE_ERR_IMR_CLR (B_BE_PLE_BUFREQ_QTAID_ERR_INT_EN | \
+ B_BE_PLE_BUFREQ_SIZE0_INT_EN | \
+ B_BE_PLE_BUFREQ_SIZELMT_INT_EN | \
+ B_BE_PLE_BUFREQ_UNAVAL_ERR_INT_EN | \
+ B_BE_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \
+ B_BE_PLE_BUFRTN_SIZE_ERR_INT_EN | \
+ B_BE_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \
+ B_BE_PLE_GETNPG_STRPG_ERR_INT_EN | \
+ B_BE_PLE_GETNPG_PGOFST_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_FRZTO_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_MRG_STRPKTID_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_MRG_QTAID_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_MRG_SZLMT_ERR_INT_EN | \
+ B_BE_PLE_QUE_CMDTYPE_ERR_INT_EN | \
+ B_BE_PLE_QUE_DSTQUEID_ERR_INT_EN | \
+ B_BE_PLE_QUE_SRCQUEID_ERR_INT_EN | \
+ B_BE_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \
+ B_BE_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \
+ B_BE_PLE_PREPKTLLT_AD_ERR_INT_EN | \
+ B_BE_PLE_NXTPKTLL_AD_ERR_INT_EN | \
+ B_BE_PLE_QUEMGN_FRZTO_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_ARBT_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_NULLPG_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_FRZTO_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_RRDY_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_ADRERR_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_CAMREQ_ERR_INT_EN)
+#define B_BE_PLE_ERR_IMR_SET (B_BE_PLE_BUFREQ_QTAID_ERR_INT_EN | \
+ B_BE_PLE_BUFREQ_SIZE0_INT_EN | \
+ B_BE_PLE_BUFREQ_SIZELMT_INT_EN | \
+ B_BE_PLE_BUFREQ_UNAVAL_ERR_INT_EN | \
+ B_BE_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \
+ B_BE_PLE_BUFRTN_SIZE_ERR_INT_EN | \
+ B_BE_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \
+ B_BE_PLE_GETNPG_STRPG_ERR_INT_EN | \
+ B_BE_PLE_GETNPG_PGOFST_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_FRZTO_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_MRG_STRPKTID_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_MRG_ENDPKTID_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_MRG_QTAID_ERR_INT_EN | \
+ B_BE_PLE_BUFMGN_MRG_SZLMT_ERR_INT_EN | \
+ B_BE_PLE_QUE_CMDTYPE_ERR_INT_EN | \
+ B_BE_PLE_QUE_DSTQUEID_ERR_INT_EN | \
+ B_BE_PLE_QUE_SRCQUEID_ERR_INT_EN | \
+ B_BE_PLE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \
+ B_BE_PLE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \
+ B_BE_PLE_PREPKTLLT_AD_ERR_INT_EN | \
+ B_BE_PLE_NXTPKTLL_AD_ERR_INT_EN | \
+ B_BE_PLE_QUEMGN_FRZTO_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_ARBT_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_NULLPG_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_FRZTO_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_RRDY_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_ADRERR_ERR_INT_EN | \
+ B_BE_PLE_DATCHN_CAMREQ_ERR_INT_EN)
+
+#define R_BE_PLE_QTA0_CFG 0x9040
+#define B_BE_PLE_Q0_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q0_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA1_CFG 0x9044
+#define B_BE_PLE_Q1_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q1_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA2_CFG 0x9048
+#define B_BE_PLE_Q2_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q2_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA3_CFG 0x904C
+#define B_BE_PLE_Q3_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q3_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA4_CFG 0x9050
+#define B_BE_PLE_Q4_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q4_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA5_CFG 0x9054
+#define B_BE_PLE_Q5_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q5_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA6_CFG 0x9058
+#define B_BE_PLE_Q6_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q6_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA7_CFG 0x905C
+#define B_BE_PLE_Q7_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q7_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA8_CFG 0x9060
+#define B_BE_PLE_Q8_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q8_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA9_CFG 0x9064
+#define B_BE_PLE_Q9_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q9_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA10_CFG 0x9068
+#define B_BE_PLE_Q10_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q10_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA11_CFG 0x906C
+#define B_BE_PLE_Q11_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q11_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_QTA12_CFG 0x9070
+#define B_BE_PLE_Q12_MAX_SIZE_MASK GENMASK(27, 16)
+#define B_BE_PLE_Q12_MIN_SIZE_MASK GENMASK(11, 0)
+
+#define R_BE_PLE_ERRFLAG1_IMR 0x90C0
+#define B_BE_PLE_SRCHPG_PGOFST_IMR BIT(26)
+#define B_BE_PLE_SRCHPG_STRPG_IMR BIT(25)
+#define B_BE_PLE_SRCHPG_FRZTO_IMR BIT(24)
+#define B_BE_PLE_ERRFLAG1_IMR_CLR (B_BE_PLE_SRCHPG_FRZTO_IMR | \
+ B_BE_PLE_SRCHPG_STRPG_IMR | \
+ B_BE_PLE_SRCHPG_PGOFST_IMR)
+#define B_BE_PLE_ERRFLAG1_IMR_SET (B_BE_PLE_SRCHPG_FRZTO_IMR | \
+ B_BE_PLE_SRCHPG_STRPG_IMR | \
+ B_BE_PLE_SRCHPG_PGOFST_IMR)
+
#define R_BE_PLE_DBG_FUN_INTF_CTL 0x9110
#define B_BE_PLE_DFI_ACTIVE BIT(31)
#define B_BE_PLE_DFI_TRGSEL_MASK GENMASK(19, 16)
@@ -4152,6 +5202,381 @@
#define R_BE_PLE_DBG_FUN_INTF_DATA 0x9114
#define B_BE_PLE_DFI_DATA_MASK GENMASK(31, 0)
+#define R_BE_WDRLS_CFG 0x9408
+#define B_BE_WDRLS_DIS_AGAC BIT(31)
+#define B_BE_RLSRPT_BUFREQ_TO_MASK GENMASK(15, 8)
+#define B_BE_RLSRPT_BUFREQ_TO_SEL_MASK GENMASK(7, 6)
+#define B_BE_WDRLS_MODE_MASK GENMASK(1, 0)
+
+#define R_BE_WDRLS_ERR_IMR 0x9430
+#define B_BE_WDRLS_RPT3_FRZTO_ERR_INT_EN BIT(21)
+#define B_BE_WDRLS_RPT3_AGGNUM0_ERR_INT_EN BIT(20)
+#define B_BE_WDRLS_RPT2_FRZTO_ERR_INT_EN BIT(17)
+#define B_BE_WDRLS_RPT2_AGGNUM0_ERR_INT_EN BIT(16)
+#define B_BE_WDRLS_RPT1_FRZTO_ERR_INT_EN BIT(13)
+#define B_BE_WDRLS_RPT1_AGGNUM0_ERR_INT_EN BIT(12)
+#define B_BE_WDRLS_RPT0_FRZTO_ERR_INT_EN BIT(9)
+#define B_BE_WDRLS_RPT0_AGGNUM0_ERR_INT_EN BIT(8)
+#define B_BE_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN BIT(5)
+#define B_BE_WDRLS_PLEBREQ_TO_ERR_INT_EN BIT(4)
+#define B_BE_WDRLS_CTL_FRZTO_ERR_INT_EN BIT(2)
+#define B_BE_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN BIT(1)
+#define B_BE_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN BIT(0)
+#define B_BE_WDRLS_ERR_IMR_CLR (B_BE_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \
+ B_BE_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \
+ B_BE_WDRLS_CTL_FRZTO_ERR_INT_EN | \
+ B_BE_WDRLS_PLEBREQ_TO_ERR_INT_EN | \
+ B_BE_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \
+ B_BE_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \
+ B_BE_WDRLS_RPT0_FRZTO_ERR_INT_EN | \
+ B_BE_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \
+ B_BE_WDRLS_RPT1_FRZTO_ERR_INT_EN)
+#define B_BE_WDRLS_ERR_IMR_SET (B_BE_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN | \
+ B_BE_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN | \
+ B_BE_WDRLS_CTL_FRZTO_ERR_INT_EN | \
+ B_BE_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN | \
+ B_BE_WDRLS_RPT0_AGGNUM0_ERR_INT_EN | \
+ B_BE_WDRLS_RPT0_FRZTO_ERR_INT_EN | \
+ B_BE_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \
+ B_BE_WDRLS_RPT1_FRZTO_ERR_INT_EN)
+
+#define R_BE_RLSRPT0_CFG1 0x9444
+#define B_BE_RLSRPT0_FLTR_MAP_MASK GENMASK(27, 24)
+#define S_BE_WDRLS_FLTR_TXOK 1
+#define S_BE_WDRLS_FLTR_RTYLMT 2
+#define S_BE_WDRLS_FLTR_LIFTIM 4
+#define S_BE_WDRLS_FLTR_MACID 8
+#define B_BE_RLSRPT0_TO_MASK GENMASK(23, 16)
+#define B_BE_RLSRPT0_AGGNUM_MASK GENMASK(7, 0)
+
+#define R_BE_BBRPT_COM_ERR_IMR 0x9608
+#define B_BE_BBRPT_COM_EVT01_ISR_EN BIT(1)
+#define B_BE_BBRPT_COM_NULL_PLPKTID_ISR_EN BIT(0)
+#define B_BE_BBRPT_COM_ERR_IMR_CLR (B_BE_BBRPT_COM_NULL_PLPKTID_ISR_EN | \
+ B_BE_BBRPT_COM_EVT01_ISR_EN)
+#define B_BE_BBRPT_COM_ERR_IMR_SET B_BE_BBRPT_COM_NULL_PLPKTID_ISR_EN
+
+#define R_BE_BBRPT_CHINFO_ERR_IMR 0x9628
+#define B_BE_ERR_BB_ONETEN_INT_EN BIT(1)
+#define B_BE_ERR_GEN_FRZTO_INT_EN BIT(0)
+#define B_BE_BBRPT_CHINFO_ERR_IMR_CLR (B_BE_ERR_GEN_FRZTO_INT_EN | \
+ B_BE_ERR_BB_ONETEN_INT_EN)
+#define B_BE_BBRPT_CHINFO_ERR_IMR_SET (B_BE_ERR_GEN_FRZTO_INT_EN | \
+ B_BE_ERR_BB_ONETEN_INT_EN)
+
+#define R_BE_BBRPT_DFS_ERR_IMR 0x9638
+#define B_BE_BBRPT_DFS_TO_ERR_INT_EN BIT(0)
+#define B_BE_BBRPT_DFS_ERR_IMR_CLR B_BE_BBRPT_DFS_TO_ERR_INT_EN
+#define B_BE_BBRPT_DFS_ERR_IMR_SET B_BE_BBRPT_DFS_TO_ERR_INT_EN
+
+#define R_BE_LA_ERRFLAG_IMR 0x9668
+#define B_BE_LA_IMR_DATA_LOSS BIT(0)
+#define B_BE_LA_ERRFLAG_IMR_CLR B_BE_LA_IMR_DATA_LOSS
+#define B_BE_LA_ERRFLAG_IMR_SET B_BE_LA_IMR_DATA_LOSS
+
+#define R_BE_LA_ERRFLAG_ISR 0x966C
+#define B_BE_LA_ISR_DATA_LOSS BIT(0)
+
+#define R_BE_CH_INFO_DBGFLAG_IMR 0x9688
+#define B_BE_BCHN_EVT01_ISR_EN BIT(29)
+#define B_BE_BCHN_REQTO_ISR_EN BIT(28)
+#define B_BE_CHIF_RXDATA_AFACT_ISR_EN BIT(11)
+#define B_BE_CHIF_RXDATA_BFACT_ISR_EN BIT(10)
+#define B_BE_CHIF_HDR_SEGLEN_ISR_EN BIT(9)
+#define B_BE_CHIF_HDR_INVLD_ISR_EN BIT(8)
+#define B_BE_CHIF_BBONL_BFACT_ISR_EN BIT(4)
+#define B_BE_CHIF_RPT_OVF_ISR_EN BIT(3)
+#define B_BE_DBG_CHIF_DATA_LOSS_ISR_EN BIT(2)
+#define B_BE_CHIF_DATA_WTOUT_ISR_EN BIT(1)
+#define B_BE_CHIF_RPT_WTOUT_ISR_EN BIT(0)
+#define B_BE_CH_INFO_DBGFLAG_IMR_CLR (B_BE_CHIF_RPT_WTOUT_ISR_EN | \
+ B_BE_CHIF_DATA_WTOUT_ISR_EN | \
+ B_BE_DBG_CHIF_DATA_LOSS_ISR_EN | \
+ B_BE_CHIF_RPT_OVF_ISR_EN | \
+ B_BE_CHIF_HDR_INVLD_ISR_EN | \
+ B_BE_CHIF_HDR_SEGLEN_ISR_EN | \
+ B_BE_CHIF_RXDATA_BFACT_ISR_EN | \
+ B_BE_CHIF_RXDATA_AFACT_ISR_EN)
+#define B_BE_CH_INFO_DBGFLAG_IMR_SET 0
+
+#define R_BE_WD_BUF_REQ 0x9800
+#define B_BE_WD_BUF_REQ_EXEC BIT(31)
+#define B_BE_WD_BUF_REQ_QUOTA_ID_MASK GENMASK(23, 16)
+#define B_BE_WD_BUF_REQ_LEN_MASK GENMASK(15, 0)
+
+#define R_BE_WD_BUF_STATUS 0x9804
+#define B_BE_WD_BUF_STAT_DONE BIT(31)
+#define B_BE_WD_BUF_STAT_PKTID_MASK GENMASK(11, 0)
+
+#define R_BE_WD_CPUQ_OP_0 0x9810
+#define B_BE_WD_CPUQ_OP_EXEC BIT(31)
+#define B_BE_WD_CPUQ_OP_CMD_TYPE_MASK GENMASK(27, 24)
+#define B_BE_WD_CPUQ_OP_PKTNUM_MASK GENMASK(7, 0)
+
+#define R_BE_WD_CPUQ_OP_1 0x9814
+#define B_BE_WD_CPUQ_OP_SRC_MACID_MASK GENMASK(19, 12)
+#define B_BE_WD_CPUQ_OP_SRC_QID_MASK GENMASK(9, 4)
+#define B_BE_WD_CPUQ_OP_SRC_PID_MASK GENMASK(2, 0)
+
+#define R_BE_WD_CPUQ_OP_2 0x9818
+#define B_BE_WD_CPUQ_OP_DST_MACID_MASK GENMASK(19, 12)
+#define B_BE_WD_CPUQ_OP_DST_QID_MASK GENMASK(9, 4)
+#define B_BE_WD_CPUQ_OP_DST_PID_MASK GENMASK(2, 0)
+
+#define R_BE_WD_CPUQ_OP_3 0x981C
+#define B_BE_WD_CPUQ_OP_STRT_PKTID_MASK GENMASK(27, 16)
+#define B_BE_WD_CPUQ_OP_END_PKTID_MASK GENMASK(11, 0)
+
+#define R_BE_WD_CPUQ_OP_STATUS 0x9820
+#define B_BE_WD_CPUQ_OP_STAT_DONE BIT(31)
+#define B_BE_WD_CPUQ_OP_PKTCNT_MASK GENMASK(27, 16)
+#define B_BE_WD_CPUQ_OP_PKTID_MASK GENMASK(11, 0)
+
+#define R_BE_PL_BUF_REQ 0x9840
+#define B_BE_PL_BUF_REQ_EXEC BIT(31)
+#define B_BE_PL_BUF_REQ_QUOTA_ID_MASK GENMASK(19, 16)
+#define B_BE_PL_BUF_REQ_LEN_MASK GENMASK(15, 0)
+
+#define R_BE_PL_BUF_STATUS 0x9844
+#define B_BE_PL_BUF_STAT_DONE BIT(31)
+#define B_BE_PL_BUF_STAT_PKTID_MASK GENMASK(11, 0)
+
+#define R_BE_PL_CPUQ_OP_0 0x9850
+#define B_BE_PL_CPUQ_OP_EXEC BIT(31)
+#define B_BE_PL_CPUQ_OP_CMD_TYPE_MASK GENMASK(27, 24)
+#define B_BE_PL_CPUQ_OP_PKTNUM_MASK GENMASK(7, 0)
+
+#define R_BE_PL_CPUQ_OP_1 0x9854
+#define B_BE_PL_CPUQ_OP_SRC_MACID_MASK GENMASK(19, 12)
+#define B_BE_PL_CPUQ_OP_SRC_QID_MASK GENMASK(9, 4)
+#define B_BE_PL_CPUQ_OP_SRC_PID_MASK GENMASK(2, 0)
+
+#define R_BE_PL_CPUQ_OP_2 0x9858
+#define B_BE_PL_CPUQ_OP_DST_MACID_MASK GENMASK(19, 12)
+#define B_BE_PL_CPUQ_OP_DST_QID_MASK GENMASK(9, 4)
+#define B_BE_PL_CPUQ_OP_DST_PID_MASK GENMASK(2, 0)
+
+#define R_BE_PL_CPUQ_OP_3 0x985C
+#define B_BE_PL_CPUQ_OP_STRT_PKTID_MASK GENMASK(27, 16)
+#define B_BE_PL_CPUQ_OP_END_PKTID_MASK GENMASK(11, 0)
+
+#define R_BE_PL_CPUQ_OP_STATUS 0x9860
+#define B_BE_PL_CPUQ_OP_STAT_DONE BIT(31)
+#define B_BE_PL_CPUQ_OP_PKTCNT_MASK GENMASK(27, 16)
+#define B_BE_PL_CPUQ_OP_PKTID_MASK GENMASK(11, 0)
+
+#define R_BE_CPUIO_ERR_IMR 0x9888
+#define B_BE_PLEQUE_OP_ERR_INT_EN BIT(12)
+#define B_BE_PLEBUF_OP_ERR_INT_EN BIT(8)
+#define B_BE_WDEQUE_OP_ERR_INT_EN BIT(4)
+#define B_BE_WDEBUF_OP_ERR_INT_EN BIT(0)
+#define B_BE_CPUIO_ERR_IMR_CLR (B_BE_WDEBUF_OP_ERR_INT_EN | \
+ B_BE_WDEQUE_OP_ERR_INT_EN | \
+ B_BE_PLEBUF_OP_ERR_INT_EN | \
+ B_BE_PLEQUE_OP_ERR_INT_EN)
+#define B_BE_CPUIO_ERR_IMR_SET (B_BE_WDEBUF_OP_ERR_INT_EN | \
+ B_BE_WDEQUE_OP_ERR_INT_EN | \
+ B_BE_PLEBUF_OP_ERR_INT_EN | \
+ B_BE_PLEQUE_OP_ERR_INT_EN)
+
+#define R_BE_PKTIN_ERR_IMR 0x9A20
+#define B_BE_SW_MERGE_ERR_INT_EN BIT(1)
+#define B_BE_GET_NULL_PKTID_ERR_INT_EN BIT(0)
+#define B_BE_PKTIN_ERR_IMR_CLR (B_BE_SW_MERGE_ERR_INT_EN | \
+ B_BE_GET_NULL_PKTID_ERR_INT_EN)
+#define B_BE_PKTIN_ERR_IMR_SET (B_BE_SW_MERGE_ERR_INT_EN | \
+ B_BE_GET_NULL_PKTID_ERR_INT_EN)
+
+#define R_BE_MPDU_TX_ERR_IMR 0x9BF4
+#define B_BE_TX_TIMEOUT_ERR_EN BIT(0)
+#define B_BE_MPDU_TX_ERR_IMR_CLR B_BE_TX_TIMEOUT_ERR_EN
+#define B_BE_MPDU_TX_ERR_IMR_SET 0
+
+#define R_BE_MPDU_RX_ERR_IMR 0x9CF4
+#define B_BE_LEN_ERR_IMR BIT(3)
+#define B_BE_TIMEOUT_ERR_IMR BIT(1)
+#define B_BE_MPDU_RX_ERR_IMR_CLR B_BE_TIMEOUT_ERR_IMR
+#define B_BE_MPDU_RX_ERR_IMR_SET 0
+
+#define R_BE_SEC_ENG_CTRL 0x9D00
+#define B_BE_SEC_ENG_EN BIT(31)
+#define B_BE_CCMP_SPP_MIC BIT(30)
+#define B_BE_CCMP_SPP_CTR BIT(29)
+#define B_BE_SEC_CAM_ACC BIT(28)
+#define B_BE_WMAC_SEC_PN_SEL_MASK GENMASK(27, 26)
+#define B_BE_WMAC_SEC_MASKIV BIT(25)
+#define B_BE_WAPI_SPEC BIT(24)
+#define B_BE_REVERT_TA_RA_MLD_EN BIT(23)
+#define B_BE_SEC_DBG_SEL_MASK GENMASK(19, 16)
+#define B_BE_CAM_FORCE_CLK BIT(15)
+#define B_BE_SEC_FORCE_CLK BIT(14)
+#define B_BE_SEC_RX_SHORT_ADD_ICVERR BIT(13)
+#define B_BE_SRAM_IO_PROT BIT(12)
+#define B_BE_SEC_PRE_ENQUE_TX BIT(11)
+#define B_BE_CLK_EN_CGCMP BIT(10)
+#define B_BE_CLK_EN_WAPI BIT(9)
+#define B_BE_CLK_EN_WEP_TKIP BIT(8)
+#define B_BE_BMC_MGNT_DEC BIT(5)
+#define B_BE_UC_MGNT_DEC BIT(4)
+#define B_BE_MC_DEC BIT(3)
+#define B_BE_BC_DEC BIT(2)
+#define B_BE_SEC_RX_DEC BIT(1)
+#define B_BE_SEC_TX_ENC BIT(0)
+
+#define R_BE_SEC_MPDU_PROC 0x9D04
+#define B_BE_DBG_ENGINE_SEL BIT(8)
+#define B_BE_STOP_RX_PKT_HANDLE BIT(7)
+#define B_BE_STOP_TX_PKT_HANDLE BIT(6)
+#define B_BE_QUEUE_FOWARD_SEL BIT(5)
+#define B_BE_RESP1_PROTECT BIT(4)
+#define B_BE_RESP0_PROTECT BIT(3)
+#define B_BE_TX_ACTIVE_PROTECT BIT(2)
+#define B_BE_APPEND_ICV BIT(1)
+#define B_BE_APPEND_MIC BIT(0)
+
+#define R_BE_SEC_CAM_ACCESS 0x9D10
+#define B_BE_SEC_TIME_OUT_MASK GENMASK(31, 16)
+#define B_BE_SEC_CAM_POLL BIT(15)
+#define B_BE_SEC_CAM_RW BIT(14)
+#define B_BE_SEC_CAM_ACC_FAIL BIT(13)
+#define B_BE_SEC_CAM_OFFSET_MASK GENMASK(10, 0)
+
+#define R_BE_SEC_CAM_RDATA 0x9D14
+#define B_BE_SEC_CAM_RDATA_MASK GENMASK(31, 0)
+
+#define R_BE_SEC_DEBUG2 0x9D28
+#define B_BE_DBG_READ_MASK GENMASK(31, 0)
+
+#define R_BE_SEC_ERROR_IMR 0x9D2C
+#define B_BE_QUEUE_OPERATION_HANG_IMR BIT(4)
+#define B_BE_SEC1_RX_HANG_IMR BIT(3)
+#define B_BE_SEC1_TX_HANG_IMR BIT(2)
+#define B_BE_RX_HANG_IMR BIT(1)
+#define B_BE_TX_HANG_IMR BIT(0)
+#define B_BE_SEC_ERROR_IMR_CLR (B_BE_TX_HANG_IMR | \
+ B_BE_RX_HANG_IMR | \
+ B_BE_SEC1_TX_HANG_IMR | \
+ B_BE_SEC1_RX_HANG_IMR | \
+ B_BE_QUEUE_OPERATION_HANG_IMR)
+#define B_BE_SEC_ERROR_IMR_SET (B_BE_TX_HANG_IMR | \
+ B_BE_RX_HANG_IMR | \
+ B_BE_SEC1_TX_HANG_IMR | \
+ B_BE_SEC1_RX_HANG_IMR | \
+ B_BE_QUEUE_OPERATION_HANG_IMR)
+
+#define R_BE_SEC_ERROR_FLAG 0x9D30
+#define B_BE_TXD_DIFF_KEYCAM_TYPE_ERROR BIT(5)
+#define B_BE_QUEUE_OPERATION_HANG_ERROR BIT(4)
+#define B_BE_SEC1_RX_HANG_ERROR BIT(3)
+#define B_BE_SEC1_TX_HANG_ERROR BIT(2)
+#define B_BE_RX_HANG_ERROR BIT(1)
+#define B_BE_TX_HANG_ERROR BIT(0)
+
+#define R_BE_TXPKTCTL_B0_ERRFLAG_IMR 0x9F78
+#define B_BE_B0_IMR_DBG_USRCTL_RLSBMPLEN BIT(25)
+#define B_BE_B0_IMR_DBG_USRCTL_RDNRLSCMD BIT(24)
+#define B_BE_B0_IMR_ERR_PRELD_ENTNUMCFG BIT(17)
+#define B_BE_B0_IMR_ERR_PRELD_RLSPKTSZERR BIT(16)
+#define B_BE_B0_IMR_ERR_CMDPSR_TBLSZ BIT(11)
+#define B_BE_B0_IMR_ERR_CMDPSR_FRZTO BIT(10)
+#define B_BE_B0_IMR_ERR_CMDPSR_CMDTYPE BIT(9)
+#define B_BE_B0_IMR_ERR_CMDPSR_1STCMDERR BIT(8)
+#define B_BE_B0_IMR_ERR_USRCTL_NOINIT BIT(1)
+#define B_BE_B0_IMR_ERR_USRCTL_REINIT BIT(0)
+#define B_BE_TXPKTCTL_B0_ERRFLAG_IMR_CLR (B_BE_B0_IMR_ERR_USRCTL_REINIT | \
+ B_BE_B0_IMR_ERR_USRCTL_NOINIT | \
+ B_BE_B0_IMR_DBG_USRCTL_RDNRLSCMD | \
+ B_BE_B0_IMR_DBG_USRCTL_RLSBMPLEN | \
+ B_BE_B0_IMR_ERR_CMDPSR_1STCMDERR | \
+ B_BE_B0_IMR_ERR_CMDPSR_CMDTYPE | \
+ B_BE_B0_IMR_ERR_CMDPSR_FRZTO | \
+ B_BE_B0_IMR_ERR_CMDPSR_TBLSZ | \
+ B_BE_B0_IMR_ERR_PRELD_RLSPKTSZERR | \
+ B_BE_B0_IMR_ERR_PRELD_ENTNUMCFG)
+#define B_BE_TXPKTCTL_B0_ERRFLAG_IMR_SET (B_BE_B0_IMR_ERR_USRCTL_REINIT | \
+ B_BE_B0_IMR_ERR_USRCTL_NOINIT | \
+ B_BE_B0_IMR_ERR_CMDPSR_1STCMDERR | \
+ B_BE_B0_IMR_ERR_CMDPSR_CMDTYPE | \
+ B_BE_B0_IMR_ERR_CMDPSR_FRZTO | \
+ B_BE_B0_IMR_ERR_CMDPSR_TBLSZ | \
+ B_BE_B0_IMR_ERR_PRELD_RLSPKTSZERR | \
+ B_BE_B0_IMR_ERR_PRELD_ENTNUMCFG)
+
+#define R_BE_TXPKTCTL_B1_ERRFLAG_IMR 0x9FB8
+#define B_BE_B1_IMR_DBG_USRCTL_RLSBMPLEN BIT(25)
+#define B_BE_B1_IMR_DBG_USRCTL_RDNRLSCMD BIT(24)
+#define B_BE_B1_IMR_ERR_PRELD_ENTNUMCFG BIT(17)
+#define B_BE_B1_IMR_ERR_PRELD_RLSPKTSZERR BIT(16)
+#define B_BE_B1_IMR_ERR_CMDPSR_TBLSZ BIT(11)
+#define B_BE_B1_IMR_ERR_CMDPSR_FRZTO BIT(10)
+#define B_BE_B1_IMR_ERR_CMDPSR_CMDTYPE BIT(9)
+#define B_BE_B1_IMR_ERR_CMDPSR_1STCMDERR BIT(8)
+#define B_BE_B1_IMR_ERR_USRCTL_NOINIT BIT(1)
+#define B_BE_B1_IMR_ERR_USRCTL_REINIT BIT(0)
+#define B_BE_TXPKTCTL_B1_ERRFLAG_IMR_CLR (B_BE_B1_IMR_ERR_USRCTL_REINIT | \
+ B_BE_B1_IMR_ERR_USRCTL_NOINIT | \
+ B_BE_B1_IMR_DBG_USRCTL_RDNRLSCMD | \
+ B_BE_B1_IMR_DBG_USRCTL_RLSBMPLEN | \
+ B_BE_B1_IMR_ERR_CMDPSR_1STCMDERR | \
+ B_BE_B1_IMR_ERR_CMDPSR_CMDTYPE | \
+ B_BE_B1_IMR_ERR_CMDPSR_FRZTO | \
+ B_BE_B1_IMR_ERR_CMDPSR_TBLSZ | \
+ B_BE_B1_IMR_ERR_PRELD_RLSPKTSZERR | \
+ B_BE_B1_IMR_ERR_PRELD_ENTNUMCFG)
+#define B_BE_TXPKTCTL_B1_ERRFLAG_IMR_SET (B_BE_B1_IMR_ERR_USRCTL_REINIT | \
+ B_BE_B1_IMR_ERR_USRCTL_NOINIT | \
+ B_BE_B1_IMR_ERR_CMDPSR_1STCMDERR | \
+ B_BE_B1_IMR_ERR_CMDPSR_CMDTYPE | \
+ B_BE_B1_IMR_ERR_CMDPSR_FRZTO | \
+ B_BE_B1_IMR_ERR_CMDPSR_TBLSZ | \
+ B_BE_B1_IMR_ERR_PRELD_RLSPKTSZERR | \
+ B_BE_B1_IMR_ERR_PRELD_ENTNUMCFG)
+
+#define R_BE_MLO_ERR_IDCT_IMR 0xA128
+#define B_BE_MLO_ERR_IDCT_IMR_0 BIT(31)
+#define B_BE_MLO_ERR_IDCT_IMR_1 BIT(30)
+#define B_BE_MLO_ERR_IDCT_IMR_2 BIT(29)
+#define B_BE_MLO_ERR_IDCT_IMR_3 BIT(28)
+#define B_BE_MLO_ERR_IDCT_IMR_CLR (B_BE_MLO_ERR_IDCT_IMR_2 | \
+ B_BE_MLO_ERR_IDCT_IMR_1 | \
+ B_BE_MLO_ERR_IDCT_IMR_0)
+#define B_BE_MLO_ERR_IDCT_IMR_SET (B_BE_MLO_ERR_IDCT_IMR_2 | \
+ B_BE_MLO_ERR_IDCT_IMR_1 | \
+ B_BE_MLO_ERR_IDCT_IMR_0)
+
+#define R_BE_MLO_ERR_IDCT_ISR 0xA12C
+#define B_BE_MLO_ISR_IDCT_0 BIT(31)
+#define B_BE_MLO_ISR_IDCT_1 BIT(30)
+#define B_BE_MLO_ISR_IDCT_2 BIT(29)
+#define B_BE_MLO_ISR_IDCT_3 BIT(28)
+
+#define R_BE_PLRLS_ERR_IMR 0xA218
+#define B_BE_PLRLS_CTL_FRZTO_IMR BIT(0)
+#define B_BE_PLRLS_ERR_IMR_CLR B_BE_PLRLS_CTL_FRZTO_IMR
+#define B_BE_PLRLS_ERR_IMR_SET B_BE_PLRLS_CTL_FRZTO_IMR
+
+#define R_BE_PLRLS_ERR_ISR 0xA21C
+#define B_BE_PLRLS_CTL_EVT03_ISR BIT(3)
+#define B_BE_PLRLS_CTL_EVT02_ISR BIT(2)
+#define B_BE_PLRLS_CTL_EVT01_ISR BIT(1)
+#define B_BE_PLRLS_CTL_FRZTO_ISR BIT(0)
+
+#define R_BE_INTERRUPT_MASK_REG 0xA3F0
+#define B_BE_PLE_B_PKTID_ERR_IMR BIT(2)
+#define B_BE_RPT_TIMEOUT_IMR BIT(1)
+#define B_BE_SEARCH_TIMEOUT_IMR BIT(0)
+#define B_BE_INTERRUPT_MASK_REG_CLR (B_BE_SEARCH_TIMEOUT_IMR | \
+ B_BE_RPT_TIMEOUT_IMR | \
+ B_BE_PLE_B_PKTID_ERR_IMR)
+#define B_BE_INTERRUPT_MASK_REG_SET (B_BE_SEARCH_TIMEOUT_IMR | \
+ B_BE_RPT_TIMEOUT_IMR | \
+ B_BE_PLE_B_PKTID_ERR_IMR)
+
+#define R_BE_INTERRUPT_STS_REG 0xA3F4
+#define B_BE_PLE_B_PKTID_ERR_ISR BIT(2)
+#define B_BE_RPT_TIMEOUT_ISR BIT(1)
+#define B_BE_SEARCH_TIMEOUT_ISR BIT(0)
+
#define R_BE_HAXI_INIT_CFG1 0xB000
#define B_BE_CFG_WD_PERIOD_IDLE_MASK GENMASK(31, 28)
#define B_BE_CFG_WD_PERIOD_ACTIVE_MASK GENMASK(27, 24)
@@ -4174,6 +5599,112 @@
#define B_BE_MAX_RXDMA_MASK GENMASK(3, 2)
#define B_BE_MAX_TXDMA_MASK GENMASK(1, 0)
+#define R_BE_HAXI_DMA_STOP1 0xB010
+#define B_BE_STOP_WPDMA BIT(31)
+#define B_BE_STOP_CH14 BIT(14)
+#define B_BE_STOP_CH13 BIT(13)
+#define B_BE_STOP_CH12 BIT(12)
+#define B_BE_STOP_CH11 BIT(11)
+#define B_BE_STOP_CH10 BIT(10)
+#define B_BE_STOP_CH9 BIT(9)
+#define B_BE_STOP_CH8 BIT(8)
+#define B_BE_STOP_CH7 BIT(7)
+#define B_BE_STOP_CH6 BIT(6)
+#define B_BE_STOP_CH5 BIT(5)
+#define B_BE_STOP_CH4 BIT(4)
+#define B_BE_STOP_CH3 BIT(3)
+#define B_BE_STOP_CH2 BIT(2)
+#define B_BE_STOP_CH1 BIT(1)
+#define B_BE_STOP_CH0 BIT(0)
+
+#define R_BE_HAXI_IDCT_MSK 0xB0B8
+#define B_BE_HAXI_RRESP_ERR_IDCT_MSK BIT(7)
+#define B_BE_HAXI_BRESP_ERR_IDCT_MSK BIT(6)
+#define B_BE_RXDMA_ERR_FLAG_IDCT_MSK BIT(5)
+#define B_BE_SET_FC_ERROR_FLAG_IDCT_MSK BIT(4)
+#define B_BE_TXBD_LEN0_ERR_IDCT_MSK BIT(3)
+#define B_BE_TXBD_4KBOUND_ERR_IDCT_MSK BIT(2)
+#define B_BE_RXMDA_STUCK_IDCT_MSK BIT(1)
+#define B_BE_TXMDA_STUCK_IDCT_MSK BIT(0)
+#define B_BE_HAXI_IDCT_MSK_CLR (B_BE_TXMDA_STUCK_IDCT_MSK | \
+ B_BE_RXMDA_STUCK_IDCT_MSK | \
+ B_BE_TXBD_LEN0_ERR_IDCT_MSK | \
+ B_BE_SET_FC_ERROR_FLAG_IDCT_MSK | \
+ B_BE_RXDMA_ERR_FLAG_IDCT_MSK | \
+ B_BE_HAXI_BRESP_ERR_IDCT_MSK | \
+ B_BE_HAXI_RRESP_ERR_IDCT_MSK)
+#define B_BE_HAXI_IDCT_MSK_SET (B_BE_TXMDA_STUCK_IDCT_MSK | \
+ B_BE_RXMDA_STUCK_IDCT_MSK | \
+ B_BE_TXBD_LEN0_ERR_IDCT_MSK | \
+ B_BE_SET_FC_ERROR_FLAG_IDCT_MSK | \
+ B_BE_RXDMA_ERR_FLAG_IDCT_MSK | \
+ B_BE_HAXI_BRESP_ERR_IDCT_MSK | \
+ B_BE_HAXI_RRESP_ERR_IDCT_MSK)
+
+#define R_BE_HAXI_IDCT 0xB0BC
+#define B_BE_HAXI_RRESP_ERR_IDCT BIT(7)
+#define B_BE_HAXI_BRESP_ERR_IDCT BIT(6)
+#define B_BE_RXDMA_ERR_FLAG_IDCT BIT(5)
+#define B_BE_SET_FC_ERROR_FLAG_IDCT BIT(4)
+#define B_BE__TXBD_LEN0_ERR_IDCT BIT(3)
+#define B_BE__TXBD_4KBOUND_ERR_IDCT BIT(2)
+#define B_BE_RXMDA_STUCK_IDCT BIT(1)
+#define B_BE_TXMDA_STUCK_IDCT BIT(0)
+
+#define R_BE_HCI_FC_CTRL 0xB700
+#define B_BE_WD_PAGE_MODE_MASK GENMASK(17, 16)
+#define B_BE_HCI_FC_CH14_FULL_COND_MASK GENMASK(15, 14)
+#define B_BE_HCI_FC_TWD_FULL_COND_MASK GENMASK(13, 12)
+#define B_BE_HCI_FC_CH12_FULL_COND_MASK GENMASK(11, 10)
+#define B_BE_HCI_FC_WP_CH811_FULL_COND_MASK GENMASK(9, 8)
+#define B_BE_HCI_FC_WP_CH07_FULL_COND_MASK GENMASK(7, 6)
+#define B_BE_HCI_FC_WD_FULL_COND_MASK GENMASK(5, 4)
+#define B_BE_HCI_FC_CH12_EN BIT(3)
+#define B_BE_HCI_FC_MODE_MASK GENMASK(2, 1)
+#define B_BE_HCI_FC_EN BIT(0)
+
+#define R_BE_CH_PAGE_CTRL 0xB704
+#define B_BE_PREC_PAGE_CH12_V1_MASK GENMASK(21, 16)
+#define B_BE_PREC_PAGE_CH011_V1_MASK GENMASK(5, 0)
+
+#define R_BE_PUB_PAGE_INFO3 0xB78C
+#define B_BE_G1_AVAL_PG_MASK GENMASK(28, 16)
+#define B_BE_G0_AVAL_PG_MASK GENMASK(12, 0)
+
+#define R_BE_PUB_PAGE_CTRL1 0xB790
+#define B_BE_PUBPG_G1_MASK GENMASK(28, 16)
+#define B_BE_PUBPG_G0_MASK GENMASK(12, 0)
+
+#define R_BE_PUB_PAGE_CTRL2 0xB794
+#define B_BE_PUBPG_ALL_MASK GENMASK(12, 0)
+
+#define R_BE_PUB_PAGE_INFO1 0xB79C
+#define B_BE_G1_USE_PG_MASK GENMASK(28, 16)
+#define B_BE_G0_USE_PG_MASK GENMASK(12, 0)
+
+#define R_BE_PUB_PAGE_INFO2 0xB7A0
+#define B_BE_PUB_AVAL_PG_MASK GENMASK(12, 0)
+
+#define R_BE_WP_PAGE_CTRL1 0xB7A4
+#define B_BE_PREC_PAGE_WP_CH811_MASK GENMASK(24, 16)
+#define B_BE_PREC_PAGE_WP_CH07_MASK GENMASK(8, 0)
+
+#define R_BE_WP_PAGE_CTRL2 0xB7A8
+#define B_BE_WP_THRD_MASK GENMASK(12, 0)
+
+#define R_BE_WP_PAGE_INFO1 0xB7AC
+#define B_BE_WP_AVAL_PG_MASK GENMASK(28, 16)
+
+#define R_BE_CMAC_SHARE_FUNC_EN 0x0E000
+#define B_BE_CMAC_SHARE_CRPRT BIT(31)
+#define B_BE_CMAC_SHARE_EN BIT(30)
+#define B_BE_FORCE_BTCOEX_REG_GCKEN BIT(24)
+#define B_BE_FORCE_CMAC_SHARE_COMMON_REG_GCKEN BIT(16)
+#define B_BE_FORCE_CMAC_SHARE_REG_GCKEN BIT(15)
+#define B_BE_RESPBA_EN BIT(2)
+#define B_BE_ADDRSRCH_EN BIT(1)
+#define B_BE_BTCOEX_EN BIT(0)
+
#define R_BE_CMAC_FUNC_EN 0x10000
#define R_BE_CMAC_FUNC_EN_C1 0x14000
#define B_BE_CMAC_CRPRT BIT(31)
@@ -4206,6 +5737,104 @@
B_BE_CMAC_CRPRT | B_BE_TXTIME_EN | B_BE_RESP_PKTCTL_EN | \
B_BE_SIGB_EN)
+#define R_BE_CK_EN 0x10004
+#define R_BE_CK_EN_C1 0x14004
+#define B_BE_CMAC_CKEN BIT(30)
+#define B_BE_BCN_P1_P4_CKEN BIT(15)
+#define B_BE_BCN_P0MB1_15_CKEN BIT(14)
+#define B_BE_TXTIME_CKEN BIT(8)
+#define B_BE_RESP_PKTCTL_CKEN BIT(7)
+#define B_BE_SIGB_CKEN BIT(6)
+#define B_BE_PHYINTF_CKEN BIT(5)
+#define B_BE_CMAC_DMA_CKEN BIT(4)
+#define B_BE_PTCLTOP_CKEN BIT(3)
+#define B_BE_SCHEDULER_CKEN BIT(2)
+#define B_BE_TMAC_CKEN BIT(1)
+#define B_BE_RMAC_CKEN BIT(0)
+#define B_BE_CK_EN_SET (B_BE_CMAC_CKEN | B_BE_PHYINTF_CKEN | B_BE_CMAC_DMA_CKEN | \
+ B_BE_PTCLTOP_CKEN | B_BE_SCHEDULER_CKEN | B_BE_TMAC_CKEN | \
+ B_BE_RMAC_CKEN | B_BE_TXTIME_CKEN | B_BE_RESP_PKTCTL_CKEN | \
+ B_BE_SIGB_CKEN)
+
+#define R_BE_CMAC_ERR_IMR 0x10160
+#define R_BE_CMAC_ERR_IMR_C1 0x14160
+#define B_BE_CMAC_FW_ERR_IDCT_EN BIT(16)
+#define B_BE_PTCL_TX_IDLETO_IDCT_EN BIT(9)
+#define B_BE_WMAC_RX_IDLETO_IDCT_EN BIT(8)
+#define B_BE_WMAC_TX_ERR_IND_EN BIT(7)
+#define B_BE_WMAC_RX_ERR_IND_EN BIT(6)
+#define B_BE_TXPWR_CTRL_ERR_IND_EN BIT(5)
+#define B_BE_PHYINTF_ERR_IND_EN BIT(4)
+#define B_BE_DMA_TOP_ERR_IND_EN BIT(3)
+#define B_BE_RESP_PKTCTL_ERR_IND_EN BIT(2)
+#define B_BE_PTCL_TOP_ERR_IND_EN BIT(1)
+#define B_BE_SCHEDULE_TOP_ERR_IND_EN BIT(0)
+
+#define R_BE_CMAC_ERR_ISR 0x10164
+#define R_BE_CMAC_ERR_ISR_C1 0x14164
+#define B_BE_CMAC_FW_ERR_IDCT BIT(16)
+#define B_BE_PTCL_TX_IDLETO_IDCT BIT(9)
+#define B_BE_WMAC_RX_IDLETO_IDCT BIT(8)
+#define B_BE_WMAC_TX_ERR_IND BIT(7)
+#define B_BE_WMAC_RX_ERR_IND BIT(6)
+#define B_BE_TXPWR_CTRL_ERR_IND BIT(5)
+#define B_BE_PHYINTF_ERR_IND BIT(4)
+#define B_BE_DMA_TOP_ERR_IND BIT(3)
+#define B_BE_RESP_PKTCTL_ERR_IDCT BIT(2)
+#define B_BE_PTCL_TOP_ERR_IND BIT(1)
+#define B_BE_SCHEDULE_TOP_ERR_IND BIT(0)
+
+#define R_BE_SER_L0_DBG_CNT 0x10170
+#define R_BE_SER_L0_DBG_CNT_C1 0x14170
+#define B_BE_SER_L0_PHYINTF_CNT_MASK GENMASK(31, 24)
+#define B_BE_SER_L0_DMA_CNT_MASK GENMASK(23, 16)
+#define B_BE_SER_L0_PTCL_CNT_MASK GENMASK(15, 8)
+#define B_BE_SER_L0_SCH_CNT_MASK GENMASK(7, 0)
+
+#define R_BE_SER_L0_DBG_CNT1 0x10174
+#define R_BE_SER_L0_DBG_CNT1_C1 0x14174
+#define B_BE_SER_L0_TMAC_COUNTER_MASK GENMASK(23, 16)
+#define B_BE_SER_L0_RMAC_COUNTER_MASK GENMASK(15, 8)
+#define B_BE_SER_L0_TXPWR_COUNTER_MASK GENMASK(7, 0)
+
+#define R_BE_SER_L0_DBG_CNT2 0x10178
+#define R_BE_SER_L0_DBG_CNT2_C1 0x14178
+
+#define R_BE_SER_L0_DBG_CNT3 0x1017C
+#define R_BE_SER_L0_DBG_CNT3_C1 0x1417C
+#define B_BE_SER_L0_SUBMODULE_BIT31_CNT BIT(31)
+#define B_BE_SER_L0_SUBMODULE_BIT30_CNT BIT(30)
+#define B_BE_SER_L0_SUBMODULE_BIT29_CNT BIT(29)
+#define B_BE_SER_L0_SUBMODULE_BIT28_CNT BIT(28)
+#define B_BE_SER_L0_SUBMODULE_BIT27_CNT BIT(27)
+#define B_BE_SER_L0_SUBMODULE_BIT26_CNT BIT(26)
+#define B_BE_SER_L0_SUBMODULE_BIT25_CNT BIT(25)
+#define B_BE_SER_L0_SUBMODULE_BIT24_CNT BIT(24)
+#define B_BE_SER_L0_SUBMODULE_BIT23_CNT BIT(23)
+#define B_BE_SER_L0_SUBMODULE_BIT22_CNT BIT(22)
+#define B_BE_SER_L0_SUBMODULE_BIT21_CNT BIT(21)
+#define B_BE_SER_L0_SUBMODULE_BIT20_CNT BIT(20)
+#define B_BE_SER_L0_SUBMODULE_BIT19_CNT BIT(19)
+#define B_BE_SER_L0_SUBMODULE_BIT18_CNT BIT(18)
+#define B_BE_SER_L0_SUBMODULE_BIT17_CNT BIT(17)
+#define B_BE_SER_L0_SUBMODULE_BIT16_CNT BIT(16)
+#define B_BE_SER_L0_SUBMODULE_BIT15_CNT BIT(15)
+#define B_BE_SER_L0_SUBMODULE_BIT14_CNT BIT(14)
+#define B_BE_SER_L0_SUBMODULE_BIT13_CNT BIT(13)
+#define B_BE_SER_L0_SUBMODULE_BIT12_CNT BIT(12)
+#define B_BE_SER_L0_SUBMODULE_BIT11_CNT BIT(11)
+#define B_BE_SER_L0_SUBMODULE_BIT10_CNT BIT(10)
+#define B_BE_SER_L0_SUBMODULE_BIT9_CNT BIT(9)
+#define B_BE_SER_L0_SUBMODULE_BIT8_CNT BIT(8)
+#define B_BE_SER_L0_SUBMODULE_BIT7_CNT BIT(7)
+#define B_BE_SER_L0_SUBMODULE_BIT6_CNT BIT(6)
+#define B_BE_SER_L0_SUBMODULE_BIT5_CNT BIT(5)
+#define B_BE_SER_L0_SUBMODULE_BIT4_CNT BIT(4)
+#define B_BE_SER_L0_SUBMODULE_BIT3_CNT BIT(3)
+#define B_BE_SER_L0_SUBMODULE_BIT2_CNT BIT(2)
+#define B_BE_SER_L0_SUBMODULE_BIT1_CNT BIT(1)
+#define B_BE_SER_L0_SUBMODULE_BIT0_CNT BIT(0)
+
#define R_BE_PORT_0_TSF_SYNC 0x102A0
#define R_BE_PORT_0_TSF_SYNC_C1 0x142A0
#define B_BE_P0_SYNC_NOW_P BIT(30)
@@ -4226,6 +5855,17 @@
#define B_BE_SET_MUEDCATIMER_TF_0 BIT(4)
#define B_BE_MUEDCA_EN_0 BIT(0)
+#define R_BE_SCHEDULE_ERR_IMR 0x103E8
+#define R_BE_SCHEDULE_ERR_IMR_C1 0x143E8
+#define B_BE_FSM_TIMEOUT_ERR_INT_EN BIT(0)
+#define B_BE_SCHEDULE_ERR_IMR_CLR B_BE_FSM_TIMEOUT_ERR_INT_EN
+#define B_BE_SCHEDULE_ERR_IMR_SET B_BE_FSM_TIMEOUT_ERR_INT_EN
+
+#define R_BE_SCHEDULE_ERR_ISR 0x103EC
+#define R_BE_SCHEDULE_ERR_ISR_C1 0x143EC
+#define B_BE_SORT_NON_IDLE_ERR_INT BIT(1)
+#define B_BE_FSM_TIMEOUT_ERR_INT BIT(0)
+
#define R_BE_PORT_CFG_P0 0x10400
#define R_BE_PORT_CFG_P0_C1 0x14400
#define B_BE_BCN_ERLY_SORT_EN_P0 BIT(18)
@@ -4364,6 +6004,348 @@
#define R_BE_PTCL_BSS_COLOR_1_C1 0x148A4
#define B_BE_BSS_COLOB_BE_PORT_4_MASK GENMASK(5, 0)
+#define R_BE_PTCL_IMR_2 0x108B8
+#define R_BE_PTCL_IMR_2_C1 0x148B8
+#define B_BE_NO_TRX_TIMEOUT_IMR BIT(1)
+#define B_BE_TX_IDLE_TIMEOUT_IMR BIT(0)
+#define B_BE_PTCL_IMR_2_CLR B_BE_TX_IDLE_TIMEOUT_IMR
+#define B_BE_PTCL_IMR_2_SET 0
+
+#define R_BE_PTCL_IMR0 0x108C0
+#define R_BE_PTCL_IMR0_C1 0x148C0
+#define B_BE_PTCL_ERROR_FLAG_IMR BIT(31)
+#define B_BE_FSM1_TIMEOUT_ERR_INT_EN BIT(1)
+#define B_BE_FSM_TIMEOUT_ERR_INT_EN BIT(0)
+#define B_BE_PTCL_IMR0_CLR (B_BE_FSM_TIMEOUT_ERR_INT_EN | \
+ B_BE_FSM1_TIMEOUT_ERR_INT_EN | \
+ B_BE_PTCL_ERROR_FLAG_IMR)
+#define B_BE_PTCL_IMR0_SET (B_BE_FSM_TIMEOUT_ERR_INT_EN | \
+ B_BE_FSM1_TIMEOUT_ERR_INT_EN | \
+ B_BE_PTCL_ERROR_FLAG_IMR)
+
+#define R_BE_PTCL_ISR0 0x108C4
+#define R_BE_PTCL_ISR0_C1 0x148C4
+#define B_BE_PTCL_ERROR_FLAG_ISR BIT(31)
+#define B_BE_FSM1_TIMEOUT_ERR BIT(1)
+#define B_BE_FSM_TIMEOUT_ERR BIT(0)
+
+#define R_BE_PTCL_IMR1 0x108C8
+#define R_BE_PTCL_IMR1_C1 0x148C8
+#define B_BE_F2PCMD_PKTID_IMR BIT(30)
+#define B_BE_F2PCMD_RD_PKTID_IMR BIT(29)
+#define B_BE_F2PCMD_ASSIGN_PKTID_IMR BIT(28)
+#define B_BE_F2PCMD_USER_ALLC_IMR BIT(27)
+#define B_BE_RX_SPF_U0_PKTID_IMR BIT(26)
+#define B_BE_TX_SPF_U1_PKTID_IMR BIT(25)
+#define B_BE_TX_SPF_U2_PKTID_IMR BIT(24)
+#define B_BE_TX_SPF_U3_PKTID_IMR BIT(23)
+#define B_BE_TX_RECORD_PKTID_IMR BIT(22)
+#define B_BE_TWTSP_QSEL_IMR BIT(14)
+#define B_BE_F2P_RLS_CTN_SEL_IMR BIT(13)
+#define B_BE_BCNQ_ORDER_IMR BIT(12)
+#define B_BE_Q_PKTID_IMR BIT(11)
+#define B_BE_D_PKTID_IMR BIT(10)
+#define B_BE_TXPRT_FULL_DROP_IMR BIT(9)
+#define B_BE_F2PCMDRPT_FULL_DROP_IMR BIT(8)
+#define B_BE_PTCL_IMR1_CLR (B_BE_F2PCMDRPT_FULL_DROP_IMR | \
+ B_BE_TXPRT_FULL_DROP_IMR | \
+ B_BE_D_PKTID_IMR | \
+ B_BE_Q_PKTID_IMR | \
+ B_BE_BCNQ_ORDER_IMR | \
+ B_BE_F2P_RLS_CTN_SEL_IMR | \
+ B_BE_TWTSP_QSEL_IMR | \
+ B_BE_TX_RECORD_PKTID_IMR | \
+ B_BE_TX_SPF_U3_PKTID_IMR | \
+ B_BE_TX_SPF_U2_PKTID_IMR | \
+ B_BE_TX_SPF_U1_PKTID_IMR | \
+ B_BE_RX_SPF_U0_PKTID_IMR | \
+ B_BE_F2PCMD_USER_ALLC_IMR | \
+ B_BE_F2PCMD_ASSIGN_PKTID_IMR | \
+ B_BE_F2PCMD_RD_PKTID_IMR | \
+ B_BE_F2PCMD_PKTID_IMR)
+#define B_BE_PTCL_IMR1_SET B_BE_F2PCMD_USER_ALLC_IMR
+
+#define R_BE_PTCL_ISR1 0x108CC
+#define R_BE_PTCL_ISR1_C1 0x148CC
+#define B_BE_F2PCMD_PKTID_ERR BIT(30)
+#define B_BE_F2PCMD_RD_PKTID_ERR BIT(29)
+#define B_BE_F2PCMD_ASSIGN_PKTID_ERR BIT(28)
+#define B_BE_F2PCMD_USER_ALLC_ERR BIT(27)
+#define B_BE_RX_SPF_U0_PKTID_ERR BIT(26)
+#define B_BE_TX_SPF_U1_PKTID_ERR BIT(25)
+#define B_BE_TX_SPF_U2_PKTID_ERR BIT(24)
+#define B_BE_TX_SPF_U3_PKTID_ERR BIT(23)
+#define B_BE_TX_RECORD_PKTID_ERR BIT(22)
+#define B_BE_TWTSP_QSEL_ERR BIT(14)
+#define B_BE_F2P_RLS_CTN_SEL_ERR BIT(13)
+#define B_BE_BCNQ_ORDER_ERR BIT(12)
+#define B_BE_Q_PKTID_ERR BIT(11)
+#define B_BE_D_PKTID_ERR BIT(10)
+#define B_BE_TXPRT_FULL_DROP_ERR BIT(9)
+#define B_BE_F2PCMDRPT_FULL_DROP_ERR BIT(8)
+
+#define R_BE_RX_ERROR_FLAG 0x10C00
+#define R_BE_RX_ERROR_FLAG_C1 0x14C00
+#define B_BE_RX_CSI_NOT_RELEASE_ERROR BIT(31)
+#define B_BE_RX_GET_NULL_PKT_ERROR BIT(30)
+#define B_BE_RX_RU0_FSM_HANG_ERROR BIT(29)
+#define B_BE_RX_RU1_FSM_HANG_ERROR BIT(28)
+#define B_BE_RX_RU2_FSM_HANG_ERROR BIT(27)
+#define B_BE_RX_RU3_FSM_HANG_ERROR BIT(26)
+#define B_BE_RX_RU4_FSM_HANG_ERROR BIT(25)
+#define B_BE_RX_RU5_FSM_HANG_ERROR BIT(24)
+#define B_BE_RX_RU6_FSM_HANG_ERROR BIT(23)
+#define B_BE_RX_RU7_FSM_HANG_ERROR BIT(22)
+#define B_BE_RX_RXSTS_FSM_HANG_ERROR BIT(21)
+#define B_BE_RX_CSI_FSM_HANG_ERROR BIT(20)
+#define B_BE_RX_TXRPT_FSM_HANG_ERROR BIT(19)
+#define B_BE_RX_F2PCMD_FSM_HANG_ERROR BIT(18)
+#define B_BE_RX_RU0_ZERO_LENGTH_ERROR BIT(17)
+#define B_BE_RX_RU1_ZERO_LENGTH_ERROR BIT(16)
+#define B_BE_RX_RU2_ZERO_LENGTH_ERROR BIT(15)
+#define B_BE_RX_RU3_ZERO_LENGTH_ERROR BIT(14)
+#define B_BE_RX_RU4_ZERO_LENGTH_ERROR BIT(13)
+#define B_BE_RX_RU5_ZERO_LENGTH_ERROR BIT(12)
+#define B_BE_RX_RU6_ZERO_LENGTH_ERROR BIT(11)
+#define B_BE_RX_RU7_ZERO_LENGTH_ERROR BIT(10)
+#define B_BE_RX_RXSTS_ZERO_LENGTH_ERROR BIT(9)
+#define B_BE_RX_CSI_ZERO_LENGTH_ERROR BIT(8)
+#define B_BE_PLE_DATA_OPT_FSM_HANG BIT(7)
+#define B_BE_PLE_RXDATA_REQUEST_BUFFER_FSM_HANG BIT(6)
+#define B_BE_PLE_TXRPT_REQUEST_BUFFER_FSM_HANG BIT(5)
+#define B_BE_PLE_WD_OPT_FSM_HANG BIT(4)
+#define B_BE_PLE_ENQ_FSM_HANG BIT(3)
+#define B_BE_RXDATA_ENQUE_ORDER_ERROR BIT(2)
+#define B_BE_RXSTS_ENQUE_ORDER_ERROR BIT(1)
+#define B_BE_RX_CSI_PKT_NUM_ERROR BIT(0)
+
+#define R_BE_RX_ERROR_FLAG_IMR 0x10C04
+#define R_BE_RX_ERROR_FLAG_IMR_C1 0x14C04
+#define B_BE_RX_CSI_NOT_RELEASE_ERROR_IMR BIT(31)
+#define B_BE_RX_GET_NULL_PKT_ERROR_IMR BIT(30)
+#define B_BE_RX_RU0_FSM_HANG_ERROR_IMR BIT(29)
+#define B_BE_RX_RU1_FSM_HANG_ERROR_IMR BIT(28)
+#define B_BE_RX_RU2_FSM_HANG_ERROR_IMR BIT(27)
+#define B_BE_RX_RU3_FSM_HANG_ERROR_IMR BIT(26)
+#define B_BE_RX_RU4_FSM_HANG_ERROR_IMR BIT(25)
+#define B_BE_RX_RU5_FSM_HANG_ERROR_IMR BIT(24)
+#define B_BE_RX_RU6_FSM_HANG_ERROR_IMR BIT(23)
+#define B_BE_RX_RU7_FSM_HANG_ERROR_IMR BIT(22)
+#define B_BE_RX_RXSTS_FSM_HANG_ERROR_IMR BIT(21)
+#define B_BE_RX_CSI_FSM_HANG_ERROR_IMR BIT(20)
+#define B_BE_RX_TXRPT_FSM_HANG_ERROR_IMR BIT(19)
+#define B_BE_RX_F2PCMD_FSM_HANG_ERROR_IMR BIT(18)
+#define B_BE_RX_RU0_ZERO_LENGTH_ERROR_IMR BIT(17)
+#define B_BE_RX_RU1_ZERO_LENGTH_ERROR_IMR BIT(16)
+#define B_BE_RX_RU2_ZERO_LENGTH_ERROR_IMR BIT(15)
+#define B_BE_RX_RU3_ZERO_LENGTH_ERROR_IMR BIT(14)
+#define B_BE_RX_RU4_ZERO_LENGTH_ERROR_IMR BIT(13)
+#define B_BE_RX_RU5_ZERO_LENGTH_ERROR_IMR BIT(12)
+#define B_BE_RX_RU6_ZERO_LENGTH_ERROR_IMR BIT(11)
+#define B_BE_RX_RU7_ZERO_LENGTH_ERROR_IMR BIT(10)
+#define B_BE_RX_RXSTS_ZERO_LENGTH_ERROR_IMR BIT(9)
+#define B_BE_RX_CSI_ZERO_LENGTH_ERROR_IMR BIT(8)
+#define B_BE_PLE_DATA_OPT_FSM_HANG_IMR BIT(7)
+#define B_BE_PLE_RXDATA_REQUEST_BUFFER_FSM_HANG_IMR BIT(6)
+#define B_BE_PLE_TXRPT_REQUEST_BUFFER_FSM_HANG_IMR BIT(5)
+#define B_BE_PLE_WD_OPT_FSM_HANG_IMR BIT(4)
+#define B_BE_PLE_ENQ_FSM_HANG_IMR BIT(3)
+#define B_BE_RXDATA_ENQUE_ORDER_ERROR_IMR BIT(2)
+#define B_BE_RXSTS_ENQUE_ORDER_ERROR_IMR BIT(1)
+#define B_BE_RX_CSI_PKT_NUM_ERROR_IMR BIT(0)
+#define B_BE_RX_ERROR_FLAG_IMR_CLR (B_BE_RX_RXSTS_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU7_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU6_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU5_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU4_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU3_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU2_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU1_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU0_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_F2PCMD_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_TXRPT_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_CSI_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RXSTS_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU7_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU6_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU5_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU4_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU3_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU2_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU1_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU0_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_GET_NULL_PKT_ERROR_IMR)
+#define B_BE_RX_ERROR_FLAG_IMR_SET (B_BE_RX_RXSTS_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU7_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU6_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU5_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU4_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU3_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU2_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU1_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU0_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_F2PCMD_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_TXRPT_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_CSI_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RXSTS_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU7_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU6_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU5_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU4_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU3_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU2_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU1_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU0_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_GET_NULL_PKT_ERROR_IMR)
+
+#define R_BE_TX_ERROR_FLAG 0x10C6C
+#define R_BE_TX_ERROR_FLAG_C1 0x14C6C
+#define B_BE_TX_RU0_FSM_HANG_ERROR BIT(31)
+#define B_BE_TX_RU1_FSM_HANG_ERROR BIT(30)
+#define B_BE_TX_RU2_FSM_HANG_ERROR BIT(29)
+#define B_BE_TX_RU3_FSM_HANG_ERROR BIT(28)
+#define B_BE_TX_RU4_FSM_HANG_ERROR BIT(27)
+#define B_BE_TX_RU5_FSM_HANG_ERROR BIT(26)
+#define B_BE_TX_RU6_FSM_HANG_ERROR BIT(25)
+#define B_BE_TX_RU7_FSM_HANG_ERROR BIT(24)
+#define B_BE_TX_RU8_FSM_HANG_ERROR BIT(23)
+#define B_BE_TX_RU9_FSM_HANG_ERROR BIT(22)
+#define B_BE_TX_RU10_FSM_HANG_ERROR BIT(21)
+#define B_BE_TX_RU11_FSM_HANG_ERROR BIT(20)
+#define B_BE_TX_RU12_FSM_HANG_ERROR BIT(19)
+#define B_BE_TX_RU13_FSM_HANG_ERROR BIT(18)
+#define B_BE_TX_RU14_FSM_HANG_ERROR BIT(17)
+#define B_BE_TX_RU15_FSM_HANG_ERROR BIT(16)
+#define B_BE_TX_CSI_FSM_HANG_ERROR BIT(15)
+#define B_BE_TX_WD_PLD_ID_FSM_HANG_ERROR BIT(14)
+
+#define R_BE_TX_ERROR_FLAG_IMR 0x10C70
+#define R_BE_TX_ERROR_FLAG_IMR_C1 0x14C70
+#define B_BE_TX_RU0_FSM_HANG_ERROR_IMR BIT(31)
+#define B_BE_TX_RU1_FSM_HANG_ERROR_IMR BIT(30)
+#define B_BE_TX_RU2_FSM_HANG_ERROR_IMR BIT(29)
+#define B_BE_TX_RU3_FSM_HANG_ERROR_IMR BIT(28)
+#define B_BE_TX_RU4_FSM_HANG_ERROR_IMR BIT(27)
+#define B_BE_TX_RU5_FSM_HANG_ERROR_IMR BIT(26)
+#define B_BE_TX_RU6_FSM_HANG_ERROR_IMR BIT(25)
+#define B_BE_TX_RU7_FSM_HANG_ERROR_IMR BIT(24)
+#define B_BE_TX_RU8_FSM_HANG_ERROR_IMR BIT(23)
+#define B_BE_TX_RU9_FSM_HANG_ERROR_IMR BIT(22)
+#define B_BE_TX_RU10_FSM_HANG_ERROR_IMR BIT(21)
+#define B_BE_TX_RU11_FSM_HANG_ERROR_IMR BIT(20)
+#define B_BE_TX_RU12_FSM_HANG_ERROR_IMR BIT(19)
+#define B_BE_TX_RU13_FSM_HANG_ERROR_IMR BIT(18)
+#define B_BE_TX_RU14_FSM_HANG_ERROR_IMR BIT(17)
+#define B_BE_TX_RU15_FSM_HANG_ERROR_IMR BIT(16)
+#define B_BE_TX_CSI_FSM_HANG_ERROR_IMR BIT(15)
+#define B_BE_TX_WD_PLD_ID_FSM_HANG_ERROR_IMR BIT(14)
+#define B_BE_TX_ERROR_FLAG_IMR_CLR (B_BE_TX_WD_PLD_ID_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_CSI_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU15_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU14_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU13_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU12_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU11_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU10_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU9_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU8_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU7_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU6_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU5_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU4_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU3_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU2_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU1_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU0_FSM_HANG_ERROR_IMR)
+#define B_BE_TX_ERROR_FLAG_IMR_SET (B_BE_TX_WD_PLD_ID_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_CSI_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU15_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU14_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU13_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU12_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU11_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU10_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU9_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU8_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU7_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU6_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU5_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU4_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU3_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU2_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU1_FSM_HANG_ERROR_IMR | \
+ B_BE_TX_RU0_FSM_HANG_ERROR_IMR)
+
+#define R_BE_RX_ERROR_FLAG_1 0x10C84
+#define R_BE_RX_ERROR_FLAG_1_C1 0x14C84
+#define B_BE_RX_RU8_FSM_HANG_ERROR BIT(29)
+#define B_BE_RX_RU9_FSM_HANG_ERROR BIT(28)
+#define B_BE_RX_RU10_FSM_HANG_ERROR BIT(27)
+#define B_BE_RX_RU11_FSM_HANG_ERROR BIT(26)
+#define B_BE_RX_RU12_FSM_HANG_ERROR BIT(25)
+#define B_BE_RX_RU13_FSM_HANG_ERROR BIT(24)
+#define B_BE_RX_RU14_FSM_HANG_ERROR BIT(23)
+#define B_BE_RX_RU15_FSM_HANG_ERROR BIT(22)
+#define B_BE_RX_RU8_ZERO_LENGTH_ERROR BIT(17)
+#define B_BE_RX_RU9_ZERO_LENGTH_ERROR BIT(16)
+#define B_BE_RX_RU10_ZERO_LENGTH_ERROR BIT(15)
+#define B_BE_RX_RU11_ZERO_LENGTH_ERROR BIT(14)
+#define B_BE_RX_RU12_ZERO_LENGTH_ERROR BIT(13)
+#define B_BE_RX_RU13_ZERO_LENGTH_ERROR BIT(12)
+#define B_BE_RX_RU14_ZERO_LENGTH_ERROR BIT(11)
+#define B_BE_RX_RU15_ZERO_LENGTH_ERROR BIT(10)
+
+#define R_BE_RX_ERROR_FLAG_IMR_1 0x10C88
+#define R_BE_RX_ERROR_FLAG_IMR_1_C1 0x14C88
+#define B_BE_RX_RU8_FSM_HANG_ERROR_IMR BIT(29)
+#define B_BE_RX_RU9_FSM_HANG_ERROR_IMR BIT(28)
+#define B_BE_RX_RU10_FSM_HANG_ERROR_IMR BIT(27)
+#define B_BE_RX_RU11_FSM_HANG_ERROR_IMR BIT(26)
+#define B_BE_RX_RU12_FSM_HANG_ERROR_IMR BIT(25)
+#define B_BE_RX_RU13_FSM_HANG_ERROR_IMR BIT(24)
+#define B_BE_RX_RU14_FSM_HANG_ERROR_IMR BIT(23)
+#define B_BE_RX_RU15_FSM_HANG_ERROR_IMR BIT(22)
+#define B_BE_RX_RU8_ZERO_LENGTH_ERROR_IMR BIT(17)
+#define B_BE_RX_RU9_ZERO_LENGTH_ERROR_IMR BIT(16)
+#define B_BE_RX_RU10_ZERO_LENGTH_ERROR_IMR BIT(15)
+#define B_BE_RX_RU11_ZERO_LENGTH_ERROR_IMR BIT(14)
+#define B_BE_RX_RU12_ZERO_LENGTH_ERROR_IMR BIT(13)
+#define B_BE_RX_RU13_ZERO_LENGTH_ERROR_IMR BIT(12)
+#define B_BE_RX_RU14_ZERO_LENGTH_ERROR_IMR BIT(11)
+#define B_BE_RX_RU15_ZERO_LENGTH_ERROR_IMR BIT(10)
+#define B_BE_TX_ERROR_FLAG_IMR_1_CLR (B_BE_RX_RU8_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU9_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU10_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU11_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU12_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU13_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU14_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU15_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU8_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU9_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU10_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU11_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU12_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU13_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU14_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU15_ZERO_LENGTH_ERROR_IMR)
+#define B_BE_TX_ERROR_FLAG_IMR_1_SET (B_BE_RX_RU8_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU9_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU10_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU11_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU12_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU13_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU14_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU15_FSM_HANG_ERROR_IMR | \
+ B_BE_RX_RU8_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU9_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU10_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU11_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU12_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU13_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU14_ZERO_LENGTH_ERROR_IMR | \
+ B_BE_RX_RU15_ZERO_LENGTH_ERROR_IMR)
+
#define R_BE_WMTX_MOREDATA_TSFT_STMP_CTL 0x10E08
#define R_BE_WMTX_MOREDATA_TSFT_STMP_CTL_C1 0x14E08
#define B_BE_TSFT_OFS_MASK GENMASK(31, 16)
@@ -4371,6 +6353,124 @@
#define B_BE_UPD_HGQMD BIT(1)
#define B_BE_UPD_TIMIE BIT(0)
+#define R_BE_RSP_CHK_SIG 0x11000
+#define R_BE_RSP_CHK_SIG_C1 0x15000
+#define B_BE_RSP_STATIC_RTS_CHK_SERV_BW_EN BIT(30)
+#define B_BE_RSP_TBPPDU_CHK_PWR BIT(29)
+#define B_BE_RESP_PAIR_MACID_LEN_EN BIT(25)
+#define B_BE_RESP_TX_ABORT_TEST_EN BIT(24)
+#define B_BE_RESP_ER_SU_RU106_EN BIT(23)
+#define B_BE_RESP_ER_SU_EN BIT(22)
+#define B_BE_TXDATA_END_PS_OPT BIT(18)
+#define B_BE_CHECK_SOUNDING_SEQ BIT(17)
+#define B_BE_RXBA_IGNOREA2 BIT(16)
+#define B_BE_ACKTO_CCK_MASK GENMASK(15, 8)
+#define B_BE_ACKTO_MASK GENMASK(8, 0)
+
+#define R_BE_TRXPTCL_RESP_0 0x11004
+#define R_BE_TRXPTCL_RESP_0_C1 0x15004
+#define B_BE_WMAC_RESP_STBC_EN BIT(31)
+#define B_BE_WMAC_RXFTM_TXACK_SB BIT(30)
+#define B_BE_WMAC_RXFTM_TXACKBWEQ BIT(29)
+#define B_BE_RESP_TB_CHK_TXTIME BIT(24)
+#define B_BE_RSP_CHK_CCA BIT(23)
+#define B_BE_WMAC_LDPC_EN BIT(22)
+#define B_BE_WMAC_SGIEN BIT(21)
+#define B_BE_WMAC_SPLCPEN BIT(20)
+#define B_BE_RESP_EHT_MCS15_REF BIT(19)
+#define B_BE_RESP_EHT_MCS14_REF BIT(18)
+#define B_BE_WMAC_BESP_EARLY_TXBA BIT(17)
+#define B_BE_WMAC_MBA_DUR_FORCE BIT(16)
+#define B_BE_WMAC_SPEC_SIFS_OFDM_MASK GENMASK(15, 8)
+#define WMAC_SPEC_SIFS_OFDM_1115E 0x11
+#define B_BE_WMAC_SPEC_SIFS_CCK_MASK GENMASK(7, 0)
+
+#define R_BE_TRXPTCL_ERROR_INDICA_MASK 0x110BC
+#define R_BE_TRXPTCL_ERROR_INDICA_MASK_C1 0x150BC
+#define B_BE_WMAC_FTM_TIMEOUT_MODE BIT(30)
+#define B_BE_WMAC_FTM_TIMEOUT_THR_MASK GENMASK(29, 24)
+#define B_BE_WMAC_MODE BIT(22)
+#define B_BE_WMAC_TIMETOUT_THR_MASK GENMASK(21, 16)
+#define B_BE_RMAC_BFMER BIT(9)
+#define B_BE_RMAC_FTM BIT(8)
+#define B_BE_RMAC_CSI BIT(7)
+#define B_BE_TMAC_MIMO_CTRL BIT(6)
+#define B_BE_TMAC_RXTB BIT(5)
+#define B_BE_TMAC_HWSIGB_GEN BIT(4)
+#define B_BE_TMAC_TXPLCP BIT(3)
+#define B_BE_TMAC_RESP BIT(2)
+#define B_BE_TMAC_TXCTL BIT(1)
+#define B_BE_TMAC_MACTX BIT(0)
+#define B_BE_TRXPTCL_ERROR_INDICA_MASK_CLR (B_BE_TMAC_MACTX | \
+ B_BE_TMAC_TXCTL | \
+ B_BE_TMAC_RESP | \
+ B_BE_TMAC_TXPLCP | \
+ B_BE_TMAC_HWSIGB_GEN | \
+ B_BE_TMAC_RXTB | \
+ B_BE_TMAC_MIMO_CTRL | \
+ B_BE_RMAC_CSI | \
+ B_BE_RMAC_FTM | \
+ B_BE_RMAC_BFMER)
+#define B_BE_TRXPTCL_ERROR_INDICA_MASK_SET (B_BE_TMAC_MACTX | \
+ B_BE_TMAC_TXCTL | \
+ B_BE_TMAC_RESP | \
+ B_BE_TMAC_TXPLCP | \
+ B_BE_TMAC_HWSIGB_GEN | \
+ B_BE_TMAC_RXTB | \
+ B_BE_TMAC_MIMO_CTRL | \
+ B_BE_RMAC_CSI | \
+ B_BE_RMAC_FTM | \
+ B_BE_RMAC_BFMER)
+
+#define R_BE_TRXPTCL_ERROR_INDICA 0x110C0
+#define R_BE_TRXPTCL_ERROR_INDICA_C1 0x150C0
+#define B_BE_BFMER_ERR_FLAG BIT(9)
+#define B_BE_FTM_ERROR_FLAG_CLR BIT(8)
+#define B_BE_CSI_ERROR_FLAG_CLR BIT(7)
+#define B_BE_MIMOCTRL_ERROR_FLAG_CLR BIT(6)
+#define B_BE_RXTB_ERROR_FLAG_CLR BIT(5)
+#define B_BE_HWSIGB_GEN_ERROR_FLAG_CLR BIT(4)
+#define B_BE_TXPLCP_ERROR_FLAG_CLR BIT(3)
+#define B_BE_RESP_ERROR_FLAG_CLR BIT(2)
+#define B_BE_TXCTL_ERROR_FLAG_CLR BIT(1)
+#define B_BE_MACTX_ERROR_FLAG_CLR BIT(0)
+
+#define R_BE_DBGSEL_TRXPTCL 0x110F4
+#define R_BE_DBGSEL_TRXPTCL_C1 0x150F4
+#define B_BE_WMAC_CHNSTS_STATE_MASK GENMASK(19, 16)
+#define B_BE_DBGSEL_TRIGCMD_SEL_MASK GENMASK(11, 8)
+#define B_BE_DBGSEL_TRXPTCL_MASK GENMASK(7, 0)
+
+#define R_BE_PHYINFO_ERR_IMR_V1 0x110F8
+#define R_BE_PHYINFO_ERR_IMR_V1_C1 0x150F8
+#define B_BE_PHYINTF_RXTB_WIDTH_MASK GENMASK(31, 30)
+#define B_BE_PHYINTF_RXTB_EN_PHASE_MASK GENMASK(29, 28)
+#define B_BE_PHYINTF_MIMO_WIDTH_MASK GENMASK(27, 26)
+#define B_BE_PHYINTF_MIMO_EN_PHASE_MASK GENMASK(25, 24)
+#define B_BE_PHYINTF_TIMEOUT_THR_V1_MASK GENMASK(21, 16)
+#define B_BE_CSI_ON_TIMEOUT_EN BIT(5)
+#define B_BE_STS_ON_TIMEOUT_EN BIT(4)
+#define B_BE_DATA_ON_TIMEOUT_EN BIT(3)
+#define B_BE_OFDM_CCA_TIMEOUT_EN BIT(2)
+#define B_BE_CCK_CCA_TIMEOUT_EN BIT(1)
+#define B_BE_PHY_TXON_TIMEOUT_EN BIT(0)
+#define B_BE_PHYINFO_ERR_IMR_V1_CLR (B_BE_PHY_TXON_TIMEOUT_EN | \
+ B_BE_CCK_CCA_TIMEOUT_EN | \
+ B_BE_OFDM_CCA_TIMEOUT_EN | \
+ B_BE_DATA_ON_TIMEOUT_EN | \
+ B_BE_STS_ON_TIMEOUT_EN | \
+ B_BE_CSI_ON_TIMEOUT_EN)
+#define B_BE_PHYINFO_ERR_IMR_V1_SET 0
+
+#define R_BE_PHYINFO_ERR_ISR 0x110FC
+#define R_BE_PHYINFO_ERR_ISR_C1 0x150FC
+#define B_BE_CSI_ON_TIMEOUT_ERR BIT(5)
+#define B_BE_STS_ON_TIMEOUT_ERR BIT(4)
+#define B_BE_DATA_ON_TIMEOUT_ERR BIT(3)
+#define B_BE_OFDM_CCA_TIMEOUT_ERR BIT(2)
+#define B_BE_CCK_CCA_TIMEOUT_ERR BIT(1)
+#define B_BE_PHY_TXON_TIMEOUT_ERR BIT(0)
+
#define R_BE_BFMEE_RESP_OPTION 0x11180
#define R_BE_BFMEE_RESP_OPTION_C1 0x15180
#define B_BE_BFMEE_CSI_SEC_TYPE_SH 20
@@ -4451,6 +6551,90 @@
#define B_BE_CSIPRT_HESU_AID_EN BIT(25)
#define B_BE_CSIPRT_VHTSU_AID_EN BIT(24)
+#define R_BE_RX_ERR_ISR 0x114F4
+#define R_BE_RX_ERR_ISR_C1 0x154F4
+#define B_BE_RX_ERR_TRIG_ACT_TO BIT(9)
+#define B_BE_RX_ERR_STS_ACT_TO BIT(8)
+#define B_BE_RX_ERR_CSI_ACT_TO BIT(7)
+#define B_BE_RX_ERR_ACT_TO BIT(6)
+#define B_BE_CSI_DATAON_ASSERT_TO BIT(5)
+#define B_BE_DATAON_ASSERT_TO BIT(4)
+#define B_BE_CCA_ASSERT_TO BIT(3)
+#define B_BE_RX_ERR_DMA_TO BIT(2)
+#define B_BE_RX_ERR_DATA_TO BIT(1)
+#define B_BE_RX_ERR_CCA_TO BIT(0)
+
+#define R_BE_RX_ERR_IMR 0x114F8
+#define R_BE_RX_ERR_IMR_C1 0x154F8
+#define B_BE_RX_ERR_TRIG_ACT_TO_MSK BIT(9)
+#define B_BE_RX_ERR_STS_ACT_TO_MSK BIT(8)
+#define B_BE_RX_ERR_CSI_ACT_TO_MSK BIT(7)
+#define B_BE_RX_ERR_ACT_TO_MSK BIT(6)
+#define B_BE_CSI_DATAON_ASSERT_TO_MSK BIT(5)
+#define B_BE_DATAON_ASSERT_TO_MSK BIT(4)
+#define B_BE_CCA_ASSERT_TO_MSK BIT(3)
+#define B_BE_RX_ERR_DMA_TO_MSK BIT(2)
+#define B_BE_RX_ERR_DATA_TO_MSK BIT(1)
+#define B_BE_RX_ERR_CCA_TO_MSK BIT(0)
+#define B_BE_RX_ERR_IMR_CLR (B_BE_RX_ERR_CCA_TO_MSK | \
+ B_BE_RX_ERR_DATA_TO_MSK | \
+ B_BE_RX_ERR_DMA_TO_MSK | \
+ B_BE_CCA_ASSERT_TO_MSK | \
+ B_BE_DATAON_ASSERT_TO_MSK | \
+ B_BE_CSI_DATAON_ASSERT_TO_MSK | \
+ B_BE_RX_ERR_ACT_TO_MSK | \
+ B_BE_RX_ERR_CSI_ACT_TO_MSK | \
+ B_BE_RX_ERR_STS_ACT_TO_MSK | \
+ B_BE_RX_ERR_TRIG_ACT_TO_MSK)
+#define B_BE_RX_ERR_IMR_SET (B_BE_RX_ERR_ACT_TO_MSK | \
+ B_BE_RX_ERR_STS_ACT_TO_MSK | \
+ B_BE_RX_ERR_TRIG_ACT_TO_MSK)
+
+#define R_BE_RESP_IMR 0x11884
+#define R_BE_RESP_IMR_C1 0x15884
+#define B_BE_RESP_TBL_FLAG_ERR_ISR_EN BIT(17)
+#define B_BE_RESP_SEC_DOUBLE_HIT_ERR_ISR_EN BIT(16)
+#define B_BE_RESP_WRPTR_CROSS_ERR_ISR_EN BIT(15)
+#define B_BE_RESP_TOO_MANY_PLD_ERR_ISR_EN BIT(14)
+#define B_BE_RESP_TXDMA_READ_DATA_ERR_ISR_EN BIT(13)
+#define B_BE_RESP_PLDID_RDY_ERR_ISR_EN BIT(12)
+#define B_BE_RESP_RX_OVERWRITE_ERR_ISR_EN BIT(11)
+#define B_BE_RESP_RXDMA_WRPTR_INVLD_ERR_ISR_EN BIT(10)
+#define B_BE_RESP_RXDMA_REQ_INVLD_ERR_ISR_EN BIT(9)
+#define B_BE_RESP_RXDMA_REQ_MACID_ERR_ISR_EN BIT(8)
+#define B_BE_RESP_TXCMD_TX_ST_ABORT_ERR_ISR_EN BIT(6)
+#define B_BE_RESP_TXCMD_DMAC_PROC_ERR_ISR_EN BIT(5)
+#define B_BE_RESP_TXCMD_TBL_ERR_ISR_EN BIT(4)
+#define B_BE_RESP_INITCMD_RX_ST_ABORT_ERR_ISR_EN BIT(3)
+#define B_BE_RESP_INITCMD_RESERVD_PAGE_ABORT_ERR_ISR_EN BIT(2)
+#define B_BE_RESP_INITCMD_TX_ST_ABORT_ERR_ISR_EN BIT(1)
+#define B_BE_RESP_DMAC_PROC_ERR_ISR_EN BIT(0)
+#define B_BE_RESP_IMR_CLR (B_BE_RESP_DMAC_PROC_ERR_ISR_EN | \
+ B_BE_RESP_INITCMD_TX_ST_ABORT_ERR_ISR_EN | \
+ B_BE_RESP_INITCMD_RX_ST_ABORT_ERR_ISR_EN | \
+ B_BE_RESP_TXCMD_TBL_ERR_ISR_EN | \
+ B_BE_RESP_TXCMD_DMAC_PROC_ERR_ISR_EN | \
+ B_BE_RESP_TXCMD_TX_ST_ABORT_ERR_ISR_EN | \
+ B_BE_RESP_RXDMA_REQ_MACID_ERR_ISR_EN | \
+ B_BE_RESP_RXDMA_REQ_INVLD_ERR_ISR_EN | \
+ B_BE_RESP_RXDMA_WRPTR_INVLD_ERR_ISR_EN | \
+ B_BE_RESP_RX_OVERWRITE_ERR_ISR_EN | \
+ B_BE_RESP_PLDID_RDY_ERR_ISR_EN | \
+ B_BE_RESP_TXDMA_READ_DATA_ERR_ISR_EN | \
+ B_BE_RESP_TOO_MANY_PLD_ERR_ISR_EN | \
+ B_BE_RESP_WRPTR_CROSS_ERR_ISR_EN | \
+ B_BE_RESP_SEC_DOUBLE_HIT_ERR_ISR_EN)
+#define B_BE_RESP_IMR_SET (B_BE_RESP_DMAC_PROC_ERR_ISR_EN | \
+ B_BE_RESP_INITCMD_TX_ST_ABORT_ERR_ISR_EN | \
+ B_BE_RESP_INITCMD_RX_ST_ABORT_ERR_ISR_EN | \
+ B_BE_RESP_TXCMD_TBL_ERR_ISR_EN | \
+ B_BE_RESP_TXCMD_DMAC_PROC_ERR_ISR_EN | \
+ B_BE_RESP_TXCMD_TX_ST_ABORT_ERR_ISR_EN | \
+ B_BE_RESP_RX_OVERWRITE_ERR_ISR_EN | \
+ B_BE_RESP_PLDID_RDY_ERR_ISR_EN | \
+ B_BE_RESP_WRPTR_CROSS_ERR_ISR_EN | \
+ B_BE_RESP_SEC_DOUBLE_HIT_ERR_ISR_EN)
+
#define R_BE_PWR_MODULE 0x11900
#define R_BE_PWR_MODULE_C1 0x15900
@@ -4462,6 +6646,17 @@
#define R_BE_PWR_RU_LMT 0x12048
#define R_BE_PWR_RU_LMT_MAX 0x120E4
+#define R_BE_C0_TXPWR_IMR 0x128E0
+#define R_BE_C0_TXPWR_IMR_C1 0x168E0
+#define B_BE_FSM_TIMEOUT_ERR_INT_EN BIT(0)
+#define B_BE_C0_TXPWR_IMR_CLR B_BE_FSM_TIMEOUT_ERR_INT_EN
+#define B_BE_C0_TXPWR_IMR_SET B_BE_FSM_TIMEOUT_ERR_INT_EN
+
+#define R_BE_TXPWR_ERR_FLAG 0x128E4
+#define R_BE_TXPWR_ERR_IMR 0x128E0
+#define R_BE_TXPWR_ERR_FLAG_C1 0x158E4
+#define R_BE_TXPWR_ERR_IMR_C1 0x158E0
+
#define CMAC1_START_ADDR_BE 0x14000
#define CMAC1_END_ADDR_BE 0x17FFF
@@ -4727,6 +6922,11 @@
#define B_P0_RSTB_WATCH_DOG BIT(0)
#define B_P1_RSTB_WATCH_DOG BIT(1)
#define B_UPD_P0_EN BIT(31)
+#define R_SPOOF_CG 0x00B4
+#define B_SPOOF_CG_EN BIT(17)
+#define R_DFS_FFT_CG 0x00B8
+#define B_DFS_CG_EN BIT(1)
+#define B_DFS_FFT_EN BIT(0)
#define R_ANAPAR_PW15 0x030C
#define B_ANAPAR_PW15 GENMASK(31, 24)
#define B_ANAPAR_PW15_H GENMASK(27, 24)
@@ -4789,6 +6989,8 @@
#define R_PHY_STS_BITMAP_HT 0x076C
#define R_PHY_STS_BITMAP_VHT 0x0770
#define R_PHY_STS_BITMAP_HE 0x0774
+#define R_EDCCA_RPTREG_SEL_BE 0x078C
+#define B_EDCCA_RPTREG_SEL_BE_MSK GENMASK(22, 20)
#define R_PMAC_GNT 0x0980
#define B_PMAC_GNT_TXEN BIT(0)
#define B_PMAC_GNT_RXEN BIT(16)
@@ -4848,12 +7050,18 @@
#define B_IOQ_IQK_DPK_EN BIT(1)
#define R_GNT_BT_WGT_EN 0x0C6C
#define B_GNT_BT_WGT_EN BIT(21)
+#define R_TX_COLLISION_T2R_ST 0x0C70
+#define B_TX_COLLISION_T2R_ST_M GENMASK(25, 20)
+#define R_TXGATING 0x0C74
+#define B_TXGATING_EN BIT(4)
#define R_PD_ARBITER_OFF 0x0C80
#define B_PD_ARBITER_OFF BIT(31)
#define R_SNDCCA_A1 0x0C9C
#define B_SNDCCA_A1_EN GENMASK(19, 12)
#define R_SNDCCA_A2 0x0CA0
#define B_SNDCCA_A2_VAL GENMASK(19, 12)
+#define R_TX_COLLISION_T2R_ST_BE 0x0CC8
+#define B_TX_COLLISION_T2R_ST_BE_M GENMASK(13, 8)
#define R_RXHT_MCS_LIMIT 0x0D18
#define B_RXHT_MCS_LIMIT GENMASK(9, 8)
#define R_RXVHT_MCS_LIMIT 0x0D18
@@ -4872,6 +7080,10 @@
#define R_BRK_ASYNC_RST_EN_1 0x0DC0
#define R_BRK_ASYNC_RST_EN_2 0x0DC4
#define R_BRK_ASYNC_RST_EN_3 0x0DC8
+#define R_CTLTOP 0x1008
+#define B_CTLTOP_ON BIT(23)
+#define B_CTLTOP_VAL GENMASK(15, 12)
+#define R_EDCCA_RPT_SEL_BE 0x10CC
#define R_S0_HW_SI_DIS 0x1200
#define B_S0_HW_SI_DIS_W_R_TRIG GENMASK(30, 28)
#define R_P0_RXCK 0x12A0
@@ -4903,6 +7115,14 @@
#define R_CFO_COMP_SEG0_H 0x1388
#define R_CFO_COMP_SEG0_CTRL 0x138C
#define R_DBG32_D 0x1730
+#define R_EDCCA_RPT_A 0x1738
+#define R_EDCCA_RPT_B 0x173c
+#define B_EDCCA_RPT_B_FB BIT(7)
+#define B_EDCCA_RPT_B_P20 BIT(6)
+#define B_EDCCA_RPT_B_S20 BIT(5)
+#define B_EDCCA_RPT_B_S40 BIT(4)
+#define B_EDCCA_RPT_B_S80 BIT(3)
+#define B_EDCCA_RPT_B_PATH_MASK GENMASK(2, 1)
#define R_SWSI_V1 0x174C
#define B_SWSI_W_BUSY_V1 BIT(24)
#define B_SWSI_R_BUSY_V1 BIT(25)
@@ -4964,6 +7184,8 @@
#define R_S0_ADDCK 0x1E00
#define B_S0_ADDCK_I GENMASK(9, 0)
#define B_S0_ADDCK_Q GENMASK(19, 10)
+#define R_EDCCA_RPT_SEL 0x20CC
+#define B_EDCCA_RPT_SEL_MSK GENMASK(2, 0)
#define R_ADC_FIFO 0x20fc
#define B_ADC_FIFO_RST GENMASK(31, 24)
#define B_ADC_FIFO_RXK GENMASK(31, 16)
@@ -5010,6 +7232,8 @@
#define B_DBCC_80P80_SEL_EVM_RPT2_EN BIT(0)
#define R_P1_EN_SOUND_WO_NDP 0x2D7C
#define B_P1_EN_SOUND_WO_NDP BIT(1)
+#define R_EDCCA_RPT_A_BE 0x2E38
+#define R_EDCCA_RPT_B_BE 0x2E3C
#define R_S1_HW_SI_DIS 0x3200
#define B_S1_HW_SI_DIS_W_R_TRIG GENMASK(30, 28)
#define R_P1_RXCK 0x32A0
@@ -5218,9 +7442,9 @@
#define R_SEG0R_PD_V2 0x6A74
#define R_SEG0R_EDCCA_LVL 0x4840
#define R_SEG0R_EDCCA_LVL_V1 0x4884
-#define B_SEG0R_PPDU_LVL_MSK GENMASK(31, 24)
-#define B_SEG0R_EDCCA_LVL_P_MSK GENMASK(15, 8)
-#define B_SEG0R_EDCCA_LVL_A_MSK GENMASK(7, 0)
+#define B_EDCCA_LVL_MSK3 GENMASK(31, 24)
+#define B_EDCCA_LVL_MSK1 GENMASK(15, 8)
+#define B_EDCCA_LVL_MSK0 GENMASK(7, 0)
#define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1 BIT(30)
#define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK BIT(29)
#define B_SEG0R_PD_LOWER_BOUND_MSK GENMASK(10, 6)
@@ -5476,6 +7700,10 @@
#define B_DCFO_WEIGHT_MSK_V1 GENMASK(31, 28)
#define R_DCFO_OPT_V1 0x6260
#define B_DCFO_OPT_EN_V1 BIT(17)
+#define R_SEG0R_EDCCA_LVL_BE 0x69EC
+#define R_SEG0R_PPDU_LVL_BE 0x69F0
+#define R_SEGSND 0x6A14
+#define B_SEGSND_EN BIT(31)
#define R_RPL_BIAS_COMP1 0x6DF0
#define B_RPL_BIAS_COMP1_MASK GENMASK(7, 0)
#define R_P1_TSSI_ALIM1 0x7630
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index dd15b904cd2f..5c167a9278ce 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -205,6 +205,20 @@ static const struct rtw89_dig_regs rtw8851b_dig_regs = {
B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
};
+static const struct rtw89_edcca_regs rtw8851b_edcca_regs = {
+ .edcca_level = R_SEG0R_EDCCA_LVL_V1,
+ .edcca_mask = B_EDCCA_LVL_MSK0,
+ .edcca_p_mask = B_EDCCA_LVL_MSK1,
+ .ppdu_level = R_SEG0R_EDCCA_LVL_V1,
+ .ppdu_mask = B_EDCCA_LVL_MSK3,
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
+ .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
+};
+
static const struct rtw89_btc_rf_trx_para rtw89_btc_8851b_rf_ul[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
@@ -2360,8 +2374,8 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.rsvd_ple_ofst = 0x2f800,
.hfc_param_ini = rtw8851b_hfc_param_ini_pcie,
.dle_mem = rtw8851b_dle_mem_pcie,
- .wde_qempty_acq_num = 4,
- .wde_qempty_mgq_sel = 4,
+ .wde_qempty_acq_grpnum = 4,
+ .wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
@@ -2440,13 +2454,15 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.dcfo_comp = &rtw8851b_dcfo_comp,
.dcfo_comp_sft = 12,
.imr_info = &rtw8851b_imr_info,
+ .imr_dmac_table = NULL,
+ .imr_cmac_table = NULL,
.rrsr_cfgs = &rtw8851b_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0},
.bss_clr_map_reg = R_BSS_CLR_MAP_V1,
.dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) |
BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) |
BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI),
- .edcca_lvl_reg = R_SEG0R_EDCCA_LVL_V1,
+ .edcca_regs = &rtw8851b_edcca_regs,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8851b,
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 2bddd0acb195..0c76c52ce22c 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -498,6 +498,20 @@ static const struct rtw89_dig_regs rtw8852a_dig_regs = {
B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
};
+static const struct rtw89_edcca_regs rtw8852a_edcca_regs = {
+ .edcca_level = R_SEG0R_EDCCA_LVL,
+ .edcca_mask = B_EDCCA_LVL_MSK0,
+ .edcca_p_mask = B_EDCCA_LVL_MSK1,
+ .ppdu_level = R_SEG0R_EDCCA_LVL,
+ .ppdu_mask = B_EDCCA_LVL_MSK3,
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
+ .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
+};
+
static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse,
struct rtw8852a_efuse *map)
{
@@ -2095,8 +2109,8 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.rsvd_ple_ofst = 0x6f800,
.hfc_param_ini = rtw8852a_hfc_param_ini_pcie,
.dle_mem = rtw8852a_dle_mem_pcie,
- .wde_qempty_acq_num = 16,
- .wde_qempty_mgq_sel = 16,
+ .wde_qempty_acq_grpnum = 16,
+ .wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xc000, 0xd000},
.pwr_on_seq = pwr_on_seq_8852a,
.pwr_off_seq = pwr_off_seq_8852a,
@@ -2177,11 +2191,13 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.dcfo_comp = &rtw8852a_dcfo_comp,
.dcfo_comp_sft = 10,
.imr_info = &rtw8852a_imr_info,
+ .imr_dmac_table = NULL,
+ .imr_cmac_table = NULL,
.rrsr_cfgs = &rtw8852a_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0},
.bss_clr_map_reg = R_BSS_CLR_MAP,
.dma_ch_mask = 0,
- .edcca_lvl_reg = R_SEG0R_EDCCA_LVL,
+ .edcca_regs = &rtw8852a_edcca_regs,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8852a,
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index a576e4f47880..de887a35f3fb 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -330,6 +330,20 @@ static const struct rtw89_dig_regs rtw8852b_dig_regs = {
B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
};
+static const struct rtw89_edcca_regs rtw8852b_edcca_regs = {
+ .edcca_level = R_SEG0R_EDCCA_LVL_V1,
+ .edcca_mask = B_EDCCA_LVL_MSK0,
+ .edcca_p_mask = B_EDCCA_LVL_MSK1,
+ .ppdu_level = R_SEG0R_EDCCA_LVL_V1,
+ .ppdu_mask = B_EDCCA_LVL_MSK3,
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
+ .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
+};
+
static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_ul[] = {
{255, 0, 0, 7}, /* 0 -> original */
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
@@ -2529,8 +2543,8 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.rsvd_ple_ofst = 0x2f800,
.hfc_param_ini = rtw8852b_hfc_param_ini_pcie,
.dle_mem = rtw8852b_dle_mem_pcie,
- .wde_qempty_acq_num = 4,
- .wde_qempty_mgq_sel = 4,
+ .wde_qempty_acq_grpnum = 4,
+ .wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
@@ -2611,13 +2625,15 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.dcfo_comp = &rtw8852b_dcfo_comp,
.dcfo_comp_sft = 10,
.imr_info = &rtw8852b_imr_info,
+ .imr_dmac_table = NULL,
+ .imr_cmac_table = NULL,
.rrsr_cfgs = &rtw8852b_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0},
.bss_clr_map_reg = R_BSS_CLR_MAP_V1,
.dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) |
BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) |
BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI),
- .edcca_lvl_reg = R_SEG0R_EDCCA_LVL_V1,
+ .edcca_regs = &rtw8852b_edcca_regs,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8852b,
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index ea152a4613f2..8618d0204f66 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -167,6 +167,20 @@ static const struct rtw89_dig_regs rtw8852c_dig_regs = {
B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
};
+static const struct rtw89_edcca_regs rtw8852c_edcca_regs = {
+ .edcca_level = R_SEG0R_EDCCA_LVL,
+ .edcca_mask = B_EDCCA_LVL_MSK0,
+ .edcca_p_mask = B_EDCCA_LVL_MSK1,
+ .ppdu_level = R_SEG0R_EDCCA_LVL,
+ .ppdu_mask = B_EDCCA_LVL_MSK3,
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
+ .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
+};
+
static void rtw8852c_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx);
@@ -2865,8 +2879,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.rsvd_ple_ofst = 0x6f800,
.hfc_param_ini = rtw8852c_hfc_param_ini_pcie,
.dle_mem = rtw8852c_dle_mem_pcie,
- .wde_qempty_acq_num = 16,
- .wde_qempty_mgq_sel = 16,
+ .wde_qempty_acq_grpnum = 16,
+ .wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xe000, 0xf000},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
@@ -2950,11 +2964,13 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.dcfo_comp = &rtw8852c_dcfo_comp,
.dcfo_comp_sft = 12,
.imr_info = &rtw8852c_imr_info,
+ .imr_dmac_table = NULL,
+ .imr_cmac_table = NULL,
.rrsr_cfgs = &rtw8852c_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0},
.bss_clr_map_reg = R_BSS_CLR_MAP,
.dma_ch_mask = 0,
- .edcca_lvl_reg = R_SEG0R_EDCCA_LVL,
+ .edcca_regs = &rtw8852c_edcca_regs,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8852c,
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index d190f095a5a8..0e7300cc6d9e 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -15,6 +15,110 @@
#define RTW8922A_MODULE_FIRMWARE \
RTW8922A_FW_BASENAME ".bin"
+static const struct rtw89_hfc_ch_cfg rtw8922a_hfc_chcfg_pcie[] = {
+ {2, 1641, grp_0}, /* ACH 0 */
+ {2, 1641, grp_0}, /* ACH 1 */
+ {2, 1641, grp_0}, /* ACH 2 */
+ {2, 1641, grp_0}, /* ACH 3 */
+ {2, 1641, grp_1}, /* ACH 4 */
+ {2, 1641, grp_1}, /* ACH 5 */
+ {2, 1641, grp_1}, /* ACH 6 */
+ {2, 1641, grp_1}, /* ACH 7 */
+ {2, 1641, grp_0}, /* B0MGQ */
+ {2, 1641, grp_0}, /* B0HIQ */
+ {2, 1641, grp_1}, /* B1MGQ */
+ {2, 1641, grp_1}, /* B1HIQ */
+ {0, 0, 0}, /* FWCMDQ */
+ {0, 0, 0}, /* BMC */
+ {0, 0, 0}, /* H2D */
+};
+
+static const struct rtw89_hfc_pub_cfg rtw8922a_hfc_pubcfg_pcie = {
+ 1651, /* Group 0 */
+ 1651, /* Group 1 */
+ 3302, /* Public Max */
+ 0, /* WP threshold */
+};
+
+static const struct rtw89_hfc_param_ini rtw8922a_hfc_param_ini_pcie[] = {
+ [RTW89_QTA_SCC] = {rtw8922a_hfc_chcfg_pcie, &rtw8922a_hfc_pubcfg_pcie,
+ &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH},
+ [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2,
+ RTW89_HCIFC_POH},
+ [RTW89_QTA_INVALID] = {NULL},
+};
+
+static const struct rtw89_dle_mem rtw8922a_dle_mem_pcie[] = {
+ [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size0_v1,
+ &rtw89_mac_size.ple_size0_v1, &rtw89_mac_size.wde_qt0_v1,
+ &rtw89_mac_size.wde_qt0_v1, &rtw89_mac_size.ple_qt0,
+ &rtw89_mac_size.ple_qt1, &rtw89_mac_size.ple_rsvd_qt0,
+ &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0},
+ [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4_v1,
+ &rtw89_mac_size.ple_size3_v1, &rtw89_mac_size.wde_qt4,
+ &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt9,
+ &rtw89_mac_size.ple_qt9, &rtw89_mac_size.ple_rsvd_qt1,
+ &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0},
+ [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
+ NULL},
+};
+
+static const struct rtw89_reg_imr rtw8922a_imr_dmac_regs[] = {
+ {R_BE_DISP_HOST_IMR, B_BE_DISP_HOST_IMR_CLR, B_BE_DISP_HOST_IMR_SET},
+ {R_BE_DISP_CPU_IMR, B_BE_DISP_CPU_IMR_CLR, B_BE_DISP_CPU_IMR_SET},
+ {R_BE_DISP_OTHER_IMR, B_BE_DISP_OTHER_IMR_CLR, B_BE_DISP_OTHER_IMR_SET},
+ {R_BE_PKTIN_ERR_IMR, B_BE_PKTIN_ERR_IMR_CLR, B_BE_PKTIN_ERR_IMR_SET},
+ {R_BE_INTERRUPT_MASK_REG, B_BE_INTERRUPT_MASK_REG_CLR, B_BE_INTERRUPT_MASK_REG_SET},
+ {R_BE_MLO_ERR_IDCT_IMR, B_BE_MLO_ERR_IDCT_IMR_CLR, B_BE_MLO_ERR_IDCT_IMR_SET},
+ {R_BE_MPDU_TX_ERR_IMR, B_BE_MPDU_TX_ERR_IMR_CLR, B_BE_MPDU_TX_ERR_IMR_SET},
+ {R_BE_MPDU_RX_ERR_IMR, B_BE_MPDU_RX_ERR_IMR_CLR, B_BE_MPDU_RX_ERR_IMR_SET},
+ {R_BE_SEC_ERROR_IMR, B_BE_SEC_ERROR_IMR_CLR, B_BE_SEC_ERROR_IMR_SET},
+ {R_BE_CPUIO_ERR_IMR, B_BE_CPUIO_ERR_IMR_CLR, B_BE_CPUIO_ERR_IMR_SET},
+ {R_BE_WDE_ERR_IMR, B_BE_WDE_ERR_IMR_CLR, B_BE_WDE_ERR_IMR_SET},
+ {R_BE_WDE_ERR1_IMR, B_BE_WDE_ERR1_IMR_CLR, B_BE_WDE_ERR1_IMR_SET},
+ {R_BE_PLE_ERR_IMR, B_BE_PLE_ERR_IMR_CLR, B_BE_PLE_ERR_IMR_SET},
+ {R_BE_PLE_ERRFLAG1_IMR, B_BE_PLE_ERRFLAG1_IMR_CLR, B_BE_PLE_ERRFLAG1_IMR_SET},
+ {R_BE_WDRLS_ERR_IMR, B_BE_WDRLS_ERR_IMR_CLR, B_BE_WDRLS_ERR_IMR_SET},
+ {R_BE_TXPKTCTL_B0_ERRFLAG_IMR, B_BE_TXPKTCTL_B0_ERRFLAG_IMR_CLR,
+ B_BE_TXPKTCTL_B0_ERRFLAG_IMR_SET},
+ {R_BE_TXPKTCTL_B1_ERRFLAG_IMR, B_BE_TXPKTCTL_B1_ERRFLAG_IMR_CLR,
+ B_BE_TXPKTCTL_B1_ERRFLAG_IMR_SET},
+ {R_BE_BBRPT_COM_ERR_IMR, B_BE_BBRPT_COM_ERR_IMR_CLR, B_BE_BBRPT_COM_ERR_IMR_SET},
+ {R_BE_BBRPT_CHINFO_ERR_IMR, B_BE_BBRPT_CHINFO_ERR_IMR_CLR,
+ B_BE_BBRPT_CHINFO_ERR_IMR_SET},
+ {R_BE_BBRPT_DFS_ERR_IMR, B_BE_BBRPT_DFS_ERR_IMR_CLR, B_BE_BBRPT_DFS_ERR_IMR_SET},
+ {R_BE_LA_ERRFLAG_IMR, B_BE_LA_ERRFLAG_IMR_CLR, B_BE_LA_ERRFLAG_IMR_SET},
+ {R_BE_CH_INFO_DBGFLAG_IMR, B_BE_CH_INFO_DBGFLAG_IMR_CLR, B_BE_CH_INFO_DBGFLAG_IMR_SET},
+ {R_BE_PLRLS_ERR_IMR, B_BE_PLRLS_ERR_IMR_CLR, B_BE_PLRLS_ERR_IMR_SET},
+ {R_BE_HAXI_IDCT_MSK, B_BE_HAXI_IDCT_MSK_CLR, B_BE_HAXI_IDCT_MSK_SET},
+};
+
+static const struct rtw89_imr_table rtw8922a_imr_dmac_table = {
+ .regs = rtw8922a_imr_dmac_regs,
+ .n_regs = ARRAY_SIZE(rtw8922a_imr_dmac_regs),
+};
+
+static const struct rtw89_reg_imr rtw8922a_imr_cmac_regs[] = {
+ {R_BE_RESP_IMR, B_BE_RESP_IMR_CLR, B_BE_RESP_IMR_SET},
+ {R_BE_RX_ERROR_FLAG_IMR, B_BE_RX_ERROR_FLAG_IMR_CLR, B_BE_RX_ERROR_FLAG_IMR_SET},
+ {R_BE_TX_ERROR_FLAG_IMR, B_BE_TX_ERROR_FLAG_IMR_CLR, B_BE_TX_ERROR_FLAG_IMR_SET},
+ {R_BE_RX_ERROR_FLAG_IMR_1, B_BE_TX_ERROR_FLAG_IMR_1_CLR, B_BE_TX_ERROR_FLAG_IMR_1_SET},
+ {R_BE_PTCL_IMR1, B_BE_PTCL_IMR1_CLR, B_BE_PTCL_IMR1_SET},
+ {R_BE_PTCL_IMR0, B_BE_PTCL_IMR0_CLR, B_BE_PTCL_IMR0_SET},
+ {R_BE_PTCL_IMR_2, B_BE_PTCL_IMR_2_CLR, B_BE_PTCL_IMR_2_SET},
+ {R_BE_SCHEDULE_ERR_IMR, B_BE_SCHEDULE_ERR_IMR_CLR, B_BE_SCHEDULE_ERR_IMR_SET},
+ {R_BE_C0_TXPWR_IMR, B_BE_C0_TXPWR_IMR_CLR, B_BE_C0_TXPWR_IMR_SET},
+ {R_BE_TRXPTCL_ERROR_INDICA_MASK, B_BE_TRXPTCL_ERROR_INDICA_MASK_CLR,
+ B_BE_TRXPTCL_ERROR_INDICA_MASK_SET},
+ {R_BE_RX_ERR_IMR, B_BE_RX_ERR_IMR_CLR, B_BE_RX_ERR_IMR_SET},
+ {R_BE_PHYINFO_ERR_IMR_V1, B_BE_PHYINFO_ERR_IMR_V1_CLR, B_BE_PHYINFO_ERR_IMR_V1_SET},
+};
+
+static const struct rtw89_imr_table rtw8922a_imr_cmac_table = {
+ .regs = rtw8922a_imr_cmac_regs,
+ .n_regs = ARRAY_SIZE(rtw8922a_imr_cmac_regs),
+};
+
static const struct rtw89_efuse_block_cfg rtw8922a_efuse_blocks[] = {
[RTW89_EFUSE_BLOCK_SYS] = {.offset = 0x00000, .size = 0x310},
[RTW89_EFUSE_BLOCK_RF] = {.offset = 0x10000, .size = 0x240},
@@ -26,6 +130,241 @@ static const struct rtw89_efuse_block_cfg rtw8922a_efuse_blocks[] = {
[RTW89_EFUSE_BLOCK_ADIE] = {.offset = 0x70000, .size = 0x10},
};
+static int rtw8922a_pwr_on_func(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u32 val32;
+ int ret;
+
+ rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_AFSM_WLSUS_EN |
+ B_BE_AFSM_PCIE_SUS_EN);
+ rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_DIS_WLBT_PDNSUSEN_SOPC);
+ rtw89_write32_set(rtwdev, R_BE_WLLPS_CTRL, B_BE_DIS_WLBT_LPSEN_LOPC);
+ rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APDM_HPDN);
+ rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS);
+
+ ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_RDY_SYSPWR,
+ 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON);
+ rtw89_write32_set(rtwdev, R_BE_WLRESUME_CTRL, B_BE_LPSROP_CMAC0 |
+ B_BE_LPSROP_CMAC1);
+ rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFN_ONMAC);
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFN_ONMAC),
+ 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_clr(rtwdev, R_BE_AFE_ON_CTRL1, B_BE_REG_CK_MON_CK960M_EN);
+ rtw89_write8_set(rtwdev, R_BE_ANAPAR_POW_MAC, B_BE_POW_PC_LDO_PORT0 |
+ B_BE_POW_PC_LDO_PORT1);
+ rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_R_SYM_ISO_ADDA_P02PP |
+ B_BE_R_SYM_ISO_ADDA_P12PP);
+ rtw89_write8_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_PLATFORM_EN);
+ rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN);
+
+ ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HAXIDMA_IO_ST,
+ 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
+ if (ret)
+ return ret;
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST),
+ 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
+
+ ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HCI_WLAN_IO_ST,
+ 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x02, 0x02);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x01, 0x01);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x40, 0x40);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x20, 0x20);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x04, 0x04);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x08, 0x08);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x10);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xEB, 0xFF);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xEB, 0xFF);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x01, 0x01);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x02, 0x02);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x80);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XREF_RF1, 0, 0x40);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XREF_RF2, 0, 0x40);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, 0x40, 0x60);
+ if (ret)
+ return ret;
+
+ if (hal->cv != CHIP_CAV) {
+ rtw89_write32_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
+ rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE);
+ rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B);
+
+ mdelay(1);
+
+ rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S);
+ rtw89_write32_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
+ }
+
+ rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN,
+ B_BE_MAC_FUNC_EN | B_BE_DMAC_FUNC_EN | B_BE_MPDU_PROC_EN |
+ B_BE_WD_RLS_EN | B_BE_DLE_WDE_EN | B_BE_TXPKT_CTRL_EN |
+ B_BE_STA_SCH_EN | B_BE_DLE_PLE_EN | B_BE_PKT_BUF_EN |
+ B_BE_DMAC_TBL_EN | B_BE_PKT_IN_EN | B_BE_DLE_CPUIO_EN |
+ B_BE_DISPATCHER_EN | B_BE_BBRPT_EN | B_BE_MAC_SEC_EN |
+ B_BE_H_AXIDMA_EN | B_BE_DMAC_MLO_EN | B_BE_PLRLS_EN |
+ B_BE_P_AXIDMA_EN | B_BE_DLE_DATACPUIO_EN | B_BE_LTR_CTL_EN);
+
+ set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
+
+ rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_FUNC_EN,
+ B_BE_CMAC_SHARE_EN | B_BE_RESPBA_EN | B_BE_ADDRSRCH_EN |
+ B_BE_BTCOEX_EN);
+ rtw89_write32_set(rtwdev, R_BE_CMAC_FUNC_EN,
+ B_BE_CMAC_EN | B_BE_CMAC_TXEN | B_BE_CMAC_RXEN |
+ B_BE_SIGB_EN | B_BE_PHYINTF_EN | B_BE_CMAC_DMA_EN |
+ B_BE_PTCLTOP_EN | B_BE_SCHEDULER_EN | B_BE_TMAC_EN |
+ B_BE_RMAC_EN | B_BE_TXTIME_EN | B_BE_RESP_PKTCTL_EN);
+
+ set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
+
+ rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
+ B_BE_FEN_BBPLAT_RSTB);
+
+ return 0;
+}
+
+static int rtw8922a_pwr_off_func(struct rtw89_dev *rtwdev)
+{
+ u32 val32;
+ int ret;
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x10, 0x10);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x08);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x04);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC6, 0xFF);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC6, 0xFF);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x80, 0x80);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x02);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x01);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x02, 0xFF);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x00, 0xFF);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_R_SYM_ISO_ADDA_P02PP |
+ B_BE_R_SYM_ISO_ADDA_P12PP);
+ rtw89_write8_clr(rtwdev, R_BE_ANAPAR_POW_MAC, B_BE_POW_PC_LDO_PORT0 |
+ B_BE_POW_PC_LDO_PORT1);
+ rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON);
+ rtw89_write8_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
+ B_BE_FEN_BBPLAT_RSTB);
+ rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x20);
+ if (ret)
+ return ret;
+
+ rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x40);
+ if (ret)
+ return ret;
+
+ rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN);
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_IO_ST),
+ 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
+ if (ret)
+ return ret;
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST),
+ 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HCI_WLAN_IO_ST),
+ 1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC);
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFM_OFFMAC),
+ 1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32(rtwdev, R_BE_WLLPS_CTRL, 0x0000A1B2);
+ rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_XTAL_OFF_A_DIE);
+ rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS);
+ rtw89_write32(rtwdev, R_BE_UDM1, 0);
+
+ return 0;
+}
+
static void rtw8922a_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
struct rtw8922a_efuse *map)
{
@@ -273,6 +612,8 @@ static const struct wiphy_wowlan_support rtw_wowlan_stub_8922a = {
static const struct rtw89_chip_ops rtw8922a_chip_ops = {
.read_efuse = rtw8922a_read_efuse,
.read_phycap = rtw8922a_read_phycap,
+ .pwr_on_func = rtw8922a_pwr_on_func,
+ .pwr_off_func = rtw8922a_pwr_off_func,
};
const struct rtw89_chip_info rtw8922a_chip_info = {
@@ -292,6 +633,10 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.max_amsdu_limit = 8000,
.dis_2g_40m_ul_ofdma = false,
.rsvd_ple_ofst = 0x8f800,
+ .hfc_param_ini = rtw8922a_hfc_param_ini_pcie,
+ .dle_mem = rtw8922a_dle_mem_pcie,
+ .wde_qempty_acq_grpnum = 4,
+ .wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
@@ -347,6 +692,8 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.dcfo_comp = NULL,
.dcfo_comp_sft = 0,
.imr_info = NULL,
+ .imr_dmac_table = &rtw8922a_imr_dmac_table,
+ .imr_cmac_table = &rtw8922a_imr_cmac_table,
.bss_clr_vld = {R_BSS_CLR_VLD_V2, B_BSS_CLR_VLD0_V2},
.bss_clr_map_reg = R_BSS_CLR_MAP_V2,
.dma_ch_mask = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c
index 1e4a79a3b814..99896d85d2f8 100644
--- a/drivers/net/wireless/realtek/rtw89/ser.c
+++ b/drivers/net/wireless/realtek/rtw89/ser.c
@@ -590,6 +590,14 @@ struct __fw_backtrace_info {
static_assert(RTW89_FW_BACKTRACE_INFO_SIZE ==
sizeof(struct __fw_backtrace_info));
+static u32 convert_addr_from_wcpu(u32 wcpu_addr)
+{
+ if (wcpu_addr < 0x30000000)
+ return wcpu_addr;
+
+ return wcpu_addr & GENMASK(28, 0);
+}
+
static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf,
const struct __fw_backtrace_entry *ent)
{
@@ -597,7 +605,7 @@ static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf,
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 filter_model_addr = mac->filter_model_addr;
u32 indir_access_addr = mac->indir_access_addr;
- u32 fwbt_addr = ent->wcpu_addr & RTW89_WCPU_BASE_MASK;
+ u32 fwbt_addr = convert_addr_from_wcpu(ent->wcpu_addr);
u32 fwbt_size = ent->size;
u32 fwbt_key = ent->key;
u32 i;
diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c
index 660bf2ece927..5c7ca36c09b6 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.c
+++ b/drivers/net/wireless/realtek/rtw89/wow.c
@@ -73,13 +73,14 @@ static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow)
static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
enum rtw89_mac_fwd_target fwd_target = enable ?
RTW89_FWD_DONT_CARE :
RTW89_FWD_TO_HOST;
- rtw89_mac_typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0);
- rtw89_mac_typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0);
- rtw89_mac_typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0);
+ mac->typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0);
+ mac->typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0);
+ mac->typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0);
}
static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/silabs/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c
index 1b6c158457b4..537caf9d914a 100644
--- a/drivers/net/wireless/silabs/wfx/sta.c
+++ b/drivers/net/wireless/silabs/wfx/sta.c
@@ -336,29 +336,38 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif)
return 0;
}
-static void wfx_set_mfp_ap(struct wfx_vif *wvif)
+static int wfx_set_mfp_ap(struct wfx_vif *wvif)
{
struct ieee80211_vif *vif = wvif_to_vif(wvif);
struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, vif, 0);
const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
- const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
- skb->len - ieoffset);
const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16);
const int pairwise_cipher_suite_size = 4 / sizeof(u16);
const int akm_suite_size = 4 / sizeof(u16);
+ const u16 *ptr;
- if (ptr) {
- ptr += pairwise_cipher_suite_count_offset;
- if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
- return;
- ptr += 1 + pairwise_cipher_suite_size * *ptr;
- if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
- return;
- ptr += 1 + akm_suite_size * *ptr;
- if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
- return;
- wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6));
- }
+ if (unlikely(!skb))
+ return -ENOMEM;
+
+ ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
+ skb->len - ieoffset);
+ if (unlikely(!ptr))
+ return -EINVAL;
+
+ ptr += pairwise_cipher_suite_count_offset;
+ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
+ return -EINVAL;
+
+ ptr += 1 + pairwise_cipher_suite_size * *ptr;
+ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
+ return -EINVAL;
+
+ ptr += 1 + akm_suite_size * *ptr;
+ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
+ return -EINVAL;
+
+ wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6));
+ return 0;
}
int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -376,8 +385,7 @@ int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
ret = wfx_hif_start(wvif, &vif->bss_conf, wvif->channel);
if (ret > 0)
return -EIO;
- wfx_set_mfp_ap(wvif);
- return ret;
+ return wfx_set_mfp_ap(wvif);
}
void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
diff --git a/drivers/platform/x86/amd/Kconfig b/drivers/platform/x86/amd/Kconfig
index 55f3a2fc6aec..54753213cc61 100644
--- a/drivers/platform/x86/amd/Kconfig
+++ b/drivers/platform/x86/amd/Kconfig
@@ -18,3 +18,17 @@ config AMD_HSMP
If you choose to compile this driver as a module the module will be
called amd_hsmp.
+
+config AMD_WBRF
+ bool "AMD Wifi RF Band mitigations (WBRF)"
+ depends on ACPI
+ help
+ WBRF(Wifi Band RFI mitigation) mechanism allows Wifi drivers
+ to notify the frequencies they are using so that other hardware
+ can be reconfigured to avoid harmonic conflicts.
+
+ AMD provides an ACPI based mechanism to support WBRF on platform with
+ appropriate underlying support.
+
+ This mechanism will only be activated on platforms that advertise a
+ need for it.
diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile
index f04932b7a7d1..dcec0a46f8af 100644
--- a/drivers/platform/x86/amd/Makefile
+++ b/drivers/platform/x86/amd/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_AMD_PMC) += pmc/
amd_hsmp-y := hsmp.o
obj-$(CONFIG_AMD_HSMP) += amd_hsmp.o
obj-$(CONFIG_AMD_PMF) += pmf/
+obj-$(CONFIG_AMD_WBRF) += wbrf.o
diff --git a/drivers/platform/x86/amd/wbrf.c b/drivers/platform/x86/amd/wbrf.c
new file mode 100644
index 000000000000..dd197b3aebe0
--- /dev/null
+++ b/drivers/platform/x86/amd/wbrf.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Wifi Frequency Band Manage Interface
+ * Copyright (C) 2023 Advanced Micro Devices
+ */
+
+#include <linux/acpi.h>
+#include <linux/acpi_amd_wbrf.h>
+
+/*
+ * Functions bit vector for WBRF method
+ *
+ * Bit 0: WBRF supported.
+ * Bit 1: Function 1 (Add / Remove frequency) is supported.
+ * Bit 2: Function 2 (Get frequency list) is supported.
+ */
+#define WBRF_ENABLED 0x0
+#define WBRF_RECORD 0x1
+#define WBRF_RETRIEVE 0x2
+
+#define WBRF_REVISION 0x1
+
+/*
+ * The data structure used for WBRF_RETRIEVE is not naturally aligned.
+ * And unfortunately the design has been settled down.
+ */
+struct amd_wbrf_ranges_out {
+ u32 num_of_ranges;
+ struct freq_band_range band_list[MAX_NUM_OF_WBRF_RANGES];
+} __packed;
+
+static const guid_t wifi_acpi_dsm_guid =
+ GUID_INIT(0x7b7656cf, 0xdc3d, 0x4c1c,
+ 0x83, 0xe9, 0x66, 0xe7, 0x21, 0xde, 0x30, 0x70);
+
+/*
+ * Used to notify consumer (amdgpu driver currently) about
+ * the wifi frequency is change.
+ */
+static BLOCKING_NOTIFIER_HEAD(wbrf_chain_head);
+
+static int wbrf_record(struct acpi_device *adev, uint8_t action, struct wbrf_ranges_in_out *in)
+{
+ union acpi_object argv4;
+ union acpi_object *tmp;
+ union acpi_object *obj;
+ u32 num_of_ranges = 0;
+ u32 num_of_elements;
+ u32 arg_idx = 0;
+ int ret;
+ u32 i;
+
+ if (!in)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(in->band_list); i++) {
+ if (in->band_list[i].start && in->band_list[i].end)
+ num_of_ranges++;
+ }
+
+ /*
+ * The num_of_ranges value in the "in" object supplied by
+ * the caller is required to be equal to the number of
+ * entries in the band_list array in there.
+ */
+ if (num_of_ranges != in->num_of_ranges)
+ return -EINVAL;
+
+ /*
+ * Every input frequency band comes with two end points(start/end)
+ * and each is accounted as an element. Meanwhile the range count
+ * and action type are accounted as an element each.
+ * So, the total element count = 2 * num_of_ranges + 1 + 1.
+ */
+ num_of_elements = 2 * num_of_ranges + 2;
+
+ tmp = kcalloc(num_of_elements, sizeof(*tmp), GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
+
+ argv4.package.type = ACPI_TYPE_PACKAGE;
+ argv4.package.count = num_of_elements;
+ argv4.package.elements = tmp;
+
+ /* save the number of ranges*/
+ tmp[0].integer.type = ACPI_TYPE_INTEGER;
+ tmp[0].integer.value = num_of_ranges;
+
+ /* save the action(WBRF_RECORD_ADD/REMOVE/RETRIEVE) */
+ tmp[1].integer.type = ACPI_TYPE_INTEGER;
+ tmp[1].integer.value = action;
+
+ arg_idx = 2;
+ for (i = 0; i < ARRAY_SIZE(in->band_list); i++) {
+ if (!in->band_list[i].start || !in->band_list[i].end)
+ continue;
+
+ tmp[arg_idx].integer.type = ACPI_TYPE_INTEGER;
+ tmp[arg_idx++].integer.value = in->band_list[i].start;
+ tmp[arg_idx].integer.type = ACPI_TYPE_INTEGER;
+ tmp[arg_idx++].integer.value = in->band_list[i].end;
+ }
+
+ obj = acpi_evaluate_dsm(adev->handle, &wifi_acpi_dsm_guid,
+ WBRF_REVISION, WBRF_RECORD, &argv4);
+
+ if (!obj)
+ return -EINVAL;
+
+ if (obj->type != ACPI_TYPE_INTEGER) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = obj->integer.value;
+ if (ret)
+ ret = -EINVAL;
+
+out:
+ ACPI_FREE(obj);
+ kfree(tmp);
+
+ return ret;
+}
+
+/**
+ * acpi_amd_wbrf_add_remove - add or remove the frequency band the device is using
+ *
+ * @dev: device pointer
+ * @action: remove or add the frequency band into bios
+ * @in: input structure containing the frequency band the device is using
+ *
+ * Broadcast to other consumers the frequency band the device starts
+ * to use. Underneath the surface the information is cached into an
+ * internal buffer first. Then a notification is sent to all those
+ * registered consumers. So then they can retrieve that buffer to
+ * know the latest active frequency bands. Consumers that haven't
+ * yet been registered can retrieve the information from the cache
+ * when they register.
+ *
+ * Return:
+ * 0 for success add/remove wifi frequency band.
+ * Returns a negative error code for failure.
+ */
+int acpi_amd_wbrf_add_remove(struct device *dev, uint8_t action, struct wbrf_ranges_in_out *in)
+{
+ struct acpi_device *adev;
+ int ret;
+
+ adev = ACPI_COMPANION(dev);
+ if (!adev)
+ return -ENODEV;
+
+ ret = wbrf_record(adev, action, in);
+ if (ret)
+ return ret;
+
+ blocking_notifier_call_chain(&wbrf_chain_head, WBRF_CHANGED, NULL);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_amd_wbrf_add_remove);
+
+/**
+ * acpi_amd_wbrf_supported_producer - determine if the WBRF can be enabled
+ * for the device as a producer
+ *
+ * @dev: device pointer
+ *
+ * Check if the platform equipped with necessary implementations to
+ * support WBRF for the device as a producer.
+ *
+ * Return:
+ * true if WBRF is supported, otherwise returns false
+ */
+bool acpi_amd_wbrf_supported_producer(struct device *dev)
+{
+ struct acpi_device *adev;
+
+ adev = ACPI_COMPANION(dev);
+ if (!adev)
+ return false;
+
+ return acpi_check_dsm(adev->handle, &wifi_acpi_dsm_guid,
+ WBRF_REVISION, BIT(WBRF_RECORD));
+}
+EXPORT_SYMBOL_GPL(acpi_amd_wbrf_supported_producer);
+
+/**
+ * acpi_amd_wbrf_supported_consumer - determine if the WBRF can be enabled
+ * for the device as a consumer
+ *
+ * @dev: device pointer
+ *
+ * Determine if the platform equipped with necessary implementations to
+ * support WBRF for the device as a consumer.
+ *
+ * Return:
+ * true if WBRF is supported, otherwise returns false.
+ */
+bool acpi_amd_wbrf_supported_consumer(struct device *dev)
+{
+ struct acpi_device *adev;
+
+ adev = ACPI_COMPANION(dev);
+ if (!adev)
+ return false;
+
+ return acpi_check_dsm(adev->handle, &wifi_acpi_dsm_guid,
+ WBRF_REVISION, BIT(WBRF_RETRIEVE));
+}
+EXPORT_SYMBOL_GPL(acpi_amd_wbrf_supported_consumer);
+
+/**
+ * amd_wbrf_retrieve_freq_band - retrieve current active frequency bands
+ *
+ * @dev: device pointer
+ * @out: output structure containing all the active frequency bands
+ *
+ * Retrieve the current active frequency bands which were broadcasted
+ * by other producers. The consumer who calls this API should take
+ * proper actions if any of the frequency band may cause RFI with its
+ * own frequency band used.
+ *
+ * Return:
+ * 0 for getting wifi freq band successfully.
+ * Returns a negative error code for failure.
+ */
+int amd_wbrf_retrieve_freq_band(struct device *dev, struct wbrf_ranges_in_out *out)
+{
+ struct amd_wbrf_ranges_out acpi_out = {0};
+ struct acpi_device *adev;
+ union acpi_object *obj;
+ union acpi_object param;
+ int ret = 0;
+
+ adev = ACPI_COMPANION(dev);
+ if (!adev)
+ return -ENODEV;
+
+ param.type = ACPI_TYPE_STRING;
+ param.string.length = 0;
+ param.string.pointer = NULL;
+
+ obj = acpi_evaluate_dsm(adev->handle, &wifi_acpi_dsm_guid,
+ WBRF_REVISION, WBRF_RETRIEVE, &param);
+ if (!obj)
+ return -EINVAL;
+
+ /*
+ * The return buffer is with variable length and the format below:
+ * number_of_entries(1 DWORD): Number of entries
+ * start_freq of 1st entry(1 QWORD): Start frequency of the 1st entry
+ * end_freq of 1st entry(1 QWORD): End frequency of the 1st entry
+ * ...
+ * ...
+ * start_freq of the last entry(1 QWORD)
+ * end_freq of the last entry(1 QWORD)
+ *
+ * Thus the buffer length is determined by the number of entries.
+ * - For zero entry scenario, the buffer length will be 4 bytes.
+ * - For one entry scenario, the buffer length will be 20 bytes.
+ */
+ if (obj->buffer.length > sizeof(acpi_out) || obj->buffer.length < 4) {
+ dev_err(dev, "Wrong sized WBRT information");
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(&acpi_out, obj->buffer.pointer, obj->buffer.length);
+
+ out->num_of_ranges = acpi_out.num_of_ranges;
+ memcpy(out->band_list, acpi_out.band_list, sizeof(acpi_out.band_list));
+
+out:
+ ACPI_FREE(obj);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(amd_wbrf_retrieve_freq_band);
+
+/**
+ * amd_wbrf_register_notifier - register for notifications of frequency
+ * band update
+ *
+ * @nb: driver notifier block
+ *
+ * The consumer should register itself via this API so that it can get
+ * notified on the frequency band updates from other producers.
+ *
+ * Return:
+ * 0 for registering a consumer driver successfully.
+ * Returns a negative error code for failure.
+ */
+int amd_wbrf_register_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&wbrf_chain_head, nb);
+}
+EXPORT_SYMBOL_GPL(amd_wbrf_register_notifier);
+
+/**
+ * amd_wbrf_unregister_notifier - unregister for notifications of
+ * frequency band update
+ *
+ * @nb: driver notifier block
+ *
+ * The consumer should call this API when it is longer interested with
+ * the frequency band updates from other producers. Usually, this should
+ * be performed during driver cleanup.
+ *
+ * Return:
+ * 0 for unregistering a consumer driver.
+ * Returns a negative error code for failure.
+ */
+int amd_wbrf_unregister_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&wbrf_chain_head, nb);
+}
+EXPORT_SYMBOL_GPL(amd_wbrf_unregister_notifier);
diff --git a/include/linux/acpi_amd_wbrf.h b/include/linux/acpi_amd_wbrf.h
new file mode 100644
index 000000000000..898f31d536d4
--- /dev/null
+++ b/include/linux/acpi_amd_wbrf.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Wifi Band Exclusion Interface (AMD ACPI Implementation)
+ * Copyright (C) 2023 Advanced Micro Devices
+ */
+
+#ifndef _ACPI_AMD_WBRF_H
+#define _ACPI_AMD_WBRF_H
+
+#include <linux/device.h>
+#include <linux/notifier.h>
+
+/* The maximum number of frequency band ranges */
+#define MAX_NUM_OF_WBRF_RANGES 11
+
+/* Record actions */
+#define WBRF_RECORD_ADD 0x0
+#define WBRF_RECORD_REMOVE 0x1
+
+/**
+ * struct freq_band_range - Wifi frequency band range definition
+ * @start: start frequency point (in Hz)
+ * @end: end frequency point (in Hz)
+ */
+struct freq_band_range {
+ u64 start;
+ u64 end;
+};
+
+/**
+ * struct wbrf_ranges_in_out - wbrf ranges info
+ * @num_of_ranges: total number of band ranges in this struct
+ * @band_list: array of Wifi band ranges
+ */
+struct wbrf_ranges_in_out {
+ u64 num_of_ranges;
+ struct freq_band_range band_list[MAX_NUM_OF_WBRF_RANGES];
+};
+
+/**
+ * enum wbrf_notifier_actions - wbrf notifier actions index
+ * @WBRF_CHANGED: there was some frequency band updates. The consumers
+ * should retrieve the latest active frequency bands.
+ */
+enum wbrf_notifier_actions {
+ WBRF_CHANGED,
+};
+
+#if IS_ENABLED(CONFIG_AMD_WBRF)
+bool acpi_amd_wbrf_supported_producer(struct device *dev);
+int acpi_amd_wbrf_add_remove(struct device *dev, uint8_t action, struct wbrf_ranges_in_out *in);
+bool acpi_amd_wbrf_supported_consumer(struct device *dev);
+int amd_wbrf_retrieve_freq_band(struct device *dev, struct wbrf_ranges_in_out *out);
+int amd_wbrf_register_notifier(struct notifier_block *nb);
+int amd_wbrf_unregister_notifier(struct notifier_block *nb);
+#else
+static inline
+bool acpi_amd_wbrf_supported_consumer(struct device *dev)
+{
+ return false;
+}
+
+static inline
+int acpi_amd_wbrf_add_remove(struct device *dev, uint8_t action, struct wbrf_ranges_in_out *in)
+{
+ return -ENODEV;
+}
+
+static inline
+bool acpi_amd_wbrf_supported_producer(struct device *dev)
+{
+ return false;
+}
+static inline
+int amd_wbrf_retrieve_freq_band(struct device *dev, struct wbrf_ranges_in_out *out)
+{
+ return -ENODEV;
+}
+static inline
+int amd_wbrf_register_notifier(struct notifier_block *nb)
+{
+ return -ENODEV;
+}
+static inline
+int amd_wbrf_unregister_notifier(struct notifier_block *nb)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_AMD_WBRF */
+
+#endif /* _ACPI_AMD_WBRF_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1b3345129a95..ac1fb326dcda 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -52,7 +52,7 @@
* such wiphy can have zero, one, or many virtual interfaces associated with
* it, which need to be identified as such by pointing the network interface's
* @ieee80211_ptr pointer to a &struct wireless_dev which further describes
- * the wireless part of the interface, normally this struct is embedded in the
+ * the wireless part of the interface. Normally this struct is embedded in the
* network interface's private data area. Drivers can optionally allow creating
* or destroying virtual interfaces on the fly, but without at least one or the
* ability to create some the wireless device isn't useful.
@@ -977,6 +977,15 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
const struct cfg80211_chan_def *chandef2);
/**
+ * nl80211_chan_width_to_mhz - get the channel width in MHz
+ * @chan_width: the channel width from &enum nl80211_chan_width
+ *
+ * Return: channel width in MHz if the chan_width from &enum nl80211_chan_width
+ * is valid. -1 otherwise.
+ */
+int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width);
+
+/**
* cfg80211_chandef_valid - check if a channel definition is valid
* @chandef: the channel definition to check
* Return: %true if the channel definition is valid. %false otherwise.
@@ -1665,6 +1674,21 @@ struct link_station_del_parameters {
};
/**
+ * struct cfg80211_ttlm_params: TID to link mapping parameters
+ *
+ * Used for setting a TID to link mapping.
+ *
+ * @dlink: Downlink TID to link mapping, as defined in section 9.4.2.314
+ * (TID-To-Link Mapping element) in Draft P802.11be_D4.0.
+ * @ulink: Uplink TID to link mapping, as defined in section 9.4.2.314
+ * (TID-To-Link Mapping element) in Draft P802.11be_D4.0.
+ */
+struct cfg80211_ttlm_params {
+ u16 dlink[8];
+ u16 ulink[8];
+};
+
+/**
* struct station_parameters - station parameters
*
* Used to change and create a new station.
@@ -2560,7 +2584,7 @@ struct cfg80211_scan_info {
* @short_ssid: short ssid to scan for
* @bssid: bssid to scan for
* @channel_idx: idx of the channel in the channel array in the scan request
- * which the above info relvant to
+ * which the above info is relevant to
* @unsolicited_probe: the AP transmits unsolicited probe response every 20 TU
* @short_ssid_valid: @short_ssid is valid and can be used
* @psc_no_listen: when set, and the channel is a PSC channel, no need to wait
@@ -2819,6 +2843,13 @@ enum cfg80211_signal_type {
* the BSS that requested the scan in which the beacon/probe was received.
* @chains: bitmask for filled values in @chain_signal.
* @chain_signal: per-chain signal strength of last received BSS in dBm.
+ * @restrict_use: restrict usage, if not set, assume @use_for is
+ * %NL80211_BSS_USE_FOR_NORMAL.
+ * @use_for: bitmap of possible usage for this BSS, see
+ * &enum nl80211_bss_use_for
+ * @cannot_use_reasons: the reasons (bitmap) for not being able to connect,
+ * if @restrict_use is set and @use_for is zero (empty); may be 0 for
+ * unspecified reasons; see &enum nl80211_bss_cannot_use_reasons
* @drv_data: Data to be passed through to @inform_bss
*/
struct cfg80211_inform_bss {
@@ -2830,6 +2861,9 @@ struct cfg80211_inform_bss {
u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS];
+ u8 restrict_use:1, use_for:7;
+ u8 cannot_use_reasons;
+
void *drv_data;
};
@@ -2881,6 +2915,11 @@ struct cfg80211_bss_ies {
* @chain_signal: per-chain signal strength of last received BSS in dBm.
* @bssid_index: index in the multiple BSS set
* @max_bssid_indicator: max number of members in the BSS set
+ * @use_for: bitmap of possible usage for this BSS, see
+ * &enum nl80211_bss_use_for
+ * @cannot_use_reasons: the reasons (bitmap) for not being able to connect,
+ * if @restrict_use is set and @use_for is zero (empty); may be 0 for
+ * unspecified reasons; see &enum nl80211_bss_cannot_use_reasons
* @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
*/
struct cfg80211_bss {
@@ -2906,6 +2945,9 @@ struct cfg80211_bss {
u8 bssid_index;
u8 max_bssid_indicator;
+ u8 use_for;
+ u8 cannot_use_reasons;
+
u8 priv[] __aligned(sizeof(void *));
};
@@ -4496,6 +4538,7 @@ struct mgmt_frame_regs {
* @del_link_station: Remove a link of a station.
*
* @set_hw_timestamp: Enable/disable HW timestamping of TM/FTM frames.
+ * @set_ttlm: set the TID to link mapping.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -4855,6 +4898,8 @@ struct cfg80211_ops {
struct link_station_del_parameters *params);
int (*set_hw_timestamp)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_set_hw_timestamp *hwts);
+ int (*set_ttlm)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ttlm_params *params);
};
/*
@@ -4913,6 +4958,8 @@ struct cfg80211_ops {
* NL80211_REGDOM_SET_BY_DRIVER.
* @WIPHY_FLAG_CHANNEL_CHANGE_ON_BEACON: reg_call_notifier() is called if driver
* set this flag to update channels on beacon hints.
+ * @WIPHY_FLAG_SUPPORTS_NSTR_NONPRIMARY: support connection to non-primary link
+ * of an NSTR mobile AP MLD.
*/
enum wiphy_flags {
WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0),
@@ -4926,7 +4973,7 @@ enum wiphy_flags {
WIPHY_FLAG_IBSS_RSN = BIT(8),
WIPHY_FLAG_MESH_AUTH = BIT(10),
WIPHY_FLAG_SUPPORTS_EXT_KCK_32 = BIT(11),
- /* use hole at 12 */
+ WIPHY_FLAG_SUPPORTS_NSTR_NONPRIMARY = BIT(12),
WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13),
WIPHY_FLAG_AP_UAPSD = BIT(14),
WIPHY_FLAG_SUPPORTS_TDLS = BIT(15),
@@ -7165,6 +7212,25 @@ cfg80211_inform_bss(struct wiphy *wiphy,
}
/**
+ * __cfg80211_get_bss - get a BSS reference
+ * @wiphy: the wiphy this BSS struct belongs to
+ * @channel: the channel to search on (or %NULL)
+ * @bssid: the desired BSSID (or %NULL)
+ * @ssid: the desired SSID (or %NULL)
+ * @ssid_len: length of the SSID (or 0)
+ * @bss_type: type of BSS, see &enum ieee80211_bss_type
+ * @privacy: privacy filter, see &enum ieee80211_privacy
+ * @use_for: indicates which use is intended
+ */
+struct cfg80211_bss *__cfg80211_get_bss(struct wiphy *wiphy,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
+ const u8 *ssid, size_t ssid_len,
+ enum ieee80211_bss_type bss_type,
+ enum ieee80211_privacy privacy,
+ u32 use_for);
+
+/**
* cfg80211_get_bss - get a BSS reference
* @wiphy: the wiphy this BSS struct belongs to
* @channel: the channel to search on (or %NULL)
@@ -7173,13 +7239,20 @@ cfg80211_inform_bss(struct wiphy *wiphy,
* @ssid_len: length of the SSID (or 0)
* @bss_type: type of BSS, see &enum ieee80211_bss_type
* @privacy: privacy filter, see &enum ieee80211_privacy
+ *
+ * This version implies regular usage, %NL80211_BSS_USE_FOR_NORMAL.
*/
-struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
- struct ieee80211_channel *channel,
- const u8 *bssid,
- const u8 *ssid, size_t ssid_len,
- enum ieee80211_bss_type bss_type,
- enum ieee80211_privacy privacy);
+static inline struct cfg80211_bss *
+cfg80211_get_bss(struct wiphy *wiphy, struct ieee80211_channel *channel,
+ const u8 *bssid, const u8 *ssid, size_t ssid_len,
+ enum ieee80211_bss_type bss_type,
+ enum ieee80211_privacy privacy)
+{
+ return __cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len,
+ bss_type, privacy,
+ NL80211_BSS_USE_FOR_NORMAL);
+}
+
static inline struct cfg80211_bss *
cfg80211_get_ibss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
@@ -7312,7 +7385,7 @@ struct cfg80211_rx_assoc_resp_data {
* This function may sleep. The caller must hold the corresponding wdev's mutex.
*/
void cfg80211_rx_assoc_resp(struct net_device *dev,
- struct cfg80211_rx_assoc_resp_data *data);
+ const struct cfg80211_rx_assoc_resp_data *data);
/**
* struct cfg80211_assoc_failure - association failure data
@@ -7431,7 +7504,7 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev,
* RFkill integration in cfg80211 is almost invisible to drivers,
* as cfg80211 automatically registers an rfkill instance for each
* wireless device it knows about. Soft kill is also translated
- * into disconnecting and turning all interfaces off, drivers are
+ * into disconnecting and turning all interfaces off. Drivers are
* expected to turn off the device when all interfaces are down.
*
* However, devices may have a hard RFkill line, in which case they
@@ -7479,7 +7552,7 @@ static inline void wiphy_rfkill_stop_polling(struct wiphy *wiphy)
* the configuration mechanism.
*
* A driver supporting vendor commands must register them as an array
- * in struct wiphy, with handlers for each one, each command has an
+ * in struct wiphy, with handlers for each one. Each command has an
* OUI and sub command ID to identify it.
*
* Note that this feature should not be (ab)used to implement protocol
@@ -7643,7 +7716,7 @@ static inline void cfg80211_vendor_event(struct sk_buff *skb, gfp_t gfp)
* interact with driver-specific tools to aid, for instance,
* factory programming.
*
- * This chapter describes how drivers interact with it, for more
+ * This chapter describes how drivers interact with it. For more
* information see the nl80211 book's chapter on it.
*/
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 580781ff9dcf..77a71b1396b1 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2686,6 +2686,9 @@ struct ieee80211_txq {
* @IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX: Hardware/driver handles transmitting
* multicast frames on all links, mac80211 should not do that.
*
+ * @IEEE80211_HW_DISALLOW_PUNCTURING: HW requires disabling puncturing in EHT
+ * and connecting with a lower bandwidth instead
+ *
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
@@ -2743,6 +2746,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP,
IEEE80211_HW_DETECTS_COLOR_COLLISION,
IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX,
+ IEEE80211_HW_DISALLOW_PUNCTURING,
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
@@ -5809,12 +5813,11 @@ void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf,
* ieee80211_remove_key - remove the given key
* @keyconf: the parameter passed with the set key
*
+ * Context: Must be called with the wiphy mutex held.
+ *
* Remove the given key. If the key was uploaded to the hardware at the
* time this function is called, it is not deleted in the hardware but
* instead assumed to have been removed already.
- *
- * Note that due to locking considerations this function can (currently)
- * only be called during key iteration (ieee80211_iter_keys().)
*/
void ieee80211_remove_key(struct ieee80211_key_conf *keyconf);
@@ -6368,12 +6371,12 @@ ieee80211_txq_airtime_check(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
* @iter: iterator function that will be called for each key
* @iter_data: custom data to pass to the iterator function
*
+ * Context: Must be called with wiphy mutex held; can sleep.
+ *
* This function can be used to iterate all the keys known to
* mac80211, even those that weren't previously programmed into
* the device. This is intended for use in WoWLAN if the device
- * needs reprogramming of the keys during suspend. Note that due
- * to locking reasons, it is also only safe to call this at few
- * spots since it must hold the RTNL and be able to sleep.
+ * needs reprogramming of the keys during suspend.
*
* The order in which the keys are iterated matches the order
* in which they were originally installed and handed to the
@@ -7435,6 +7438,9 @@ static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
* @vif: interface to set active links on
* @active_links: the new active links bitmap
*
+ * Context: Must be called with wiphy mutex held; may sleep; calls
+ * back into the driver.
+ *
* This changes the active links on an interface. The interface
* must be in client mode (in AP mode, all links are always active),
* and @active_links must be a subset of the vif's valid_links.
@@ -7442,6 +7448,7 @@ static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
* If a link is switched off and another is switched on at the same
* time (e.g. active_links going from 0x1 to 0x10) then you will get
* a sequence of calls like
+ *
* - change_vif_links(0x11)
* - unassign_vif_chanctx(link_id=0)
* - change_sta_links(0x11) for each affected STA (the AP)
@@ -7451,10 +7458,6 @@ static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
* - change_sta_links(0x10) for each affected STA (the AP)
* - assign_vif_chanctx(link_id=4)
* - change_vif_links(0x10)
- *
- * Note: This function acquires some mac80211 locks and must not
- * be called with any driver locks held that could cause a
- * lock dependency inversion. Best call it without locks.
*/
int ieee80211_set_active_links(struct ieee80211_vif *vif, u16 active_links);
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 0cd1da2c2902..a682b54bd3ba 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -72,7 +72,7 @@
* For drivers supporting TDLS with external setup (WIPHY_FLAG_SUPPORTS_TDLS
* and WIPHY_FLAG_TDLS_EXTERNAL_SETUP), the station lifetime is as follows:
* - a setup station entry is added, not yet authorized, without any rate
- * or capability information, this just exists to avoid race conditions
+ * or capability information; this just exists to avoid race conditions
* - when the TDLS setup is done, a single NL80211_CMD_SET_STATION is valid
* to add rate and capability information to the station and at the same
* time mark it authorized.
@@ -87,7 +87,7 @@
* DOC: Frame transmission/registration support
*
* Frame transmission and registration support exists to allow userspace
- * management entities such as wpa_supplicant react to management frames
+ * management entities such as wpa_supplicant to react to management frames
* that are not being handled by the kernel. This includes, for example,
* certain classes of action frames that cannot be handled in the kernel
* for various reasons.
@@ -113,7 +113,7 @@
*
* Frame transmission allows userspace to send for example the required
* responses to action frames. It is subject to some sanity checking,
- * but many frames can be transmitted. When a frame was transmitted, its
+ * but many frames can be transmitted. When a frame is transmitted, its
* status is indicated to the sending socket.
*
* For more technical details, see the corresponding command descriptions
@@ -123,7 +123,7 @@
/**
* DOC: Virtual interface / concurrency capabilities
*
- * Some devices are able to operate with virtual MACs, they can have
+ * Some devices are able to operate with virtual MACs; they can have
* more than one virtual interface. The capability handling for this
* is a bit complex though, as there may be a number of restrictions
* on the types of concurrency that are supported.
@@ -135,7 +135,7 @@
* Once concurrency is desired, more attributes must be observed:
* To start with, since some interface types are purely managed in
* software, like the AP-VLAN type in mac80211 for example, there's
- * an additional list of these, they can be added at any time and
+ * an additional list of these; they can be added at any time and
* are only restricted by some semantic restrictions (e.g. AP-VLAN
* cannot be added without a corresponding AP interface). This list
* is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute.
@@ -164,7 +164,7 @@
* Packet coalesce feature helps to reduce number of received interrupts
* to host by buffering these packets in firmware/hardware for some
* predefined time. Received interrupt will be generated when one of the
- * following events occur.
+ * following events occurs.
* a) Expiration of hardware timer whose expiration time is set to maximum
* coalescing delay of matching coalesce rule.
* b) Coalescing buffer in hardware reaches its limit.
@@ -174,7 +174,7 @@
* rule.
* a) Maximum coalescing delay
* b) List of packet patterns which needs to be matched
- * c) Condition for coalescence. pattern 'match' or 'no match'
+ * c) Condition for coalescence: pattern 'match' or 'no match'
* Multiple such rules can be created.
*/
@@ -213,7 +213,7 @@
/**
* DOC: FILS shared key authentication offload
*
- * FILS shared key authentication offload can be advertized by drivers by
+ * FILS shared key authentication offload can be advertised by drivers by
* setting @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD flag. The drivers that support
* FILS shared key authentication offload should be able to construct the
* authentication and association frames for FILS shared key authentication and
@@ -239,7 +239,7 @@
* The PMKSA can be maintained in userspace persistently so that it can be used
* later after reboots or wifi turn off/on also.
*
- * %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertized by a FILS
+ * %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertised by a FILS
* capable AP supporting PMK caching. It specifies the scope within which the
* PMKSAs are cached in an ESS. %NL80211_CMD_SET_PMKSA and
* %NL80211_CMD_DEL_PMKSA are enhanced to allow support for PMKSA caching based
@@ -290,12 +290,12 @@
* If the configuration needs to be applied for specific peer then the MAC
* address of the peer needs to be passed in %NL80211_ATTR_MAC, otherwise the
* configuration will be applied for all the connected peers in the vif except
- * any peers that have peer specific configuration for the TID by default; if
- * the %NL80211_TID_CONFIG_ATTR_OVERRIDE flag is set, peer specific values
+ * any peers that have peer-specific configuration for the TID by default; if
+ * the %NL80211_TID_CONFIG_ATTR_OVERRIDE flag is set, peer-specific values
* will be overwritten.
*
- * All this configuration is valid only for STA's current connection
- * i.e. the configuration will be reset to default when the STA connects back
+ * All this configuration is valid only for STA's current connection,
+ * i.e., the configuration will be reset to default when the STA connects back
* after disconnection/roaming, and this configuration will be cleared when
* the interface goes down.
*/
@@ -521,7 +521,7 @@
* %NL80211_ATTR_SCHED_SCAN_PLANS. If %NL80211_ATTR_SCHED_SCAN_PLANS is
* not specified and only %NL80211_ATTR_SCHED_SCAN_INTERVAL is specified,
* scheduled scan will run in an infinite loop with the specified interval.
- * These attributes are mutually exculsive,
+ * These attributes are mutually exclusive,
* i.e. NL80211_ATTR_SCHED_SCAN_INTERVAL must not be passed if
* NL80211_ATTR_SCHED_SCAN_PLANS is defined.
* If for some reason scheduled scan is aborted by the driver, all scan
@@ -552,7 +552,7 @@
* %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface
* is brought down while a scheduled scan was running.
*
- * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
+ * @NL80211_CMD_GET_SURVEY: get survey results, e.g. channel occupation
* or noise level
* @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
* NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
@@ -563,12 +563,13 @@
* using %NL80211_ATTR_SSID, %NL80211_ATTR_FILS_CACHE_ID,
* %NL80211_ATTR_PMKID, and %NL80211_ATTR_PMK in case of FILS
* authentication where %NL80211_ATTR_FILS_CACHE_ID is the identifier
- * advertized by a FILS capable AP identifying the scope of PMKSA in an
+ * advertised by a FILS capable AP identifying the scope of PMKSA in an
* ESS.
* @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC
* (for the BSSID) and %NL80211_ATTR_PMKID or using %NL80211_ATTR_SSID,
* %NL80211_ATTR_FILS_CACHE_ID, and %NL80211_ATTR_PMKID in case of FILS
- * authentication.
+ * authentication. Additionally in case of SAE offload and OWE offloads
+ * PMKSA entry can be deleted using %NL80211_ATTR_SSID.
* @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries.
*
* @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
@@ -607,7 +608,7 @@
* BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
* the SSID (mainly for association, but is included in authentication
* request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ +
- * %NL80211_ATTR_WIPHY_FREQ_OFFSET is used to specify the frequence of the
+ * %NL80211_ATTR_WIPHY_FREQ_OFFSET is used to specify the frequency of the
* channel in MHz. %NL80211_ATTR_AUTH_TYPE is used to specify the
* authentication type. %NL80211_ATTR_IE is used to define IEs
* (VendorSpecificInfo, but also including RSN IE and FT IEs) to be added
@@ -816,7 +817,7 @@
* reached.
* @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
* and the attributes determining channel width) the given interface
- * (identifed by %NL80211_ATTR_IFINDEX) shall operate on.
+ * (identified by %NL80211_ATTR_IFINDEX) shall operate on.
* In case multiple channels are supported by the device, the mechanism
* with which it switches channels is implementation-defined.
* When a monitor interface is given, it can only switch channel while
@@ -888,7 +889,7 @@
* inform userspace of the new replay counter.
*
* @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace
- * of PMKSA caching dandidates.
+ * of PMKSA caching candidates.
*
* @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
* In addition, this can be used as an event to request userspace to take
@@ -924,7 +925,7 @@
*
* @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface
* by sending a null data frame to it and reporting when the frame is
- * acknowleged. This is used to allow timing out inactive clients. Uses
+ * acknowledged. This is used to allow timing out inactive clients. Uses
* %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a
* direct reply with an %NL80211_ATTR_COOKIE that is later used to match
* up the event with the request. The event includes the same data and
@@ -1327,6 +1328,11 @@
* Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide
* information about the removed STA MLD setup links.
*
+ * @NL80211_CMD_SET_TID_TO_LINK_MAPPING: Set the TID to Link Mapping for a
+ * non-AP MLD station. The %NL80211_ATTR_MLO_TTLM_DLINK and
+ * %NL80211_ATTR_MLO_TTLM_ULINK attributes are used to specify the
+ * TID to Link mapping for downlink/uplink traffic.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1582,6 +1588,8 @@ enum nl80211_commands {
NL80211_CMD_LINKS_REMOVED,
+ NL80211_CMD_SET_TID_TO_LINK_MAPPING,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1839,7 +1847,7 @@ enum nl80211_commands {
* using %CMD_CONTROL_PORT_FRAME. If control port routing over NL80211 is
* to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER
* flag. When used with %NL80211_ATTR_CONTROL_PORT_NO_PREAUTH, pre-auth
- * frames are not forwared over the control port.
+ * frames are not forwarded over the control port.
*
* @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
* We recommend using nested, driver-specific attributes within this.
@@ -1976,10 +1984,10 @@ enum nl80211_commands {
* bit. Depending on which antennas are selected in the bitmap, 802.11n
* drivers can derive which chainmasks to use (if all antennas belonging to
* a particular chain are disabled this chain should be disabled) and if
- * a chain has diversity antennas wether diversity should be used or not.
+ * a chain has diversity antennas whether diversity should be used or not.
* HT capabilities (STBC, TX Beamforming, Antenna selection) can be
* derived from the available chains after applying the antenna mask.
- * Non-802.11n drivers can derive wether to use diversity or not.
+ * Non-802.11n drivers can derive whether to use diversity or not.
* Drivers may reject configurations or RX/TX mask combinations they cannot
* support by returning -EINVAL.
*
@@ -2549,7 +2557,7 @@ enum nl80211_commands {
* from successful FILS authentication and is used with
* %NL80211_CMD_CONNECT.
*
- * @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertized by a FILS AP
+ * @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertised by a FILS AP
* identifying the scope of PMKSAs. This is used with
* @NL80211_CMD_SET_PMKSA and @NL80211_CMD_DEL_PMKSA.
*
@@ -2830,6 +2838,19 @@ enum nl80211_commands {
* @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is
* disabled.
*
+ * @NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA: Include BSS usage data, i.e.
+ * include BSSes that can only be used in restricted scenarios and/or
+ * cannot be used at all.
+ *
+ * @NL80211_ATTR_MLO_TTLM_DLINK: Binary attribute specifying the downlink TID to
+ * link mapping. The length is 8 * sizeof(u16). For each TID the link
+ * mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
+ * in Draft P802.11be_D4.0.
+ * @NL80211_ATTR_MLO_TTLM_ULINK: Binary attribute specifying the uplink TID to
+ * link mapping. The length is 8 * sizeof(u16). For each TID the link
+ * mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
+ * in Draft P802.11be_D4.0.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3368,6 +3389,11 @@ enum nl80211_attrs {
NL80211_ATTR_MLO_LINK_DISABLED,
+ NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA,
+
+ NL80211_ATTR_MLO_TTLM_DLINK,
+ NL80211_ATTR_MLO_TTLM_ULINK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -4174,7 +4200,7 @@ enum nl80211_wmm_rule {
* (100 * dBm).
* @NL80211_FREQUENCY_ATTR_DFS_STATE: current state for DFS
* (enum nl80211_dfs_state)
- * @NL80211_FREQUENCY_ATTR_DFS_TIME: time in miliseconds for how long
+ * @NL80211_FREQUENCY_ATTR_DFS_TIME: time in milliseconds for how long
* this channel is in this DFS state.
* @NL80211_FREQUENCY_ATTR_NO_HT40_MINUS: HT40- isn't possible with this
* channel as the control channel
@@ -5032,6 +5058,30 @@ enum nl80211_bss_scan_width {
};
/**
+ * enum nl80211_bss_use_for - bitmap indicating possible BSS use
+ * @NL80211_BSS_USE_FOR_NORMAL: Use this BSS for normal "connection",
+ * including IBSS/MBSS depending on the type.
+ * @NL80211_BSS_USE_FOR_MLD_LINK: This BSS can be used as a link in an
+ * MLO connection. Note that for an MLO connection, all links including
+ * the assoc link must have this flag set, and the assoc link must
+ * additionally have %NL80211_BSS_USE_FOR_NORMAL set.
+ */
+enum nl80211_bss_use_for {
+ NL80211_BSS_USE_FOR_NORMAL = 1 << 0,
+ NL80211_BSS_USE_FOR_MLD_LINK = 1 << 1,
+};
+
+/**
+ * enum nl80211_bss_cannot_use_reasons - reason(s) connection to a
+ * BSS isn't possible
+ * @NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY: NSTR nonprimary links aren't
+ * supported by the device, and this BSS entry represents one.
+ */
+enum nl80211_bss_cannot_use_reasons {
+ NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 1 << 0,
+};
+
+/**
* enum nl80211_bss - netlink attributes for a BSS
*
* @__NL80211_BSS_INVALID: invalid
@@ -5083,6 +5133,14 @@ enum nl80211_bss_scan_width {
* @NL80211_BSS_FREQUENCY_OFFSET: frequency offset in KHz
* @NL80211_BSS_MLO_LINK_ID: MLO link ID of the BSS (u8).
* @NL80211_BSS_MLD_ADDR: MLD address of this BSS if connected to it.
+ * @NL80211_BSS_USE_FOR: u32 bitmap attribute indicating what the BSS can be
+ * used for, see &enum nl80211_bss_use_for.
+ * @NL80211_BSS_CANNOT_USE_REASONS: Indicates the reason that this BSS cannot
+ * be used for all or some of the possible uses by the device reporting it,
+ * even though its presence was detected.
+ * This is a u64 attribute containing a bitmap of values from
+ * &enum nl80211_cannot_use_reasons, note that the attribute may be missing
+ * if no reasons are specified.
* @__NL80211_BSS_AFTER_LAST: internal
* @NL80211_BSS_MAX: highest BSS attribute
*/
@@ -5110,6 +5168,8 @@ enum nl80211_bss {
NL80211_BSS_FREQUENCY_OFFSET,
NL80211_BSS_MLO_LINK_ID,
NL80211_BSS_MLD_ADDR,
+ NL80211_BSS_USE_FOR,
+ NL80211_BSS_CANNOT_USE_REASONS,
/* keep last */
__NL80211_BSS_AFTER_LAST,
@@ -5458,7 +5518,7 @@ enum nl80211_tx_rate_setting {
* (%NL80211_TID_CONFIG_ATTR_TIDS, %NL80211_TID_CONFIG_ATTR_OVERRIDE).
* @NL80211_TID_CONFIG_ATTR_PEER_SUPP: same as the previous per-vif one, but
* per peer instead.
- * @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if set indicates
+ * @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribute, if set indicates
* that the new configuration overrides all previous peer
* configurations, otherwise previous peer specific configurations
* should be left untouched.
@@ -5841,7 +5901,7 @@ enum nl80211_attr_coalesce_rule {
/**
* enum nl80211_coalesce_condition - coalesce rule conditions
- * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns
+ * @NL80211_COALESCE_CONDITION_MATCH: coalesce Rx packets when patterns
* in a rule are matched.
* @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns
* in a rule are not matched.
@@ -5940,7 +6000,7 @@ enum nl80211_if_combination_attrs {
* enum nl80211_plink_state - state of a mesh peer link finite state machine
*
* @NL80211_PLINK_LISTEN: initial state, considered the implicit
- * state of non existent mesh peer links
+ * state of non-existent mesh peer links
* @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to
* this mesh peer
* @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received
@@ -6233,7 +6293,7 @@ enum nl80211_feature_flags {
* request to use RRM (see %NL80211_ATTR_USE_RRM) with
* %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set
* the ASSOC_REQ_USE_RRM flag in the association request even if
- * NL80211_FEATURE_QUIET is not advertized.
+ * NL80211_FEATURE_QUIET is not advertised.
* @NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER: This device supports MU-MIMO air
* sniffer which means that it can be configured to hear packets from
* certain groups which can be configured by the
@@ -6245,7 +6305,7 @@ enum nl80211_feature_flags {
* the BSS that the interface that requested the scan is connected to
* (if available).
* @NL80211_EXT_FEATURE_BSS_PARENT_TSF: Per BSS, this driver reports the
- * time the last beacon/probe was received. For a non MLO connection, the
+ * time the last beacon/probe was received. For a non-MLO connection, the
* time is the TSF of the BSS that the interface that requested the scan is
* connected to (if available). For an MLO connection, the time is the TSF
* of the BSS corresponding with link ID specified in the scan request (if
@@ -6253,7 +6313,7 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of
* channel dwell time.
* @NL80211_EXT_FEATURE_BEACON_RATE_LEGACY: Driver supports beacon rate
- * configuration (AP/mesh), supporting a legacy (non HT/VHT) rate.
+ * configuration (AP/mesh), supporting a legacy (non-HT/VHT) rate.
* @NL80211_EXT_FEATURE_BEACON_RATE_HT: Driver supports beacon rate
* configuration (AP/mesh) with HT rates.
* @NL80211_EXT_FEATURE_BEACON_RATE_VHT: Driver supports beacon rate
@@ -6589,7 +6649,7 @@ enum nl80211_timeout_reason {
* request parameters IE in the probe request
* @NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP: accept broadcast probe responses
* @NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE: send probe request frames at
- * rate of at least 5.5M. In case non OCE AP is discovered in the channel,
+ * rate of at least 5.5M. In case non-OCE AP is discovered in the channel,
* only the first probe req in the channel will be sent in high rate.
* @NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: allow probe request
* tx deferral (dot11FILSProbeDelay shall be set to 15ms)
@@ -6625,7 +6685,7 @@ enum nl80211_timeout_reason {
* received on the 2.4/5 GHz channels to actively scan only the 6GHz
* channels on which APs are expected to be found. Note that when not set,
* the scan logic would scan all 6GHz channels, but since transmission of
- * probe requests on non PSC channels is limited, it is highly likely that
+ * probe requests on non-PSC channels is limited, it is highly likely that
* these channels would passively be scanned. Also note that when the flag
* is set, in addition to the colocated APs, PSC channels would also be
* scanned if the user space has asked for it.
@@ -6957,7 +7017,7 @@ enum nl80211_nan_func_term_reason {
* The instance ID for the follow up Service Discovery Frame. This is u8.
* @NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID: relevant if the function's type
* is follow up. This is a u8.
- * The requestor instance ID for the follow up Service Discovery Frame.
+ * The requester instance ID for the follow up Service Discovery Frame.
* @NL80211_NAN_FUNC_FOLLOW_UP_DEST: the MAC address of the recipient of the
* follow up Service Discovery Frame. This is a binary attribute.
* @NL80211_NAN_FUNC_CLOSE_RANGE: is this function limited for devices in a
@@ -7347,7 +7407,7 @@ enum nl80211_peer_measurement_attrs {
* @NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED: flag attribute indicating if
* trigger based ranging measurement is supported
* @NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED: flag attribute indicating
- * if non trigger based ranging measurement is supported
+ * if non-trigger-based ranging measurement is supported
*
* @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal
* @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number
@@ -7401,7 +7461,7 @@ enum nl80211_peer_measurement_ftm_capa {
* if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
* %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
* ranging will be used.
- * @NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED: request non trigger based
+ * @NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED: request non-trigger-based
* ranging measurement (flag)
* This attribute and %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED are
* mutually exclusive.
@@ -7479,7 +7539,7 @@ enum nl80211_peer_measurement_ftm_failure_reasons {
* @NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_ATTEMPTS: number of FTM Request frames
* transmitted (u32, optional)
* @NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_SUCCESSES: number of FTM Request frames
- * that were acknowleged (u32, optional)
+ * that were acknowledged (u32, optional)
* @NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME: retry time received from the
* busy peer (u32, seconds)
* @NL80211_PMSR_FTM_RESP_ATTR_NUM_BURSTS_EXP: actual number of bursts exponent
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index c9eb52768133..4406b4f8f3b9 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -67,4 +67,6 @@ mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
obj-y += tests/
+mac80211-y += wbrf.o
+
ccflags-y += -DDEBUG
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 606b1b2e4123..e0a4f9eecb2c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1270,7 +1270,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
return -EALREADY;
if (params->smps_mode != NL80211_SMPS_OFF)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
link->smps_mode = IEEE80211_SMPS_OFF;
@@ -2556,7 +2556,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
* devices that report signal in dBm.
*/
if (!ieee80211_hw_check(&sdata->local->hw, SIGNAL_DBM))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
conf->rssi_threshold = nconf->rssi_threshold;
}
if (_chg_mesh_attr(NL80211_MESHCONF_HT_OPMODE, mask)) {
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 1d928f29ad6f..ef4c2cebc080 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -507,11 +507,16 @@ static void _ieee80211_change_chanctx(struct ieee80211_local *local,
WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
+ ieee80211_remove_wbrf(local, &ctx->conf.def);
+
ctx->conf.def = *chandef;
/* check if min chanctx also changed */
changed = IEEE80211_CHANCTX_CHANGE_WIDTH |
_ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for);
+
+ ieee80211_add_wbrf(local, &ctx->conf.def);
+
drv_change_chanctx(local, ctx, changed);
if (!local->use_chanctx) {
@@ -667,6 +672,8 @@ static int ieee80211_add_chanctx(struct ieee80211_local *local,
lockdep_assert_wiphy(local->hw.wiphy);
+ ieee80211_add_wbrf(local, &ctx->conf.def);
+
if (!local->use_chanctx)
local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
@@ -746,6 +753,8 @@ static void ieee80211_del_chanctx(struct ieee80211_local *local,
}
ieee80211_recalc_idle(local);
+
+ ieee80211_remove_wbrf(local, &ctx->conf.def);
}
static void ieee80211_free_chanctx(struct ieee80211_local *local,
@@ -858,7 +867,7 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
int ret = 0;
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
conf = rcu_dereference_protected(link->conf->chanctx_conf,
lockdep_is_held(&local->hw.wiphy->mtx));
@@ -1106,7 +1115,7 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
curr_ctx = ieee80211_link_get_chanctx(link);
if (curr_ctx && local->use_chanctx && !local->ops->switch_vif_chanctx)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
if (!new_ctx) {
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index b575ae90e57f..74be49191e70 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -497,6 +497,7 @@ static const char *hw_flag_names[] = {
FLAG(SUPPORTS_CONC_MON_RX_DECAP),
FLAG(DETECTS_COLOR_COLLISION),
FLAG(MLO_MCAST_MULTI_LINK_TX),
+ FLAG(DISALLOW_PUNCTURING),
#undef FLAG
};
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index f690c385a345..e9219f927875 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -805,7 +805,7 @@ drv_cancel_remain_on_channel(struct ieee80211_local *local,
static inline int drv_set_ringparam(struct ieee80211_local *local,
u32 tx, u32 rx)
{
- int ret = -ENOTSUPP;
+ int ret = -EOPNOTSUPP;
might_sleep();
lockdep_assert_wiphy(local->hw.wiphy);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 8b1e02f2f9ae..8f2b445a5ec3 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -485,7 +485,7 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
ifibss->ssid_len, IEEE80211_BSS_TYPE_IBSS,
IEEE80211_PRIVACY(ifibss->privacy));
- if (WARN_ON(!cbss))
+ if (unlikely(!cbss))
return -EINVAL;
rcu_read_lock();
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 84df104f272b..29312f6638a1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -92,11 +92,14 @@ enum ieee80211_status_data {
IEEE80211_STATUS_SUBDATA_MASK = 0xff0,
};
-/*
- * Keep a station's queues on the active list for deficit accounting purposes
- * if it was active or queued during the last 100ms
- */
-#define AIRTIME_ACTIVE_DURATION (HZ / 10)
+static inline bool
+ieee80211_sta_keep_active(struct sta_info *sta, u8 ac)
+{
+ /* Keep a station's queues on the active list for deficit accounting
+ * purposes if it was active or queued during the last 100ms.
+ */
+ return time_before_eq(jiffies, sta->airtime[ac].last_active + HZ / 10);
+}
struct ieee80211_bss {
u32 device_ts_beacon, device_ts_presp;
@@ -1559,6 +1562,8 @@ struct ieee80211_local {
/* extended capabilities provided by mac80211 */
u8 ext_capa[8];
+
+ bool wbrf_supported;
};
static inline struct ieee80211_sub_if_data *
@@ -2600,4 +2605,9 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata,
const struct ieee80211_eht_cap_elem *eht_cap_ie_elem,
u8 eht_cap_len,
struct link_sta_info *link_sta);
+
+void ieee80211_check_wbrf_support(struct ieee80211_local *local);
+void ieee80211_add_wbrf(struct ieee80211_local *local, struct cfg80211_chan_def *chandef);
+void ieee80211_remove_wbrf(struct ieee80211_local *local, struct cfg80211_chan_def *chandef);
+
#endif /* IEEE80211_I_H */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 033a5261ac3a..f2ece7793573 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1405,6 +1405,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
debugfs_hw_add(local);
rate_control_add_debugfs(local);
+ ieee80211_check_wbrf_support(local);
+
rtnl_lock();
wiphy_lock(hw->wiphy);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 775d52561c54..024f48db6b05 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -151,7 +151,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
break;
default:
kfree_skb(skb);
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
*pos++ = ie_len;
*pos++ = flags;
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 8a3f44ce3e04..735edde1bd81 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -676,10 +676,10 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata,
if (ether_addr_equal(dst, sdata->vif.addr))
/* never add ourselves as neighbours */
- return ERR_PTR(-ENOTSUPP);
+ return ERR_PTR(-EOPNOTSUPP);
if (is_multicast_ether_addr(dst))
- return ERR_PTR(-ENOTSUPP);
+ return ERR_PTR(-EOPNOTSUPP);
if (atomic_add_unless(&sdata->u.mesh.mpaths, 1, MESH_MAX_MPATHS) == 0)
return ERR_PTR(-ENOSPC);
@@ -719,10 +719,10 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
if (ether_addr_equal(dst, sdata->vif.addr))
/* never add ourselves as neighbours */
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
if (is_multicast_ether_addr(dst))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 887b496f2b81..a693ca2cf8cd 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -135,6 +135,7 @@ ieee80211_handle_puncturing_bitmap(struct ieee80211_link_data *link,
u16 bitmap, u64 *changed)
{
struct cfg80211_chan_def *chandef = &link->conf->chandef;
+ struct ieee80211_local *local = link->sdata->local;
u16 extracted;
u64 _changed = 0;
@@ -147,7 +148,9 @@ ieee80211_handle_puncturing_bitmap(struct ieee80211_link_data *link,
bitmap);
if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
- chandef))
+ chandef) &&
+ !(bitmap && ieee80211_hw_check(&local->hw,
+ DISALLOW_PUNCTURING)))
break;
link->u.mgd.conn_flags |=
ieee80211_chandef_downgrade(chandef);
@@ -1382,7 +1385,7 @@ static int ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
struct ieee80211_mgmt *mgmt;
u8 *pos, qos_info, *ie_start;
size_t offset, noffset;
- u16 capab = WLAN_CAPABILITY_ESS, link_capab;
+ u16 capab = 0, link_capab;
__le16 listen_int;
struct element *ext_capa = NULL;
enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
@@ -1529,6 +1532,17 @@ static int ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
*pos++ = assoc_data->ssid_len;
memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);
+ /*
+ * This bit is technically reserved, so it shouldn't matter for either
+ * the AP or us, but it also means we shouldn't set it. However, we've
+ * always set it in the past, and apparently some EHT APs check that
+ * we don't set it. To avoid interoperability issues with old APs that
+ * for some reason check it and want it to be set, set the bit for all
+ * pre-EHT connections as we used to do.
+ */
+ if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_EHT)
+ capab |= WLAN_CAPABILITY_ESS;
+
/* add the elements for the assoc (main) link */
link_capab = capab;
offset = ieee80211_assoc_link_elems(sdata, skb, &link_capab,
@@ -5682,6 +5696,7 @@ static bool ieee80211_config_puncturing(struct ieee80211_link_data *link,
const struct ieee80211_eht_operation *eht_oper,
u64 *changed)
{
+ struct ieee80211_local *local = link->sdata->local;
u16 bitmap = 0, extracted;
if ((eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT) &&
@@ -5713,6 +5728,9 @@ static bool ieee80211_config_puncturing(struct ieee80211_link_data *link,
return false;
}
+ if (bitmap && ieee80211_hw_check(&local->hw, DISALLOW_PUNCTURING))
+ return false;
+
ieee80211_handle_puncturing_bitmap(link, eht_oper, bitmap, changed);
return true;
}
@@ -7584,7 +7602,8 @@ ieee80211_setup_assoc_link(struct ieee80211_sub_if_data *sdata,
bitmap = get_unaligned_le16(disable_subchannel_bitmap);
if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
- &link->conf->chandef))
+ &link->conf->chandef) &&
+ !(bitmap && ieee80211_hw_check(&local->hw, DISALLOW_PUNCTURING)))
ieee80211_handle_puncturing_bitmap(link,
eht_oper,
bitmap,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 64352e4e6d00..bbfdcb0ade72 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -920,7 +920,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
* Drivers always need to pass packets that are aligned to two-byte boundaries
* to the stack.
*
- * Additionally, should, if possible, align the payload data in a way that
+ * Additionally, they should, if possible, align the payload data in a way that
* guarantees that the contained IP header is aligned to a four-byte
* boundary. In the case of regular frames, this simply means aligning the
* payload to a four-byte boundary (because either the IP header is directly
@@ -936,7 +936,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
* subframe to a length that is a multiple of four.
*
* Padding like Atheros hardware adds which is between the 802.11 header and
- * the payload is not supported, the driver is required to move the 802.11
+ * the payload is not supported; the driver is required to move the 802.11
* header to be directly in front of the payload in that case.
*/
static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 1d98877647d8..645355e5f1bc 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1289,7 +1289,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
iebufsz = local->scan_ies_len + req->ie_len;
if (!local->ops->sched_scan_start)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
for (i = 0; i < NUM_NL80211_BANDS; i++) {
if (local->hw.wiphy->bands[i]) {
@@ -1354,7 +1354,7 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_local *local)
lockdep_assert_wiphy(local->hw.wiphy);
if (!local->ops->sched_scan_stop)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
/* We don't want to restart sched scan anymore. */
RCU_INIT_POINTER(local->sched_scan_req, NULL);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 0ba613dd1cc4..bf1adcd96b41 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -40,7 +40,7 @@
* either sta_info_insert() or sta_info_insert_rcu(); only in the latter
* case (which acquires an rcu read section but must not be called from
* within one) will the pointer still be valid after the call. Note that
- * the caller may not do much with the STA info before inserting it, in
+ * the caller may not do much with the STA info before inserting it; in
* particular, it may not start any mesh peer link management or add
* encryption keys.
*
@@ -58,7 +58,7 @@
* In order to remove a STA info structure, various sta_info_destroy_*()
* calls are available.
*
- * There is no concept of ownership on a STA entry, each structure is
+ * There is no concept of ownership on a STA entry; each structure is
* owned by the global hash table/list until it is removed. All users of
* the structure need to be RCU protected so that the structure won't be
* freed before they are done using it.
@@ -2268,7 +2268,6 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
struct ieee80211_local *local = sta->sdata->local;
u8 ac = ieee80211_ac_from_tid(tid);
u32 airtime = 0;
- u32 diff;
if (sta->local->airtime_flags & AIRTIME_USE_TX)
airtime += tx_airtime;
@@ -2279,8 +2278,7 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
sta->airtime[ac].tx_airtime += tx_airtime;
sta->airtime[ac].rx_airtime += rx_airtime;
- diff = (u32)jiffies - sta->airtime[ac].last_active;
- if (diff <= AIRTIME_ACTIVE_DURATION)
+ if (ieee80211_sta_keep_active(sta, ac))
sta->airtime[ac].deficit -= airtime;
spin_unlock_bh(&local->active_txq_lock[ac]);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 7acf2223e47a..5ef1554f991f 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -138,7 +138,7 @@ enum ieee80211_agg_stop_reason {
struct airtime_info {
u64 rx_airtime;
u64 tx_airtime;
- u32 last_active;
+ unsigned long last_active;
s32 deficit;
atomic_t aql_tx_pending; /* Estimated airtime for frames pending */
u32 aql_limit_low;
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 05a7dff69fe9..49730b424141 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -1001,7 +1001,7 @@ ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata,
skb);
break;
default:
- ret = -ENOTSUPP;
+ ret = -EOPNOTSUPP;
break;
}
@@ -1071,7 +1071,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
/* any value is ok */
break;
default:
- ret = -ENOTSUPP;
+ ret = -EOPNOTSUPP;
break;
}
@@ -1177,7 +1177,7 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
smps_mode != IEEE80211_SMPS_OFF) {
tdls_dbg(sdata, "Aborting TDLS setup due to SMPS mode %d\n",
smps_mode);
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
lockdep_assert_wiphy(local->hw.wiphy);
@@ -1289,7 +1289,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
int ret;
if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
/* make sure we are in managed mode, and associated */
if (sdata->vif.type != NL80211_IFTYPE_STATION ||
@@ -1446,7 +1446,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
lockdep_assert_wiphy(local->hw.wiphy);
if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
if (sdata->vif.type != NL80211_IFTYPE_STATION)
return -EINVAL;
@@ -1459,7 +1459,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
case NL80211_TDLS_SETUP:
case NL80211_TDLS_DISCOVERY_REQ:
/* We don't support in-driver setup/teardown/discovery */
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
/* protect possible bss_conf changes and avoid concurrency in
@@ -1510,7 +1510,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
return ret;
break;
default:
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
if (ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
@@ -1673,7 +1673,7 @@ ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev,
if (!test_sta_flag(sta, WLAN_STA_TDLS_CHAN_SWITCH)) {
tdls_dbg(sdata, "TDLS channel switch unsupported by %pM\n",
addr);
- ret = -ENOTSUPP;
+ ret = -EOPNOTSUPP;
goto out;
}
@@ -1993,7 +1993,7 @@ ieee80211_process_tdls_channel_switch_req(struct ieee80211_sub_if_data *sdata,
if (!sta->sta.deflink.ht_cap.ht_supported && elems->sec_chan_offs &&
elems->sec_chan_offs->sec_chan_offs) {
tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n");
- ret = -ENOTSUPP;
+ ret = -EOPNOTSUPP;
goto out;
}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ed4fdf655343..314998fdb1a5 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4013,14 +4013,13 @@ ieee80211_txq_set_active(struct txq_info *txqi)
return;
sta = container_of(txqi->txq.sta, struct sta_info, sta);
- sta->airtime[txqi->txq.ac].last_active = (u32)jiffies;
+ sta->airtime[txqi->txq.ac].last_active = jiffies;
}
static bool
ieee80211_txq_keep_active(struct txq_info *txqi)
{
struct sta_info *sta;
- u32 diff;
if (!txqi->txq.sta)
return false;
@@ -4029,9 +4028,7 @@ ieee80211_txq_keep_active(struct txq_info *txqi)
if (ieee80211_sta_deficit(sta, txqi->txq.ac) >= 0)
return false;
- diff = (u32)jiffies - sta->airtime[txqi->txq.ac].last_active;
-
- return diff <= AIRTIME_ACTIVE_DURATION;
+ return ieee80211_sta_keep_active(sta, txqi->txq.ac);
}
struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
diff --git a/net/mac80211/wbrf.c b/net/mac80211/wbrf.c
new file mode 100644
index 000000000000..a05c5b971789
--- /dev/null
+++ b/net/mac80211/wbrf.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Wifi Band Exclusion Interface for WLAN
+ * Copyright (C) 2023 Advanced Micro Devices
+ *
+ */
+
+#include <linux/acpi_amd_wbrf.h>
+#include <linux/units.h>
+#include <net/cfg80211.h>
+#include "ieee80211_i.h"
+
+void ieee80211_check_wbrf_support(struct ieee80211_local *local)
+{
+ struct wiphy *wiphy = local->hw.wiphy;
+ struct device *dev;
+
+ if (!wiphy)
+ return;
+
+ dev = wiphy->dev.parent;
+ if (!dev)
+ return;
+
+ local->wbrf_supported = acpi_amd_wbrf_supported_producer(dev);
+ dev_dbg(dev, "WBRF is %s supported\n",
+ local->wbrf_supported ? "" : "not");
+}
+
+static void get_chan_freq_boundary(u32 center_freq, u32 bandwidth, u64 *start, u64 *end)
+{
+ bandwidth *= KHZ_PER_MHZ;
+ center_freq *= KHZ_PER_MHZ;
+
+ *start = center_freq - bandwidth / 2;
+ *end = center_freq + bandwidth / 2;
+
+ /* Frequency in Hz is expected */
+ *start = *start * HZ_PER_KHZ;
+ *end = *end * HZ_PER_KHZ;
+}
+
+static void get_ranges_from_chandef(struct cfg80211_chan_def *chandef,
+ struct wbrf_ranges_in_out *ranges_in)
+{
+ u64 start_freq1, end_freq1;
+ u64 start_freq2, end_freq2;
+ int bandwidth;
+
+ bandwidth = nl80211_chan_width_to_mhz(chandef->width);
+
+ get_chan_freq_boundary(chandef->center_freq1, bandwidth, &start_freq1, &end_freq1);
+
+ ranges_in->band_list[0].start = start_freq1;
+ ranges_in->band_list[0].end = end_freq1;
+ ranges_in->num_of_ranges = 1;
+
+ if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
+ get_chan_freq_boundary(chandef->center_freq2, bandwidth, &start_freq2, &end_freq2);
+
+ ranges_in->band_list[1].start = start_freq2;
+ ranges_in->band_list[1].end = end_freq2;
+ ranges_in->num_of_ranges++;
+ }
+}
+
+void ieee80211_add_wbrf(struct ieee80211_local *local, struct cfg80211_chan_def *chandef)
+{
+ struct wbrf_ranges_in_out ranges_in = {0};
+ struct device *dev;
+
+ if (!local->wbrf_supported)
+ return;
+
+ dev = local->hw.wiphy->dev.parent;
+
+ get_ranges_from_chandef(chandef, &ranges_in);
+
+ acpi_amd_wbrf_add_remove(dev, WBRF_RECORD_ADD, &ranges_in);
+}
+
+void ieee80211_remove_wbrf(struct ieee80211_local *local, struct cfg80211_chan_def *chandef)
+{
+ struct wbrf_ranges_in_out ranges_in = {0};
+ struct device *dev;
+
+ if (!local->wbrf_supported)
+ return;
+
+ dev = local->hw.wiphy->dev.parent;
+
+ get_ranges_from_chandef(chandef, &ranges_in);
+
+ acpi_amd_wbrf_add_remove(dev, WBRF_RECORD_REMOVE, &ranges_in);
+}
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 089c841528c8..72074fd36df4 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -25,7 +25,7 @@ ifneq ($(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR),)
cfg80211-y += extra-certs.o
endif
-$(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.hex)
+$(obj)/shipped-certs.c: $(sort $(wildcard $(srctree)/$(src)/certs/*.hex))
@$(kecho) " GEN $@"
$(Q)(echo '#include "reg.h"'; \
echo 'const u8 shipped_regdb_certs[] = {'; \
@@ -35,7 +35,7 @@ $(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.hex)
) > $@
$(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR) \
- $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR)/*.x509)
+ $(sort $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR)/*.x509))
@$(kecho) " GEN $@"
$(Q)(set -e; \
allf=""; \
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 2d21e423abdb..dfb4893421d7 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -141,7 +141,7 @@ static bool cfg80211_edmg_chandef_valid(const struct cfg80211_chan_def *chandef)
return true;
}
-static int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
+int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
{
int mhz;
@@ -190,6 +190,7 @@ static int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
}
return mhz;
}
+EXPORT_SYMBOL(nl80211_chan_width_to_mhz);
static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
{
diff --git a/net/wireless/core.h b/net/wireless/core.h
index cb61d33d4f1e..1963958263d2 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -458,6 +458,9 @@ int cfg80211_scan(struct cfg80211_registered_device *rdev);
extern struct work_struct cfg80211_disconnect_work;
+#define NL80211_BSS_USE_FOR_ALL (NL80211_BSS_USE_FOR_NORMAL | \
+ NL80211_BSS_USE_FOR_MLD_LINK)
+
void cfg80211_set_dfs_state(struct wiphy *wiphy,
const struct cfg80211_chan_def *chandef,
enum nl80211_dfs_state dfs_state);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index bad9e4fd842f..f635a8b6ca2e 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -22,7 +22,7 @@
void cfg80211_rx_assoc_resp(struct net_device *dev,
- struct cfg80211_rx_assoc_resp_data *data)
+ const struct cfg80211_rx_assoc_resp_data *data)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d0f499227c29..8b45fb420f4c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -818,6 +818,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
[NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
[NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG },
+ [NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA] = { .type = NLA_FLAG },
+ [NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
+ [NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
};
/* policy for the key attributes */
@@ -4855,7 +4858,7 @@ static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
return ERR_PTR(n_entries);
if (n_entries > wiphy->max_acl_mac_addrs)
- return ERR_PTR(-ENOTSUPP);
+ return ERR_PTR(-EOPNOTSUPP);
acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
if (!acl)
@@ -10410,6 +10413,15 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
break;
}
+ if (nla_put_u32(msg, NL80211_BSS_USE_FOR, res->use_for))
+ goto nla_put_failure;
+
+ if (res->cannot_use_reasons &&
+ nla_put_u64_64bit(msg, NL80211_BSS_CANNOT_USE_REASONS,
+ res->cannot_use_reasons,
+ NL80211_BSS_PAD))
+ goto nla_put_failure;
+
nla_nest_end(msg, bss);
genlmsg_end(msg, hdr);
@@ -10427,15 +10439,27 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
struct cfg80211_registered_device *rdev;
struct cfg80211_internal_bss *scan;
struct wireless_dev *wdev;
+ struct nlattr **attrbuf;
int start = cb->args[2], idx = 0;
+ bool dump_include_use_data;
int err;
- err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
- if (err)
+ attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
+ if (!attrbuf)
+ return -ENOMEM;
+
+ err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, attrbuf);
+ if (err) {
+ kfree(attrbuf);
return err;
+ }
/* nl80211_prepare_wdev_dump acquired it in the successful case */
__acquire(&rdev->wiphy.mtx);
+ dump_include_use_data =
+ attrbuf[NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA];
+ kfree(attrbuf);
+
spin_lock_bh(&rdev->bss_lock);
/*
@@ -10452,6 +10476,9 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
list_for_each_entry(scan, &rdev->bss_list, list) {
if (++idx <= start)
continue;
+ if (!dump_include_use_data &&
+ !(scan->pub.use_for & NL80211_BSS_USE_FOR_NORMAL))
+ continue;
if (nl80211_send_bss(skb, cb,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
rdev, wdev, scan) < 0) {
@@ -10903,12 +10930,13 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device *rdev,
const u8 *ssid, int ssid_len,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ int assoc_link_id, int link_id)
{
struct ieee80211_channel *chan;
struct cfg80211_bss *bss;
const u8 *bssid;
- u32 freq;
+ u32 freq, use_for = 0;
if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_WIPHY_FREQ])
return ERR_PTR(-EINVAL);
@@ -10923,10 +10951,16 @@ static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device
if (!chan)
return ERR_PTR(-EINVAL);
- bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid,
- ssid, ssid_len,
- IEEE80211_BSS_TYPE_ESS,
- IEEE80211_PRIVACY_ANY);
+ if (assoc_link_id >= 0)
+ use_for = NL80211_BSS_USE_FOR_MLD_LINK;
+ if (assoc_link_id == link_id)
+ use_for |= NL80211_BSS_USE_FOR_NORMAL;
+
+ bss = __cfg80211_get_bss(&rdev->wiphy, chan, bssid,
+ ssid, ssid_len,
+ IEEE80211_BSS_TYPE_ESS,
+ IEEE80211_PRIVACY_ANY,
+ use_for);
if (!bss)
return ERR_PTR(-ENOENT);
@@ -11105,7 +11139,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
goto free;
}
req.links[link_id].bss =
- nl80211_assoc_bss(rdev, ssid, ssid_len, attrs);
+ nl80211_assoc_bss(rdev, ssid, ssid_len, attrs,
+ req.link_id, link_id);
if (IS_ERR(req.links[link_id].bss)) {
err = PTR_ERR(req.links[link_id].bss);
req.links[link_id].bss = NULL;
@@ -11170,7 +11205,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
if (req.link_id >= 0)
return -EINVAL;
- req.bss = nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs);
+ req.bss = nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs,
+ -1, -1);
if (IS_ERR(req.bss))
return PTR_ERR(req.bss);
ap_addr = req.bss->bssid;
@@ -12179,16 +12215,18 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
return err;
}
-static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
+static int nl80211_set_pmksa(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
- int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_pmksa *pmksa) = NULL;
struct net_device *dev = info->user_ptr[1];
struct cfg80211_pmksa pmksa;
+ bool ap_pmksa_caching_support = false;
memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
+ ap_pmksa_caching_support = wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
+
if (!info->attrs[NL80211_ATTR_PMKID])
return -EINVAL;
@@ -12197,16 +12235,15 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_MAC]) {
pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
} else if (info->attrs[NL80211_ATTR_SSID] &&
- info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
- (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
- info->attrs[NL80211_ATTR_PMK])) {
+ info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
+ info->attrs[NL80211_ATTR_PMK]) {
pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
- pmksa.cache_id =
- nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
+ pmksa.cache_id = nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
} else {
return -EINVAL;
}
+
if (info->attrs[NL80211_ATTR_PMK]) {
pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
@@ -12218,32 +12255,71 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD])
pmksa.pmk_reauth_threshold =
- nla_get_u8(
- info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD]);
+ nla_get_u8(info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD]);
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
- !(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP &&
- wiphy_ext_feature_isset(&rdev->wiphy,
- NL80211_EXT_FEATURE_AP_PMKSA_CACHING)))
+ !((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
+ dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) &&
+ ap_pmksa_caching_support))
return -EOPNOTSUPP;
- switch (info->genlhdr->cmd) {
- case NL80211_CMD_SET_PMKSA:
- rdev_ops = rdev->ops->set_pmksa;
- break;
- case NL80211_CMD_DEL_PMKSA:
- rdev_ops = rdev->ops->del_pmksa;
- break;
- default:
- WARN_ON(1);
- break;
+ if (!rdev->ops->set_pmksa)
+ return -EOPNOTSUPP;
+
+ return rdev_set_pmksa(rdev, dev, &pmksa);
+}
+
+static int nl80211_del_pmksa(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct cfg80211_pmksa pmksa;
+ bool sae_offload_support = false;
+ bool owe_offload_support = false;
+ bool ap_pmksa_caching_support = false;
+
+ memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
+
+ sae_offload_support = wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_SAE_OFFLOAD);
+ owe_offload_support = wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_OWE_OFFLOAD);
+ ap_pmksa_caching_support = wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
+
+ if (info->attrs[NL80211_ATTR_PMKID])
+ pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
+
+ if (info->attrs[NL80211_ATTR_MAC]) {
+ pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ } else if (info->attrs[NL80211_ATTR_SSID]) {
+ /* SSID based pmksa flush suppported only for FILS,
+ * OWE/SAE OFFLOAD cases
+ */
+ if (info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
+ info->attrs[NL80211_ATTR_PMK]) {
+ pmksa.cache_id = nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
+ } else if (!sae_offload_support && !owe_offload_support) {
+ return -EINVAL;
+ }
+ pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+ pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+ } else {
+ return -EINVAL;
}
- if (!rdev_ops)
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
+ !((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
+ dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) &&
+ ap_pmksa_caching_support))
+ return -EOPNOTSUPP;
+
+ if (!rdev->ops->del_pmksa)
return -EOPNOTSUPP;
- return rdev_ops(&rdev->wiphy, dev, &pmksa);
+ return rdev_del_pmksa(rdev, dev, &pmksa);
}
static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
@@ -15847,7 +15923,7 @@ static int parse_tid_conf(struct cfg80211_registered_device *rdev,
if (tid_conf->mask & ~mask) {
NL_SET_ERR_MSG(extack, "unsupported TID configuration");
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
return 0;
@@ -16240,6 +16316,35 @@ static int nl80211_set_hw_timestamp(struct sk_buff *skb,
return rdev_set_hw_timestamp(rdev, dev, &hwts);
}
+static int
+nl80211_set_ttlm(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_ttlm_params params = {};
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
+
+ if (!wdev->connected)
+ return -ENOLINK;
+
+ if (!info->attrs[NL80211_ATTR_MLO_TTLM_DLINK] ||
+ !info->attrs[NL80211_ATTR_MLO_TTLM_ULINK])
+ return -EINVAL;
+
+ nla_memcpy(params.dlink,
+ info->attrs[NL80211_ATTR_MLO_TTLM_DLINK],
+ sizeof(params.dlink));
+ nla_memcpy(params.ulink,
+ info->attrs[NL80211_ATTR_MLO_TTLM_ULINK],
+ sizeof(params.ulink));
+
+ return rdev_set_ttlm(rdev, dev, &params);
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -16928,7 +17033,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
{
.cmd = NL80211_CMD_SET_PMKSA,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .doit = nl80211_setdel_pmksa,
+ .doit = nl80211_set_pmksa,
.flags = GENL_UNS_ADMIN_PERM,
.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_CLEAR_SKB),
@@ -16936,7 +17041,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
{
.cmd = NL80211_CMD_DEL_PMKSA,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .doit = nl80211_setdel_pmksa,
+ .doit = nl80211_del_pmksa,
.flags = GENL_UNS_ADMIN_PERM,
.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
},
@@ -17421,6 +17526,12 @@ static const struct genl_small_ops nl80211_small_ops[] = {
.flags = GENL_UNS_ADMIN_PERM,
.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
},
+ {
+ .cmd = NL80211_CMD_SET_TID_TO_LINK_MAPPING,
+ .doit = nl80211_set_ttlm,
+ .flags = GENL_UNS_ADMIN_PERM,
+ .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
+ },
};
static struct genl_family nl80211_fam __ro_after_init = {
@@ -17752,21 +17863,29 @@ nla_put_failure:
nlmsg_free(msg);
}
+struct nl80211_mlme_event {
+ enum nl80211_commands cmd;
+ const u8 *buf;
+ size_t buf_len;
+ int uapsd_queues;
+ const u8 *req_ies;
+ size_t req_ies_len;
+ bool reconnect;
+};
+
static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
- const u8 *buf, size_t len,
- enum nl80211_commands cmd, gfp_t gfp,
- int uapsd_queues, const u8 *req_ies,
- size_t req_ies_len, bool reconnect)
+ const struct nl80211_mlme_event *event,
+ gfp_t gfp)
{
struct sk_buff *msg;
void *hdr;
- msg = nlmsg_new(100 + len + req_ies_len, gfp);
+ msg = nlmsg_new(100 + event->buf_len + event->req_ies_len, gfp);
if (!msg)
return;
- hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
+ hdr = nl80211hdr_put(msg, 0, 0, 0, event->cmd);
if (!hdr) {
nlmsg_free(msg);
return;
@@ -17774,22 +17893,24 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
- nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
- (req_ies &&
- nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
+ nla_put(msg, NL80211_ATTR_FRAME, event->buf_len, event->buf) ||
+ (event->req_ies &&
+ nla_put(msg, NL80211_ATTR_REQ_IE, event->req_ies_len,
+ event->req_ies)))
goto nla_put_failure;
- if (reconnect && nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
+ if (event->reconnect &&
+ nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
goto nla_put_failure;
- if (uapsd_queues >= 0) {
+ if (event->uapsd_queues >= 0) {
struct nlattr *nla_wmm =
nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
if (!nla_wmm)
goto nla_put_failure;
if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
- uapsd_queues))
+ event->uapsd_queues))
goto nla_put_failure;
nla_nest_end(msg, nla_wmm);
@@ -17809,37 +17930,60 @@ void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *buf,
size_t len, gfp_t gfp)
{
- nl80211_send_mlme_event(rdev, netdev, buf, len,
- NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0,
- false);
+ struct nl80211_mlme_event event = {
+ .cmd = NL80211_CMD_AUTHENTICATE,
+ .buf = buf,
+ .buf_len = len,
+ .uapsd_queues = -1,
+ };
+
+ nl80211_send_mlme_event(rdev, netdev, &event, gfp);
}
void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
- struct cfg80211_rx_assoc_resp_data *data)
+ const struct cfg80211_rx_assoc_resp_data *data)
{
- nl80211_send_mlme_event(rdev, netdev, data->buf, data->len,
- NL80211_CMD_ASSOCIATE, GFP_KERNEL,
- data->uapsd_queues,
- data->req_ies, data->req_ies_len, false);
+ struct nl80211_mlme_event event = {
+ .cmd = NL80211_CMD_ASSOCIATE,
+ .buf = data->buf,
+ .buf_len = data->len,
+ .uapsd_queues = data->uapsd_queues,
+ .req_ies = data->req_ies,
+ .req_ies_len = data->req_ies_len,
+ };
+
+ nl80211_send_mlme_event(rdev, netdev, &event, GFP_KERNEL);
}
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *buf,
size_t len, bool reconnect, gfp_t gfp)
{
- nl80211_send_mlme_event(rdev, netdev, buf, len,
- NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0,
- reconnect);
+ struct nl80211_mlme_event event = {
+ .cmd = NL80211_CMD_DEAUTHENTICATE,
+ .buf = buf,
+ .buf_len = len,
+ .reconnect = reconnect,
+ .uapsd_queues = -1,
+ };
+
+ nl80211_send_mlme_event(rdev, netdev, &event, gfp);
}
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *buf,
size_t len, bool reconnect, gfp_t gfp)
{
- nl80211_send_mlme_event(rdev, netdev, buf, len,
- NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0,
- reconnect);
+ struct nl80211_mlme_event event = {
+ .cmd = NL80211_CMD_DISASSOCIATE,
+ .buf = buf,
+ .buf_len = len,
+ .reconnect = reconnect,
+ .uapsd_queues = -1,
+ };
+
+ nl80211_send_mlme_event(rdev, netdev, &event, gfp);
}
void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
@@ -17849,28 +17993,31 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
const struct ieee80211_mgmt *mgmt = (void *)buf;
- u32 cmd;
+ struct nl80211_mlme_event event = {
+ .buf = buf,
+ .buf_len = len,
+ .uapsd_queues = -1,
+ };
if (WARN_ON(len < 2))
return;
if (ieee80211_is_deauth(mgmt->frame_control)) {
- cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
+ event.cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
} else if (ieee80211_is_disassoc(mgmt->frame_control)) {
- cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
+ event.cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
} else if (ieee80211_is_beacon(mgmt->frame_control)) {
if (wdev->unprot_beacon_reported &&
elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000)
return;
- cmd = NL80211_CMD_UNPROT_BEACON;
+ event.cmd = NL80211_CMD_UNPROT_BEACON;
wdev->unprot_beacon_reported = jiffies;
} else {
return;
}
trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
- nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
- NULL, 0, false);
+ nl80211_send_mlme_event(rdev, dev, &event, GFP_ATOMIC);
}
EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index aad40240d9cb..6376f3a87f8a 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -60,7 +60,7 @@ void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
const u8 *buf, size_t len, gfp_t gfp);
void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
- struct cfg80211_rx_assoc_resp_data *data);
+ const struct cfg80211_rx_assoc_resp_data *data);
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *buf, size_t len,
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 2214a90cf101..43897a5269b6 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1046,7 +1046,7 @@ rdev_nan_change_conf(struct cfg80211_registered_device *rdev,
ret = rdev->ops->nan_change_conf(&rdev->wiphy, wdev, conf,
changes);
else
- ret = -ENOTSUPP;
+ ret = -EOPNOTSUPP;
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
@@ -1200,7 +1200,7 @@ rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
struct cfg80211_chan_def *chandef,
u32 cac_time_ms)
{
- int ret = -ENOTSUPP;
+ int ret = -EOPNOTSUPP;
trace_rdev_start_radar_detection(&rdev->wiphy, dev, chandef,
cac_time_ms);
@@ -1226,7 +1226,7 @@ rdev_set_mcast_rate(struct cfg80211_registered_device *rdev,
struct net_device *dev,
int mcast_rate[NUM_NL80211_BANDS])
{
- int ret = -ENOTSUPP;
+ int ret = -EOPNOTSUPP;
trace_rdev_set_mcast_rate(&rdev->wiphy, dev, mcast_rate);
if (rdev->ops->set_mcast_rate)
@@ -1239,7 +1239,7 @@ static inline int
rdev_set_coalesce(struct cfg80211_registered_device *rdev,
struct cfg80211_coalesce *coalesce)
{
- int ret = -ENOTSUPP;
+ int ret = -EOPNOTSUPP;
trace_rdev_set_coalesce(&rdev->wiphy, coalesce);
if (rdev->ops->set_coalesce)
@@ -1524,4 +1524,22 @@ rdev_set_hw_timestamp(struct cfg80211_registered_device *rdev,
return ret;
}
+
+static inline int
+rdev_set_ttlm(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_ttlm_params *params)
+{
+ struct wiphy *wiphy = &rdev->wiphy;
+ int ret;
+
+ if (!rdev->ops->set_ttlm)
+ return -EOPNOTSUPP;
+
+ trace_rdev_set_ttlm(wiphy, dev, params);
+ ret = rdev->ops->set_ttlm(wiphy, dev, params);
+ trace_rdev_return_int(wiphy, ret);
+
+ return ret;
+}
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9e5ccffd6868..3d260c99c348 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1535,12 +1535,13 @@ static bool cfg80211_bss_type_match(u16 capability,
}
/* Returned bss is reference counted and must be cleaned up appropriately. */
-struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
- struct ieee80211_channel *channel,
- const u8 *bssid,
- const u8 *ssid, size_t ssid_len,
- enum ieee80211_bss_type bss_type,
- enum ieee80211_privacy privacy)
+struct cfg80211_bss *__cfg80211_get_bss(struct wiphy *wiphy,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
+ const u8 *ssid, size_t ssid_len,
+ enum ieee80211_bss_type bss_type,
+ enum ieee80211_privacy privacy,
+ u32 use_for)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct cfg80211_internal_bss *bss, *res = NULL;
@@ -1565,6 +1566,8 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
continue;
if (!is_valid_ether_addr(bss->pub.bssid))
continue;
+ if ((bss->pub.use_for & use_for) != use_for)
+ continue;
/* Don't get expired BSS structs */
if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
!atomic_read(&bss->hold))
@@ -1582,7 +1585,7 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
trace_cfg80211_return_bss(&res->pub);
return &res->pub;
}
-EXPORT_SYMBOL(cfg80211_get_bss);
+EXPORT_SYMBOL(__cfg80211_get_bss);
static void rb_insert_bss(struct cfg80211_registered_device *rdev,
struct cfg80211_internal_bss *bss)
@@ -1746,7 +1749,9 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
new->pub.proberesp_ies);
if (old)
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
- } else if (rcu_access_pointer(new->pub.beacon_ies)) {
+ }
+
+ if (rcu_access_pointer(new->pub.beacon_ies)) {
const struct cfg80211_bss_ies *old;
if (known->pub.hidden_beacon_bss &&
@@ -1800,6 +1805,8 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
ether_addr_copy(known->parent_bssid, new->parent_bssid);
known->pub.max_bssid_indicator = new->pub.max_bssid_indicator;
known->pub.bssid_index = new->pub.bssid_index;
+ known->pub.use_for &= new->pub.use_for;
+ known->pub.cannot_use_reasons = new->pub.cannot_use_reasons;
return true;
}
@@ -2044,6 +2051,9 @@ struct cfg80211_inform_single_bss_data {
struct cfg80211_bss *source_bss;
u8 max_bssid_indicator;
u8 bssid_index;
+
+ u8 use_for;
+ u64 cannot_use_reasons;
};
/* Returned bss is reference counted and must be cleaned up appropriately. */
@@ -2089,6 +2099,8 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
tmp.ts_boottime = drv_data->boottime_ns;
tmp.parent_tsf = drv_data->parent_tsf;
ether_addr_copy(tmp.parent_bssid, drv_data->parent_bssid);
+ tmp.pub.use_for = data->use_for;
+ tmp.pub.cannot_use_reasons = data->cannot_use_reasons;
if (data->bss_source != BSS_SOURCE_DIRECT) {
tmp.pub.transmitted_bss = data->source_bss;
@@ -2259,6 +2271,8 @@ cfg80211_parse_mbssid_data(struct wiphy *wiphy,
.beacon_interval = tx_data->beacon_interval,
.source_bss = source_bss,
.bss_source = BSS_SOURCE_MBSSID,
+ .use_for = tx_data->use_for,
+ .cannot_use_reasons = tx_data->cannot_use_reasons,
};
const u8 *mbssid_index_ie;
const struct element *elem, *sub;
@@ -2521,7 +2535,7 @@ error:
return NULL;
}
-static bool
+static u8
cfg80211_tbtt_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
const struct ieee80211_neighbor_ap_info **ap_info,
const u8 **tbtt_info)
@@ -2540,6 +2554,7 @@ cfg80211_tbtt_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
u16 params;
u8 length, i, count, mld_params_offset;
u8 type, lid;
+ u32 use_for;
info = (void *)pos;
count = u8_get_bits(info->tbtt_info_hdr,
@@ -2549,20 +2564,22 @@ cfg80211_tbtt_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
pos += sizeof(*info);
if (count * length > end - pos)
- return false;
+ return 0;
type = u8_get_bits(info->tbtt_info_hdr,
IEEE80211_AP_INFO_TBTT_HDR_TYPE);
- /* Only accept full TBTT information. NSTR mobile APs
- * use the shortened version, but we ignore them here.
- */
if (type == IEEE80211_TBTT_INFO_TYPE_TBTT &&
length >=
offsetofend(struct ieee80211_tbtt_info_ge_11,
mld_params)) {
mld_params_offset =
offsetof(struct ieee80211_tbtt_info_ge_11, mld_params);
+ use_for = NL80211_BSS_USE_FOR_ALL;
+ } else if (type == IEEE80211_TBTT_INFO_TYPE_MLD &&
+ length >= sizeof(struct ieee80211_rnr_mld_params)) {
+ mld_params_offset = 0;
+ use_for = NL80211_BSS_USE_FOR_MLD_LINK;
} else {
pos += count * length;
continue;
@@ -2580,7 +2597,7 @@ cfg80211_tbtt_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
*ap_info = info;
*tbtt_info = pos;
- return true;
+ return use_for;
}
pos += length;
@@ -2588,7 +2605,7 @@ cfg80211_tbtt_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
}
}
- return false;
+ return 0;
}
static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
@@ -2606,6 +2623,7 @@ static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
const struct element *elem;
struct cfg80211_mle *mle;
u16 control;
+ u8 ml_common_len;
u8 *new_ie;
struct cfg80211_bss *bss;
int mld_id;
@@ -2636,6 +2654,8 @@ static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
!(control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP))
return;
+ ml_common_len = ml_elem->variable[0];
+
/* length + MLD MAC address + link ID info + BSS Params Change Count */
pos = ml_elem->variable + 1 + 6 + 1 + 1;
@@ -2676,7 +2696,7 @@ static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
const u8 *profile;
const u8 *tbtt_info;
ssize_t profile_len;
- u8 link_id;
+ u8 link_id, use_for;
if (!ieee80211_mle_basic_sta_prof_size_ok((u8 *)mle->sta_prof[i],
mle->sta_prof_len[i]))
@@ -2718,9 +2738,11 @@ static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
profile_len -= 2;
/* Find in RNR to look up channel information */
- if (!cfg80211_tbtt_info_for_mld_ap(tx_data->ie, tx_data->ielen,
- mld_id, link_id,
- &ap_info, &tbtt_info))
+ use_for = cfg80211_tbtt_info_for_mld_ap(tx_data->ie,
+ tx_data->ielen,
+ mld_id, link_id,
+ &ap_info, &tbtt_info);
+ if (!use_for)
continue;
/* We could sanity check the BSSID is included */
@@ -2732,6 +2754,14 @@ static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
freq = ieee80211_channel_to_freq_khz(ap_info->channel, band);
data.channel = ieee80211_get_channel_khz(wiphy, freq);
+ if (use_for == NL80211_BSS_USE_FOR_MLD_LINK &&
+ !(wiphy->flags & WIPHY_FLAG_SUPPORTS_NSTR_NONPRIMARY)) {
+ use_for = 0;
+ data.cannot_use_reasons =
+ NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY;
+ }
+ data.use_for = use_for;
+
/* Generate new elements */
memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
data.ie = new_ie;
@@ -2742,6 +2772,34 @@ static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
if (!data.ielen)
continue;
+ /* The generated elements do not contain:
+ * - Basic ML element
+ * - A TBTT entry in the RNR for the transmitting AP
+ *
+ * This information is needed both internally and in userspace
+ * as such, we should append it here.
+ */
+ if (data.ielen + 3 + sizeof(*ml_elem) + ml_common_len >
+ IEEE80211_MAX_DATA_LEN)
+ continue;
+
+ /* Copy the Basic Multi-Link element including the common
+ * information, and then fix up the link ID.
+ * Note that the ML element length has been verified and we
+ * also checked that it contains the link ID.
+ */
+ new_ie[data.ielen++] = WLAN_EID_EXTENSION;
+ new_ie[data.ielen++] = 1 + sizeof(*ml_elem) + ml_common_len;
+ new_ie[data.ielen++] = WLAN_EID_EXT_EHT_MULTI_LINK;
+ memcpy(new_ie + data.ielen, ml_elem,
+ sizeof(*ml_elem) + ml_common_len);
+
+ new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN] = link_id;
+
+ data.ielen += sizeof(*ml_elem) + ml_common_len;
+
+ /* TODO: Add an RNR containing only the reporting AP */
+
bss = cfg80211_inform_single_bss_data(wiphy, &data, gfp);
if (!bss)
break;
@@ -2769,6 +2827,10 @@ cfg80211_inform_bss_data(struct wiphy *wiphy,
.beacon_interval = beacon_interval,
.ie = ie,
.ielen = ielen,
+ .use_for = data->restrict_use ?
+ data->use_for :
+ NL80211_BSS_USE_FOR_ALL,
+ .cannot_use_reasons = data->cannot_use_reasons,
};
struct cfg80211_bss *res;
@@ -2899,6 +2961,10 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
tmp.pub.chains = data->chains;
memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS);
ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
+ tmp.pub.use_for = data->restrict_use ?
+ data->use_for :
+ NL80211_BSS_USE_FOR_ALL;
+ tmp.pub.cannot_use_reasons = data->cannot_use_reasons;
signal_valid = data->chan == channel;
spin_lock_bh(&rdev->bss_lock);
@@ -2930,6 +2996,10 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
.ie = mgmt->u.probe_resp.variable,
.ielen = len - offsetof(struct ieee80211_mgmt,
u.probe_resp.variable),
+ .use_for = data->restrict_use ?
+ data->use_for :
+ NL80211_BSS_USE_FOR_ALL,
+ .cannot_use_reasons = data->cannot_use_reasons,
};
struct cfg80211_bss *res;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 30cd1bd58aac..1f374c8a17a5 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2928,7 +2928,7 @@ DEFINE_EVENT(netdev_evt_only, cfg80211_send_rx_auth,
TRACE_EVENT(cfg80211_send_rx_assoc,
TP_PROTO(struct net_device *netdev,
- struct cfg80211_rx_assoc_resp_data *data),
+ const struct cfg80211_rx_assoc_resp_data *data),
TP_ARGS(netdev, data),
TP_STRUCT__entry(
NETDEV_ENTRY
@@ -3979,6 +3979,26 @@ TRACE_EVENT(cfg80211_links_removed,
__entry->link_mask)
);
+TRACE_EVENT(rdev_set_ttlm,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_ttlm_params *params),
+ TP_ARGS(wiphy, netdev, params),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ __array(u8, dlink, sizeof(u16) * 8)
+ __array(u8, ulink, sizeof(u16) * 8)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ memcpy(__entry->dlink, params->dlink, sizeof(params->dlink));
+ memcpy(__entry->ulink, params->ulink, sizeof(params->ulink));
+ ),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
+ WIPHY_PR_ARG, NETDEV_PR_ARG)
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH