summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig7
-rw-r--r--drivers/net/wireless/Makefile4
-rw-r--r--drivers/net/wireless/ath/ath10k/bmi.h10
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c10
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c343
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h42
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c516
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h11
-rw-r--r--drivers/net/wireless/ath/ath10k/hif.h26
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c51
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.h4
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c57
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h13
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c31
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c254
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h11
-rw-r--r--drivers/net/wireless/ath/ath10k/thermal.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c5
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h32
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c655
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h46
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_mbox.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/dfs_pattern_detector.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/Kconfig1
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile1
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c10
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c14
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/pmc.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c26
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c62
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h7
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h10
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_crash_dump.c115
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c2
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bus.h21
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c86
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/common.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c65
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.h11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/debug.c42
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/debug.h8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.h1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c71
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/pcie.c74
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c49
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c29
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h2
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig4
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c2
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c52
-rw-r--r--drivers/net/wireless/mwifiex/fw.h16
-rw-r--r--drivers/net/wireless/mwifiex/main.c1
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c31
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c25
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c16
-rw-r--r--drivers/net/wireless/mwifiex/usb.c14
-rw-r--r--drivers/net/wireless/mwifiex/usb.h5
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c2
-rw-r--r--drivers/net/wireless/realtek/Makefile9
-rw-r--r--drivers/net/wireless/realtek/rtl818x/Kconfig (renamed from drivers/net/wireless/rtl818x/Kconfig)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/Makefile (renamed from drivers/net/wireless/rtl818x/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/Makefile (renamed from drivers/net/wireless/rtl818x/rtl8180/Makefile)2
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c (renamed from drivers/net/wireless/rtl818x/rtl8180/dev.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.c (renamed from drivers/net/wireless/rtl818x/rtl8180/grf5101.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.h (renamed from drivers/net/wireless/rtl818x/rtl8180/grf5101.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.c (renamed from drivers/net/wireless/rtl818x/rtl8180/max2820.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.h (renamed from drivers/net/wireless/rtl818x/rtl8180/max2820.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8180.h (renamed from drivers/net/wireless/rtl818x/rtl8180/rtl8180.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c (renamed from drivers/net/wireless/rtl818x/rtl8180/rtl8225.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.h (renamed from drivers/net/wireless/rtl818x/rtl8180/rtl8225.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c (renamed from drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.h (renamed from drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.c (renamed from drivers/net/wireless/rtl818x/rtl8180/sa2400.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.h (renamed from drivers/net/wireless/rtl818x/rtl8180/sa2400.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/Makefile (renamed from drivers/net/wireless/rtl818x/rtl8187/Makefile)2
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c (renamed from drivers/net/wireless/rtl818x/rtl8187/dev.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c (renamed from drivers/net/wireless/rtl818x/rtl8187/leds.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/leds.h (renamed from drivers/net/wireless/rtl818x/rtl8187/leds.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.c (renamed from drivers/net/wireless/rtl818x/rtl8187/rfkill.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.h (renamed from drivers/net/wireless/rtl818x/rtl8187/rfkill.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.h (renamed from drivers/net/wireless/rtl818x/rtl8187/rtl8187.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c (renamed from drivers/net/wireless/rtl818x/rtl8187/rtl8225.c)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.h (renamed from drivers/net/wireless/rtl818x/rtl8187/rtl8225.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl818x.h (renamed from drivers/net/wireless/rtl818x/rtl818x.h)0
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/Kconfig34
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/Makefile1
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c5993
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h676
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h981
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/Kconfig (renamed from drivers/net/wireless/rtlwifi/Kconfig)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/Makefile (renamed from drivers/net/wireless/rtlwifi/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.c (renamed from drivers/net/wireless/rtlwifi/base.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.h (renamed from drivers/net/wireless/rtlwifi/base.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/Makefile (renamed from drivers/net/wireless/rtlwifi/btcoexist/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbt_precomp.h (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.h (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.h (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.h (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h (renamed from drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c (renamed from drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h (renamed from drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/cam.c (renamed from drivers/net/wireless/rtlwifi/cam.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/cam.h (renamed from drivers/net/wireless/rtlwifi/cam.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/core.c (renamed from drivers/net/wireless/rtlwifi/core.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/core.h (renamed from drivers/net/wireless/rtlwifi/core.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/debug.c (renamed from drivers/net/wireless/rtlwifi/debug.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/debug.h (renamed from drivers/net/wireless/rtlwifi/debug.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/efuse.c (renamed from drivers/net/wireless/rtlwifi/efuse.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/efuse.h (renamed from drivers/net/wireless/rtlwifi/efuse.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pci.c (renamed from drivers/net/wireless/rtlwifi/pci.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pci.h (renamed from drivers/net/wireless/rtlwifi/pci.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/ps.c (renamed from drivers/net/wireless/rtlwifi/ps.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/ps.h (renamed from drivers/net/wireless/rtlwifi/ps.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pwrseqcmd.h (renamed from drivers/net/wireless/rtlwifi/pwrseqcmd.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rc.c (renamed from drivers/net/wireless/rtlwifi/rc.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rc.h (renamed from drivers/net/wireless/rtlwifi/rc.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/regd.c (renamed from drivers/net/wireless/rtlwifi/regd.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/regd.h (renamed from drivers/net/wireless/rtlwifi/regd.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/fw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/fw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/hw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8188ee/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192c/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8192c/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c (renamed from drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.h (renamed from drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c (renamed from drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.h (renamed from drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192c/main.c (renamed from drivers/net/wireless/rtlwifi/rtl8192c/main.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c (renamed from drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h (renamed from drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/hw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ce/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/hw.c)8
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/mac.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/mac.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8192cu/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8192de/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/fw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/fw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/hw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8192de/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8192de/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/fw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/fw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/hw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/pwrseq.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/pwrseq.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8192ee/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8192se/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/fw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/fw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/hw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8192se/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8192se/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/btc.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/btc.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/fw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/fw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/hw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8723ae/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8723be/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/fw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/fw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/hw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8723be/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8723be/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723com/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8723com/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.c (renamed from drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.h (renamed from drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c (renamed from drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h (renamed from drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723com/main.c (renamed from drivers/net/wireless/rtlwifi/rtl8723com/main.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c (renamed from drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.h (renamed from drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/Makefile (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/Makefile)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/def.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/def.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/dm.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/dm.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/fw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/fw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/hw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/hw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/led.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/led.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/phy.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/phy.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/reg.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/reg.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/rf.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/rf.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/sw.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/sw.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/table.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/table.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/trx.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h (renamed from drivers/net/wireless/rtlwifi/rtl8821ae/trx.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/stats.c (renamed from drivers/net/wireless/rtlwifi/stats.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/stats.h (renamed from drivers/net/wireless/rtlwifi/stats.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/usb.c (renamed from drivers/net/wireless/rtlwifi/usb.c)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/usb.h (renamed from drivers/net/wireless/rtlwifi/usb.h)0
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/wifi.h (renamed from drivers/net/wireless/rtlwifi/wifi.h)0
367 files changed, 10073 insertions, 728 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index a63ab2e..f9f9422 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -214,8 +214,6 @@ config USB_NET_RNDIS_WLAN
If you choose to build a module, it'll be called rndis_wlan.
-source "drivers/net/wireless/rtl818x/Kconfig"
-
config ADM8211
tristate "ADMtek ADM8211 support"
depends on MAC80211 && PCI
@@ -243,6 +241,8 @@ config ADM8211
Thanks to Infineon-ADMtek for their support of this driver.
+source "drivers/net/wireless/realtek/rtl818x/Kconfig"
+
config MAC80211_HWSIM
tristate "Simulated radio testing tool for mac80211"
depends on MAC80211
@@ -278,7 +278,8 @@ source "drivers/net/wireless/orinoco/Kconfig"
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
source "drivers/net/wireless/mediatek/Kconfig"
-source "drivers/net/wireless/rtlwifi/Kconfig"
+source "drivers/net/wireless/realtek/rtlwifi/Kconfig"
+source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig"
source "drivers/net/wireless/ti/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
source "drivers/net/wireless/mwifiex/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 6b9e729..740fdd3 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -22,9 +22,7 @@ obj-$(CONFIG_HOSTAP) += hostap/
obj-$(CONFIG_B43) += b43/
obj-$(CONFIG_B43LEGACY) += b43legacy/
obj-$(CONFIG_ZD1211RW) += zd1211rw/
-obj-$(CONFIG_RTL8180) += rtl818x/
-obj-$(CONFIG_RTL8187) += rtl818x/
-obj-$(CONFIG_RTLWIFI) += rtlwifi/
+obj-$(CONFIG_WLAN) += realtek/
# 16-bit wireless PCMCIA client drivers
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
diff --git a/drivers/net/wireless/ath/ath10k/bmi.h b/drivers/net/wireless/ath/ath10k/bmi.h
index df7c761..7d3231a 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.h
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
@@ -82,6 +82,16 @@ enum bmi_cmd_id {
#define BMI_NVRAM_SEG_NAME_SZ 16
+#define BMI_PARAM_GET_EEPROM_BOARD_ID 0x10
+
+#define ATH10K_BMI_BOARD_ID_FROM_OTP_MASK 0x7c00
+#define ATH10K_BMI_BOARD_ID_FROM_OTP_LSB 10
+
+#define ATH10K_BMI_CHIP_ID_FROM_OTP_MASK 0x18000
+#define ATH10K_BMI_CHIP_ID_FROM_OTP_LSB 15
+
+#define ATH10K_BMI_BOARD_ID_STATUS_MASK 0xff
+
struct bmi_cmd {
__le32 id; /* enum bmi_cmd_id */
union {
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index cf28fbe..84220c3 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -413,7 +413,7 @@ int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
lockdep_assert_held(&ar_pci->ce_lock);
if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) == 0)
- return -EIO;
+ return -ENOSPC;
desc->addr = __cpu_to_le32(paddr);
desc->nbytes = 0;
@@ -1076,9 +1076,7 @@ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id)
}
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
- const struct ce_attr *attr,
- void (*send_cb)(struct ath10k_ce_pipe *),
- void (*recv_cb)(struct ath10k_ce_pipe *))
+ const struct ce_attr *attr)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
@@ -1104,10 +1102,10 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
ce_state->src_sz_max = attr->src_sz_max;
if (attr->src_nentries)
- ce_state->send_cb = send_cb;
+ ce_state->send_cb = attr->send_cb;
if (attr->dest_nentries)
- ce_state->recv_cb = recv_cb;
+ ce_state->recv_cb = attr->recv_cb;
if (attr->src_nentries) {
ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr);
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index 5c903e15..dbb94fd 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -209,9 +209,7 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
const struct ce_attr *attr);
void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
- const struct ce_attr *attr,
- void (*send_cb)(struct ath10k_ce_pipe *),
- void (*recv_cb)(struct ath10k_ce_pipe *));
+ const struct ce_attr *attr);
void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);
/*==================CE Engine Shutdown=======================*/
@@ -277,6 +275,9 @@ struct ce_attr {
/* #entries in destination ring - Must be a power of 2 */
unsigned int dest_nentries;
+
+ void (*send_cb)(struct ath10k_ce_pipe *);
+ void (*recv_cb)(struct ath10k_ce_pipe *);
};
#define SR_BA_ADDRESS 0x0000
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 879625a..13de361 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -448,6 +448,56 @@ out:
return ret;
}
+static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
+{
+ u32 result, address;
+ u8 board_id, chip_id;
+ int ret;
+
+ address = ar->hw_params.patch_load_addr;
+
+ if (!ar->otp_data || !ar->otp_len) {
+ ath10k_warn(ar,
+ "failed to retrieve board id because of invalid otp\n");
+ return -ENODATA;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "boot upload otp to 0x%x len %zd for board id\n",
+ address, ar->otp_len);
+
+ ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
+ if (ret) {
+ ath10k_err(ar, "could not write otp for board id check: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = ath10k_bmi_execute(ar, address, BMI_PARAM_GET_EEPROM_BOARD_ID,
+ &result);
+ if (ret) {
+ ath10k_err(ar, "could not execute otp for board id check: %d\n",
+ ret);
+ return ret;
+ }
+
+ board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP);
+ chip_id = MS(result, ATH10K_BMI_CHIP_ID_FROM_OTP);
+
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "boot get otp board id result 0x%08x board_id %d chip_id %d\n",
+ result, board_id, chip_id);
+
+ if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0)
+ return -EOPNOTSUPP;
+
+ ar->id.bmi_ids_valid = true;
+ ar->id.bmi_board_id = board_id;
+ ar->id.bmi_chip_id = chip_id;
+
+ return 0;
+}
+
static int ath10k_download_and_run_otp(struct ath10k *ar)
{
u32 result, address = ar->hw_params.patch_load_addr;
@@ -486,8 +536,8 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
- ar->fw_features))
- && result != 0) {
+ ar->fw_features)) &&
+ result != 0) {
ath10k_err(ar, "otp calibration failed: %d", result);
return -EINVAL;
}
@@ -510,7 +560,7 @@ static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
data_len = ar->firmware_len;
mode_name = "normal";
ret = ath10k_swap_code_seg_configure(ar,
- ATH10K_SWAP_CODE_SEG_BIN_TYPE_FW);
+ ATH10K_SWAP_CODE_SEG_BIN_TYPE_FW);
if (ret) {
ath10k_err(ar, "failed to configure fw code swap: %d\n",
ret);
@@ -541,11 +591,18 @@ static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
return ret;
}
-static void ath10k_core_free_firmware_files(struct ath10k *ar)
+static void ath10k_core_free_board_files(struct ath10k *ar)
{
if (!IS_ERR(ar->board))
release_firmware(ar->board);
+ ar->board = NULL;
+ ar->board_data = NULL;
+ ar->board_len = 0;
+}
+
+static void ath10k_core_free_firmware_files(struct ath10k *ar)
+{
if (!IS_ERR(ar->otp))
release_firmware(ar->otp);
@@ -557,10 +614,6 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar)
ath10k_swap_code_seg_release(ar);
- ar->board = NULL;
- ar->board_data = NULL;
- ar->board_len = 0;
-
ar->otp = NULL;
ar->otp_data = NULL;
ar->otp_len = 0;
@@ -570,7 +623,6 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar)
ar->firmware_len = 0;
ar->cal_file = NULL;
-
}
static int ath10k_fetch_cal_file(struct ath10k *ar)
@@ -592,68 +644,251 @@ static int ath10k_fetch_cal_file(struct ath10k *ar)
return 0;
}
-static int ath10k_core_fetch_spec_board_file(struct ath10k *ar)
+static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar)
{
- char filename[100];
-
- scnprintf(filename, sizeof(filename), "board-%s-%s.bin",
- ath10k_bus_str(ar->hif.bus), ar->spec_board_id);
+ if (!ar->hw_params.fw.board) {
+ ath10k_err(ar, "failed to find board file fw entry\n");
+ return -EINVAL;
+ }
- ar->board = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, filename);
+ ar->board = ath10k_fetch_fw_file(ar,
+ ar->hw_params.fw.dir,
+ ar->hw_params.fw.board);
if (IS_ERR(ar->board))
return PTR_ERR(ar->board);
ar->board_data = ar->board->data;
ar->board_len = ar->board->size;
- ar->spec_board_loaded = true;
return 0;
}
-static int ath10k_core_fetch_generic_board_file(struct ath10k *ar)
+static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,
+ const void *buf, size_t buf_len,
+ const char *boardname)
{
- if (!ar->hw_params.fw.board) {
- ath10k_err(ar, "failed to find board file fw entry\n");
- return -EINVAL;
+ const struct ath10k_fw_ie *hdr;
+ bool name_match_found;
+ int ret, board_ie_id;
+ size_t board_ie_len;
+ const void *board_ie_data;
+
+ name_match_found = false;
+
+ /* go through ATH10K_BD_IE_BOARD_ elements */
+ while (buf_len > sizeof(struct ath10k_fw_ie)) {
+ hdr = buf;
+ board_ie_id = le32_to_cpu(hdr->id);
+ board_ie_len = le32_to_cpu(hdr->len);
+ board_ie_data = hdr->data;
+
+ buf_len -= sizeof(*hdr);
+ buf += sizeof(*hdr);
+
+ if (buf_len < ALIGN(board_ie_len, 4)) {
+ ath10k_err(ar, "invalid ATH10K_BD_IE_BOARD length: %zu < %zu\n",
+ buf_len, ALIGN(board_ie_len, 4));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ switch (board_ie_id) {
+ case ATH10K_BD_IE_BOARD_NAME:
+ ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "board name", "",
+ board_ie_data, board_ie_len);
+
+ if (board_ie_len != strlen(boardname))
+ break;
+
+ ret = memcmp(board_ie_data, boardname, strlen(boardname));
+ if (ret)
+ break;
+
+ name_match_found = true;
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "boot found match for name '%s'",
+ boardname);
+ break;
+ case ATH10K_BD_IE_BOARD_DATA:
+ if (!name_match_found)
+ /* no match found */
+ break;
+
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "boot found board data for '%s'",
+ boardname);
+
+ ar->board_data = board_ie_data;
+ ar->board_len = board_ie_len;
+
+ ret = 0;
+ goto out;
+ default:
+ ath10k_warn(ar, "unknown ATH10K_BD_IE_BOARD found: %d\n",
+ board_ie_id);
+ break;
+ }
+
+ /* jump over the padding */
+ board_ie_len = ALIGN(board_ie_len, 4);
+
+ buf_len -= board_ie_len;
+ buf += board_ie_len;
}
- ar->board = ath10k_fetch_fw_file(ar,
- ar->hw_params.fw.dir,
- ar->hw_params.fw.board);
+ /* no match found */
+ ret = -ENOENT;
+
+out:
+ return ret;
+}
+
+static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
+ const char *boardname,
+ const char *filename)
+{
+ size_t len, magic_len, ie_len;
+ struct ath10k_fw_ie *hdr;
+ const u8 *data;
+ int ret, ie_id;
+
+ ar->board = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, filename);
if (IS_ERR(ar->board))
return PTR_ERR(ar->board);
- ar->board_data = ar->board->data;
- ar->board_len = ar->board->size;
- ar->spec_board_loaded = false;
+ data = ar->board->data;
+ len = ar->board->size;
+
+ /* magic has extra null byte padded */
+ magic_len = strlen(ATH10K_BOARD_MAGIC) + 1;
+ if (len < magic_len) {
+ ath10k_err(ar, "failed to find magic value in %s/%s, file too short: %zu\n",
+ ar->hw_params.fw.dir, filename, len);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (memcmp(data, ATH10K_BOARD_MAGIC, magic_len)) {
+ ath10k_err(ar, "found invalid board magic\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* magic is padded to 4 bytes */
+ magic_len = ALIGN(magic_len, 4);
+ if (len < magic_len) {
+ ath10k_err(ar, "failed: %s/%s too small to contain board data, len: %zu\n",
+ ar->hw_params.fw.dir, filename, len);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ data += magic_len;
+ len -= magic_len;
+
+ while (len > sizeof(struct ath10k_fw_ie)) {
+ hdr = (struct ath10k_fw_ie *)data;
+ ie_id = le32_to_cpu(hdr->id);
+ ie_len = le32_to_cpu(hdr->len);
+
+ len -= sizeof(*hdr);
+ data = hdr->data;
+
+ if (len < ALIGN(ie_len, 4)) {
+ ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
+ ie_id, ie_len, len);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ switch (ie_id) {
+ case ATH10K_BD_IE_BOARD:
+ ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
+ boardname);
+ if (ret == -ENOENT)
+ /* no match found, continue */
+ break;
+ else if (ret)
+ /* there was an error, bail out */
+ goto err;
+
+ /* board data found */
+ goto out;
+ }
+
+ /* jump over the padding */
+ ie_len = ALIGN(ie_len, 4);
+
+ len -= ie_len;
+ data += ie_len;
+ }
+
+out:
+ if (!ar->board_data || !ar->board_len) {
+ ath10k_err(ar,
+ "failed to fetch board data for %s from %s/%s\n",
+ ar->hw_params.fw.dir, boardname, filename);
+ ret = -ENODATA;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ ath10k_core_free_board_files(ar);
+ return ret;
+}
+
+static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
+ size_t name_len)
+{
+ if (ar->id.bmi_ids_valid) {
+ scnprintf(name, name_len,
+ "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
+ ath10k_bus_str(ar->hif.bus),
+ ar->id.bmi_chip_id,
+ ar->id.bmi_board_id);
+ goto out;
+ }
+
+ scnprintf(name, name_len,
+ "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
+ ath10k_bus_str(ar->hif.bus),
+ ar->id.vendor, ar->id.device,
+ ar->id.subsystem_vendor, ar->id.subsystem_device);
+
+out:
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
return 0;
}
static int ath10k_core_fetch_board_file(struct ath10k *ar)
{
+ char boardname[100];
int ret;
- if (strlen(ar->spec_board_id) > 0) {
- ret = ath10k_core_fetch_spec_board_file(ar);
- if (ret) {
- ath10k_info(ar, "failed to load spec board file, falling back to generic: %d\n",
- ret);
- goto generic;
- }
-
- ath10k_dbg(ar, ATH10K_DBG_BOOT, "found specific board file for %s\n",
- ar->spec_board_id);
- return 0;
+ ret = ath10k_core_create_board_name(ar, boardname, sizeof(boardname));
+ if (ret) {
+ ath10k_err(ar, "failed to create board name: %d", ret);
+ return ret;
}
-generic:
- ret = ath10k_core_fetch_generic_board_file(ar);
+ ar->bd_api = 2;
+ ret = ath10k_core_fetch_board_data_api_n(ar, boardname,
+ ATH10K_BOARD_API2_FILE);
+ if (!ret)
+ goto success;
+
+ ar->bd_api = 1;
+ ret = ath10k_core_fetch_board_data_api_1(ar);
if (ret) {
- ath10k_err(ar, "failed to fetch generic board data: %d\n", ret);
+ ath10k_err(ar, "failed to fetch board data\n");
return ret;
}
+success:
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "using board api %d\n", ar->bd_api);
return 0;
}
@@ -885,12 +1120,6 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
/* calibration file is optional, don't check for any errors */
ath10k_fetch_cal_file(ar);
- ret = ath10k_core_fetch_board_file(ar);
- if (ret) {
- ath10k_err(ar, "failed to fetch board file: %d\n", ret);
- return ret;
- }
-
ar->fw_api = 5;
ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
@@ -1263,10 +1492,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
goto err;
/* Some of of qca988x solutions are having global reset issue
- * during target initialization. Bypassing PLL setting before
- * downloading firmware and letting the SoC run on REF_CLK is
- * fixing the problem. Corresponding firmware change is also needed
- * to set the clock source once the target is initialized.
+ * during target initialization. Bypassing PLL setting before
+ * downloading firmware and letting the SoC run on REF_CLK is
+ * fixing the problem. Corresponding firmware change is also needed
+ * to set the clock source once the target is initialized.
*/
if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
ar->fw_features)) {
@@ -1500,6 +1729,19 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_power_down;
}
+ ret = ath10k_core_get_board_id_from_otp(ar);
+ if (ret && ret != -EOPNOTSUPP) {
+ ath10k_err(ar, "failed to get board id from otp for qca99x0: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = ath10k_core_fetch_board_file(ar);
+ if (ret) {
+ ath10k_err(ar, "failed to fetch board file: %d\n", ret);
+ goto err_free_firmware_files;
+ }
+
ret = ath10k_core_init_firmware_features(ar);
if (ret) {
ath10k_err(ar, "fatal problem with firmware features: %d\n",
@@ -1627,6 +1869,7 @@ void ath10k_core_unregister(struct ath10k *ar)
ath10k_testmode_destroy(ar);
ath10k_core_free_firmware_files(ar);
+ ath10k_core_free_board_files(ar);
ath10k_debug_unregister(ar);
}
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 04e040a..7cc7cdd 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -250,6 +250,30 @@ struct ath10k_fw_stats {
struct list_head peers;
};
+#define ATH10K_TPC_TABLE_TYPE_FLAG 1
+#define ATH10K_TPC_PREAM_TABLE_END 0xFFFF
+
+struct ath10k_tpc_table {
+ u32 pream_idx[WMI_TPC_RATE_MAX];
+ u8 rate_code[WMI_TPC_RATE_MAX];
+ char tpc_value[WMI_TPC_RATE_MAX][WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
+};
+
+struct ath10k_tpc_stats {
+ u32 reg_domain;
+ u32 chan_freq;
+ u32 phy_mode;
+ u32 twice_antenna_reduction;
+ u32 twice_max_rd_power;
+ s32 twice_antenna_gain;
+ u32 power_limit;
+ u32 num_tx_chain;
+ u32 ctl;
+ u32 rate_max;
+ u8 flag[WMI_TPC_FLAG];
+ struct ath10k_tpc_table tpc_table[WMI_TPC_FLAG];
+};
+
struct ath10k_dfs_stats {
u32 phy_errors;
u32 pulses_total;
@@ -378,6 +402,11 @@ struct ath10k_debug {
struct ath10k_dfs_stats dfs_stats;
struct ath_dfs_pool_stats dfs_pool_stats;
+ /* used for tpc-dump storage, protected by data-lock */
+ struct ath10k_tpc_stats *tpc_stats;
+
+ struct completion tpc_complete;
+
/* protected by conf_mutex */
u32 fw_dbglog_mask;
u32 fw_dbglog_level;
@@ -647,10 +676,19 @@ struct ath10k {
struct ath10k_swap_code_seg_info *firmware_swap_code_seg_info;
} swap;
- char spec_board_id[100];
- bool spec_board_loaded;
+ struct {
+ u32 vendor;
+ u32 device;
+ u32 subsystem_vendor;
+ u32 subsystem_device;
+
+ bool bmi_ids_valid;
+ u8 bmi_board_id;
+ u8 bmi_chip_id;
+ } id;
int fw_api;
+ int bd_api;
enum ath10k_cal_mode cal_mode;
struct {
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index bf033f4..6cc1aa3 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -125,19 +125,25 @@ EXPORT_SYMBOL(ath10k_info);
void ath10k_print_driver_info(struct ath10k *ar)
{
char fw_features[128] = {};
+ char boardinfo[100];
ath10k_core_get_fw_features_str(ar, fw_features, sizeof(fw_features));
- ath10k_info(ar, "%s (0x%08x, 0x%08x%s%s%s) fw %s api %d htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d features %s\n",
+ if (ar->id.bmi_ids_valid)
+ scnprintf(boardinfo, sizeof(boardinfo), "bmi %d:%d",
+ ar->id.bmi_chip_id, ar->id.bmi_board_id);
+ else
+ scnprintf(boardinfo, sizeof(boardinfo), "sub %04x:%04x",
+ ar->id.subsystem_vendor, ar->id.subsystem_device);
+
+ ath10k_info(ar, "%s (0x%08x, 0x%08x %s) fw %s fwapi %d bdapi %d htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d features %s\n",
ar->hw_params.name,
ar->target_version,
ar->chip_id,
- (strlen(ar->spec_board_id) > 0 ? ", " : ""),
- ar->spec_board_id,
- (strlen(ar->spec_board_id) > 0 && !ar->spec_board_loaded
- ? " fallback" : ""),
+ boardinfo,
ar->hw->wiphy->fw_version,
ar->fw_api,
+ ar->bd_api,
ar->htt.target_version_major,
ar->htt.target_version_minor,
ar->wmi.op_version,
@@ -285,28 +291,6 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
spin_unlock_bh(&ar->data_lock);
}
-static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head)
-{
- struct ath10k_fw_stats_peer *i;
- size_t num = 0;
-
- list_for_each_entry(i, head, list)
- ++num;
-
- return num;
-}
-
-static size_t ath10k_debug_fw_stats_num_vdevs(struct list_head *head)
-{
- struct ath10k_fw_stats_vdev *i;
- size_t num = 0;
-
- list_for_each_entry(i, head, list)
- ++num;
-
- return num;
-}
-
void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
{
struct ath10k_fw_stats stats = {};
@@ -343,8 +327,8 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
goto free;
}
- num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers);
- num_vdevs = ath10k_debug_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
+ num_peers = ath10k_wmi_fw_stats_num_peers(&ar->debug.fw_stats.peers);
+ num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
!list_empty(&stats.pdevs));
is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
@@ -429,240 +413,6 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar)
return 0;
}
-/* FIXME: How to calculate the buffer size sanely? */
-#define ATH10K_FW_STATS_BUF_SIZE (1024*1024)
-
-static void ath10k_fw_stats_fill(struct ath10k *ar,
- struct ath10k_fw_stats *fw_stats,
- char *buf)
-{
- unsigned int len = 0;
- unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
- const struct ath10k_fw_stats_pdev *pdev;
- const struct ath10k_fw_stats_vdev *vdev;
- const struct ath10k_fw_stats_peer *peer;
- size_t num_peers;
- size_t num_vdevs;
- int i;
-
- spin_lock_bh(&ar->data_lock);
-
- pdev = list_first_entry_or_null(&fw_stats->pdevs,
- struct ath10k_fw_stats_pdev, list);
- if (!pdev) {
- ath10k_warn(ar, "failed to get pdev stats\n");
- goto unlock;
- }
-
- num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers);
- num_vdevs = ath10k_debug_fw_stats_num_vdevs(&fw_stats->vdevs);
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%30s\n",
- "ath10k PDEV stats");
- len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
- "=================");
-
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Channel noise floor", pdev->ch_noise_floor);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "Channel TX power", pdev->chan_tx_power);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "TX frame count", pdev->tx_frame_count);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "RX frame count", pdev->rx_frame_count);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "RX clear count", pdev->rx_clear_count);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "Cycle count", pdev->cycle_count);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "PHY error count", pdev->phy_err_count);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "RTS bad count", pdev->rts_bad);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "RTS good count", pdev->rts_good);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "FCS bad count", pdev->fcs_bad);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "No beacon count", pdev->no_beacons);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "MIB int count", pdev->mib_int_count);
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%30s\n",
- "ath10k PDEV TX stats");
- len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
- "=================");
-
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "HTT cookies queued", pdev->comp_queued);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "HTT cookies disp.", pdev->comp_delivered);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MSDU queued", pdev->msdu_enqued);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MPDU queued", pdev->mpdu_enqued);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MSDUs dropped", pdev->wmm_drop);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Local enqued", pdev->local_enqued);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Local freed", pdev->local_freed);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "HW queued", pdev->hw_queued);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "PPDUs reaped", pdev->hw_reaped);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Num underruns", pdev->underrun);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "PPDUs cleaned", pdev->tx_abort);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MPDUs requed", pdev->mpdus_requed);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Excessive retries", pdev->tx_ko);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "HW rate", pdev->data_rc);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Sched self tiggers", pdev->self_triggers);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Dropped due to SW retries",
- pdev->sw_retry_failure);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Illegal rate phy errors",
- pdev->illgl_rate_phy_err);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Pdev continous xretry", pdev->pdev_cont_xretry);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "TX timeout", pdev->pdev_tx_timeout);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "PDEV resets", pdev->pdev_resets);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "PHY underrun", pdev->phy_underrun);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MPDU is more than txop limit", pdev->txop_ovf);
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%30s\n",
- "ath10k PDEV RX stats");
- len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
- "=================");
-
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Mid PPDU route change",
- pdev->mid_ppdu_route_change);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Tot. number of statuses", pdev->status_rcvd);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Extra frags on rings 0", pdev->r0_frags);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Extra frags on rings 1", pdev->r1_frags);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Extra frags on rings 2", pdev->r2_frags);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Extra frags on rings 3", pdev->r3_frags);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MSDUs delivered to HTT", pdev->htt_msdus);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MPDUs delivered to HTT", pdev->htt_mpdus);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MSDUs delivered to stack", pdev->loc_msdus);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MPDUs delivered to stack", pdev->loc_mpdus);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "Oversized AMSUs", pdev->oversize_amsdu);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "PHY errors", pdev->phy_errs);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "PHY errors drops", pdev->phy_err_drop);
- len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
- "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
- "ath10k VDEV stats", num_vdevs);
- len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
- "=================");
-
- list_for_each_entry(vdev, &fw_stats->vdevs, list) {
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "vdev id", vdev->vdev_id);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "beacon snr", vdev->beacon_snr);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "data snr", vdev->data_snr);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "num rx frames", vdev->num_rx_frames);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "num rts fail", vdev->num_rts_fail);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "num rts success", vdev->num_rts_success);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "num rx err", vdev->num_rx_err);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "num rx discard", vdev->num_rx_discard);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "num tx not acked", vdev->num_tx_not_acked);
-
- for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
- len += scnprintf(buf + len, buf_len - len,
- "%25s [%02d] %u\n",
- "num tx frames", i,
- vdev->num_tx_frames[i]);
-
- for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
- len += scnprintf(buf + len, buf_len - len,
- "%25s [%02d] %u\n",
- "num tx frames retries", i,
- vdev->num_tx_frames_retries[i]);
-
- for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
- len += scnprintf(buf + len, buf_len - len,
- "%25s [%02d] %u\n",
- "num tx frames failures", i,
- vdev->num_tx_frames_failures[i]);
-
- for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
- len += scnprintf(buf + len, buf_len - len,
- "%25s [%02d] 0x%08x\n",
- "tx rate history", i,
- vdev->tx_rate_history[i]);
-
- for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
- len += scnprintf(buf + len, buf_len - len,
- "%25s [%02d] %u\n",
- "beacon rssi history", i,
- vdev->beacon_rssi_history[i]);
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- }
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
- "ath10k PEER stats", num_peers);
- len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
- "=================");
-
- list_for_each_entry(peer, &fw_stats->peers, list) {
- len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
- "Peer MAC address", peer->peer_macaddr);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "Peer RSSI", peer->peer_rssi);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "Peer TX rate", peer->peer_tx_rate);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "Peer RX rate", peer->peer_rx_rate);
- len += scnprintf(buf + len, buf_len - len, "\n");
- }
-
-unlock:
- spin_unlock_bh(&ar->data_lock);
-
- if (len >= buf_len)
- buf[len - 1] = 0;
- else
- buf[len] = 0;
-}
-
static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
{
struct ath10k *ar = inode->i_private;
@@ -688,7 +438,12 @@ static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
goto err_free;
}
- ath10k_fw_stats_fill(ar, &ar->debug.fw_stats, buf);
+ ret = ath10k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, buf);
+ if (ret) {
+ ath10k_warn(ar, "failed to fill fw stats: %d\n", ret);
+ goto err_free;
+ }
+
file->private_data = buf;
mutex_unlock(&ar->conf_mutex);
@@ -1843,6 +1598,233 @@ static const struct file_operations fops_nf_cal_period = {
.llseek = default_llseek,
};
+#define ATH10K_TPC_CONFIG_BUF_SIZE (1024 * 1024)
+
+static int ath10k_debug_tpc_stats_request(struct ath10k *ar)
+{
+ int ret;
+ unsigned long time_left;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ reinit_completion(&ar->debug.tpc_complete);
+
+ ret = ath10k_wmi_pdev_get_tpc_config(ar, WMI_TPC_CONFIG_PARAM);
+ if (ret) {
+ ath10k_warn(ar, "failed to request tpc config: %d\n", ret);
+ return ret;
+ }
+
+ time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
+ 1 * HZ);
+ if (time_left == 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+void ath10k_debug_tpc_stats_process(struct ath10k *ar,
+ struct ath10k_tpc_stats *tpc_stats)
+{
+ spin_lock_bh(&ar->data_lock);
+
+ kfree(ar->debug.tpc_stats);
+ ar->debug.tpc_stats = tpc_stats;
+ complete(&ar->debug.tpc_complete);
+
+ spin_unlock_bh(&ar->data_lock);
+}
+
+static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
+ unsigned int j, char *buf, unsigned int *len)
+{
+ unsigned int i, buf_len;
+ static const char table_str[][5] = { "CDD",
+ "STBC",
+ "TXBF" };
+ static const char pream_str[][6] = { "CCK",
+ "OFDM",
+ "HT20",
+ "HT40",
+ "VHT20",
+ "VHT40",
+ "VHT80",
+ "HTCUP" };
+
+ buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
+ *len += scnprintf(buf + *len, buf_len - *len,
+ "********************************\n");
+ *len += scnprintf(buf + *len, buf_len - *len,
+ "******************* %s POWER TABLE ****************\n",
+ table_str[j]);
+ *len += scnprintf(buf + *len, buf_len - *len,
+ "********************************\n");
+ *len += scnprintf(buf + *len, buf_len - *len,
+ "No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3\n");
+
+ for (i = 0; i < tpc_stats->rate_max; i++) {
+ *len += scnprintf(buf + *len, buf_len - *len,
+ "%8d %s 0x%2x %s\n", i,
+ pream_str[tpc_stats->tpc_table[j].pream_idx[i]],
+ tpc_stats->tpc_table[j].rate_code[i],
+ tpc_stats->tpc_table[j].tpc_value[i]);
+ }
+
+ *len += scnprintf(buf + *len, buf_len - *len,
+ "***********************************\n");
+}
+
+static void ath10k_tpc_stats_fill(struct ath10k *ar,
+ struct ath10k_tpc_stats *tpc_stats,
+ char *buf)
+{
+ unsigned int len, j, buf_len;
+
+ len = 0;
+ buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
+
+ spin_lock_bh(&ar->data_lock);
+
+ if (!tpc_stats) {
+ ath10k_warn(ar, "failed to get tpc stats\n");
+ goto unlock;
+ }
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ len += scnprintf(buf + len, buf_len - len,
+ "*************************************\n");
+ len += scnprintf(buf + len, buf_len - len,
+ "TPC config for channel %4d mode %d\n",
+ tpc_stats->chan_freq,
+ tpc_stats->phy_mode);
+ len += scnprintf(buf + len, buf_len - len,
+ "*************************************\n");
+ len += scnprintf(buf + len, buf_len - len,
+ "CTL = 0x%2x Reg. Domain = %2d\n",
+ tpc_stats->ctl,
+ tpc_stats->reg_domain);
+ len += scnprintf(buf + len, buf_len - len,
+ "Antenna Gain = %2d Reg. Max Antenna Gain = %2d\n",
+ tpc_stats->twice_antenna_gain,
+ tpc_stats->twice_antenna_reduction);
+ len += scnprintf(buf + len, buf_len - len,
+ "Power Limit = %2d Reg. Max Power = %2d\n",
+ tpc_stats->power_limit,
+ tpc_stats->twice_max_rd_power / 2);
+ len += scnprintf(buf + len, buf_len - len,
+ "Num tx chains = %2d Num supported rates = %2d\n",
+ tpc_stats->num_tx_chain,
+ tpc_stats->rate_max);
+
+ for (j = 0; j < tpc_stats->num_tx_chain ; j++) {
+ switch (j) {
+ case WMI_TPC_TABLE_TYPE_CDD:
+ if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
+ len += scnprintf(buf + len, buf_len - len,
+ "CDD not supported\n");
+ break;
+ }
+
+ ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
+ break;
+ case WMI_TPC_TABLE_TYPE_STBC:
+ if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
+ len += scnprintf(buf + len, buf_len - len,
+ "STBC not supported\n");
+ break;
+ }
+
+ ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
+ break;
+ case WMI_TPC_TABLE_TYPE_TXBF:
+ if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
+ len += scnprintf(buf + len, buf_len - len,
+ "TXBF not supported\n***************************\n");
+ break;
+ }
+
+ ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
+ break;
+ default:
+ len += scnprintf(buf + len, buf_len - len,
+ "Invalid Type\n");
+ break;
+ }
+ }
+
+unlock:
+ spin_unlock_bh(&ar->data_lock);
+
+ if (len >= buf_len)
+ buf[len - 1] = 0;
+ else
+ buf[len] = 0;
+}
+
+static int ath10k_tpc_stats_open(struct inode *inode, struct file *file)
+{
+ struct ath10k *ar = inode->i_private;
+ void *buf = NULL;
+ int ret;
+
+ mutex_lock(&ar->conf_mutex);
+
+ if (ar->state != ATH10K_STATE_ON) {
+ ret = -ENETDOWN;
+ goto err_unlock;
+ }
+
+ buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto err_unlock;
+ }
+
+ ret = ath10k_debug_tpc_stats_request(ar);
+ if (ret) {
+ ath10k_warn(ar, "failed to request tpc config stats: %d\n",
+ ret);
+ goto err_free;
+ }
+
+ ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
+ file->private_data = buf;
+
+ mutex_unlock(&ar->conf_mutex);
+ return 0;
+
+err_free:
+ vfree(buf);
+
+err_unlock:
+ mutex_unlock(&ar->conf_mutex);
+ return ret;
+}
+
+static int ath10k_tpc_stats_release(struct inode *inode, struct file *file)
+{
+ vfree(file->private_data);
+
+ return 0;
+}
+
+static ssize_t ath10k_tpc_stats_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ const char *buf = file->private_data;
+ unsigned int len = strlen(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_tpc_stats = {
+ .open = ath10k_tpc_stats_open,
+ .release = ath10k_tpc_stats_release,
+ .read = ath10k_tpc_stats_read,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
int ath10k_debug_start(struct ath10k *ar)
{
int ret;
@@ -2111,6 +2093,8 @@ void ath10k_debug_destroy(struct ath10k *ar)
ar->debug.fw_crash_data = NULL;
ath10k_debug_fw_stats_reset(ar);
+
+ kfree(ar->debug.tpc_stats);
}
int ath10k_debug_register(struct ath10k *ar)
@@ -2127,6 +2111,7 @@ int ath10k_debug_register(struct ath10k *ar)
INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
ath10k_debug_htt_stats_dwork);
+ init_completion(&ar->debug.tpc_complete);
init_completion(&ar->debug.fw_stats_complete);
debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar,
@@ -2195,6 +2180,9 @@ int ath10k_debug_register(struct ath10k *ar)
debugfs_create_file("quiet_period", S_IRUGO | S_IWUSR,
ar->debug.debugfs_phy, ar, &fops_quiet_period);
+ debugfs_create_file("tpc_stats", S_IRUSR,
+ ar->debug.debugfs_phy, ar, &fops_tpc_stats);
+
return 0;
}
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index 53bd6a1..7de780c 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -55,6 +55,9 @@ enum ath10k_dbg_aggr_mode {
ATH10K_DBG_AGGR_MODE_MAX,
};
+/* FIXME: How to calculate the buffer size sanely? */
+#define ATH10K_FW_STATS_BUF_SIZE (1024*1024)
+
extern unsigned int ath10k_debug_mask;
__printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...);
@@ -70,6 +73,8 @@ void ath10k_debug_destroy(struct ath10k *ar);
int ath10k_debug_register(struct ath10k *ar);
void ath10k_debug_unregister(struct ath10k *ar);
void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
+void ath10k_debug_tpc_stats_process(struct ath10k *ar,
+ struct ath10k_tpc_stats *tpc_stats);
struct ath10k_fw_crash_data *
ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
@@ -117,6 +122,12 @@ static inline void ath10k_debug_fw_stats_process(struct ath10k *ar,
{
}
+static inline void ath10k_debug_tpc_stats_process(struct ath10k *ar,
+ struct ath10k_tpc_stats *tpc_stats)
+{
+ kfree(tpc_stats);
+}
+
static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer,
int len)
{
diff --git a/drivers/net/wireless/ath/ath10k/hif.h b/drivers/net/wireless/ath/ath10k/hif.h
index 0c92e02..89e7076 100644
--- a/drivers/net/wireless/ath/ath10k/hif.h
+++ b/drivers/net/wireless/ath/ath10k/hif.h
@@ -30,13 +30,6 @@ struct ath10k_hif_sg_item {
u16 len;
};
-struct ath10k_hif_cb {
- int (*tx_completion)(struct ath10k *ar,
- struct sk_buff *wbuf);
- int (*rx_completion)(struct ath10k *ar,
- struct sk_buff *wbuf);
-};
-
struct ath10k_hif_ops {
/* send a scatter-gather list to the target */
int (*tx_sg)(struct ath10k *ar, u8 pipe_id,
@@ -65,8 +58,7 @@ struct ath10k_hif_ops {
void (*stop)(struct ath10k *ar);
int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id,
- u8 *ul_pipe, u8 *dl_pipe,
- int *ul_is_polled, int *dl_is_polled);
+ u8 *ul_pipe, u8 *dl_pipe);
void (*get_default_pipe)(struct ath10k *ar, u8 *ul_pipe, u8 *dl_pipe);
@@ -80,9 +72,6 @@ struct ath10k_hif_ops {
*/
void (*send_complete_check)(struct ath10k *ar, u8 pipe_id, int force);
- void (*set_callbacks)(struct ath10k *ar,
- struct ath10k_hif_cb *callbacks);
-
u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id);
u32 (*read32)(struct ath10k *ar, u32 address);
@@ -142,13 +131,10 @@ static inline void ath10k_hif_stop(struct ath10k *ar)
static inline int ath10k_hif_map_service_to_pipe(struct ath10k *ar,
u16 service_id,
- u8 *ul_pipe, u8 *dl_pipe,
- int *ul_is_polled,
- int *dl_is_polled)
+ u8 *ul_pipe, u8 *dl_pipe)
{
return ar->hif.ops->map_service_to_pipe(ar, service_id,
- ul_pipe, dl_pipe,
- ul_is_polled, dl_is_polled);
+ ul_pipe, dl_pipe);
}
static inline void ath10k_hif_get_default_pipe(struct ath10k *ar,
@@ -163,12 +149,6 @@ static inline void ath10k_hif_send_complete_check(struct ath10k *ar,
ar->hif.ops->send_complete_check(ar, pipe_id, force);
}
-static inline void ath10k_hif_set_callbacks(struct ath10k *ar,
- struct ath10k_hif_cb *callbacks)
-{
- ar->hif.ops->set_callbacks(ar, callbacks);
-}
-
static inline u16 ath10k_hif_get_free_queue_number(struct ath10k *ar,
u8 pipe_id)
{
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index 32d9ff1..5b3c6bc 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -23,16 +23,6 @@
/* Send */
/********/
-static inline void ath10k_htc_send_complete_check(struct ath10k_htc_ep *ep,
- int force)
-{
- /*
- * Check whether HIF has any prior sends that have finished,
- * have not had the post-processing done.
- */
- ath10k_hif_send_complete_check(ep->htc->ar, ep->ul_pipe_id, force);
-}
-
static void ath10k_htc_control_tx_complete(struct ath10k *ar,
struct sk_buff *skb)
{
@@ -181,24 +171,22 @@ err_pull:
return ret;
}
-static int ath10k_htc_tx_completion_handler(struct ath10k *ar,
- struct sk_buff *skb)
+void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
{
struct ath10k_htc *htc = &ar->htc;
struct ath10k_skb_cb *skb_cb;
struct ath10k_htc_ep *ep;
if (WARN_ON_ONCE(!skb))
- return 0;
+ return;
skb_cb = ATH10K_SKB_CB(skb);
ep = &htc->endpoint[skb_cb->eid];
ath10k_htc_notify_tx_completion(ep, skb);
/* the skb now belongs to the completion handler */
-
- return 0;
}
+EXPORT_SYMBOL(ath10k_htc_tx_completion_handler);
/***********/
/* Receive */
@@ -304,8 +292,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
return status;
}
-static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
- struct sk_buff *skb)
+void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
{
int status = 0;
struct ath10k_htc *htc = &ar->htc;
@@ -326,21 +313,11 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
ath10k_warn(ar, "HTC Rx: invalid eid %d\n", eid);
ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad header", "",
hdr, sizeof(*hdr));
- status = -EINVAL;
goto out;
}
ep = &htc->endpoint[eid];
- /*
- * If this endpoint that received a message from the target has
- * a to-target HIF pipe whose send completions are polled rather
- * than interrupt-driven, this is a good point to ask HIF to check
- * whether it has any completed sends to handle.
- */
- if (ep->ul_is_polled)
- ath10k_htc_send_complete_check(ep, 1);
-
payload_len = __le16_to_cpu(hdr->len);
if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) {
@@ -348,7 +325,6 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
payload_len + sizeof(*hdr));
ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", "",
hdr, sizeof(*hdr));
- status = -EINVAL;
goto out;
}
@@ -358,7 +334,6 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
skb->len, payload_len);
ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len",
"", hdr, sizeof(*hdr));
- status = -EINVAL;
goto out;
}
@@ -374,7 +349,6 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
(trailer_len > payload_len)) {
ath10k_warn(ar, "Invalid trailer length: %d\n",
trailer_len);
- status = -EPROTO;
goto out;
}
@@ -407,7 +381,6 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
* sending unsolicited messages on the ep 0
*/
ath10k_warn(ar, "HTC rx ctrl still processing\n");
- status = -EINVAL;
complete(&htc->ctl_resp);
goto out;
}
@@ -439,9 +412,8 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
skb = NULL;
out:
kfree_skb(skb);
-
- return status;
}
+EXPORT_SYMBOL(ath10k_htc_rx_completion_handler);
static void ath10k_htc_control_rx_complete(struct ath10k *ar,
struct sk_buff *skb)
@@ -767,9 +739,7 @@ setup:
status = ath10k_hif_map_service_to_pipe(htc->ar,
ep->service_id,
&ep->ul_pipe_id,
- &ep->dl_pipe_id,
- &ep->ul_is_polled,
- &ep->dl_is_polled);
+ &ep->dl_pipe_id);
if (status)
return status;
@@ -778,10 +748,6 @@ setup:
htc_service_name(ep->service_id), ep->ul_pipe_id,
ep->dl_pipe_id, ep->eid);
- ath10k_dbg(ar, ATH10K_DBG_BOOT,
- "boot htc ep %d ul polled %d dl polled %d\n",
- ep->eid, ep->ul_is_polled, ep->dl_is_polled);
-
if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) {
ep->tx_credit_flow_enabled = false;
ath10k_dbg(ar, ATH10K_DBG_BOOT,
@@ -841,7 +807,6 @@ int ath10k_htc_start(struct ath10k_htc *htc)
/* registered target arrival callback from the HIF layer */
int ath10k_htc_init(struct ath10k *ar)
{
- struct ath10k_hif_cb htc_callbacks;
struct ath10k_htc_ep *ep = NULL;
struct ath10k_htc *htc = &ar->htc;
@@ -849,15 +814,11 @@ int ath10k_htc_init(struct ath10k *ar)
ath10k_htc_reset_endpoint_states(htc);
- /* setup HIF layer callbacks */
- htc_callbacks.rx_completion = ath10k_htc_rx_completion_handler;
- htc_callbacks.tx_completion = ath10k_htc_tx_completion_handler;
htc->ar = ar;
/* Get HIF default pipe for HTC message exchange */
ep = &htc->endpoint[ATH10K_HTC_EP_0];
- ath10k_hif_set_callbacks(ar, &htc_callbacks);
ath10k_hif_get_default_pipe(ar, &ep->ul_pipe_id, &ep->dl_pipe_id);
init_completion(&htc->ctl_resp);
diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h
index 527179c..e70aa38 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -312,8 +312,6 @@ struct ath10k_htc_ep {
int max_ep_message_len;
u8 ul_pipe_id;
u8 dl_pipe_id;
- int ul_is_polled; /* call HIF to get tx completions */
- int dl_is_polled; /* call HIF to fetch rx (not implemented) */
u8 seq_no; /* for debugging */
int tx_credits;
@@ -355,5 +353,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
struct sk_buff *packet);
struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size);
+void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb);
+void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb);
#endif
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 5a8e4ea..2bad50e 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1488,7 +1488,6 @@ struct ath10k_htt {
int num_pending_mgmt_tx;
struct idr pending_tx;
wait_queue_head_t empty_tx_wq;
- struct dma_pool *tx_pool;
/* set if host-fw communication goes haywire
* used to avoid further failures */
@@ -1509,6 +1508,11 @@ struct ath10k_htt {
dma_addr_t paddr;
struct htt_msdu_ext_desc *vaddr;
} frag_desc;
+
+ struct {
+ dma_addr_t paddr;
+ struct ath10k_htt_txbuf *vaddr;
+ } txbuf;
};
#define RX_HTT_HDR_STATUS_LEN 64
@@ -1587,6 +1591,7 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
u8 max_subfrms_ampdu,
u8 max_subfrms_amsdu);
+void ath10k_htt_hif_tx_complete(struct ath10k *ar, struct sk_buff *skb);
void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt, bool limit_mgmt_desc);
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 606c1a3..6060dda 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2125,6 +2125,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
/* Free the indication buffer */
dev_kfree_skb_any(skb);
}
+EXPORT_SYMBOL(ath10k_htt_t2h_msg_handler);
static void ath10k_htt_txrx_compl_task(unsigned long ptr)
{
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index eb5ba9b..1682397 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -108,9 +108,12 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
spin_lock_init(&htt->tx_lock);
idr_init(&htt->pending_tx);
- htt->tx_pool = dma_pool_create("ath10k htt tx pool", htt->ar->dev,
- sizeof(struct ath10k_htt_txbuf), 4, 0);
- if (!htt->tx_pool) {
+ size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf);
+ htt->txbuf.vaddr = dma_alloc_coherent(ar->dev, size,
+ &htt->txbuf.paddr,
+ GFP_DMA);
+ if (!htt->txbuf.vaddr) {
+ ath10k_err(ar, "failed to alloc tx buffer\n");
ret = -ENOMEM;
goto free_idr_pending_tx;
}
@@ -125,14 +128,17 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
if (!htt->frag_desc.vaddr) {
ath10k_warn(ar, "failed to alloc fragment desc memory\n");
ret = -ENOMEM;
- goto free_tx_pool;
+ goto free_txbuf;
}
skip_frag_desc_alloc:
return 0;
-free_tx_pool:
- dma_pool_destroy(htt->tx_pool);
+free_txbuf:
+ size = htt->max_num_pending_tx *
+ sizeof(struct ath10k_htt_txbuf);
+ dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr,
+ htt->txbuf.paddr);
free_idr_pending_tx:
idr_destroy(&htt->pending_tx);
return ret;
@@ -160,7 +166,13 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt)
idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
idr_destroy(&htt->pending_tx);
- dma_pool_destroy(htt->tx_pool);
+
+ if (htt->txbuf.vaddr) {
+ size = htt->max_num_pending_tx *
+ sizeof(struct ath10k_htt_txbuf);
+ dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr,
+ htt->txbuf.paddr);
+ }
if (htt->frag_desc.vaddr) {
size = htt->max_num_pending_tx *
@@ -175,6 +187,12 @@ void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
+void ath10k_htt_hif_tx_complete(struct ath10k *ar, struct sk_buff *skb)
+{
+ dev_kfree_skb_any(skb);
+}
+EXPORT_SYMBOL(ath10k_htt_hif_tx_complete);
+
int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
{
struct ath10k *ar = htt->ar;
@@ -454,9 +472,9 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
spin_lock_bh(&htt->tx_lock);
res = ath10k_htt_tx_alloc_msdu_id(htt, msdu);
spin_unlock_bh(&htt->tx_lock);
- if (res < 0) {
+ if (res < 0)
goto err_tx_dec;
- }
+
msdu_id = res;
txdesc = ath10k_htc_alloc_skb(ar, len);
@@ -521,7 +539,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
int res;
u8 flags0 = 0;
u16 msdu_id, flags1 = 0;
- dma_addr_t paddr = 0;
u32 frags_paddr = 0;
struct htt_msdu_ext_desc *ext_desc = NULL;
bool limit_mgmt_desc = false;
@@ -542,21 +559,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
spin_lock_bh(&htt->tx_lock);
res = ath10k_htt_tx_alloc_msdu_id(htt, msdu);
spin_unlock_bh(&htt->tx_lock);
- if (res < 0) {
+ if (res < 0)
goto err_tx_dec;
- }
+
msdu_id = res;
prefetch_len = min(htt->prefetch_len, msdu->len);
prefetch_len = roundup(prefetch_len, 4);
- skb_cb->htt.txbuf = dma_pool_alloc(htt->tx_pool, GFP_ATOMIC,
- &paddr);
- if (!skb_cb->htt.txbuf) {
- res = -ENOMEM;
- goto err_free_msdu_id;
- }
- skb_cb->htt.txbuf_paddr = paddr;
+ skb_cb->htt.txbuf = &htt->txbuf.vaddr[msdu_id];
+ skb_cb->htt.txbuf_paddr = htt->txbuf.paddr +
+ (sizeof(struct ath10k_htt_txbuf) * msdu_id);
if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
@@ -574,7 +587,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
res = dma_mapping_error(dev, skb_cb->paddr);
if (res) {
res = -EIO;
- goto err_free_txbuf;
+ goto err_free_msdu_id;
}
switch (skb_cb->txmode) {
@@ -706,10 +719,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
err_unmap_msdu:
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
-err_free_txbuf:
- dma_pool_free(htt->tx_pool,
- skb_cb->htt.txbuf,
- skb_cb->htt.txbuf_paddr);
err_free_msdu_id:
spin_lock_bh(&htt->tx_lock);
ath10k_htt_tx_free_msdu_id(htt, msdu_id);
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 80c174f..2d87737 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -97,6 +97,9 @@ enum qca6174_chip_id_rev {
/* includes also the null byte */
#define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K"
+#define ATH10K_BOARD_MAGIC "QCA-ATH10K-BOARD"
+
+#define ATH10K_BOARD_API2_FILE "board-2.bin"
#define REG_DUMP_COUNT_QCA988X 60
@@ -159,6 +162,16 @@ enum ath10k_fw_htt_op_version {
ATH10K_FW_HTT_OP_VERSION_MAX,
};
+enum ath10k_bd_ie_type {
+ /* contains sub IEs of enum ath10k_bd_ie_board_type */
+ ATH10K_BD_IE_BOARD = 0,
+};
+
+enum ath10k_bd_ie_board_type {
+ ATH10K_BD_IE_BOARD_NAME = 0,
+ ATH10K_BD_IE_BOARD_DATA = 1,
+};
+
enum ath10k_hw_rev {
ATH10K_HW_QCA988X,
ATH10K_HW_QCA6174,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 79490ad..484c1a1 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -197,9 +197,8 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
return -EOPNOTSUPP;
}
- if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
+ if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- }
if (cmd == DISABLE_KEY) {
arg.key_cipher = WMI_CIPHER_NONE;
@@ -1111,7 +1110,8 @@ static int ath10k_monitor_recalc(struct ath10k *ar)
ret = ath10k_monitor_stop(ar);
if (ret)
- ath10k_warn(ar, "failed to stop disallowed monitor: %d\n", ret);
+ ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
+ ret);
/* not serious */
}
@@ -2084,7 +2084,8 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
enum ieee80211_band band;
const u8 *ht_mcs_mask;
const u16 *vht_mcs_mask;
- int i, n, max_nss;
+ int i, n;
+ u8 max_nss;
u32 stbc;
lockdep_assert_held(&ar->conf_mutex);
@@ -2169,7 +2170,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
arg->peer_ht_rates.rates[i] = i;
} else {
arg->peer_ht_rates.num_rates = n;
- arg->peer_num_spatial_streams = max_nss;
+ arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
}
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
@@ -4065,6 +4066,7 @@ static u32 get_nss_from_chainmask(u16 chain_mask)
static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
{
int nsts = ar->vht_cap_info;
+
nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
@@ -4081,8 +4083,9 @@ static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
{
int sound_dim = ar->vht_cap_info;
+
sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
- sound_dim >>=IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
+ sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
/* If the sounding dimension is not advertised by the firmware,
* let's use a default value of 1
@@ -4656,7 +4659,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
info->use_cts_prot ? 1 : 0);
if (ret)
ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
- info->use_cts_prot, arvif->vdev_id, ret);
+ info->use_cts_prot, arvif->vdev_id, ret);
}
if (changed & BSS_CHANGED_ERP_SLOT) {
@@ -6268,8 +6271,8 @@ ath10k_mac_update_rx_channel(struct ath10k *ar,
rcu_read_lock();
if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
ieee80211_iter_chan_contexts_atomic(ar->hw,
- ath10k_mac_get_any_chandef_iter,
- &def);
+ ath10k_mac_get_any_chandef_iter,
+ &def);
if (vifs)
def = &vifs[0].new_ctx->def;
@@ -7301,7 +7304,7 @@ int ath10k_mac_register(struct ath10k *ar)
ath10k_reg_notifier);
if (ret) {
ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
- goto err_free;
+ goto err_dfs_detector_exit;
}
ar->hw->wiphy->cipher_suites = cipher_suites;
@@ -7310,7 +7313,7 @@ int ath10k_mac_register(struct ath10k *ar)
ret = ieee80211_register_hw(ar->hw);
if (ret) {
ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
- goto err_free;
+ goto err_dfs_detector_exit;
}
if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
@@ -7324,10 +7327,16 @@ int ath10k_mac_register(struct ath10k *ar)
err_unregister:
ieee80211_unregister_hw(ar->hw);
+
+err_dfs_detector_exit:
+ if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
+ ar->dfs_detector->exit(ar->dfs_detector);
+
err_free:
kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
+ SET_IEEE80211_DEV(ar->hw, NULL);
return ret;
}
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 110fcad6..5c05b0c 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -104,6 +104,10 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
struct ath10k_ce_pipe *rx_pipe,
struct bmi_xfer *xfer);
static int ath10k_pci_qca99x0_chip_reset(struct ath10k *ar);
+static void ath10k_pci_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
static const struct ce_attr host_ce_config_wlan[] = {
/* CE0: host->target HTC control and raw streams */
@@ -112,6 +116,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
.src_nentries = 16,
.src_sz_max = 256,
.dest_nentries = 0,
+ .send_cb = ath10k_pci_htc_tx_cb,
},
/* CE1: target->host HTT + HTC control */
@@ -120,6 +125,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
+ .recv_cb = ath10k_pci_htc_rx_cb,
},
/* CE2: target->host WMI */
@@ -128,6 +134,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 128,
+ .recv_cb = ath10k_pci_htc_rx_cb,
},
/* CE3: host->target WMI */
@@ -136,6 +143,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
.src_nentries = 32,
.src_sz_max = 2048,
.dest_nentries = 0,
+ .send_cb = ath10k_pci_htc_tx_cb,
},
/* CE4: host->target HTT */
@@ -144,14 +152,16 @@ static const struct ce_attr host_ce_config_wlan[] = {
.src_nentries = CE_HTT_H2T_MSG_SRC_NENTRIES,
.src_sz_max = 256,
.dest_nentries = 0,
+ .send_cb = ath10k_pci_htt_tx_cb,
},
- /* CE5: unused */
+ /* CE5: target->host HTT (HIF->HTT) */
{
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
- .src_sz_max = 0,
- .dest_nentries = 0,
+ .src_sz_max = 512,
+ .dest_nentries = 512,
+ .recv_cb = ath10k_pci_htt_rx_cb,
},
/* CE6: target autonomous hif_memcpy */
@@ -257,12 +267,12 @@ static const struct ce_pipe_config target_ce_config_wlan[] = {
/* NB: 50% of src nentries, since tx has 2 frags */
- /* CE5: unused */
+ /* CE5: target->host HTT (HIF->HTT) */
{
.pipenum = __cpu_to_le32(5),
- .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
.nentries = __cpu_to_le32(32),
- .nbytes_max = __cpu_to_le32(2048),
+ .nbytes_max = __cpu_to_le32(512),
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
.reserved = __cpu_to_le32(0),
},
@@ -396,7 +406,7 @@ static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
{
__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
- __cpu_to_le32(1),
+ __cpu_to_le32(5),
},
/* (Additions here) */
@@ -452,8 +462,12 @@ static int ath10k_pci_wake_wait(struct ath10k *ar)
int curr_delay = 5;
while (tot_delay < PCIE_WAKE_TIMEOUT) {
- if (ath10k_pci_is_awake(ar))
+ if (ath10k_pci_is_awake(ar)) {
+ if (tot_delay > PCIE_WAKE_LATE_US)
+ ath10k_warn(ar, "device wakeup took %d ms which is unusally long, otherwise it works normally.\n",
+ tot_delay / 1000);
return 0;
+ }
udelay(curr_delay);
tot_delay += curr_delay;
@@ -465,12 +479,53 @@ static int ath10k_pci_wake_wait(struct ath10k *ar)
return -ETIMEDOUT;
}
+static int ath10k_pci_force_wake(struct ath10k *ar)
+{
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&ar_pci->ps_lock, flags);
+
+ if (!ar_pci->ps_awake) {
+ iowrite32(PCIE_SOC_WAKE_V_MASK,
+ ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
+ PCIE_SOC_WAKE_ADDRESS);
+
+ ret = ath10k_pci_wake_wait(ar);
+ if (ret == 0)
+ ar_pci->ps_awake = true;
+ }
+
+ spin_unlock_irqrestore(&ar_pci->ps_lock, flags);
+
+ return ret;
+}
+
+static void ath10k_pci_force_sleep(struct ath10k *ar)
+{
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ar_pci->ps_lock, flags);
+
+ iowrite32(PCIE_SOC_WAKE_RESET,
+ ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
+ PCIE_SOC_WAKE_ADDRESS);
+ ar_pci->ps_awake = false;
+
+ spin_unlock_irqrestore(&ar_pci->ps_lock, flags);
+}
+
static int ath10k_pci_wake(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
unsigned long flags;
int ret = 0;
+ if (ar_pci->pci_ps == 0)
+ return ret;
+
spin_lock_irqsave(&ar_pci->ps_lock, flags);
ath10k_dbg(ar, ATH10K_DBG_PCI_PS, "pci ps wake refcount %lu awake %d\n",
@@ -502,6 +557,9 @@ static void ath10k_pci_sleep(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
unsigned long flags;
+ if (ar_pci->pci_ps == 0)
+ return;
+
spin_lock_irqsave(&ar_pci->ps_lock, flags);
ath10k_dbg(ar, ATH10K_DBG_PCI_PS, "pci ps sleep refcount %lu awake %d\n",
@@ -544,6 +602,11 @@ static void ath10k_pci_sleep_sync(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
unsigned long flags;
+ if (ar_pci->pci_ps == 0) {
+ ath10k_pci_force_sleep(ar);
+ return;
+ }
+
del_timer_sync(&ar_pci->ps_timer);
spin_lock_irqsave(&ar_pci->ps_lock, flags);
@@ -682,8 +745,6 @@ static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe)
dma_addr_t paddr;
int ret;
- lockdep_assert_held(&ar_pci->ce_lock);
-
skb = dev_alloc_skb(pipe->buf_sz);
if (!skb)
return -ENOMEM;
@@ -701,9 +762,10 @@ static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe)
ATH10K_SKB_RXCB(skb)->paddr = paddr;
+ spin_lock_bh(&ar_pci->ce_lock);
ret = __ath10k_ce_rx_post_buf(ce_pipe, skb, paddr);
+ spin_unlock_bh(&ar_pci->ce_lock);
if (ret) {
- ath10k_warn(ar, "failed to post pci rx buf: %d\n", ret);
dma_unmap_single(ar->dev, paddr, skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
@@ -713,25 +775,27 @@ static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe)
return 0;
}
-static void __ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe)
+static void ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe)
{
struct ath10k *ar = pipe->hif_ce_state;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
int ret, num;
- lockdep_assert_held(&ar_pci->ce_lock);
-
if (pipe->buf_sz == 0)
return;
if (!ce_pipe->dest_ring)
return;
+ spin_lock_bh(&ar_pci->ce_lock);
num = __ath10k_ce_rx_num_free_bufs(ce_pipe);
+ spin_unlock_bh(&ar_pci->ce_lock);
while (num--) {
ret = __ath10k_pci_rx_post_buf(pipe);
if (ret) {
+ if (ret == -ENOSPC)
+ break;
ath10k_warn(ar, "failed to post pci rx buf: %d\n", ret);
mod_timer(&ar_pci->rx_post_retry, jiffies +
ATH10K_PCI_RX_POST_RETRY_MS);
@@ -740,25 +804,13 @@ static void __ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe)
}
}
-static void ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe)
-{
- struct ath10k *ar = pipe->hif_ce_state;
- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-
- spin_lock_bh(&ar_pci->ce_lock);
- __ath10k_pci_rx_post_pipe(pipe);
- spin_unlock_bh(&ar_pci->ce_lock);
-}
-
static void ath10k_pci_rx_post(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int i;
- spin_lock_bh(&ar_pci->ce_lock);
for (i = 0; i < CE_COUNT; i++)
- __ath10k_pci_rx_post_pipe(&ar_pci->pipe_info[i]);
- spin_unlock_bh(&ar_pci->ce_lock);
+ ath10k_pci_rx_post_pipe(&ar_pci->pipe_info[i]);
}
static void ath10k_pci_rx_replenish_retry(unsigned long ptr)
@@ -1102,11 +1154,9 @@ static int ath10k_pci_diag_write32(struct ath10k *ar, u32 address, u32 value)
}
/* Called by lower (CE) layer when a send to Target completes. */
-static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state)
+static void ath10k_pci_htc_tx_cb(struct ath10k_ce_pipe *ce_state)
{
struct ath10k *ar = ce_state->ar;
- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- struct ath10k_hif_cb *cb = &ar_pci->msg_callbacks_current;
struct sk_buff_head list;
struct sk_buff *skb;
u32 ce_data;
@@ -1124,16 +1174,16 @@ static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state)
}
while ((skb = __skb_dequeue(&list)))
- cb->tx_completion(ar, skb);
+ ath10k_htc_tx_completion_handler(ar, skb);
}
-/* Called by lower (CE) layer when data is received from the Target. */
-static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state)
+static void ath10k_pci_process_rx_cb(struct ath10k_ce_pipe *ce_state,
+ void (*callback)(struct ath10k *ar,
+ struct sk_buff *skb))
{
struct ath10k *ar = ce_state->ar;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_pci_pipe *pipe_info = &ar_pci->pipe_info[ce_state->id];
- struct ath10k_hif_cb *cb = &ar_pci->msg_callbacks_current;
struct sk_buff *skb;
struct sk_buff_head list;
void *transfer_context;
@@ -1168,12 +1218,56 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state)
ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci rx: ",
skb->data, skb->len);
- cb->rx_completion(ar, skb);
+ callback(ar, skb);
}
ath10k_pci_rx_post_pipe(pipe_info);
}
+/* Called by lower (CE) layer when data is received from the Target. */
+static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
+{
+ ath10k_pci_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
+}
+
+/* Called by lower (CE) layer when a send to HTT Target completes. */
+static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
+{
+ struct ath10k *ar = ce_state->ar;
+ struct sk_buff *skb;
+ u32 ce_data;
+ unsigned int nbytes;
+ unsigned int transfer_id;
+
+ while (ath10k_ce_completed_send_next(ce_state, (void **)&skb, &ce_data,
+ &nbytes, &transfer_id) == 0) {
+ /* no need to call tx completion for NULL pointers */
+ if (!skb)
+ continue;
+
+ dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
+ skb->len, DMA_TO_DEVICE);
+ ath10k_htt_hif_tx_complete(ar, skb);
+ }
+}
+
+static void ath10k_pci_htt_rx_deliver(struct ath10k *ar, struct sk_buff *skb)
+{
+ skb_pull(skb, sizeof(struct ath10k_htc_hdr));
+ ath10k_htt_t2h_msg_handler(ar, skb);
+}
+
+/* Called by lower (CE) layer when HTT data is received from the Target. */
+static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state)
+{
+ /* CE4 polling needs to be done whenever CE pipe which transports
+ * HTT Rx (target->host) is processed.
+ */
+ ath10k_ce_per_engine_service(ce_state->ar, 4);
+
+ ath10k_pci_process_rx_cb(ce_state, ath10k_pci_htt_rx_deliver);
+}
+
static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
struct ath10k_hif_sg_item *items, int n_items)
{
@@ -1343,17 +1437,6 @@ static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
ath10k_ce_per_engine_service(ar, pipe);
}
-static void ath10k_pci_hif_set_callbacks(struct ath10k *ar,
- struct ath10k_hif_cb *callbacks)
-{
- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-
- ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif set callbacks\n");
-
- memcpy(&ar_pci->msg_callbacks_current, callbacks,
- sizeof(ar_pci->msg_callbacks_current));
-}
-
static void ath10k_pci_kill_tasklet(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
@@ -1368,10 +1451,8 @@ static void ath10k_pci_kill_tasklet(struct ath10k *ar)
del_timer_sync(&ar_pci->rx_post_retry);
}
-static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar,
- u16 service_id, u8 *ul_pipe,
- u8 *dl_pipe, int *ul_is_polled,
- int *dl_is_polled)
+static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id,
+ u8 *ul_pipe, u8 *dl_pipe)
{
const struct service_to_pipe *entry;
bool ul_set = false, dl_set = false;
@@ -1379,9 +1460,6 @@ static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar,
ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif map service\n");
- /* polling for received messages not supported */
- *dl_is_polled = 0;
-
for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) {
entry = &target_service_to_ce_map_wlan[i];
@@ -1415,25 +1493,17 @@ static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar,
if (WARN_ON(!ul_set || !dl_set))
return -ENOENT;
- *ul_is_polled =
- (host_ce_config_wlan[*ul_pipe].flags & CE_ATTR_DIS_INTR) != 0;
-
return 0;
}
static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar,
u8 *ul_pipe, u8 *dl_pipe)
{
- int ul_is_polled, dl_is_polled;
-
ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif get default pipe\n");
(void)ath10k_pci_hif_map_service_to_pipe(ar,
ATH10K_HTC_SVC_ID_RSVD_CTRL,
- ul_pipe,
- dl_pipe,
- &ul_is_polled,
- &dl_is_polled);
+ ul_pipe, dl_pipe);
}
static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar)
@@ -1504,6 +1574,7 @@ static void ath10k_pci_irq_enable(struct ath10k *ar)
static int ath10k_pci_hif_start(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n");
ath10k_pci_irq_enable(ar);
@@ -1579,7 +1650,7 @@ static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe)
ce_ring->per_transfer_context[i] = NULL;
- ar_pci->msg_callbacks_current.tx_completion(ar, skb);
+ ath10k_htc_tx_completion_handler(ar, skb);
}
}
@@ -1999,9 +2070,7 @@ static int ath10k_pci_alloc_pipes(struct ath10k *ar)
pipe->pipe_num = i;
pipe->hif_ce_state = ar;
- ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i],
- ath10k_pci_ce_send_done,
- ath10k_pci_ce_recv_data);
+ ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]);
if (ret) {
ath10k_err(ar, "failed to allocate copy engine pipe %d: %d\n",
i, ret);
@@ -2257,7 +2326,7 @@ static int ath10k_pci_qca6174_chip_reset(struct ath10k *ar)
ret = ath10k_pci_wait_for_target_init(ar);
if (ret) {
ath10k_warn(ar, "failed to wait for target after cold reset: %d\n",
- ret);
+ ret);
return ret;
}
@@ -2397,6 +2466,15 @@ static int ath10k_pci_hif_resume(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct pci_dev *pdev = ar_pci->pdev;
u32 val;
+ int ret = 0;
+
+ if (ar_pci->pci_ps == 0) {
+ ret = ath10k_pci_force_wake(ar);
+ if (ret) {
+ ath10k_err(ar, "failed to wake up target: %d\n", ret);
+ return ret;
+ }
+ }
/* Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -2407,7 +2485,7 @@ static int ath10k_pci_hif_resume(struct ath10k *ar)
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
- return 0;
+ return ret;
}
#endif
@@ -2421,7 +2499,6 @@ static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
.map_service_to_pipe = ath10k_pci_hif_map_service_to_pipe,
.get_default_pipe = ath10k_pci_hif_get_default_pipe,
.send_complete_check = ath10k_pci_hif_send_complete_check,
- .set_callbacks = ath10k_pci_hif_set_callbacks,
.get_free_queue_number = ath10k_pci_hif_get_free_queue_number,
.power_up = ath10k_pci_hif_power_up,
.power_down = ath10k_pci_hif_power_down,
@@ -2501,6 +2578,16 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg)
{
struct ath10k *ar = arg;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+ int ret;
+
+ if (ar_pci->pci_ps == 0) {
+ ret = ath10k_pci_force_wake(ar);
+ if (ret) {
+ ath10k_warn(ar, "failed to wake device up on irq: %d\n",
+ ret);
+ return IRQ_NONE;
+ }
+ }
if (ar_pci->num_msi_intrs == 0) {
if (!ath10k_pci_irq_pending(ar))
@@ -2900,17 +2987,21 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
struct ath10k_pci *ar_pci;
enum ath10k_hw_rev hw_rev;
u32 chip_id;
+ bool pci_ps;
switch (pci_dev->device) {
case QCA988X_2_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA988X;
+ pci_ps = false;
break;
case QCA6164_2_1_DEVICE_ID:
case QCA6174_2_1_DEVICE_ID:
hw_rev = ATH10K_HW_QCA6174;
+ pci_ps = true;
break;
case QCA99X0_2_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA99X0;
+ pci_ps = false;
break;
default:
WARN_ON(1);
@@ -2924,19 +3015,21 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
return -ENOMEM;
}
- ath10k_dbg(ar, ATH10K_DBG_PCI, "pci probe\n");
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n",
+ pdev->vendor, pdev->device,
+ pdev->subsystem_vendor, pdev->subsystem_device);
ar_pci = ath10k_pci_priv(ar);
ar_pci->pdev = pdev;
ar_pci->dev = &pdev->dev;
ar_pci->ar = ar;
ar->dev_id = pci_dev->device;
+ ar_pci->pci_ps = pci_ps;
- if (pdev->subsystem_vendor || pdev->subsystem_device)
- scnprintf(ar->spec_board_id, sizeof(ar->spec_board_id),
- "%04x:%04x:%04x:%04x",
- pdev->vendor, pdev->device,
- pdev->subsystem_vendor, pdev->subsystem_device);
+ ar->id.vendor = pdev->vendor;
+ ar->id.device = pdev->device;
+ ar->id.subsystem_vendor = pdev->subsystem_vendor;
+ ar->id.subsystem_device = pdev->subsystem_device;
spin_lock_init(&ar_pci->ce_lock);
spin_lock_init(&ar_pci->ps_lock);
@@ -2962,6 +3055,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
ath10k_pci_ce_deinit(ar);
ath10k_pci_irq_disable(ar);
+ if (ar_pci->pci_ps == 0) {
+ ret = ath10k_pci_force_wake(ar);
+ if (ret) {
+ ath10k_warn(ar, "failed to wake up device : %d\n", ret);
+ goto err_free_pipes;
+ }
+ }
+
ret = ath10k_pci_init_irq(ar);
if (ret) {
ath10k_err(ar, "failed to init irqs: %d\n", ret);
@@ -3090,13 +3191,16 @@ MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_FW_API3_FILE);
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_FW_API4_FILE);
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_FW_API5_FILE);
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE);
+MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_BOARD_API2_FILE);
/* QCA6174 2.1 firmware files */
MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API4_FILE);
MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API5_FILE);
MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" QCA6174_HW_2_1_BOARD_DATA_FILE);
+MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_BOARD_API2_FILE);
/* QCA6174 3.1 firmware files */
MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_FW_API4_FILE);
MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_FW_API5_FILE);
MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" QCA6174_HW_3_0_BOARD_DATA_FILE);
+MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_BOARD_API2_FILE);
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 8d364fb..f91bf33 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -175,8 +175,6 @@ struct ath10k_pci {
struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX];
- struct ath10k_hif_cb msg_callbacks_current;
-
/* Copy Engine used for Diagnostic Accesses */
struct ath10k_ce_pipe *ce_diag;
@@ -221,6 +219,12 @@ struct ath10k_pci {
* powersave register state changes.
*/
bool ps_awake;
+
+ /* pci power save, disable for QCA988X and QCA99X0.
+ * Writing 'false' to this variable avoids frequent locking
+ * on MMIO read/write.
+ */
+ bool pci_ps;
};
static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
@@ -230,7 +234,8 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
#define ATH10K_PCI_RX_POST_RETRY_MS 50
#define ATH_PCI_RESET_WAIT_MAX 10 /* ms */
-#define PCIE_WAKE_TIMEOUT 10000 /* 10ms */
+#define PCIE_WAKE_TIMEOUT 30000 /* 30ms */
+#define PCIE_WAKE_LATE_US 10000 /* 10ms */
#define BAR_NUM 0
diff --git a/drivers/net/wireless/ath/ath10k/thermal.c b/drivers/net/wireless/ath/ath10k/thermal.c
index 1a899d7..60fe562 100644
--- a/drivers/net/wireless/ath/ath10k/thermal.c
+++ b/drivers/net/wireless/ath/ath10k/thermal.c
@@ -215,6 +215,6 @@ err_cooling_destroy:
void ath10k_thermal_unregister(struct ath10k *ar)
{
- thermal_cooling_device_unregister(ar->thermal.cdev);
sysfs_remove_link(&ar->dev->kobj, "cooling_device");
+ thermal_cooling_device_unregister(ar->thermal.cdev);
}
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 7db7d50..6d1105a 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -92,11 +92,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
skb_cb = ATH10K_SKB_CB(msdu);
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
- if (skb_cb->htt.txbuf)
- dma_pool_free(htt->tx_pool,
- skb_cb->htt.txbuf,
- skb_cb->htt.txbuf_paddr);
-
ath10k_report_offchan_tx(htt->ar, msdu);
info = IEEE80211_SKB_CB(msdu);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 248ffc3..b54aa08 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -177,6 +177,11 @@ struct wmi_ops {
const struct wmi_tdls_peer_capab_arg *cap,
const struct wmi_channel_arg *chan);
struct sk_buff *(*gen_adaptive_qcs)(struct ath10k *ar, bool enable);
+ struct sk_buff *(*gen_pdev_get_tpc_config)(struct ath10k *ar,
+ u32 param);
+ void (*fw_stats_fill)(struct ath10k *ar,
+ struct ath10k_fw_stats *fw_stats,
+ char *buf);
};
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1270,4 +1275,31 @@ ath10k_wmi_adaptive_qcs(struct ath10k *ar, bool enable)
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->adaptive_qcs_cmdid);
}
+static inline int
+ath10k_wmi_pdev_get_tpc_config(struct ath10k *ar, u32 param)
+{
+ struct sk_buff *skb;
+
+ if (!ar->wmi.ops->gen_pdev_get_tpc_config)
+ return -EOPNOTSUPP;
+
+ skb = ar->wmi.ops->gen_pdev_get_tpc_config(ar, param);
+
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ return ath10k_wmi_cmd_send(ar, skb,
+ ar->wmi.cmd->pdev_get_tpc_config_cmdid);
+}
+
+static inline int
+ath10k_wmi_fw_stats_fill(struct ath10k *ar, struct ath10k_fw_stats *fw_stats,
+ char *buf)
+{
+ if (!ar->wmi.ops->fw_stats_fill)
+ return -EOPNOTSUPP;
+
+ ar->wmi.ops->fw_stats_fill(ar, fw_stats, buf);
+ return 0;
+}
#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index b5849b3..8f83548 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -3468,6 +3468,7 @@ static const struct wmi_ops wmi_tlv_ops = {
.gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state,
.gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
.gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs,
+ .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
};
/************/
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 87d9de2..6e7d7a7 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -3018,8 +3018,6 @@ static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
memcpy(skb_put(bcn, arvif->u.ap.noa_len),
arvif->u.ap.noa_data,
arvif->u.ap.noa_len);
-
- return;
}
static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb,
@@ -3507,7 +3505,7 @@ void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
tsf);
if (res < 0) {
ath10k_dbg(ar, ATH10K_DBG_WMI, "failed to process fft report: %d\n",
- res);
+ res);
return;
}
break;
@@ -3835,9 +3833,258 @@ void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb)
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n");
}
+static u8 ath10k_tpc_config_get_rate(struct ath10k *ar,
+ struct wmi_pdev_tpc_config_event *ev,
+ u32 rate_idx, u32 num_chains,
+ u32 rate_code, u8 type)
+{
+ u8 tpc, num_streams, preamble, ch, stm_idx;
+
+ num_streams = ATH10K_HW_NSS(rate_code);
+ preamble = ATH10K_HW_PREAMBLE(rate_code);
+ ch = num_chains - 1;
+
+ tpc = min_t(u8, ev->rates_array[rate_idx], ev->max_reg_allow_pow[ch]);
+
+ if (__le32_to_cpu(ev->num_tx_chain) <= 1)
+ goto out;
+
+ if (preamble == WMI_RATE_PREAMBLE_CCK)
+ goto out;
+
+ stm_idx = num_streams - 1;
+ if (num_chains <= num_streams)
+ goto out;
+
+ switch (type) {
+ case WMI_TPC_TABLE_TYPE_STBC:
+ tpc = min_t(u8, tpc,
+ ev->max_reg_allow_pow_agstbc[ch - 1][stm_idx]);
+ break;
+ case WMI_TPC_TABLE_TYPE_TXBF:
+ tpc = min_t(u8, tpc,
+ ev->max_reg_allow_pow_agtxbf[ch - 1][stm_idx]);
+ break;
+ case WMI_TPC_TABLE_TYPE_CDD:
+ tpc = min_t(u8, tpc,
+ ev->max_reg_allow_pow_agcdd[ch - 1][stm_idx]);
+ break;
+ default:
+ ath10k_warn(ar, "unknown wmi tpc table type: %d\n", type);
+ tpc = 0;
+ break;
+ }
+
+out:
+ return tpc;
+}
+
+static void ath10k_tpc_config_disp_tables(struct ath10k *ar,
+ struct wmi_pdev_tpc_config_event *ev,
+ struct ath10k_tpc_stats *tpc_stats,
+ u8 *rate_code, u16 *pream_table, u8 type)
+{
+ u32 i, j, pream_idx, flags;
+ u8 tpc[WMI_TPC_TX_N_CHAIN];
+ char tpc_value[WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
+ char buff[WMI_TPC_BUF_SIZE];
+
+ flags = __le32_to_cpu(ev->flags);
+
+ switch (type) {
+ case WMI_TPC_TABLE_TYPE_CDD:
+ if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD)) {
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "CDD not supported\n");
+ tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
+ return;
+ }
+ break;
+ case WMI_TPC_TABLE_TYPE_STBC:
+ if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC)) {
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "STBC not supported\n");
+ tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
+ return;
+ }
+ break;
+ case WMI_TPC_TABLE_TYPE_TXBF:
+ if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF)) {
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "TXBF not supported\n");
+ tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
+ return;
+ }
+ break;
+ default:
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
+ "invalid table type in wmi tpc event: %d\n", type);
+ return;
+ }
+
+ pream_idx = 0;
+ for (i = 0; i < __le32_to_cpu(ev->rate_max); i++) {
+ memset(tpc_value, 0, sizeof(tpc_value));
+ memset(buff, 0, sizeof(buff));
+ if (i == pream_table[pream_idx])
+ pream_idx++;
+
+ for (j = 0; j < WMI_TPC_TX_N_CHAIN; j++) {
+ if (j >= __le32_to_cpu(ev->num_tx_chain))
+ break;
+
+ tpc[j] = ath10k_tpc_config_get_rate(ar, ev, i, j + 1,
+ rate_code[i],
+ type);
+ snprintf(buff, sizeof(buff), "%8d ", tpc[j]);
+ strncat(tpc_value, buff, strlen(buff));
+ }
+ tpc_stats->tpc_table[type].pream_idx[i] = pream_idx;
+ tpc_stats->tpc_table[type].rate_code[i] = rate_code[i];
+ memcpy(tpc_stats->tpc_table[type].tpc_value[i],
+ tpc_value, sizeof(tpc_value));
+ }
+}
+
void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
{
- ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n");
+ u32 i, j, pream_idx, num_tx_chain;
+ u8 rate_code[WMI_TPC_RATE_MAX], rate_idx;
+ u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
+ struct wmi_pdev_tpc_config_event *ev;
+ struct ath10k_tpc_stats *tpc_stats;
+
+ ev = (struct wmi_pdev_tpc_config_event *)skb->data;
+
+ tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
+ if (!tpc_stats)
+ return;
+
+ /* Create the rate code table based on the chains supported */
+ rate_idx = 0;
+ pream_idx = 0;
+
+ /* Fill CCK rate code */
+ for (i = 0; i < 4; i++) {
+ rate_code[rate_idx] =
+ ATH10K_HW_RATECODE(i, 0, WMI_RATE_PREAMBLE_CCK);
+ rate_idx++;
+ }
+ pream_table[pream_idx] = rate_idx;
+ pream_idx++;
+
+ /* Fill OFDM rate code */
+ for (i = 0; i < 8; i++) {
+ rate_code[rate_idx] =
+ ATH10K_HW_RATECODE(i, 0, WMI_RATE_PREAMBLE_OFDM);
+ rate_idx++;
+ }
+ pream_table[pream_idx] = rate_idx;
+ pream_idx++;
+
+ num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
+
+ /* Fill HT20 rate code */
+ for (i = 0; i < num_tx_chain; i++) {
+ for (j = 0; j < 8; j++) {
+ rate_code[rate_idx] =
+ ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_HT);
+ rate_idx++;
+ }
+ }
+ pream_table[pream_idx] = rate_idx;
+ pream_idx++;
+
+ /* Fill HT40 rate code */
+ for (i = 0; i < num_tx_chain; i++) {
+ for (j = 0; j < 8; j++) {
+ rate_code[rate_idx] =
+ ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_HT);
+ rate_idx++;
+ }
+ }
+ pream_table[pream_idx] = rate_idx;
+ pream_idx++;
+
+ /* Fill VHT20 rate code */
+ for (i = 0; i < __le32_to_cpu(ev->num_tx_chain); i++) {
+ for (j = 0; j < 10; j++) {
+ rate_code[rate_idx] =
+ ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
+ rate_idx++;
+ }
+ }
+ pream_table[pream_idx] = rate_idx;
+ pream_idx++;
+
+ /* Fill VHT40 rate code */
+ for (i = 0; i < num_tx_chain; i++) {
+ for (j = 0; j < 10; j++) {
+ rate_code[rate_idx] =
+ ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
+ rate_idx++;
+ }
+ }
+ pream_table[pream_idx] = rate_idx;
+ pream_idx++;
+
+ /* Fill VHT80 rate code */
+ for (i = 0; i < num_tx_chain; i++) {
+ for (j = 0; j < 10; j++) {
+ rate_code[rate_idx] =
+ ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
+ rate_idx++;
+ }
+ }
+ pream_table[pream_idx] = rate_idx;
+ pream_idx++;
+
+ rate_code[rate_idx++] =
+ ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_CCK);
+ rate_code[rate_idx++] =
+ ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
+ rate_code[rate_idx++] =
+ ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_CCK);
+ rate_code[rate_idx++] =
+ ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
+ rate_code[rate_idx++] =
+ ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
+
+ pream_table[pream_idx] = ATH10K_TPC_PREAM_TABLE_END;
+
+ tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
+ tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
+ tpc_stats->ctl = __le32_to_cpu(ev->ctl);
+ tpc_stats->reg_domain = __le32_to_cpu(ev->reg_domain);
+ tpc_stats->twice_antenna_gain = a_sle32_to_cpu(ev->twice_antenna_gain);
+ tpc_stats->twice_antenna_reduction =
+ __le32_to_cpu(ev->twice_antenna_reduction);
+ tpc_stats->power_limit = __le32_to_cpu(ev->power_limit);
+ tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power);
+ tpc_stats->num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
+ tpc_stats->rate_max = __le32_to_cpu(ev->rate_max);
+
+ ath10k_tpc_config_disp_tables(ar, ev, tpc_stats,
+ rate_code, pream_table,
+ WMI_TPC_TABLE_TYPE_CDD);
+ ath10k_tpc_config_disp_tables(ar, ev, tpc_stats,
+ rate_code, pream_table,
+ WMI_TPC_TABLE_TYPE_STBC);
+ ath10k_tpc_config_disp_tables(ar, ev, tpc_stats,
+ rate_code, pream_table,
+ WMI_TPC_TABLE_TYPE_TXBF);
+
+ ath10k_debug_tpc_stats_process(ar, tpc_stats);
+
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
+ "wmi event tpc config channel %d mode %d ctl %d regd %d gain %d %d limit %d max_power %d tx_chanins %d rates %d\n",
+ __le32_to_cpu(ev->chan_freq),
+ __le32_to_cpu(ev->phy_mode),
+ __le32_to_cpu(ev->ctl),
+ __le32_to_cpu(ev->reg_domain),
+ a_sle32_to_cpu(ev->twice_antenna_gain),
+ __le32_to_cpu(ev->twice_antenna_reduction),
+ __le32_to_cpu(ev->power_limit),
+ __le32_to_cpu(ev->twice_max_rd_power) / 2,
+ __le32_to_cpu(ev->num_tx_chain),
+ __le32_to_cpu(ev->rate_max));
}
void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb)
@@ -5090,7 +5337,7 @@ static struct sk_buff *ath10k_wmi_10_4_op_gen_init(struct ath10k *ar)
config.rx_timeout_pri[2] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_LO_PRI);
config.rx_timeout_pri[3] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_HI_PRI);
- config.rx_decap_mode = __cpu_to_le32(TARGET_10_4_RX_DECAP_MODE);
+ config.rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode);
config.scan_max_pending_req = __cpu_to_le32(TARGET_10_4_SCAN_MAX_REQS);
config.bmiss_offload_max_vdev =
__cpu_to_le32(TARGET_10_4_BMISS_OFFLOAD_MAX_VDEV);
@@ -6356,6 +6603,399 @@ ath10k_wmi_op_gen_delba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac,
return skb;
}
+static struct sk_buff *
+ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config(struct ath10k *ar, u32 param)
+{
+ struct wmi_pdev_get_tpc_config_cmd *cmd;
+ struct sk_buff *skb;
+
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
+ if (!skb)
+ return ERR_PTR(-ENOMEM);
+
+ cmd = (struct wmi_pdev_get_tpc_config_cmd *)skb->data;
+ cmd->param = __cpu_to_le32(param);
+
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
+ "wmi pdev get tcp config param:%d\n", param);
+ return skb;
+}
+
+size_t ath10k_wmi_fw_stats_num_peers(struct list_head *head)
+{
+ struct ath10k_fw_stats_peer *i;
+ size_t num = 0;
+
+ list_for_each_entry(i, head, list)
+ ++num;
+
+ return num;
+}
+
+size_t ath10k_wmi_fw_stats_num_vdevs(struct list_head *head)
+{
+ struct ath10k_fw_stats_vdev *i;
+ size_t num = 0;
+
+ list_for_each_entry(i, head, list)
+ ++num;
+
+ return num;
+}
+
+static void
+ath10k_wmi_fw_pdev_base_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
+ char *buf, u32 *length)
+{
+ u32 len = *length;
+ u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ len += scnprintf(buf + len, buf_len - len, "%30s\n",
+ "ath10k PDEV stats");
+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+ "=================");
+
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Channel noise floor", pdev->ch_noise_floor);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "Channel TX power", pdev->chan_tx_power);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "TX frame count", pdev->tx_frame_count);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "RX frame count", pdev->rx_frame_count);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "RX clear count", pdev->rx_clear_count);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "Cycle count", pdev->cycle_count);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "PHY error count", pdev->phy_err_count);
+
+ *length = len;
+}
+
+static void
+ath10k_wmi_fw_pdev_extra_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
+ char *buf, u32 *length)
+{
+ u32 len = *length;
+ u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
+
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "RTS bad count", pdev->rts_bad);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "RTS good count", pdev->rts_good);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "FCS bad count", pdev->fcs_bad);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "No beacon count", pdev->no_beacons);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "MIB int count", pdev->mib_int_count);
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ *length = len;
+}
+
+static void
+ath10k_wmi_fw_pdev_tx_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
+ char *buf, u32 *length)
+{
+ u32 len = *length;
+ u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
+
+ len += scnprintf(buf + len, buf_len - len, "\n%30s\n",
+ "ath10k PDEV TX stats");
+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+ "=================");
+
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "HTT cookies queued", pdev->comp_queued);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "HTT cookies disp.", pdev->comp_delivered);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MSDU queued", pdev->msdu_enqued);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MPDU queued", pdev->mpdu_enqued);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MSDUs dropped", pdev->wmm_drop);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Local enqued", pdev->local_enqued);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Local freed", pdev->local_freed);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "HW queued", pdev->hw_queued);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "PPDUs reaped", pdev->hw_reaped);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Num underruns", pdev->underrun);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "PPDUs cleaned", pdev->tx_abort);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MPDUs requed", pdev->mpdus_requed);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Excessive retries", pdev->tx_ko);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "HW rate", pdev->data_rc);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Sched self tiggers", pdev->self_triggers);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Dropped due to SW retries",
+ pdev->sw_retry_failure);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Illegal rate phy errors",
+ pdev->illgl_rate_phy_err);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Pdev continuous xretry", pdev->pdev_cont_xretry);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "TX timeout", pdev->pdev_tx_timeout);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "PDEV resets", pdev->pdev_resets);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "PHY underrun", pdev->phy_underrun);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MPDU is more than txop limit", pdev->txop_ovf);
+ *length = len;
+}
+
+static void
+ath10k_wmi_fw_pdev_rx_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
+ char *buf, u32 *length)
+{
+ u32 len = *length;
+ u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
+
+ len += scnprintf(buf + len, buf_len - len, "\n%30s\n",
+ "ath10k PDEV RX stats");
+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+ "=================");
+
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Mid PPDU route change",
+ pdev->mid_ppdu_route_change);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Tot. number of statuses", pdev->status_rcvd);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Extra frags on rings 0", pdev->r0_frags);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Extra frags on rings 1", pdev->r1_frags);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Extra frags on rings 2", pdev->r2_frags);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Extra frags on rings 3", pdev->r3_frags);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MSDUs delivered to HTT", pdev->htt_msdus);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MPDUs delivered to HTT", pdev->htt_mpdus);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MSDUs delivered to stack", pdev->loc_msdus);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MPDUs delivered to stack", pdev->loc_mpdus);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "Oversized AMSUs", pdev->oversize_amsdu);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "PHY errors", pdev->phy_errs);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "PHY errors drops", pdev->phy_err_drop);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+ "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);
+ *length = len;
+}
+
+static void
+ath10k_wmi_fw_vdev_stats_fill(const struct ath10k_fw_stats_vdev *vdev,
+ char *buf, u32 *length)
+{
+ u32 len = *length;
+ u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
+ int i;
+
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "vdev id", vdev->vdev_id);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "beacon snr", vdev->beacon_snr);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "data snr", vdev->data_snr);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "num rx frames", vdev->num_rx_frames);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "num rts fail", vdev->num_rts_fail);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "num rts success", vdev->num_rts_success);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "num rx err", vdev->num_rx_err);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "num rx discard", vdev->num_rx_discard);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "num tx not acked", vdev->num_tx_not_acked);
+
+ for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
+ len += scnprintf(buf + len, buf_len - len,
+ "%25s [%02d] %u\n",
+ "num tx frames", i,
+ vdev->num_tx_frames[i]);
+
+ for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
+ len += scnprintf(buf + len, buf_len - len,
+ "%25s [%02d] %u\n",
+ "num tx frames retries", i,
+ vdev->num_tx_frames_retries[i]);
+
+ for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
+ len += scnprintf(buf + len, buf_len - len,
+ "%25s [%02d] %u\n",
+ "num tx frames failures", i,
+ vdev->num_tx_frames_failures[i]);
+
+ for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
+ len += scnprintf(buf + len, buf_len - len,
+ "%25s [%02d] 0x%08x\n",
+ "tx rate history", i,
+ vdev->tx_rate_history[i]);
+
+ for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
+ len += scnprintf(buf + len, buf_len - len,
+ "%25s [%02d] %u\n",
+ "beacon rssi history", i,
+ vdev->beacon_rssi_history[i]);
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ *length = len;
+}
+
+static void
+ath10k_wmi_fw_peer_stats_fill(const struct ath10k_fw_stats_peer *peer,
+ char *buf, u32 *length)
+{
+ u32 len = *length;
+ u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
+
+ len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
+ "Peer MAC address", peer->peer_macaddr);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "Peer RSSI", peer->peer_rssi);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "Peer TX rate", peer->peer_tx_rate);
+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ "Peer RX rate", peer->peer_rx_rate);
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ *length = len;
+}
+
+void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar,
+ struct ath10k_fw_stats *fw_stats,
+ char *buf)
+{
+ u32 len = 0;
+ u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
+ const struct ath10k_fw_stats_pdev *pdev;
+ const struct ath10k_fw_stats_vdev *vdev;
+ const struct ath10k_fw_stats_peer *peer;
+ size_t num_peers;
+ size_t num_vdevs;
+
+ spin_lock_bh(&ar->data_lock);
+
+ pdev = list_first_entry_or_null(&fw_stats->pdevs,
+ struct ath10k_fw_stats_pdev, list);
+ if (!pdev) {
+ ath10k_warn(ar, "failed to get pdev stats\n");
+ goto unlock;
+ }
+
+ num_peers = ath10k_wmi_fw_stats_num_peers(&fw_stats->peers);
+ num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&fw_stats->vdevs);
+
+ ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
+ ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
+ ath10k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
+ "ath10k VDEV stats", num_vdevs);
+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+ "=================");
+
+ list_for_each_entry(vdev, &fw_stats->vdevs, list) {
+ ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len);
+ }
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
+ "ath10k PEER stats", num_peers);
+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+ "=================");
+
+ list_for_each_entry(peer, &fw_stats->peers, list) {
+ ath10k_wmi_fw_peer_stats_fill(peer, buf, &len);
+ }
+
+unlock:
+ spin_unlock_bh(&ar->data_lock);
+
+ if (len >= buf_len)
+ buf[len - 1] = 0;
+ else
+ buf[len] = 0;
+}
+
+void ath10k_wmi_10x_op_fw_stats_fill(struct ath10k *ar,
+ struct ath10k_fw_stats *fw_stats,
+ char *buf)
+{
+ unsigned int len = 0;
+ unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
+ const struct ath10k_fw_stats_pdev *pdev;
+ const struct ath10k_fw_stats_vdev *vdev;
+ const struct ath10k_fw_stats_peer *peer;
+ size_t num_peers;
+ size_t num_vdevs;
+
+ spin_lock_bh(&ar->data_lock);
+
+ pdev = list_first_entry_or_null(&fw_stats->pdevs,
+ struct ath10k_fw_stats_pdev, list);
+ if (!pdev) {
+ ath10k_warn(ar, "failed to get pdev stats\n");
+ goto unlock;
+ }
+
+ num_peers = ath10k_wmi_fw_stats_num_peers(&fw_stats->peers);
+ num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&fw_stats->vdevs);
+
+ ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
+ ath10k_wmi_fw_pdev_extra_stats_fill(pdev, buf, &len);
+ ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
+ ath10k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
+ "ath10k VDEV stats", num_vdevs);
+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+ "=================");
+
+ list_for_each_entry(vdev, &fw_stats->vdevs, list) {
+ ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len);
+ }
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
+ "ath10k PEER stats", num_peers);
+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+ "=================");
+
+ list_for_each_entry(peer, &fw_stats->peers, list) {
+ ath10k_wmi_fw_peer_stats_fill(peer, buf, &len);
+ }
+
+unlock:
+ spin_unlock_bh(&ar->data_lock);
+
+ if (len >= buf_len)
+ buf[len - 1] = 0;
+ else
+ buf[len] = 0;
+}
+
static const struct wmi_ops wmi_ops = {
.rx = ath10k_wmi_op_rx,
.map_svc = wmi_main_svc_map,
@@ -6414,6 +7054,7 @@ static const struct wmi_ops wmi_ops = {
.gen_addba_send = ath10k_wmi_op_gen_addba_send,
.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
+ .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
@@ -6479,6 +7120,7 @@ static const struct wmi_ops wmi_10_1_ops = {
.gen_addba_send = ath10k_wmi_op_gen_addba_send,
.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
+ .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
@@ -6545,6 +7187,7 @@ static const struct wmi_ops wmi_10_2_ops = {
.gen_addba_send = ath10k_wmi_op_gen_addba_send,
.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
+ .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
};
static const struct wmi_ops wmi_10_2_4_ops = {
@@ -6606,6 +7249,8 @@ static const struct wmi_ops wmi_10_2_4_ops = {
.gen_addba_send = ath10k_wmi_op_gen_addba_send,
.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
+ .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
+ .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 3e5a159..6e84d1c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -73,6 +73,25 @@ struct wmi_cmd_hdr {
#define HTC_PROTOCOL_VERSION 0x0002
#define WMI_PROTOCOL_VERSION 0x0002
+/*
+ * There is no signed version of __le32, so for a temporary solution come
+ * up with our own version. The idea is from fs/ntfs/types.h.
+ *
+ * Use a_ prefix so that it doesn't conflict if we get proper support to
+ * linux/types.h.
+ */
+typedef __s32 __bitwise a_sle32;
+
+static inline a_sle32 a_cpu_to_sle32(s32 val)
+{
+ return (__force a_sle32)cpu_to_le32(val);
+}
+
+static inline s32 a_sle32_to_cpu(a_sle32 val)
+{
+ return le32_to_cpu((__force __le32)val);
+}
+
enum wmi_service {
WMI_SERVICE_BEACON_OFFLOAD = 0,
WMI_SERVICE_SCAN_OFFLOAD,
@@ -3642,8 +3661,18 @@ struct wmi_pdev_get_tpc_config_cmd {
__le32 param;
} __packed;
+#define WMI_TPC_CONFIG_PARAM 1
#define WMI_TPC_RATE_MAX 160
#define WMI_TPC_TX_N_CHAIN 4
+#define WMI_TPC_PREAM_TABLE_MAX 10
+#define WMI_TPC_FLAG 3
+#define WMI_TPC_BUF_SIZE 10
+
+enum wmi_tpc_table_type {
+ WMI_TPC_TABLE_TYPE_CDD = 0,
+ WMI_TPC_TABLE_TYPE_STBC = 1,
+ WMI_TPC_TABLE_TYPE_TXBF = 2,
+};
enum wmi_tpc_config_event_flag {
WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD = 0x1,
@@ -3657,7 +3686,7 @@ struct wmi_pdev_tpc_config_event {
__le32 phy_mode;
__le32 twice_antenna_reduction;
__le32 twice_max_rd_power;
- s32 twice_antenna_gain;
+ a_sle32 twice_antenna_gain;
__le32 power_limit;
__le32 rate_max;
__le32 num_tx_chain;
@@ -4253,6 +4282,11 @@ enum wmi_rate_preamble {
WMI_RATE_PREAMBLE_VHT,
};
+#define ATH10K_HW_NSS(rate) (1 + (((rate) >> 4) & 0x3))
+#define ATH10K_HW_PREAMBLE(rate) (((rate) >> 6) & 0x3)
+#define ATH10K_HW_RATECODE(rate, nss, preamble) \
+ (((preamble) << 6) | ((nss) << 4) | (rate))
+
/* Value to disable fixed rate setting */
#define WMI_FIXED_RATE_NONE (0xff)
@@ -6064,6 +6098,7 @@ struct ath10k;
struct ath10k_vif;
struct ath10k_fw_stats_pdev;
struct ath10k_fw_stats_peer;
+struct ath10k_fw_stats;
int ath10k_wmi_attach(struct ath10k *ar);
void ath10k_wmi_detach(struct ath10k *ar);
@@ -6145,4 +6180,13 @@ void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_op_pull_phyerr_ev(struct ath10k *ar, const void *phyerr_buf,
int left_len, struct wmi_phyerr_ev_arg *arg);
+void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar,
+ struct ath10k_fw_stats *fw_stats,
+ char *buf);
+void ath10k_wmi_10x_op_fw_stats_fill(struct ath10k *ar,
+ struct ath10k_fw_stats *fw_stats,
+ char *buf);
+size_t ath10k_wmi_fw_stats_num_peers(struct list_head *head);
+size_t ath10k_wmi_fw_stats_num_vdevs(struct list_head *head);
+
#endif /* _WMI_H_ */
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 3fda750..76b682e 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2217,7 +2217,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
/* enter / leave wow suspend on first vif always */
first_vif = ath6kl_vif_first(ar);
- if (WARN_ON(unlikely(!first_vif)) ||
+ if (WARN_ON(!first_vif) ||
!ath6kl_cfg80211_ready(first_vif))
return -EIO;
@@ -2297,7 +2297,7 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
int ret;
vif = ath6kl_vif_first(ar);
- if (WARN_ON(unlikely(!vif)) ||
+ if (WARN_ON(!vif) ||
!ath6kl_cfg80211_ready(vif))
return -EIO;
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index e481f14..fffb65b 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -1085,9 +1085,7 @@ static int htc_setup_tx_complete(struct htc_target *target)
send_pkt->completion = NULL;
ath6kl_htc_tx_prep_pkt(send_pkt, 0, 0, 0);
status = ath6kl_htc_tx_issue(target, send_pkt);
-
- if (send_pkt != NULL)
- htc_reclaim_txctrl_buf(target, send_pkt);
+ htc_reclaim_txctrl_buf(target, send_pkt);
return status;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index 6314ae2..9d17a53 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -610,8 +610,8 @@
#define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ -127
#define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ -116
-#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -120
+#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -112
#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ -127
-#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -110
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -97
#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 79fd3b2..8b238c1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -857,7 +857,7 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
qca956x_1p0_common_rx_gain_table);
INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
qca956x_1p0_common_rx_gain_bounds);
- INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+ INIT_INI_ARRAY(&ah->ini_modes_rxgain_xlna,
qca956x_1p0_xlna_only);
} else if (AR_SREV_9580(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
@@ -942,7 +942,7 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
ar9462_2p1_baseband_core_mix_rxgain);
INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
ar9462_2p1_baseband_postamble_mix_rxgain);
- INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+ INIT_INI_ARRAY(&ah->ini_modes_rxgain_xlna,
ar9462_2p1_baseband_postamble_5g_xlna);
} else if (AR_SREV_9462_20(ah)) {
INIT_INI_ARRAY(&ah->iniModesRxGain,
@@ -951,7 +951,7 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
ar9462_2p0_baseband_core_mix_rxgain);
INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
ar9462_2p0_baseband_postamble_mix_rxgain);
- INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+ INIT_INI_ARRAY(&ah->ini_modes_rxgain_xlna,
ar9462_2p0_baseband_postamble_5g_xlna);
}
}
@@ -961,12 +961,12 @@ static void ar9003_rx_gain_table_mode3(struct ath_hw *ah)
if (AR_SREV_9462_21(ah)) {
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_2p1_common_5g_xlna_only_rxgain);
- INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+ INIT_INI_ARRAY(&ah->ini_modes_rxgain_xlna,
ar9462_2p1_baseband_postamble_5g_xlna);
} else if (AR_SREV_9462_20(ah)) {
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_2p0_common_5g_xlna_only_rxgain);
- INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+ INIT_INI_ARRAY(&ah->ini_modes_rxgain_xlna,
ar9462_2p0_baseband_postamble_5g_xlna);
}
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 1ad66b7..201425e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -926,19 +926,18 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
*/
if ((ar9003_hw_get_rx_gain_idx(ah) == 2) ||
(ar9003_hw_get_rx_gain_idx(ah) == 3)) {
- REG_WRITE_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+ REG_WRITE_ARRAY(&ah->ini_modes_rxgain_xlna,
modesIndex, regWrites);
}
-
- if (AR_SREV_9561(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0))
- REG_WRITE_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
- modesIndex, regWrites);
}
if (AR_SREV_9550(ah) || AR_SREV_9561(ah))
REG_WRITE_ARRAY(&ah->ini_modes_rx_gain_bounds, modesIndex,
regWrites);
+ if (AR_SREV_9561(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0))
+ REG_WRITE_ARRAY(&ah->ini_modes_rxgain_xlna,
+ modesIndex, regWrites);
/*
* TXGAIN initvals.
*/
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e8454db..4f0a3f6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -919,7 +919,7 @@ struct ath_hw {
struct ar5416IniArray iniCckfirJapan2484;
struct ar5416IniArray iniModes_9271_ANI_reg;
struct ar5416IniArray ini_radio_post_sys2ant;
- struct ar5416IniArray ini_modes_rxgain_5g_xlna;
+ struct ar5416IniArray ini_modes_rxgain_xlna;
struct ar5416IniArray ini_modes_rxgain_bb_core;
struct ar5416IniArray ini_modes_rxgain_bb_postamble;
diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c
index 9d68712..2303ef9 100644
--- a/drivers/net/wireless/ath/dfs_pattern_detector.c
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
@@ -284,10 +284,10 @@ dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event)
if (cd == NULL)
return false;
- dpd->last_pulse_ts = event->ts;
/* reset detector on time stamp wraparound, caused by TSF reset */
if (event->ts < dpd->last_pulse_ts)
dpd_reset(dpd);
+ dpd->last_pulse_ts = event->ts;
/* do type individual pattern matching */
for (i = 0; i < dpd->num_radar_types; i++) {
diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig
index ce8c038..6dfedc8 100644
--- a/drivers/net/wireless/ath/wil6210/Kconfig
+++ b/drivers/net/wireless/ath/wil6210/Kconfig
@@ -1,5 +1,6 @@
config WIL6210
tristate "Wilocity 60g WiFi card wil6210 support"
+ select WANT_DEV_COREDUMP
depends on CFG80211
depends on PCI
default n
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile
index 64b4326..fdf63d5 100644
--- a/drivers/net/wireless/ath/wil6210/Makefile
+++ b/drivers/net/wireless/ath/wil6210/Makefile
@@ -17,6 +17,7 @@ wil6210-y += pmc.o
wil6210-$(CONFIG_WIL6210_TRACING) += trace.o
wil6210-y += wil_platform.o
wil6210-y += ethtool.o
+wil6210-y += wil_crash_dump.o
# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index d1a1e16..97bc186 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1373,6 +1373,12 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
}
}
spin_unlock_bh(&p->tid_rx_lock);
+ seq_printf(s,
+ "Rx invalid frame: non-data %lu, short %lu, large %lu\n",
+ p->stats.rx_non_data_frame,
+ p->stats.rx_short_frame,
+ p->stats.rx_large_frame);
+
seq_puts(s, "Rx/MCS:");
for (mcs = 0; mcs < ARRAY_SIZE(p->stats.rx_per_mcs);
mcs++)
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index a371f036..06fc46f 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -347,7 +347,12 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
wil6210_mask_irq_misc(wil);
if (isr & ISR_MISC_FW_ERROR) {
- wil_err(wil, "Firmware error detected\n");
+ u32 fw_assert_code = wil_r(wil, RGF_FW_ASSERT_CODE);
+ u32 ucode_assert_code = wil_r(wil, RGF_UCODE_ASSERT_CODE);
+
+ wil_err(wil,
+ "Firmware error detected, assert codes FW 0x%08x, UCODE 0x%08x\n",
+ fw_assert_code, ucode_assert_code);
clear_bit(wil_status_fwready, wil->status);
/*
* do not clear @isr here - we do 2-nd part in thread
@@ -386,6 +391,7 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);
if (isr & ISR_MISC_FW_ERROR) {
+ wil_fw_core_dump(wil);
wil_notify_fw_error(wil);
isr &= ~ISR_MISC_FW_ERROR;
wil_fw_error_recovery(wil);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 2fb04c5..aade16b 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -203,11 +203,13 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
* - disconnect single STA, already disconnected
* - disconnect all
*
- * For "disconnect all", there are 2 options:
+ * For "disconnect all", there are 3 options:
* - bssid == NULL
+ * - bssid is broadcast address (ff:ff:ff:ff:ff:ff)
* - bssid is our MAC address
*/
- if (bssid && memcmp(ndev->dev_addr, bssid, ETH_ALEN)) {
+ if (bssid && !is_broadcast_ether_addr(bssid) &&
+ !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) {
cid = wil_find_cid(wil, bssid);
wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n",
bssid, cid, reason_code);
@@ -765,6 +767,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
if (wil->hw_version == HW_VER_UNKNOWN)
return -ENODEV;
+ set_bit(wil_status_resetting, wil->status);
+
cancel_work_sync(&wil->disconnect_worker);
wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
wil_bcast_fini(wil);
@@ -851,6 +855,12 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
void wil_fw_error_recovery(struct wil6210_priv *wil)
{
wil_dbg_misc(wil, "starting fw error recovery\n");
+
+ if (test_bit(wil_status_resetting, wil->status)) {
+ wil_info(wil, "Reset already in progress\n");
+ return;
+ }
+
wil->recovery_state = fw_recovery_pending;
schedule_work(&wil->fw_error_worker);
}
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index feff1ef..1a3142c3 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -260,6 +260,7 @@ static const struct pci_device_id wil6210_pcie_ids[] = {
MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids);
#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int wil6210_suspend(struct device *dev, bool is_runtime)
{
@@ -307,7 +308,6 @@ static int wil6210_resume(struct device *dev, bool is_runtime)
return rc;
}
-#ifdef CONFIG_PM_SLEEP
static int wil6210_pm_suspend(struct device *dev)
{
return wil6210_suspend(dev, false);
diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c
index 8a8cdc6..5ca0307 100644
--- a/drivers/net/wireless/ath/wil6210/pmc.c
+++ b/drivers/net/wireless/ath/wil6210/pmc.c
@@ -110,7 +110,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
*/
for (i = 0; i < num_descriptors; i++) {
struct vring_tx_desc *_d = &pmc->pring_va[i];
- struct vring_tx_desc dd, *d = &dd;
+ struct vring_tx_desc dd = {}, *d = &dd;
int j = 0;
pmc->descriptors[i].va = dma_alloc_coherent(dev,
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index 9238c1a..e3d1be8 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -205,6 +205,32 @@ out:
spin_unlock(&sta->tid_rx_lock);
}
+/* process BAR frame, called in NAPI context */
+void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq)
+{
+ struct wil_sta_info *sta = &wil->sta[cid];
+ struct wil_tid_ampdu_rx *r;
+
+ spin_lock(&sta->tid_rx_lock);
+
+ r = sta->tid_rx[tid];
+ if (!r) {
+ wil_err(wil, "BAR for non-existing CID %d TID %d\n", cid, tid);
+ goto out;
+ }
+ if (seq_less(seq, r->head_seq_num)) {
+ wil_err(wil, "BAR Seq 0x%03x preceding head 0x%03x\n",
+ seq, r->head_seq_num);
+ goto out;
+ }
+ wil_dbg_txrx(wil, "BAR: CID %d TID %d Seq 0x%03x head 0x%03x\n",
+ cid, tid, seq, r->head_seq_num);
+ wil_release_reorder_frames(wil, r, seq);
+
+out:
+ spin_unlock(&sta->tid_rx_lock);
+}
+
struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
int size, u16 ssn)
{
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 6229110..0f8b687 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -358,6 +358,13 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
}
}
+/* similar to ieee80211_ version, but FC contain only 1-st byte */
+static inline int wil_is_back_req(u8 fc)
+{
+ return (fc & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+ (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ);
+}
+
/**
* reap 1 frame from @swhead
*
@@ -379,14 +386,16 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
u16 dmalen;
u8 ftype;
int cid;
- int i = (int)vring->swhead;
+ int i;
struct wil_net_stats *stats;
BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
+again:
if (unlikely(wil_vring_is_empty(vring)))
return NULL;
+ i = (int)vring->swhead;
_d = &vring->va[i].rx;
if (unlikely(!(_d->dma.status & RX_DMA_STATUS_DU))) {
/* it is not error, we just reached end of Rx done area */
@@ -398,7 +407,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
wil_vring_advance_head(vring, 1);
if (!skb) {
wil_err(wil, "No Rx skb at [%d]\n", i);
- return NULL;
+ goto again;
}
d = wil_skb_rxdesc(skb);
*d = *_d;
@@ -409,13 +418,17 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
trace_wil6210_rx(i, d);
wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", i, dmalen);
- wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
+ wil_hex_dump_txrx("RxD ", DUMP_PREFIX_NONE, 32, 4,
(const void *)d, sizeof(*d), false);
+ cid = wil_rxdesc_cid(d);
+ stats = &wil->sta[cid].stats;
+
if (unlikely(dmalen > sz)) {
wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
+ stats->rx_large_frame++;
kfree_skb(skb);
- return NULL;
+ goto again;
}
skb_trim(skb, dmalen);
@@ -424,8 +437,6 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, skb_headlen(skb), false);
- cid = wil_rxdesc_cid(d);
- stats = &wil->sta[cid].stats;
stats->last_mcs_rx = wil_rxdesc_mcs(d);
if (stats->last_mcs_rx < ARRAY_SIZE(stats->rx_per_mcs))
stats->rx_per_mcs[stats->last_mcs_rx]++;
@@ -437,24 +448,47 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
/* no extra checks if in sniffer mode */
if (ndev->type != ARPHRD_ETHER)
return skb;
- /*
- * Non-data frames may be delivered through Rx DMA channel (ex: BAR)
+ /* Non-data frames may be delivered through Rx DMA channel (ex: BAR)
* Driver should recognize it by frame type, that is found
* in Rx descriptor. If type is not data, it is 802.11 frame as is
*/
ftype = wil_rxdesc_ftype(d) << 2;
if (unlikely(ftype != IEEE80211_FTYPE_DATA)) {
- wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
- /* TODO: process it */
+ u8 fc1 = wil_rxdesc_fc1(d);
+ int mid = wil_rxdesc_mid(d);
+ int tid = wil_rxdesc_tid(d);
+ u16 seq = wil_rxdesc_seq(d);
+
+ wil_dbg_txrx(wil,
+ "Non-data frame FC[7:0] 0x%02x MID %d CID %d TID %d Seq 0x%03x\n",
+ fc1, mid, cid, tid, seq);
+ stats->rx_non_data_frame++;
+ if (wil_is_back_req(fc1)) {
+ wil_dbg_txrx(wil,
+ "BAR: MID %d CID %d TID %d Seq 0x%03x\n",
+ mid, cid, tid, seq);
+ wil_rx_bar(wil, cid, tid, seq);
+ } else {
+ /* print again all info. One can enable only this
+ * without overhead for printing every Rx frame
+ */
+ wil_dbg_txrx(wil,
+ "Unhandled non-data frame FC[7:0] 0x%02x MID %d CID %d TID %d Seq 0x%03x\n",
+ fc1, mid, cid, tid, seq);
+ wil_hex_dump_txrx("RxD ", DUMP_PREFIX_NONE, 32, 4,
+ (const void *)d, sizeof(*d), false);
+ wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
+ skb->data, skb_headlen(skb), false);
+ }
kfree_skb(skb);
- return NULL;
+ goto again;
}
if (unlikely(skb->len < ETH_HLEN + snaplen)) {
wil_err(wil, "Short frame, len = %d\n", skb->len);
- /* TODO: process it (i.e. BAR) */
+ stats->rx_short_frame++;
kfree_skb(skb);
- return NULL;
+ goto again;
}
/* L4 IDENT is on when HW calculated checksum, check status
@@ -1633,7 +1667,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
goto drop;
}
if (unlikely(!test_bit(wil_status_fwconnected, wil->status))) {
- wil_err(wil, "FW not connected\n");
+ wil_err_ratelimited(wil, "FW not connected\n");
goto drop;
}
if (unlikely(wil->wdev->iftype == NL80211_IFTYPE_MONITOR)) {
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 82a8f9a..ee7c7b4 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -464,6 +464,12 @@ static inline int wil_rxdesc_subtype(struct vring_rx_desc *d)
return WIL_GET_BITS(d->mac.d0, 12, 15);
}
+/* 1-st byte (with frame type/subtype) of FC field */
+static inline u8 wil_rxdesc_fc1(struct vring_rx_desc *d)
+{
+ return (u8)(WIL_GET_BITS(d->mac.d0, 10, 15) << 2);
+}
+
static inline int wil_rxdesc_seq(struct vring_rx_desc *d)
{
return WIL_GET_BITS(d->mac.d0, 16, 27);
@@ -501,6 +507,7 @@ static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb)
void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev);
void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb);
+void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq);
struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
int size, u16 ssn);
void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index dd4ea92..f619bf2 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -246,6 +246,10 @@ struct RGF_ICR {
#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */
#define JTAG_DEV_ID_SPARROW_B0 (0x2632072f)
+/* crash codes for FW/Ucode stored here */
+#define RGF_FW_ASSERT_CODE (0x91f020)
+#define RGF_UCODE_ASSERT_CODE (0x91f028)
+
enum {
HW_VER_UNKNOWN,
HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
@@ -405,6 +409,7 @@ enum { /* for wil6210_priv.status */
wil_status_reset_done,
wil_status_irqen, /* FIXME: interrupts enabled - for debug */
wil_status_napi_en, /* NAPI enabled protected by wil->mutex */
+ wil_status_resetting, /* reset in progress */
wil_status_last /* keep last */
};
@@ -465,6 +470,9 @@ struct wil_net_stats {
unsigned long tx_bytes;
unsigned long tx_errors;
unsigned long rx_dropped;
+ unsigned long rx_non_data_frame;
+ unsigned long rx_short_frame;
+ unsigned long rx_large_frame;
u16 last_mcs_rx;
u64 rx_per_mcs[WIL_MCS_MAX + 1];
};
@@ -820,4 +828,6 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime);
int wil_suspend(struct wil6210_priv *wil, bool is_runtime);
int wil_resume(struct wil6210_priv *wil, bool is_runtime);
+void wil_fw_core_dump(struct wil6210_priv *wil);
+
#endif /* __WIL6210_H__ */
diff --git a/drivers/net/wireless/ath/wil6210/wil_crash_dump.c b/drivers/net/wireless/ath/wil6210/wil_crash_dump.c
new file mode 100644
index 0000000..7e70934
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/wil_crash_dump.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "wil6210.h"
+#include <linux/devcoredump.h>
+
+static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil,
+ u32 *out_dump_size, u32 *out_host_min)
+{
+ int i;
+ const struct fw_map *map;
+ u32 host_min, host_max, tmp_max;
+
+ if (!out_dump_size)
+ return -EINVAL;
+
+ /* calculate the total size of the unpacked crash dump */
+ BUILD_BUG_ON(ARRAY_SIZE(fw_mapping) == 0);
+ map = &fw_mapping[0];
+ host_min = map->host;
+ host_max = map->host + (map->to - map->from);
+
+ for (i = 1; i < ARRAY_SIZE(fw_mapping); i++) {
+ map = &fw_mapping[i];
+
+ if (map->host < host_min)
+ host_min = map->host;
+
+ tmp_max = map->host + (map->to - map->from);
+ if (tmp_max > host_max)
+ host_max = tmp_max;
+ }
+
+ *out_dump_size = host_max - host_min;
+ if (out_host_min)
+ *out_host_min = host_min;
+
+ return 0;
+}
+
+static int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest,
+ u32 size)
+{
+ int i;
+ const struct fw_map *map;
+ void *data;
+ u32 host_min, dump_size, offset, len;
+
+ if (wil_fw_get_crash_dump_bounds(wil, &dump_size, &host_min)) {
+ wil_err(wil, "%s: fail to obtain crash dump size\n", __func__);
+ return -EINVAL;
+ }
+
+ if (dump_size > size) {
+ wil_err(wil, "%s: not enough space for dump. Need %d have %d\n",
+ __func__, dump_size, size);
+ return -EINVAL;
+ }
+
+ /* copy to crash dump area */
+ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
+ map = &fw_mapping[i];
+
+ data = (void * __force)wil->csr + HOSTADDR(map->host);
+ len = map->to - map->from;
+ offset = map->host - host_min;
+
+ wil_dbg_misc(wil, "%s() - dump %s, size %d, offset %d\n",
+ __func__, fw_mapping[i].name, len, offset);
+
+ wil_memcpy_fromio_32((void * __force)(dest + offset),
+ (const void __iomem * __force)data, len);
+ }
+
+ return 0;
+}
+
+void wil_fw_core_dump(struct wil6210_priv *wil)
+{
+ void *fw_dump_data;
+ u32 fw_dump_size;
+
+ if (wil_fw_get_crash_dump_bounds(wil, &fw_dump_size, NULL)) {
+ wil_err(wil, "%s: fail to get fw dump size\n", __func__);
+ return;
+ }
+
+ fw_dump_data = vzalloc(fw_dump_size);
+ if (!fw_dump_data)
+ return;
+
+ if (wil_fw_copy_crash_dump(wil, fw_dump_data, fw_dump_size)) {
+ vfree(fw_dump_data);
+ return;
+ }
+ /* fw_dump_data will be free in device coredump release function
+ * after 5 min
+ */
+ dev_coredumpv(wil_to_dev(wil), fw_dump_data, fw_dump_size, GFP_KERNEL);
+ wil_info(wil, "%s: fw core dumped, size %d bytes\n", __func__,
+ fw_dump_size);
+}
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 2f35d4c..6112189 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -1120,7 +1120,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP);
cmd.sniffer_cfg.phy_support =
cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
- ? WMI_SNIFFER_CP : WMI_SNIFFER_DP);
+ ? WMI_SNIFFER_CP : WMI_SNIFFER_BOTH_PHYS);
} else {
/* Initialize offload (in non-sniffer mode).
* Linux IP stack always calculates IP checksum
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index fe3dc12..ab42b1f 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -82,5 +82,6 @@ config BRCM_TRACING
config BRCMDBG
bool "Broadcom driver debug functions"
depends on BRCMSMAC || BRCMFMAC
+ select WANT_DEV_COREDUMP
---help---
Selecting this enables additional code for debug purposes.
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
index 89e6a4d..230cad7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
@@ -65,6 +65,8 @@ struct brcmf_bus_dcmd {
* @rxctl: receive a control response message from dongle.
* @gettxq: obtain a reference of bus transmit queue (optional).
* @wowl_config: specify if dongle is configured for wowl when going to suspend
+ * @get_ramsize: obtain size of device memory.
+ * @get_memdump: obtain device memory dump in provided buffer.
*
* This structure provides an abstract interface towards the
* bus specific driver. For control messages to common driver
@@ -79,6 +81,8 @@ struct brcmf_bus_ops {
int (*rxctl)(struct device *dev, unsigned char *msg, uint len);
struct pktq * (*gettxq)(struct device *dev);
void (*wowl_config)(struct device *dev, bool enabled);
+ size_t (*get_ramsize)(struct device *dev);
+ int (*get_memdump)(struct device *dev, void *data, size_t len);
};
@@ -185,6 +189,23 @@ void brcmf_bus_wowl_config(struct brcmf_bus *bus, bool enabled)
bus->ops->wowl_config(bus->dev, enabled);
}
+static inline size_t brcmf_bus_get_ramsize(struct brcmf_bus *bus)
+{
+ if (!bus->ops->get_ramsize)
+ return 0;
+
+ return bus->ops->get_ramsize(bus->dev);
+}
+
+static inline
+int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
+{
+ if (!bus->ops->get_memdump)
+ return -EOPNOTSUPP;
+
+ return bus->ops->get_memdump(bus->dev, data, len);
+}
+
/*
* interface functions from common layer
*/
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index 891f4ed..deb5f78 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -840,7 +840,6 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
}
if (!err) {
- set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
brcmf_dbg(INFO, "IF Type = AP\n");
}
} else {
@@ -2432,6 +2431,9 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_sta_info_le sta_info_le;
u32 sta_flags;
u32 is_tdls_peer;
+ s32 total_rssi;
+ s32 count_rssi;
+ u32 i;
brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
if (!check_vif_up(ifp->vif))
@@ -2478,13 +2480,13 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
if (sinfo->tx_packets) {
sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
- sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate);
- sinfo->txrate.legacy /= 100;
+ sinfo->txrate.legacy =
+ le32_to_cpu(sta_info_le.tx_rate) / 100;
}
if (sinfo->rx_packets) {
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
- sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate);
- sinfo->rxrate.legacy /= 100;
+ sinfo->rxrate.legacy =
+ le32_to_cpu(sta_info_le.rx_rate) / 100;
}
if (le16_to_cpu(sta_info_le.ver) >= 4) {
sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
@@ -2492,12 +2494,61 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
}
+ total_rssi = 0;
+ count_rssi = 0;
+ for (i = 0; i < BRCMF_ANT_MAX; i++) {
+ if (sta_info_le.rssi[i]) {
+ sinfo->chain_signal_avg[count_rssi] =
+ sta_info_le.rssi[i];
+ sinfo->chain_signal[count_rssi] =
+ sta_info_le.rssi[i];
+ total_rssi += sta_info_le.rssi[i];
+ count_rssi++;
+ }
+ }
+ if (count_rssi) {
+ sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
+ sinfo->chains = count_rssi;
+
+ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+ total_rssi /= count_rssi;
+ sinfo->signal = total_rssi;
+ }
}
done:
brcmf_dbg(TRACE, "Exit\n");
return err;
}
+static int
+brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
+ int idx, u8 *mac, struct station_info *sinfo)
+{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ s32 err;
+
+ brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
+
+ if (idx == 0) {
+ cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
+ &cfg->assoclist,
+ sizeof(cfg->assoclist));
+ if (err) {
+ brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
+ err);
+ cfg->assoclist.count = 0;
+ return -EOPNOTSUPP;
+ }
+ }
+ if (idx < le32_to_cpu(cfg->assoclist.count)) {
+ memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
+ return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
+ }
+ return -ENOENT;
+}
+
static s32
brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
bool enabled, s32 timeout)
@@ -4199,8 +4250,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
brcmf_dbg(TRACE, "GO mode configuration complete\n");
}
- clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
+ brcmf_net_setcarrier(ifp, true);
exit:
if ((err) && (!mbss)) {
@@ -4264,8 +4315,8 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
}
brcmf_set_mpc(ifp, 1);
brcmf_configure_arp_offload(ifp, true);
- set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
+ brcmf_net_setcarrier(ifp, false);
return err;
}
@@ -4597,6 +4648,7 @@ static struct cfg80211_ops wl_cfg80211_ops = {
.join_ibss = brcmf_cfg80211_join_ibss,
.leave_ibss = brcmf_cfg80211_leave_ibss,
.get_station = brcmf_cfg80211_get_station,
+ .dump_station = brcmf_cfg80211_dump_station,
.set_tx_power = brcmf_cfg80211_set_tx_power,
.get_tx_power = brcmf_cfg80211_get_tx_power,
.add_key = brcmf_cfg80211_add_key,
@@ -4974,6 +5026,7 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
&ifp->vif->sme_state);
} else
brcmf_bss_connect_done(cfg, ndev, e, true);
+ brcmf_net_setcarrier(ifp, true);
} else if (brcmf_is_linkdown(e)) {
brcmf_dbg(CONN, "Linkdown\n");
if (!brcmf_is_ibssmode(ifp->vif)) {
@@ -4983,6 +5036,7 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
brcmf_init_prof(ndev_to_prof(ndev));
if (ndev != cfg_to_ndev(cfg))
complete(&cfg->vif_disabled);
+ brcmf_net_setcarrier(ifp, false);
} else if (brcmf_is_nonetwork(cfg, e)) {
if (brcmf_is_ibssmode(ifp->vif))
clear_bit(BRCMF_VIF_STATUS_CONNECTING,
@@ -6238,6 +6292,17 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
else
*cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
}
+ /* p2p might require that "if-events" get processed by fweh. So
+ * activate the already registered event handlers now and activate
+ * the rest when initialization has completed. drvr->config needs to
+ * be assigned before activating events.
+ */
+ drvr->config = cfg;
+ err = brcmf_fweh_activate_events(ifp);
+ if (err) {
+ brcmf_err("FWEH activation failed (%d)\n", err);
+ goto wiphy_unreg_out;
+ }
err = brcmf_p2p_attach(cfg, p2pdev_forced);
if (err) {
@@ -6260,6 +6325,13 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
brcmf_notify_tdls_peer_event);
}
+ /* (re-) activate FWEH event handling */
+ err = brcmf_fweh_activate_events(ifp);
+ if (err) {
+ brcmf_err("FWEH activation failed (%d)\n", err);
+ goto wiphy_unreg_out;
+ }
+
return cfg;
wiphy_unreg_out:
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
index 3f5e550..6a878c8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
@@ -143,7 +143,6 @@ struct brcmf_cfg80211_profile {
* @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress.
* @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully.
* @BRCMF_VIF_STATUS_DISCONNECTING: disconnect/disable in progress.
- * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation.
* @BRCMF_VIF_STATUS_AP_CREATED: AP operation started.
*/
enum brcmf_vif_status {
@@ -151,7 +150,6 @@ enum brcmf_vif_status {
BRCMF_VIF_STATUS_CONNECTING,
BRCMF_VIF_STATUS_CONNECTED,
BRCMF_VIF_STATUS_DISCONNECTING,
- BRCMF_VIF_STATUS_AP_CREATING,
BRCMF_VIF_STATUS_AP_CREATED
};
@@ -407,6 +405,7 @@ struct brcmf_cfg80211_info {
struct brcmu_d11inf d11inf;
bool wowl_enabled;
u32 pre_wowl_pmmode;
+ struct brcmf_assoclist_le assoclist;
};
/**
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
index ffc3ace..f04833d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -682,6 +682,7 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
case BRCM_CC_43570_CHIP_ID:
case BRCM_CC_4358_CHIP_ID:
case BRCM_CC_43602_CHIP_ID:
+ case BRCM_CC_4371_CHIP_ID:
return 0x180000;
case BRCM_CC_4365_CHIP_ID:
case BRCM_CC_4366_CHIP_ID:
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/common.h b/drivers/net/wireless/brcm80211/brcmfmac/common.h
index 0d39d80..21c7488 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/common.h
@@ -17,4 +17,7 @@
extern const u8 ALLFFMAC[ETH_ALEN];
+/* Sets dongle media info (drv_version, mac address). */
+int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
+
#endif /* BRCMFMAC_COMMON_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index 8c2a280..b5ab98e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -33,6 +33,7 @@
#include "feature.h"
#include "proto.h"
#include "pcie.h"
+#include "common.h"
MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -634,8 +635,7 @@ static int brcmf_netdev_stop(struct net_device *ndev)
brcmf_cfg80211_down(ndev);
- /* Set state and stop OS transmissions */
- netif_stop_queue(ndev);
+ brcmf_net_setcarrier(ifp, false);
return 0;
}
@@ -669,8 +669,8 @@ static int brcmf_netdev_open(struct net_device *ndev)
return -EIO;
}
- /* Allow transmit calls */
- netif_start_queue(ndev);
+ /* Clear, carrier, set when connected or AP mode. */
+ netif_carrier_off(ndev);
return 0;
}
@@ -735,6 +735,24 @@ static void brcmf_net_detach(struct net_device *ndev)
brcmf_cfg80211_free_netdev(ndev);
}
+void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
+{
+ struct net_device *ndev;
+
+ brcmf_dbg(TRACE, "Enter, idx=%d carrier=%d\n", ifp->bssidx, on);
+
+ ndev = ifp->ndev;
+ brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_DISCONNECTED, !on);
+ if (on) {
+ if (!netif_carrier_ok(ndev))
+ netif_carrier_on(ndev);
+
+ } else {
+ if (netif_carrier_ok(ndev))
+ netif_carrier_off(ndev);
+ }
+}
+
static int brcmf_net_p2p_open(struct net_device *ndev)
{
brcmf_dbg(TRACE, "Enter\n");
@@ -828,8 +846,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
} else {
brcmf_dbg(INFO, "allocate netdev interface\n");
/* Allocate netdev, including space for private structure */
- ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN,
- ether_setup);
+ ndev = alloc_netdev(sizeof(*ifp), is_p2pdev ? "p2p%d" : name,
+ NET_NAME_UNKNOWN, ether_setup);
if (!ndev)
return ERR_PTR(-ENOMEM);
@@ -957,8 +975,8 @@ int brcmf_attach(struct device *dev)
drvr->bus_if = dev_get_drvdata(dev);
drvr->bus_if->drvr = drvr;
- /* create device debugfs folder */
- brcmf_debugfs_attach(drvr);
+ /* attach debug facilities */
+ brcmf_debug_attach(drvr);
/* Attach and link in the protocol */
ret = brcmf_proto_attach(drvr);
@@ -1021,12 +1039,7 @@ int brcmf_bus_start(struct device *dev)
if (IS_ERR(ifp))
return PTR_ERR(ifp);
- if (brcmf_p2p_enable)
- p2p_ifp = brcmf_add_if(drvr, 1, 0, false, "p2p%d", NULL);
- else
- p2p_ifp = NULL;
- if (IS_ERR(p2p_ifp))
- p2p_ifp = NULL;
+ p2p_ifp = NULL;
/* signal bus ready */
brcmf_bus_change_state(bus_if, BRCMF_BUS_UP);
@@ -1060,11 +1073,13 @@ int brcmf_bus_start(struct device *dev)
goto fail;
}
- ret = brcmf_fweh_activate_events(ifp);
- if (ret < 0)
- goto fail;
-
ret = brcmf_net_attach(ifp, false);
+
+ if ((!ret) && (brcmf_p2p_enable)) {
+ p2p_ifp = drvr->iflist[1];
+ if (p2p_ifp)
+ ret = brcmf_net_p2p_attach(p2p_ifp);
+ }
fail:
if (ret < 0) {
brcmf_err("failed: %d\n", ret);
@@ -1076,20 +1091,12 @@ fail:
brcmf_fws_del_interface(ifp);
brcmf_fws_deinit(drvr);
}
- if (drvr->iflist[0]) {
+ if (ifp)
brcmf_net_detach(ifp->ndev);
- drvr->iflist[0] = NULL;
- }
- if (p2p_ifp) {
+ if (p2p_ifp)
brcmf_net_detach(p2p_ifp->ndev);
- drvr->iflist[1] = NULL;
- }
return ret;
}
- if ((brcmf_p2p_enable) && (p2p_ifp))
- if (brcmf_net_p2p_attach(p2p_ifp) < 0)
- brcmf_p2p_enable = 0;
-
return 0;
}
@@ -1155,7 +1162,7 @@ void brcmf_detach(struct device *dev)
brcmf_proto_detach(drvr);
- brcmf_debugfs_detach(drvr);
+ brcmf_debug_detach(drvr);
bus_if->drvr = NULL;
kfree(drvr);
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.h b/drivers/net/wireless/brcm80211/brcmfmac/core.h
index d81ff95..2f9101b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
@@ -154,10 +154,13 @@ struct brcmf_fws_mac_descriptor;
* netif stopped due to firmware signalling flow control.
* @BRCMF_NETIF_STOP_REASON_FLOW:
* netif stopped due to flowring full.
+ * @BRCMF_NETIF_STOP_REASON_DISCONNECTED:
+ * netif stopped due to not being connected (STA mode).
*/
enum brcmf_netif_stop_reason {
- BRCMF_NETIF_STOP_REASON_FWS_FC = 1,
- BRCMF_NETIF_STOP_REASON_FLOW = 2
+ BRCMF_NETIF_STOP_REASON_FWS_FC = BIT(0),
+ BRCMF_NETIF_STOP_REASON_FLOW = BIT(1),
+ BRCMF_NETIF_STOP_REASON_DISCONNECTED = BIT(2)
};
/**
@@ -213,8 +216,6 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
enum brcmf_netif_stop_reason reason, bool state);
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
-
-/* Sets dongle media info (drv_version, mac address). */
-int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
+void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
#endif /* BRCMFMAC_CORE_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
index 2d6d005..1299dcc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
@@ -16,15 +16,45 @@
#include <linux/debugfs.h>
#include <linux/netdevice.h>
#include <linux/module.h>
+#include <linux/devcoredump.h>
#include <brcmu_wifi.h>
#include <brcmu_utils.h>
#include "core.h"
#include "bus.h"
+#include "fweh.h"
#include "debug.h"
static struct dentry *root_folder;
+static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
+ size_t len)
+{
+ void *dump;
+ size_t ramsize;
+
+ ramsize = brcmf_bus_get_ramsize(bus);
+ if (ramsize) {
+ dump = vzalloc(len + ramsize);
+ if (!dump)
+ return -ENOMEM;
+ memcpy(dump, data, len);
+ brcmf_bus_get_memdump(bus, dump + len, ramsize);
+ dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
+ }
+ return 0;
+}
+
+static int brcmf_debug_psm_watchdog_notify(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *evtmsg,
+ void *data)
+{
+ brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
+
+ return brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
+ evtmsg->datalen);
+}
+
void brcmf_debugfs_init(void)
{
root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
@@ -41,7 +71,7 @@ void brcmf_debugfs_exit(void)
root_folder = NULL;
}
-int brcmf_debugfs_attach(struct brcmf_pub *drvr)
+int brcmf_debug_attach(struct brcmf_pub *drvr)
{
struct device *dev = drvr->bus_if->dev;
@@ -49,12 +79,18 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
return -ENODEV;
drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
+ if (IS_ERR(drvr->dbgfs_dir))
+ return PTR_ERR(drvr->dbgfs_dir);
- return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
+
+ return brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
+ brcmf_debug_psm_watchdog_notify);
}
-void brcmf_debugfs_detach(struct brcmf_pub *drvr)
+void brcmf_debug_detach(struct brcmf_pub *drvr)
{
+ brcmf_fweh_unregister(drvr, BRCMF_E_PSM_WATCHDOG);
+
if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
debugfs_remove_recursive(drvr->dbgfs_dir);
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/debug.h b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
index 48648ca..d0d9676 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
@@ -109,8 +109,8 @@ struct brcmf_pub;
#ifdef DEBUG
void brcmf_debugfs_init(void);
void brcmf_debugfs_exit(void);
-int brcmf_debugfs_attach(struct brcmf_pub *drvr);
-void brcmf_debugfs_detach(struct brcmf_pub *drvr);
+int brcmf_debug_attach(struct brcmf_pub *drvr);
+void brcmf_debug_detach(struct brcmf_pub *drvr);
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
int (*read_fn)(struct seq_file *seq, void *data));
@@ -121,11 +121,11 @@ static inline void brcmf_debugfs_init(void)
static inline void brcmf_debugfs_exit(void)
{
}
-static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
+static inline int brcmf_debug_attach(struct brcmf_pub *drvr)
{
return 0;
}
-static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
+static inline void brcmf_debug_detach(struct brcmf_pub *drvr)
{
}
static inline
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
index 971920f..4248f3c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -29,7 +29,7 @@
#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */
char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
-module_param_string(firmware_path, brcmf_firmware_path,
+module_param_string(alternative_fw_path, brcmf_firmware_path,
BRCMF_FW_PATH_LEN, 0440);
enum nvram_parser_state {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index 383d6fa..3878b6f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -213,7 +213,8 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
is_p2pdev, emsg->ifname, emsg->addr);
if (IS_ERR(ifp))
return;
- brcmf_fws_add_interface(ifp);
+ if (!is_p2pdev)
+ brcmf_fws_add_interface(ifp);
if (!drvr->fweh.evt_handler[BRCMF_E_IF])
if (brcmf_net_attach(ifp, false) < 0)
return;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
index 5434dcf..b20fc0f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
@@ -72,6 +72,7 @@
#define BRCMF_C_GET_BSS_INFO 136
#define BRCMF_C_GET_BANDLIST 140
#define BRCMF_C_SET_SCB_TIMEOUT 158
+#define BRCMF_C_GET_ASSOCLIST 159
#define BRCMF_C_GET_PHYLIST 180
#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index 297911f..daa427b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -119,6 +119,8 @@
#define BRCMF_COUNTRY_BUF_SZ 4
#define BRCMF_ANT_MAX 4
+#define BRCMF_MAX_ASSOCLIST 128
+
/* join preference types for join_pref iovar */
enum brcmf_join_pref_types {
BRCMF_JOIN_PREF_RSSI = 1,
@@ -621,4 +623,15 @@ struct brcmf_rev_info_le {
__le32 nvramrev;
};
+/**
+ * struct brcmf_assoclist_le - request assoc list.
+ *
+ * @count: indicates number of stations.
+ * @mac: MAC addresses of stations.
+ */
+struct brcmf_assoclist_le {
+ __le32 count;
+ u8 mac[BRCMF_MAX_ASSOCLIST][ETH_ALEN];
+};
+
#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index 7eff9de..44e618f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -873,9 +873,6 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)
commonring = msgbuf->flowrings[flowid];
atomic_dec(&commonring->outstanding_tx);
- /* Hante: i believe this was a bug as tx_status->msg.ifidx was used
- * in brcmf_txfinalize as index in drvr->iflist. Can you confirm/deny?
- */
brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx),
skb, true);
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 37a8c352..d224b3d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -2353,83 +2353,30 @@ void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev)
* brcmf_p2p_attach() - attach for P2P.
*
* @cfg: driver private data for cfg80211 interface.
+ * @p2pdev_forced: create p2p device interface at attach.
*/
s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)
{
- struct brcmf_if *pri_ifp;
- struct brcmf_if *p2p_ifp;
- struct brcmf_cfg80211_vif *p2p_vif;
struct brcmf_p2p_info *p2p;
- struct brcmf_pub *drvr;
- s32 bssidx;
+ struct brcmf_if *pri_ifp;
s32 err = 0;
+ void *err_ptr;
p2p = &cfg->p2p;
p2p->cfg = cfg;
- drvr = cfg->pub;
-
- pri_ifp = brcmf_get_ifp(drvr, 0);
+ pri_ifp = brcmf_get_ifp(cfg->pub, 0);
p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
if (p2pdev_forced) {
- p2p_ifp = drvr->iflist[1];
+ err_ptr = brcmf_p2p_create_p2pdev(p2p, NULL, NULL);
+ if (IS_ERR(err_ptr)) {
+ brcmf_err("P2P device creation failed.\n");
+ err = PTR_ERR(err_ptr);
+ }
} else {
- p2p_ifp = NULL;
p2p->p2pdev_dynamically = true;
}
- if (p2p_ifp) {
- p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
- false);
- if (IS_ERR(p2p_vif)) {
- brcmf_err("could not create discovery vif\n");
- err = -ENOMEM;
- goto exit;
- }
-
- p2p_vif->ifp = p2p_ifp;
- p2p_ifp->vif = p2p_vif;
- p2p_vif->wdev.netdev = p2p_ifp->ndev;
- p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev;
- SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy));
-
- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
-
- brcmf_p2p_generate_bss_mac(p2p, NULL);
- memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
- brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
-
- brcmf_fweh_p2pdev_setup(pri_ifp, true);
-
- /* Initialize P2P Discovery in the firmware */
- err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
- if (err < 0) {
- brcmf_err("set p2p_disc error\n");
- brcmf_free_vif(p2p_vif);
- goto exit;
- }
- /* obtain bsscfg index for P2P discovery */
- err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
- if (err < 0) {
- brcmf_err("retrieving discover bsscfg index failed\n");
- brcmf_free_vif(p2p_vif);
- goto exit;
- }
- /* Verify that firmware uses same bssidx as driver !! */
- if (p2p_ifp->bssidx != bssidx) {
- brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
- bssidx, p2p_ifp->bssidx);
- brcmf_free_vif(p2p_vif);
- goto exit;
- }
-
- init_completion(&p2p->send_af_done);
- INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
- init_completion(&p2p->afx_hdl.act_frm_scan);
- init_completion(&p2p->wait_next_af);
-exit:
- brcmf_fweh_p2pdev_setup(pri_ifp, false);
- }
return err;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
index 30baf35..83d8042 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
@@ -59,6 +59,8 @@ enum brcmf_pcie_state {
#define BRCMF_PCIE_4365_NVRAM_NAME "brcm/brcmfmac4365b-pcie.txt"
#define BRCMF_PCIE_4366_FW_NAME "brcm/brcmfmac4366b-pcie.bin"
#define BRCMF_PCIE_4366_NVRAM_NAME "brcm/brcmfmac4366b-pcie.txt"
+#define BRCMF_PCIE_4371_FW_NAME "brcm/brcmfmac4371-pcie.bin"
+#define BRCMF_PCIE_4371_NVRAM_NAME "brcm/brcmfmac4371-pcie.txt"
#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */
@@ -212,6 +214,8 @@ MODULE_FIRMWARE(BRCMF_PCIE_4365_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4365_NVRAM_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4366_FW_NAME);
MODULE_FIRMWARE(BRCMF_PCIE_4366_NVRAM_NAME);
+MODULE_FIRMWARE(BRCMF_PCIE_4371_FW_NAME);
+MODULE_FIRMWARE(BRCMF_PCIE_4371_NVRAM_NAME);
struct brcmf_pcie_console {
@@ -448,6 +452,47 @@ brcmf_pcie_copy_mem_todev(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
}
+static void
+brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
+ void *dstaddr, u32 len)
+{
+ void __iomem *address = devinfo->tcm + mem_offset;
+ __le32 *dst32;
+ __le16 *dst16;
+ u8 *dst8;
+
+ if (((ulong)address & 4) || ((ulong)dstaddr & 4) || (len & 4)) {
+ if (((ulong)address & 2) || ((ulong)dstaddr & 2) || (len & 2)) {
+ dst8 = (u8 *)dstaddr;
+ while (len) {
+ *dst8 = ioread8(address);
+ address++;
+ dst8++;
+ len--;
+ }
+ } else {
+ len = len / 2;
+ dst16 = (__le16 *)dstaddr;
+ while (len) {
+ *dst16 = cpu_to_le16(ioread16(address));
+ address += 2;
+ dst16++;
+ len--;
+ }
+ }
+ } else {
+ len = len / 4;
+ dst32 = (__le32 *)dstaddr;
+ while (len) {
+ *dst32 = cpu_to_le32(ioread32(address));
+ address += 4;
+ dst32++;
+ len--;
+ }
+ }
+}
+
+
#define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \
CHIPCREGOFFS(reg), value)
@@ -1352,12 +1397,36 @@ static void brcmf_pcie_wowl_config(struct device *dev, bool enabled)
}
+static size_t brcmf_pcie_get_ramsize(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
+
+ return devinfo->ci->ramsize - devinfo->ci->srsize;
+}
+
+
+static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
+
+ brcmf_dbg(PCIE, "dump at 0x%08X: len=%zu\n", devinfo->ci->rambase, len);
+ brcmf_pcie_copy_dev_tomem(devinfo, devinfo->ci->rambase, data, len);
+ return 0;
+}
+
+
static struct brcmf_bus_ops brcmf_pcie_bus_ops = {
.txdata = brcmf_pcie_tx,
.stop = brcmf_pcie_down,
.txctl = brcmf_pcie_tx_ctlpkt,
.rxctl = brcmf_pcie_rx_ctlpkt,
.wowl_config = brcmf_pcie_wowl_config,
+ .get_ramsize = brcmf_pcie_get_ramsize,
+ .get_memdump = brcmf_pcie_get_memdump,
};
@@ -1456,6 +1525,10 @@ static int brcmf_pcie_get_fwnames(struct brcmf_pciedev_info *devinfo)
fw_name = BRCMF_PCIE_4366_FW_NAME;
nvram_name = BRCMF_PCIE_4366_NVRAM_NAME;
break;
+ case BRCM_CC_4371_CHIP_ID:
+ fw_name = BRCMF_PCIE_4371_FW_NAME;
+ nvram_name = BRCMF_PCIE_4371_NVRAM_NAME;
+ break;
default:
brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip);
return -ENODEV;
@@ -1995,6 +2068,7 @@ static struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID),
{ /* end: all zeroes */ }
};
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index 7f574f2..7e74ac3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -3539,6 +3539,51 @@ done:
return err;
}
+static size_t brcmf_sdio_bus_get_ramsize(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+ struct brcmf_sdio *bus = sdiodev->bus;
+
+ return bus->ci->ramsize - bus->ci->srsize;
+}
+
+static int brcmf_sdio_bus_get_memdump(struct device *dev, void *data,
+ size_t mem_size)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+ struct brcmf_sdio *bus = sdiodev->bus;
+ int err;
+ int address;
+ int offset;
+ int len;
+
+ brcmf_dbg(INFO, "dump at 0x%08x: size=%zu\n", bus->ci->rambase,
+ mem_size);
+
+ address = bus->ci->rambase;
+ offset = err = 0;
+ sdio_claim_host(sdiodev->func[1]);
+ while (offset < mem_size) {
+ len = ((offset + MEMBLOCK) < mem_size) ? MEMBLOCK :
+ mem_size - offset;
+ err = brcmf_sdiod_ramrw(sdiodev, false, address, data, len);
+ if (err) {
+ brcmf_err("error %d on reading %d membytes at 0x%08x\n",
+ err, len, address);
+ goto done;
+ }
+ data += len;
+ offset += len;
+ address += len;
+ }
+
+done:
+ sdio_release_host(sdiodev->func[1]);
+ return err;
+}
+
void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus)
{
if (!bus->dpc_triggered) {
@@ -3987,7 +4032,9 @@ static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.txctl = brcmf_sdio_bus_txctl,
.rxctl = brcmf_sdio_bus_rxctl,
.gettxq = brcmf_sdio_bus_gettxq,
- .wowl_config = brcmf_sdio_wowl_config
+ .wowl_config = brcmf_sdio_wowl_config,
+ .get_ramsize = brcmf_sdio_bus_get_ramsize,
+ .get_memdump = brcmf_sdio_bus_get_memdump,
};
static void brcmf_sdio_firmware_callback(struct device *dev,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index daba86d..689e64d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -144,6 +144,7 @@ struct brcmf_usbdev_info {
struct usb_device *usbdev;
struct device *dev;
+ struct mutex dev_init_lock;
int ctl_in_pipe, ctl_out_pipe;
struct urb *ctl_urb; /* URB for control endpoint */
@@ -1204,6 +1205,8 @@ static void brcmf_usb_probe_phase2(struct device *dev,
int ret;
brcmf_dbg(USB, "Start fw downloading\n");
+
+ devinfo = bus->bus_priv.usb->devinfo;
ret = check_file(fw->data);
if (ret < 0) {
brcmf_err("invalid firmware\n");
@@ -1211,7 +1214,6 @@ static void brcmf_usb_probe_phase2(struct device *dev,
goto error;
}
- devinfo = bus->bus_priv.usb->devinfo;
devinfo->image = fw->data;
devinfo->image_len = fw->size;
@@ -1224,9 +1226,11 @@ static void brcmf_usb_probe_phase2(struct device *dev,
if (ret)
goto error;
+ mutex_unlock(&devinfo->dev_init_lock);
return;
error:
brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret);
+ mutex_unlock(&devinfo->dev_init_lock);
device_release_driver(dev);
}
@@ -1264,6 +1268,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
if (ret)
goto fail;
/* we are done */
+ mutex_unlock(&devinfo->dev_init_lock);
return 0;
}
bus->chip = bus_pub->devid;
@@ -1317,6 +1322,12 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
devinfo->usbdev = usb;
devinfo->dev = &usb->dev;
+ /* Take an init lock, to protect for disconnect while still loading.
+ * Necessary because of the asynchronous firmware load construction
+ */
+ mutex_init(&devinfo->dev_init_lock);
+ mutex_lock(&devinfo->dev_init_lock);
+
usb_set_intfdata(intf, devinfo);
/* Check that the device supports only one configuration */
@@ -1391,6 +1402,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
return 0;
fail:
+ mutex_unlock(&devinfo->dev_init_lock);
kfree(devinfo);
usb_set_intfdata(intf, NULL);
return ret;
@@ -1403,8 +1415,19 @@ brcmf_usb_disconnect(struct usb_interface *intf)
brcmf_dbg(USB, "Enter\n");
devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
- brcmf_usb_disconnect_cb(devinfo);
- kfree(devinfo);
+
+ if (devinfo) {
+ mutex_lock(&devinfo->dev_init_lock);
+ /* Make sure that devinfo still exists. Firmware probe routines
+ * may have released the device and cleared the intfdata.
+ */
+ if (!usb_get_intfdata(intf))
+ goto done;
+
+ brcmf_usb_disconnect_cb(devinfo);
+ kfree(devinfo);
+ }
+done:
brcmf_dbg(USB, "Exit\n");
}
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index d823734..aa06ea2 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -50,6 +50,7 @@
#define BRCM_CC_43602_CHIP_ID 43602
#define BRCM_CC_4365_CHIP_ID 0x4365
#define BRCM_CC_4366_CHIP_ID 0x4366
+#define BRCM_CC_4371_CHIP_ID 0x4371
/* USB Device IDs */
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
@@ -75,6 +76,7 @@
#define BRCM_PCIE_4366_DEVICE_ID 0x43c3
#define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4
#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
+#define BRCM_PCIE_4371_DEVICE_ID 0x440d
/* brcmsmac IDs */
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
index 317d991..279167d 100644
--- a/drivers/net/wireless/mwifiex/Kconfig
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -33,12 +33,12 @@ config MWIFIEX_PCIE
mwifiex_pcie.
config MWIFIEX_USB
- tristate "Marvell WiFi-Ex Driver for USB8766/8797/8897/8997"
+ tristate "Marvell WiFi-Ex Driver for USB8766/8797/8997"
depends on MWIFIEX && USB
select FW_LOADER
---help---
This adds support for wireless adapters based on Marvell
- 8797/8897/8997 chipset with USB interface.
+ 8797/8997 chipset with USB interface.
If you choose to build it as a module, it will be called
mwifiex_usb.
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 30cbafb..b7ac45f 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2374,7 +2374,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
* CFG802.11 operation handler for scan request.
*
* This function issues a scan request to the firmware based upon
- * the user specified scan configuration. On successfull completion,
+ * the user specified scan configuration. On successful completion,
* it also informs the results.
*/
static int
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 5583856..9824d8d 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -856,6 +856,56 @@ mwifiex_hscfg_read(struct file *file, char __user *ubuf,
return ret;
}
+static ssize_t
+mwifiex_timeshare_coex_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv = file->private_data;
+ char buf[3];
+ bool timeshare_coex;
+ int ret;
+ unsigned int len;
+
+ if (priv->adapter->fw_api_ver != MWIFIEX_FW_V15)
+ return -EOPNOTSUPP;
+
+ ret = mwifiex_send_cmd(priv, HostCmd_CMD_ROBUST_COEX,
+ HostCmd_ACT_GEN_GET, 0, &timeshare_coex, true);
+ if (ret)
+ return ret;
+
+ len = sprintf(buf, "%d\n", timeshare_coex);
+ return simple_read_from_buffer(ubuf, count, ppos, buf, len);
+}
+
+static ssize_t
+mwifiex_timeshare_coex_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ bool timeshare_coex;
+ struct mwifiex_private *priv = file->private_data;
+ char kbuf[16];
+ int ret;
+
+ if (priv->adapter->fw_api_ver != MWIFIEX_FW_V15)
+ return -EOPNOTSUPP;
+
+ memset(kbuf, 0, sizeof(kbuf));
+
+ if (copy_from_user(&kbuf, ubuf, min_t(size_t, sizeof(kbuf) - 1, count)))
+ return -EFAULT;
+
+ if (strtobool(kbuf, &timeshare_coex))
+ return -EINVAL;
+
+ ret = mwifiex_send_cmd(priv, HostCmd_CMD_ROBUST_COEX,
+ HostCmd_ACT_GEN_SET, 0, &timeshare_coex, true);
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
#define MWIFIEX_DFS_ADD_FILE(name) do { \
if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \
priv, &mwifiex_dfs_##name##_fops)) \
@@ -892,6 +942,7 @@ MWIFIEX_DFS_FILE_OPS(memrw);
MWIFIEX_DFS_FILE_OPS(hscfg);
MWIFIEX_DFS_FILE_OPS(histogram);
MWIFIEX_DFS_FILE_OPS(debug_mask);
+MWIFIEX_DFS_FILE_OPS(timeshare_coex);
/*
* This function creates the debug FS directory structure and the files.
@@ -918,6 +969,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
MWIFIEX_DFS_ADD_FILE(hscfg);
MWIFIEX_DFS_ADD_FILE(histogram);
MWIFIEX_DFS_ADD_FILE(debug_mask);
+ MWIFIEX_DFS_ADD_FILE(timeshare_coex);
}
/*
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 0e6f029..1e1e81a 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -101,6 +101,9 @@ enum KEY_TYPE_ID {
#define FIRMWARE_READY_SDIO 0xfedc
#define FIRMWARE_READY_PCIE 0xfedcba00
+#define MWIFIEX_COEX_MODE_TIMESHARE 0x01
+#define MWIFIEX_COEX_MODE_SPATIAL 0x82
+
enum mwifiex_usb_ep {
MWIFIEX_USB_EP_CMD_EVENT = 1,
MWIFIEX_USB_EP_DATA = 2,
@@ -163,6 +166,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_CHANRPT_11H_BASIC (PROPRIETARY_TLV_BASE_ID + 91)
#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93)
#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
+#define TLV_TYPE_ROBUST_COEX (PROPRIETARY_TLV_BASE_ID + 96)
#define TLV_TYPE_UAP_MGMT_FRAME (PROPRIETARY_TLV_BASE_ID + 104)
#define TLV_TYPE_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 105)
#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113)
@@ -354,6 +358,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define HostCmd_CMD_AMSDU_AGGR_CTRL 0x00df
#define HostCmd_CMD_TXPWR_CFG 0x00d1
#define HostCmd_CMD_TX_RATE_CFG 0x00d6
+#define HostCmd_CMD_ROBUST_COEX 0x00e0
#define HostCmd_CMD_802_11_PS_MODE_ENH 0x00e4
#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5
#define HostCmd_CMD_P2P_MODE_CFG 0x00eb
@@ -1877,6 +1882,11 @@ struct mwifiex_ie_types_btcoex_aggr_win_size {
u8 reserved;
} __packed;
+struct mwifiex_ie_types_robust_coex {
+ struct mwifiex_ie_types_header header;
+ __le32 mode;
+} __packed;
+
struct host_cmd_ds_version_ext {
u8 version_str_sel;
char version_str[128];
@@ -2078,6 +2088,11 @@ struct host_cmd_ds_multi_chan_policy {
__le16 policy;
} __packed;
+struct host_cmd_ds_robust_coex {
+ __le16 action;
+ __le16 reserved;
+} __packed;
+
struct host_cmd_ds_command {
__le16 command;
__le16 size;
@@ -2147,6 +2162,7 @@ struct host_cmd_ds_command {
struct host_cmd_ds_chan_rpt_req chan_rpt_req;
struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg;
struct host_cmd_ds_multi_chan_policy mc_policy;
+ struct host_cmd_ds_robust_coex coex;
} params;
} __packed;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 6e3faa7..969ca1e 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -1199,6 +1199,7 @@ static const struct net_device_ops mwifiex_netdev_ops = {
.ndo_stop = mwifiex_close,
.ndo_start_xmit = mwifiex_hard_start_xmit,
.ndo_set_mac_address = mwifiex_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
.ndo_tx_timeout = mwifiex_tx_timeout,
.ndo_get_stats = mwifiex_get_stats,
.ndo_set_rx_mode = mwifiex_set_multicast_list,
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 504b321..e486867 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1531,6 +1531,33 @@ mwifiex_cmd_set_mc_policy(struct mwifiex_private *priv,
return 0;
}
+static int mwifiex_cmd_robust_coex(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *cmd,
+ u16 cmd_action, bool *is_timeshare)
+{
+ struct host_cmd_ds_robust_coex *coex = &cmd->params.coex;
+ struct mwifiex_ie_types_robust_coex *coex_tlv;
+
+ cmd->command = cpu_to_le16(HostCmd_CMD_ROBUST_COEX);
+ cmd->size = cpu_to_le16(sizeof(*coex) + sizeof(*coex_tlv) + S_DS_GEN);
+
+ coex->action = cpu_to_le16(cmd_action);
+ coex_tlv = (struct mwifiex_ie_types_robust_coex *)
+ ((u8 *)coex + sizeof(*coex));
+ coex_tlv->header.type = cpu_to_le16(TLV_TYPE_ROBUST_COEX);
+ coex_tlv->header.len = cpu_to_le16(sizeof(coex_tlv->mode));
+
+ if (coex->action == HostCmd_ACT_GEN_GET)
+ return 0;
+
+ if (*is_timeshare)
+ coex_tlv->mode = cpu_to_le32(MWIFIEX_COEX_MODE_TIMESHARE);
+ else
+ coex_tlv->mode = cpu_to_le32(MWIFIEX_COEX_MODE_SPATIAL);
+
+ return 0;
+}
+
static int
mwifiex_cmd_coalesce_cfg(struct mwifiex_private *priv,
struct host_cmd_ds_command *cmd,
@@ -2040,6 +2067,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
ret = mwifiex_cmd_set_mc_policy(priv, cmd_ptr, cmd_action,
data_buf);
break;
+ case HostCmd_CMD_ROBUST_COEX:
+ ret = mwifiex_cmd_robust_coex(priv, cmd_ptr, cmd_action,
+ data_buf);
+ break;
default:
mwifiex_dbg(priv->adapter, ERROR,
"PREP_CMD: unknown cmd- %#x\n", cmd_no);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index d0961635..9ac7aa2 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -1007,6 +1007,28 @@ static int mwifiex_ret_sdio_rx_aggr_cfg(struct mwifiex_private *priv,
return 0;
}
+static int mwifiex_ret_robust_coex(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp,
+ bool *is_timeshare)
+{
+ struct host_cmd_ds_robust_coex *coex = &resp->params.coex;
+ struct mwifiex_ie_types_robust_coex *coex_tlv;
+ u16 action = le16_to_cpu(coex->action);
+ u32 mode;
+
+ coex_tlv = (struct mwifiex_ie_types_robust_coex
+ *)((u8 *)coex + sizeof(struct host_cmd_ds_robust_coex));
+ if (action == HostCmd_ACT_GEN_GET) {
+ mode = le32_to_cpu(coex_tlv->mode);
+ if (mode == MWIFIEX_COEX_MODE_TIMESHARE)
+ *is_timeshare = true;
+ else
+ *is_timeshare = false;
+ }
+
+ return 0;
+}
+
/*
* This function handles the command responses.
*
@@ -1213,6 +1235,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
break;
case HostCmd_CMD_TDLS_CONFIG:
break;
+ case HostCmd_CMD_ROBUST_COEX:
+ ret = mwifiex_ret_robust_coex(priv, resp, data_buf);
+ break;
default:
mwifiex_dbg(adapter, ERROR,
"CMD_RESP: unknown cmd response %#x\n",
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 4d5a6e3..759a6ad 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -846,22 +846,6 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
{
enum state_11d_t state_11d;
- if (mwifiex_del_mgmt_ies(priv))
- mwifiex_dbg(priv->adapter, ERROR,
- "Failed to delete mgmt IEs!\n");
-
- if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
- HostCmd_ACT_GEN_SET, 0, NULL, true)) {
- mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n");
- return -1;
- }
-
- if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET,
- HostCmd_ACT_GEN_SET, 0, NULL, true)) {
- mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n");
- return -1;
- }
-
if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
HostCmd_ACT_GEN_SET,
UAP_BSS_PARAMS_I, bss_cfg, false)) {
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 9f5356e..e43aff9 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -42,11 +42,6 @@ static struct usb_device_id mwifiex_usb_table[] = {
{USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8801_PID_2,
USB_CLASS_VENDOR_SPEC,
USB_SUBCLASS_VENDOR_SPEC, 0xff)},
- /* 8897 */
- {USB_DEVICE(USB8XXX_VID, USB8897_PID_1)},
- {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8897_PID_2,
- USB_CLASS_VENDOR_SPEC,
- USB_SUBCLASS_VENDOR_SPEC, 0xff)},
/* 8997 */
{USB_DEVICE(USB8XXX_VID, USB8997_PID_1)},
{USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8997_PID_2,
@@ -403,14 +398,12 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
case USB8766_PID_1:
case USB8797_PID_1:
case USB8801_PID_1:
- case USB8897_PID_1:
case USB8997_PID_1:
card->usb_boot_state = USB8XXX_FW_DNLD;
break;
case USB8766_PID_2:
case USB8797_PID_2:
case USB8801_PID_2:
- case USB8897_PID_2:
case USB8997_PID_2:
card->usb_boot_state = USB8XXX_FW_READY;
break;
@@ -964,12 +957,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
strcpy(adapter->fw_name, USB8997_DEFAULT_FW_NAME);
adapter->ext_scan = true;
break;
- case USB8897_PID_1:
- case USB8897_PID_2:
- adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
- strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME);
- adapter->ext_scan = true;
- break;
case USB8766_PID_1:
case USB8766_PID_2:
adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
@@ -1277,5 +1264,4 @@ MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE(USB8766_DEFAULT_FW_NAME);
MODULE_FIRMWARE(USB8797_DEFAULT_FW_NAME);
MODULE_FIRMWARE(USB8801_DEFAULT_FW_NAME);
-MODULE_FIRMWARE(USB8897_DEFAULT_FW_NAME);
MODULE_FIRMWARE(USB8997_DEFAULT_FW_NAME);
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index bab10ee..b4e9246 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -28,11 +28,9 @@
#define USB8766_PID_2 0x2042
#define USB8797_PID_1 0x2043
#define USB8797_PID_2 0x2044
-#define USB8897_PID_1 0x2045
-#define USB8897_PID_2 0x2046
#define USB8801_PID_1 0x2049
#define USB8801_PID_2 0x204a
-#define USB8997_PID_1 0x204d
+#define USB8997_PID_1 0x2052
#define USB8997_PID_2 0x204e
@@ -48,7 +46,6 @@
#define USB8766_DEFAULT_FW_NAME "mrvl/usb8766_uapsta.bin"
#define USB8797_DEFAULT_FW_NAME "mrvl/usb8797_uapsta.bin"
#define USB8801_DEFAULT_FW_NAME "mrvl/usb8801_uapsta.bin"
-#define USB8897_DEFAULT_FW_NAME "mrvl/usb8897_uapsta.bin"
#define USB8997_DEFAULT_FW_NAME "mrvl/usb8997_uapsta.bin"
#define FW_DNLD_TX_BUF_SIZE 620
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 57c13ec..acccd67 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -684,7 +684,7 @@ void mwifiex_update_ralist_tx_pause_in_tdls_cs(struct mwifiex_private *priv,
if (!memcmp(ra_list->ra, mac, ETH_ALEN))
continue;
- if (ra_list && ra_list->tx_paused != tx_pause) {
+ if (ra_list->tx_paused != tx_pause) {
pkt_cnt += ra_list->total_pkt_count;
ra_list->tx_paused = tx_pause;
if (tx_pause)
diff --git a/drivers/net/wireless/realtek/Makefile b/drivers/net/wireless/realtek/Makefile
new file mode 100644
index 0000000..9c78deb
--- /dev/null
+++ b/drivers/net/wireless/realtek/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the Linux Wireless network device drivers for Realtek units
+#
+
+obj-$(CONFIG_RTL8180) += rtl818x/
+obj-$(CONFIG_RTL8187) += rtl818x/
+obj-$(CONFIG_RTLWIFI) += rtlwifi/
+obj-$(CONFIG_RTL8XXXU) += rtl8xxxu/
+
diff --git a/drivers/net/wireless/rtl818x/Kconfig b/drivers/net/wireless/realtek/rtl818x/Kconfig
index 1ce1d55..1ce1d55 100644
--- a/drivers/net/wireless/rtl818x/Kconfig
+++ b/drivers/net/wireless/realtek/rtl818x/Kconfig
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/realtek/rtl818x/Makefile
index 9975690..9975690 100644
--- a/drivers/net/wireless/rtl818x/Makefile
+++ b/drivers/net/wireless/realtek/rtl818x/Makefile
diff --git a/drivers/net/wireless/rtl818x/rtl8180/Makefile b/drivers/net/wireless/realtek/rtl818x/rtl8180/Makefile
index 21005bd..2966681 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/Makefile
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/Makefile
@@ -2,4 +2,4 @@ rtl818x_pci-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o rtl8225se.o
obj-$(CONFIG_RTL8180) += rtl818x_pci.o
-ccflags-y += -Idrivers/net/wireless/rtl818x
+ccflags-y += -Idrivers/net/wireless/realtek/rtl818x
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
index a43a16f..a43a16f 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
diff --git a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.c
index b1bfee7..b1bfee7 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.c
diff --git a/drivers/net/wireless/rtl818x/rtl8180/grf5101.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.h
index 4d80a27..4d80a27 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/grf5101.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/grf5101.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180/max2820.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.c
index eebf239..eebf239 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/max2820.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.c
diff --git a/drivers/net/wireless/rtl818x/rtl8180/max2820.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.h
index 8e982b7..8e982b7 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/max2820.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8180.h
index e8243a4..e8243a4 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8180.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c
index 9bda5bc..9bda5bc 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.h
index 310013a..310013a 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c
index fde8986..fde8986 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.h
index 2294002..2294002 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.h
diff --git a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.c
index 959b049..959b049 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.c
diff --git a/drivers/net/wireless/rtl818x/rtl8180/sa2400.h b/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.h
index fb0093f..fb0093f 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/sa2400.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/sa2400.h
diff --git a/drivers/net/wireless/rtl818x/rtl8187/Makefile b/drivers/net/wireless/realtek/rtl818x/rtl8187/Makefile
index 7b62992..ff07491 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/Makefile
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/Makefile
@@ -2,4 +2,4 @@ rtl8187-objs := dev.o rtl8225.o leds.o rfkill.o
obj-$(CONFIG_RTL8187) += rtl8187.o
-ccflags-y += -Idrivers/net/wireless/rtl818x
+ccflags-y += -Idrivers/net/wireless/realtek/rtl818x
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
index b7f72f9..b7f72f9 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c
index c2d5b49..c2d5b49 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/leds.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c
diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.h b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.h
index d743c96..d743c96 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/leds.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.h
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rfkill.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.c
index 3411671..3411671 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/rfkill.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.c
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rfkill.h b/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.h
index e12575e..e12575e 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/rfkill.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.h
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.h
index a6ad79f..a6ad79f 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.h
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c
index 5ecf18e..5ecf18e 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.h b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.h
index 141afb0..141afb0 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.h
diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/realtek/rtl818x/rtl818x.h
index 7abef95..7abef95 100644
--- a/drivers/net/wireless/rtl818x/rtl818x.h
+++ b/drivers/net/wireless/realtek/rtl818x/rtl818x.h
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/Kconfig b/drivers/net/wireless/realtek/rtl8xxxu/Kconfig
new file mode 100644
index 0000000..dd4d626
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8xxxu/Kconfig
@@ -0,0 +1,34 @@
+#
+# RTL8XXXU Wireless LAN device configuration
+#
+config RTL8XXXU
+ tristate "RTL8723AU/RTL8188[CR]U/RTL819[12]CU (mac80211) support"
+ depends on MAC80211 && USB
+ ---help---
+ This is an alternative driver for various Realtek RTL8XXX
+ parts written to utilize the Linux mac80211 stack.
+ The driver is known to work with a number of RTL8723AU,
+ RL8188CU, RTL8188RU, RTL8191CU, and RTL8192CU devices
+
+ This driver is under development and has a limited feature
+ set. In particular it does not yet support 40MHz channels
+ and power management. However it should have a smaller
+ memory footprint than the vendor drivers and benetifs
+ from the in kernel mac80211 stack.
+
+ It can coexist with drivers from drivers/staging/rtl8723au,
+ drivers/staging/rtl8192u, and drivers/net/wireless/rtlwifi,
+ but you will need to control which module you wish to load.
+
+ To compile this driver as a module, choose M here: the module will
+ be called r8xxxu. If unsure, say N.
+
+config RTL8XXXU_UNTESTED
+ bool "Include support for untested Realtek 8xxx USB devices (EXPERIMENTAL)"
+ depends on RTL8XXXU
+ ---help---
+ This option enables detection of Realtek 8723/8188/8191/8192 WiFi
+ USB devices which have not been tested directly by the driver
+ author or reported to be working by third parties.
+
+ Please report your results!
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/Makefile b/drivers/net/wireless/realtek/rtl8xxxu/Makefile
new file mode 100644
index 0000000..5dea3bb
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8xxxu/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RTL8XXXU) += rtl8xxxu.o
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
new file mode 100644
index 0000000..6aed923
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
@@ -0,0 +1,5993 @@
+/*
+ * RTL8XXXU mac80211 USB driver
+ *
+ * Copyright (c) 2014 - 2015 Jes Sorensen <Jes.Sorensen@redhat.com>
+ *
+ * Portions, notably calibration code:
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * This driver was written as a replacement for the vendor provided
+ * rtl8723au driver. As the Realtek 8xxx chips are very similar in
+ * their programming interface, I have started adding support for
+ * additional 8xxx chips like the 8192cu, 8188cus, etc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <linux/firmware.h>
+#include <linux/moduleparam.h>
+#include <net/mac80211.h>
+#include "rtl8xxxu.h"
+#include "rtl8xxxu_regs.h"
+
+#define DRIVER_NAME "rtl8xxxu"
+
+static int rtl8xxxu_debug;
+static bool rtl8xxxu_ht40_2g;
+
+MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@redhat.com>");
+MODULE_DESCRIPTION("RTL8XXXu USB mac80211 Wireless LAN Driver");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B_NoBT.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin");
+
+module_param_named(debug, rtl8xxxu_debug, int, 0600);
+MODULE_PARM_DESC(debug, "Set debug mask");
+module_param_named(ht40_2g, rtl8xxxu_ht40_2g, bool, 0600);
+MODULE_PARM_DESC(ht40_2g, "Enable HT40 support on the 2.4GHz band");
+
+#define USB_VENDOR_ID_REALTEK 0x0bda
+/* Minimum IEEE80211_MAX_FRAME_LEN */
+#define RTL_RX_BUFFER_SIZE IEEE80211_MAX_FRAME_LEN
+#define RTL8XXXU_RX_URBS 32
+#define RTL8XXXU_RX_URB_PENDING_WATER 8
+#define RTL8XXXU_TX_URBS 64
+#define RTL8XXXU_TX_URB_LOW_WATER 25
+#define RTL8XXXU_TX_URB_HIGH_WATER 32
+
+static int rtl8xxxu_submit_rx_urb(struct rtl8xxxu_priv *priv,
+ struct rtl8xxxu_rx_urb *rx_urb);
+
+static struct ieee80211_rate rtl8xxxu_rates[] = {
+ { .bitrate = 10, .hw_value = DESC_RATE_1M, .flags = 0 },
+ { .bitrate = 20, .hw_value = DESC_RATE_2M, .flags = 0 },
+ { .bitrate = 55, .hw_value = DESC_RATE_5_5M, .flags = 0 },
+ { .bitrate = 110, .hw_value = DESC_RATE_11M, .flags = 0 },
+ { .bitrate = 60, .hw_value = DESC_RATE_6M, .flags = 0 },
+ { .bitrate = 90, .hw_value = DESC_RATE_9M, .flags = 0 },
+ { .bitrate = 120, .hw_value = DESC_RATE_12M, .flags = 0 },
+ { .bitrate = 180, .hw_value = DESC_RATE_18M, .flags = 0 },
+ { .bitrate = 240, .hw_value = DESC_RATE_24M, .flags = 0 },
+ { .bitrate = 360, .hw_value = DESC_RATE_36M, .flags = 0 },
+ { .bitrate = 480, .hw_value = DESC_RATE_48M, .flags = 0 },
+ { .bitrate = 540, .hw_value = DESC_RATE_54M, .flags = 0 },
+};
+
+static struct ieee80211_channel rtl8xxxu_channels_2g[] = {
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2412,
+ .hw_value = 1, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2417,
+ .hw_value = 2, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2422,
+ .hw_value = 3, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2427,
+ .hw_value = 4, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2432,
+ .hw_value = 5, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2437,
+ .hw_value = 6, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2442,
+ .hw_value = 7, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2447,
+ .hw_value = 8, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2452,
+ .hw_value = 9, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2457,
+ .hw_value = 10, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2462,
+ .hw_value = 11, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2467,
+ .hw_value = 12, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2472,
+ .hw_value = 13, .max_power = 30 },
+ { .band = IEEE80211_BAND_2GHZ, .center_freq = 2484,
+ .hw_value = 14, .max_power = 30 }
+};
+
+static struct ieee80211_supported_band rtl8xxxu_supported_band = {
+ .channels = rtl8xxxu_channels_2g,
+ .n_channels = ARRAY_SIZE(rtl8xxxu_channels_2g),
+ .bitrates = rtl8xxxu_rates,
+ .n_bitrates = ARRAY_SIZE(rtl8xxxu_rates),
+};
+
+static struct rtl8xxxu_reg8val rtl8723a_mac_init_table[] = {
+ {0x420, 0x80}, {0x423, 0x00}, {0x430, 0x00}, {0x431, 0x00},
+ {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05},
+ {0x436, 0x06}, {0x437, 0x07}, {0x438, 0x00}, {0x439, 0x00},
+ {0x43a, 0x00}, {0x43b, 0x01}, {0x43c, 0x04}, {0x43d, 0x05},
+ {0x43e, 0x06}, {0x43f, 0x07}, {0x440, 0x5d}, {0x441, 0x01},
+ {0x442, 0x00}, {0x444, 0x15}, {0x445, 0xf0}, {0x446, 0x0f},
+ {0x447, 0x00}, {0x458, 0x41}, {0x459, 0xa8}, {0x45a, 0x72},
+ {0x45b, 0xb9}, {0x460, 0x66}, {0x461, 0x66}, {0x462, 0x08},
+ {0x463, 0x03}, {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff},
+ {0x4cd, 0xff}, {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2},
+ {0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3},
+ {0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4},
+ {0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4},
+ {0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a},
+ {0x515, 0x10}, {0x516, 0x0a}, {0x517, 0x10}, {0x51a, 0x16},
+ {0x524, 0x0f}, {0x525, 0x4f}, {0x546, 0x40}, {0x547, 0x00},
+ {0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, {0x55a, 0x02},
+ {0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a},
+ {0x652, 0x20}, {0x63c, 0x0a}, {0x63d, 0x0a}, {0x63e, 0x0e},
+ {0x63f, 0x0e}, {0x66e, 0x05}, {0x700, 0x21}, {0x701, 0x43},
+ {0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43},
+ {0x70a, 0x65}, {0x70b, 0x87}, {0xffff, 0xff},
+};
+
+static struct rtl8xxxu_reg32val rtl8723a_phy_1t_init_table[] = {
+ {0x800, 0x80040000}, {0x804, 0x00000003},
+ {0x808, 0x0000fc00}, {0x80c, 0x0000000a},
+ {0x810, 0x10001331}, {0x814, 0x020c3d10},
+ {0x818, 0x02200385}, {0x81c, 0x00000000},
+ {0x820, 0x01000100}, {0x824, 0x00390004},
+ {0x828, 0x00000000}, {0x82c, 0x00000000},
+ {0x830, 0x00000000}, {0x834, 0x00000000},
+ {0x838, 0x00000000}, {0x83c, 0x00000000},
+ {0x840, 0x00010000}, {0x844, 0x00000000},
+ {0x848, 0x00000000}, {0x84c, 0x00000000},
+ {0x850, 0x00000000}, {0x854, 0x00000000},
+ {0x858, 0x569a569a}, {0x85c, 0x001b25a4},
+ {0x860, 0x66f60110}, {0x864, 0x061f0130},
+ {0x868, 0x00000000}, {0x86c, 0x32323200},
+ {0x870, 0x07000760}, {0x874, 0x22004000},
+ {0x878, 0x00000808}, {0x87c, 0x00000000},
+ {0x880, 0xc0083070}, {0x884, 0x000004d5},
+ {0x888, 0x00000000}, {0x88c, 0xccc000c0},
+ {0x890, 0x00000800}, {0x894, 0xfffffffe},
+ {0x898, 0x40302010}, {0x89c, 0x00706050},
+ {0x900, 0x00000000}, {0x904, 0x00000023},
+ {0x908, 0x00000000}, {0x90c, 0x81121111},
+ {0xa00, 0x00d047c8}, {0xa04, 0x80ff000c},
+ {0xa08, 0x8c838300}, {0xa0c, 0x2e68120f},
+ {0xa10, 0x9500bb78}, {0xa14, 0x11144028},
+ {0xa18, 0x00881117}, {0xa1c, 0x89140f00},
+ {0xa20, 0x1a1b0000}, {0xa24, 0x090e1317},
+ {0xa28, 0x00000204}, {0xa2c, 0x00d30000},
+ {0xa70, 0x101fbf00}, {0xa74, 0x00000007},
+ {0xa78, 0x00000900},
+ {0xc00, 0x48071d40}, {0xc04, 0x03a05611},
+ {0xc08, 0x000000e4}, {0xc0c, 0x6c6c6c6c},
+ {0xc10, 0x08800000}, {0xc14, 0x40000100},
+ {0xc18, 0x08800000}, {0xc1c, 0x40000100},
+ {0xc20, 0x00000000}, {0xc24, 0x00000000},
+ {0xc28, 0x00000000}, {0xc2c, 0x00000000},
+ {0xc30, 0x69e9ac44}, {0xc34, 0x469652af},
+ {0xc38, 0x49795994}, {0xc3c, 0x0a97971c},
+ {0xc40, 0x1f7c403f}, {0xc44, 0x000100b7},
+ {0xc48, 0xec020107}, {0xc4c, 0x007f037f},
+ {0xc50, 0x69543420}, {0xc54, 0x43bc0094},
+ {0xc58, 0x69543420}, {0xc5c, 0x433c0094},
+ {0xc60, 0x00000000}, {0xc64, 0x7112848b},
+ {0xc68, 0x47c00bff}, {0xc6c, 0x00000036},
+ {0xc70, 0x2c7f000d}, {0xc74, 0x018610db},
+ {0xc78, 0x0000001f}, {0xc7c, 0x00b91612},
+ {0xc80, 0x40000100}, {0xc84, 0x20f60000},
+ {0xc88, 0x40000100}, {0xc8c, 0x20200000},
+ {0xc90, 0x00121820}, {0xc94, 0x00000000},
+ {0xc98, 0x00121820}, {0xc9c, 0x00007f7f},
+ {0xca0, 0x00000000}, {0xca4, 0x00000080},
+ {0xca8, 0x00000000}, {0xcac, 0x00000000},
+ {0xcb0, 0x00000000}, {0xcb4, 0x00000000},
+ {0xcb8, 0x00000000}, {0xcbc, 0x28000000},
+ {0xcc0, 0x00000000}, {0xcc4, 0x00000000},
+ {0xcc8, 0x00000000}, {0xccc, 0x00000000},
+ {0xcd0, 0x00000000}, {0xcd4, 0x00000000},
+ {0xcd8, 0x64b22427}, {0xcdc, 0x00766932},
+ {0xce0, 0x00222222}, {0xce4, 0x00000000},
+ {0xce8, 0x37644302}, {0xcec, 0x2f97d40c},
+ {0xd00, 0x00080740}, {0xd04, 0x00020401},
+ {0xd08, 0x0000907f}, {0xd0c, 0x20010201},
+ {0xd10, 0xa0633333}, {0xd14, 0x3333bc43},
+ {0xd18, 0x7a8f5b6b}, {0xd2c, 0xcc979975},
+ {0xd30, 0x00000000}, {0xd34, 0x80608000},
+ {0xd38, 0x00000000}, {0xd3c, 0x00027293},
+ {0xd40, 0x00000000}, {0xd44, 0x00000000},
+ {0xd48, 0x00000000}, {0xd4c, 0x00000000},
+ {0xd50, 0x6437140a}, {0xd54, 0x00000000},
+ {0xd58, 0x00000000}, {0xd5c, 0x30032064},
+ {0xd60, 0x4653de68}, {0xd64, 0x04518a3c},
+ {0xd68, 0x00002101}, {0xd6c, 0x2a201c16},
+ {0xd70, 0x1812362e}, {0xd74, 0x322c2220},
+ {0xd78, 0x000e3c24}, {0xe00, 0x2a2a2a2a},
+ {0xe04, 0x2a2a2a2a}, {0xe08, 0x03902a2a},
+ {0xe10, 0x2a2a2a2a}, {0xe14, 0x2a2a2a2a},
+ {0xe18, 0x2a2a2a2a}, {0xe1c, 0x2a2a2a2a},
+ {0xe28, 0x00000000}, {0xe30, 0x1000dc1f},
+ {0xe34, 0x10008c1f}, {0xe38, 0x02140102},
+ {0xe3c, 0x681604c2}, {0xe40, 0x01007c00},
+ {0xe44, 0x01004800}, {0xe48, 0xfb000000},
+ {0xe4c, 0x000028d1}, {0xe50, 0x1000dc1f},
+ {0xe54, 0x10008c1f}, {0xe58, 0x02140102},
+ {0xe5c, 0x28160d05}, {0xe60, 0x00000008},
+ {0xe68, 0x001b25a4}, {0xe6c, 0x631b25a0},
+ {0xe70, 0x631b25a0}, {0xe74, 0x081b25a0},
+ {0xe78, 0x081b25a0}, {0xe7c, 0x081b25a0},
+ {0xe80, 0x081b25a0}, {0xe84, 0x631b25a0},
+ {0xe88, 0x081b25a0}, {0xe8c, 0x631b25a0},
+ {0xed0, 0x631b25a0}, {0xed4, 0x631b25a0},
+ {0xed8, 0x631b25a0}, {0xedc, 0x001b25a0},
+ {0xee0, 0x001b25a0}, {0xeec, 0x6b1b25a0},
+ {0xf14, 0x00000003}, {0xf4c, 0x00000000},
+ {0xf00, 0x00000300},
+ {0xffff, 0xffffffff},
+};
+
+static struct rtl8xxxu_reg32val rtl8192cu_phy_2t_init_table[] = {
+ {0x024, 0x0011800f}, {0x028, 0x00ffdb83},
+ {0x800, 0x80040002}, {0x804, 0x00000003},
+ {0x808, 0x0000fc00}, {0x80c, 0x0000000a},
+ {0x810, 0x10000330}, {0x814, 0x020c3d10},
+ {0x818, 0x02200385}, {0x81c, 0x00000000},
+ {0x820, 0x01000100}, {0x824, 0x00390004},
+ {0x828, 0x01000100}, {0x82c, 0x00390004},
+ {0x830, 0x27272727}, {0x834, 0x27272727},
+ {0x838, 0x27272727}, {0x83c, 0x27272727},
+ {0x840, 0x00010000}, {0x844, 0x00010000},
+ {0x848, 0x27272727}, {0x84c, 0x27272727},
+ {0x850, 0x00000000}, {0x854, 0x00000000},
+ {0x858, 0x569a569a}, {0x85c, 0x0c1b25a4},
+ {0x860, 0x66e60230}, {0x864, 0x061f0130},
+ {0x868, 0x27272727}, {0x86c, 0x2b2b2b27},
+ {0x870, 0x07000700}, {0x874, 0x22184000},
+ {0x878, 0x08080808}, {0x87c, 0x00000000},
+ {0x880, 0xc0083070}, {0x884, 0x000004d5},
+ {0x888, 0x00000000}, {0x88c, 0xcc0000c0},
+ {0x890, 0x00000800}, {0x894, 0xfffffffe},
+ {0x898, 0x40302010}, {0x89c, 0x00706050},
+ {0x900, 0x00000000}, {0x904, 0x00000023},
+ {0x908, 0x00000000}, {0x90c, 0x81121313},
+ {0xa00, 0x00d047c8}, {0xa04, 0x80ff000c},
+ {0xa08, 0x8c838300}, {0xa0c, 0x2e68120f},
+ {0xa10, 0x9500bb78}, {0xa14, 0x11144028},
+ {0xa18, 0x00881117}, {0xa1c, 0x89140f00},
+ {0xa20, 0x1a1b0000}, {0xa24, 0x090e1317},
+ {0xa28, 0x00000204}, {0xa2c, 0x00d30000},
+ {0xa70, 0x101fbf00}, {0xa74, 0x00000007},
+ {0xc00, 0x48071d40}, {0xc04, 0x03a05633},
+ {0xc08, 0x000000e4}, {0xc0c, 0x6c6c6c6c},
+ {0xc10, 0x08800000}, {0xc14, 0x40000100},
+ {0xc18, 0x08800000}, {0xc1c, 0x40000100},
+ {0xc20, 0x00000000}, {0xc24, 0x00000000},
+ {0xc28, 0x00000000}, {0xc2c, 0x00000000},
+ {0xc30, 0x69e9ac44}, {0xc34, 0x469652cf},
+ {0xc38, 0x49795994}, {0xc3c, 0x0a97971c},
+ {0xc40, 0x1f7c403f}, {0xc44, 0x000100b7},
+ {0xc48, 0xec020107}, {0xc4c, 0x007f037f},
+ {0xc50, 0x69543420}, {0xc54, 0x43bc0094},
+ {0xc58, 0x69543420}, {0xc5c, 0x433c0094},
+ {0xc60, 0x00000000}, {0xc64, 0x5116848b},
+ {0xc68, 0x47c00bff}, {0xc6c, 0x00000036},
+ {0xc70, 0x2c7f000d}, {0xc74, 0x2186115b},
+ {0xc78, 0x0000001f}, {0xc7c, 0x00b99612},
+ {0xc80, 0x40000100}, {0xc84, 0x20f60000},
+ {0xc88, 0x40000100}, {0xc8c, 0xa0e40000},
+ {0xc90, 0x00121820}, {0xc94, 0x00000000},
+ {0xc98, 0x00121820}, {0xc9c, 0x00007f7f},
+ {0xca0, 0x00000000}, {0xca4, 0x00000080},
+ {0xca8, 0x00000000}, {0xcac, 0x00000000},
+ {0xcb0, 0x00000000}, {0xcb4, 0x00000000},
+ {0xcb8, 0x00000000}, {0xcbc, 0x28000000},
+ {0xcc0, 0x00000000}, {0xcc4, 0x00000000},
+ {0xcc8, 0x00000000}, {0xccc, 0x00000000},
+ {0xcd0, 0x00000000}, {0xcd4, 0x00000000},
+ {0xcd8, 0x64b22427}, {0xcdc, 0x00766932},
+ {0xce0, 0x00222222}, {0xce4, 0x00000000},
+ {0xce8, 0x37644302}, {0xcec, 0x2f97d40c},
+ {0xd00, 0x00080740}, {0xd04, 0x00020403},
+ {0xd08, 0x0000907f}, {0xd0c, 0x20010201},
+ {0xd10, 0xa0633333}, {0xd14, 0x3333bc43},
+ {0xd18, 0x7a8f5b6b}, {0xd2c, 0xcc979975},
+ {0xd30, 0x00000000}, {0xd34, 0x80608000},
+ {0xd38, 0x00000000}, {0xd3c, 0x00027293},
+ {0xd40, 0x00000000}, {0xd44, 0x00000000},
+ {0xd48, 0x00000000}, {0xd4c, 0x00000000},
+ {0xd50, 0x6437140a}, {0xd54, 0x00000000},
+ {0xd58, 0x00000000}, {0xd5c, 0x30032064},
+ {0xd60, 0x4653de68}, {0xd64, 0x04518a3c},
+ {0xd68, 0x00002101}, {0xd6c, 0x2a201c16},
+ {0xd70, 0x1812362e}, {0xd74, 0x322c2220},
+ {0xd78, 0x000e3c24}, {0xe00, 0x2a2a2a2a},
+ {0xe04, 0x2a2a2a2a}, {0xe08, 0x03902a2a},
+ {0xe10, 0x2a2a2a2a}, {0xe14, 0x2a2a2a2a},
+ {0xe18, 0x2a2a2a2a}, {0xe1c, 0x2a2a2a2a},
+ {0xe28, 0x00000000}, {0xe30, 0x1000dc1f},
+ {0xe34, 0x10008c1f}, {0xe38, 0x02140102},
+ {0xe3c, 0x681604c2}, {0xe40, 0x01007c00},
+ {0xe44, 0x01004800}, {0xe48, 0xfb000000},
+ {0xe4c, 0x000028d1}, {0xe50, 0x1000dc1f},
+ {0xe54, 0x10008c1f}, {0xe58, 0x02140102},
+ {0xe5c, 0x28160d05}, {0xe60, 0x00000010},
+ {0xe68, 0x001b25a4}, {0xe6c, 0x63db25a4},
+ {0xe70, 0x63db25a4}, {0xe74, 0x0c1b25a4},
+ {0xe78, 0x0c1b25a4}, {0xe7c, 0x0c1b25a4},
+ {0xe80, 0x0c1b25a4}, {0xe84, 0x63db25a4},
+ {0xe88, 0x0c1b25a4}, {0xe8c, 0x63db25a4},
+ {0xed0, 0x63db25a4}, {0xed4, 0x63db25a4},
+ {0xed8, 0x63db25a4}, {0xedc, 0x001b25a4},
+ {0xee0, 0x001b25a4}, {0xeec, 0x6fdb25a4},
+ {0xf14, 0x00000003}, {0xf4c, 0x00000000},
+ {0xf00, 0x00000300},
+ {0xffff, 0xffffffff},
+};
+
+static struct rtl8xxxu_reg32val rtl8188ru_phy_1t_highpa_table[] = {
+ {0x024, 0x0011800f}, {0x028, 0x00ffdb83},
+ {0x040, 0x000c0004}, {0x800, 0x80040000},
+ {0x804, 0x00000001}, {0x808, 0x0000fc00},
+ {0x80c, 0x0000000a}, {0x810, 0x10005388},
+ {0x814, 0x020c3d10}, {0x818, 0x02200385},
+ {0x81c, 0x00000000}, {0x820, 0x01000100},
+ {0x824, 0x00390204}, {0x828, 0x00000000},
+ {0x82c, 0x00000000}, {0x830, 0x00000000},
+ {0x834, 0x00000000}, {0x838, 0x00000000},
+ {0x83c, 0x00000000}, {0x840, 0x00010000},
+ {0x844, 0x00000000}, {0x848, 0x00000000},
+ {0x84c, 0x00000000}, {0x850, 0x00000000},
+ {0x854, 0x00000000}, {0x858, 0x569a569a},
+ {0x85c, 0x001b25a4}, {0x860, 0x66e60230},
+ {0x864, 0x061f0130}, {0x868, 0x00000000},
+ {0x86c, 0x20202000}, {0x870, 0x03000300},
+ {0x874, 0x22004000}, {0x878, 0x00000808},
+ {0x87c, 0x00ffc3f1}, {0x880, 0xc0083070},
+ {0x884, 0x000004d5}, {0x888, 0x00000000},
+ {0x88c, 0xccc000c0}, {0x890, 0x00000800},
+ {0x894, 0xfffffffe}, {0x898, 0x40302010},
+ {0x89c, 0x00706050}, {0x900, 0x00000000},
+ {0x904, 0x00000023}, {0x908, 0x00000000},
+ {0x90c, 0x81121111}, {0xa00, 0x00d047c8},
+ {0xa04, 0x80ff000c}, {0xa08, 0x8c838300},
+ {0xa0c, 0x2e68120f}, {0xa10, 0x9500bb78},
+ {0xa14, 0x11144028}, {0xa18, 0x00881117},
+ {0xa1c, 0x89140f00}, {0xa20, 0x15160000},
+ {0xa24, 0x070b0f12}, {0xa28, 0x00000104},
+ {0xa2c, 0x00d30000}, {0xa70, 0x101fbf00},
+ {0xa74, 0x00000007}, {0xc00, 0x48071d40},
+ {0xc04, 0x03a05611}, {0xc08, 0x000000e4},
+ {0xc0c, 0x6c6c6c6c}, {0xc10, 0x08800000},
+ {0xc14, 0x40000100}, {0xc18, 0x08800000},
+ {0xc1c, 0x40000100}, {0xc20, 0x00000000},
+ {0xc24, 0x00000000}, {0xc28, 0x00000000},
+ {0xc2c, 0x00000000}, {0xc30, 0x69e9ac44},
+ {0xc34, 0x469652cf}, {0xc38, 0x49795994},
+ {0xc3c, 0x0a97971c}, {0xc40, 0x1f7c403f},
+ {0xc44, 0x000100b7}, {0xc48, 0xec020107},
+ {0xc4c, 0x007f037f}, {0xc50, 0x6954342e},
+ {0xc54, 0x43bc0094}, {0xc58, 0x6954342f},
+ {0xc5c, 0x433c0094}, {0xc60, 0x00000000},
+ {0xc64, 0x5116848b}, {0xc68, 0x47c00bff},
+ {0xc6c, 0x00000036}, {0xc70, 0x2c46000d},
+ {0xc74, 0x018610db}, {0xc78, 0x0000001f},
+ {0xc7c, 0x00b91612}, {0xc80, 0x24000090},
+ {0xc84, 0x20f60000}, {0xc88, 0x24000090},
+ {0xc8c, 0x20200000}, {0xc90, 0x00121820},
+ {0xc94, 0x00000000}, {0xc98, 0x00121820},
+ {0xc9c, 0x00007f7f}, {0xca0, 0x00000000},
+ {0xca4, 0x00000080}, {0xca8, 0x00000000},
+ {0xcac, 0x00000000}, {0xcb0, 0x00000000},
+ {0xcb4, 0x00000000}, {0xcb8, 0x00000000},
+ {0xcbc, 0x28000000}, {0xcc0, 0x00000000},
+ {0xcc4, 0x00000000}, {0xcc8, 0x00000000},
+ {0xccc, 0x00000000}, {0xcd0, 0x00000000},
+ {0xcd4, 0x00000000}, {0xcd8, 0x64b22427},
+ {0xcdc, 0x00766932}, {0xce0, 0x00222222},
+ {0xce4, 0x00000000}, {0xce8, 0x37644302},
+ {0xcec, 0x2f97d40c}, {0xd00, 0x00080740},
+ {0xd04, 0x00020401}, {0xd08, 0x0000907f},
+ {0xd0c, 0x20010201}, {0xd10, 0xa0633333},
+ {0xd14, 0x3333bc43}, {0xd18, 0x7a8f5b6b},
+ {0xd2c, 0xcc979975}, {0xd30, 0x00000000},
+ {0xd34, 0x80608000}, {0xd38, 0x00000000},
+ {0xd3c, 0x00027293}, {0xd40, 0x00000000},
+ {0xd44, 0x00000000}, {0xd48, 0x00000000},
+ {0xd4c, 0x00000000}, {0xd50, 0x6437140a},
+ {0xd54, 0x00000000}, {0xd58, 0x00000000},
+ {0xd5c, 0x30032064}, {0xd60, 0x4653de68},
+ {0xd64, 0x04518a3c}, {0xd68, 0x00002101},
+ {0xd6c, 0x2a201c16}, {0xd70, 0x1812362e},
+ {0xd74, 0x322c2220}, {0xd78, 0x000e3c24},
+ {0xe00, 0x24242424}, {0xe04, 0x24242424},
+ {0xe08, 0x03902024}, {0xe10, 0x24242424},
+ {0xe14, 0x24242424}, {0xe18, 0x24242424},
+ {0xe1c, 0x24242424}, {0xe28, 0x00000000},
+ {0xe30, 0x1000dc1f}, {0xe34, 0x10008c1f},
+ {0xe38, 0x02140102}, {0xe3c, 0x681604c2},
+ {0xe40, 0x01007c00}, {0xe44, 0x01004800},
+ {0xe48, 0xfb000000}, {0xe4c, 0x000028d1},
+ {0xe50, 0x1000dc1f}, {0xe54, 0x10008c1f},
+ {0xe58, 0x02140102}, {0xe5c, 0x28160d05},
+ {0xe60, 0x00000008}, {0xe68, 0x001b25a4},
+ {0xe6c, 0x631b25a0}, {0xe70, 0x631b25a0},
+ {0xe74, 0x081b25a0}, {0xe78, 0x081b25a0},
+ {0xe7c, 0x081b25a0}, {0xe80, 0x081b25a0},
+ {0xe84, 0x631b25a0}, {0xe88, 0x081b25a0},
+ {0xe8c, 0x631b25a0}, {0xed0, 0x631b25a0},
+ {0xed4, 0x631b25a0}, {0xed8, 0x631b25a0},
+ {0xedc, 0x001b25a0}, {0xee0, 0x001b25a0},
+ {0xeec, 0x6b1b25a0}, {0xee8, 0x31555448},
+ {0xf14, 0x00000003}, {0xf4c, 0x00000000},
+ {0xf00, 0x00000300},
+ {0xffff, 0xffffffff},
+};
+
+static struct rtl8xxxu_reg32val rtl8xxx_agc_standard_table[] = {
+ {0xc78, 0x7b000001}, {0xc78, 0x7b010001},
+ {0xc78, 0x7b020001}, {0xc78, 0x7b030001},
+ {0xc78, 0x7b040001}, {0xc78, 0x7b050001},
+ {0xc78, 0x7a060001}, {0xc78, 0x79070001},
+ {0xc78, 0x78080001}, {0xc78, 0x77090001},
+ {0xc78, 0x760a0001}, {0xc78, 0x750b0001},
+ {0xc78, 0x740c0001}, {0xc78, 0x730d0001},
+ {0xc78, 0x720e0001}, {0xc78, 0x710f0001},
+ {0xc78, 0x70100001}, {0xc78, 0x6f110001},
+ {0xc78, 0x6e120001}, {0xc78, 0x6d130001},
+ {0xc78, 0x6c140001}, {0xc78, 0x6b150001},
+ {0xc78, 0x6a160001}, {0xc78, 0x69170001},
+ {0xc78, 0x68180001}, {0xc78, 0x67190001},
+ {0xc78, 0x661a0001}, {0xc78, 0x651b0001},
+ {0xc78, 0x641c0001}, {0xc78, 0x631d0001},
+ {0xc78, 0x621e0001}, {0xc78, 0x611f0001},
+ {0xc78, 0x60200001}, {0xc78, 0x49210001},
+ {0xc78, 0x48220001}, {0xc78, 0x47230001},
+ {0xc78, 0x46240001}, {0xc78, 0x45250001},
+ {0xc78, 0x44260001}, {0xc78, 0x43270001},
+ {0xc78, 0x42280001}, {0xc78, 0x41290001},
+ {0xc78, 0x402a0001}, {0xc78, 0x262b0001},
+ {0xc78, 0x252c0001}, {0xc78, 0x242d0001},
+ {0xc78, 0x232e0001}, {0xc78, 0x222f0001},
+ {0xc78, 0x21300001}, {0xc78, 0x20310001},
+ {0xc78, 0x06320001}, {0xc78, 0x05330001},
+ {0xc78, 0x04340001}, {0xc78, 0x03350001},
+ {0xc78, 0x02360001}, {0xc78, 0x01370001},
+ {0xc78, 0x00380001}, {0xc78, 0x00390001},
+ {0xc78, 0x003a0001}, {0xc78, 0x003b0001},
+ {0xc78, 0x003c0001}, {0xc78, 0x003d0001},
+ {0xc78, 0x003e0001}, {0xc78, 0x003f0001},
+ {0xc78, 0x7b400001}, {0xc78, 0x7b410001},
+ {0xc78, 0x7b420001}, {0xc78, 0x7b430001},
+ {0xc78, 0x7b440001}, {0xc78, 0x7b450001},
+ {0xc78, 0x7a460001}, {0xc78, 0x79470001},
+ {0xc78, 0x78480001}, {0xc78, 0x77490001},
+ {0xc78, 0x764a0001}, {0xc78, 0x754b0001},
+ {0xc78, 0x744c0001}, {0xc78, 0x734d0001},
+ {0xc78, 0x724e0001}, {0xc78, 0x714f0001},
+ {0xc78, 0x70500001}, {0xc78, 0x6f510001},
+ {0xc78, 0x6e520001}, {0xc78, 0x6d530001},
+ {0xc78, 0x6c540001}, {0xc78, 0x6b550001},
+ {0xc78, 0x6a560001}, {0xc78, 0x69570001},
+ {0xc78, 0x68580001}, {0xc78, 0x67590001},
+ {0xc78, 0x665a0001}, {0xc78, 0x655b0001},
+ {0xc78, 0x645c0001}, {0xc78, 0x635d0001},
+ {0xc78, 0x625e0001}, {0xc78, 0x615f0001},
+ {0xc78, 0x60600001}, {0xc78, 0x49610001},
+ {0xc78, 0x48620001}, {0xc78, 0x47630001},
+ {0xc78, 0x46640001}, {0xc78, 0x45650001},
+ {0xc78, 0x44660001}, {0xc78, 0x43670001},
+ {0xc78, 0x42680001}, {0xc78, 0x41690001},
+ {0xc78, 0x406a0001}, {0xc78, 0x266b0001},
+ {0xc78, 0x256c0001}, {0xc78, 0x246d0001},
+ {0xc78, 0x236e0001}, {0xc78, 0x226f0001},
+ {0xc78, 0x21700001}, {0xc78, 0x20710001},
+ {0xc78, 0x06720001}, {0xc78, 0x05730001},
+ {0xc78, 0x04740001}, {0xc78, 0x03750001},
+ {0xc78, 0x02760001}, {0xc78, 0x01770001},
+ {0xc78, 0x00780001}, {0xc78, 0x00790001},
+ {0xc78, 0x007a0001}, {0xc78, 0x007b0001},
+ {0xc78, 0x007c0001}, {0xc78, 0x007d0001},
+ {0xc78, 0x007e0001}, {0xc78, 0x007f0001},
+ {0xc78, 0x3800001e}, {0xc78, 0x3801001e},
+ {0xc78, 0x3802001e}, {0xc78, 0x3803001e},
+ {0xc78, 0x3804001e}, {0xc78, 0x3805001e},
+ {0xc78, 0x3806001e}, {0xc78, 0x3807001e},
+ {0xc78, 0x3808001e}, {0xc78, 0x3c09001e},
+ {0xc78, 0x3e0a001e}, {0xc78, 0x400b001e},
+ {0xc78, 0x440c001e}, {0xc78, 0x480d001e},
+ {0xc78, 0x4c0e001e}, {0xc78, 0x500f001e},
+ {0xc78, 0x5210001e}, {0xc78, 0x5611001e},
+ {0xc78, 0x5a12001e}, {0xc78, 0x5e13001e},
+ {0xc78, 0x6014001e}, {0xc78, 0x6015001e},
+ {0xc78, 0x6016001e}, {0xc78, 0x6217001e},
+ {0xc78, 0x6218001e}, {0xc78, 0x6219001e},
+ {0xc78, 0x621a001e}, {0xc78, 0x621b001e},
+ {0xc78, 0x621c001e}, {0xc78, 0x621d001e},
+ {0xc78, 0x621e001e}, {0xc78, 0x621f001e},
+ {0xffff, 0xffffffff}
+};
+
+static struct rtl8xxxu_reg32val rtl8xxx_agc_highpa_table[] = {
+ {0xc78, 0x7b000001}, {0xc78, 0x7b010001},
+ {0xc78, 0x7b020001}, {0xc78, 0x7b030001},
+ {0xc78, 0x7b040001}, {0xc78, 0x7b050001},
+ {0xc78, 0x7b060001}, {0xc78, 0x7b070001},
+ {0xc78, 0x7b080001}, {0xc78, 0x7a090001},
+ {0xc78, 0x790a0001}, {0xc78, 0x780b0001},
+ {0xc78, 0x770c0001}, {0xc78, 0x760d0001},
+ {0xc78, 0x750e0001}, {0xc78, 0x740f0001},
+ {0xc78, 0x73100001}, {0xc78, 0x72110001},
+ {0xc78, 0x71120001}, {0xc78, 0x70130001},
+ {0xc78, 0x6f140001}, {0xc78, 0x6e150001},
+ {0xc78, 0x6d160001}, {0xc78, 0x6c170001},
+ {0xc78, 0x6b180001}, {0xc78, 0x6a190001},
+ {0xc78, 0x691a0001}, {0xc78, 0x681b0001},
+ {0xc78, 0x671c0001}, {0xc78, 0x661d0001},
+ {0xc78, 0x651e0001}, {0xc78, 0x641f0001},
+ {0xc78, 0x63200001}, {0xc78, 0x62210001},
+ {0xc78, 0x61220001}, {0xc78, 0x60230001},
+ {0xc78, 0x46240001}, {0xc78, 0x45250001},
+ {0xc78, 0x44260001}, {0xc78, 0x43270001},
+ {0xc78, 0x42280001}, {0xc78, 0x41290001},
+ {0xc78, 0x402a0001}, {0xc78, 0x262b0001},
+ {0xc78, 0x252c0001}, {0xc78, 0x242d0001},
+ {0xc78, 0x232e0001}, {0xc78, 0x222f0001},
+ {0xc78, 0x21300001}, {0xc78, 0x20310001},
+ {0xc78, 0x06320001}, {0xc78, 0x05330001},
+ {0xc78, 0x04340001}, {0xc78, 0x03350001},
+ {0xc78, 0x02360001}, {0xc78, 0x01370001},
+ {0xc78, 0x00380001}, {0xc78, 0x00390001},
+ {0xc78, 0x003a0001}, {0xc78, 0x003b0001},
+ {0xc78, 0x003c0001}, {0xc78, 0x003d0001},
+ {0xc78, 0x003e0001}, {0xc78, 0x003f0001},
+ {0xc78, 0x7b400001}, {0xc78, 0x7b410001},
+ {0xc78, 0x7b420001}, {0xc78, 0x7b430001},
+ {0xc78, 0x7b440001}, {0xc78, 0x7b450001},
+ {0xc78, 0x7b460001}, {0xc78, 0x7b470001},
+ {0xc78, 0x7b480001}, {0xc78, 0x7a490001},
+ {0xc78, 0x794a0001}, {0xc78, 0x784b0001},
+ {0xc78, 0x774c0001}, {0xc78, 0x764d0001},
+ {0xc78, 0x754e0001}, {0xc78, 0x744f0001},
+ {0xc78, 0x73500001}, {0xc78, 0x72510001},
+ {0xc78, 0x71520001}, {0xc78, 0x70530001},
+ {0xc78, 0x6f540001}, {0xc78, 0x6e550001},
+ {0xc78, 0x6d560001}, {0xc78, 0x6c570001},
+ {0xc78, 0x6b580001}, {0xc78, 0x6a590001},
+ {0xc78, 0x695a0001}, {0xc78, 0x685b0001},
+ {0xc78, 0x675c0001}, {0xc78, 0x665d0001},
+ {0xc78, 0x655e0001}, {0xc78, 0x645f0001},
+ {0xc78, 0x63600001}, {0xc78, 0x62610001},
+ {0xc78, 0x61620001}, {0xc78, 0x60630001},
+ {0xc78, 0x46640001}, {0xc78, 0x45650001},
+ {0xc78, 0x44660001}, {0xc78, 0x43670001},
+ {0xc78, 0x42680001}, {0xc78, 0x41690001},
+ {0xc78, 0x406a0001}, {0xc78, 0x266b0001},
+ {0xc78, 0x256c0001}, {0xc78, 0x246d0001},
+ {0xc78, 0x236e0001}, {0xc78, 0x226f0001},
+ {0xc78, 0x21700001}, {0xc78, 0x20710001},
+ {0xc78, 0x06720001}, {0xc78, 0x05730001},
+ {0xc78, 0x04740001}, {0xc78, 0x03750001},
+ {0xc78, 0x02760001}, {0xc78, 0x01770001},
+ {0xc78, 0x00780001}, {0xc78, 0x00790001},
+ {0xc78, 0x007a0001}, {0xc78, 0x007b0001},
+ {0xc78, 0x007c0001}, {0xc78, 0x007d0001},
+ {0xc78, 0x007e0001}, {0xc78, 0x007f0001},
+ {0xc78, 0x3800001e}, {0xc78, 0x3801001e},
+ {0xc78, 0x3802001e}, {0xc78, 0x3803001e},
+ {0xc78, 0x3804001e}, {0xc78, 0x3805001e},
+ {0xc78, 0x3806001e}, {0xc78, 0x3807001e},
+ {0xc78, 0x3808001e}, {0xc78, 0x3c09001e},
+ {0xc78, 0x3e0a001e}, {0xc78, 0x400b001e},
+ {0xc78, 0x440c001e}, {0xc78, 0x480d001e},
+ {0xc78, 0x4c0e001e}, {0xc78, 0x500f001e},
+ {0xc78, 0x5210001e}, {0xc78, 0x5611001e},
+ {0xc78, 0x5a12001e}, {0xc78, 0x5e13001e},
+ {0xc78, 0x6014001e}, {0xc78, 0x6015001e},
+ {0xc78, 0x6016001e}, {0xc78, 0x6217001e},
+ {0xc78, 0x6218001e}, {0xc78, 0x6219001e},
+ {0xc78, 0x621a001e}, {0xc78, 0x621b001e},
+ {0xc78, 0x621c001e}, {0xc78, 0x621d001e},
+ {0xc78, 0x621e001e}, {0xc78, 0x621f001e},
+ {0xffff, 0xffffffff}
+};
+
+static struct rtl8xxxu_rfregval rtl8723au_radioa_1t_init_table[] = {
+ {0x00, 0x00030159}, {0x01, 0x00031284},
+ {0x02, 0x00098000}, {0x03, 0x00039c63},
+ {0x04, 0x000210e7}, {0x09, 0x0002044f},
+ {0x0a, 0x0001a3f1}, {0x0b, 0x00014787},
+ {0x0c, 0x000896fe}, {0x0d, 0x0000e02c},
+ {0x0e, 0x00039ce7}, {0x0f, 0x00000451},
+ {0x19, 0x00000000}, {0x1a, 0x00030355},
+ {0x1b, 0x00060a00}, {0x1c, 0x000fc378},
+ {0x1d, 0x000a1250}, {0x1e, 0x0000024f},
+ {0x1f, 0x00000000}, {0x20, 0x0000b614},
+ {0x21, 0x0006c000}, {0x22, 0x00000000},
+ {0x23, 0x00001558}, {0x24, 0x00000060},
+ {0x25, 0x00000483}, {0x26, 0x0004f000},
+ {0x27, 0x000ec7d9}, {0x28, 0x00057730},
+ {0x29, 0x00004783}, {0x2a, 0x00000001},
+ {0x2b, 0x00021334}, {0x2a, 0x00000000},
+ {0x2b, 0x00000054}, {0x2a, 0x00000001},
+ {0x2b, 0x00000808}, {0x2b, 0x00053333},
+ {0x2c, 0x0000000c}, {0x2a, 0x00000002},
+ {0x2b, 0x00000808}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000003},
+ {0x2b, 0x00000808}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000004},
+ {0x2b, 0x00000808}, {0x2b, 0x0006b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000005},
+ {0x2b, 0x00000808}, {0x2b, 0x00073333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000006},
+ {0x2b, 0x00000709}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000007},
+ {0x2b, 0x00000709}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000008},
+ {0x2b, 0x0000060a}, {0x2b, 0x0004b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000009},
+ {0x2b, 0x0000060a}, {0x2b, 0x00053333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000a},
+ {0x2b, 0x0000060a}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000b},
+ {0x2b, 0x0000060a}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000c},
+ {0x2b, 0x0000060a}, {0x2b, 0x0006b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000d},
+ {0x2b, 0x0000060a}, {0x2b, 0x00073333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000e},
+ {0x2b, 0x0000050b}, {0x2b, 0x00066666},
+ {0x2c, 0x0000001a}, {0x2a, 0x000e0000},
+ {0x10, 0x0004000f}, {0x11, 0x000e31fc},
+ {0x10, 0x0006000f}, {0x11, 0x000ff9f8},
+ {0x10, 0x0002000f}, {0x11, 0x000203f9},
+ {0x10, 0x0003000f}, {0x11, 0x000ff500},
+ {0x10, 0x00000000}, {0x11, 0x00000000},
+ {0x10, 0x0008000f}, {0x11, 0x0003f100},
+ {0x10, 0x0009000f}, {0x11, 0x00023100},
+ {0x12, 0x00032000}, {0x12, 0x00071000},
+ {0x12, 0x000b0000}, {0x12, 0x000fc000},
+ {0x13, 0x000287b3}, {0x13, 0x000244b7},
+ {0x13, 0x000204ab}, {0x13, 0x0001c49f},
+ {0x13, 0x00018493}, {0x13, 0x0001429b},
+ {0x13, 0x00010299}, {0x13, 0x0000c29c},
+ {0x13, 0x000081a0}, {0x13, 0x000040ac},
+ {0x13, 0x00000020}, {0x14, 0x0001944c},
+ {0x14, 0x00059444}, {0x14, 0x0009944c},
+ {0x14, 0x000d9444}, {0x15, 0x0000f474},
+ {0x15, 0x0004f477}, {0x15, 0x0008f455},
+ {0x15, 0x000cf455}, {0x16, 0x00000339},
+ {0x16, 0x00040339}, {0x16, 0x00080339},
+ {0x16, 0x000c0366}, {0x00, 0x00010159},
+ {0x18, 0x0000f401}, {0xfe, 0x00000000},
+ {0xfe, 0x00000000}, {0x1f, 0x00000003},
+ {0xfe, 0x00000000}, {0xfe, 0x00000000},
+ {0x1e, 0x00000247}, {0x1f, 0x00000000},
+ {0x00, 0x00030159},
+ {0xff, 0xffffffff}
+};
+
+static struct rtl8xxxu_rfregval rtl8192cu_radioa_2t_init_table[] = {
+ {0x00, 0x00030159}, {0x01, 0x00031284},
+ {0x02, 0x00098000}, {0x03, 0x00018c63},
+ {0x04, 0x000210e7}, {0x09, 0x0002044f},
+ {0x0a, 0x0001adb1}, {0x0b, 0x00054867},
+ {0x0c, 0x0008992e}, {0x0d, 0x0000e52c},
+ {0x0e, 0x00039ce7}, {0x0f, 0x00000451},
+ {0x19, 0x00000000}, {0x1a, 0x00010255},
+ {0x1b, 0x00060a00}, {0x1c, 0x000fc378},
+ {0x1d, 0x000a1250}, {0x1e, 0x0004445f},
+ {0x1f, 0x00080001}, {0x20, 0x0000b614},
+ {0x21, 0x0006c000}, {0x22, 0x00000000},
+ {0x23, 0x00001558}, {0x24, 0x00000060},
+ {0x25, 0x00000483}, {0x26, 0x0004f000},
+ {0x27, 0x000ec7d9}, {0x28, 0x000577c0},
+ {0x29, 0x00004783}, {0x2a, 0x00000001},
+ {0x2b, 0x00021334}, {0x2a, 0x00000000},
+ {0x2b, 0x00000054}, {0x2a, 0x00000001},
+ {0x2b, 0x00000808}, {0x2b, 0x00053333},
+ {0x2c, 0x0000000c}, {0x2a, 0x00000002},
+ {0x2b, 0x00000808}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000003},
+ {0x2b, 0x00000808}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000004},
+ {0x2b, 0x00000808}, {0x2b, 0x0006b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000005},
+ {0x2b, 0x00000808}, {0x2b, 0x00073333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000006},
+ {0x2b, 0x00000709}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000007},
+ {0x2b, 0x00000709}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000008},
+ {0x2b, 0x0000060a}, {0x2b, 0x0004b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000009},
+ {0x2b, 0x0000060a}, {0x2b, 0x00053333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000a},
+ {0x2b, 0x0000060a}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000b},
+ {0x2b, 0x0000060a}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000c},
+ {0x2b, 0x0000060a}, {0x2b, 0x0006b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000d},
+ {0x2b, 0x0000060a}, {0x2b, 0x00073333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000e},
+ {0x2b, 0x0000050b}, {0x2b, 0x00066666},
+ {0x2c, 0x0000001a}, {0x2a, 0x000e0000},
+ {0x10, 0x0004000f}, {0x11, 0x000e31fc},
+ {0x10, 0x0006000f}, {0x11, 0x000ff9f8},
+ {0x10, 0x0002000f}, {0x11, 0x000203f9},
+ {0x10, 0x0003000f}, {0x11, 0x000ff500},
+ {0x10, 0x00000000}, {0x11, 0x00000000},
+ {0x10, 0x0008000f}, {0x11, 0x0003f100},
+ {0x10, 0x0009000f}, {0x11, 0x00023100},
+ {0x12, 0x00032000}, {0x12, 0x00071000},
+ {0x12, 0x000b0000}, {0x12, 0x000fc000},
+ {0x13, 0x000287b3}, {0x13, 0x000244b7},
+ {0x13, 0x000204ab}, {0x13, 0x0001c49f},
+ {0x13, 0x00018493}, {0x13, 0x0001429b},
+ {0x13, 0x00010299}, {0x13, 0x0000c29c},
+ {0x13, 0x000081a0}, {0x13, 0x000040ac},
+ {0x13, 0x00000020}, {0x14, 0x0001944c},
+ {0x14, 0x00059444}, {0x14, 0x0009944c},
+ {0x14, 0x000d9444}, {0x15, 0x0000f424},
+ {0x15, 0x0004f424}, {0x15, 0x0008f424},
+ {0x15, 0x000cf424}, {0x16, 0x000e0330},
+ {0x16, 0x000a0330}, {0x16, 0x00060330},
+ {0x16, 0x00020330}, {0x00, 0x00010159},
+ {0x18, 0x0000f401}, {0xfe, 0x00000000},
+ {0xfe, 0x00000000}, {0x1f, 0x00080003},
+ {0xfe, 0x00000000}, {0xfe, 0x00000000},
+ {0x1e, 0x00044457}, {0x1f, 0x00080000},
+ {0x00, 0x00030159},
+ {0xff, 0xffffffff}
+};
+
+static struct rtl8xxxu_rfregval rtl8192cu_radiob_2t_init_table[] = {
+ {0x00, 0x00030159}, {0x01, 0x00031284},
+ {0x02, 0x00098000}, {0x03, 0x00018c63},
+ {0x04, 0x000210e7}, {0x09, 0x0002044f},
+ {0x0a, 0x0001adb1}, {0x0b, 0x00054867},
+ {0x0c, 0x0008992e}, {0x0d, 0x0000e52c},
+ {0x0e, 0x00039ce7}, {0x0f, 0x00000451},
+ {0x12, 0x00032000}, {0x12, 0x00071000},
+ {0x12, 0x000b0000}, {0x12, 0x000fc000},
+ {0x13, 0x000287af}, {0x13, 0x000244b7},
+ {0x13, 0x000204ab}, {0x13, 0x0001c49f},
+ {0x13, 0x00018493}, {0x13, 0x00014297},
+ {0x13, 0x00010295}, {0x13, 0x0000c298},
+ {0x13, 0x0000819c}, {0x13, 0x000040a8},
+ {0x13, 0x0000001c}, {0x14, 0x0001944c},
+ {0x14, 0x00059444}, {0x14, 0x0009944c},
+ {0x14, 0x000d9444}, {0x15, 0x0000f424},
+ {0x15, 0x0004f424}, {0x15, 0x0008f424},
+ {0x15, 0x000cf424}, {0x16, 0x000e0330},
+ {0x16, 0x000a0330}, {0x16, 0x00060330},
+ {0x16, 0x00020330},
+ {0xff, 0xffffffff}
+};
+
+static struct rtl8xxxu_rfregval rtl8192cu_radioa_1t_init_table[] = {
+ {0x00, 0x00030159}, {0x01, 0x00031284},
+ {0x02, 0x00098000}, {0x03, 0x00018c63},
+ {0x04, 0x000210e7}, {0x09, 0x0002044f},
+ {0x0a, 0x0001adb1}, {0x0b, 0x00054867},
+ {0x0c, 0x0008992e}, {0x0d, 0x0000e52c},
+ {0x0e, 0x00039ce7}, {0x0f, 0x00000451},
+ {0x19, 0x00000000}, {0x1a, 0x00010255},
+ {0x1b, 0x00060a00}, {0x1c, 0x000fc378},
+ {0x1d, 0x000a1250}, {0x1e, 0x0004445f},
+ {0x1f, 0x00080001}, {0x20, 0x0000b614},
+ {0x21, 0x0006c000}, {0x22, 0x00000000},
+ {0x23, 0x00001558}, {0x24, 0x00000060},
+ {0x25, 0x00000483}, {0x26, 0x0004f000},
+ {0x27, 0x000ec7d9}, {0x28, 0x000577c0},
+ {0x29, 0x00004783}, {0x2a, 0x00000001},
+ {0x2b, 0x00021334}, {0x2a, 0x00000000},
+ {0x2b, 0x00000054}, {0x2a, 0x00000001},
+ {0x2b, 0x00000808}, {0x2b, 0x00053333},
+ {0x2c, 0x0000000c}, {0x2a, 0x00000002},
+ {0x2b, 0x00000808}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000003},
+ {0x2b, 0x00000808}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000004},
+ {0x2b, 0x00000808}, {0x2b, 0x0006b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000005},
+ {0x2b, 0x00000808}, {0x2b, 0x00073333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000006},
+ {0x2b, 0x00000709}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000007},
+ {0x2b, 0x00000709}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000008},
+ {0x2b, 0x0000060a}, {0x2b, 0x0004b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000009},
+ {0x2b, 0x0000060a}, {0x2b, 0x00053333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000a},
+ {0x2b, 0x0000060a}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000b},
+ {0x2b, 0x0000060a}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000c},
+ {0x2b, 0x0000060a}, {0x2b, 0x0006b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000d},
+ {0x2b, 0x0000060a}, {0x2b, 0x00073333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000e},
+ {0x2b, 0x0000050b}, {0x2b, 0x00066666},
+ {0x2c, 0x0000001a}, {0x2a, 0x000e0000},
+ {0x10, 0x0004000f}, {0x11, 0x000e31fc},
+ {0x10, 0x0006000f}, {0x11, 0x000ff9f8},
+ {0x10, 0x0002000f}, {0x11, 0x000203f9},
+ {0x10, 0x0003000f}, {0x11, 0x000ff500},
+ {0x10, 0x00000000}, {0x11, 0x00000000},
+ {0x10, 0x0008000f}, {0x11, 0x0003f100},
+ {0x10, 0x0009000f}, {0x11, 0x00023100},
+ {0x12, 0x00032000}, {0x12, 0x00071000},
+ {0x12, 0x000b0000}, {0x12, 0x000fc000},
+ {0x13, 0x000287b3}, {0x13, 0x000244b7},
+ {0x13, 0x000204ab}, {0x13, 0x0001c49f},
+ {0x13, 0x00018493}, {0x13, 0x0001429b},
+ {0x13, 0x00010299}, {0x13, 0x0000c29c},
+ {0x13, 0x000081a0}, {0x13, 0x000040ac},
+ {0x13, 0x00000020}, {0x14, 0x0001944c},
+ {0x14, 0x00059444}, {0x14, 0x0009944c},
+ {0x14, 0x000d9444}, {0x15, 0x0000f405},
+ {0x15, 0x0004f405}, {0x15, 0x0008f405},
+ {0x15, 0x000cf405}, {0x16, 0x000e0330},
+ {0x16, 0x000a0330}, {0x16, 0x00060330},
+ {0x16, 0x00020330}, {0x00, 0x00010159},
+ {0x18, 0x0000f401}, {0xfe, 0x00000000},
+ {0xfe, 0x00000000}, {0x1f, 0x00080003},
+ {0xfe, 0x00000000}, {0xfe, 0x00000000},
+ {0x1e, 0x00044457}, {0x1f, 0x00080000},
+ {0x00, 0x00030159},
+ {0xff, 0xffffffff}
+};
+
+static struct rtl8xxxu_rfregval rtl8188ru_radioa_1t_highpa_table[] = {
+ {0x00, 0x00030159}, {0x01, 0x00031284},
+ {0x02, 0x00098000}, {0x03, 0x00018c63},
+ {0x04, 0x000210e7}, {0x09, 0x0002044f},
+ {0x0a, 0x0001adb0}, {0x0b, 0x00054867},
+ {0x0c, 0x0008992e}, {0x0d, 0x0000e529},
+ {0x0e, 0x00039ce7}, {0x0f, 0x00000451},
+ {0x19, 0x00000000}, {0x1a, 0x00000255},
+ {0x1b, 0x00060a00}, {0x1c, 0x000fc378},
+ {0x1d, 0x000a1250}, {0x1e, 0x0004445f},
+ {0x1f, 0x00080001}, {0x20, 0x0000b614},
+ {0x21, 0x0006c000}, {0x22, 0x0000083c},
+ {0x23, 0x00001558}, {0x24, 0x00000060},
+ {0x25, 0x00000483}, {0x26, 0x0004f000},
+ {0x27, 0x000ec7d9}, {0x28, 0x000977c0},
+ {0x29, 0x00004783}, {0x2a, 0x00000001},
+ {0x2b, 0x00021334}, {0x2a, 0x00000000},
+ {0x2b, 0x00000054}, {0x2a, 0x00000001},
+ {0x2b, 0x00000808}, {0x2b, 0x00053333},
+ {0x2c, 0x0000000c}, {0x2a, 0x00000002},
+ {0x2b, 0x00000808}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000003},
+ {0x2b, 0x00000808}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000004},
+ {0x2b, 0x00000808}, {0x2b, 0x0006b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000005},
+ {0x2b, 0x00000808}, {0x2b, 0x00073333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000006},
+ {0x2b, 0x00000709}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000007},
+ {0x2b, 0x00000709}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000008},
+ {0x2b, 0x0000060a}, {0x2b, 0x0004b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x00000009},
+ {0x2b, 0x0000060a}, {0x2b, 0x00053333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000a},
+ {0x2b, 0x0000060a}, {0x2b, 0x0005b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000b},
+ {0x2b, 0x0000060a}, {0x2b, 0x00063333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000c},
+ {0x2b, 0x0000060a}, {0x2b, 0x0006b333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000d},
+ {0x2b, 0x0000060a}, {0x2b, 0x00073333},
+ {0x2c, 0x0000000d}, {0x2a, 0x0000000e},
+ {0x2b, 0x0000050b}, {0x2b, 0x00066666},
+ {0x2c, 0x0000001a}, {0x2a, 0x000e0000},
+ {0x10, 0x0004000f}, {0x11, 0x000e31fc},
+ {0x10, 0x0006000f}, {0x11, 0x000ff9f8},
+ {0x10, 0x0002000f}, {0x11, 0x000203f9},
+ {0x10, 0x0003000f}, {0x11, 0x000ff500},
+ {0x10, 0x00000000}, {0x11, 0x00000000},
+ {0x10, 0x0008000f}, {0x11, 0x0003f100},
+ {0x10, 0x0009000f}, {0x11, 0x00023100},
+ {0x12, 0x000d8000}, {0x12, 0x00090000},
+ {0x12, 0x00051000}, {0x12, 0x00012000},
+ {0x13, 0x00028fb4}, {0x13, 0x00024fa8},
+ {0x13, 0x000207a4}, {0x13, 0x0001c3b0},
+ {0x13, 0x000183a4}, {0x13, 0x00014398},
+ {0x13, 0x000101a4}, {0x13, 0x0000c198},
+ {0x13, 0x000080a4}, {0x13, 0x00004098},
+ {0x13, 0x00000000}, {0x14, 0x0001944c},
+ {0x14, 0x00059444}, {0x14, 0x0009944c},
+ {0x14, 0x000d9444}, {0x15, 0x0000f405},
+ {0x15, 0x0004f405}, {0x15, 0x0008f405},
+ {0x15, 0x000cf405}, {0x16, 0x000e0330},
+ {0x16, 0x000a0330}, {0x16, 0x00060330},
+ {0x16, 0x00020330}, {0x00, 0x00010159},
+ {0x18, 0x0000f401}, {0xfe, 0x00000000},
+ {0xfe, 0x00000000}, {0x1f, 0x00080003},
+ {0xfe, 0x00000000}, {0xfe, 0x00000000},
+ {0x1e, 0x00044457}, {0x1f, 0x00080000},
+ {0x00, 0x00030159},
+ {0xff, 0xffffffff}
+};
+
+static struct rtl8xxxu_rfregs rtl8xxxu_rfregs[] = {
+ { /* RF_A */
+ .hssiparm1 = REG_FPGA0_XA_HSSI_PARM1,
+ .hssiparm2 = REG_FPGA0_XA_HSSI_PARM2,
+ .lssiparm = REG_FPGA0_XA_LSSI_PARM,
+ .hspiread = REG_HSPI_XA_READBACK,
+ .lssiread = REG_FPGA0_XA_LSSI_READBACK,
+ .rf_sw_ctrl = REG_FPGA0_XA_RF_SW_CTRL,
+ },
+ { /* RF_B */
+ .hssiparm1 = REG_FPGA0_XB_HSSI_PARM1,
+ .hssiparm2 = REG_FPGA0_XB_HSSI_PARM2,
+ .lssiparm = REG_FPGA0_XB_LSSI_PARM,
+ .hspiread = REG_HSPI_XB_READBACK,
+ .lssiread = REG_FPGA0_XB_LSSI_READBACK,
+ .rf_sw_ctrl = REG_FPGA0_XB_RF_SW_CTRL,
+ },
+};
+
+static const u32 rtl8723au_iqk_phy_iq_bb_reg[RTL8XXXU_BB_REGS] = {
+ REG_OFDM0_XA_RX_IQ_IMBALANCE,
+ REG_OFDM0_XB_RX_IQ_IMBALANCE,
+ REG_OFDM0_ENERGY_CCA_THRES,
+ REG_OFDM0_AGCR_SSI_TABLE,
+ REG_OFDM0_XA_TX_IQ_IMBALANCE,
+ REG_OFDM0_XB_TX_IQ_IMBALANCE,
+ REG_OFDM0_XC_TX_AFE,
+ REG_OFDM0_XD_TX_AFE,
+ REG_OFDM0_RX_IQ_EXT_ANTA
+};
+
+static u8 rtl8xxxu_read8(struct rtl8xxxu_priv *priv, u16 addr)
+{
+ struct usb_device *udev = priv->udev;
+ int len;
+ u8 data;
+
+ mutex_lock(&priv->usb_buf_mutex);
+ len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ REALTEK_USB_CMD_REQ, REALTEK_USB_READ,
+ addr, 0, &priv->usb_buf.val8, sizeof(u8),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
+ data = priv->usb_buf.val8;
+ mutex_unlock(&priv->usb_buf_mutex);
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_READ)
+ dev_info(&udev->dev, "%s(%04x) = 0x%02x, len %i\n",
+ __func__, addr, data, len);
+ return data;
+}
+
+static u16 rtl8xxxu_read16(struct rtl8xxxu_priv *priv, u16 addr)
+{
+ struct usb_device *udev = priv->udev;
+ int len;
+ u16 data;
+
+ mutex_lock(&priv->usb_buf_mutex);
+ len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ REALTEK_USB_CMD_REQ, REALTEK_USB_READ,
+ addr, 0, &priv->usb_buf.val16, sizeof(u16),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
+ data = le16_to_cpu(priv->usb_buf.val16);
+ mutex_unlock(&priv->usb_buf_mutex);
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_READ)
+ dev_info(&udev->dev, "%s(%04x) = 0x%04x, len %i\n",
+ __func__, addr, data, len);
+ return data;
+}
+
+static u32 rtl8xxxu_read32(struct rtl8xxxu_priv *priv, u16 addr)
+{
+ struct usb_device *udev = priv->udev;
+ int len;
+ u32 data;
+
+ mutex_lock(&priv->usb_buf_mutex);
+ len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ REALTEK_USB_CMD_REQ, REALTEK_USB_READ,
+ addr, 0, &priv->usb_buf.val32, sizeof(u32),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
+ data = le32_to_cpu(priv->usb_buf.val32);
+ mutex_unlock(&priv->usb_buf_mutex);
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_READ)
+ dev_info(&udev->dev, "%s(%04x) = 0x%08x, len %i\n",
+ __func__, addr, data, len);
+ return data;
+}
+
+static int rtl8xxxu_write8(struct rtl8xxxu_priv *priv, u16 addr, u8 val)
+{
+ struct usb_device *udev = priv->udev;
+ int ret;
+
+ mutex_lock(&priv->usb_buf_mutex);
+ priv->usb_buf.val8 = val;
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE,
+ addr, 0, &priv->usb_buf.val8, sizeof(u8),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
+
+ mutex_unlock(&priv->usb_buf_mutex);
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE)
+ dev_info(&udev->dev, "%s(%04x) = 0x%02x\n",
+ __func__, addr, val);
+ return ret;
+}
+
+static int rtl8xxxu_write16(struct rtl8xxxu_priv *priv, u16 addr, u16 val)
+{
+ struct usb_device *udev = priv->udev;
+ int ret;
+
+ mutex_lock(&priv->usb_buf_mutex);
+ priv->usb_buf.val16 = cpu_to_le16(val);
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE,
+ addr, 0, &priv->usb_buf.val16, sizeof(u16),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
+ mutex_unlock(&priv->usb_buf_mutex);
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE)
+ dev_info(&udev->dev, "%s(%04x) = 0x%04x\n",
+ __func__, addr, val);
+ return ret;
+}
+
+static int rtl8xxxu_write32(struct rtl8xxxu_priv *priv, u16 addr, u32 val)
+{
+ struct usb_device *udev = priv->udev;
+ int ret;
+
+ mutex_lock(&priv->usb_buf_mutex);
+ priv->usb_buf.val32 = cpu_to_le32(val);
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE,
+ addr, 0, &priv->usb_buf.val32, sizeof(u32),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
+ mutex_unlock(&priv->usb_buf_mutex);
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE)
+ dev_info(&udev->dev, "%s(%04x) = 0x%08x\n",
+ __func__, addr, val);
+ return ret;
+}
+
+static int
+rtl8xxxu_writeN(struct rtl8xxxu_priv *priv, u16 addr, u8 *buf, u16 len)
+{
+ struct usb_device *udev = priv->udev;
+ int blocksize = priv->fops->writeN_block_size;
+ int ret, i, count, remainder;
+
+ count = len / blocksize;
+ remainder = len % blocksize;
+
+ for (i = 0; i < count; i++) {
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE,
+ addr, 0, buf, blocksize,
+ RTW_USB_CONTROL_MSG_TIMEOUT);
+ if (ret != blocksize)
+ goto write_error;
+
+ addr += blocksize;
+ buf += blocksize;
+ }
+
+ if (remainder) {
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_CMD_REQ, REALTEK_USB_WRITE,
+ addr, 0, buf, remainder,
+ RTW_USB_CONTROL_MSG_TIMEOUT);
+ if (ret != remainder)
+ goto write_error;
+ }
+
+ return len;
+
+write_error:
+ dev_info(&udev->dev,
+ "%s: Failed to write block at addr: %04x size: %04x\n",
+ __func__, addr, blocksize);
+ return -EAGAIN;
+}
+
+static u32 rtl8xxxu_read_rfreg(struct rtl8xxxu_priv *priv,
+ enum rtl8xxxu_rfpath path, u8 reg)
+{
+ u32 hssia, val32, retval;
+
+ hssia = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM2);
+ if (path != RF_A)
+ val32 = rtl8xxxu_read32(priv, rtl8xxxu_rfregs[path].hssiparm2);
+ else
+ val32 = hssia;
+
+ val32 &= ~FPGA0_HSSI_PARM2_ADDR_MASK;
+ val32 |= (reg << FPGA0_HSSI_PARM2_ADDR_SHIFT);
+ val32 |= FPGA0_HSSI_PARM2_EDGE_READ;
+ hssia &= ~FPGA0_HSSI_PARM2_EDGE_READ;
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM2, hssia);
+
+ udelay(10);
+
+ rtl8xxxu_write32(priv, rtl8xxxu_rfregs[path].hssiparm2, val32);
+ udelay(100);
+
+ hssia |= FPGA0_HSSI_PARM2_EDGE_READ;
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM2, hssia);
+ udelay(10);
+
+ val32 = rtl8xxxu_read32(priv, rtl8xxxu_rfregs[path].hssiparm1);
+ if (val32 & FPGA0_HSSI_PARM1_PI)
+ retval = rtl8xxxu_read32(priv, rtl8xxxu_rfregs[path].hspiread);
+ else
+ retval = rtl8xxxu_read32(priv, rtl8xxxu_rfregs[path].lssiread);
+
+ retval &= 0xfffff;
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_RFREG_READ)
+ dev_info(&priv->udev->dev, "%s(%02x) = 0x%06x\n",
+ __func__, reg, retval);
+ return retval;
+}
+
+static int rtl8xxxu_write_rfreg(struct rtl8xxxu_priv *priv,
+ enum rtl8xxxu_rfpath path, u8 reg, u32 data)
+{
+ int ret, retval;
+ u32 dataaddr;
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_RFREG_WRITE)
+ dev_info(&priv->udev->dev, "%s(%02x) = 0x%06x\n",
+ __func__, reg, data);
+
+ data &= FPGA0_LSSI_PARM_DATA_MASK;
+ dataaddr = (reg << FPGA0_LSSI_PARM_ADDR_SHIFT) | data;
+
+ /* Use XB for path B */
+ ret = rtl8xxxu_write32(priv, rtl8xxxu_rfregs[path].lssiparm, dataaddr);
+ if (ret != sizeof(dataaddr))
+ retval = -EIO;
+ else
+ retval = 0;
+
+ udelay(1);
+
+ return retval;
+}
+
+static int rtl8723a_h2c_cmd(struct rtl8xxxu_priv *priv, struct h2c_cmd *h2c)
+{
+ struct device *dev = &priv->udev->dev;
+ int mbox_nr, retry, retval = 0;
+ int mbox_reg, mbox_ext_reg;
+ u8 val8;
+
+ mutex_lock(&priv->h2c_mutex);
+
+ mbox_nr = priv->next_mbox;
+ mbox_reg = REG_HMBOX_0 + (mbox_nr * 4);
+ mbox_ext_reg = REG_HMBOX_EXT_0 + (mbox_nr * 2);
+
+ /*
+ * MBOX ready?
+ */
+ retry = 100;
+ do {
+ val8 = rtl8xxxu_read8(priv, REG_HMTFR);
+ if (!(val8 & BIT(mbox_nr)))
+ break;
+ } while (retry--);
+
+ if (!retry) {
+ dev_dbg(dev, "%s: Mailbox busy\n", __func__);
+ retval = -EBUSY;
+ goto error;
+ }
+
+ /*
+ * Need to swap as it's being swapped again by rtl8xxxu_write16/32()
+ */
+ if (h2c->cmd.cmd & H2C_EXT) {
+ rtl8xxxu_write16(priv, mbox_ext_reg,
+ le16_to_cpu(h2c->raw.ext));
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_H2C)
+ dev_info(dev, "H2C_EXT %04x\n",
+ le16_to_cpu(h2c->raw.ext));
+ }
+ rtl8xxxu_write32(priv, mbox_reg, le32_to_cpu(h2c->raw.data));
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_H2C)
+ dev_info(dev, "H2C %08x\n", le32_to_cpu(h2c->raw.data));
+
+ priv->next_mbox = (mbox_nr + 1) % H2C_MAX_MBOX;
+
+error:
+ mutex_unlock(&priv->h2c_mutex);
+ return retval;
+}
+
+static void rtl8723a_enable_rf(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+ u32 val32;
+
+ val8 = rtl8xxxu_read8(priv, REG_SPS0_CTRL);
+ val8 |= BIT(0) | BIT(3);
+ rtl8xxxu_write8(priv, REG_SPS0_CTRL, val8);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_PARM);
+ val32 &= ~(BIT(4) | BIT(5));
+ val32 |= BIT(3);
+ if (priv->rf_paths == 2) {
+ val32 &= ~(BIT(20) | BIT(21));
+ val32 |= BIT(19);
+ }
+ rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_PARM, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE);
+ val32 &= ~OFDM_RF_PATH_TX_MASK;
+ if (priv->tx_paths == 2)
+ val32 |= OFDM_RF_PATH_TX_A | OFDM_RF_PATH_TX_B;
+ else if (priv->rtlchip == 0x8192c || priv->rtlchip == 0x8191c)
+ val32 |= OFDM_RF_PATH_TX_B;
+ else
+ val32 |= OFDM_RF_PATH_TX_A;
+ rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
+ val32 &= ~FPGA_RF_MODE_JAPAN;
+ rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
+
+ if (priv->rf_paths == 2)
+ rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x63db25a0);
+ else
+ rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x631b25a0);
+
+ rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0x32d95);
+ if (priv->rf_paths == 2)
+ rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC, 0x32d95);
+
+ rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00);
+}
+
+static void rtl8723a_disable_rf(struct rtl8xxxu_priv *priv)
+{
+ u8 sps0;
+ u32 val32;
+
+ rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
+
+ sps0 = rtl8xxxu_read8(priv, REG_SPS0_CTRL);
+
+ /* RF RX code for preamble power saving */
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_PARM);
+ val32 &= ~(BIT(3) | BIT(4) | BIT(5));
+ if (priv->rf_paths == 2)
+ val32 &= ~(BIT(19) | BIT(20) | BIT(21));
+ rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_PARM, val32);
+
+ /* Disable TX for four paths */
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE);
+ val32 &= ~OFDM_RF_PATH_TX_MASK;
+ rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32);
+
+ /* Enable power saving */
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
+ val32 |= FPGA_RF_MODE_JAPAN;
+ rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
+
+ /* AFE control register to power down bits [30:22] */
+ if (priv->rf_paths == 2)
+ rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x00db25a0);
+ else
+ rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x001b25a0);
+
+ /* Power down RF module */
+ rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0);
+ if (priv->rf_paths == 2)
+ rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC, 0);
+
+ sps0 &= ~(BIT(0) | BIT(3));
+ rtl8xxxu_write8(priv, REG_SPS0_CTRL, sps0);
+}
+
+
+static void rtl8723a_stop_tx_beacon(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+
+ val8 = rtl8xxxu_read8(priv, REG_FWHW_TXQ_CTRL + 2);
+ val8 &= ~BIT(6);
+ rtl8xxxu_write8(priv, REG_FWHW_TXQ_CTRL + 2, val8);
+
+ rtl8xxxu_write8(priv, REG_TBTT_PROHIBIT + 1, 0x64);
+ val8 = rtl8xxxu_read8(priv, REG_TBTT_PROHIBIT + 2);
+ val8 &= ~BIT(0);
+ rtl8xxxu_write8(priv, REG_TBTT_PROHIBIT + 2, val8);
+}
+
+
+/*
+ * The rtl8723a has 3 channel groups for it's efuse settings. It only
+ * supports the 2.4GHz band, so channels 1 - 14:
+ * group 0: channels 1 - 3
+ * group 1: channels 4 - 9
+ * group 2: channels 10 - 14
+ *
+ * Note: We index from 0 in the code
+ */
+static int rtl8723a_channel_to_group(int channel)
+{
+ int group;
+
+ if (channel < 4)
+ group = 0;
+ else if (channel < 10)
+ group = 1;
+ else
+ group = 2;
+
+ return group;
+}
+
+static void rtl8723au_config_channel(struct ieee80211_hw *hw)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ u32 val32, rsr;
+ u8 val8, opmode;
+ bool ht = true;
+ int sec_ch_above, channel;
+ int i;
+
+ opmode = rtl8xxxu_read8(priv, REG_BW_OPMODE);
+ rsr = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET);
+ channel = hw->conf.chandef.chan->hw_value;
+
+ switch (hw->conf.chandef.width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ ht = false;
+ case NL80211_CHAN_WIDTH_20:
+ opmode |= BW_OPMODE_20MHZ;
+ rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
+ val32 &= ~FPGA_RF_MODE;
+ rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE);
+ val32 &= ~FPGA_RF_MODE;
+ rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_ANALOG2);
+ val32 |= FPGA0_ANALOG2_20MHZ;
+ rtl8xxxu_write32(priv, REG_FPGA0_ANALOG2, val32);
+ break;
+ case NL80211_CHAN_WIDTH_40:
+ if (hw->conf.chandef.center_freq1 >
+ hw->conf.chandef.chan->center_freq) {
+ sec_ch_above = 1;
+ channel += 2;
+ } else {
+ sec_ch_above = 0;
+ channel -= 2;
+ }
+
+ opmode &= ~BW_OPMODE_20MHZ;
+ rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode);
+ rsr &= ~RSR_RSC_BANDWIDTH_40M;
+ if (sec_ch_above)
+ rsr |= RSR_RSC_UPPER_SUB_CHANNEL;
+ else
+ rsr |= RSR_RSC_LOWER_SUB_CHANNEL;
+ rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, rsr);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
+ val32 |= FPGA_RF_MODE;
+ rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE);
+ val32 |= FPGA_RF_MODE;
+ rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32);
+
+ /*
+ * Set Control channel to upper or lower. These settings
+ * are required only for 40MHz
+ */
+ val32 = rtl8xxxu_read32(priv, REG_CCK0_SYSTEM);
+ val32 &= ~CCK0_SIDEBAND;
+ if (!sec_ch_above)
+ val32 |= CCK0_SIDEBAND;
+ rtl8xxxu_write32(priv, REG_CCK0_SYSTEM, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM1_LSTF);
+ val32 &= ~OFDM_LSTF_PRIME_CH_MASK; /* 0xc00 */
+ if (sec_ch_above)
+ val32 |= OFDM_LSTF_PRIME_CH_LOW;
+ else
+ val32 |= OFDM_LSTF_PRIME_CH_HIGH;
+ rtl8xxxu_write32(priv, REG_OFDM1_LSTF, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_ANALOG2);
+ val32 &= ~FPGA0_ANALOG2_20MHZ;
+ rtl8xxxu_write32(priv, REG_FPGA0_ANALOG2, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_POWER_SAVE);
+ val32 &= ~(FPGA0_PS_LOWER_CHANNEL | FPGA0_PS_UPPER_CHANNEL);
+ if (sec_ch_above)
+ val32 |= FPGA0_PS_UPPER_CHANNEL;
+ else
+ val32 |= FPGA0_PS_LOWER_CHANNEL;
+ rtl8xxxu_write32(priv, REG_FPGA0_POWER_SAVE, val32);
+ break;
+
+ default:
+ break;
+ }
+
+ for (i = RF_A; i < priv->rf_paths; i++) {
+ val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG);
+ val32 &= ~MODE_AG_CHANNEL_MASK;
+ val32 |= channel;
+ rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32);
+ }
+
+ if (ht)
+ val8 = 0x0e;
+ else
+ val8 = 0x0a;
+
+ rtl8xxxu_write8(priv, REG_SIFS_CCK + 1, val8);
+ rtl8xxxu_write8(priv, REG_SIFS_OFDM + 1, val8);
+
+ rtl8xxxu_write16(priv, REG_R2T_SIFS, 0x0808);
+ rtl8xxxu_write16(priv, REG_T2T_SIFS, 0x0a0a);
+
+ for (i = RF_A; i < priv->rf_paths; i++) {
+ val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG);
+ if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40)
+ val32 &= ~MODE_AG_CHANNEL_20MHZ;
+ else
+ val32 |= MODE_AG_CHANNEL_20MHZ;
+ rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32);
+ }
+}
+
+static void
+rtl8723a_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
+{
+ u8 cck[RTL8723A_MAX_RF_PATHS], ofdm[RTL8723A_MAX_RF_PATHS];
+ u8 ofdmbase[RTL8723A_MAX_RF_PATHS], mcsbase[RTL8723A_MAX_RF_PATHS];
+ u32 val32, ofdm_a, ofdm_b, mcs_a, mcs_b;
+ u8 val8;
+ int group, i;
+
+ group = rtl8723a_channel_to_group(channel);
+
+ cck[0] = priv->cck_tx_power_index_A[group];
+ cck[1] = priv->cck_tx_power_index_B[group];
+
+ ofdm[0] = priv->ht40_1s_tx_power_index_A[group];
+ ofdm[1] = priv->ht40_1s_tx_power_index_B[group];
+
+ ofdmbase[0] = ofdm[0] + priv->ofdm_tx_power_index_diff[group].a;
+ ofdmbase[1] = ofdm[1] + priv->ofdm_tx_power_index_diff[group].b;
+
+ mcsbase[0] = ofdm[0];
+ mcsbase[1] = ofdm[1];
+ if (!ht40) {
+ mcsbase[0] += priv->ht20_tx_power_index_diff[group].a;
+ mcsbase[1] += priv->ht20_tx_power_index_diff[group].b;
+ }
+
+ if (priv->tx_paths > 1) {
+ if (ofdm[0] > priv->ht40_2s_tx_power_index_diff[group].a)
+ ofdm[0] -= priv->ht40_2s_tx_power_index_diff[group].a;
+ if (ofdm[1] > priv->ht40_2s_tx_power_index_diff[group].b)
+ ofdm[1] -= priv->ht40_2s_tx_power_index_diff[group].b;
+ }
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_CHANNEL)
+ dev_info(&priv->udev->dev,
+ "%s: Setting TX power CCK A: %02x, "
+ "CCK B: %02x, OFDM A: %02x, OFDM B: %02x\n",
+ __func__, cck[0], cck[1], ofdm[0], ofdm[1]);
+
+ for (i = 0; i < RTL8723A_MAX_RF_PATHS; i++) {
+ if (cck[i] > RF6052_MAX_TX_PWR)
+ cck[i] = RF6052_MAX_TX_PWR;
+ if (ofdm[i] > RF6052_MAX_TX_PWR)
+ ofdm[i] = RF6052_MAX_TX_PWR;
+ }
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_AGC_A_CCK1_MCS32);
+ val32 &= 0xffff00ff;
+ val32 |= (cck[0] << 8);
+ rtl8xxxu_write32(priv, REG_TX_AGC_A_CCK1_MCS32, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11);
+ val32 &= 0xff;
+ val32 |= ((cck[0] << 8) | (cck[0] << 16) | (cck[0] << 24));
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11);
+ val32 &= 0xffffff00;
+ val32 |= cck[1];
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK1_55_MCS32);
+ val32 &= 0xff;
+ val32 |= ((cck[1] << 8) | (cck[1] << 16) | (cck[1] << 24));
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK1_55_MCS32, val32);
+
+ ofdm_a = ofdmbase[0] | ofdmbase[0] << 8 |
+ ofdmbase[0] << 16 | ofdmbase[0] << 24;
+ ofdm_b = ofdmbase[1] | ofdmbase[1] << 8 |
+ ofdmbase[1] << 16 | ofdmbase[1] << 24;
+ rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE18_06, ofdm_a);
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_RATE18_06, ofdm_b);
+
+ rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE54_24, ofdm_a);
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_RATE54_24, ofdm_b);
+
+ mcs_a = mcsbase[0] | mcsbase[0] << 8 |
+ mcsbase[0] << 16 | mcsbase[0] << 24;
+ mcs_b = mcsbase[1] | mcsbase[1] << 8 |
+ mcsbase[1] << 16 | mcsbase[1] << 24;
+
+ rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS03_MCS00, mcs_a);
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS03_MCS00, mcs_b);
+
+ rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS07_MCS04, mcs_a);
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS07_MCS04, mcs_b);
+
+ rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS11_MCS08, mcs_a);
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS11_MCS08, mcs_b);
+
+ rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12, mcs_a);
+ for (i = 0; i < 3; i++) {
+ if (i != 2)
+ val8 = (mcsbase[0] > 8) ? (mcsbase[0] - 8) : 0;
+ else
+ val8 = (mcsbase[0] > 6) ? (mcsbase[0] - 6) : 0;
+ rtl8xxxu_write8(priv, REG_OFDM0_XC_TX_IQ_IMBALANCE + i, val8);
+ }
+ rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS15_MCS12, mcs_b);
+ for (i = 0; i < 3; i++) {
+ if (i != 2)
+ val8 = (mcsbase[1] > 8) ? (mcsbase[1] - 8) : 0;
+ else
+ val8 = (mcsbase[1] > 6) ? (mcsbase[1] - 6) : 0;
+ rtl8xxxu_write8(priv, REG_OFDM0_XD_TX_IQ_IMBALANCE + i, val8);
+ }
+}
+
+static void rtl8xxxu_set_linktype(struct rtl8xxxu_priv *priv,
+ enum nl80211_iftype linktype)
+{
+ u16 val8;
+
+ val8 = rtl8xxxu_read16(priv, REG_MSR);
+ val8 &= ~MSR_LINKTYPE_MASK;
+
+ switch (linktype) {
+ case NL80211_IFTYPE_UNSPECIFIED:
+ val8 |= MSR_LINKTYPE_NONE;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ val8 |= MSR_LINKTYPE_ADHOC;
+ break;
+ case NL80211_IFTYPE_STATION:
+ val8 |= MSR_LINKTYPE_STATION;
+ break;
+ case NL80211_IFTYPE_AP:
+ val8 |= MSR_LINKTYPE_AP;
+ break;
+ default:
+ goto out;
+ }
+
+ rtl8xxxu_write8(priv, REG_MSR, val8);
+out:
+ return;
+}
+
+static void
+rtl8xxxu_set_retry(struct rtl8xxxu_priv *priv, u16 short_retry, u16 long_retry)
+{
+ u16 val16;
+
+ val16 = ((short_retry << RETRY_LIMIT_SHORT_SHIFT) &
+ RETRY_LIMIT_SHORT_MASK) |
+ ((long_retry << RETRY_LIMIT_LONG_SHIFT) &
+ RETRY_LIMIT_LONG_MASK);
+
+ rtl8xxxu_write16(priv, REG_RETRY_LIMIT, val16);
+}
+
+static void
+rtl8xxxu_set_spec_sifs(struct rtl8xxxu_priv *priv, u16 cck, u16 ofdm)
+{
+ u16 val16;
+
+ val16 = ((cck << SPEC_SIFS_CCK_SHIFT) & SPEC_SIFS_CCK_MASK) |
+ ((ofdm << SPEC_SIFS_OFDM_SHIFT) & SPEC_SIFS_OFDM_MASK);
+
+ rtl8xxxu_write16(priv, REG_SPEC_SIFS, val16);
+}
+
+static void rtl8xxxu_print_chipinfo(struct rtl8xxxu_priv *priv)
+{
+ struct device *dev = &priv->udev->dev;
+ char *cut;
+
+ switch (priv->chip_cut) {
+ case 0:
+ cut = "A";
+ break;
+ case 1:
+ cut = "B";
+ break;
+ default:
+ cut = "unknown";
+ }
+
+ dev_info(dev,
+ "RTL%s rev %s (%s) %iT%iR, TX queues %i, WiFi=%i, BT=%i, GPS=%i, HI PA=%i\n",
+ priv->chip_name, cut, priv->vendor_umc ? "UMC" : "TSMC",
+ priv->tx_paths, priv->rx_paths, priv->ep_tx_count,
+ priv->has_wifi, priv->has_bluetooth, priv->has_gps,
+ priv->hi_pa);
+
+ dev_info(dev, "RTL%s MAC: %pM\n", priv->chip_name, priv->mac_addr);
+}
+
+static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+{
+ struct device *dev = &priv->udev->dev;
+ u32 val32, bonding;
+ u16 val16;
+
+ val32 = rtl8xxxu_read32(priv, REG_SYS_CFG);
+ priv->chip_cut = (val32 & SYS_CFG_CHIP_VERSION_MASK) >>
+ SYS_CFG_CHIP_VERSION_SHIFT;
+ if (val32 & SYS_CFG_TRP_VAUX_EN) {
+ dev_info(dev, "Unsupported test chip\n");
+ return -ENOTSUPP;
+ }
+
+ if (val32 & SYS_CFG_BT_FUNC) {
+ sprintf(priv->chip_name, "8723AU");
+ priv->rf_paths = 1;
+ priv->rx_paths = 1;
+ priv->tx_paths = 1;
+ priv->rtlchip = 0x8723a;
+
+ val32 = rtl8xxxu_read32(priv, REG_MULTI_FUNC_CTRL);
+ if (val32 & MULTI_WIFI_FUNC_EN)
+ priv->has_wifi = 1;
+ if (val32 & MULTI_BT_FUNC_EN)
+ priv->has_bluetooth = 1;
+ if (val32 & MULTI_GPS_FUNC_EN)
+ priv->has_gps = 1;
+ } else if (val32 & SYS_CFG_TYPE_ID) {
+ bonding = rtl8xxxu_read32(priv, REG_HPON_FSM);
+ bonding &= HPON_FSM_BONDING_MASK;
+ if (bonding == HPON_FSM_BONDING_1T2R) {
+ sprintf(priv->chip_name, "8191CU");
+ priv->rf_paths = 2;
+ priv->rx_paths = 2;
+ priv->tx_paths = 1;
+ priv->rtlchip = 0x8191c;
+ } else {
+ sprintf(priv->chip_name, "8192CU");
+ priv->rf_paths = 2;
+ priv->rx_paths = 2;
+ priv->tx_paths = 2;
+ priv->rtlchip = 0x8192c;
+ }
+ priv->has_wifi = 1;
+ } else {
+ sprintf(priv->chip_name, "8188CU");
+ priv->rf_paths = 1;
+ priv->rx_paths = 1;
+ priv->tx_paths = 1;
+ priv->rtlchip = 0x8188c;
+ priv->has_wifi = 1;
+ }
+
+ if (val32 & SYS_CFG_VENDOR_ID)
+ priv->vendor_umc = 1;
+
+ val32 = rtl8xxxu_read32(priv, REG_GPIO_OUTSTS);
+ priv->rom_rev = (val32 & GPIO_RF_RL_ID) >> 28;
+
+ val16 = rtl8xxxu_read16(priv, REG_NORMAL_SIE_EP_TX);
+ if (val16 & NORMAL_SIE_EP_TX_HIGH_MASK) {
+ priv->ep_tx_high_queue = 1;
+ priv->ep_tx_count++;
+ }
+
+ if (val16 & NORMAL_SIE_EP_TX_NORMAL_MASK) {
+ priv->ep_tx_normal_queue = 1;
+ priv->ep_tx_count++;
+ }
+
+ if (val16 & NORMAL_SIE_EP_TX_LOW_MASK) {
+ priv->ep_tx_low_queue = 1;
+ priv->ep_tx_count++;
+ }
+
+ /*
+ * Fallback for devices that do not provide REG_NORMAL_SIE_EP_TX
+ */
+ if (!priv->ep_tx_count) {
+ switch (priv->nr_out_eps) {
+ case 3:
+ priv->ep_tx_low_queue = 1;
+ priv->ep_tx_count++;
+ case 2:
+ priv->ep_tx_normal_queue = 1;
+ priv->ep_tx_count++;
+ case 1:
+ priv->ep_tx_high_queue = 1;
+ priv->ep_tx_count++;
+ break;
+ default:
+ dev_info(dev, "Unsupported USB TX end-points\n");
+ return -ENOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
+static int rtl8723au_parse_efuse(struct rtl8xxxu_priv *priv)
+{
+ if (priv->efuse_wifi.efuse8723.rtl_id != cpu_to_le16(0x8129))
+ return -EINVAL;
+
+ ether_addr_copy(priv->mac_addr, priv->efuse_wifi.efuse8723.mac_addr);
+
+ memcpy(priv->cck_tx_power_index_A,
+ priv->efuse_wifi.efuse8723.cck_tx_power_index_A,
+ sizeof(priv->cck_tx_power_index_A));
+ memcpy(priv->cck_tx_power_index_B,
+ priv->efuse_wifi.efuse8723.cck_tx_power_index_B,
+ sizeof(priv->cck_tx_power_index_B));
+
+ memcpy(priv->ht40_1s_tx_power_index_A,
+ priv->efuse_wifi.efuse8723.ht40_1s_tx_power_index_A,
+ sizeof(priv->ht40_1s_tx_power_index_A));
+ memcpy(priv->ht40_1s_tx_power_index_B,
+ priv->efuse_wifi.efuse8723.ht40_1s_tx_power_index_B,
+ sizeof(priv->ht40_1s_tx_power_index_B));
+
+ memcpy(priv->ht20_tx_power_index_diff,
+ priv->efuse_wifi.efuse8723.ht20_tx_power_index_diff,
+ sizeof(priv->ht20_tx_power_index_diff));
+ memcpy(priv->ofdm_tx_power_index_diff,
+ priv->efuse_wifi.efuse8723.ofdm_tx_power_index_diff,
+ sizeof(priv->ofdm_tx_power_index_diff));
+
+ memcpy(priv->ht40_max_power_offset,
+ priv->efuse_wifi.efuse8723.ht40_max_power_offset,
+ sizeof(priv->ht40_max_power_offset));
+ memcpy(priv->ht20_max_power_offset,
+ priv->efuse_wifi.efuse8723.ht20_max_power_offset,
+ sizeof(priv->ht20_max_power_offset));
+
+ dev_info(&priv->udev->dev, "Vendor: %.7s\n",
+ priv->efuse_wifi.efuse8723.vendor_name);
+ dev_info(&priv->udev->dev, "Product: %.41s\n",
+ priv->efuse_wifi.efuse8723.device_name);
+ return 0;
+}
+
+#ifdef CONFIG_RTL8XXXU_UNTESTED
+
+static int rtl8192cu_parse_efuse(struct rtl8xxxu_priv *priv)
+{
+ int i;
+
+ if (priv->efuse_wifi.efuse8192.rtl_id != cpu_to_le16(0x8129))
+ return -EINVAL;
+
+ ether_addr_copy(priv->mac_addr, priv->efuse_wifi.efuse8192.mac_addr);
+
+ memcpy(priv->cck_tx_power_index_A,
+ priv->efuse_wifi.efuse8192.cck_tx_power_index_A,
+ sizeof(priv->cck_tx_power_index_A));
+ memcpy(priv->cck_tx_power_index_B,
+ priv->efuse_wifi.efuse8192.cck_tx_power_index_B,
+ sizeof(priv->cck_tx_power_index_B));
+
+ memcpy(priv->ht40_1s_tx_power_index_A,
+ priv->efuse_wifi.efuse8192.ht40_1s_tx_power_index_A,
+ sizeof(priv->ht40_1s_tx_power_index_A));
+ memcpy(priv->ht40_1s_tx_power_index_B,
+ priv->efuse_wifi.efuse8192.ht40_1s_tx_power_index_B,
+ sizeof(priv->ht40_1s_tx_power_index_B));
+ memcpy(priv->ht40_2s_tx_power_index_diff,
+ priv->efuse_wifi.efuse8192.ht40_2s_tx_power_index_diff,
+ sizeof(priv->ht40_2s_tx_power_index_diff));
+
+ memcpy(priv->ht20_tx_power_index_diff,
+ priv->efuse_wifi.efuse8192.ht20_tx_power_index_diff,
+ sizeof(priv->ht20_tx_power_index_diff));
+ memcpy(priv->ofdm_tx_power_index_diff,
+ priv->efuse_wifi.efuse8192.ofdm_tx_power_index_diff,
+ sizeof(priv->ofdm_tx_power_index_diff));
+
+ memcpy(priv->ht40_max_power_offset,
+ priv->efuse_wifi.efuse8192.ht40_max_power_offset,
+ sizeof(priv->ht40_max_power_offset));
+ memcpy(priv->ht20_max_power_offset,
+ priv->efuse_wifi.efuse8192.ht20_max_power_offset,
+ sizeof(priv->ht20_max_power_offset));
+
+ dev_info(&priv->udev->dev, "Vendor: %.7s\n",
+ priv->efuse_wifi.efuse8192.vendor_name);
+ dev_info(&priv->udev->dev, "Product: %.20s\n",
+ priv->efuse_wifi.efuse8192.device_name);
+
+ if (priv->efuse_wifi.efuse8192.rf_regulatory & 0x20) {
+ sprintf(priv->chip_name, "8188RU");
+ priv->hi_pa = 1;
+ }
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) {
+ unsigned char *raw = priv->efuse_wifi.raw;
+
+ dev_info(&priv->udev->dev,
+ "%s: dumping efuse (0x%02zx bytes):\n",
+ __func__, sizeof(struct rtl8192cu_efuse));
+ for (i = 0; i < sizeof(struct rtl8192cu_efuse); i += 8) {
+ dev_info(&priv->udev->dev, "%02x: "
+ "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+ raw[i], raw[i + 1], raw[i + 2],
+ raw[i + 3], raw[i + 4], raw[i + 5],
+ raw[i + 6], raw[i + 7]);
+ }
+ }
+ return 0;
+}
+
+#endif
+
+static int
+rtl8xxxu_read_efuse8(struct rtl8xxxu_priv *priv, u16 offset, u8 *data)
+{
+ int i;
+ u8 val8;
+ u32 val32;
+
+ /* Write Address */
+ rtl8xxxu_write8(priv, REG_EFUSE_CTRL + 1, offset & 0xff);
+ val8 = rtl8xxxu_read8(priv, REG_EFUSE_CTRL + 2);
+ val8 &= 0xfc;
+ val8 |= (offset >> 8) & 0x03;
+ rtl8xxxu_write8(priv, REG_EFUSE_CTRL + 2, val8);
+
+ val8 = rtl8xxxu_read8(priv, REG_EFUSE_CTRL + 3);
+ rtl8xxxu_write8(priv, REG_EFUSE_CTRL + 3, val8 & 0x7f);
+
+ /* Poll for data read */
+ val32 = rtl8xxxu_read32(priv, REG_EFUSE_CTRL);
+ for (i = 0; i < RTL8XXXU_MAX_REG_POLL; i++) {
+ val32 = rtl8xxxu_read32(priv, REG_EFUSE_CTRL);
+ if (val32 & BIT(31))
+ break;
+ }
+
+ if (i == RTL8XXXU_MAX_REG_POLL)
+ return -EIO;
+
+ udelay(50);
+ val32 = rtl8xxxu_read32(priv, REG_EFUSE_CTRL);
+
+ *data = val32 & 0xff;
+ return 0;
+}
+
+static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv)
+{
+ struct device *dev = &priv->udev->dev;
+ int i, ret = 0;
+ u8 val8, word_mask, header, extheader;
+ u16 val16, efuse_addr, offset;
+ u32 val32;
+
+ val16 = rtl8xxxu_read16(priv, REG_9346CR);
+ if (val16 & EEPROM_ENABLE)
+ priv->has_eeprom = 1;
+ if (val16 & EEPROM_BOOT)
+ priv->boot_eeprom = 1;
+
+ val32 = rtl8xxxu_read32(priv, REG_EFUSE_TEST);
+ val32 = (val32 & ~EFUSE_SELECT_MASK) | EFUSE_WIFI_SELECT;
+ rtl8xxxu_write32(priv, REG_EFUSE_TEST, val32);
+
+ dev_dbg(dev, "Booting from %s\n",
+ priv->boot_eeprom ? "EEPROM" : "EFUSE");
+
+ rtl8xxxu_write8(priv, REG_EFUSE_ACCESS, EFUSE_ACCESS_ENABLE);
+
+ /* 1.2V Power: From VDDON with Power Cut(0x0000[15]), default valid */
+ val16 = rtl8xxxu_read16(priv, REG_SYS_ISO_CTRL);
+ if (!(val16 & SYS_ISO_PWC_EV12V)) {
+ val16 |= SYS_ISO_PWC_EV12V;
+ rtl8xxxu_write16(priv, REG_SYS_ISO_CTRL, val16);
+ }
+ /* Reset: 0x0000[28], default valid */
+ val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
+ if (!(val16 & SYS_FUNC_ELDR)) {
+ val16 |= SYS_FUNC_ELDR;
+ rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
+ }
+
+ /*
+ * Clock: Gated(0x0008[5]) 8M(0x0008[1]) clock from ANA, default valid
+ */
+ val16 = rtl8xxxu_read16(priv, REG_SYS_CLKR);
+ if (!(val16 & SYS_CLK_LOADER_ENABLE) || !(val16 & SYS_CLK_ANA8M)) {
+ val16 |= (SYS_CLK_LOADER_ENABLE | SYS_CLK_ANA8M);
+ rtl8xxxu_write16(priv, REG_SYS_CLKR, val16);
+ }
+
+ /* Default value is 0xff */
+ memset(priv->efuse_wifi.raw, 0xff, EFUSE_MAP_LEN_8723A);
+
+ efuse_addr = 0;
+ while (efuse_addr < EFUSE_REAL_CONTENT_LEN_8723A) {
+ ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &header);
+ if (ret || header == 0xff)
+ goto exit;
+
+ if ((header & 0x1f) == 0x0f) { /* extended header */
+ offset = (header & 0xe0) >> 5;
+
+ ret = rtl8xxxu_read_efuse8(priv, efuse_addr++,
+ &extheader);
+ if (ret)
+ goto exit;
+ /* All words disabled */
+ if ((extheader & 0x0f) == 0x0f)
+ continue;
+
+ offset |= ((extheader & 0xf0) >> 1);
+ word_mask = extheader & 0x0f;
+ } else {
+ offset = (header >> 4) & 0x0f;
+ word_mask = header & 0x0f;
+ }
+
+ if (offset < EFUSE_MAX_SECTION_8723A) {
+ u16 map_addr;
+ /* Get word enable value from PG header */
+
+ /* We have 8 bits to indicate validity */
+ map_addr = offset * 8;
+ if (map_addr >= EFUSE_MAP_LEN_8723A) {
+ dev_warn(dev, "%s: Illegal map_addr (%04x), "
+ "efuse corrupt!\n",
+ __func__, map_addr);
+ ret = -EINVAL;
+ goto exit;
+ }
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ /* Check word enable condition in the section */
+ if (!(word_mask & BIT(i))) {
+ ret = rtl8xxxu_read_efuse8(priv,
+ efuse_addr++,
+ &val8);
+ if (ret)
+ goto exit;
+ priv->efuse_wifi.raw[map_addr++] = val8;
+
+ ret = rtl8xxxu_read_efuse8(priv,
+ efuse_addr++,
+ &val8);
+ if (ret)
+ goto exit;
+ priv->efuse_wifi.raw[map_addr++] = val8;
+ } else
+ map_addr += 2;
+ }
+ } else {
+ dev_warn(dev,
+ "%s: Illegal offset (%04x), efuse corrupt!\n",
+ __func__, offset);
+ ret = -EINVAL;
+ goto exit;
+ }
+ }
+
+exit:
+ rtl8xxxu_write8(priv, REG_EFUSE_ACCESS, EFUSE_ACCESS_DISABLE);
+
+ return ret;
+}
+
+static int rtl8xxxu_start_firmware(struct rtl8xxxu_priv *priv)
+{
+ struct device *dev = &priv->udev->dev;
+ int ret = 0, i;
+ u32 val32;
+
+ /* Poll checksum report */
+ for (i = 0; i < RTL8XXXU_FIRMWARE_POLL_MAX; i++) {
+ val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL);
+ if (val32 & MCU_FW_DL_CSUM_REPORT)
+ break;
+ }
+
+ if (i == RTL8XXXU_FIRMWARE_POLL_MAX) {
+ dev_warn(dev, "Firmware checksum poll timed out\n");
+ ret = -EAGAIN;
+ goto exit;
+ }
+
+ val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL);
+ val32 |= MCU_FW_DL_READY;
+ val32 &= ~MCU_WINT_INIT_READY;
+ rtl8xxxu_write32(priv, REG_MCU_FW_DL, val32);
+
+ /* Wait for firmware to become ready */
+ for (i = 0; i < RTL8XXXU_FIRMWARE_POLL_MAX; i++) {
+ val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL);
+ if (val32 & MCU_WINT_INIT_READY)
+ break;
+
+ udelay(100);
+ }
+
+ if (i == RTL8XXXU_FIRMWARE_POLL_MAX) {
+ dev_warn(dev, "Firmware failed to start\n");
+ ret = -EAGAIN;
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
+{
+ int pages, remainder, i, ret;
+ u8 val8;
+ u16 val16;
+ u32 val32;
+ u8 *fwptr;
+
+ val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC + 1);
+ val8 |= 4;
+ rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, val8);
+
+ /* 8051 enable */
+ val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
+ rtl8xxxu_write16(priv, REG_SYS_FUNC, val16 | SYS_FUNC_CPU_ENABLE);
+
+ /* MCU firmware download enable */
+ val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL);
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8 | MCU_FW_DL_ENABLE);
+
+ /* 8051 reset */
+ val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL);
+ rtl8xxxu_write32(priv, REG_MCU_FW_DL, val32 & ~BIT(19));
+
+ /* Reset firmware download checksum */
+ val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL);
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8 | MCU_FW_DL_CSUM_REPORT);
+
+ pages = priv->fw_size / RTL_FW_PAGE_SIZE;
+ remainder = priv->fw_size % RTL_FW_PAGE_SIZE;
+
+ fwptr = priv->fw_data->data;
+
+ for (i = 0; i < pages; i++) {
+ val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL + 2) & 0xF8;
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8 | i);
+
+ ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS,
+ fwptr, RTL_FW_PAGE_SIZE);
+ if (ret != RTL_FW_PAGE_SIZE) {
+ ret = -EAGAIN;
+ goto fw_abort;
+ }
+
+ fwptr += RTL_FW_PAGE_SIZE;
+ }
+
+ if (remainder) {
+ val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL + 2) & 0xF8;
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8 | i);
+ ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS,
+ fwptr, remainder);
+ if (ret != remainder) {
+ ret = -EAGAIN;
+ goto fw_abort;
+ }
+ }
+
+ ret = 0;
+fw_abort:
+ /* MCU firmware download disable */
+ val16 = rtl8xxxu_read16(priv, REG_MCU_FW_DL);
+ rtl8xxxu_write16(priv, REG_MCU_FW_DL,
+ val16 & (~MCU_FW_DL_ENABLE & 0xff));
+
+ return ret;
+}
+
+static int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, char *fw_name)
+{
+ struct device *dev = &priv->udev->dev;
+ const struct firmware *fw;
+ int ret = 0;
+ u16 signature;
+
+ dev_info(dev, "%s: Loading firmware %s\n", DRIVER_NAME, fw_name);
+ if (request_firmware(&fw, fw_name, &priv->udev->dev)) {
+ dev_warn(dev, "request_firmware(%s) failed\n", fw_name);
+ ret = -EAGAIN;
+ goto exit;
+ }
+ if (!fw) {
+ dev_warn(dev, "Firmware data not available\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ priv->fw_data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ priv->fw_size = fw->size - sizeof(struct rtl8xxxu_firmware_header);
+
+ signature = le16_to_cpu(priv->fw_data->signature);
+ switch (signature & 0xfff0) {
+ case 0x92c0:
+ case 0x88c0:
+ case 0x2300:
+ break;
+ default:
+ ret = -EINVAL;
+ dev_warn(dev, "%s: Invalid firmware signature: 0x%04x\n",
+ __func__, signature);
+ }
+
+ dev_info(dev, "Firmware revision %i.%i (signature 0x%04x)\n",
+ le16_to_cpu(priv->fw_data->major_version),
+ priv->fw_data->minor_version, signature);
+
+exit:
+ release_firmware(fw);
+ return ret;
+}
+
+static int rtl8723au_load_firmware(struct rtl8xxxu_priv *priv)
+{
+ char *fw_name;
+ int ret;
+
+ switch (priv->chip_cut) {
+ case 0:
+ fw_name = "rtlwifi/rtl8723aufw_A.bin";
+ break;
+ case 1:
+ if (priv->enable_bluetooth)
+ fw_name = "rtlwifi/rtl8723aufw_B.bin";
+ else
+ fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = rtl8xxxu_load_firmware(priv, fw_name);
+ return ret;
+}
+
+#ifdef CONFIG_RTL8XXXU_UNTESTED
+
+static int rtl8192cu_load_firmware(struct rtl8xxxu_priv *priv)
+{
+ char *fw_name;
+ int ret;
+
+ if (!priv->vendor_umc)
+ fw_name = "rtlwifi/rtl8192cufw_TMSC.bin";
+ else if (priv->chip_cut || priv->rtlchip == 0x8192c)
+ fw_name = "rtlwifi/rtl8192cufw_B.bin";
+ else
+ fw_name = "rtlwifi/rtl8192cufw_A.bin";
+
+ ret = rtl8xxxu_load_firmware(priv, fw_name);
+
+ return ret;
+}
+
+#endif
+
+static void rtl8xxxu_firmware_self_reset(struct rtl8xxxu_priv *priv)
+{
+ u16 val16;
+ int i = 100;
+
+ /* Inform 8051 to perform reset */
+ rtl8xxxu_write8(priv, REG_HMTFR + 3, 0x20);
+
+ for (i = 100; i > 0; i--) {
+ val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
+
+ if (!(val16 & SYS_FUNC_CPU_ENABLE)) {
+ dev_dbg(&priv->udev->dev,
+ "%s: Firmware self reset success!\n", __func__);
+ break;
+ }
+ udelay(50);
+ }
+
+ if (!i) {
+ /* Force firmware reset */
+ val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
+ val16 &= ~SYS_FUNC_CPU_ENABLE;
+ rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
+ }
+}
+
+static int
+rtl8xxxu_init_mac(struct rtl8xxxu_priv *priv, struct rtl8xxxu_reg8val *array)
+{
+ int i, ret;
+ u16 reg;
+ u8 val;
+
+ for (i = 0; ; i++) {
+ reg = array[i].reg;
+ val = array[i].val;
+
+ if (reg == 0xffff && val == 0xff)
+ break;
+
+ ret = rtl8xxxu_write8(priv, reg, val);
+ if (ret != 1) {
+ dev_warn(&priv->udev->dev,
+ "Failed to initialize MAC\n");
+ return -EAGAIN;
+ }
+ }
+
+ rtl8xxxu_write8(priv, REG_MAX_AGGR_NUM, 0x0a);
+
+ return 0;
+}
+
+static int rtl8xxxu_init_phy_regs(struct rtl8xxxu_priv *priv,
+ struct rtl8xxxu_reg32val *array)
+{
+ int i, ret;
+ u16 reg;
+ u32 val;
+
+ for (i = 0; ; i++) {
+ reg = array[i].reg;
+ val = array[i].val;
+
+ if (reg == 0xffff && val == 0xffffffff)
+ break;
+
+ ret = rtl8xxxu_write32(priv, reg, val);
+ if (ret != sizeof(val)) {
+ dev_warn(&priv->udev->dev,
+ "Failed to initialize PHY\n");
+ return -EAGAIN;
+ }
+ udelay(1);
+ }
+
+ return 0;
+}
+
+/*
+ * Most of this is black magic retrieved from the old rtl8723au driver
+ */
+static int rtl8xxxu_init_phy_bb(struct rtl8xxxu_priv *priv)
+{
+ u8 val8, ldoa15, ldov12d, lpldo, ldohci12;
+ u32 val32;
+
+ /*
+ * Todo: The vendor driver maintains a table of PHY register
+ * addresses, which is initialized here. Do we need this?
+ */
+
+ val8 = rtl8xxxu_read8(priv, REG_AFE_PLL_CTRL);
+ udelay(2);
+ val8 |= AFE_PLL_320_ENABLE;
+ rtl8xxxu_write8(priv, REG_AFE_PLL_CTRL, val8);
+ udelay(2);
+
+ rtl8xxxu_write8(priv, REG_AFE_PLL_CTRL + 1, 0xff);
+ udelay(2);
+
+ val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC);
+ val8 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB;
+ rtl8xxxu_write8(priv, REG_SYS_FUNC, val8);
+
+ /* AFE_XTAL_RF_GATE (bit 14) if addressing as 32 bit register */
+ val32 = rtl8xxxu_read32(priv, REG_AFE_XTAL_CTRL);
+ val32 &= ~AFE_XTAL_RF_GATE;
+ if (priv->has_bluetooth)
+ val32 &= ~AFE_XTAL_BT_GATE;
+ rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, val32);
+
+ /* 6. 0x1f[7:0] = 0x07 */
+ val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB;
+ rtl8xxxu_write8(priv, REG_RF_CTRL, val8);
+
+ if (priv->hi_pa)
+ rtl8xxxu_init_phy_regs(priv, rtl8188ru_phy_1t_highpa_table);
+ else if (priv->tx_paths == 2)
+ rtl8xxxu_init_phy_regs(priv, rtl8192cu_phy_2t_init_table);
+ else
+ rtl8xxxu_init_phy_regs(priv, rtl8723a_phy_1t_init_table);
+
+
+ if (priv->rtlchip == 0x8188c && priv->hi_pa &&
+ priv->vendor_umc && priv->chip_cut == 1)
+ rtl8xxxu_write8(priv, REG_OFDM0_AGC_PARM1 + 2, 0x50);
+
+ if (priv->tx_paths == 1 && priv->rx_paths == 2) {
+ /*
+ * For 1T2R boards, patch the registers.
+ *
+ * It looks like 8191/2 1T2R boards use path B for TX
+ */
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_TX_INFO);
+ val32 &= ~(BIT(0) | BIT(1));
+ val32 |= BIT(1);
+ rtl8xxxu_write32(priv, REG_FPGA0_TX_INFO, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA1_TX_INFO);
+ val32 &= ~0x300033;
+ val32 |= 0x200022;
+ rtl8xxxu_write32(priv, REG_FPGA1_TX_INFO, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING);
+ val32 &= 0xff000000;
+ val32 |= 0x45000000;
+ rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE);
+ val32 &= ~(OFDM_RF_PATH_RX_MASK | OFDM_RF_PATH_TX_MASK);
+ val32 |= (OFDM_RF_PATH_RX_A | OFDM_RF_PATH_RX_B |
+ OFDM_RF_PATH_TX_B);
+ rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_AGC_PARM1);
+ val32 &= ~(BIT(4) | BIT(5));
+ val32 |= BIT(4);
+ rtl8xxxu_write32(priv, REG_OFDM0_AGC_PARM1, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_CCK_RFON);
+ val32 &= ~(BIT(27) | BIT(26));
+ val32 |= BIT(27);
+ rtl8xxxu_write32(priv, REG_TX_CCK_RFON, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_CCK_BBON);
+ val32 &= ~(BIT(27) | BIT(26));
+ val32 |= BIT(27);
+ rtl8xxxu_write32(priv, REG_TX_CCK_BBON, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_OFDM_RFON);
+ val32 &= ~(BIT(27) | BIT(26));
+ val32 |= BIT(27);
+ rtl8xxxu_write32(priv, REG_TX_OFDM_RFON, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_OFDM_BBON);
+ val32 &= ~(BIT(27) | BIT(26));
+ val32 |= BIT(27);
+ rtl8xxxu_write32(priv, REG_TX_OFDM_BBON, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_TX_TO_TX);
+ val32 &= ~(BIT(27) | BIT(26));
+ val32 |= BIT(27);
+ rtl8xxxu_write32(priv, REG_TX_TO_TX, val32);
+ }
+
+ if (priv->hi_pa)
+ rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_highpa_table);
+ else
+ rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_standard_table);
+
+ if (priv->rtlchip == 0x8723a &&
+ priv->efuse_wifi.efuse8723.version >= 0x01) {
+ val32 = rtl8xxxu_read32(priv, REG_MAC_PHY_CTRL);
+
+ val8 = priv->efuse_wifi.efuse8723.xtal_k & 0x3f;
+ val32 &= 0xff000fff;
+ val32 |= ((val8 | (val8 << 6)) << 12);
+
+ rtl8xxxu_write32(priv, REG_MAC_PHY_CTRL, val32);
+ }
+
+ ldoa15 = LDOA15_ENABLE | LDOA15_OBUF;
+ ldov12d = LDOV12D_ENABLE | BIT(2) | (2 << LDOV12D_VADJ_SHIFT);
+ ldohci12 = 0x57;
+ lpldo = 1;
+ val32 = (lpldo << 24) | (ldohci12 << 16) | (ldov12d << 8) | ldoa15;
+
+ rtl8xxxu_write32(priv, REG_LDOA15_CTRL, val32);
+
+ return 0;
+}
+
+static int rtl8xxxu_init_rf_regs(struct rtl8xxxu_priv *priv,
+ struct rtl8xxxu_rfregval *array,
+ enum rtl8xxxu_rfpath path)
+{
+ int i, ret;
+ u8 reg;
+ u32 val;
+
+ for (i = 0; ; i++) {
+ reg = array[i].reg;
+ val = array[i].val;
+
+ if (reg == 0xff && val == 0xffffffff)
+ break;
+
+ switch (reg) {
+ case 0xfe:
+ msleep(50);
+ continue;
+ case 0xfd:
+ mdelay(5);
+ continue;
+ case 0xfc:
+ mdelay(1);
+ continue;
+ case 0xfb:
+ udelay(50);
+ continue;
+ case 0xfa:
+ udelay(5);
+ continue;
+ case 0xf9:
+ udelay(1);
+ continue;
+ }
+
+ reg &= 0x3f;
+
+ ret = rtl8xxxu_write_rfreg(priv, path, reg, val);
+ if (ret) {
+ dev_warn(&priv->udev->dev,
+ "Failed to initialize RF\n");
+ return -EAGAIN;
+ }
+ udelay(1);
+ }
+
+ return 0;
+}
+
+static int rtl8xxxu_init_phy_rf(struct rtl8xxxu_priv *priv,
+ struct rtl8xxxu_rfregval *table,
+ enum rtl8xxxu_rfpath path)
+{
+ u32 val32;
+ u16 val16, rfsi_rfenv;
+ u16 reg_sw_ctrl, reg_int_oe, reg_hssi_parm2;
+
+ switch (path) {
+ case RF_A:
+ reg_sw_ctrl = REG_FPGA0_XA_RF_SW_CTRL;
+ reg_int_oe = REG_FPGA0_XA_RF_INT_OE;
+ reg_hssi_parm2 = REG_FPGA0_XA_HSSI_PARM2;
+ break;
+ case RF_B:
+ reg_sw_ctrl = REG_FPGA0_XB_RF_SW_CTRL;
+ reg_int_oe = REG_FPGA0_XB_RF_INT_OE;
+ reg_hssi_parm2 = REG_FPGA0_XB_HSSI_PARM2;
+ break;
+ default:
+ dev_err(&priv->udev->dev, "%s:Unsupported RF path %c\n",
+ __func__, path + 'A');
+ return -EINVAL;
+ }
+ /* For path B, use XB */
+ rfsi_rfenv = rtl8xxxu_read16(priv, reg_sw_ctrl);
+ rfsi_rfenv &= FPGA0_RF_RFENV;
+
+ /*
+ * These two we might be able to optimize into one
+ */
+ val32 = rtl8xxxu_read32(priv, reg_int_oe);
+ val32 |= BIT(20); /* 0x10 << 16 */
+ rtl8xxxu_write32(priv, reg_int_oe, val32);
+ udelay(1);
+
+ val32 = rtl8xxxu_read32(priv, reg_int_oe);
+ val32 |= BIT(4);
+ rtl8xxxu_write32(priv, reg_int_oe, val32);
+ udelay(1);
+
+ /*
+ * These two we might be able to optimize into one
+ */
+ val32 = rtl8xxxu_read32(priv, reg_hssi_parm2);
+ val32 &= ~FPGA0_HSSI_3WIRE_ADDR_LEN;
+ rtl8xxxu_write32(priv, reg_hssi_parm2, val32);
+ udelay(1);
+
+ val32 = rtl8xxxu_read32(priv, reg_hssi_parm2);
+ val32 &= ~FPGA0_HSSI_3WIRE_DATA_LEN;
+ rtl8xxxu_write32(priv, reg_hssi_parm2, val32);
+ udelay(1);
+
+ rtl8xxxu_init_rf_regs(priv, table, path);
+
+ /* For path B, use XB */
+ val16 = rtl8xxxu_read16(priv, reg_sw_ctrl);
+ val16 &= ~FPGA0_RF_RFENV;
+ val16 |= rfsi_rfenv;
+ rtl8xxxu_write16(priv, reg_sw_ctrl, val16);
+
+ return 0;
+}
+
+static int rtl8xxxu_llt_write(struct rtl8xxxu_priv *priv, u8 address, u8 data)
+{
+ int ret = -EBUSY;
+ int count = 0;
+ u32 value;
+
+ value = LLT_OP_WRITE | address << 8 | data;
+
+ rtl8xxxu_write32(priv, REG_LLT_INIT, value);
+
+ do {
+ value = rtl8xxxu_read32(priv, REG_LLT_INIT);
+ if ((value & LLT_OP_MASK) == LLT_OP_INACTIVE) {
+ ret = 0;
+ break;
+ }
+ } while (count++ < 20);
+
+ return ret;
+}
+
+static int rtl8xxxu_init_llt_table(struct rtl8xxxu_priv *priv, u8 last_tx_page)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < last_tx_page; i++) {
+ ret = rtl8xxxu_llt_write(priv, i, i + 1);
+ if (ret)
+ goto exit;
+ }
+
+ ret = rtl8xxxu_llt_write(priv, last_tx_page, 0xff);
+ if (ret)
+ goto exit;
+
+ /* Mark remaining pages as a ring buffer */
+ for (i = last_tx_page + 1; i < 0xff; i++) {
+ ret = rtl8xxxu_llt_write(priv, i, (i + 1));
+ if (ret)
+ goto exit;
+ }
+
+ /* Let last entry point to the start entry of ring buffer */
+ ret = rtl8xxxu_llt_write(priv, 0xff, last_tx_page + 1);
+ if (ret)
+ goto exit;
+
+exit:
+ return ret;
+}
+
+static int rtl8xxxu_init_queue_priority(struct rtl8xxxu_priv *priv)
+{
+ u16 val16, hi, lo;
+ u16 hiq, mgq, bkq, beq, viq, voq;
+ int hip, mgp, bkp, bep, vip, vop;
+ int ret = 0;
+
+ switch (priv->ep_tx_count) {
+ case 1:
+ if (priv->ep_tx_high_queue) {
+ hi = TRXDMA_QUEUE_HIGH;
+ } else if (priv->ep_tx_low_queue) {
+ hi = TRXDMA_QUEUE_LOW;
+ } else if (priv->ep_tx_normal_queue) {
+ hi = TRXDMA_QUEUE_NORMAL;
+ } else {
+ hi = 0;
+ ret = -EINVAL;
+ }
+
+ hiq = hi;
+ mgq = hi;
+ bkq = hi;
+ beq = hi;
+ viq = hi;
+ voq = hi;
+
+ hip = 0;
+ mgp = 0;
+ bkp = 0;
+ bep = 0;
+ vip = 0;
+ vop = 0;
+ break;
+ case 2:
+ if (priv->ep_tx_high_queue && priv->ep_tx_low_queue) {
+ hi = TRXDMA_QUEUE_HIGH;
+ lo = TRXDMA_QUEUE_LOW;
+ } else if (priv->ep_tx_normal_queue && priv->ep_tx_low_queue) {
+ hi = TRXDMA_QUEUE_NORMAL;
+ lo = TRXDMA_QUEUE_LOW;
+ } else if (priv->ep_tx_high_queue && priv->ep_tx_normal_queue) {
+ hi = TRXDMA_QUEUE_HIGH;
+ lo = TRXDMA_QUEUE_NORMAL;
+ } else {
+ ret = -EINVAL;
+ hi = 0;
+ lo = 0;
+ }
+
+ hiq = hi;
+ mgq = hi;
+ bkq = lo;
+ beq = lo;
+ viq = hi;
+ voq = hi;
+
+ hip = 0;
+ mgp = 0;
+ bkp = 1;
+ bep = 1;
+ vip = 0;
+ vop = 0;
+ break;
+ case 3:
+ beq = TRXDMA_QUEUE_LOW;
+ bkq = TRXDMA_QUEUE_LOW;
+ viq = TRXDMA_QUEUE_NORMAL;
+ voq = TRXDMA_QUEUE_HIGH;
+ mgq = TRXDMA_QUEUE_HIGH;
+ hiq = TRXDMA_QUEUE_HIGH;
+
+ hip = hiq ^ 3;
+ mgp = mgq ^ 3;
+ bkp = bkq ^ 3;
+ bep = beq ^ 3;
+ vip = viq ^ 3;
+ vop = viq ^ 3;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ /*
+ * None of the vendor drivers are configuring the beacon
+ * queue here .... why?
+ */
+ if (!ret) {
+ val16 = rtl8xxxu_read16(priv, REG_TRXDMA_CTRL);
+ val16 &= 0x7;
+ val16 |= (voq << TRXDMA_CTRL_VOQ_SHIFT) |
+ (viq << TRXDMA_CTRL_VIQ_SHIFT) |
+ (beq << TRXDMA_CTRL_BEQ_SHIFT) |
+ (bkq << TRXDMA_CTRL_BKQ_SHIFT) |
+ (mgq << TRXDMA_CTRL_MGQ_SHIFT) |
+ (hiq << TRXDMA_CTRL_HIQ_SHIFT);
+ rtl8xxxu_write16(priv, REG_TRXDMA_CTRL, val16);
+
+ priv->pipe_out[TXDESC_QUEUE_VO] =
+ usb_sndbulkpipe(priv->udev, priv->out_ep[vop]);
+ priv->pipe_out[TXDESC_QUEUE_VI] =
+ usb_sndbulkpipe(priv->udev, priv->out_ep[vip]);
+ priv->pipe_out[TXDESC_QUEUE_BE] =
+ usb_sndbulkpipe(priv->udev, priv->out_ep[bep]);
+ priv->pipe_out[TXDESC_QUEUE_BK] =
+ usb_sndbulkpipe(priv->udev, priv->out_ep[bkp]);
+ priv->pipe_out[TXDESC_QUEUE_BEACON] =
+ usb_sndbulkpipe(priv->udev, priv->out_ep[0]);
+ priv->pipe_out[TXDESC_QUEUE_MGNT] =
+ usb_sndbulkpipe(priv->udev, priv->out_ep[mgp]);
+ priv->pipe_out[TXDESC_QUEUE_HIGH] =
+ usb_sndbulkpipe(priv->udev, priv->out_ep[hip]);
+ priv->pipe_out[TXDESC_QUEUE_CMD] =
+ usb_sndbulkpipe(priv->udev, priv->out_ep[0]);
+ }
+
+ return ret;
+}
+
+static void rtl8xxxu_fill_iqk_matrix_a(struct rtl8xxxu_priv *priv,
+ bool iqk_ok, int result[][8],
+ int candidate, bool tx_only)
+{
+ u32 oldval, x, tx0_a, reg;
+ int y, tx0_c;
+ u32 val32;
+
+ if (!iqk_ok)
+ return;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE);
+ oldval = val32 >> 22;
+
+ x = result[candidate][0];
+ if ((x & 0x00000200) != 0)
+ x = x | 0xfffffc00;
+ tx0_a = (x * oldval) >> 8;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE);
+ val32 &= ~0x3ff;
+ val32 |= tx0_a;
+ rtl8xxxu_write32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_ENERGY_CCA_THRES);
+ val32 &= ~BIT(31);
+ if ((x * oldval >> 7) & 0x1)
+ val32 |= BIT(31);
+ rtl8xxxu_write32(priv, REG_OFDM0_ENERGY_CCA_THRES, val32);
+
+ y = result[candidate][1];
+ if ((y & 0x00000200) != 0)
+ y = y | 0xfffffc00;
+ tx0_c = (y * oldval) >> 8;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XC_TX_AFE);
+ val32 &= ~0xf0000000;
+ val32 |= (((tx0_c & 0x3c0) >> 6) << 28);
+ rtl8xxxu_write32(priv, REG_OFDM0_XC_TX_AFE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE);
+ val32 &= ~0x003f0000;
+ val32 |= ((tx0_c & 0x3f) << 16);
+ rtl8xxxu_write32(priv, REG_OFDM0_XA_TX_IQ_IMBALANCE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_ENERGY_CCA_THRES);
+ val32 &= ~BIT(29);
+ if ((y * oldval >> 7) & 0x1)
+ val32 |= BIT(29);
+ rtl8xxxu_write32(priv, REG_OFDM0_ENERGY_CCA_THRES, val32);
+
+ if (tx_only) {
+ dev_dbg(&priv->udev->dev, "%s: only TX\n", __func__);
+ return;
+ }
+
+ reg = result[candidate][2];
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_RX_IQ_IMBALANCE);
+ val32 &= ~0x3ff;
+ val32 |= (reg & 0x3ff);
+ rtl8xxxu_write32(priv, REG_OFDM0_XA_RX_IQ_IMBALANCE, val32);
+
+ reg = result[candidate][3] & 0x3F;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_RX_IQ_IMBALANCE);
+ val32 &= ~0xfc00;
+ val32 |= ((reg << 10) & 0xfc00);
+ rtl8xxxu_write32(priv, REG_OFDM0_XA_RX_IQ_IMBALANCE, val32);
+
+ reg = (result[candidate][3] >> 6) & 0xF;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_RX_IQ_EXT_ANTA);
+ val32 &= ~0xf0000000;
+ val32 |= (reg << 28);
+ rtl8xxxu_write32(priv, REG_OFDM0_RX_IQ_EXT_ANTA, val32);
+}
+
+static void rtl8xxxu_fill_iqk_matrix_b(struct rtl8xxxu_priv *priv,
+ bool iqk_ok, int result[][8],
+ int candidate, bool tx_only)
+{
+ u32 oldval, x, tx1_a, reg;
+ int y, tx1_c;
+ u32 val32;
+
+ if (!iqk_ok)
+ return;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE);
+ oldval = val32 >> 22;
+
+ x = result[candidate][4];
+ if ((x & 0x00000200) != 0)
+ x = x | 0xfffffc00;
+ tx1_a = (x * oldval) >> 8;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE);
+ val32 &= ~0x3ff;
+ val32 |= tx1_a;
+ rtl8xxxu_write32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_ENERGY_CCA_THRES);
+ val32 &= ~BIT(27);
+ if ((x * oldval >> 7) & 0x1)
+ val32 |= BIT(27);
+ rtl8xxxu_write32(priv, REG_OFDM0_ENERGY_CCA_THRES, val32);
+
+ y = result[candidate][5];
+ if ((y & 0x00000200) != 0)
+ y = y | 0xfffffc00;
+ tx1_c = (y * oldval) >> 8;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XD_TX_AFE);
+ val32 &= ~0xf0000000;
+ val32 |= (((tx1_c & 0x3c0) >> 6) << 28);
+ rtl8xxxu_write32(priv, REG_OFDM0_XD_TX_AFE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE);
+ val32 &= ~0x003f0000;
+ val32 |= ((tx1_c & 0x3f) << 16);
+ rtl8xxxu_write32(priv, REG_OFDM0_XB_TX_IQ_IMBALANCE, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_ENERGY_CCA_THRES);
+ val32 &= ~BIT(25);
+ if ((y * oldval >> 7) & 0x1)
+ val32 |= BIT(25);
+ rtl8xxxu_write32(priv, REG_OFDM0_ENERGY_CCA_THRES, val32);
+
+ if (tx_only) {
+ dev_dbg(&priv->udev->dev, "%s: only TX\n", __func__);
+ return;
+ }
+
+ reg = result[candidate][6];
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_RX_IQ_IMBALANCE);
+ val32 &= ~0x3ff;
+ val32 |= (reg & 0x3ff);
+ rtl8xxxu_write32(priv, REG_OFDM0_XB_RX_IQ_IMBALANCE, val32);
+
+ reg = result[candidate][7] & 0x3f;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_RX_IQ_IMBALANCE);
+ val32 &= ~0xfc00;
+ val32 |= ((reg << 10) & 0xfc00);
+ rtl8xxxu_write32(priv, REG_OFDM0_XB_RX_IQ_IMBALANCE, val32);
+
+ reg = (result[candidate][7] >> 6) & 0xf;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_AGCR_SSI_TABLE);
+ val32 &= ~0x0000f000;
+ val32 |= (reg << 12);
+ rtl8xxxu_write32(priv, REG_OFDM0_AGCR_SSI_TABLE, val32);
+}
+
+#define MAX_TOLERANCE 5
+
+static bool rtl8xxxu_simularity_compare(struct rtl8xxxu_priv *priv,
+ int result[][8], int c1, int c2)
+{
+ u32 i, j, diff, simubitmap, bound = 0;
+ int candidate[2] = {-1, -1}; /* for path A and path B */
+ bool retval = true;
+
+ if (priv->tx_paths > 1)
+ bound = 8;
+ else
+ bound = 4;
+
+ simubitmap = 0;
+
+ for (i = 0; i < bound; i++) {
+ diff = (result[c1][i] > result[c2][i]) ?
+ (result[c1][i] - result[c2][i]) :
+ (result[c2][i] - result[c1][i]);
+ if (diff > MAX_TOLERANCE) {
+ if ((i == 2 || i == 6) && !simubitmap) {
+ if (result[c1][i] + result[c1][i + 1] == 0)
+ candidate[(i / 4)] = c2;
+ else if (result[c2][i] + result[c2][i + 1] == 0)
+ candidate[(i / 4)] = c1;
+ else
+ simubitmap = simubitmap | (1 << i);
+ } else {
+ simubitmap = simubitmap | (1 << i);
+ }
+ }
+ }
+
+ if (simubitmap == 0) {
+ for (i = 0; i < (bound / 4); i++) {
+ if (candidate[i] >= 0) {
+ for (j = i * 4; j < (i + 1) * 4 - 2; j++)
+ result[3][j] = result[candidate[i]][j];
+ retval = false;
+ }
+ }
+ return retval;
+ } else if (!(simubitmap & 0x0f)) {
+ /* path A OK */
+ for (i = 0; i < 4; i++)
+ result[3][i] = result[c1][i];
+ } else if (!(simubitmap & 0xf0) && priv->tx_paths > 1) {
+ /* path B OK */
+ for (i = 4; i < 8; i++)
+ result[3][i] = result[c1][i];
+ }
+
+ return false;
+}
+
+static void
+rtl8xxxu_save_mac_regs(struct rtl8xxxu_priv *priv, const u32 *reg, u32 *backup)
+{
+ int i;
+
+ for (i = 0; i < (RTL8XXXU_MAC_REGS - 1); i++)
+ backup[i] = rtl8xxxu_read8(priv, reg[i]);
+
+ backup[i] = rtl8xxxu_read32(priv, reg[i]);
+}
+
+static void rtl8xxxu_restore_mac_regs(struct rtl8xxxu_priv *priv,
+ const u32 *reg, u32 *backup)
+{
+ int i;
+
+ for (i = 0; i < (RTL8XXXU_MAC_REGS - 1); i++)
+ rtl8xxxu_write8(priv, reg[i], backup[i]);
+
+ rtl8xxxu_write32(priv, reg[i], backup[i]);
+}
+
+static void rtl8xxxu_save_regs(struct rtl8xxxu_priv *priv, const u32 *regs,
+ u32 *backup, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ backup[i] = rtl8xxxu_read32(priv, regs[i]);
+}
+
+static void rtl8xxxu_restore_regs(struct rtl8xxxu_priv *priv, const u32 *regs,
+ u32 *backup, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ rtl8xxxu_write32(priv, regs[i], backup[i]);
+}
+
+
+static void rtl8xxxu_path_adda_on(struct rtl8xxxu_priv *priv, const u32 *regs,
+ bool path_a_on)
+{
+ u32 path_on;
+ int i;
+
+ path_on = path_a_on ? 0x04db25a4 : 0x0b1b25a4;
+ if (priv->tx_paths == 1) {
+ path_on = 0x0bdb25a0;
+ rtl8xxxu_write32(priv, regs[0], 0x0b1b25a0);
+ } else {
+ rtl8xxxu_write32(priv, regs[0], path_on);
+ }
+
+ for (i = 1 ; i < RTL8XXXU_ADDA_REGS ; i++)
+ rtl8xxxu_write32(priv, regs[i], path_on);
+}
+
+static void rtl8xxxu_mac_calibration(struct rtl8xxxu_priv *priv,
+ const u32 *regs, u32 *backup)
+{
+ int i = 0;
+
+ rtl8xxxu_write8(priv, regs[i], 0x3f);
+
+ for (i = 1 ; i < (RTL8XXXU_MAC_REGS - 1); i++)
+ rtl8xxxu_write8(priv, regs[i], (u8)(backup[i] & ~BIT(3)));
+
+ rtl8xxxu_write8(priv, regs[i], (u8)(backup[i] & ~BIT(5)));
+}
+
+static int rtl8xxxu_iqk_path_a(struct rtl8xxxu_priv *priv)
+{
+ u32 reg_eac, reg_e94, reg_e9c, reg_ea4, val32;
+ int result = 0;
+
+ /* path-A IQK setting */
+ rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x10008c1f);
+ rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x10008c1f);
+ rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82140102);
+
+ val32 = (priv->rf_paths > 1) ? 0x28160202 :
+ /*IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)?0x28160202: */
+ 0x28160502;
+ rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, val32);
+
+ /* path-B IQK setting */
+ if (priv->rf_paths > 1) {
+ rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x10008c22);
+ rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x10008c22);
+ rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82140102);
+ rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28160202);
+ }
+
+ /* LO calibration setting */
+ rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x001028d1);
+
+ /* One shot, path A LOK & IQK */
+ rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000);
+ rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000);
+
+ mdelay(1);
+
+ /* Check failed */
+ reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
+ reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A);
+ reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A);
+ reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2);
+
+ if (!(reg_eac & BIT(28)) &&
+ ((reg_e94 & 0x03ff0000) != 0x01420000) &&
+ ((reg_e9c & 0x03ff0000) != 0x00420000))
+ result |= 0x01;
+ else /* If TX not OK, ignore RX */
+ goto out;
+
+ /* If TX is OK, check whether RX is OK */
+ if (!(reg_eac & BIT(27)) &&
+ ((reg_ea4 & 0x03ff0000) != 0x01320000) &&
+ ((reg_eac & 0x03ff0000) != 0x00360000))
+ result |= 0x02;
+ else
+ dev_warn(&priv->udev->dev, "%s: Path A RX IQK failed!\n",
+ __func__);
+out:
+ return result;
+}
+
+static int rtl8xxxu_iqk_path_b(struct rtl8xxxu_priv *priv)
+{
+ u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
+ int result = 0;
+
+ /* One shot, path B LOK & IQK */
+ rtl8xxxu_write32(priv, REG_IQK_AGC_CONT, 0x00000002);
+ rtl8xxxu_write32(priv, REG_IQK_AGC_CONT, 0x00000000);
+
+ mdelay(1);
+
+ /* Check failed */
+ reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
+ reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B);
+ reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B);
+ reg_ec4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2);
+ reg_ecc = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2);
+
+ if (!(reg_eac & BIT(31)) &&
+ ((reg_eb4 & 0x03ff0000) != 0x01420000) &&
+ ((reg_ebc & 0x03ff0000) != 0x00420000))
+ result |= 0x01;
+ else
+ goto out;
+
+ if (!(reg_eac & BIT(30)) &&
+ (((reg_ec4 & 0x03ff0000) >> 16) != 0x132) &&
+ (((reg_ecc & 0x03ff0000) >> 16) != 0x36))
+ result |= 0x02;
+ else
+ dev_warn(&priv->udev->dev, "%s: Path B RX IQK failed!\n",
+ __func__);
+out:
+ return result;
+}
+
+static void rtl8xxxu_phy_iqcalibrate(struct rtl8xxxu_priv *priv,
+ int result[][8], int t)
+{
+ struct device *dev = &priv->udev->dev;
+ u32 i, val32;
+ int path_a_ok, path_b_ok;
+ int retry = 2;
+ const u32 adda_regs[RTL8XXXU_ADDA_REGS] = {
+ REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH,
+ REG_RX_WAIT_CCA, REG_TX_CCK_RFON,
+ REG_TX_CCK_BBON, REG_TX_OFDM_RFON,
+ REG_TX_OFDM_BBON, REG_TX_TO_RX,
+ REG_TX_TO_TX, REG_RX_CCK,
+ REG_RX_OFDM, REG_RX_WAIT_RIFS,
+ REG_RX_TO_RX, REG_STANDBY,
+ REG_SLEEP, REG_PMPD_ANAEN
+ };
+ const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = {
+ REG_TXPAUSE, REG_BEACON_CTRL,
+ REG_BEACON_CTRL_1, REG_GPIO_MUXCFG
+ };
+ const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = {
+ REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR,
+ REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B,
+ REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE,
+ REG_FPGA0_XB_RF_INT_OE, REG_FPGA0_RF_MODE
+ };
+
+ /*
+ * Note: IQ calibration must be performed after loading
+ * PHY_REG.txt , and radio_a, radio_b.txt
+ */
+
+ if (t == 0) {
+ /* Save ADDA parameters, turn Path A ADDA on */
+ rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup,
+ RTL8XXXU_ADDA_REGS);
+ rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup);
+ rtl8xxxu_save_regs(priv, iqk_bb_regs,
+ priv->bb_backup, RTL8XXXU_BB_REGS);
+ }
+
+ rtl8xxxu_path_adda_on(priv, adda_regs, true);
+
+ if (t == 0) {
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM1);
+ if (val32 & FPGA0_HSSI_PARM1_PI)
+ priv->pi_enabled = 1;
+ }
+
+ if (!priv->pi_enabled) {
+ /* Switch BB to PI mode to do IQ Calibration. */
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100);
+ rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, 0x01000100);
+ }
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
+ val32 &= ~FPGA_RF_MODE_CCK;
+ rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
+
+ rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600);
+ rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4);
+ rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x22204000);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_SW_CTRL);
+ val32 |= (FPGA0_RF_PAPE | (FPGA0_RF_PAPE << FPGA0_RF_BD_CTRL_SHIFT));
+ rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_SW_CTRL, val32);
+
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_RF_INT_OE);
+ val32 &= ~BIT(10);
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, val32);
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE);
+ val32 &= ~BIT(10);
+ rtl8xxxu_write32(priv, REG_FPGA0_XB_RF_INT_OE, val32);
+
+ if (priv->tx_paths > 1) {
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_LSSI_PARM, 0x00010000);
+ rtl8xxxu_write32(priv, REG_FPGA0_XB_LSSI_PARM, 0x00010000);
+ }
+
+ /* MAC settings */
+ rtl8xxxu_mac_calibration(priv, iqk_mac_regs, priv->mac_backup);
+
+ /* Page B init */
+ rtl8xxxu_write32(priv, REG_CONFIG_ANT_A, 0x00080000);
+
+ if (priv->tx_paths > 1)
+ rtl8xxxu_write32(priv, REG_CONFIG_ANT_B, 0x00080000);
+
+ /* IQ calibration setting */
+ rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000);
+ rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00);
+ rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
+
+ for (i = 0; i < retry; i++) {
+ path_a_ok = rtl8xxxu_iqk_path_a(priv);
+ if (path_a_ok == 0x03) {
+ val32 = rtl8xxxu_read32(priv,
+ REG_TX_POWER_BEFORE_IQK_A);
+ result[t][0] = (val32 >> 16) & 0x3ff;
+ val32 = rtl8xxxu_read32(priv,
+ REG_TX_POWER_AFTER_IQK_A);
+ result[t][1] = (val32 >> 16) & 0x3ff;
+ val32 = rtl8xxxu_read32(priv,
+ REG_RX_POWER_BEFORE_IQK_A_2);
+ result[t][2] = (val32 >> 16) & 0x3ff;
+ val32 = rtl8xxxu_read32(priv,
+ REG_RX_POWER_AFTER_IQK_A_2);
+ result[t][3] = (val32 >> 16) & 0x3ff;
+ break;
+ } else if (i == (retry - 1) && path_a_ok == 0x01) {
+ /* TX IQK OK */
+ dev_dbg(dev, "%s: Path A IQK Only Tx Success!!\n",
+ __func__);
+
+ val32 = rtl8xxxu_read32(priv,
+ REG_TX_POWER_BEFORE_IQK_A);
+ result[t][0] = (val32 >> 16) & 0x3ff;
+ val32 = rtl8xxxu_read32(priv,
+ REG_TX_POWER_AFTER_IQK_A);
+ result[t][1] = (val32 >> 16) & 0x3ff;
+ }
+ }
+
+ if (!path_a_ok)
+ dev_dbg(dev, "%s: Path A IQK failed!\n", __func__);
+
+ if (priv->tx_paths > 1) {
+ /*
+ * Path A into standby
+ */
+ rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x0);
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_LSSI_PARM, 0x00010000);
+ rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000);
+
+ /* Turn Path B ADDA on */
+ rtl8xxxu_path_adda_on(priv, adda_regs, false);
+
+ for (i = 0; i < retry; i++) {
+ path_b_ok = rtl8xxxu_iqk_path_b(priv);
+ if (path_b_ok == 0x03) {
+ val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B);
+ result[t][4] = (val32 >> 16) & 0x3ff;
+ val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B);
+ result[t][5] = (val32 >> 16) & 0x3ff;
+ val32 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2);
+ result[t][6] = (val32 >> 16) & 0x3ff;
+ val32 = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2);
+ result[t][7] = (val32 >> 16) & 0x3ff;
+ break;
+ } else if (i == (retry - 1) && path_b_ok == 0x01) {
+ /* TX IQK OK */
+ val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B);
+ result[t][4] = (val32 >> 16) & 0x3ff;
+ val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B);
+ result[t][5] = (val32 >> 16) & 0x3ff;
+ }
+ }
+
+ if (!path_b_ok)
+ dev_dbg(dev, "%s: Path B IQK failed!\n", __func__);
+ }
+
+ /* Back to BB mode, load original value */
+ rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0);
+
+ if (t) {
+ if (!priv->pi_enabled) {
+ /*
+ * Switch back BB to SI mode after finishing
+ * IQ Calibration
+ */
+ val32 = 0x01000000;
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, val32);
+ rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, val32);
+ }
+
+ /* Reload ADDA power saving parameters */
+ rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup,
+ RTL8XXXU_ADDA_REGS);
+
+ /* Reload MAC parameters */
+ rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup);
+
+ /* Reload BB parameters */
+ rtl8xxxu_restore_regs(priv, iqk_bb_regs,
+ priv->bb_backup, RTL8XXXU_BB_REGS);
+
+ /* Restore RX initial gain */
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_LSSI_PARM, 0x00032ed3);
+
+ if (priv->tx_paths > 1) {
+ rtl8xxxu_write32(priv, REG_FPGA0_XB_LSSI_PARM,
+ 0x00032ed3);
+ }
+
+ /* Load 0xe30 IQC default value */
+ rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00);
+ rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00);
+ }
+}
+
+static void rtl8723a_phy_iq_calibrate(struct rtl8xxxu_priv *priv)
+{
+ struct device *dev = &priv->udev->dev;
+ int result[4][8]; /* last is final result */
+ int i, candidate;
+ bool path_a_ok, path_b_ok;
+ u32 reg_e94, reg_e9c, reg_ea4, reg_eac;
+ u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc;
+ s32 reg_tmp = 0;
+ bool simu;
+
+ memset(result, 0, sizeof(result));
+ candidate = -1;
+
+ path_a_ok = false;
+ path_b_ok = false;
+
+ rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
+
+ for (i = 0; i < 3; i++) {
+ rtl8xxxu_phy_iqcalibrate(priv, result, i);
+
+ if (i == 1) {
+ simu = rtl8xxxu_simularity_compare(priv, result, 0, 1);
+ if (simu) {
+ candidate = 0;
+ break;
+ }
+ }
+
+ if (i == 2) {
+ simu = rtl8xxxu_simularity_compare(priv, result, 0, 2);
+ if (simu) {
+ candidate = 0;
+ break;
+ }
+
+ simu = rtl8xxxu_simularity_compare(priv, result, 1, 2);
+ if (simu) {
+ candidate = 1;
+ } else {
+ for (i = 0; i < 8; i++)
+ reg_tmp += result[3][i];
+
+ if (reg_tmp)
+ candidate = 3;
+ else
+ candidate = -1;
+ }
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ reg_e94 = result[i][0];
+ reg_e9c = result[i][1];
+ reg_ea4 = result[i][2];
+ reg_eac = result[i][3];
+ reg_eb4 = result[i][4];
+ reg_ebc = result[i][5];
+ reg_ec4 = result[i][6];
+ reg_ecc = result[i][7];
+ }
+
+ if (candidate >= 0) {
+ reg_e94 = result[candidate][0];
+ priv->rege94 = reg_e94;
+ reg_e9c = result[candidate][1];
+ priv->rege9c = reg_e9c;
+ reg_ea4 = result[candidate][2];
+ reg_eac = result[candidate][3];
+ reg_eb4 = result[candidate][4];
+ priv->regeb4 = reg_eb4;
+ reg_ebc = result[candidate][5];
+ priv->regebc = reg_ebc;
+ reg_ec4 = result[candidate][6];
+ reg_ecc = result[candidate][7];
+ dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate);
+ dev_dbg(dev,
+ "%s: e94 =%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x "
+ "ecc=%x\n ", __func__, reg_e94, reg_e9c,
+ reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc);
+ path_a_ok = true;
+ path_b_ok = true;
+ } else {
+ reg_e94 = reg_eb4 = priv->rege94 = priv->regeb4 = 0x100;
+ reg_e9c = reg_ebc = priv->rege9c = priv->regebc = 0x0;
+ }
+
+ if (reg_e94 && candidate >= 0)
+ rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result,
+ candidate, (reg_ea4 == 0));
+
+ if (priv->tx_paths > 1 && reg_eb4)
+ rtl8xxxu_fill_iqk_matrix_b(priv, path_b_ok, result,
+ candidate, (reg_ec4 == 0));
+
+ rtl8xxxu_save_regs(priv, rtl8723au_iqk_phy_iq_bb_reg,
+ priv->bb_recovery_backup, RTL8XXXU_BB_REGS);
+}
+
+static void rtl8723a_phy_lc_calibrate(struct rtl8xxxu_priv *priv)
+{
+ u32 val32;
+ u32 rf_amode, rf_bmode = 0, lstf;
+
+ /* Check continuous TX and Packet TX */
+ lstf = rtl8xxxu_read32(priv, REG_OFDM1_LSTF);
+
+ if (lstf & OFDM_LSTF_MASK) {
+ /* Disable all continuous TX */
+ val32 = lstf & ~OFDM_LSTF_MASK;
+ rtl8xxxu_write32(priv, REG_OFDM1_LSTF, val32);
+
+ /* Read original RF mode Path A */
+ rf_amode = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_AC);
+
+ /* Set RF mode to standby Path A */
+ rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC,
+ (rf_amode & 0x8ffff) | 0x10000);
+
+ /* Path-B */
+ if (priv->tx_paths > 1) {
+ rf_bmode = rtl8xxxu_read_rfreg(priv, RF_B,
+ RF6052_REG_AC);
+
+ rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC,
+ (rf_bmode & 0x8ffff) | 0x10000);
+ }
+ } else {
+ /* Deal with Packet TX case */
+ /* block all queues */
+ rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
+ }
+
+ /* Start LC calibration */
+ val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG);
+ val32 |= 0x08000;
+ rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32);
+
+ msleep(100);
+
+ /* Restore original parameters */
+ if (lstf & OFDM_LSTF_MASK) {
+ /* Path-A */
+ rtl8xxxu_write32(priv, REG_OFDM1_LSTF, lstf);
+ rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, rf_amode);
+
+ /* Path-B */
+ if (priv->tx_paths > 1)
+ rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_AC,
+ rf_bmode);
+ } else /* Deal with Packet TX case */
+ rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00);
+}
+
+static int rtl8xxxu_set_mac(struct rtl8xxxu_priv *priv)
+{
+ int i;
+ u16 reg;
+
+ reg = REG_MACID;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ rtl8xxxu_write8(priv, reg + i, priv->mac_addr[i]);
+
+ return 0;
+}
+
+static int rtl8xxxu_set_bssid(struct rtl8xxxu_priv *priv, const u8 *bssid)
+{
+ int i;
+ u16 reg;
+
+ dev_dbg(&priv->udev->dev, "%s: (%pM)\n", __func__, bssid);
+
+ reg = REG_BSSID;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ rtl8xxxu_write8(priv, reg + i, bssid[i]);
+
+ return 0;
+}
+
+static void
+rtl8xxxu_set_ampdu_factor(struct rtl8xxxu_priv *priv, u8 ampdu_factor)
+{
+ u8 vals[4] = { 0x41, 0xa8, 0x72, 0xb9 };
+ u8 max_agg = 0xf;
+ int i;
+
+ ampdu_factor = 1 << (ampdu_factor + 2);
+ if (ampdu_factor > max_agg)
+ ampdu_factor = max_agg;
+
+ for (i = 0; i < 4; i++) {
+ if ((vals[i] & 0xf0) > (ampdu_factor << 4))
+ vals[i] = (vals[i] & 0x0f) | (ampdu_factor << 4);
+
+ if ((vals[i] & 0x0f) > ampdu_factor)
+ vals[i] = (vals[i] & 0xf0) | ampdu_factor;
+
+ rtl8xxxu_write8(priv, REG_AGGLEN_LMT + i, vals[i]);
+ }
+}
+
+static void rtl8xxxu_set_ampdu_min_space(struct rtl8xxxu_priv *priv, u8 density)
+{
+ u8 val8;
+
+ val8 = rtl8xxxu_read8(priv, REG_AMPDU_MIN_SPACE);
+ val8 &= 0xf8;
+ val8 |= density;
+ rtl8xxxu_write8(priv, REG_AMPDU_MIN_SPACE, val8);
+}
+
+static int rtl8xxxu_active_to_emu(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+ int count, ret;
+
+ /* Start of rtl8723AU_card_enable_flow */
+ /* Act to Cardemu sequence*/
+ /* Turn off RF */
+ rtl8xxxu_write8(priv, REG_RF_CTRL, 0);
+
+ /* 0x004E[7] = 0, switch DPDT_SEL_P output from register 0x0065[2] */
+ val8 = rtl8xxxu_read8(priv, REG_LEDCFG2);
+ val8 &= ~LEDCFG2_DPDT_SELECT;
+ rtl8xxxu_write8(priv, REG_LEDCFG2, val8);
+
+ /* 0x0005[1] = 1 turn off MAC by HW state machine*/
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ val8 |= BIT(1);
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
+
+ for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ if ((val8 & BIT(1)) == 0)
+ break;
+ udelay(10);
+ }
+
+ if (!count) {
+ dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n",
+ __func__);
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* 0x0000[5] = 1 analog Ips to digital, 1:isolation */
+ val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL);
+ val8 |= SYS_ISO_ANALOG_IPS;
+ rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8);
+
+ /* 0x0020[0] = 0 disable LDOA12 MACRO block*/
+ val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL);
+ val8 &= ~LDOA15_ENABLE;
+ rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8);
+
+exit:
+ return ret;
+}
+
+static int rtl8xxxu_active_to_lps(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+ u8 val32;
+ int count, ret;
+
+ rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
+
+ /*
+ * Poll - wait for RX packet to complete
+ */
+ for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
+ val32 = rtl8xxxu_read32(priv, 0x5f8);
+ if (!val32)
+ break;
+ udelay(10);
+ }
+
+ if (!count) {
+ dev_warn(&priv->udev->dev,
+ "%s: RX poll timed out (0x05f8)\n", __func__);
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* Disable CCK and OFDM, clock gated */
+ val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC);
+ val8 &= ~SYS_FUNC_BBRSTB;
+ rtl8xxxu_write8(priv, REG_SYS_FUNC, val8);
+
+ udelay(2);
+
+ /* Reset baseband */
+ val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC);
+ val8 &= ~SYS_FUNC_BB_GLB_RSTN;
+ rtl8xxxu_write8(priv, REG_SYS_FUNC, val8);
+
+ /* Reset MAC TRX */
+ val8 = rtl8xxxu_read8(priv, REG_CR);
+ val8 = CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE;
+ rtl8xxxu_write8(priv, REG_CR, val8);
+
+ /* Reset MAC TRX */
+ val8 = rtl8xxxu_read8(priv, REG_CR + 1);
+ val8 &= ~BIT(1); /* CR_SECURITY_ENABLE */
+ rtl8xxxu_write8(priv, REG_CR + 1, val8);
+
+ /* Respond TX OK to scheduler */
+ val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST);
+ val8 |= DUAL_TSF_TX_OK;
+ rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8);
+
+exit:
+ return ret;
+}
+
+static void rtl8xxxu_disabled_to_emu(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+
+ /* Clear suspend enable and power down enable*/
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ val8 &= ~(BIT(3) | BIT(7));
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
+
+ /* 0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/
+ val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2);
+ val8 &= ~BIT(0);
+ rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8);
+
+ /* 0x04[12:11] = 11 enable WL suspend*/
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ val8 &= ~(BIT(3) | BIT(4));
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
+}
+
+static int rtl8xxxu_emu_to_active(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+ u32 val32;
+ int count, ret = 0;
+
+ /* 0x20[0] = 1 enable LDOA12 MACRO block for all interface*/
+ val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL);
+ val8 |= LDOA15_ENABLE;
+ rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8);
+
+ /* 0x67[0] = 0 to disable BT_GPS_SEL pins*/
+ val8 = rtl8xxxu_read8(priv, 0x0067);
+ val8 &= ~BIT(4);
+ rtl8xxxu_write8(priv, 0x0067, val8);
+
+ mdelay(1);
+
+ /* 0x00[5] = 0 release analog Ips to digital, 1:isolation */
+ val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL);
+ val8 &= ~SYS_ISO_ANALOG_IPS;
+ rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8);
+
+ /* disable SW LPS 0x04[10]= 0 */
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ val8 &= ~BIT(2);
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
+
+ /* wait till 0x04[17] = 1 power ready*/
+ for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
+ val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
+ if (val32 & BIT(17))
+ break;
+
+ udelay(10);
+ }
+
+ if (!count) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* We should be able to optimize the following three entries into one */
+
+ /* release WLON reset 0x04[16]= 1*/
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 2);
+ val8 |= BIT(0);
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 2, val8);
+
+ /* disable HWPDN 0x04[15]= 0*/
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ val8 &= ~BIT(7);
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
+
+ /* disable WL suspend*/
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ val8 &= ~(BIT(3) | BIT(4));
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
+
+ /* set, then poll until 0 */
+ val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
+ val32 |= APS_FSMCO_MAC_ENABLE;
+ rtl8xxxu_write32(priv, REG_APS_FSMCO, val32);
+
+ for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
+ val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
+ if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) {
+ ret = 0;
+ break;
+ }
+ udelay(10);
+ }
+
+ if (!count) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* 0x4C[23] = 0x4E[7] = 1, switch DPDT_SEL_P output from WL BB */
+ /*
+ * Note: Vendor driver actually clears this bit, despite the
+ * documentation claims it's being set!
+ */
+ val8 = rtl8xxxu_read8(priv, REG_LEDCFG2);
+ val8 |= LEDCFG2_DPDT_SELECT;
+ val8 &= ~LEDCFG2_DPDT_SELECT;
+ rtl8xxxu_write8(priv, REG_LEDCFG2, val8);
+
+exit:
+ return ret;
+}
+
+static int rtl8xxxu_emu_to_disabled(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+
+ /* 0x0007[7:0] = 0x20 SOP option to disable BG/MB */
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20);
+
+ /* 0x04[12:11] = 01 enable WL suspend */
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ val8 &= ~BIT(4);
+ val8 |= BIT(3);
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
+
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
+ val8 |= BIT(7);
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
+
+ /* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */
+ val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2);
+ val8 |= BIT(0);
+ rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8);
+
+ return 0;
+}
+
+static int rtl8723au_power_on(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+ u16 val16;
+ u32 val32;
+ int ret;
+
+ /*
+ * RSV_CTRL 0x001C[7:0] = 0x00, unlock ISO/CLK/Power control register
+ */
+ rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0);
+
+ rtl8xxxu_disabled_to_emu(priv);
+
+ ret = rtl8xxxu_emu_to_active(priv);
+ if (ret)
+ goto exit;
+
+ /*
+ * 0x0004[19] = 1, reset 8051
+ */
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 2);
+ val8 |= BIT(3);
+ rtl8xxxu_write8(priv, REG_APS_FSMCO + 2, val8);
+
+ /*
+ * Enable MAC DMA/WMAC/SCHEDULE/SEC block
+ * Set CR bit10 to enable 32k calibration.
+ */
+ val16 = rtl8xxxu_read16(priv, REG_CR);
+ val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE |
+ CR_TXDMA_ENABLE | CR_RXDMA_ENABLE |
+ CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE |
+ CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE |
+ CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE);
+ rtl8xxxu_write16(priv, REG_CR, val16);
+
+ /* For EFuse PG */
+ val32 = rtl8xxxu_read32(priv, REG_EFUSE_CTRL);
+ val32 &= ~(BIT(28) | BIT(29) | BIT(30));
+ val32 |= (0x06 << 28);
+ rtl8xxxu_write32(priv, REG_EFUSE_CTRL, val32);
+exit:
+ return ret;
+}
+
+#ifdef CONFIG_RTL8XXXU_UNTESTED
+
+static int rtl8192cu_power_on(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+ u16 val16;
+ u32 val32;
+ int i;
+
+ for (i = 100; i; i--) {
+ val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO);
+ if (val8 & APS_FSMCO_PFM_ALDN)
+ break;
+ }
+
+ if (!i) {
+ pr_info("%s: Poll failed\n", __func__);
+ return -ENODEV;
+ }
+
+ /*
+ * RSV_CTRL 0x001C[7:0] = 0x00, unlock ISO/CLK/Power control register
+ */
+ rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0);
+ rtl8xxxu_write8(priv, REG_SPS0_CTRL, 0x2b);
+ udelay(100);
+
+ val8 = rtl8xxxu_read8(priv, REG_LDOV12D_CTRL);
+ if (!(val8 & LDOV12D_ENABLE)) {
+ pr_info("%s: Enabling LDOV12D (%02x)\n", __func__, val8);
+ val8 |= LDOV12D_ENABLE;
+ rtl8xxxu_write8(priv, REG_LDOV12D_CTRL, val8);
+
+ udelay(100);
+
+ val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL);
+ val8 &= ~SYS_ISO_MD2PP;
+ rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8);
+ }
+
+ /*
+ * Auto enable WLAN
+ */
+ val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO);
+ val16 |= APS_FSMCO_MAC_ENABLE;
+ rtl8xxxu_write16(priv, REG_APS_FSMCO, val16);
+
+ for (i = 1000; i; i--) {
+ val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO);
+ if (!(val16 & APS_FSMCO_MAC_ENABLE))
+ break;
+ }
+ if (!i) {
+ pr_info("%s: FSMCO_MAC_ENABLE poll failed\n", __func__);
+ return -EBUSY;
+ }
+
+ /*
+ * Enable radio, GPIO, LED
+ */
+ val16 = APS_FSMCO_HW_SUSPEND | APS_FSMCO_ENABLE_POWERDOWN |
+ APS_FSMCO_PFM_ALDN;
+ rtl8xxxu_write16(priv, REG_APS_FSMCO, val16);
+
+ /*
+ * Release RF digital isolation
+ */
+ val16 = rtl8xxxu_read16(priv, REG_SYS_ISO_CTRL);
+ val16 &= ~SYS_ISO_DIOR;
+ rtl8xxxu_write16(priv, REG_SYS_ISO_CTRL, val16);
+
+ val8 = rtl8xxxu_read8(priv, REG_APSD_CTRL);
+ val8 &= ~APSD_CTRL_OFF;
+ rtl8xxxu_write8(priv, REG_APSD_CTRL, val8);
+ for (i = 200; i; i--) {
+ val8 = rtl8xxxu_read8(priv, REG_APSD_CTRL);
+ if (!(val8 & APSD_CTRL_OFF_STATUS))
+ break;
+ }
+
+ if (!i) {
+ pr_info("%s: APSD_CTRL poll failed\n", __func__);
+ return -EBUSY;
+ }
+
+ /*
+ * Enable MAC DMA/WMAC/SCHEDULE/SEC block
+ */
+ val16 = rtl8xxxu_read16(priv, REG_CR);
+ val16 |= CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE |
+ CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | CR_PROTOCOL_ENABLE |
+ CR_SCHEDULE_ENABLE | CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE;
+ rtl8xxxu_write16(priv, REG_CR, val16);
+
+ /*
+ * Workaround for 8188RU LNA power leakage problem.
+ */
+ if (priv->rtlchip == 0x8188c && priv->hi_pa) {
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM);
+ val32 &= ~BIT(1);
+ rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32);
+ }
+ return 0;
+}
+
+#endif
+
+static void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv)
+{
+ u8 val8;
+ u16 val16;
+ u32 val32;
+
+ /*
+ * Workaround for 8188RU LNA power leakage problem.
+ */
+ if (priv->rtlchip == 0x8188c && priv->hi_pa) {
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM);
+ val32 |= BIT(1);
+ rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32);
+ }
+
+ rtl8xxxu_active_to_lps(priv);
+
+ /* Turn off RF */
+ rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00);
+
+ /* Reset Firmware if running in RAM */
+ if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL)
+ rtl8xxxu_firmware_self_reset(priv);
+
+ /* Reset MCU */
+ val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
+ val16 &= ~SYS_FUNC_CPU_ENABLE;
+ rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
+
+ /* Reset MCU ready status */
+ rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
+
+ rtl8xxxu_active_to_emu(priv);
+ rtl8xxxu_emu_to_disabled(priv);
+
+ /* Reset MCU IO Wrapper */
+ val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
+ val8 &= ~BIT(0);
+ rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
+
+ val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
+ val8 |= BIT(0);
+ rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
+
+ /* RSV_CTRL 0x1C[7:0] = 0x0e lock ISO/CLK/Power control register */
+ rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e);
+}
+
+static void rtl8xxxu_init_bt(struct rtl8xxxu_priv *priv)
+{
+ if (!priv->has_bluetooth)
+ return;
+}
+
+static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct device *dev = &priv->udev->dev;
+ struct rtl8xxxu_rfregval *rftable;
+ bool macpower;
+ int ret;
+ u8 val8;
+ u16 val16;
+ u32 val32;
+
+ /* Check if MAC is already powered on */
+ val8 = rtl8xxxu_read8(priv, REG_CR);
+
+ /*
+ * Fix 92DU-VC S3 hang with the reason is that secondary mac is not
+ * initialized. First MAC returns 0xea, second MAC returns 0x00
+ */
+ if (val8 == 0xea)
+ macpower = false;
+ else
+ macpower = true;
+
+ ret = priv->fops->power_on(priv);
+ if (ret < 0) {
+ dev_warn(dev, "%s: Failed power on\n", __func__);
+ goto exit;
+ }
+
+ dev_dbg(dev, "%s: macpower %i\n", __func__, macpower);
+ if (!macpower) {
+ ret = rtl8xxxu_init_llt_table(priv, TX_TOTAL_PAGE_NUM);
+ if (ret) {
+ dev_warn(dev, "%s: LLT table init failed\n", __func__);
+ goto exit;
+ }
+ }
+
+ ret = rtl8xxxu_download_firmware(priv);
+ dev_dbg(dev, "%s: download_fiwmare %i\n", __func__, ret);
+ if (ret)
+ goto exit;
+ ret = rtl8xxxu_start_firmware(priv);
+ dev_dbg(dev, "%s: start_fiwmare %i\n", __func__, ret);
+ if (ret)
+ goto exit;
+
+ ret = rtl8xxxu_init_mac(priv, rtl8723a_mac_init_table);
+ dev_dbg(dev, "%s: init_mac %i\n", __func__, ret);
+ if (ret)
+ goto exit;
+
+ ret = rtl8xxxu_init_phy_bb(priv);
+ dev_dbg(dev, "%s: init_phy_bb %i\n", __func__, ret);
+ if (ret)
+ goto exit;
+
+ switch(priv->rtlchip) {
+ case 0x8723a:
+ rftable = rtl8723au_radioa_1t_init_table;
+ ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_A);
+ break;
+ case 0x8188c:
+ if (priv->hi_pa)
+ rftable = rtl8188ru_radioa_1t_highpa_table;
+ else
+ rftable = rtl8192cu_radioa_1t_init_table;
+ ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_A);
+ break;
+ case 0x8191c:
+ rftable = rtl8192cu_radioa_1t_init_table;
+ ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_A);
+ break;
+ case 0x8192c:
+ rftable = rtl8192cu_radioa_2t_init_table;
+ ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_A);
+ if (ret)
+ break;
+ rftable = rtl8192cu_radiob_2t_init_table;
+ ret = rtl8xxxu_init_phy_rf(priv, rftable, RF_B);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ if (ret)
+ goto exit;
+
+ /* Reduce 80M spur */
+ rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, 0x0381808d);
+ rtl8xxxu_write32(priv, REG_AFE_PLL_CTRL, 0xf0ffff83);
+ rtl8xxxu_write32(priv, REG_AFE_PLL_CTRL, 0xf0ffff82);
+ rtl8xxxu_write32(priv, REG_AFE_PLL_CTRL, 0xf0ffff83);
+
+ /* RFSW Control - clear bit 14 ?? */
+ rtl8xxxu_write32(priv, REG_FPGA0_TX_INFO, 0x00000003);
+ /* 0x07000760 */
+ val32 = FPGA0_RF_TRSW | FPGA0_RF_TRSWB | FPGA0_RF_ANTSW |
+ FPGA0_RF_ANTSWB | FPGA0_RF_PAPE |
+ ((FPGA0_RF_ANTSW | FPGA0_RF_ANTSWB | FPGA0_RF_PAPE) <<
+ FPGA0_RF_BD_CTRL_SHIFT);
+ rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_SW_CTRL, val32);
+ /* 0x860[6:5]= 00 - why? - this sets antenna B */
+ rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, 0x66F60210);
+
+ priv->rf_mode_ag[0] = rtl8xxxu_read_rfreg(priv, RF_A,
+ RF6052_REG_MODE_AG);
+
+ dev_dbg(dev, "%s: macpower %i\n", __func__, macpower);
+ if (!macpower) {
+ if (priv->ep_tx_normal_queue)
+ val8 = TX_PAGE_NUM_NORM_PQ;
+ else
+ val8 = 0;
+
+ rtl8xxxu_write8(priv, REG_RQPN_NPQ, val8);
+
+ val32 = (TX_PAGE_NUM_PUBQ << RQPN_NORM_PQ_SHIFT) | RQPN_LOAD;
+
+ if (priv->ep_tx_high_queue)
+ val32 |= (TX_PAGE_NUM_HI_PQ << RQPN_HI_PQ_SHIFT);
+ if (priv->ep_tx_low_queue)
+ val32 |= (TX_PAGE_NUM_LO_PQ << RQPN_LO_PQ_SHIFT);
+
+ rtl8xxxu_write32(priv, REG_RQPN, val32);
+
+ /*
+ * Set TX buffer boundary
+ */
+ val8 = TX_TOTAL_PAGE_NUM + 1;
+ rtl8xxxu_write8(priv, REG_TXPKTBUF_BCNQ_BDNY, val8);
+ rtl8xxxu_write8(priv, REG_TXPKTBUF_MGQ_BDNY, val8);
+ rtl8xxxu_write8(priv, REG_TXPKTBUF_WMAC_LBK_BF_HD, val8);
+ rtl8xxxu_write8(priv, REG_TRXFF_BNDY, val8);
+ rtl8xxxu_write8(priv, REG_TDECTRL + 1, val8);
+ }
+
+ ret = rtl8xxxu_init_queue_priority(priv);
+ dev_dbg(dev, "%s: init_queue_priority %i\n", __func__, ret);
+ if (ret)
+ goto exit;
+
+ /*
+ * Set RX page boundary
+ */
+ rtl8xxxu_write16(priv, REG_TRXFF_BNDY + 2, 0x27ff);
+ /*
+ * Transfer page size is always 128
+ */
+ val8 = (PBP_PAGE_SIZE_128 << PBP_PAGE_SIZE_RX_SHIFT) |
+ (PBP_PAGE_SIZE_128 << PBP_PAGE_SIZE_TX_SHIFT);
+ rtl8xxxu_write8(priv, REG_PBP, val8);
+
+ /*
+ * Unit in 8 bytes, not obvious what it is used for
+ */
+ rtl8xxxu_write8(priv, REG_RX_DRVINFO_SZ, 4);
+
+ /*
+ * Enable all interrupts - not obvious USB needs to do this
+ */
+ rtl8xxxu_write32(priv, REG_HISR, 0xffffffff);
+ rtl8xxxu_write32(priv, REG_HIMR, 0xffffffff);
+
+ rtl8xxxu_set_mac(priv);
+ rtl8xxxu_set_linktype(priv, NL80211_IFTYPE_STATION);
+
+ /*
+ * Configure initial WMAC settings
+ */
+ val32 = RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_MCAST | RCR_ACCEPT_BCAST |
+ /* RCR_CHECK_BSSID_MATCH | RCR_CHECK_BSSID_BEACON | */
+ RCR_ACCEPT_MGMT_FRAME | RCR_HTC_LOC_CTRL |
+ RCR_APPEND_PHYSTAT | RCR_APPEND_ICV | RCR_APPEND_MIC;
+ rtl8xxxu_write32(priv, REG_RCR, val32);
+
+ /*
+ * Accept all multicast
+ */
+ rtl8xxxu_write32(priv, REG_MAR, 0xffffffff);
+ rtl8xxxu_write32(priv, REG_MAR + 4, 0xffffffff);
+
+ /*
+ * Init adaptive controls
+ */
+ val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET);
+ val32 &= ~RESPONSE_RATE_BITMAP_ALL;
+ val32 |= RESPONSE_RATE_RRSR_CCK_ONLY_1M;
+ rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32);
+
+ /* CCK = 0x0a, OFDM = 0x10 */
+ rtl8xxxu_set_spec_sifs(priv, 0x10, 0x10);
+ rtl8xxxu_set_retry(priv, 0x30, 0x30);
+ rtl8xxxu_set_spec_sifs(priv, 0x0a, 0x10);
+
+ /*
+ * Init EDCA
+ */
+ rtl8xxxu_write16(priv, REG_MAC_SPEC_SIFS, 0x100a);
+
+ /* Set CCK SIFS */
+ rtl8xxxu_write16(priv, REG_SIFS_CCK, 0x100a);
+
+ /* Set OFDM SIFS */
+ rtl8xxxu_write16(priv, REG_SIFS_OFDM, 0x100a);
+
+ /* TXOP */
+ rtl8xxxu_write32(priv, REG_EDCA_BE_PARAM, 0x005ea42b);
+ rtl8xxxu_write32(priv, REG_EDCA_BK_PARAM, 0x0000a44f);
+ rtl8xxxu_write32(priv, REG_EDCA_VI_PARAM, 0x005ea324);
+ rtl8xxxu_write32(priv, REG_EDCA_VO_PARAM, 0x002fa226);
+
+ /* Set data auto rate fallback retry count */
+ rtl8xxxu_write32(priv, REG_DARFRC, 0x00000000);
+ rtl8xxxu_write32(priv, REG_DARFRC + 4, 0x10080404);
+ rtl8xxxu_write32(priv, REG_RARFRC, 0x04030201);
+ rtl8xxxu_write32(priv, REG_RARFRC + 4, 0x08070605);
+
+ val8 = rtl8xxxu_read8(priv, REG_FWHW_TXQ_CTRL);
+ val8 |= FWHW_TXQ_CTRL_AMPDU_RETRY;
+ rtl8xxxu_write8(priv, REG_FWHW_TXQ_CTRL, val8);
+
+ /* Set ACK timeout */
+ rtl8xxxu_write8(priv, REG_ACKTO, 0x40);
+
+ /*
+ * Initialize beacon parameters
+ */
+ val16 = BEACON_DISABLE_TSF_UPDATE | (BEACON_DISABLE_TSF_UPDATE << 8);
+ rtl8xxxu_write16(priv, REG_BEACON_CTRL, val16);
+ rtl8xxxu_write16(priv, REG_TBTT_PROHIBIT, 0x6404);
+ rtl8xxxu_write8(priv, REG_DRIVER_EARLY_INT, DRIVER_EARLY_INT_TIME);
+ rtl8xxxu_write8(priv, REG_BEACON_DMA_TIME, BEACON_DMA_ATIME_INT_TIME);
+ rtl8xxxu_write16(priv, REG_BEACON_TCFG, 0x660F);
+
+ /*
+ * Enable CCK and OFDM block
+ */
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
+ val32 |= (FPGA_RF_MODE_CCK | FPGA_RF_MODE_OFDM);
+ rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
+
+ /*
+ * Invalidate all CAM entries - bit 30 is undocumented
+ */
+ rtl8xxxu_write32(priv, REG_CAM_CMD, CAM_CMD_POLLING | BIT(30));
+
+ /*
+ * Start out with default power levels for channel 6, 20MHz
+ */
+ rtl8723a_set_tx_power(priv, 1, false);
+
+ /* Let the 8051 take control of antenna setting */
+ val8 = rtl8xxxu_read8(priv, REG_LEDCFG2);
+ val8 |= LEDCFG2_DPDT_SELECT;
+ rtl8xxxu_write8(priv, REG_LEDCFG2, val8);
+
+ rtl8xxxu_write8(priv, REG_HWSEQ_CTRL, 0xff);
+
+ /* Disable BAR - not sure if this has any effect on USB */
+ rtl8xxxu_write32(priv, REG_BAR_MODE_CTRL, 0x0201ffff);
+
+ rtl8xxxu_write16(priv, REG_FAST_EDCA_CTRL, 0);
+
+ /*
+ * Not sure if we should get into this at all
+ */
+ if (priv->iqk_initialized) {
+ rtl8xxxu_restore_regs(priv, rtl8723au_iqk_phy_iq_bb_reg,
+ priv->bb_recovery_backup,
+ RTL8XXXU_BB_REGS);
+ } else {
+ rtl8723a_phy_iq_calibrate(priv);
+ priv->iqk_initialized = true;
+ }
+
+ /*
+ * This should enable thermal meter
+ */
+ rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_T_METER, 0x60);
+
+ rtl8723a_phy_lc_calibrate(priv);
+
+ /* fix USB interface interference issue */
+ rtl8xxxu_write8(priv, 0xfe40, 0xe0);
+ rtl8xxxu_write8(priv, 0xfe41, 0x8d);
+ rtl8xxxu_write8(priv, 0xfe42, 0x80);
+ rtl8xxxu_write32(priv, REG_TXDMA_OFFSET_CHK, 0xfd0320);
+
+ /* Solve too many protocol error on USB bus */
+ /* Can't do this for 8188/8192 UMC A cut parts */
+ rtl8xxxu_write8(priv, 0xfe40, 0xe6);
+ rtl8xxxu_write8(priv, 0xfe41, 0x94);
+ rtl8xxxu_write8(priv, 0xfe42, 0x80);
+
+ rtl8xxxu_write8(priv, 0xfe40, 0xe0);
+ rtl8xxxu_write8(priv, 0xfe41, 0x19);
+ rtl8xxxu_write8(priv, 0xfe42, 0x80);
+
+ rtl8xxxu_write8(priv, 0xfe40, 0xe5);
+ rtl8xxxu_write8(priv, 0xfe41, 0x91);
+ rtl8xxxu_write8(priv, 0xfe42, 0x80);
+
+ rtl8xxxu_write8(priv, 0xfe40, 0xe2);
+ rtl8xxxu_write8(priv, 0xfe41, 0x81);
+ rtl8xxxu_write8(priv, 0xfe42, 0x80);
+
+ /* Init BT hw config. */
+ rtl8xxxu_init_bt(priv);
+
+ /*
+ * Not sure if we really need to save these parameters, but the
+ * vendor driver does
+ */
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM2);
+ if (val32 & FPGA0_HSSI_PARM2_CCK_HIGH_PWR)
+ priv->path_a_hi_power = 1;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE);
+ priv->path_a_rf_paths = val32 & OFDM_RF_PATH_RX_MASK;
+
+ val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1);
+ priv->path_a_ig_value = val32 & OFDM0_X_AGC_CORE1_IGI_MASK;
+
+ /* Set NAV_UPPER to 30000us */
+ val8 = ((30000 + NAV_UPPER_UNIT - 1) / NAV_UPPER_UNIT);
+ rtl8xxxu_write8(priv, REG_NAV_UPPER, val8);
+
+ /*
+ * 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test,
+ * but we need to fin root cause.
+ */
+ val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
+ if ((val32 & 0xff000000) != 0x83000000) {
+ val32 |= FPGA_RF_MODE_CCK;
+ rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
+ }
+
+ val32 = rtl8xxxu_read32(priv, REG_FWHW_TXQ_CTRL);
+ val32 |= FWHW_TXQ_CTRL_XMIT_MGMT_ACK;
+ /* ack for xmit mgmt frames. */
+ rtl8xxxu_write32(priv, REG_FWHW_TXQ_CTRL, val32);
+
+exit:
+ return ret;
+}
+
+static void rtl8xxxu_disable_device(struct ieee80211_hw *hw)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+
+ rtl8xxxu_power_off(priv);
+}
+
+static void rtl8xxxu_cam_write(struct rtl8xxxu_priv *priv,
+ struct ieee80211_key_conf *key, const u8 *mac)
+{
+ u32 cmd, val32, addr, ctrl;
+ int j, i, tmp_debug;
+
+ tmp_debug = rtl8xxxu_debug;
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_KEY)
+ rtl8xxxu_debug |= RTL8XXXU_DEBUG_REG_WRITE;
+
+ /*
+ * This is a bit of a hack - the lower bits of the cipher
+ * suite selector happens to match the cipher index in the CAM
+ */
+ addr = key->keyidx << CAM_CMD_KEY_SHIFT;
+ ctrl = (key->cipher & 0x0f) << 2 | key->keyidx | CAM_WRITE_VALID;
+
+ for (j = 5; j >= 0; j--) {
+ switch (j) {
+ case 0:
+ val32 = ctrl | (mac[0] << 16) | (mac[1] << 24);
+ break;
+ case 1:
+ val32 = mac[2] | (mac[3] << 8) |
+ (mac[4] << 16) | (mac[5] << 24);
+ break;
+ default:
+ i = (j - 2) << 2;
+ val32 = key->key[i] | (key->key[i + 1] << 8) |
+ key->key[i + 2] << 16 | key->key[i + 3] << 24;
+ break;
+ }
+
+ rtl8xxxu_write32(priv, REG_CAM_WRITE, val32);
+ cmd = CAM_CMD_POLLING | CAM_CMD_WRITE | (addr + j);
+ rtl8xxxu_write32(priv, REG_CAM_CMD, cmd);
+ udelay(100);
+ }
+
+ rtl8xxxu_debug = tmp_debug;
+}
+
+static void rtl8xxxu_sw_scan_start(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, const u8* mac)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ u8 val8;
+
+ val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
+ val8 |= BEACON_DISABLE_TSF_UPDATE;
+ rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
+}
+
+static void rtl8xxxu_sw_scan_complete(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ u8 val8;
+
+ val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
+ val8 &= ~BEACON_DISABLE_TSF_UPDATE;
+ rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
+}
+
+static void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
+ u32 ramask, int sgi)
+{
+ struct h2c_cmd h2c;
+
+ h2c.ramask.cmd = H2C_SET_RATE_MASK;
+ h2c.ramask.mask_lo = cpu_to_le16(ramask & 0xffff);
+ h2c.ramask.mask_hi = cpu_to_le16(ramask >> 16);
+
+ h2c.ramask.arg = 0x80;
+ if (sgi)
+ h2c.ramask.arg |= 0x20;
+
+ dev_dbg(&priv->udev->dev, "%s: rate mask %08x, arg %02x\n", __func__,
+ ramask, h2c.ramask.arg);
+ rtl8723a_h2c_cmd(priv, &h2c);
+}
+
+static void rtl8xxxu_set_basic_rates(struct rtl8xxxu_priv *priv, u32 rate_cfg)
+{
+ u32 val32;
+ u8 rate_idx = 0;
+
+ rate_cfg &= RESPONSE_RATE_BITMAP_ALL;
+
+ val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET);
+ val32 &= ~RESPONSE_RATE_BITMAP_ALL;
+ val32 |= rate_cfg;
+ rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32);
+
+ dev_dbg(&priv->udev->dev, "%s: rates %08x\n", __func__, rate_cfg);
+
+ while (rate_cfg) {
+ rate_cfg = (rate_cfg >> 1);
+ rate_idx++;
+ }
+ rtl8xxxu_write8(priv, REG_INIRTS_RATE_SEL, rate_idx);
+}
+
+static void
+rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf, u32 changed)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct device *dev = &priv->udev->dev;
+ struct ieee80211_sta *sta;
+ u32 val32;
+ u8 val8;
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ struct h2c_cmd h2c;
+
+ dev_dbg(dev, "Changed ASSOC: %i!\n", bss_conf->assoc);
+
+ memset(&h2c, 0, sizeof(struct h2c_cmd));
+ rtl8xxxu_set_linktype(priv, vif->type);
+
+ if (bss_conf->assoc) {
+ u32 ramask;
+ int sgi = 0;
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, bss_conf->bssid);
+ if (!sta) {
+ dev_info(dev, "%s: ASSOC no sta found\n",
+ __func__);
+ rcu_read_unlock();
+ goto error;
+ }
+
+ if (sta->ht_cap.ht_supported)
+ dev_info(dev, "%s: HT supported\n", __func__);
+ if (sta->vht_cap.vht_supported)
+ dev_info(dev, "%s: VHT supported\n", __func__);
+
+ /* TODO: Set bits 28-31 for rate adaptive id */
+ ramask = (sta->supp_rates[0] & 0xfff) |
+ sta->ht_cap.mcs.rx_mask[0] << 12 |
+ sta->ht_cap.mcs.rx_mask[1] << 20;
+ if (sta->ht_cap.cap &
+ (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))
+ sgi = 1;
+ rcu_read_unlock();
+
+ rtl8xxxu_update_rate_mask(priv, ramask, sgi);
+
+ val32 = rtl8xxxu_read32(priv, REG_RCR);
+ val32 |= RCR_CHECK_BSSID_MATCH | RCR_CHECK_BSSID_BEACON;
+ rtl8xxxu_write32(priv, REG_RCR, val32);
+
+ /* Enable RX of data frames */
+ rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0xffff);
+
+ rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
+
+ rtl8723a_stop_tx_beacon(priv);
+
+ /* joinbss sequence */
+ rtl8xxxu_write16(priv, REG_BCN_PSR_RPT,
+ 0xc000 | bss_conf->aid);
+
+ h2c.joinbss.data = H2C_JOIN_BSS_CONNECT;
+ } else {
+ val32 = rtl8xxxu_read32(priv, REG_RCR);
+ val32 &= ~(RCR_CHECK_BSSID_MATCH |
+ RCR_CHECK_BSSID_BEACON);
+ rtl8xxxu_write32(priv, REG_RCR, val32);
+
+ val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
+ val8 |= BEACON_DISABLE_TSF_UPDATE;
+ rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
+
+ /* Disable RX of data frames */
+ rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x0000);
+ h2c.joinbss.data = H2C_JOIN_BSS_DISCONNECT;
+ }
+ h2c.joinbss.cmd = H2C_JOIN_BSS_REPORT;
+ rtl8723a_h2c_cmd(priv, &h2c);
+ }
+
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ dev_dbg(dev, "Changed ERP_PREAMBLE: Use short preamble %i\n",
+ bss_conf->use_short_preamble);
+ val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET);
+ if (bss_conf->use_short_preamble)
+ val32 |= RSR_ACK_SHORT_PREAMBLE;
+ else
+ val32 &= ~RSR_ACK_SHORT_PREAMBLE;
+ rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32);
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ dev_dbg(dev, "Changed ERP_SLOT: short_slot_time %i\n",
+ bss_conf->use_short_slot);
+
+ if (bss_conf->use_short_slot)
+ val8 = 9;
+ else
+ val8 = 20;
+ rtl8xxxu_write8(priv, REG_SLOT, val8);
+ }
+
+ if (changed & BSS_CHANGED_BSSID) {
+ dev_dbg(dev, "Changed BSSID!\n");
+ rtl8xxxu_set_bssid(priv, bss_conf->bssid);
+ }
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ dev_dbg(dev, "Changed BASIC_RATES!\n");
+ rtl8xxxu_set_basic_rates(priv, bss_conf->basic_rates);
+ }
+error:
+ return;
+}
+
+static u32 rtl8xxxu_80211_to_rtl_queue(u32 queue)
+{
+ u32 rtlqueue;
+
+ switch (queue) {
+ case IEEE80211_AC_VO:
+ rtlqueue = TXDESC_QUEUE_VO;
+ break;
+ case IEEE80211_AC_VI:
+ rtlqueue = TXDESC_QUEUE_VI;
+ break;
+ case IEEE80211_AC_BE:
+ rtlqueue = TXDESC_QUEUE_BE;
+ break;
+ case IEEE80211_AC_BK:
+ rtlqueue = TXDESC_QUEUE_BK;
+ break;
+ default:
+ rtlqueue = TXDESC_QUEUE_BE;
+ }
+
+ return rtlqueue;
+}
+
+static u32 rtl8xxxu_queue_select(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ u32 queue;
+
+ if (ieee80211_is_mgmt(hdr->frame_control))
+ queue = TXDESC_QUEUE_MGNT;
+ else
+ queue = rtl8xxxu_80211_to_rtl_queue(skb_get_queue_mapping(skb));
+
+ return queue;
+}
+
+static void rtl8xxxu_calc_tx_desc_csum(struct rtl8xxxu_tx_desc *tx_desc)
+{
+ __le16 *ptr = (__le16 *)tx_desc;
+ u16 csum = 0;
+ int i;
+
+ /*
+ * Clear csum field before calculation, as the csum field is
+ * in the middle of the struct.
+ */
+ tx_desc->csum = cpu_to_le16(0);
+
+ for (i = 0; i < (sizeof(struct rtl8xxxu_tx_desc) / sizeof(u16)); i++)
+ csum = csum ^ le16_to_cpu(ptr[i]);
+
+ tx_desc->csum |= cpu_to_le16(csum);
+}
+
+static void rtl8xxxu_free_tx_resources(struct rtl8xxxu_priv *priv)
+{
+ struct rtl8xxxu_tx_urb *tx_urb, *tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->tx_urb_lock, flags);
+ list_for_each_entry_safe(tx_urb, tmp, &priv->tx_urb_free_list, list) {
+ list_del(&tx_urb->list);
+ priv->tx_urb_free_count--;
+ usb_free_urb(&tx_urb->urb);
+ }
+ spin_unlock_irqrestore(&priv->tx_urb_lock, flags);
+}
+
+static struct rtl8xxxu_tx_urb *
+rtl8xxxu_alloc_tx_urb(struct rtl8xxxu_priv *priv)
+{
+ struct rtl8xxxu_tx_urb *tx_urb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->tx_urb_lock, flags);
+ tx_urb = list_first_entry_or_null(&priv->tx_urb_free_list,
+ struct rtl8xxxu_tx_urb, list);
+ if (tx_urb) {
+ list_del(&tx_urb->list);
+ priv->tx_urb_free_count--;
+ if (priv->tx_urb_free_count < RTL8XXXU_TX_URB_LOW_WATER &&
+ !priv->tx_stopped) {
+ priv->tx_stopped = true;
+ ieee80211_stop_queues(priv->hw);
+ }
+ }
+
+ spin_unlock_irqrestore(&priv->tx_urb_lock, flags);
+
+ return tx_urb;
+}
+
+static void rtl8xxxu_free_tx_urb(struct rtl8xxxu_priv *priv,
+ struct rtl8xxxu_tx_urb *tx_urb)
+{
+ unsigned long flags;
+
+ INIT_LIST_HEAD(&tx_urb->list);
+
+ spin_lock_irqsave(&priv->tx_urb_lock, flags);
+
+ list_add(&tx_urb->list, &priv->tx_urb_free_list);
+ priv->tx_urb_free_count++;
+ if (priv->tx_urb_free_count > RTL8XXXU_TX_URB_HIGH_WATER &&
+ priv->tx_stopped) {
+ priv->tx_stopped = false;
+ ieee80211_wake_queues(priv->hw);
+ }
+
+ spin_unlock_irqrestore(&priv->tx_urb_lock, flags);
+}
+
+static void rtl8xxxu_tx_complete(struct urb *urb)
+{
+ struct sk_buff *skb = (struct sk_buff *)urb->context;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_hw *hw;
+ struct rtl8xxxu_tx_urb *tx_urb =
+ container_of(urb, struct rtl8xxxu_tx_urb, urb);
+
+ tx_info = IEEE80211_SKB_CB(skb);
+ hw = tx_info->rate_driver_data[0];
+
+ skb_pull(skb, sizeof(struct rtl8xxxu_tx_desc));
+
+ ieee80211_tx_info_clear_status(tx_info);
+ tx_info->status.rates[0].idx = -1;
+ tx_info->status.rates[0].count = 0;
+
+ if (!urb->status)
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
+
+ ieee80211_tx_status_irqsafe(hw, skb);
+
+ rtl8xxxu_free_tx_urb(hw->priv, tx_urb);
+}
+
+static void rtl8xxxu_dump_action(struct device *dev,
+ struct ieee80211_hdr *hdr)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)hdr;
+ u16 cap, timeout;
+
+ if (!(rtl8xxxu_debug & RTL8XXXU_DEBUG_ACTION))
+ return;
+
+ switch (mgmt->u.action.u.addba_resp.action_code) {
+ case WLAN_ACTION_ADDBA_RESP:
+ cap = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
+ timeout = le16_to_cpu(mgmt->u.action.u.addba_resp.timeout);
+ dev_info(dev, "WLAN_ACTION_ADDBA_RESP: "
+ "timeout %i, tid %02x, buf_size %02x, policy %02x, "
+ "status %02x\n",
+ timeout,
+ (cap & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2,
+ (cap & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6,
+ (cap >> 1) & 0x1,
+ le16_to_cpu(mgmt->u.action.u.addba_resp.status));
+ break;
+ case WLAN_ACTION_ADDBA_REQ:
+ cap = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+ timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
+ dev_info(dev, "WLAN_ACTION_ADDBA_REQ: "
+ "timeout %i, tid %02x, buf_size %02x, policy %02x\n",
+ timeout,
+ (cap & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2,
+ (cap & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6,
+ (cap >> 1) & 0x1);
+ break;
+ default:
+ dev_info(dev, "action frame %02x\n",
+ mgmt->u.action.u.addba_resp.action_code);
+ break;
+ }
+}
+
+static void rtl8xxxu_tx(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct rtl8xxxu_tx_desc *tx_desc;
+ struct rtl8xxxu_tx_urb *tx_urb;
+ struct ieee80211_sta *sta = NULL;
+ struct ieee80211_vif *vif = tx_info->control.vif;
+ struct device *dev = &priv->udev->dev;
+ u32 queue, rate;
+ u16 pktlen = skb->len;
+ u16 seq_number;
+ u16 rate_flag = tx_info->control.rates[0].flags;
+ int ret;
+
+ if (skb_headroom(skb) < sizeof(struct rtl8xxxu_tx_desc)) {
+ dev_warn(dev,
+ "%s: Not enough headroom (%i) for tx descriptor\n",
+ __func__, skb_headroom(skb));
+ goto error;
+ }
+
+ if (unlikely(skb->len > (65535 - sizeof(struct rtl8xxxu_tx_desc)))) {
+ dev_warn(dev, "%s: Trying to send over-sized skb (%i)\n",
+ __func__, skb->len);
+ goto error;
+ }
+
+ tx_urb = rtl8xxxu_alloc_tx_urb(priv);
+ if (!tx_urb) {
+ dev_warn(dev, "%s: Unable to allocate tx urb\n", __func__);
+ goto error;
+ }
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX)
+ dev_info(dev, "%s: TX rate: %d (%d), pkt size %d\n",
+ __func__, tx_rate->bitrate, tx_rate->hw_value, pktlen);
+
+ if (ieee80211_is_action(hdr->frame_control))
+ rtl8xxxu_dump_action(dev, hdr);
+
+ tx_info->rate_driver_data[0] = hw;
+
+ if (control && control->sta)
+ sta = control->sta;
+
+ tx_desc = (struct rtl8xxxu_tx_desc *)
+ skb_push(skb, sizeof(struct rtl8xxxu_tx_desc));
+
+ memset(tx_desc, 0, sizeof(struct rtl8xxxu_tx_desc));
+ tx_desc->pkt_size = cpu_to_le16(pktlen);
+ tx_desc->pkt_offset = sizeof(struct rtl8xxxu_tx_desc);
+
+ tx_desc->txdw0 =
+ TXDESC_OWN | TXDESC_FIRST_SEGMENT | TXDESC_LAST_SEGMENT;
+ if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
+ is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
+ tx_desc->txdw0 |= TXDESC_BROADMULTICAST;
+
+ queue = rtl8xxxu_queue_select(hw, skb);
+ tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT);
+
+ if (tx_info->control.hw_key) {
+ switch (tx_info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
+ tx_desc->txdw1 |= cpu_to_le32(TXDESC_SEC_RC4);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ tx_desc->txdw1 |= cpu_to_le32(TXDESC_SEC_AES);
+ break;
+ default:
+ break;
+ }
+ }
+
+ seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
+ tx_desc->txdw3 = cpu_to_le32((u32)seq_number << TXDESC_SEQ_SHIFT);
+
+ if (rate_flag & IEEE80211_TX_RC_MCS)
+ rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0;
+ else
+ rate = tx_rate->hw_value;
+ tx_desc->txdw5 = cpu_to_le32(rate);
+
+ if (ieee80211_is_data(hdr->frame_control))
+ tx_desc->txdw5 |= cpu_to_le32(0x0001ff00);
+
+ /* (tx_info->flags & IEEE80211_TX_CTL_AMPDU) && */
+ if (ieee80211_is_data_qos(hdr->frame_control) && sta) {
+ if (sta->ht_cap.ht_supported) {
+ u32 ampdu, val32;
+
+ ampdu = (u32)sta->ht_cap.ampdu_density;
+ val32 = ampdu << TXDESC_AMPDU_DENSITY_SHIFT;
+ tx_desc->txdw2 |= cpu_to_le32(val32);
+ tx_desc->txdw1 |= cpu_to_le32(TXDESC_AGG_ENABLE);
+ } else
+ tx_desc->txdw1 |= cpu_to_le32(TXDESC_BK);
+ } else
+ tx_desc->txdw1 |= cpu_to_le32(TXDESC_BK);
+
+ if (ieee80211_is_data_qos(hdr->frame_control))
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC_QOS);
+ if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ||
+ (sta && vif && vif->bss_conf.use_short_preamble))
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC_SHORT_PREAMBLE);
+ if (rate_flag & IEEE80211_TX_RC_SHORT_GI ||
+ (ieee80211_is_data_qos(hdr->frame_control) &&
+ sta && sta->ht_cap.cap &
+ (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))) {
+ tx_desc->txdw5 |= cpu_to_le32(TXDESC_SHORT_GI);
+ }
+ if (ieee80211_is_mgmt(hdr->frame_control)) {
+ tx_desc->txdw5 = cpu_to_le32(tx_rate->hw_value);
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC_USE_DRIVER_RATE);
+ tx_desc->txdw5 |= cpu_to_le32(6 << TXDESC_RETRY_LIMIT_SHIFT);
+ tx_desc->txdw5 |= cpu_to_le32(TXDESC_RETRY_LIMIT_ENABLE);
+ }
+
+ if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
+ /* Use RTS rate 24M - does the mac80211 tell us which to use? */
+ tx_desc->txdw4 |= cpu_to_le32(DESC_RATE_24M);
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC_RTS_CTS_ENABLE);
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC_HW_RTS_ENABLE);
+ }
+
+ rtl8xxxu_calc_tx_desc_csum(tx_desc);
+
+ usb_fill_bulk_urb(&tx_urb->urb, priv->udev, priv->pipe_out[queue],
+ skb->data, skb->len, rtl8xxxu_tx_complete, skb);
+
+ usb_anchor_urb(&tx_urb->urb, &priv->tx_anchor);
+ ret = usb_submit_urb(&tx_urb->urb, GFP_ATOMIC);
+ if (ret) {
+ usb_unanchor_urb(&tx_urb->urb);
+ rtl8xxxu_free_tx_urb(priv, tx_urb);
+ goto error;
+ }
+ return;
+error:
+ dev_kfree_skb(skb);
+}
+
+static void rtl8xxxu_rx_parse_phystats(struct rtl8xxxu_priv *priv,
+ struct ieee80211_rx_status *rx_status,
+ struct rtl8xxxu_rx_desc *rx_desc,
+ struct rtl8723au_phy_stats *phy_stats)
+{
+ if (phy_stats->sgi_en)
+ rx_status->flag |= RX_FLAG_SHORT_GI;
+
+ if (rx_desc->rxmcs < DESC_RATE_6M) {
+ /*
+ * Handle PHY stats for CCK rates
+ */
+ u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a;
+
+ switch (cck_agc_rpt & 0xc0) {
+ case 0xc0:
+ rx_status->signal = -46 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x80:
+ rx_status->signal = -26 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x40:
+ rx_status->signal = -12 - (cck_agc_rpt & 0x3e);
+ break;
+ case 0x00:
+ rx_status->signal = 16 - (cck_agc_rpt & 0x3e);
+ break;
+ }
+ } else {
+ rx_status->signal =
+ (phy_stats->cck_sig_qual_ofdm_pwdb_all >> 1) - 110;
+ }
+}
+
+static void rtl8xxxu_free_rx_resources(struct rtl8xxxu_priv *priv)
+{
+ struct rtl8xxxu_rx_urb *rx_urb, *tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->rx_urb_lock, flags);
+
+ list_for_each_entry_safe(rx_urb, tmp,
+ &priv->rx_urb_pending_list, list) {
+ list_del(&rx_urb->list);
+ priv->rx_urb_pending_count--;
+ usb_free_urb(&rx_urb->urb);
+ }
+
+ spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
+}
+
+static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv,
+ struct rtl8xxxu_rx_urb *rx_urb)
+{
+ struct sk_buff *skb;
+ unsigned long flags;
+ int pending = 0;
+
+ spin_lock_irqsave(&priv->rx_urb_lock, flags);
+
+ if (!priv->shutdown) {
+ list_add_tail(&rx_urb->list, &priv->rx_urb_pending_list);
+ priv->rx_urb_pending_count++;
+ pending = priv->rx_urb_pending_count;
+ } else {
+ skb = (struct sk_buff *)rx_urb->urb.context;
+ dev_kfree_skb(skb);
+ usb_free_urb(&rx_urb->urb);
+ }
+
+ spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
+
+ if (pending > RTL8XXXU_RX_URB_PENDING_WATER)
+ schedule_work(&priv->rx_urb_wq);
+}
+
+static void rtl8xxxu_rx_urb_work(struct work_struct *work)
+{
+ struct rtl8xxxu_priv *priv;
+ struct rtl8xxxu_rx_urb *rx_urb, *tmp;
+ struct list_head local;
+ struct sk_buff *skb;
+ unsigned long flags;
+ int ret;
+
+ priv = container_of(work, struct rtl8xxxu_priv, rx_urb_wq);
+ INIT_LIST_HEAD(&local);
+
+ spin_lock_irqsave(&priv->rx_urb_lock, flags);
+
+ list_splice_init(&priv->rx_urb_pending_list, &local);
+ priv->rx_urb_pending_count = 0;
+
+ spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
+
+ list_for_each_entry_safe(rx_urb, tmp, &local, list) {
+ list_del_init(&rx_urb->list);
+ ret = rtl8xxxu_submit_rx_urb(priv, rx_urb);
+ /*
+ * If out of memory or temporary error, put it back on the
+ * queue and try again. Otherwise the device is dead/gone
+ * and we should drop it.
+ */
+ switch (ret) {
+ case 0:
+ break;
+ case -ENOMEM:
+ case -EAGAIN:
+ rtl8xxxu_queue_rx_urb(priv, rx_urb);
+ break;
+ default:
+ pr_info("failed to requeue urb %i\n", ret);
+ skb = (struct sk_buff *)rx_urb->urb.context;
+ dev_kfree_skb(skb);
+ usb_free_urb(&rx_urb->urb);
+ }
+ }
+}
+
+static void rtl8xxxu_rx_complete(struct urb *urb)
+{
+ struct rtl8xxxu_rx_urb *rx_urb =
+ container_of(urb, struct rtl8xxxu_rx_urb, urb);
+ struct ieee80211_hw *hw = rx_urb->hw;
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct sk_buff *skb = (struct sk_buff *)urb->context;
+ struct rtl8xxxu_rx_desc *rx_desc = (struct rtl8xxxu_rx_desc *)skb->data;
+ struct rtl8723au_phy_stats *phy_stats;
+ struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
+ struct ieee80211_mgmt *mgmt;
+ struct device *dev = &priv->udev->dev;
+ __le32 *_rx_desc_le = (__le32 *)skb->data;
+ u32 *_rx_desc = (u32 *)skb->data;
+ int cnt, len, drvinfo_sz, desc_shift, i;
+
+ for (i = 0; i < (sizeof(struct rtl8xxxu_rx_desc) / sizeof(u32)); i++)
+ _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]);
+
+ cnt = rx_desc->frag;
+ len = rx_desc->pktlen;
+ drvinfo_sz = rx_desc->drvinfo_sz * 8;
+ desc_shift = rx_desc->shift;
+ skb_put(skb, urb->actual_length);
+
+ if (urb->status == 0) {
+ skb_pull(skb, sizeof(struct rtl8xxxu_rx_desc));
+ phy_stats = (struct rtl8723au_phy_stats *)skb->data;
+
+ skb_pull(skb, drvinfo_sz + desc_shift);
+
+ mgmt = (struct ieee80211_mgmt *)skb->data;
+
+ memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
+
+ if (rx_desc->phy_stats)
+ rtl8xxxu_rx_parse_phystats(priv, rx_status,
+ rx_desc, phy_stats);
+
+ rx_status->freq = hw->conf.chandef.chan->center_freq;
+ rx_status->band = hw->conf.chandef.chan->band;
+
+ rx_status->mactime = le32_to_cpu(rx_desc->tsfl);
+ rx_status->flag |= RX_FLAG_MACTIME_START;
+
+ if (!rx_desc->swdec)
+ rx_status->flag |= RX_FLAG_DECRYPTED;
+ if (rx_desc->crc32)
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ if (rx_desc->bw)
+ rx_status->flag |= RX_FLAG_40MHZ;
+
+ if (rx_desc->rxht) {
+ rx_status->flag |= RX_FLAG_HT;
+ rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
+ } else {
+ rx_status->rate_idx = rx_desc->rxmcs;
+ }
+
+ ieee80211_rx_irqsafe(hw, skb);
+ skb = NULL;
+ rx_urb->urb.context = NULL;
+ rtl8xxxu_queue_rx_urb(priv, rx_urb);
+ } else {
+ dev_dbg(dev, "%s: status %i\n", __func__, urb->status);
+ goto cleanup;
+ }
+ return;
+
+cleanup:
+ usb_free_urb(urb);
+ dev_kfree_skb(skb);
+ return;
+}
+
+static int rtl8xxxu_submit_rx_urb(struct rtl8xxxu_priv *priv,
+ struct rtl8xxxu_rx_urb *rx_urb)
+{
+ struct sk_buff *skb;
+ int skb_size;
+ int ret;
+
+ skb_size = sizeof(struct rtl8xxxu_rx_desc) + RTL_RX_BUFFER_SIZE;
+ skb = __netdev_alloc_skb(NULL, skb_size, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ memset(skb->data, 0, sizeof(struct rtl8xxxu_rx_desc));
+ usb_fill_bulk_urb(&rx_urb->urb, priv->udev, priv->pipe_in, skb->data,
+ skb_size, rtl8xxxu_rx_complete, skb);
+ usb_anchor_urb(&rx_urb->urb, &priv->rx_anchor);
+ ret = usb_submit_urb(&rx_urb->urb, GFP_ATOMIC);
+ if (ret)
+ usb_unanchor_urb(&rx_urb->urb);
+ return ret;
+}
+
+static void rtl8xxxu_int_complete(struct urb *urb)
+{
+ struct rtl8xxxu_priv *priv = (struct rtl8xxxu_priv *)urb->context;
+ struct device *dev = &priv->udev->dev;
+ int ret;
+
+ dev_dbg(dev, "%s: status %i\n", __func__, urb->status);
+ if (urb->status == 0) {
+ usb_anchor_urb(urb, &priv->int_anchor);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret)
+ usb_unanchor_urb(urb);
+ } else {
+ dev_info(dev, "%s: Error %i\n", __func__, urb->status);
+ }
+}
+
+
+static int rtl8xxxu_submit_int_urb(struct ieee80211_hw *hw)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct urb *urb;
+ u32 val32;
+ int ret;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ return -ENOMEM;
+
+ usb_fill_int_urb(urb, priv->udev, priv->pipe_interrupt,
+ priv->int_buf, USB_INTR_CONTENT_LENGTH,
+ rtl8xxxu_int_complete, priv, 1);
+ usb_anchor_urb(urb, &priv->int_anchor);
+ ret = usb_submit_urb(urb, GFP_KERNEL);
+ if (ret) {
+ usb_unanchor_urb(urb);
+ goto error;
+ }
+
+ val32 = rtl8xxxu_read32(priv, REG_USB_HIMR);
+ val32 |= USB_HIMR_CPWM;
+ rtl8xxxu_write32(priv, REG_USB_HIMR, val32);
+
+error:
+ return ret;
+}
+
+static int rtl8xxxu_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ int ret;
+ u8 val8;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ rtl8723a_stop_tx_beacon(priv);
+
+ val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
+ val8 |= BEACON_ATIM | BEACON_FUNCTION_ENABLE |
+ BEACON_DISABLE_TSF_UPDATE;
+ rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
+ ret = 0;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ rtl8xxxu_set_linktype(priv, vif->type);
+
+ return ret;
+}
+
+static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+
+ dev_dbg(&priv->udev->dev, "%s\n", __func__);
+}
+
+static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct device *dev = &priv->udev->dev;
+ u16 val16;
+ int ret = 0, channel;
+ bool ht40;
+
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_CHANNEL)
+ dev_info(dev,
+ "%s: channel: %i (changed %08x chandef.width %02x)\n",
+ __func__, hw->conf.chandef.chan->hw_value,
+ changed, hw->conf.chandef.width);
+
+ if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+ val16 = ((hw->conf.long_frame_max_tx_count <<
+ RETRY_LIMIT_LONG_SHIFT) & RETRY_LIMIT_LONG_MASK) |
+ ((hw->conf.short_frame_max_tx_count <<
+ RETRY_LIMIT_SHORT_SHIFT) & RETRY_LIMIT_SHORT_MASK);
+ rtl8xxxu_write16(priv, REG_RETRY_LIMIT, val16);
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ switch (hw->conf.chandef.width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
+ ht40 = false;
+ break;
+ case NL80211_CHAN_WIDTH_40:
+ ht40 = true;
+ break;
+ default:
+ ret = -ENOTSUPP;
+ goto exit;
+ }
+
+ channel = hw->conf.chandef.chan->hw_value;
+
+ rtl8723a_set_tx_power(priv, channel, ht40);
+
+ rtl8723au_config_channel(hw);
+ }
+
+exit:
+ return ret;
+}
+
+static int rtl8xxxu_conf_tx(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u16 queue,
+ const struct ieee80211_tx_queue_params *param)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct device *dev = &priv->udev->dev;
+ u32 val32;
+ u8 aifs, acm_ctrl, acm_bit;
+
+ aifs = param->aifs;
+
+ val32 = aifs |
+ fls(param->cw_min) << EDCA_PARAM_ECW_MIN_SHIFT |
+ fls(param->cw_max) << EDCA_PARAM_ECW_MAX_SHIFT |
+ (u32)param->txop << EDCA_PARAM_TXOP_SHIFT;
+
+ acm_ctrl = rtl8xxxu_read8(priv, REG_ACM_HW_CTRL);
+ dev_dbg(dev,
+ "%s: IEEE80211 queue %02x val %08x, acm %i, acm_ctrl %02x\n",
+ __func__, queue, val32, param->acm, acm_ctrl);
+
+ switch (queue) {
+ case IEEE80211_AC_VO:
+ acm_bit = ACM_HW_CTRL_VO;
+ rtl8xxxu_write32(priv, REG_EDCA_VO_PARAM, val32);
+ break;
+ case IEEE80211_AC_VI:
+ acm_bit = ACM_HW_CTRL_VI;
+ rtl8xxxu_write32(priv, REG_EDCA_VI_PARAM, val32);
+ break;
+ case IEEE80211_AC_BE:
+ acm_bit = ACM_HW_CTRL_BE;
+ rtl8xxxu_write32(priv, REG_EDCA_BE_PARAM, val32);
+ break;
+ case IEEE80211_AC_BK:
+ acm_bit = ACM_HW_CTRL_BK;
+ rtl8xxxu_write32(priv, REG_EDCA_BK_PARAM, val32);
+ break;
+ default:
+ acm_bit = 0;
+ break;
+ }
+
+ if (param->acm)
+ acm_ctrl |= acm_bit;
+ else
+ acm_ctrl &= ~acm_bit;
+ rtl8xxxu_write8(priv, REG_ACM_HW_CTRL, acm_ctrl);
+
+ return 0;
+}
+
+static void rtl8xxxu_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags, u64 multicast)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+
+ dev_dbg(&priv->udev->dev, "%s: changed_flags %08x, total_flags %08x\n",
+ __func__, changed_flags, *total_flags);
+
+ *total_flags &= (FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC);
+}
+
+static int rtl8xxxu_set_rts_threshold(struct ieee80211_hw *hw, u32 rts)
+{
+ if (rts > 2347)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int rtl8xxxu_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct device *dev = &priv->udev->dev;
+ u8 mac_addr[ETH_ALEN];
+ u8 val8;
+ u16 val16;
+ u32 val32;
+ int retval = -EOPNOTSUPP;
+
+ dev_dbg(dev, "%s: cmd %02x, cipher %08x, index %i\n",
+ __func__, cmd, key->cipher, key->keyidx);
+
+ if (vif->type != NL80211_IFTYPE_STATION)
+ return -EOPNOTSUPP;
+
+ if (key->keyidx > 3)
+ return -EOPNOTSUPP;
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+ dev_dbg(dev, "%s: pairwise key\n", __func__);
+ ether_addr_copy(mac_addr, sta->addr);
+ } else {
+ dev_dbg(dev, "%s: group key\n", __func__);
+ eth_broadcast_addr(mac_addr);
+ }
+
+ val16 = rtl8xxxu_read16(priv, REG_CR);
+ val16 |= CR_SECURITY_ENABLE;
+ rtl8xxxu_write16(priv, REG_CR, val16);
+
+ val8 = SEC_CFG_TX_SEC_ENABLE | SEC_CFG_TXBC_USE_DEFKEY |
+ SEC_CFG_RX_SEC_ENABLE | SEC_CFG_RXBC_USE_DEFKEY;
+ val8 |= SEC_CFG_TX_USE_DEFKEY | SEC_CFG_RX_USE_DEFKEY;
+ rtl8xxxu_write8(priv, REG_SECURITY_CFG, val8);
+
+ switch (cmd) {
+ case SET_KEY:
+ key->hw_key_idx = key->keyidx;
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ rtl8xxxu_cam_write(priv, key, mac_addr);
+ retval = 0;
+ break;
+ case DISABLE_KEY:
+ rtl8xxxu_write32(priv, REG_CAM_WRITE, 0x00000000);
+ val32 = CAM_CMD_POLLING | CAM_CMD_WRITE |
+ key->keyidx << CAM_CMD_KEY_SHIFT;
+ rtl8xxxu_write32(priv, REG_CAM_CMD, val32);
+ retval = 0;
+ break;
+ default:
+ dev_warn(dev, "%s: Unsupported command %02x\n", __func__, cmd);
+ }
+
+ return retval;
+}
+
+static int
+rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size,
+ bool amsdu)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct device *dev = &priv->udev->dev;
+ u8 ampdu_factor, ampdu_density;
+
+ switch (action) {
+ case IEEE80211_AMPDU_TX_START:
+ dev_info(dev, "%s: IEEE80211_AMPDU_TX_START\n", __func__);
+ ampdu_factor = sta->ht_cap.ampdu_factor;
+ ampdu_density = sta->ht_cap.ampdu_density;
+ rtl8xxxu_set_ampdu_factor(priv, ampdu_factor);
+ rtl8xxxu_set_ampdu_min_space(priv, ampdu_density);
+ dev_dbg(dev,
+ "Changed HT: ampdu_factor %02x, ampdu_density %02x\n",
+ ampdu_factor, ampdu_density);
+ break;
+ case IEEE80211_AMPDU_TX_STOP_FLUSH:
+ dev_info(dev, "%s: IEEE80211_AMPDU_TX_STOP_FLUSH\n", __func__);
+ rtl8xxxu_set_ampdu_factor(priv, 0);
+ rtl8xxxu_set_ampdu_min_space(priv, 0);
+ break;
+ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+ dev_info(dev, "%s: IEEE80211_AMPDU_TX_STOP_FLUSH_CONT\n",
+ __func__);
+ rtl8xxxu_set_ampdu_factor(priv, 0);
+ rtl8xxxu_set_ampdu_min_space(priv, 0);
+ break;
+ case IEEE80211_AMPDU_RX_START:
+ dev_info(dev, "%s: IEEE80211_AMPDU_RX_START\n", __func__);
+ break;
+ case IEEE80211_AMPDU_RX_STOP:
+ dev_info(dev, "%s: IEEE80211_AMPDU_RX_STOP\n", __func__);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int rtl8xxxu_start(struct ieee80211_hw *hw)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ struct rtl8xxxu_rx_urb *rx_urb;
+ struct rtl8xxxu_tx_urb *tx_urb;
+ unsigned long flags;
+ int ret, i;
+
+ ret = 0;
+
+ init_usb_anchor(&priv->rx_anchor);
+ init_usb_anchor(&priv->tx_anchor);
+ init_usb_anchor(&priv->int_anchor);
+
+ rtl8723a_enable_rf(priv);
+ ret = rtl8xxxu_submit_int_urb(hw);
+ if (ret)
+ goto exit;
+
+ for (i = 0; i < RTL8XXXU_TX_URBS; i++) {
+ tx_urb = kmalloc(sizeof(struct rtl8xxxu_tx_urb), GFP_KERNEL);
+ if (!tx_urb) {
+ if (!i)
+ ret = -ENOMEM;
+
+ goto error_out;
+ }
+ usb_init_urb(&tx_urb->urb);
+ INIT_LIST_HEAD(&tx_urb->list);
+ tx_urb->hw = hw;
+ list_add(&tx_urb->list, &priv->tx_urb_free_list);
+ priv->tx_urb_free_count++;
+ }
+
+ priv->tx_stopped = false;
+
+ spin_lock_irqsave(&priv->rx_urb_lock, flags);
+ priv->shutdown = false;
+ spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
+
+ for (i = 0; i < RTL8XXXU_RX_URBS; i++) {
+ rx_urb = kmalloc(sizeof(struct rtl8xxxu_rx_urb), GFP_KERNEL);
+ if (!rx_urb) {
+ if (!i)
+ ret = -ENOMEM;
+
+ goto error_out;
+ }
+ usb_init_urb(&rx_urb->urb);
+ INIT_LIST_HEAD(&rx_urb->list);
+ rx_urb->hw = hw;
+
+ ret = rtl8xxxu_submit_rx_urb(priv, rx_urb);
+ }
+exit:
+ /*
+ * Disable all data frames
+ */
+ rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x0000);
+ /*
+ * Accept all mgmt frames
+ */
+ rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0xffff);
+
+ rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, 0x6954341e);
+
+ return ret;
+
+error_out:
+ rtl8xxxu_free_tx_resources(priv);
+ /*
+ * Disable all data and mgmt frames
+ */
+ rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x0000);
+ rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0x0000);
+
+ return ret;
+}
+
+static void rtl8xxxu_stop(struct ieee80211_hw *hw)
+{
+ struct rtl8xxxu_priv *priv = hw->priv;
+ unsigned long flags;
+
+ rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
+
+ rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0x0000);
+ rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x0000);
+
+ spin_lock_irqsave(&priv->rx_urb_lock, flags);
+ priv->shutdown = true;
+ spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
+
+ usb_kill_anchored_urbs(&priv->rx_anchor);
+ usb_kill_anchored_urbs(&priv->tx_anchor);
+ usb_kill_anchored_urbs(&priv->int_anchor);
+
+ rtl8723a_disable_rf(priv);
+
+ /*
+ * Disable interrupts
+ */
+ rtl8xxxu_write32(priv, REG_USB_HIMR, 0);
+
+ rtl8xxxu_free_rx_resources(priv);
+ rtl8xxxu_free_tx_resources(priv);
+}
+
+static const struct ieee80211_ops rtl8xxxu_ops = {
+ .tx = rtl8xxxu_tx,
+ .add_interface = rtl8xxxu_add_interface,
+ .remove_interface = rtl8xxxu_remove_interface,
+ .config = rtl8xxxu_config,
+ .conf_tx = rtl8xxxu_conf_tx,
+ .bss_info_changed = rtl8xxxu_bss_info_changed,
+ .configure_filter = rtl8xxxu_configure_filter,
+ .set_rts_threshold = rtl8xxxu_set_rts_threshold,
+ .start = rtl8xxxu_start,
+ .stop = rtl8xxxu_stop,
+ .sw_scan_start = rtl8xxxu_sw_scan_start,
+ .sw_scan_complete = rtl8xxxu_sw_scan_complete,
+ .set_key = rtl8xxxu_set_key,
+ .ampdu_action = rtl8xxxu_ampdu_action,
+};
+
+static int rtl8xxxu_parse_usb(struct rtl8xxxu_priv *priv,
+ struct usb_interface *interface)
+{
+ struct usb_interface_descriptor *interface_desc;
+ struct usb_host_interface *host_interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct device *dev = &priv->udev->dev;
+ int i, j = 0, endpoints;
+ u8 dir, xtype, num;
+ int ret = 0;
+
+ host_interface = &interface->altsetting[0];
+ interface_desc = &host_interface->desc;
+ endpoints = interface_desc->bNumEndpoints;
+
+ for (i = 0; i < endpoints; i++) {
+ endpoint = &host_interface->endpoint[i].desc;
+
+ dir = endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
+ num = usb_endpoint_num(endpoint);
+ xtype = usb_endpoint_type(endpoint);
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_USB)
+ dev_dbg(dev,
+ "%s: endpoint: dir %02x, # %02x, type %02x\n",
+ __func__, dir, num, xtype);
+ if (usb_endpoint_dir_in(endpoint) &&
+ usb_endpoint_xfer_bulk(endpoint)) {
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_USB)
+ dev_dbg(dev, "%s: in endpoint num %i\n",
+ __func__, num);
+
+ if (priv->pipe_in) {
+ dev_warn(dev,
+ "%s: Too many IN pipes\n", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ priv->pipe_in = usb_rcvbulkpipe(priv->udev, num);
+ }
+
+ if (usb_endpoint_dir_in(endpoint) &&
+ usb_endpoint_xfer_int(endpoint)) {
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_USB)
+ dev_dbg(dev, "%s: interrupt endpoint num %i\n",
+ __func__, num);
+
+ if (priv->pipe_interrupt) {
+ dev_warn(dev, "%s: Too many INTERRUPT pipes\n",
+ __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ priv->pipe_interrupt = usb_rcvintpipe(priv->udev, num);
+ }
+
+ if (usb_endpoint_dir_out(endpoint) &&
+ usb_endpoint_xfer_bulk(endpoint)) {
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_USB)
+ dev_dbg(dev, "%s: out endpoint num %i\n",
+ __func__, num);
+ if (j >= RTL8XXXU_OUT_ENDPOINTS) {
+ dev_warn(dev,
+ "%s: Too many OUT pipes\n", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+ priv->out_ep[j++] = num;
+ }
+ }
+exit:
+ priv->nr_out_eps = j;
+ return ret;
+}
+
+static int rtl8xxxu_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct rtl8xxxu_priv *priv;
+ struct ieee80211_hw *hw;
+ struct usb_device *udev;
+ struct ieee80211_supported_band *sband;
+ int ret = 0;
+ int untested = 1;
+
+ udev = usb_get_dev(interface_to_usbdev(interface));
+
+ switch (id->idVendor) {
+ case USB_VENDOR_ID_REALTEK:
+ switch(id->idProduct) {
+ case 0x1724:
+ case 0x8176:
+ case 0x8178:
+ case 0x817f:
+ untested = 0;
+ break;
+ }
+ break;
+ case 0x7392:
+ if (id->idProduct == 0x7811)
+ untested = 0;
+ break;
+ default:
+ break;
+ }
+
+ if (untested) {
+ rtl8xxxu_debug = RTL8XXXU_DEBUG_EFUSE;
+ dev_info(&udev->dev,
+ "This Realtek USB WiFi dongle (0x%04x:0x%04x) is untested!\n",
+ id->idVendor, id->idProduct);
+ dev_info(&udev->dev,
+ "Please report results to Jes.Sorensen@gmail.com\n");
+ }
+
+ hw = ieee80211_alloc_hw(sizeof(struct rtl8xxxu_priv), &rtl8xxxu_ops);
+ if (!hw) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+ priv->udev = udev;
+ priv->fops = (struct rtl8xxxu_fileops *)id->driver_info;
+ mutex_init(&priv->usb_buf_mutex);
+ mutex_init(&priv->h2c_mutex);
+ INIT_LIST_HEAD(&priv->tx_urb_free_list);
+ spin_lock_init(&priv->tx_urb_lock);
+ INIT_LIST_HEAD(&priv->rx_urb_pending_list);
+ spin_lock_init(&priv->rx_urb_lock);
+ INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work);
+
+ usb_set_intfdata(interface, hw);
+
+ ret = rtl8xxxu_parse_usb(priv, interface);
+ if (ret)
+ goto exit;
+
+ ret = rtl8xxxu_identify_chip(priv);
+ if (ret) {
+ dev_err(&udev->dev, "Fatal - failed to identify chip\n");
+ goto exit;
+ }
+
+ ret = rtl8xxxu_read_efuse(priv);
+ if (ret) {
+ dev_err(&udev->dev, "Fatal - failed to read EFuse\n");
+ goto exit;
+ }
+
+ ret = priv->fops->parse_efuse(priv);
+ if (ret) {
+ dev_err(&udev->dev, "Fatal - failed to parse EFuse\n");
+ goto exit;
+ }
+
+ rtl8xxxu_print_chipinfo(priv);
+
+ ret = priv->fops->load_firmware(priv);
+ if (ret) {
+ dev_err(&udev->dev, "Fatal - failed to load firmware\n");
+ goto exit;
+ }
+
+ ret = rtl8xxxu_init_device(hw);
+
+ hw->wiphy->max_scan_ssids = 1;
+ hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ hw->queues = 4;
+
+ sband = &rtl8xxxu_supported_band;
+ sband->ht_cap.ht_supported = true;
+ sband->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+ sband->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+ sband->ht_cap.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40;
+ memset(&sband->ht_cap.mcs, 0, sizeof(sband->ht_cap.mcs));
+ sband->ht_cap.mcs.rx_mask[0] = 0xff;
+ sband->ht_cap.mcs.rx_mask[4] = 0x01;
+ if (priv->rf_paths > 1) {
+ sband->ht_cap.mcs.rx_mask[1] = 0xff;
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+ }
+ sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+ /*
+ * Some APs will negotiate HT20_40 in a noisy environment leading
+ * to miserable performance. Rather than defaulting to this, only
+ * enable it if explicitly requested at module load time.
+ */
+ if (rtl8xxxu_ht40_2g) {
+ dev_info(&udev->dev, "Enabling HT_20_40 on the 2.4GHz band\n");
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ }
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+
+ hw->wiphy->rts_threshold = 2347;
+
+ SET_IEEE80211_DEV(priv->hw, &interface->dev);
+ SET_IEEE80211_PERM_ADDR(hw, priv->mac_addr);
+
+ hw->extra_tx_headroom = sizeof(struct rtl8xxxu_tx_desc);
+ ieee80211_hw_set(hw, SIGNAL_DBM);
+ /*
+ * The firmware handles rate control
+ */
+ ieee80211_hw_set(hw, HAS_RATE_CONTROL);
+ ieee80211_hw_set(hw, AMPDU_AGGREGATION);
+
+ ret = ieee80211_register_hw(priv->hw);
+ if (ret) {
+ dev_err(&udev->dev, "%s: Failed to register: %i\n",
+ __func__, ret);
+ goto exit;
+ }
+
+exit:
+ if (ret < 0)
+ usb_put_dev(udev);
+ return ret;
+}
+
+static void rtl8xxxu_disconnect(struct usb_interface *interface)
+{
+ struct rtl8xxxu_priv *priv;
+ struct ieee80211_hw *hw;
+
+ hw = usb_get_intfdata(interface);
+ priv = hw->priv;
+
+ rtl8xxxu_disable_device(hw);
+ usb_set_intfdata(interface, NULL);
+
+ dev_info(&priv->udev->dev, "disconnecting\n");
+
+ ieee80211_unregister_hw(hw);
+
+ kfree(priv->fw_data);
+ mutex_destroy(&priv->usb_buf_mutex);
+ mutex_destroy(&priv->h2c_mutex);
+
+ usb_put_dev(priv->udev);
+ ieee80211_free_hw(hw);
+}
+
+static struct rtl8xxxu_fileops rtl8723au_fops = {
+ .parse_efuse = rtl8723au_parse_efuse,
+ .load_firmware = rtl8723au_load_firmware,
+ .power_on = rtl8723au_power_on,
+ .writeN_block_size = 1024,
+};
+
+#ifdef CONFIG_RTL8XXXU_UNTESTED
+
+static struct rtl8xxxu_fileops rtl8192cu_fops = {
+ .parse_efuse = rtl8192cu_parse_efuse,
+ .load_firmware = rtl8192cu_load_firmware,
+ .power_on = rtl8192cu_power_on,
+ .writeN_block_size = 128,
+};
+
+#endif
+
+static struct usb_device_id dev_table[] = {
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8724, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8723au_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x1724, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8723au_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x0724, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8723au_fops},
+#ifdef CONFIG_RTL8XXXU_UNTESTED
+/* Still supported by rtlwifi */
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8176, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8178, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817f, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+/* Tested by Larry Finger */
+{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7811, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+/* Currently untested 8188 series devices */
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8191, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8170, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8177, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817a, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817b, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817d, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x817e, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818a, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x317f, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x1058, 0x0631, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x094c, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1102, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x06f8, 0xe033, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8189, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9041, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17ba, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x1e1e, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x5088, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0052, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x005c, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0eb0, 0x9071, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x103c, 0x1629, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x13d3, 0x3357, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3308, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330b, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0x4902, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab2a, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab2e, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xed17, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x648b, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x4855, 0x0090, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x4856, 0x0091, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0xcdab, 0x8010, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x317f, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops}, /* Netcore 8188RU */
+{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff7, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff9, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaffa, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff8, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaffb, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaffc, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0x1201, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+/* Currently untested 8192 series devices */
+{USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0950, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1004, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x2102, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x2103, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x341f, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x06f8, 0xe035, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17ab, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0061, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0070, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0789, 0x016d, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x07aa, 0x0056, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8178, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9021, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0xf001, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x2e2e, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0019, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0020, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3307, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3309, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330a, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab2b, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x624d, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0100, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x4855, 0x0091, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7822, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192cu_fops},
+#endif
+{ }
+};
+
+static struct usb_driver rtl8xxxu_driver = {
+ .name = DRIVER_NAME,
+ .probe = rtl8xxxu_probe,
+ .disconnect = rtl8xxxu_disconnect,
+ .id_table = dev_table,
+ .disable_hub_initiated_lpm = 1,
+};
+
+static int __init rtl8xxxu_module_init(void)
+{
+ int res;
+
+ res = usb_register(&rtl8xxxu_driver);
+ if (res < 0)
+ pr_err(DRIVER_NAME ": usb_register() failed (%i)\n", res);
+
+ return res;
+}
+
+static void __exit rtl8xxxu_module_exit(void)
+{
+ usb_deregister(&rtl8xxxu_driver);
+}
+
+
+MODULE_DEVICE_TABLE(usb, dev_table);
+
+module_init(rtl8xxxu_module_init);
+module_exit(rtl8xxxu_module_exit);
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
new file mode 100644
index 0000000..f2a1bac
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -0,0 +1,676 @@
+/*
+ * Copyright (c) 2014 - 2015 Jes Sorensen <Jes.Sorensen@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * Register definitions taken from original Realtek rtl8723au driver
+ */
+
+#include <asm/byteorder.h>
+
+#define RTL8XXXU_DEBUG_REG_WRITE 0x01
+#define RTL8XXXU_DEBUG_REG_READ 0x02
+#define RTL8XXXU_DEBUG_RFREG_WRITE 0x04
+#define RTL8XXXU_DEBUG_RFREG_READ 0x08
+#define RTL8XXXU_DEBUG_CHANNEL 0x10
+#define RTL8XXXU_DEBUG_TX 0x20
+#define RTL8XXXU_DEBUG_TX_DUMP 0x40
+#define RTL8XXXU_DEBUG_RX 0x80
+#define RTL8XXXU_DEBUG_RX_DUMP 0x100
+#define RTL8XXXU_DEBUG_USB 0x200
+#define RTL8XXXU_DEBUG_KEY 0x400
+#define RTL8XXXU_DEBUG_H2C 0x800
+#define RTL8XXXU_DEBUG_ACTION 0x1000
+#define RTL8XXXU_DEBUG_EFUSE 0x2000
+
+#define RTW_USB_CONTROL_MSG_TIMEOUT 500
+#define RTL8XXXU_MAX_REG_POLL 500
+#define USB_INTR_CONTENT_LENGTH 56
+
+#define RTL8XXXU_OUT_ENDPOINTS 3
+
+#define REALTEK_USB_READ 0xc0
+#define REALTEK_USB_WRITE 0x40
+#define REALTEK_USB_CMD_REQ 0x05
+#define REALTEK_USB_CMD_IDX 0x00
+
+#define TX_TOTAL_PAGE_NUM 0xf8
+/* (HPQ + LPQ + NPQ + PUBQ) = TX_TOTAL_PAGE_NUM */
+#define TX_PAGE_NUM_PUBQ 0xe7
+#define TX_PAGE_NUM_HI_PQ 0x0c
+#define TX_PAGE_NUM_LO_PQ 0x02
+#define TX_PAGE_NUM_NORM_PQ 0x02
+
+#define RTL_FW_PAGE_SIZE 4096
+#define RTL8XXXU_FIRMWARE_POLL_MAX 1000
+
+#define RTL8723A_CHANNEL_GROUPS 3
+#define RTL8723A_MAX_RF_PATHS 2
+#define RF6052_MAX_TX_PWR 0x3f
+
+#define EFUSE_MAP_LEN_8723A 256
+#define EFUSE_MAX_SECTION_8723A 32
+#define EFUSE_REAL_CONTENT_LEN_8723A 512
+#define EFUSE_BT_MAP_LEN_8723A 1024
+#define EFUSE_MAX_WORD_UNIT 4
+
+struct rtl8xxxu_rx_desc {
+#ifdef __LITTLE_ENDIAN
+ u32 pktlen:14;
+ u32 crc32:1;
+ u32 icverr:1;
+ u32 drvinfo_sz:4;
+ u32 security:3;
+ u32 qos:1;
+ u32 shift:2;
+ u32 phy_stats:1;
+ u32 swdec:1;
+ u32 ls:1;
+ u32 fs:1;
+ u32 eor:1;
+ u32 own:1;
+
+ u32 macid:5;
+ u32 tid:4;
+ u32 hwrsvd:4;
+ u32 amsdu:1;
+ u32 paggr:1;
+ u32 faggr:1;
+ u32 a1fit:4;
+ u32 a2fit:4;
+ u32 pam:1;
+ u32 pwr:1;
+ u32 md:1;
+ u32 mf:1;
+ u32 type:2;
+ u32 mc:1;
+ u32 bc:1;
+
+ u32 seq:12;
+ u32 frag:4;
+ u32 nextpktlen:14;
+ u32 nextind:1;
+ u32 reserved0:1;
+
+ u32 rxmcs:6;
+ u32 rxht:1;
+ u32 gf:1;
+ u32 splcp:1;
+ u32 bw:1;
+ u32 htc:1;
+ u32 eosp:1;
+ u32 bssidfit:2;
+ u32 reserved1:16;
+ u32 unicastwake:1;
+ u32 magicwake:1;
+
+ u32 pattern0match:1;
+ u32 pattern1match:1;
+ u32 pattern2match:1;
+ u32 pattern3match:1;
+ u32 pattern4match:1;
+ u32 pattern5match:1;
+ u32 pattern6match:1;
+ u32 pattern7match:1;
+ u32 pattern8match:1;
+ u32 pattern9match:1;
+ u32 patternamatch:1;
+ u32 patternbmatch:1;
+ u32 patterncmatch:1;
+ u32 reserved2:19;
+#else
+ u32 own:1;
+ u32 eor:1;
+ u32 fs:1;
+ u32 ls:1;
+ u32 swdec:1;
+ u32 phy_stats:1;
+ u32 shift:2;
+ u32 qos:1;
+ u32 security:3;
+ u32 drvinfo_sz:4;
+ u32 icverr:1;
+ u32 crc32:1;
+ u32 pktlen:14;
+
+ u32 bc:1;
+ u32 mc:1;
+ u32 type:2;
+ u32 mf:1;
+ u32 md:1;
+ u32 pwr:1;
+ u32 pam:1;
+ u32 a2fit:4;
+ u32 a1fit:4;
+ u32 faggr:1;
+ u32 paggr:1;
+ u32 amsdu:1;
+ u32 hwrsvd:4;
+ u32 tid:4;
+ u32 macid:5;
+
+ u32 reserved0:1;
+ u32 nextind:1;
+ u32 nextpktlen:14;
+ u32 frag:4;
+ u32 seq:12;
+
+ u32 magicwake:1;
+ u32 unicastwake:1;
+ u32 reserved1:16;
+ u32 bssidfit:2;
+ u32 eosp:1;
+ u32 htc:1;
+ u32 bw:1;
+ u32 splcp:1;
+ u32 gf:1;
+ u32 rxht:1;
+ u32 rxmcs:6;
+
+ u32 reserved2:19;
+ u32 patterncmatch:1;
+ u32 patternbmatch:1;
+ u32 patternamatch:1;
+ u32 pattern9match:1;
+ u32 pattern8match:1;
+ u32 pattern7match:1;
+ u32 pattern6match:1;
+ u32 pattern5match:1;
+ u32 pattern4match:1;
+ u32 pattern3match:1;
+ u32 pattern2match:1;
+ u32 pattern1match:1;
+ u32 pattern0match:1;
+#endif
+ __le32 tsfl;
+#if 0
+ u32 bassn:12;
+ u32 bavld:1;
+ u32 reserved3:19;
+#endif
+};
+
+struct rtl8xxxu_tx_desc {
+ __le16 pkt_size;
+ u8 pkt_offset;
+ u8 txdw0;
+ __le32 txdw1;
+ __le32 txdw2;
+ __le32 txdw3;
+ __le32 txdw4;
+ __le32 txdw5;
+ __le32 txdw6;
+ __le16 csum;
+ __le16 txdw7;
+};
+
+/* CCK Rates, TxHT = 0 */
+#define DESC_RATE_1M 0x00
+#define DESC_RATE_2M 0x01
+#define DESC_RATE_5_5M 0x02
+#define DESC_RATE_11M 0x03
+
+/* OFDM Rates, TxHT = 0 */
+#define DESC_RATE_6M 0x04
+#define DESC_RATE_9M 0x05
+#define DESC_RATE_12M 0x06
+#define DESC_RATE_18M 0x07
+#define DESC_RATE_24M 0x08
+#define DESC_RATE_36M 0x09
+#define DESC_RATE_48M 0x0a
+#define DESC_RATE_54M 0x0b
+
+/* MCS Rates, TxHT = 1 */
+#define DESC_RATE_MCS0 0x0c
+#define DESC_RATE_MCS1 0x0d
+#define DESC_RATE_MCS2 0x0e
+#define DESC_RATE_MCS3 0x0f
+#define DESC_RATE_MCS4 0x10
+#define DESC_RATE_MCS5 0x11
+#define DESC_RATE_MCS6 0x12
+#define DESC_RATE_MCS7 0x13
+#define DESC_RATE_MCS8 0x14
+#define DESC_RATE_MCS9 0x15
+#define DESC_RATE_MCS10 0x16
+#define DESC_RATE_MCS11 0x17
+#define DESC_RATE_MCS12 0x18
+#define DESC_RATE_MCS13 0x19
+#define DESC_RATE_MCS14 0x1a
+#define DESC_RATE_MCS15 0x1b
+#define DESC_RATE_MCS15_SG 0x1c
+#define DESC_RATE_MCS32 0x20
+
+#define TXDESC_OFFSET_SZ 0
+#define TXDESC_OFFSET_SHT 16
+#if 0
+#define TXDESC_BMC BIT(24)
+#define TXDESC_LSG BIT(26)
+#define TXDESC_FSG BIT(27)
+#define TXDESC_OWN BIT(31)
+#else
+#define TXDESC_BROADMULTICAST BIT(0)
+#define TXDESC_LAST_SEGMENT BIT(2)
+#define TXDESC_FIRST_SEGMENT BIT(3)
+#define TXDESC_OWN BIT(7)
+#endif
+
+/* Word 1 */
+#define TXDESC_PKT_OFFSET_SZ 0
+#define TXDESC_AGG_ENABLE BIT(5)
+#define TXDESC_BK BIT(6)
+#define TXDESC_QUEUE_SHIFT 8
+#define TXDESC_QUEUE_MASK 0x1f00
+#define TXDESC_QUEUE_BK 0x2
+#define TXDESC_QUEUE_BE 0x0
+#define TXDESC_QUEUE_VI 0x5
+#define TXDESC_QUEUE_VO 0x7
+#define TXDESC_QUEUE_BEACON 0x10
+#define TXDESC_QUEUE_HIGH 0x11
+#define TXDESC_QUEUE_MGNT 0x12
+#define TXDESC_QUEUE_CMD 0x13
+#define TXDESC_QUEUE_MAX (TXDESC_QUEUE_CMD + 1)
+
+#define DESC_RATE_ID_SHIFT 16
+#define DESC_RATE_ID_MASK 0xf
+#define TXDESC_NAVUSEHDR BIT(20)
+#define TXDESC_SEC_RC4 0x00400000
+#define TXDESC_SEC_AES 0x00c00000
+#define TXDESC_PKT_OFFSET_SHIFT 26
+#define TXDESC_AGG_EN BIT(29)
+#define TXDESC_HWPC BIT(31)
+
+/* Word 2 */
+#define TXDESC_ACK_REPORT BIT(19)
+#define TXDESC_AMPDU_DENSITY_SHIFT 20
+
+/* Word 3 */
+#define TXDESC_SEQ_SHIFT 16
+#define TXDESC_SEQ_MASK 0x0fff0000
+
+/* Word 4 */
+#define TXDESC_QOS BIT(6)
+#define TXDESC_HW_SEQ_ENABLE BIT(7)
+#define TXDESC_USE_DRIVER_RATE BIT(8)
+#define TXDESC_DISABLE_DATA_FB BIT(10)
+#define TXDESC_CTS_SELF_ENABLE BIT(11)
+#define TXDESC_RTS_CTS_ENABLE BIT(12)
+#define TXDESC_HW_RTS_ENABLE BIT(13)
+#define TXDESC_PRIME_CH_OFF_LOWER BIT(20)
+#define TXDESC_PRIME_CH_OFF_UPPER BIT(21)
+#define TXDESC_SHORT_PREAMBLE BIT(24)
+#define TXDESC_DATA_BW BIT(25)
+#define TXDESC_RTS_DATA_BW BIT(27)
+#define TXDESC_RTS_PRIME_CH_OFF_LOWER BIT(28)
+#define TXDESC_RTS_PRIME_CH_OFF_UPPER BIT(29)
+
+/* Word 5 */
+#define TXDESC_RTS_RATE_SHIFT 0
+#define TXDESC_RTS_RATE_MASK 0x3f
+#define TXDESC_SHORT_GI BIT(6)
+#define TXDESC_CCX_TAG BIT(7)
+#define TXDESC_RETRY_LIMIT_ENABLE BIT(17)
+#define TXDESC_RETRY_LIMIT_SHIFT 18
+#define TXDESC_RETRY_LIMIT_MASK 0x00fc0000
+
+/* Word 6 */
+#define TXDESC_MAX_AGG_SHIFT 11
+
+struct phy_rx_agc_info {
+#ifdef __LITTLE_ENDIAN
+ u8 gain:7, trsw:1;
+#else
+ u8 trsw:1, gain:7;
+#endif
+};
+
+struct rtl8723au_phy_stats {
+ struct phy_rx_agc_info path_agc[RTL8723A_MAX_RF_PATHS];
+ u8 ch_corr[RTL8723A_MAX_RF_PATHS];
+ u8 cck_sig_qual_ofdm_pwdb_all;
+ u8 cck_agc_rpt_ofdm_cfosho_a;
+ u8 cck_rpt_b_ofdm_cfosho_b;
+ u8 reserved_1;
+ u8 noise_power_db_msb;
+ u8 path_cfotail[RTL8723A_MAX_RF_PATHS];
+ u8 pcts_mask[RTL8723A_MAX_RF_PATHS];
+ s8 stream_rxevm[RTL8723A_MAX_RF_PATHS];
+ u8 path_rxsnr[RTL8723A_MAX_RF_PATHS];
+ u8 noise_power_db_lsb;
+ u8 reserved_2[3];
+ u8 stream_csi[RTL8723A_MAX_RF_PATHS];
+ u8 stream_target_csi[RTL8723A_MAX_RF_PATHS];
+ s8 sig_evm;
+ u8 reserved_3;
+
+#ifdef __LITTLE_ENDIAN
+ u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */
+ u8 sgi_en:1;
+ u8 rxsc:2;
+ u8 idle_long:1;
+ u8 r_ant_train_en:1;
+ u8 antenna_select_b:1;
+ u8 antenna_select:1;
+#else /* _BIG_ENDIAN_ */
+ u8 antenna_select:1;
+ u8 antenna_select_b:1;
+ u8 r_ant_train_en:1;
+ u8 idle_long:1;
+ u8 rxsc:2;
+ u8 sgi_en:1;
+ u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */
+#endif
+};
+
+/*
+ * Regs to backup
+ */
+#define RTL8XXXU_ADDA_REGS 16
+#define RTL8XXXU_MAC_REGS 4
+#define RTL8XXXU_BB_REGS 9
+
+struct rtl8xxxu_firmware_header {
+ __le16 signature; /* 92C0: test chip; 92C,
+ 88C0: test chip;
+ 88C1: MP A-cut;
+ 92C1: MP A-cut */
+ u8 category; /* AP/NIC and USB/PCI */
+ u8 function;
+
+ __le16 major_version; /* FW Version */
+ u8 minor_version; /* FW Subversion, default 0x00 */
+ u8 reserved1;
+
+ u8 month; /* Release time Month field */
+ u8 date; /* Release time Date field */
+ u8 hour; /* Release time Hour field */
+ u8 minute; /* Release time Minute field */
+
+ __le16 ramcodesize; /* Size of RAM code */
+ u16 reserved2;
+
+ __le32 svn_idx; /* SVN entry index */
+ u32 reserved3;
+
+ u32 reserved4;
+ u32 reserved5;
+
+ u8 data[0];
+};
+
+/*
+ * The 8723au has 3 channel groups: 1-3, 4-9, and 10-14
+ */
+struct rtl8723au_idx {
+#ifdef __LITTLE_ENDIAN
+ int a:4;
+ int b:4;
+#else
+ int b:4;
+ int a:4;
+#endif
+} __attribute__((packed));
+
+struct rtl8723au_efuse {
+ __le16 rtl_id;
+ u8 res0[0xe];
+ u8 cck_tx_power_index_A[3]; /* 0x10 */
+ u8 cck_tx_power_index_B[3];
+ u8 ht40_1s_tx_power_index_A[3]; /* 0x16 */
+ u8 ht40_1s_tx_power_index_B[3];
+ /*
+ * The following entries are half-bytes split as:
+ * bits 0-3: path A, bits 4-7: path B, all values 4 bits signed
+ */
+ struct rtl8723au_idx ht20_tx_power_index_diff[3];
+ struct rtl8723au_idx ofdm_tx_power_index_diff[3];
+ struct rtl8723au_idx ht40_max_power_offset[3];
+ struct rtl8723au_idx ht20_max_power_offset[3];
+ u8 channel_plan; /* 0x28 */
+ u8 tssi_a;
+ u8 thermal_meter;
+ u8 rf_regulatory;
+ u8 rf_option_2;
+ u8 rf_option_3;
+ u8 rf_option_4;
+ u8 res7;
+ u8 version /* 0x30 */;
+ u8 customer_id_major;
+ u8 customer_id_minor;
+ u8 xtal_k;
+ u8 chipset; /* 0x34 */
+ u8 res8[0x82];
+ u8 vid; /* 0xb7 */
+ u8 res9;
+ u8 pid; /* 0xb9 */
+ u8 res10[0x0c];
+ u8 mac_addr[ETH_ALEN]; /* 0xc6 */
+ u8 res11[2];
+ u8 vendor_name[7];
+ u8 res12[2];
+ u8 device_name[0x29]; /* 0xd7 */
+};
+
+struct rtl8192cu_efuse {
+ __le16 rtl_id;
+ __le16 hpon;
+ u8 res0[2];
+ __le16 clk;
+ __le16 testr;
+ __le16 vid;
+ __le16 did;
+ __le16 svid;
+ __le16 smid; /* 0x10 */
+ u8 res1[4];
+ u8 mac_addr[ETH_ALEN]; /* 0x16 */
+ u8 res2[2];
+ u8 vendor_name[7];
+ u8 res3[3];
+ u8 device_name[0x14]; /* 0x28 */
+ u8 res4[0x1e]; /* 0x3c */
+ u8 cck_tx_power_index_A[3]; /* 0x5a */
+ u8 cck_tx_power_index_B[3];
+ u8 ht40_1s_tx_power_index_A[3]; /* 0x60 */
+ u8 ht40_1s_tx_power_index_B[3];
+ /*
+ * The following entries are half-bytes split as:
+ * bits 0-3: path A, bits 4-7: path B, all values 4 bits signed
+ */
+ struct rtl8723au_idx ht40_2s_tx_power_index_diff[3];
+ struct rtl8723au_idx ht20_tx_power_index_diff[3]; /* 0x69 */
+ struct rtl8723au_idx ofdm_tx_power_index_diff[3];
+ struct rtl8723au_idx ht40_max_power_offset[3]; /* 0x6f */
+ struct rtl8723au_idx ht20_max_power_offset[3];
+ u8 channel_plan; /* 0x75 */
+ u8 tssi_a;
+ u8 tssi_b;
+ u8 thermal_meter; /* xtal_k */ /* 0x78 */
+ u8 rf_regulatory;
+ u8 rf_option_2;
+ u8 rf_option_3;
+ u8 rf_option_4;
+ u8 res5[1]; /* 0x7d */
+ u8 version;
+ u8 customer_id;
+};
+
+struct rtl8xxxu_reg8val {
+ u16 reg;
+ u8 val;
+};
+
+struct rtl8xxxu_reg32val {
+ u16 reg;
+ u32 val;
+};
+
+struct rtl8xxxu_rfregval {
+ u8 reg;
+ u32 val;
+};
+
+enum rtl8xxxu_rfpath {
+ RF_A = 0,
+ RF_B = 1,
+};
+
+struct rtl8xxxu_rfregs {
+ u16 hssiparm1;
+ u16 hssiparm2;
+ u16 lssiparm;
+ u16 hspiread;
+ u16 lssiread;
+ u16 rf_sw_ctrl;
+};
+
+#define H2C_MAX_MBOX 4
+#define H2C_EXT BIT(7)
+#define H2C_SET_POWER_MODE 1
+#define H2C_JOIN_BSS_REPORT 2
+#define H2C_JOIN_BSS_DISCONNECT 0
+#define H2C_JOIN_BSS_CONNECT 1
+#define H2C_SET_RSSI 5
+#define H2C_SET_RATE_MASK (6 | H2C_EXT)
+
+struct h2c_cmd {
+ union {
+ struct {
+ u8 cmd;
+ u8 data[5];
+ } __packed cmd;
+ struct {
+ __le32 data;
+ __le16 ext;
+ } __packed raw;
+ struct {
+ u8 cmd;
+ u8 data;
+ u8 pad[4];
+ } __packed joinbss;
+ struct {
+ u8 cmd;
+ __le16 mask_hi;
+ u8 arg;
+ __le16 mask_lo;
+ } __packed ramask;
+ };
+};
+
+struct rtl8xxxu_fileops;
+
+struct rtl8xxxu_priv {
+ struct ieee80211_hw *hw;
+ struct usb_device *udev;
+ struct rtl8xxxu_fileops *fops;
+
+ spinlock_t tx_urb_lock;
+ struct list_head tx_urb_free_list;
+ int tx_urb_free_count;
+ bool tx_stopped;
+
+ spinlock_t rx_urb_lock;
+ struct list_head rx_urb_pending_list;
+ int rx_urb_pending_count;
+ bool shutdown;
+ struct work_struct rx_urb_wq;
+
+ u8 mac_addr[ETH_ALEN];
+ char chip_name[8];
+ u8 cck_tx_power_index_A[3]; /* 0x10 */
+ u8 cck_tx_power_index_B[3];
+ u8 ht40_1s_tx_power_index_A[3]; /* 0x16 */
+ u8 ht40_1s_tx_power_index_B[3];
+ /*
+ * The following entries are half-bytes split as:
+ * bits 0-3: path A, bits 4-7: path B, all values 4 bits signed
+ */
+ struct rtl8723au_idx ht40_2s_tx_power_index_diff[3];
+ struct rtl8723au_idx ht20_tx_power_index_diff[3];
+ struct rtl8723au_idx ofdm_tx_power_index_diff[3];
+ struct rtl8723au_idx ht40_max_power_offset[3];
+ struct rtl8723au_idx ht20_max_power_offset[3];
+ u32 chip_cut:4;
+ u32 rom_rev:4;
+ u32 has_wifi:1;
+ u32 has_bluetooth:1;
+ u32 enable_bluetooth:1;
+ u32 has_gps:1;
+ u32 hi_pa:1;
+ u32 vendor_umc:1;
+ u32 has_polarity_ctrl:1;
+ u32 has_eeprom:1;
+ u32 boot_eeprom:1;
+ u32 ep_tx_high_queue:1;
+ u32 ep_tx_normal_queue:1;
+ u32 ep_tx_low_queue:1;
+ u32 path_a_hi_power:1;
+ u32 path_a_rf_paths:4;
+ unsigned int pipe_interrupt;
+ unsigned int pipe_in;
+ unsigned int pipe_out[TXDESC_QUEUE_MAX];
+ u8 out_ep[RTL8XXXU_OUT_ENDPOINTS];
+ u8 path_a_ig_value;
+ u8 ep_tx_count;
+ u8 rf_paths;
+ u8 rx_paths;
+ u8 tx_paths;
+ u32 rf_mode_ag[2];
+ u32 rege94;
+ u32 rege9c;
+ u32 regeb4;
+ u32 regebc;
+ int next_mbox;
+ int nr_out_eps;
+
+ struct mutex h2c_mutex;
+
+ struct usb_anchor rx_anchor;
+ struct usb_anchor tx_anchor;
+ struct usb_anchor int_anchor;
+ struct rtl8xxxu_firmware_header *fw_data;
+ size_t fw_size;
+ struct mutex usb_buf_mutex;
+ union {
+ __le32 val32;
+ __le16 val16;
+ u8 val8;
+ } usb_buf;
+ union {
+ u8 raw[EFUSE_MAP_LEN_8723A];
+ struct rtl8723au_efuse efuse8723;
+ struct rtl8192cu_efuse efuse8192;
+ } efuse_wifi;
+ u32 adda_backup[RTL8XXXU_ADDA_REGS];
+ u32 mac_backup[RTL8XXXU_MAC_REGS];
+ u32 bb_backup[RTL8XXXU_BB_REGS];
+ u32 bb_recovery_backup[RTL8XXXU_BB_REGS];
+ u32 rtlchip;
+ u8 pi_enabled:1;
+ u8 iqk_initialized:1;
+ u8 int_buf[USB_INTR_CONTENT_LENGTH];
+};
+
+struct rtl8xxxu_rx_urb {
+ struct urb urb;
+ struct ieee80211_hw *hw;
+ struct list_head list;
+};
+
+struct rtl8xxxu_tx_urb {
+ struct urb urb;
+ struct ieee80211_hw *hw;
+ struct list_head list;
+};
+
+struct rtl8xxxu_fileops {
+ int (*parse_efuse) (struct rtl8xxxu_priv *priv);
+ int (*load_firmware) (struct rtl8xxxu_priv *priv);
+ int (*power_on) (struct rtl8xxxu_priv *priv);
+ int writeN_block_size;
+};
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
new file mode 100644
index 0000000..23208f7
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
@@ -0,0 +1,981 @@
+/*
+ * Copyright (c) 2014 - 2015 Jes Sorensen <Jes.Sorensen@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * Register definitions taken from original Realtek rtl8723au driver
+ */
+
+/* 0x0000 ~ 0x00FF System Configuration */
+#define REG_SYS_ISO_CTRL 0x0000
+#define SYS_ISO_MD2PP BIT(0)
+#define SYS_ISO_ANALOG_IPS BIT(5)
+#define SYS_ISO_DIOR BIT(9)
+#define SYS_ISO_PWC_EV25V BIT(14)
+#define SYS_ISO_PWC_EV12V BIT(15)
+
+#define REG_SYS_FUNC 0x0002
+#define SYS_FUNC_BBRSTB BIT(0)
+#define SYS_FUNC_BB_GLB_RSTN BIT(1)
+#define SYS_FUNC_USBA BIT(2)
+#define SYS_FUNC_UPLL BIT(3)
+#define SYS_FUNC_USBD BIT(4)
+#define SYS_FUNC_DIO_PCIE BIT(5)
+#define SYS_FUNC_PCIEA BIT(6)
+#define SYS_FUNC_PPLL BIT(7)
+#define SYS_FUNC_PCIED BIT(8)
+#define SYS_FUNC_DIOE BIT(9)
+#define SYS_FUNC_CPU_ENABLE BIT(10)
+#define SYS_FUNC_DCORE BIT(11)
+#define SYS_FUNC_ELDR BIT(12)
+#define SYS_FUNC_DIO_RF BIT(13)
+#define SYS_FUNC_HWPDN BIT(14)
+#define SYS_FUNC_MREGEN BIT(15)
+
+#define REG_APS_FSMCO 0x0004
+#define APS_FSMCO_PFM_ALDN BIT(1)
+#define APS_FSMCO_PFM_WOWL BIT(3)
+#define APS_FSMCO_ENABLE_POWERDOWN BIT(4)
+#define APS_FSMCO_MAC_ENABLE BIT(8)
+#define APS_FSMCO_MAC_OFF BIT(9)
+#define APS_FSMCO_HW_SUSPEND BIT(11)
+#define APS_FSMCO_PCIE BIT(12)
+#define APS_FSMCO_HW_POWERDOWN BIT(15)
+#define APS_FSMCO_WLON_RESET BIT(16)
+
+#define REG_SYS_CLKR 0x0008
+#define SYS_CLK_ANAD16V_ENABLE BIT(0)
+#define SYS_CLK_ANA8M BIT(1)
+#define SYS_CLK_MACSLP BIT(4)
+#define SYS_CLK_LOADER_ENABLE BIT(5)
+#define SYS_CLK_80M_SSC_DISABLE BIT(7)
+#define SYS_CLK_80M_SSC_ENABLE_HO BIT(8)
+#define SYS_CLK_PHY_SSC_RSTB BIT(9)
+#define SYS_CLK_SEC_CLK_ENABLE BIT(10)
+#define SYS_CLK_MAC_CLK_ENABLE BIT(11)
+#define SYS_CLK_ENABLE BIT(12)
+#define SYS_CLK_RING_CLK_ENABLE BIT(13)
+
+#define REG_9346CR 0x000a
+#define EEPROM_BOOT BIT(4)
+#define EEPROM_ENABLE BIT(5)
+
+#define REG_EE_VPD 0x000c
+#define REG_AFE_MISC 0x0010
+#define REG_SPS0_CTRL 0x0011
+#define REG_SPS_OCP_CFG 0x0018
+#define REG_RSV_CTRL 0x001c
+
+#define REG_RF_CTRL 0x001f
+#define RF_ENABLE BIT(0)
+#define RF_RSTB BIT(1)
+#define RF_SDMRSTB BIT(2)
+
+#define REG_LDOA15_CTRL 0x0020
+#define LDOA15_ENABLE BIT(0)
+#define LDOA15_STANDBY BIT(1)
+#define LDOA15_OBUF BIT(2)
+#define LDOA15_REG_VOS BIT(3)
+#define LDOA15_VOADJ_SHIFT 4
+
+#define REG_LDOV12D_CTRL 0x0021
+#define LDOV12D_ENABLE BIT(0)
+#define LDOV12D_STANDBY BIT(1)
+#define LDOV12D_VADJ_SHIFT 4
+
+#define REG_LDOHCI12_CTRL 0x0022
+
+#define REG_LPLDO_CTRL 0x0023
+#define LPLDO_HSM BIT(2)
+#define LPLDO_LSM_DIS BIT(3)
+
+#define REG_AFE_XTAL_CTRL 0x0024
+#define AFE_XTAL_ENABLE BIT(0)
+#define AFE_XTAL_B_SELECT BIT(1)
+#define AFE_XTAL_GATE_USB BIT(8)
+#define AFE_XTAL_GATE_AFE BIT(11)
+#define AFE_XTAL_RF_GATE BIT(14)
+#define AFE_XTAL_GATE_DIG BIT(17)
+#define AFE_XTAL_BT_GATE BIT(20)
+
+#define REG_AFE_PLL_CTRL 0x0028
+#define AFE_PLL_ENABLE BIT(0)
+#define AFE_PLL_320_ENABLE BIT(1)
+#define APE_PLL_FREF_SELECT BIT(2)
+#define AFE_PLL_EDGE_SELECT BIT(3)
+#define AFE_PLL_WDOGB BIT(4)
+#define AFE_PLL_LPF_ENABLE BIT(5)
+
+#define REG_MAC_PHY_CTRL 0x002c
+
+#define REG_EFUSE_CTRL 0x0030
+#define REG_EFUSE_TEST 0x0034
+#define EFUSE_TRPT BIT(7)
+ /* 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 */
+#define EFUSE_CELL_SEL (BIT(8) | BIT(9))
+#define EFUSE_LDOE25_ENABLE BIT(31)
+#define EFUSE_SELECT_MASK 0x0300
+#define EFUSE_WIFI_SELECT 0x0000
+#define EFUSE_BT0_SELECT 0x0100
+#define EFUSE_BT1_SELECT 0x0200
+#define EFUSE_BT2_SELECT 0x0300
+
+#define EFUSE_ACCESS_ENABLE 0x69 /* RTL8723 only */
+#define EFUSE_ACCESS_DISABLE 0x00 /* RTL8723 only */
+
+#define REG_PWR_DATA 0x0038
+#define REG_CAL_TIMER 0x003c
+#define REG_ACLK_MON 0x003e
+#define REG_GPIO_MUXCFG 0x0040
+#define REG_GPIO_IO_SEL 0x0042
+#define REG_MAC_PINMUX_CFG 0x0043
+#define REG_GPIO_PIN_CTRL 0x0044
+#define REG_GPIO_INTM 0x0048
+#define REG_LEDCFG0 0x004c
+#define REG_LEDCFG1 0x004d
+#define REG_LEDCFG2 0x004e
+#define LEDCFG2_DPDT_SELECT BIT(7)
+#define REG_LEDCFG3 0x004f
+#define REG_LEDCFG REG_LEDCFG2
+#define REG_FSIMR 0x0050
+#define REG_FSISR 0x0054
+#define REG_HSIMR 0x0058
+#define REG_HSISR 0x005c
+/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. */
+#define REG_GPIO_PIN_CTRL_2 0x0060
+/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. */
+#define REG_GPIO_IO_SEL_2 0x0062
+
+/* RTL8723 only WIFI/BT/GPS Multi-Function control source. */
+#define REG_MULTI_FUNC_CTRL 0x0068
+
+#define MULTI_FN_WIFI_HW_PWRDOWN_EN BIT(0) /* Enable GPIO[9] as WiFi HW
+ powerdown source */
+#define MULTI_FN_WIFI_HW_PWRDOWN_SL BIT(1) /* WiFi HW powerdown polarity
+ control */
+#define MULTI_WIFI_FUNC_EN BIT(2) /* WiFi function enable */
+
+#define MULTI_WIFI_HW_ROF_EN BIT(3) /* Enable GPIO[9] as WiFi RF HW
+ powerdown source */
+#define MULTI_BT_HW_PWRDOWN_EN BIT(16) /* Enable GPIO[11] as BT HW
+ powerdown source */
+#define MULTI_BT_HW_PWRDOWN_SL BIT(17) /* BT HW powerdown polarity
+ control */
+#define MULTI_BT_FUNC_EN BIT(18) /* BT function enable */
+#define MULTI_BT_HW_ROF_EN BIT(19) /* Enable GPIO[11] as BT/GPS
+ RF HW powerdown source */
+#define MULTI_GPS_HW_PWRDOWN_EN BIT(20) /* Enable GPIO[10] as GPS HW
+ powerdown source */
+#define MULTI_GPS_HW_PWRDOWN_SL BIT(21) /* GPS HW powerdown polarity
+ control */
+#define MULTI_GPS_FUNC_EN BIT(22) /* GPS function enable */
+
+#define REG_MCU_FW_DL 0x0080
+#define MCU_FW_DL_ENABLE BIT(0)
+#define MCU_FW_DL_READY BIT(1)
+#define MCU_FW_DL_CSUM_REPORT BIT(2)
+#define MCU_MAC_INIT_READY BIT(3)
+#define MCU_BB_INIT_READY BIT(4)
+#define MCU_RF_INIT_READY BIT(5)
+#define MCU_WINT_INIT_READY BIT(6)
+#define MCU_FW_RAM_SEL BIT(7) /* 1: RAM, 0:ROM */
+#define MCU_CP_RESET BIT(23)
+
+#define REG_HMBOX_EXT_0 0x0088
+#define REG_HMBOX_EXT_1 0x008a
+#define REG_HMBOX_EXT_2 0x008c
+#define REG_HMBOX_EXT_3 0x008e
+/* Host suspend counter on FPGA platform */
+#define REG_HOST_SUSP_CNT 0x00bc
+/* Efuse access protection for RTL8723 */
+#define REG_EFUSE_ACCESS 0x00cf
+#define REG_BIST_SCAN 0x00d0
+#define REG_BIST_RPT 0x00d4
+#define REG_BIST_ROM_RPT 0x00d8
+#define REG_USB_SIE_INTF 0x00e0
+#define REG_PCIE_MIO_INTF 0x00e4
+#define REG_PCIE_MIO_INTD 0x00e8
+#define REG_HPON_FSM 0x00ec
+#define HPON_FSM_BONDING_MASK (BIT(22) | BIT(23))
+#define HPON_FSM_BONDING_1T2R BIT(22)
+#define REG_SYS_CFG 0x00f0
+#define SYS_CFG_XCLK_VLD BIT(0)
+#define SYS_CFG_ACLK_VLD BIT(1)
+#define SYS_CFG_UCLK_VLD BIT(2)
+#define SYS_CFG_PCLK_VLD BIT(3)
+#define SYS_CFG_PCIRSTB BIT(4)
+#define SYS_CFG_V15_VLD BIT(5)
+#define SYS_CFG_TRP_B15V_EN BIT(7)
+#define SYS_CFG_SIC_IDLE BIT(8)
+#define SYS_CFG_BD_MAC2 BIT(9)
+#define SYS_CFG_BD_MAC1 BIT(10)
+#define SYS_CFG_IC_MACPHY_MODE BIT(11)
+#define SYS_CFG_CHIP_VER (BIT(12) | BIT(13) | BIT(14) | BIT(15))
+#define SYS_CFG_BT_FUNC BIT(16)
+#define SYS_CFG_VENDOR_ID BIT(19)
+#define SYS_CFG_PAD_HWPD_IDN BIT(22)
+#define SYS_CFG_TRP_VAUX_EN BIT(23)
+#define SYS_CFG_TRP_BT_EN BIT(24)
+#define SYS_CFG_BD_PKG_SEL BIT(25)
+#define SYS_CFG_BD_HCI_SEL BIT(26)
+#define SYS_CFG_TYPE_ID BIT(27)
+#define SYS_CFG_RTL_ID BIT(23) /* TestChip ID,
+ 1:Test(RLE); 0:MP(RL) */
+#define SYS_CFG_SPS_SEL BIT(24) /* 1:LDO regulator mode;
+ 0:Switching regulator mode*/
+#define SYS_CFG_CHIP_VERSION_MASK 0xf000 /* Bit 12 - 15 */
+#define SYS_CFG_CHIP_VERSION_SHIFT 12
+
+#define REG_GPIO_OUTSTS 0x00f4 /* For RTL8723 only. */
+#define GPIO_EFS_HCI_SEL (BIT(0) | BIT(1))
+#define GPIO_PAD_HCI_SEL (BIT(2) | BIT(3))
+#define GPIO_HCI_SEL (BIT(4) | BIT(5))
+#define GPIO_PKG_SEL_HCI BIT(6)
+#define GPIO_FEN_GPS BIT(7)
+#define GPIO_FEN_BT BIT(8)
+#define GPIO_FEN_WL BIT(9)
+#define GPIO_FEN_PCI BIT(10)
+#define GPIO_FEN_USB BIT(11)
+#define GPIO_BTRF_HWPDN_N BIT(12)
+#define GPIO_WLRF_HWPDN_N BIT(13)
+#define GPIO_PDN_BT_N BIT(14)
+#define GPIO_PDN_GPS_N BIT(15)
+#define GPIO_BT_CTL_HWPDN BIT(16)
+#define GPIO_GPS_CTL_HWPDN BIT(17)
+#define GPIO_PPHY_SUSB BIT(20)
+#define GPIO_UPHY_SUSB BIT(21)
+#define GPIO_PCI_SUSEN BIT(22)
+#define GPIO_USB_SUSEN BIT(23)
+#define GPIO_RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28))
+
+/* 0x0100 ~ 0x01FF MACTOP General Configuration */
+#define REG_CR 0x0100
+#define CR_HCI_TXDMA_ENABLE BIT(0)
+#define CR_HCI_RXDMA_ENABLE BIT(1)
+#define CR_TXDMA_ENABLE BIT(2)
+#define CR_RXDMA_ENABLE BIT(3)
+#define CR_PROTOCOL_ENABLE BIT(4)
+#define CR_SCHEDULE_ENABLE BIT(5)
+#define CR_MAC_TX_ENABLE BIT(6)
+#define CR_MAC_RX_ENABLE BIT(7)
+#define CR_SW_BEACON_ENABLE BIT(8)
+#define CR_SECURITY_ENABLE BIT(9)
+#define CR_CALTIMER_ENABLE BIT(10)
+
+/* Media Status Register */
+#define REG_MSR 0x0102
+#define MSR_LINKTYPE_MASK 0x3
+#define MSR_LINKTYPE_NONE 0x0
+#define MSR_LINKTYPE_ADHOC 0x1
+#define MSR_LINKTYPE_STATION 0x2
+#define MSR_LINKTYPE_AP 0x3
+
+#define REG_PBP 0x0104
+#define PBP_PAGE_SIZE_RX_SHIFT 0
+#define PBP_PAGE_SIZE_TX_SHIFT 4
+#define PBP_PAGE_SIZE_64 0x0
+#define PBP_PAGE_SIZE_128 0x1
+#define PBP_PAGE_SIZE_256 0x2
+#define PBP_PAGE_SIZE_512 0x3
+#define PBP_PAGE_SIZE_1024 0x4
+
+#define REG_TRXDMA_CTRL 0x010c
+#define TRXDMA_CTRL_VOQ_SHIFT 4
+#define TRXDMA_CTRL_VIQ_SHIFT 6
+#define TRXDMA_CTRL_BEQ_SHIFT 8
+#define TRXDMA_CTRL_BKQ_SHIFT 10
+#define TRXDMA_CTRL_MGQ_SHIFT 12
+#define TRXDMA_CTRL_HIQ_SHIFT 14
+#define TRXDMA_QUEUE_LOW 1
+#define TRXDMA_QUEUE_NORMAL 2
+#define TRXDMA_QUEUE_HIGH 3
+
+#define REG_TRXFF_BNDY 0x0114
+#define REG_TRXFF_STATUS 0x0118
+#define REG_RXFF_PTR 0x011c
+#define REG_HIMR 0x0120
+#define REG_HISR 0x0124
+#define REG_HIMRE 0x0128
+#define REG_HISRE 0x012c
+#define REG_CPWM 0x012f
+#define REG_FWIMR 0x0130
+#define REG_FWISR 0x0134
+#define REG_PKTBUF_DBG_CTRL 0x0140
+#define REG_PKTBUF_DBG_DATA_L 0x0144
+#define REG_PKTBUF_DBG_DATA_H 0x0148
+
+#define REG_TC0_CTRL 0x0150
+#define REG_TC1_CTRL 0x0154
+#define REG_TC2_CTRL 0x0158
+#define REG_TC3_CTRL 0x015c
+#define REG_TC4_CTRL 0x0160
+#define REG_TCUNIT_BASE 0x0164
+#define REG_MBIST_START 0x0174
+#define REG_MBIST_DONE 0x0178
+#define REG_MBIST_FAIL 0x017c
+#define REG_C2HEVT_MSG_NORMAL 0x01a0
+#define REG_C2HEVT_CLEAR 0x01af
+#define REG_C2HEVT_MSG_TEST 0x01b8
+#define REG_MCUTST_1 0x01c0
+#define REG_FMTHR 0x01c8
+#define REG_HMTFR 0x01cc
+#define REG_HMBOX_0 0x01d0
+#define REG_HMBOX_1 0x01d4
+#define REG_HMBOX_2 0x01d8
+#define REG_HMBOX_3 0x01dc
+
+#define REG_LLT_INIT 0x01e0
+#define LLT_OP_INACTIVE 0x0
+#define LLT_OP_WRITE (0x1 << 30)
+#define LLT_OP_READ (0x2 << 30)
+#define LLT_OP_MASK (0x3 << 30)
+
+#define REG_BB_ACCEESS_CTRL 0x01e8
+#define REG_BB_ACCESS_DATA 0x01ec
+
+/* 0x0200 ~ 0x027F TXDMA Configuration */
+#define REG_RQPN 0x0200
+#define RQPN_HI_PQ_SHIFT 0
+#define RQPN_LO_PQ_SHIFT 8
+#define RQPN_NORM_PQ_SHIFT 16
+#define RQPN_LOAD BIT(31)
+
+#define REG_FIFOPAGE 0x0204
+#define REG_TDECTRL 0x0208
+#define REG_TXDMA_OFFSET_CHK 0x020c
+#define REG_TXDMA_STATUS 0x0210
+#define REG_RQPN_NPQ 0x0214
+
+/* 0x0280 ~ 0x02FF RXDMA Configuration */
+#define REG_RXDMA_AGG_PG_TH 0x0280
+#define REG_RXPKT_NUM 0x0284
+#define REG_RXDMA_STATUS 0x0288
+
+#define REG_RF_BB_CMD_ADDR 0x02c0
+#define REG_RF_BB_CMD_DATA 0x02c4
+
+/* spec version 11 */
+/* 0x0400 ~ 0x047F Protocol Configuration */
+#define REG_VOQ_INFORMATION 0x0400
+#define REG_VIQ_INFORMATION 0x0404
+#define REG_BEQ_INFORMATION 0x0408
+#define REG_BKQ_INFORMATION 0x040c
+#define REG_MGQ_INFORMATION 0x0410
+#define REG_HGQ_INFORMATION 0x0414
+#define REG_BCNQ_INFORMATION 0x0418
+
+#define REG_CPU_MGQ_INFORMATION 0x041c
+#define REG_FWHW_TXQ_CTRL 0x0420
+#define FWHW_TXQ_CTRL_AMPDU_RETRY BIT(7)
+#define FWHW_TXQ_CTRL_XMIT_MGMT_ACK BIT(12)
+
+#define REG_HWSEQ_CTRL 0x0423
+#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
+#define REG_TXPKTBUF_MGQ_BDNY 0x0425
+#define REG_LIFETIME_EN 0x0426
+#define REG_MULTI_BCNQ_OFFSET 0x0427
+
+#define REG_SPEC_SIFS 0x0428
+#define SPEC_SIFS_CCK_MASK 0x00ff
+#define SPEC_SIFS_CCK_SHIFT 0
+#define SPEC_SIFS_OFDM_MASK 0xff00
+#define SPEC_SIFS_OFDM_SHIFT 8
+
+#define REG_RETRY_LIMIT 0x042a
+#define RETRY_LIMIT_LONG_SHIFT 0
+#define RETRY_LIMIT_LONG_MASK 0x003f
+#define RETRY_LIMIT_SHORT_SHIFT 8
+#define RETRY_LIMIT_SHORT_MASK 0x3f00
+
+#define REG_DARFRC 0x0430
+#define REG_RARFRC 0x0438
+#define REG_RESPONSE_RATE_SET 0x0440
+#define RESPONSE_RATE_BITMAP_ALL 0xfffff
+#define RESPONSE_RATE_RRSR_CCK_ONLY_1M 0xffff1
+#define RSR_1M BIT(0)
+#define RSR_2M BIT(1)
+#define RSR_5_5M BIT(2)
+#define RSR_11M BIT(3)
+#define RSR_6M BIT(4)
+#define RSR_9M BIT(5)
+#define RSR_12M BIT(6)
+#define RSR_18M BIT(7)
+#define RSR_24M BIT(8)
+#define RSR_36M BIT(9)
+#define RSR_48M BIT(10)
+#define RSR_54M BIT(11)
+#define RSR_MCS0 BIT(12)
+#define RSR_MCS1 BIT(13)
+#define RSR_MCS2 BIT(14)
+#define RSR_MCS3 BIT(15)
+#define RSR_MCS4 BIT(16)
+#define RSR_MCS5 BIT(17)
+#define RSR_MCS6 BIT(18)
+#define RSR_MCS7 BIT(19)
+#define RSR_RSC_LOWER_SUB_CHANNEL BIT(21) /* 0x200000 */
+#define RSR_RSC_UPPER_SUB_CHANNEL BIT(22) /* 0x400000 */
+#define RSR_RSC_BANDWIDTH_40M (RSR_RSC_UPPER_SUB_CHANNEL | \
+ RSR_RSC_LOWER_SUB_CHANNEL)
+#define RSR_ACK_SHORT_PREAMBLE BIT(23)
+
+#define REG_ARFR0 0x0444
+#define REG_ARFR1 0x0448
+#define REG_ARFR2 0x044c
+#define REG_ARFR3 0x0450
+#define REG_AGGLEN_LMT 0x0458
+#define REG_AMPDU_MIN_SPACE 0x045c
+#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045d
+#define REG_FAST_EDCA_CTRL 0x0460
+#define REG_RD_RESP_PKT_TH 0x0463
+#define REG_INIRTS_RATE_SEL 0x0480
+#define REG_INIDATA_RATE_SEL 0x0484
+
+#define REG_POWER_STATUS 0x04a4
+#define REG_POWER_STAGE1 0x04b4
+#define REG_POWER_STAGE2 0x04b8
+#define REG_PKT_VO_VI_LIFE_TIME 0x04c0
+#define REG_PKT_BE_BK_LIFE_TIME 0x04c2
+#define REG_STBC_SETTING 0x04c4
+#define REG_PROT_MODE_CTRL 0x04c8
+#define REG_MAX_AGGR_NUM 0x04ca
+#define REG_RTS_MAX_AGGR_NUM 0x04cb
+#define REG_BAR_MODE_CTRL 0x04cc
+#define REG_RA_TRY_RATE_AGG_LMT 0x04cf
+#define REG_NQOS_SEQ 0x04dc
+#define REG_QOS_SEQ 0x04de
+#define REG_NEED_CPU_HANDLE 0x04e0
+#define REG_PKT_LOSE_RPT 0x04e1
+#define REG_PTCL_ERR_STATUS 0x04e2
+#define REG_DUMMY 0x04fc
+
+/* 0x0500 ~ 0x05FF EDCA Configuration */
+#define REG_EDCA_VO_PARAM 0x0500
+#define REG_EDCA_VI_PARAM 0x0504
+#define REG_EDCA_BE_PARAM 0x0508
+#define REG_EDCA_BK_PARAM 0x050c
+#define EDCA_PARAM_ECW_MIN_SHIFT 8
+#define EDCA_PARAM_ECW_MAX_SHIFT 12
+#define EDCA_PARAM_TXOP_SHIFT 16
+#define REG_BEACON_TCFG 0x0510
+#define REG_PIFS 0x0512
+#define REG_RDG_PIFS 0x0513
+#define REG_SIFS_CCK 0x0514
+#define REG_SIFS_OFDM 0x0516
+#define REG_TSFTR_SYN_OFFSET 0x0518
+#define REG_AGGR_BREAK_TIME 0x051a
+#define REG_SLOT 0x051b
+#define REG_TX_PTCL_CTRL 0x0520
+#define REG_TXPAUSE 0x0522
+#define REG_DIS_TXREQ_CLR 0x0523
+#define REG_RD_CTRL 0x0524
+#define REG_TBTT_PROHIBIT 0x0540
+#define REG_RD_NAV_NXT 0x0544
+#define REG_NAV_PROT_LEN 0x0546
+
+#define REG_BEACON_CTRL 0x0550
+#define REG_BEACON_CTRL_1 0x0551
+#define BEACON_ATIM BIT(0)
+#define BEACON_CTRL_MBSSID BIT(1)
+#define BEACON_CTRL_TX_BEACON_RPT BIT(2)
+#define BEACON_FUNCTION_ENABLE BIT(3)
+#define BEACON_DISABLE_TSF_UPDATE BIT(4)
+
+#define REG_MBID_NUM 0x0552
+#define REG_DUAL_TSF_RST 0x0553
+#define DUAL_TSF_RESET_TSF0 BIT(0)
+#define DUAL_TSF_RESET_TSF1 BIT(1)
+#define DUAL_TSF_RESET_P2P BIT(4)
+#define DUAL_TSF_TX_OK BIT(5)
+
+/* The same as REG_MBSSID_BCN_SPACE */
+#define REG_BCN_INTERVAL 0x0554
+#define REG_MBSSID_BCN_SPACE 0x0554
+
+#define REG_DRIVER_EARLY_INT 0x0558
+#define DRIVER_EARLY_INT_TIME 5
+
+#define REG_BEACON_DMA_TIME 0x0559
+#define BEACON_DMA_ATIME_INT_TIME 2
+
+#define REG_ATIMWND 0x055a
+#define REG_BCN_MAX_ERR 0x055d
+#define REG_RXTSF_OFFSET_CCK 0x055e
+#define REG_RXTSF_OFFSET_OFDM 0x055f
+#define REG_TSFTR 0x0560
+#define REG_TSFTR1 0x0568
+#define REG_INIT_TSFTR 0x0564
+#define REG_ATIMWND_1 0x0570
+#define REG_PSTIMER 0x0580
+#define REG_TIMER0 0x0584
+#define REG_TIMER1 0x0588
+#define REG_ACM_HW_CTRL 0x05c0
+#define ACM_HW_CTRL_BK BIT(0)
+#define ACM_HW_CTRL_BE BIT(1)
+#define ACM_HW_CTRL_VI BIT(2)
+#define ACM_HW_CTRL_VO BIT(3)
+#define REG_ACM_RST_CTRL 0x05c1
+#define REG_ACMAVG 0x05c2
+#define REG_VO_ADMTIME 0x05c4
+#define REG_VI_ADMTIME 0x05c6
+#define REG_BE_ADMTIME 0x05c8
+#define REG_EDCA_RANDOM_GEN 0x05cc
+#define REG_SCH_TXCMD 0x05d0
+
+/* define REG_FW_TSF_SYNC_CNT 0x04a0 */
+#define REG_FW_RESET_TSF_CNT_1 0x05fc
+#define REG_FW_RESET_TSF_CNT_0 0x05fd
+#define REG_FW_BCN_DIS_CNT 0x05fe
+
+/* 0x0600 ~ 0x07FF WMAC Configuration */
+#define REG_APSD_CTRL 0x0600
+#define APSD_CTRL_OFF BIT(6)
+#define APSD_CTRL_OFF_STATUS BIT(7)
+#define REG_BW_OPMODE 0x0603
+#define BW_OPMODE_20MHZ BIT(2)
+#define BW_OPMODE_5G BIT(1)
+#define BW_OPMODE_11J BIT(0)
+
+#define REG_TCR 0x0604
+
+/* Receive Configuration Register */
+#define REG_RCR 0x0608
+#define RCR_ACCEPT_AP BIT(0) /* Accept all unicast packet */
+#define RCR_ACCEPT_PHYS_MATCH BIT(1) /* Accept phys match packet */
+#define RCR_ACCEPT_MCAST BIT(2)
+#define RCR_ACCEPT_BCAST BIT(3)
+#define RCR_ACCEPT_ADDR3 BIT(4) /* Accept address 3 match
+ packet */
+#define RCR_ACCEPT_PM BIT(5) /* Accept power management
+ packet */
+#define RCR_CHECK_BSSID_MATCH BIT(6) /* Accept BSSID match packet */
+#define RCR_CHECK_BSSID_BEACON BIT(7) /* Accept BSSID match packet
+ (Rx beacon, probe rsp) */
+#define RCR_ACCEPT_CRC32 BIT(8) /* Accept CRC32 error packet */
+#define RCR_ACCEPT_ICV BIT(9) /* Accept ICV error packet */
+#define RCR_ACCEPT_DATA_FRAME BIT(11)
+#define RCR_ACCEPT_CTRL_FRAME BIT(12)
+#define RCR_ACCEPT_MGMT_FRAME BIT(13)
+#define RCR_HTC_LOC_CTRL BIT(14) /* MFC<--HTC=1 MFC-->HTC=0 */
+#define RCR_MFBEN BIT(22)
+#define RCR_LSIGEN BIT(23)
+#define RCR_MULTI_BSSID_ENABLE BIT(24) /* Enable Multiple BssId */
+#define RCR_ACCEPT_BA_SSN BIT(27) /* Accept BA SSN */
+#define RCR_APPEND_PHYSTAT BIT(28)
+#define RCR_APPEND_ICV BIT(29)
+#define RCR_APPEND_MIC BIT(30)
+#define RCR_APPEND_FCS BIT(31) /* WMAC append FCS after */
+
+#define REG_RX_PKT_LIMIT 0x060c
+#define REG_RX_DLK_TIME 0x060d
+#define REG_RX_DRVINFO_SZ 0x060f
+
+#define REG_MACID 0x0610
+#define REG_BSSID 0x0618
+#define REG_MAR 0x0620
+#define REG_MBIDCAMCFG 0x0628
+
+#define REG_USTIME_EDCA 0x0638
+#define REG_MAC_SPEC_SIFS 0x063a
+
+/* 20100719 Joseph: Hardware register definition change. (HW datasheet v54) */
+ /* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */
+#define REG_R2T_SIFS 0x063c
+ /* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */
+#define REG_T2T_SIFS 0x063e
+#define REG_ACKTO 0x0640
+#define REG_CTS2TO 0x0641
+#define REG_EIFS 0x0642
+
+/* WMA, BA, CCX */
+#define REG_NAV_CTRL 0x0650
+/* In units of 128us */
+#define REG_NAV_UPPER 0x0652
+#define NAV_UPPER_UNIT 128
+
+#define REG_BACAMCMD 0x0654
+#define REG_BACAMCONTENT 0x0658
+#define REG_LBDLY 0x0660
+#define REG_FWDLY 0x0661
+#define REG_RXERR_RPT 0x0664
+#define REG_WMAC_TRXPTCL_CTL 0x0668
+
+/* Security */
+#define REG_CAM_CMD 0x0670
+#define CAM_CMD_POLLING BIT(31)
+#define CAM_CMD_WRITE BIT(16)
+#define CAM_CMD_KEY_SHIFT 3
+#define REG_CAM_WRITE 0x0674
+#define CAM_WRITE_VALID BIT(15)
+#define REG_CAM_READ 0x0678
+#define REG_CAM_DEBUG 0x067c
+#define REG_SECURITY_CFG 0x0680
+#define SEC_CFG_TX_USE_DEFKEY BIT(0)
+#define SEC_CFG_RX_USE_DEFKEY BIT(1)
+#define SEC_CFG_TX_SEC_ENABLE BIT(2)
+#define SEC_CFG_RX_SEC_ENABLE BIT(3)
+#define SEC_CFG_SKBYA2 BIT(4)
+#define SEC_CFG_NO_SKMC BIT(5)
+#define SEC_CFG_TXBC_USE_DEFKEY BIT(6)
+#define SEC_CFG_RXBC_USE_DEFKEY BIT(7)
+
+/* Power */
+#define REG_WOW_CTRL 0x0690
+#define REG_PSSTATUS 0x0691
+#define REG_PS_RX_INFO 0x0692
+#define REG_LPNAV_CTRL 0x0694
+#define REG_WKFMCAM_CMD 0x0698
+#define REG_WKFMCAM_RWD 0x069c
+#define REG_RXFLTMAP0 0x06a0
+#define REG_RXFLTMAP1 0x06a2
+#define REG_RXFLTMAP2 0x06a4
+#define REG_BCN_PSR_RPT 0x06a8
+#define REG_CALB32K_CTRL 0x06ac
+#define REG_PKT_MON_CTRL 0x06b4
+#define REG_BT_COEX_TABLE 0x06c0
+#define REG_WMAC_RESP_TXINFO 0x06d8
+
+#define REG_MACID1 0x0700
+#define REG_BSSID1 0x0708
+
+#define REG_FPGA0_RF_MODE 0x0800
+#define FPGA_RF_MODE BIT(0)
+#define FPGA_RF_MODE_JAPAN BIT(1)
+#define FPGA_RF_MODE_CCK BIT(24)
+#define FPGA_RF_MODE_OFDM BIT(25)
+
+#define REG_FPGA0_TX_INFO 0x0804
+#define REG_FPGA0_PSD_FUNC 0x0808
+#define REG_FPGA0_TX_GAIN 0x080c
+#define REG_FPGA0_RF_TIMING1 0x0810
+#define REG_FPGA0_RF_TIMING2 0x0814
+#define REG_FPGA0_POWER_SAVE 0x0818
+#define FPGA0_PS_LOWER_CHANNEL BIT(26)
+#define FPGA0_PS_UPPER_CHANNEL BIT(27)
+
+#define REG_FPGA0_XA_HSSI_PARM1 0x0820 /* RF 3 wire register */
+#define FPGA0_HSSI_PARM1_PI BIT(8)
+#define REG_FPGA0_XA_HSSI_PARM2 0x0824
+#define REG_FPGA0_XB_HSSI_PARM1 0x0828
+#define REG_FPGA0_XB_HSSI_PARM2 0x082c
+#define FPGA0_HSSI_3WIRE_DATA_LEN 0x800
+#define FPGA0_HSSI_3WIRE_ADDR_LEN 0x400
+#define FPGA0_HSSI_PARM2_ADDR_SHIFT 23
+#define FPGA0_HSSI_PARM2_ADDR_MASK 0x7f800000 /* 0xff << 23 */
+#define FPGA0_HSSI_PARM2_CCK_HIGH_PWR BIT(9)
+#define FPGA0_HSSI_PARM2_EDGE_READ BIT(31)
+
+#define REG_TX_AGC_B_RATE18_06 0x0830
+#define REG_TX_AGC_B_RATE54_24 0x0834
+#define REG_TX_AGC_B_CCK1_55_MCS32 0x0838
+#define REG_TX_AGC_B_MCS03_MCS00 0x083c
+
+#define REG_FPGA0_XA_LSSI_PARM 0x0840
+#define REG_FPGA0_XB_LSSI_PARM 0x0844
+#define FPGA0_LSSI_PARM_ADDR_SHIFT 20
+#define FPGA0_LSSI_PARM_ADDR_MASK 0x0ff00000
+#define FPGA0_LSSI_PARM_DATA_MASK 0x000fffff
+
+#define REG_TX_AGC_B_MCS07_MCS04 0x0848
+#define REG_TX_AGC_B_MCS11_MCS08 0x084c
+
+#define REG_FPGA0_XCD_SWITCH_CTRL 0x085c
+
+#define REG_FPGA0_XA_RF_INT_OE 0x0860 /* RF Channel switch */
+#define REG_FPGA0_XB_RF_INT_OE 0x0864
+#define FPGA0_INT_OE_ANTENNA_AB_OPEN 0x000
+#define FPGA0_INT_OE_ANTENNA_A BIT(8)
+#define FPGA0_INT_OE_ANTENNA_B BIT(9)
+#define FPGA0_INT_OE_ANTENNA_MASK (FPGA0_INT_OE_ANTENNA_A | \
+ FPGA0_INT_OE_ANTENNA_B)
+
+#define REG_TX_AGC_B_MCS15_MCS12 0x0868
+#define REG_TX_AGC_B_CCK11_A_CCK2_11 0x086c
+
+#define REG_FPGA0_XAB_RF_SW_CTRL 0x0870
+#define REG_FPGA0_XA_RF_SW_CTRL 0x0870 /* 16 bit */
+#define REG_FPGA0_XB_RF_SW_CTRL 0x0872 /* 16 bit */
+#define REG_FPGA0_XCD_RF_SW_CTRL 0x0874
+#define REG_FPGA0_XC_RF_SW_CTRL 0x0874 /* 16 bit */
+#define REG_FPGA0_XD_RF_SW_CTRL 0x0876 /* 16 bit */
+#define FPGA0_RF_3WIRE_DATA BIT(0)
+#define FPGA0_RF_3WIRE_CLOC BIT(1)
+#define FPGA0_RF_3WIRE_LOAD BIT(2)
+#define FPGA0_RF_3WIRE_RW BIT(3)
+#define FPGA0_RF_3WIRE_MASK 0xf
+#define FPGA0_RF_RFENV BIT(4)
+#define FPGA0_RF_TRSW BIT(5) /* Useless now */
+#define FPGA0_RF_TRSWB BIT(6)
+#define FPGA0_RF_ANTSW BIT(8)
+#define FPGA0_RF_ANTSWB BIT(9)
+#define FPGA0_RF_PAPE BIT(10)
+#define FPGA0_RF_PAPE5G BIT(11)
+#define FPGA0_RF_BD_CTRL_SHIFT 16
+
+#define REG_FPGA0_XAB_RF_PARM 0x0878 /* Antenna select path in ODM */
+#define REG_FPGA0_XA_RF_PARM 0x0878 /* 16 bit */
+#define REG_FPGA0_XB_RF_PARM 0x087a /* 16 bit */
+#define REG_FPGA0_XCD_RF_PARM 0x087c
+#define REG_FPGA0_XC_RF_PARM 0x087c /* 16 bit */
+#define REG_FPGA0_XD_RF_PARM 0x087e /* 16 bit */
+#define FPGA0_RF_PARM_RFA_ENABLE BIT(1)
+#define FPGA0_RF_PARM_RFB_ENABLE BIT(17)
+#define FPGA0_RF_PARM_CLK_GATE BIT(31)
+
+#define REG_FPGA0_ANALOG1 0x0880
+#define REG_FPGA0_ANALOG2 0x0884
+#define FPGA0_ANALOG2_20MHZ BIT(10)
+#define REG_FPGA0_ANALOG3 0x0888
+#define REG_FPGA0_ANALOG4 0x088c
+
+#define REG_FPGA0_XA_LSSI_READBACK 0x08a0 /* Tranceiver LSSI Readback */
+#define REG_FPGA0_XB_LSSI_READBACK 0x08a4
+#define REG_HSPI_XA_READBACK 0x08b8 /* Transceiver A HSPI read */
+#define REG_HSPI_XB_READBACK 0x08bc /* Transceiver B HSPI read */
+
+#define REG_FPGA1_RF_MODE 0x0900
+
+#define REG_FPGA1_TX_INFO 0x090c
+
+#define REG_CCK0_SYSTEM 0x0a00
+#define CCK0_SIDEBAND BIT(4)
+
+#define REG_CCK0_AFE_SETTING 0x0a04
+
+#define REG_CONFIG_ANT_A 0x0b68
+#define REG_CONFIG_ANT_B 0x0b6c
+
+#define REG_OFDM0_TRX_PATH_ENABLE 0x0c04
+#define OFDM_RF_PATH_RX_MASK 0x0f
+#define OFDM_RF_PATH_RX_A BIT(0)
+#define OFDM_RF_PATH_RX_B BIT(1)
+#define OFDM_RF_PATH_RX_C BIT(2)
+#define OFDM_RF_PATH_RX_D BIT(3)
+#define OFDM_RF_PATH_TX_MASK 0xf0
+#define OFDM_RF_PATH_TX_A BIT(4)
+#define OFDM_RF_PATH_TX_B BIT(5)
+#define OFDM_RF_PATH_TX_C BIT(6)
+#define OFDM_RF_PATH_TX_D BIT(7)
+
+#define REG_OFDM0_TR_MUX_PAR 0x0c08
+
+#define REG_OFDM0_XA_RX_IQ_IMBALANCE 0x0c14
+#define REG_OFDM0_XB_RX_IQ_IMBALANCE 0x0c1c
+
+#define REG_OFDM0_ENERGY_CCA_THRES 0x0c4c
+
+#define REG_OFDM0_XA_AGC_CORE1 0x0c50
+#define REG_OFDM0_XA_AGC_CORE2 0x0c54
+#define REG_OFDM0_XB_AGC_CORE1 0x0c58
+#define REG_OFDM0_XB_AGC_CORE2 0x0c5c
+#define REG_OFDM0_XC_AGC_CORE1 0x0c60
+#define REG_OFDM0_XC_AGC_CORE2 0x0c64
+#define REG_OFDM0_XD_AGC_CORE1 0x0c68
+#define REG_OFDM0_XD_AGC_CORE2 0x0c6c
+#define OFDM0_X_AGC_CORE1_IGI_MASK 0x0000007F
+
+#define REG_OFDM0_AGC_PARM1 0x0c70
+
+#define REG_OFDM0_AGCR_SSI_TABLE 0x0c78
+
+#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80
+#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88
+#define REG_OFDM0_XC_TX_IQ_IMBALANCE 0x0c90
+#define REG_OFDM0_XD_TX_IQ_IMBALANCE 0x0c98
+
+#define REG_OFDM0_XC_TX_AFE 0x0c94
+#define REG_OFDM0_XD_TX_AFE 0x0c9c
+
+#define REG_OFDM0_RX_IQ_EXT_ANTA 0x0ca0
+
+#define REG_OFDM1_LSTF 0x0d00
+#define OFDM_LSTF_PRIME_CH_LOW BIT(10)
+#define OFDM_LSTF_PRIME_CH_HIGH BIT(11)
+#define OFDM_LSTF_PRIME_CH_MASK (OFDM_LSTF_PRIME_CH_LOW | \
+ OFDM_LSTF_PRIME_CH_HIGH)
+#define OFDM_LSTF_CONTINUE_TX BIT(28)
+#define OFDM_LSTF_SINGLE_CARRIER BIT(29)
+#define OFDM_LSTF_SINGLE_TONE BIT(30)
+#define OFDM_LSTF_MASK 0x70000000
+
+#define REG_OFDM1_TRX_PATH_ENABLE 0x0d04
+
+#define REG_TX_AGC_A_RATE18_06 0x0e00
+#define REG_TX_AGC_A_RATE54_24 0x0e04
+#define REG_TX_AGC_A_CCK1_MCS32 0x0e08
+#define REG_TX_AGC_A_MCS03_MCS00 0x0e10
+#define REG_TX_AGC_A_MCS07_MCS04 0x0e14
+#define REG_TX_AGC_A_MCS11_MCS08 0x0e18
+#define REG_TX_AGC_A_MCS15_MCS12 0x0e1c
+
+#define REG_FPGA0_IQK 0x0e28
+
+#define REG_TX_IQK_TONE_A 0x0e30
+#define REG_RX_IQK_TONE_A 0x0e34
+#define REG_TX_IQK_PI_A 0x0e38
+#define REG_RX_IQK_PI_A 0x0e3c
+
+#define REG_TX_IQK 0x0e40
+#define REG_RX_IQK 0x0e44
+#define REG_IQK_AGC_PTS 0x0e48
+#define REG_IQK_AGC_RSP 0x0e4c
+#define REG_TX_IQK_TONE_B 0x0e50
+#define REG_RX_IQK_TONE_B 0x0e54
+#define REG_TX_IQK_PI_B 0x0e58
+#define REG_RX_IQK_PI_B 0x0e5c
+#define REG_IQK_AGC_CONT 0x0e60
+
+#define REG_BLUETOOTH 0x0e6c
+#define REG_RX_WAIT_CCA 0x0e70
+#define REG_TX_CCK_RFON 0x0e74
+#define REG_TX_CCK_BBON 0x0e78
+#define REG_TX_OFDM_RFON 0x0e7c
+#define REG_TX_OFDM_BBON 0x0e80
+#define REG_TX_TO_RX 0x0e84
+#define REG_TX_TO_TX 0x0e88
+#define REG_RX_CCK 0x0e8c
+
+#define REG_TX_POWER_BEFORE_IQK_A 0x0e94
+#define REG_TX_POWER_AFTER_IQK_A 0x0e9c
+
+#define REG_RX_POWER_BEFORE_IQK_A 0x0ea0
+#define REG_RX_POWER_BEFORE_IQK_A_2 0x0ea4
+#define REG_RX_POWER_AFTER_IQK_A 0x0ea8
+#define REG_RX_POWER_AFTER_IQK_A_2 0x0eac
+
+#define REG_TX_POWER_BEFORE_IQK_B 0x0eb4
+#define REG_TX_POWER_AFTER_IQK_B 0x0ebc
+
+#define REG_RX_POWER_BEFORE_IQK_B 0x0ec0
+#define REG_RX_POWER_BEFORE_IQK_B_2 0x0ec4
+#define REG_RX_POWER_AFTER_IQK_B 0x0ec8
+#define REG_RX_POWER_AFTER_IQK_B_2 0x0ecc
+
+#define REG_RX_OFDM 0x0ed0
+#define REG_RX_WAIT_RIFS 0x0ed4
+#define REG_RX_TO_RX 0x0ed8
+#define REG_STANDBY 0x0edc
+#define REG_SLEEP 0x0ee0
+#define REG_PMPD_ANAEN 0x0eec
+
+#define REG_FW_START_ADDRESS 0x1000
+
+#define REG_USB_INFO 0xfe17
+#define REG_USB_HIMR 0xfe38
+#define USB_HIMR_TIMEOUT2 BIT(31)
+#define USB_HIMR_TIMEOUT1 BIT(30)
+#define USB_HIMR_PSTIMEOUT BIT(29)
+#define USB_HIMR_GTINT4 BIT(28)
+#define USB_HIMR_GTINT3 BIT(27)
+#define USB_HIMR_TXBCNERR BIT(26)
+#define USB_HIMR_TXBCNOK BIT(25)
+#define USB_HIMR_TSF_BIT32_TOGGLE BIT(24)
+#define USB_HIMR_BCNDMAINT3 BIT(23)
+#define USB_HIMR_BCNDMAINT2 BIT(22)
+#define USB_HIMR_BCNDMAINT1 BIT(21)
+#define USB_HIMR_BCNDMAINT0 BIT(20)
+#define USB_HIMR_BCNDOK3 BIT(19)
+#define USB_HIMR_BCNDOK2 BIT(18)
+#define USB_HIMR_BCNDOK1 BIT(17)
+#define USB_HIMR_BCNDOK0 BIT(16)
+#define USB_HIMR_HSISR_IND BIT(15)
+#define USB_HIMR_BCNDMAINT_E BIT(14)
+/* RSVD BIT(13) */
+#define USB_HIMR_CTW_END BIT(12)
+/* RSVD BIT(11) */
+#define USB_HIMR_C2HCMD BIT(10)
+#define USB_HIMR_CPWM2 BIT(9)
+#define USB_HIMR_CPWM BIT(8)
+#define USB_HIMR_HIGHDOK BIT(7) /* High Queue DMA OK
+ Interrupt */
+#define USB_HIMR_MGNTDOK BIT(6) /* Management Queue DMA OK
+ Interrupt */
+#define USB_HIMR_BKDOK BIT(5) /* AC_BK DMA OK Interrupt */
+#define USB_HIMR_BEDOK BIT(4) /* AC_BE DMA OK Interrupt */
+#define USB_HIMR_VIDOK BIT(3) /* AC_VI DMA OK Interrupt */
+#define USB_HIMR_VODOK BIT(2) /* AC_VO DMA Interrupt */
+#define USB_HIMR_RDU BIT(1) /* Receive Descriptor
+ Unavailable */
+#define USB_HIMR_ROK BIT(0) /* Receive DMA OK Interrupt */
+
+#define REG_USB_SPECIAL_OPTION 0xfe55
+#define REG_USB_DMA_AGG_TO 0xfe5b
+#define REG_USB_AGG_TO 0xfe5c
+#define REG_USB_AGG_TH 0xfe5d
+
+#define REG_NORMAL_SIE_VID 0xfe60 /* 0xfe60 - 0xfe61 */
+#define REG_NORMAL_SIE_PID 0xfe62 /* 0xfe62 - 0xfe63 */
+#define REG_NORMAL_SIE_OPTIONAL 0xfe64
+#define REG_NORMAL_SIE_EP 0xfe65 /* 0xfe65 - 0xfe67 */
+#define REG_NORMAL_SIE_EP_TX 0xfe66
+#define NORMAL_SIE_EP_TX_HIGH_MASK 0x000f
+#define NORMAL_SIE_EP_TX_NORMAL_MASK 0x00f0
+#define NORMAL_SIE_EP_TX_LOW_MASK 0x0f00
+
+#define REG_NORMAL_SIE_PHY 0xfe68 /* 0xfe68 - 0xfe6b */
+#define REG_NORMAL_SIE_OPTIONAL2 0xfe6c
+#define REG_NORMAL_SIE_GPS_EP 0xfe6d /* RTL8723 only */
+#define REG_NORMAL_SIE_MAC_ADDR 0xfe70 /* 0xfe70 - 0xfe75 */
+#define REG_NORMAL_SIE_STRING 0xfe80 /* 0xfe80 - 0xfedf */
+
+/* RF6052 registers */
+#define RF6052_REG_AC 0x00
+#define RF6052_REG_IQADJ_G1 0x01
+#define RF6052_REG_IQADJ_G2 0x02
+#define RF6052_REG_BS_PA_APSET_G1_G4 0x03
+#define RF6052_REG_BS_PA_APSET_G5_G8 0x04
+#define RF6052_REG_POW_TRSW 0x05
+#define RF6052_REG_GAIN_RX 0x06
+#define RF6052_REG_GAIN_TX 0x07
+#define RF6052_REG_TXM_IDAC 0x08
+#define RF6052_REG_IPA_G 0x09
+#define RF6052_REG_TXBIAS_G 0x0a
+#define RF6052_REG_TXPA_AG 0x0b
+#define RF6052_REG_IPA_A 0x0c
+#define RF6052_REG_TXBIAS_A 0x0d
+#define RF6052_REG_BS_PA_APSET_G9_G11 0x0e
+#define RF6052_REG_BS_IQGEN 0x0f
+#define RF6052_REG_MODE1 0x10
+#define RF6052_REG_MODE2 0x11
+#define RF6052_REG_RX_AGC_HP 0x12
+#define RF6052_REG_TX_AGC 0x13
+#define RF6052_REG_BIAS 0x14
+#define RF6052_REG_IPA 0x15
+#define RF6052_REG_TXBIAS 0x16
+#define RF6052_REG_POW_ABILITY 0x17
+#define RF6052_REG_MODE_AG 0x18 /* RF channel and BW switch */
+#define MODE_AG_CHANNEL_MASK 0x3ff
+#define MODE_AG_CHANNEL_20MHZ BIT(10)
+
+#define RF6052_REG_TOP 0x19
+#define RF6052_REG_RX_G1 0x1a
+#define RF6052_REG_RX_G2 0x1b
+#define RF6052_REG_RX_BB2 0x1c
+#define RF6052_REG_RX_BB1 0x1d
+#define RF6052_REG_RCK1 0x1e
+#define RF6052_REG_RCK2 0x1f
+#define RF6052_REG_TX_G1 0x20
+#define RF6052_REG_TX_G2 0x21
+#define RF6052_REG_TX_G3 0x22
+#define RF6052_REG_TX_BB1 0x23
+#define RF6052_REG_T_METER 0x24
+#define RF6052_REG_SYN_G1 0x25 /* RF TX Power control */
+#define RF6052_REG_SYN_G2 0x26 /* RF TX Power control */
+#define RF6052_REG_SYN_G3 0x27 /* RF TX Power control */
+#define RF6052_REG_SYN_G4 0x28 /* RF TX Power control */
+#define RF6052_REG_SYN_G5 0x29 /* RF TX Power control */
+#define RF6052_REG_SYN_G6 0x2a /* RF TX Power control */
+#define RF6052_REG_SYN_G7 0x2b /* RF TX Power control */
+#define RF6052_REG_SYN_G8 0x2c /* RF TX Power control */
+
+#define RF6052_REG_RCK_OS 0x30 /* RF TX PA control */
+
+#define RF6052_REG_TXPA_G1 0x31 /* RF TX PA control */
+#define RF6052_REG_TXPA_G2 0x32 /* RF TX PA control */
+#define RF6052_REG_TXPA_G3 0x33 /* RF TX PA control */
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/realtek/rtlwifi/Kconfig
index 73067ca..73067ca 100644
--- a/drivers/net/wireless/rtlwifi/Kconfig
+++ b/drivers/net/wireless/realtek/rtlwifi/Kconfig
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/realtek/rtlwifi/Makefile
index ad6d3c5..ad6d3c5 100644
--- a/drivers/net/wireless/rtlwifi/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/Makefile
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 0517a4f..0517a4f 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h
index 74233d6..74233d6 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/realtek/rtlwifi/base.h
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/Makefile b/drivers/net/wireless/realtek/rtlwifi/btcoexist/Makefile
index 47ceecf..47ceecf 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/Makefile
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbt_precomp.h
index 39b9a33..39b9a33 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbt_precomp.h
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c
index 53261d6..53261d6 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.h
index 75e1f7d..75e1f7d 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.h
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
index c4acd40..c4acd40 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h
index 75f8094..75f8094 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
index f2b9d11..f2b9d11 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.h
index 567f354..567f354 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.h
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
index b72e537..b72e537 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h
index 20e9048..20e9048 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c
index cf819f0..cf819f0 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.h
index b4cf1f5..b4cf1f5 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.h
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index b2791c8..b2791c8 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
index 0a903ea..0a903ea 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
index b9b0cb7..b9b0cb7 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h
index ccd5a0f..ccd5a0f 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/realtek/rtlwifi/cam.c
index 8fe8b4c..8fe8b4c 100644
--- a/drivers/net/wireless/rtlwifi/cam.c
+++ b/drivers/net/wireless/realtek/rtlwifi/cam.c
diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/realtek/rtlwifi/cam.h
index e2e647d..e2e647d 100644
--- a/drivers/net/wireless/rtlwifi/cam.h
+++ b/drivers/net/wireless/realtek/rtlwifi/cam.h
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
index c925a4d..c925a4d 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/realtek/rtlwifi/core.h
index 782ac2f..782ac2f 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/realtek/rtlwifi/core.h
diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c
index fd25aba..fd25aba 100644
--- a/drivers/net/wireless/rtlwifi/debug.c
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.c
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h
index fc794b3..fc794b3 100644
--- a/drivers/net/wireless/rtlwifi/debug.h
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.h
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/realtek/rtlwifi/efuse.c
index 0b4082c..0b4082c 100644
--- a/drivers/net/wireless/rtlwifi/efuse.c
+++ b/drivers/net/wireless/realtek/rtlwifi/efuse.c
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/realtek/rtlwifi/efuse.h
index be02e78..be02e78 100644
--- a/drivers/net/wireless/rtlwifi/efuse.h
+++ b/drivers/net/wireless/realtek/rtlwifi/efuse.h
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index f46c9d7..f46c9d7 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h
index 5da6703..5da6703 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.h
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c
index b69321d..b69321d 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/realtek/rtlwifi/ps.h
index 29dfc51..29dfc51 100644
--- a/drivers/net/wireless/rtlwifi/ps.h
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.h
diff --git a/drivers/net/wireless/rtlwifi/pwrseqcmd.h b/drivers/net/wireless/realtek/rtlwifi/pwrseqcmd.h
index 17ce0cb..17ce0cb 100644
--- a/drivers/net/wireless/rtlwifi/pwrseqcmd.h
+++ b/drivers/net/wireless/realtek/rtlwifi/pwrseqcmd.h
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/realtek/rtlwifi/rc.c
index 74c14ce..74c14ce 100644
--- a/drivers/net/wireless/rtlwifi/rc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rc.c
diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/realtek/rtlwifi/rc.h
index f29643d..f29643d 100644
--- a/drivers/net/wireless/rtlwifi/rc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rc.h
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/realtek/rtlwifi/regd.c
index a62bf0a..a62bf0a 100644
--- a/drivers/net/wireless/rtlwifi/regd.c
+++ b/drivers/net/wireless/realtek/rtlwifi/regd.c
diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/realtek/rtlwifi/regd.h
index f7f15bc..f7f15bc 100644
--- a/drivers/net/wireless/rtlwifi/regd.h
+++ b/drivers/net/wireless/realtek/rtlwifi/regd.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile
index a85419a..a85419a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/def.h
index 0532b98..0532b98 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
index ce4da9d..ce4da9d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h
index 071ccee..071ccee 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
index 6291256..6291256 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.h
index 21bd4a5..21bd4a5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
index 8ee83b0..8ee83b0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h
index 1850fde..1850fde 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.c
index b504bd0..b504bd0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.h
index 4b325b7..4b325b7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c
index a2bb02c..a2bb02c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.h
index b29bd77..b29bd77 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.c
index 02013df..02013df 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h
index f2d9c61..f2d9c61 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/reg.h
index 15400ee..15400ee 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.c
index 40893ce..40893ce 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.h
index 0eca030..0eca030 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
index 1134412..1134412 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.h
index 22398c3..22398c3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.c
index 68bcb7f..68bcb7f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.h
index 403c4dd..403c4dd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
index 791efbe..791efbe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h
index eab5ae0..eab5ae0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/Makefile
index aee42d7..aee42d7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c
index 03cbe4c..03cbe4c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.h
index 4422e31..4422e31 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
index 43fcb25..43fcb25 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.h
index 864806c..864806c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/main.c
index 918b1d1..918b1d1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/main.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/main.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c
index 77e61b1..77e61b1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h
index 64bc49f..64bc49f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/Makefile
index c0cb0cf..c0cb0cf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/def.h
index 690a7a1..690a7a1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.c
index 09898cf..09898cf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.h
index 38ba707..38ba707 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
index 04eb5c3..04eb5c3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h
index 98a0868..98a0868 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.c
index 8283e9b..8283e9b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.h
index c576106..c576106 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c
index 1ee5a6a..1ee5a6a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h
index e5e1353..e5e1353 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/reg.h
index dc8460c..dc8460c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.c
index a9c406f..a9c406f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.h
index ebd72ca..ebd72ca 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
index de6cb6c..de6cb6c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.h
index d2367a5..d2367a5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.c
index 752f943..752f943 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.h
index 8b79161..8b79161 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
index 84ddd4d..84ddd4d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.h
index 4bec4b0..4bec4b0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/Makefile
index ad2de6b..ad2de6b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/def.h
index 74a479a..74a479a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.c
index c16209a..c16209a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.h
index fafa6ba..fafa6ba 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c
index 25db369..34ce064 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c
@@ -1946,6 +1946,14 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val);
mac->rx_data_filter = *(u16 *)val;
break;
+ case HW_VAR_KEEP_ALIVE:{
+ u8 array[2];
+ array[0] = 0xff;
+ array[1] = *((u8 *)val);
+ rtl92c_fill_h2c_cmd(hw, H2C_92C_KEEP_ALIVE_CTRL, 2,
+ array);
+ break;
+ }
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.h
index 6758808..6758808 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.c
index 75a2deb..75a2deb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.h
index 0f37227..0f37227 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.c
index 0357133..0357133 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.h
index 553a4bf..553a4bf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c
index c972fa5..c972fa5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.h
index 42b0686..42b0686 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/reg.h
index 8b81465..8b81465 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c
index 5624ade..5624ade 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.h
index 6f987de..6f987de 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
index fd4a535..fd4a535 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.h
index a1310ab..a1310ab 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.c
index 7903c15..7903c15 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.h
index 4b020e9..4b020e9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
index 95880fe..95880fe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h
index fd8051d..fd8051d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/Makefile
index e3213c8..e3213c8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/def.h
index 0a443ed..0a443ed 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.c
index 7c1db7e..7c1db7e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.h
index f2d318c..f2d318c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c
index 62ef820..62ef820 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.h
index 8a38daa..8a38daa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c
index f49b60d..f49b60d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h
index 1bc7b1a..1bc7b1a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.c
index 76a57ae..76a57ae 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.h
index a29df30..a29df30 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
index bb06fe8..bb06fe8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.h
index 48d5c68..48d5c68 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/reg.h
index 315a298..315a298 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c
index 6a6ac54..6a6ac54 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.h
index 7303d12..7303d12 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
index b19d039..b19d039 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.h
index 0e6035b..0e6035b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.c
index 8ea6f52..8ea6f52 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.h
index 8b724a8..8b724a8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
index 1feaa62..1feaa62 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h
index fb5cf06..fb5cf06 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/Makefile
index 0315eed..0315eed 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/def.h
index 60f5728..60f5728 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c
index 459f3d0..459f3d0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.h
index 107d5a4..107d5a4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
index 0708eed..0708eed 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.h
index 069da1e..069da1e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
index 5f14308..5f14308 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h
index 05413f1..05413f1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.c
index 8388e37..8388e37 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.h
index 8ef640a..8ef640a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c
index 018340a..018340a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.h
index c6e97c8..c6e97c8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.c
index 1a701d0..1a701d0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/pwrseq.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h
index 781eeaa..781eeaa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/pwrseq.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/reg.h
index 1eaa1fa..1eaa1fa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.c
index c9bc33c..c9bc33c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.h
index 039c013..039c013 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c
index c31c6bf..c31c6bf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.h
index 21433d0..21433d0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.c
index abcdd06..abcdd06 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.h
index bff9df8..bff9df8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c
index d39ee67..d39ee67 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h
index 8f78ac9..8f78ac9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/Makefile
index b7eb138..b7eb138 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/def.h
index 41466f9..41466f9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c
index 9bae5a9..9bae5a9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.h
index de6ac79..de6ac79 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c
index 331b158..331b158 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h
index b1e44b8..b1e44b8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c
index 12b0978..12b0978 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h
index 4cacee1..4cacee1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c
index 44949b5..44949b5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.h
index 2182dbe..2182dbe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c
index 4b4612f..4b4612f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.h
index 8acf476..8acf476 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/reg.h
index e130434..e130434 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c
index 78a81c1..78a81c1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.h
index 8a29eb9..8a29eb9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
index e1fd27c..e1fd27c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.h
index 2eb8886..2eb8886 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.c
index f1a73f7..f1a73f7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.h
index 2feb73b..2feb73b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c
index 125b29b..125b29b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.h
index 5a13f17..5a13f17 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/Makefile
index 6220672..6220672 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/btc.h
index 06c448c..06c448c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/btc.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/def.h
index bcdf227..bcdf227 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
index 4c1c96c..4c1c96c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.h
index 5711105..5711105 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c
index b7c0d38..b7c0d38 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.h
index 9d1fe25..9d1fe25 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.c
index 5aac45d..5aac45d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.h
index bcd64a2..bcd64a2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_bt_coexist.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c
index 00a0531..00a0531 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.h
index 3723d74..3723d74 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c
index a4b7eac..a4b7eac 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h
index 32c1ace..32c1ace 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.c
index 1317335..1317335 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.h
index c22b19f..c22b19f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c
index d367097..d367097 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.h
index b85f5c7..b85f5c7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.c
index 2f7f81a..2f7f81a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h
index 4ac7db5..4ac7db5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/reg.h
index 306059f..306059f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.c
index 9ebc828..9ebc828 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.h
index 7b44ebc..7b44ebc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
index 3859b3e..3859b3e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.h
index 4647878..4647878 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.c
index 61e8604..61e8604 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.h
index 57a548c..57a548c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
index 2f7c144..2f7c144 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h
index 017da7e..017da7e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/Makefile
index a77c341..a77c341 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/def.h
index 025ea5c..025ea5c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c
index 3a81cdb..3a81cdb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.h
index f752a2c..f752a2c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c
index d5da0f3..d5da0f3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.h
index 0674296..0674296 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/fw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
index c983d2f..c983d2f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h
index eae863d..eae863d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.c
index 4196efb..4196efb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.h
index c57de37..c57de37 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c
index b7b73cb..b7b73cb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.h
index 9021d47..9021d47 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.c
index a1bb1f6..a1bb1f6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h
index 0fee5e0..0fee5e0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/reg.h
index 03581d2..03581d2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.c
index 5ed4492..5ed4492 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.h
index f423e15..f423e15 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
index d091f1d..d091f1d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.h
index a7b25e76..a7b25e76 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c
index a180761..a180761 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.h
index dc17001..dc17001 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c
index 338ec9a..338ec9a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h
index 45949ac..45949ac 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/Makefile
index 345a68a..345a68a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.c
index 0643406..0643406 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.h
index 5c1b94c..5c1b94c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/dm_common.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c
index a2f5e89..a2f5e89 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h
index 8ea372d..8ea372d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/main.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/main.c
index 9014a94..9014a94 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/main.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/main.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c
index 75cbd15..75cbd15 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.h
index 83b891a..83b891a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/Makefile b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/Makefile
index f7a26f7..f7a26f7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/Makefile
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/Makefile
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/def.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/def.h
index dfbdf53..dfbdf53 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c
index b57cfd9..b57cfd9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.h
index 625a6bb..625a6bb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
index 525eb23..525eb23 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h
index 8f5b4aa..8f5b4aa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/fw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
index 6e9418e..6e9418e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h
index a3553e3..a3553e3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/led.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.c
index ba1946a..ba1946a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/led.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/led.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.h
index 038e64e..038e64e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/led.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
index 9b4d8a6..9b4d8a6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.h
index c411f0a..c411f0a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.c
index 9ddf78a..9ddf78a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h
index 36b3e91..36b3e91 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/reg.h
index 1d6110f..1d6110f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.c
index 2922538..2922538 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.h
index efd22bd..efd22bd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
index 8ee141a..8ee141a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.h
index d001e7c..d001e7c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c
index 62a0fb7..62a0fb7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/table.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h
index 24bcff6..24bcff6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/table.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c
index 174743a..174743a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h
index 3140904..3140904 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h
diff --git a/drivers/net/wireless/rtlwifi/stats.c b/drivers/net/wireless/realtek/rtlwifi/stats.c
index d8b3069..d8b3069 100644
--- a/drivers/net/wireless/rtlwifi/stats.c
+++ b/drivers/net/wireless/realtek/rtlwifi/stats.c
diff --git a/drivers/net/wireless/rtlwifi/stats.h b/drivers/net/wireless/realtek/rtlwifi/stats.h
index 2b57dff..2b57dff 100644
--- a/drivers/net/wireless/rtlwifi/stats.h
+++ b/drivers/net/wireless/realtek/rtlwifi/stats.h
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c
index 2721cf8..2721cf8 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/realtek/rtlwifi/usb.c
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/realtek/rtlwifi/usb.h
index 685273c..685273c 100644
--- a/drivers/net/wireless/rtlwifi/usb.h
+++ b/drivers/net/wireless/realtek/rtlwifi/usb.h
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index 4544752..4544752 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h