aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-03-13 14:21:43 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-03-13 14:21:43 -0400
commit42775a34d23027b19e984956a539448f5e7ff075 (patch)
treee344340c7f0aed4c8faf7534fabbc64607a8e784
parent433131ba03c511a84e1fda5669c70cf8b44702e1 (diff)
parent4e3b3bcd81776527fa6f11624d68849de8c8802e (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/ath/ath9k/recv.c
-rw-r--r--Documentation/DocBook/80211.tmpl2
-rw-r--r--Documentation/devices.txt1
-rw-r--r--Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt39
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c6
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c13
-rw-r--r--drivers/bluetooth/ath3k.c84
-rw-r--r--drivers/bluetooth/btusb.c58
-rw-r--r--drivers/bluetooth/hci_vhci.c3
-rw-r--r--drivers/net/wireless/Kconfig8
-rw-r--r--drivers/net/wireless/airo.c17
-rw-r--r--drivers/net/wireless/ath/ath.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c36
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h47
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c35
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h6
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c634
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c147
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c118
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h34
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c1
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c6
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c41
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/common-init.c244
-rw-r--r--drivers/net/wireless/ath/ath9k/common-init.h20
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c229
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c231
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c5
-rw-r--r--drivers/net/wireless/ath/regd.c10
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile1
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c202
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c119
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c119
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c177
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c125
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h7
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h82
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c116
-rw-r--r--drivers/net/wireless/atmel.c8
-rw-r--r--drivers/net/wireless/b43/Kconfig2
-rw-r--r--drivers/net/wireless/b43/debugfs.h2
-rw-r--r--drivers/net/wireless/b43/main.c2
-rw-r--r--drivers/net/wireless/b43/phy_common.c4
-rw-r--r--drivers/net/wireless/b43/pio.c10
-rw-r--r--drivers/net/wireless/b43/sysfs.c2
-rw-r--r--drivers/net/wireless/b43/xmit.c2
-rw-r--r--drivers/net/wireless/b43legacy/main.c4
-rw-r--r--drivers/net/wireless/b43legacy/sysfs.c2
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c55
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c209
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c55
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h1
-rw-r--r--drivers/net/wireless/cw1200/fwio.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c2
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c2
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c2
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c13
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c15
-rw-r--r--drivers/net/wireless/iwlegacy/commands.h3
-rw-r--r--drivers/net/wireless/iwlegacy/common.c83
-rw-r--r--drivers/net/wireless/iwlegacy/common.h17
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/devices.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c245
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c118
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c18
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h35
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c67
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c48
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c93
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c47
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c68
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c4
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c31
-rw-r--r--drivers/net/wireless/mac80211_hwsim.h4
-rw-r--r--drivers/net/wireless/mwifiex/11h.c4
-rw-r--r--drivers/net/wireless/mwifiex/11n.c8
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c32
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h3
-rw-r--r--drivers/net/wireless/mwifiex/README2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c205
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c2
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c95
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c8
-rw-r--r--drivers/net/wireless/mwifiex/fw.h13
-rw-r--r--drivers/net/wireless/mwifiex/ie.c6
-rw-r--r--drivers/net/wireless/mwifiex/init.c3
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h2
-rw-r--r--drivers/net/wireless/mwifiex/join.c52
-rw-r--r--drivers/net/wireless/mwifiex/main.c7
-rw-r--r--drivers/net/wireless/mwifiex/main.h14
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c9
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h3
-rw-r--r--drivers/net/wireless/mwifiex/scan.c4
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c9
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h6
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c84
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c9
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c40
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c117
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c18
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c4
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c6
-rw-r--r--drivers/net/wireless/mwifiex/usb.c10
-rw-r--r--drivers/net/wireless/mwifiex/util.c4
-rw-r--r--drivers/net/wireless/mwl8k.c197
-rw-r--r--drivers/net/wireless/orinoco/cfg.c5
-rw-r--r--drivers/net/wireless/orinoco/hw.c2
-rw-r--r--drivers/net/wireless/orinoco/scan.c5
-rw-r--r--drivers/net/wireless/orinoco/wext.c2
-rw-r--r--drivers/net/wireless/p54/p54usb.c2
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c2
-rw-r--r--drivers/net/wireless/rndis_wlan.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c41
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig27
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile3
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/Makefile7
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h75
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c3698
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h173
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c1011
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h559
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c218
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h52
-rw-r--r--drivers/net/wireless/rtlwifi/core.c124
-rw-r--r--drivers/net/wireless/rtlwifi/core.h4
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c66
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h14
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c100
-rw-r--r--drivers/net/wireless/rtlwifi/ps.h60
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/Makefile1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c62
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/phy.c63
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/reg.h16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/trx.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/trx.h8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.c71
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/reg.h16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.h7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c31
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/phy.c71
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.c50
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c18
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/phy.c429
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/reg.h14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/rf.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.h7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c34
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.c87
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/reg.h12
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/rf.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.h8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/Makefile1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/def.h5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.c42
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.c260
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.h18
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c60
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.c530
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.h21
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/reg.h16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c13
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.h13
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/Makefile19
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/def.h248
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.c1325
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.h310
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/fw.c620
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/fw.h248
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.c2527
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.h64
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/led.c153
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/led.h35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/phy.c2156
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/phy.h217
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c106
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h304
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c140
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h95
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/reg.h2277
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/rf.c504
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.c384
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.h35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/table.c572
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/table.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/trx.c960
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/trx.h617
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/Makefile9
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c65
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h33
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c329
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h126
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/main.c33
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c434
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h89
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c4
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h518
-rw-r--r--drivers/net/wireless/ti/wilink_platform_data.c37
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.c2
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.c2
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c31
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.c71
-rw-r--r--drivers/net/wireless/ti/wl1251/wl1251.h4
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c8
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/sysfs.c2
-rw-r--r--drivers/net/wireless/wl3501_cs.c6
-rw-r--r--drivers/net/wireless/zd1201.c9
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/trx.c2
-rw-r--r--drivers/staging/wlan-ng/cfg80211.c2
-rw-r--r--include/linux/ieee80211.h36
-rw-r--r--include/linux/miscdevice.h1
-rw-r--r--include/linux/tty.h6
-rw-r--r--include/linux/wl12xx.h24
-rw-r--r--include/net/bluetooth/bluetooth.h1
-rw-r--r--include/net/bluetooth/hci.h76
-rw-r--r--include/net/bluetooth/hci_core.h197
-rw-r--r--include/net/bluetooth/l2cap.h8
-rw-r--r--include/net/bluetooth/mgmt.h51
-rw-r--r--include/net/bluetooth/rfcomm.h10
-rw-r--r--include/net/cfg80211.h24
-rw-r--r--include/net/mac80211.h43
-rw-r--r--include/uapi/linux/nl80211.h42
-rw-r--r--net/bluetooth/a2mp.c8
-rw-r--r--net/bluetooth/af_bluetooth.c2
-rw-r--r--net/bluetooth/hci_conn.c206
-rw-r--r--net/bluetooth/hci_core.c1193
-rw-r--r--net/bluetooth/hci_event.c478
-rw-r--r--net/bluetooth/hci_sock.c1
-rw-r--r--net/bluetooth/hci_sysfs.c18
-rw-r--r--net/bluetooth/l2cap_core.c616
-rw-r--r--net/bluetooth/l2cap_sock.c62
-rw-r--r--net/bluetooth/mgmt.c913
-rw-r--r--net/bluetooth/rfcomm/core.c92
-rw-r--r--net/bluetooth/rfcomm/sock.c33
-rw-r--r--net/bluetooth/rfcomm/tty.c262
-rw-r--r--net/bluetooth/smp.c418
-rw-r--r--net/bluetooth/smp.h22
-rw-r--r--net/mac80211/cfg.c7
-rw-r--r--net/mac80211/debugfs_netdev.c13
-rw-r--r--net/mac80211/driver-ops.h12
-rw-r--r--net/mac80211/ht.c2
-rw-r--r--net/mac80211/ibss.c5
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/iface.c11
-rw-r--r--net/mac80211/main.c12
-rw-r--r--net/mac80211/mlme.c72
-rw-r--r--net/mac80211/rx.c5
-rw-r--r--net/mac80211/scan.c9
-rw-r--r--net/wireless/chan.c6
-rw-r--r--net/wireless/genregdb.awk2
-rw-r--r--net/wireless/ibss.c7
-rw-r--r--net/wireless/mesh.c6
-rw-r--r--net/wireless/nl80211.c33
-rw-r--r--net/wireless/rdev-ops.h9
-rw-r--r--net/wireless/reg.c83
-rw-r--r--net/wireless/trace.h12
-rw-r--r--net/wireless/util.c31
314 files changed, 30338 insertions, 4597 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 46ad6faee9ab..044b76436e83 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -98,6 +98,8 @@
98!Finclude/net/cfg80211.h priv_to_wiphy 98!Finclude/net/cfg80211.h priv_to_wiphy
99!Finclude/net/cfg80211.h set_wiphy_dev 99!Finclude/net/cfg80211.h set_wiphy_dev
100!Finclude/net/cfg80211.h wdev_priv 100!Finclude/net/cfg80211.h wdev_priv
101!Finclude/net/cfg80211.h ieee80211_iface_limit
102!Finclude/net/cfg80211.h ieee80211_iface_combination
101 </chapter> 103 </chapter>
102 <chapter> 104 <chapter>
103 <title>Actions and configuration</title> 105 <title>Actions and configuration</title>
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 10378cc48374..04356f5bc3af 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -353,6 +353,7 @@ Your cooperation is appreciated.
353 133 = /dev/exttrp External device trap 353 133 = /dev/exttrp External device trap
354 134 = /dev/apm_bios Advanced Power Management BIOS 354 134 = /dev/apm_bios Advanced Power Management BIOS
355 135 = /dev/rtc Real Time Clock 355 135 = /dev/rtc Real Time Clock
356 137 = /dev/vhci Bluetooth virtual HCI driver
356 139 = /dev/openprom SPARC OpenBoot PROM 357 139 = /dev/openprom SPARC OpenBoot PROM
357 140 = /dev/relay8 Berkshire Products Octal relay card 358 140 = /dev/relay8 Berkshire Products Octal relay card
358 141 = /dev/relay16 Berkshire Products ISO-16 relay card 359 141 = /dev/relay16 Berkshire Products ISO-16 relay card
diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt b/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
new file mode 100644
index 000000000000..189ae5cad8f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
@@ -0,0 +1,39 @@
1* Texas Instruments wl1251 wireless lan controller
2
3The wl1251 chip can be connected via SPI or via SDIO. This
4document describes the binding for the SPI connected chip.
5
6Required properties:
7- compatible : Should be "ti,wl1251"
8- reg : Chip select address of device
9- spi-max-frequency : Maximum SPI clocking speed of device in Hz
10- interrupts : Should contain interrupt line
11- interrupt-parent : Should be the phandle for the interrupt controller
12 that services interrupts for this device
13- vio-supply : phandle to regulator providing VIO
14- ti,power-gpio : GPIO connected to chip's PMEN pin
15
16Optional properties:
17- ti,wl1251-has-eeprom : boolean, the wl1251 has an eeprom connected, which
18 provides configuration data (calibration, MAC, ...)
19- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
20 for optional SPI connection related properties,
21
22Examples:
23
24&spi1 {
25 wl1251@0 {
26 compatible = "ti,wl1251";
27
28 reg = <0>;
29 spi-max-frequency = <48000000>;
30 spi-cpol;
31 spi-cpha;
32
33 interrupt-parent = <&gpio2>;
34 interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */
35
36 vio-supply = <&vio>;
37 ti,power-gpio = <&gpio3 23 GPIO_ACTIVE_HIGH>; /* 87 */
38 };
39};
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index de1bc6bbe585..cf18340eb3bb 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -536,11 +536,13 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
536 536
537static void __init pandora_wl1251_init(void) 537static void __init pandora_wl1251_init(void)
538{ 538{
539 struct wl12xx_platform_data pandora_wl1251_pdata; 539 struct wl1251_platform_data pandora_wl1251_pdata;
540 int ret; 540 int ret;
541 541
542 memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); 542 memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
543 543
544 pandora_wl1251_pdata.power_gpio = -1;
545
544 ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); 546 ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
545 if (ret < 0) 547 if (ret < 0)
546 goto fail; 548 goto fail;
@@ -550,7 +552,7 @@ static void __init pandora_wl1251_init(void)
550 goto fail_irq; 552 goto fail_irq;
551 553
552 pandora_wl1251_pdata.use_eeprom = true; 554 pandora_wl1251_pdata.use_eeprom = true;
553 ret = wl12xx_set_platform_data(&pandora_wl1251_pdata); 555 ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
554 if (ret < 0) 556 if (ret < 0)
555 goto fail_irq; 557 goto fail_irq;
556 558
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 8760bbe3baab..ddfc8df83c6a 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -84,7 +84,7 @@ enum {
84 RX51_SPI_MIPID, /* LCD panel */ 84 RX51_SPI_MIPID, /* LCD panel */
85}; 85};
86 86
87static struct wl12xx_platform_data wl1251_pdata; 87static struct wl1251_platform_data wl1251_pdata;
88static struct tsc2005_platform_data tsc2005_pdata; 88static struct tsc2005_platform_data tsc2005_pdata;
89 89
90#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) 90#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
@@ -1173,13 +1173,7 @@ static inline void board_smc91x_init(void)
1173 1173
1174#endif 1174#endif
1175 1175
1176static void rx51_wl1251_set_power(bool enable)
1177{
1178 gpio_set_value(RX51_WL1251_POWER_GPIO, enable);
1179}
1180
1181static struct gpio rx51_wl1251_gpios[] __initdata = { 1176static struct gpio rx51_wl1251_gpios[] __initdata = {
1182 { RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW, "wl1251 power" },
1183 { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" }, 1177 { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" },
1184}; 1178};
1185 1179
@@ -1196,17 +1190,16 @@ static void __init rx51_init_wl1251(void)
1196 if (irq < 0) 1190 if (irq < 0)
1197 goto err_irq; 1191 goto err_irq;
1198 1192
1199 wl1251_pdata.set_power = rx51_wl1251_set_power; 1193 wl1251_pdata.power_gpio = RX51_WL1251_POWER_GPIO;
1200 rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq; 1194 rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq;
1201 1195
1202 return; 1196 return;
1203 1197
1204err_irq: 1198err_irq:
1205 gpio_free(RX51_WL1251_IRQ_GPIO); 1199 gpio_free(RX51_WL1251_IRQ_GPIO);
1206 gpio_free(RX51_WL1251_POWER_GPIO);
1207error: 1200error:
1208 printk(KERN_ERR "wl1251 board initialisation failed\n"); 1201 printk(KERN_ERR "wl1251 board initialisation failed\n");
1209 wl1251_pdata.set_power = NULL; 1202 wl1251_pdata.power_gpio = -1;
1210 1203
1211 /* 1204 /*
1212 * Now rx51_peripherals_spi_board_info[1].irq is zero and 1205 * Now rx51_peripherals_spi_board_info[1].irq is zero and
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 106d1d8e16ad..4f78a9d39dc8 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -62,50 +62,53 @@ static const struct usb_device_id ath3k_table[] = {
62 { USB_DEVICE(0x0CF3, 0x3000) }, 62 { USB_DEVICE(0x0CF3, 0x3000) },
63 63
64 /* Atheros AR3011 with sflash firmware*/ 64 /* Atheros AR3011 with sflash firmware*/
65 { USB_DEVICE(0x0489, 0xE027) },
66 { USB_DEVICE(0x0489, 0xE03D) },
67 { USB_DEVICE(0x0930, 0x0215) },
65 { USB_DEVICE(0x0CF3, 0x3002) }, 68 { USB_DEVICE(0x0CF3, 0x3002) },
66 { USB_DEVICE(0x0CF3, 0xE019) }, 69 { USB_DEVICE(0x0CF3, 0xE019) },
67 { USB_DEVICE(0x13d3, 0x3304) }, 70 { USB_DEVICE(0x13d3, 0x3304) },
68 { USB_DEVICE(0x0930, 0x0215) },
69 { USB_DEVICE(0x0489, 0xE03D) },
70 { USB_DEVICE(0x0489, 0xE027) },
71 71
72 /* Atheros AR9285 Malbec with sflash firmware */ 72 /* Atheros AR9285 Malbec with sflash firmware */
73 { USB_DEVICE(0x03F0, 0x311D) }, 73 { USB_DEVICE(0x03F0, 0x311D) },
74 74
75 /* Atheros AR3012 with sflash firmware*/ 75 /* Atheros AR3012 with sflash firmware*/
76 { USB_DEVICE(0x0CF3, 0x0036) }, 76 { USB_DEVICE(0x0489, 0xe04d) },
77 { USB_DEVICE(0x0CF3, 0x3004) }, 77 { USB_DEVICE(0x0489, 0xe04e) },
78 { USB_DEVICE(0x0CF3, 0x3008) }, 78 { USB_DEVICE(0x0489, 0xe057) },
79 { USB_DEVICE(0x0CF3, 0x311D) }, 79 { USB_DEVICE(0x0489, 0xe056) },
80 { USB_DEVICE(0x0CF3, 0x817a) }, 80 { USB_DEVICE(0x0489, 0xe05f) },
81 { USB_DEVICE(0x13d3, 0x3375) }, 81 { USB_DEVICE(0x04c5, 0x1330) },
82 { USB_DEVICE(0x04CA, 0x3004) }, 82 { USB_DEVICE(0x04CA, 0x3004) },
83 { USB_DEVICE(0x04CA, 0x3005) }, 83 { USB_DEVICE(0x04CA, 0x3005) },
84 { USB_DEVICE(0x04CA, 0x3006) }, 84 { USB_DEVICE(0x04CA, 0x3006) },
85 { USB_DEVICE(0x04CA, 0x3008) }, 85 { USB_DEVICE(0x04CA, 0x3008) },
86 { USB_DEVICE(0x04CA, 0x300b) }, 86 { USB_DEVICE(0x04CA, 0x300b) },
87 { USB_DEVICE(0x13d3, 0x3362) },
88 { USB_DEVICE(0x0CF3, 0xE004) },
89 { USB_DEVICE(0x0CF3, 0xE005) },
90 { USB_DEVICE(0x0930, 0x0219) }, 87 { USB_DEVICE(0x0930, 0x0219) },
91 { USB_DEVICE(0x0930, 0x0220) }, 88 { USB_DEVICE(0x0930, 0x0220) },
92 { USB_DEVICE(0x0489, 0xe057) }, 89 { USB_DEVICE(0x0b05, 0x17d0) },
93 { USB_DEVICE(0x13d3, 0x3393) }, 90 { USB_DEVICE(0x0CF3, 0x0036) },
94 { USB_DEVICE(0x0489, 0xe04e) }, 91 { USB_DEVICE(0x0CF3, 0x3004) },
95 { USB_DEVICE(0x0489, 0xe056) }, 92 { USB_DEVICE(0x0CF3, 0x3008) },
96 { USB_DEVICE(0x0489, 0xe04d) }, 93 { USB_DEVICE(0x0CF3, 0x311D) },
97 { USB_DEVICE(0x04c5, 0x1330) }, 94 { USB_DEVICE(0x0CF3, 0x311E) },
98 { USB_DEVICE(0x13d3, 0x3402) }, 95 { USB_DEVICE(0x0CF3, 0x311F) },
99 { USB_DEVICE(0x0cf3, 0x3121) }, 96 { USB_DEVICE(0x0cf3, 0x3121) },
97 { USB_DEVICE(0x0CF3, 0x817a) },
100 { USB_DEVICE(0x0cf3, 0xe003) }, 98 { USB_DEVICE(0x0cf3, 0xe003) },
101 { USB_DEVICE(0x0489, 0xe05f) }, 99 { USB_DEVICE(0x0CF3, 0xE004) },
100 { USB_DEVICE(0x0CF3, 0xE005) },
101 { USB_DEVICE(0x13d3, 0x3362) },
102 { USB_DEVICE(0x13d3, 0x3375) },
103 { USB_DEVICE(0x13d3, 0x3393) },
104 { USB_DEVICE(0x13d3, 0x3402) },
102 105
103 /* Atheros AR5BBU12 with sflash firmware */ 106 /* Atheros AR5BBU12 with sflash firmware */
104 { USB_DEVICE(0x0489, 0xE02C) }, 107 { USB_DEVICE(0x0489, 0xE02C) },
105 108
106 /* Atheros AR5BBU22 with sflash firmware */ 109 /* Atheros AR5BBU22 with sflash firmware */
107 { USB_DEVICE(0x0489, 0xE03C) },
108 { USB_DEVICE(0x0489, 0xE036) }, 110 { USB_DEVICE(0x0489, 0xE036) },
111 { USB_DEVICE(0x0489, 0xE03C) },
109 112
110 { } /* Terminating entry */ 113 { } /* Terminating entry */
111}; 114};
@@ -118,36 +121,39 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
118static const struct usb_device_id ath3k_blist_tbl[] = { 121static const struct usb_device_id ath3k_blist_tbl[] = {
119 122
120 /* Atheros AR3012 with sflash firmware*/ 123 /* Atheros AR3012 with sflash firmware*/
121 { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, 124 { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
122 { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, 125 { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
123 { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, 126 { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
124 { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, 127 { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
125 { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 }, 128 { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
126 { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, 129 { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
127 { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, 130 { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
128 { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, 131 { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
129 { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, 132 { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
130 { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, 133 { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
131 { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, 134 { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
132 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
133 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
134 { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
135 { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, 135 { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
136 { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, 136 { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
137 { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, 137 { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
138 { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, 138 { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
139 { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, 139 { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
140 { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, 140 { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
141 { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, 141 { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
142 { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, 142 { USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
143 { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, 143 { USB_DEVICE(0x0cf3, 0x311F), .driver_info = BTUSB_ATH3012 },
144 { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, 144 { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
145 { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
146 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
147 { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
145 { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, 148 { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
146 { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, 149 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
150 { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
151 { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
152 { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
147 153
148 /* Atheros AR5BBU22 with sflash firmware */ 154 /* Atheros AR5BBU22 with sflash firmware */
149 { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
150 { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 }, 155 { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
156 { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
151 157
152 { } /* Terminating entry */ 158 { } /* Terminating entry */
153}; 159};
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index baeaaed299e4..199b9d42489c 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -101,21 +101,24 @@ static const struct usb_device_id btusb_table[] = {
101 { USB_DEVICE(0x0c10, 0x0000) }, 101 { USB_DEVICE(0x0c10, 0x0000) },
102 102
103 /* Broadcom BCM20702A0 */ 103 /* Broadcom BCM20702A0 */
104 { USB_DEVICE(0x0489, 0xe042) },
105 { USB_DEVICE(0x04ca, 0x2003) },
104 { USB_DEVICE(0x0b05, 0x17b5) }, 106 { USB_DEVICE(0x0b05, 0x17b5) },
105 { USB_DEVICE(0x0b05, 0x17cb) }, 107 { USB_DEVICE(0x0b05, 0x17cb) },
106 { USB_DEVICE(0x04ca, 0x2003) },
107 { USB_DEVICE(0x0489, 0xe042) },
108 { USB_DEVICE(0x413c, 0x8197) }, 108 { USB_DEVICE(0x413c, 0x8197) },
109 109
110 /* Foxconn - Hon Hai */ 110 /* Foxconn - Hon Hai */
111 { USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) }, 111 { USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) },
112 112
113 /*Broadcom devices with vendor specific id */ 113 /* Broadcom devices with vendor specific id */
114 { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, 114 { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
115 115
116 /* Belkin F8065bf - Broadcom based */ 116 /* Belkin F8065bf - Broadcom based */
117 { USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) }, 117 { USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
118 118
119 /* IMC Networks - Broadcom based */
120 { USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
121
119 { } /* Terminating entry */ 122 { } /* Terminating entry */
120}; 123};
121 124
@@ -129,55 +132,58 @@ static const struct usb_device_id blacklist_table[] = {
129 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, 132 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
130 133
131 /* Atheros 3011 with sflash firmware */ 134 /* Atheros 3011 with sflash firmware */
135 { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
136 { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
137 { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
132 { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, 138 { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
133 { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, 139 { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE },
134 { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, 140 { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
135 { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
136 { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
137 { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
138 141
139 /* Atheros AR9285 Malbec with sflash firmware */ 142 /* Atheros AR9285 Malbec with sflash firmware */
140 { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, 143 { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
141 144
142 /* Atheros 3012 with sflash firmware */ 145 /* Atheros 3012 with sflash firmware */
143 { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, 146 { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
144 { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, 147 { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
145 { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, 148 { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
146 { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, 149 { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
147 { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 }, 150 { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
148 { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, 151 { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
149 { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, 152 { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
150 { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, 153 { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
151 { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, 154 { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
152 { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, 155 { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
153 { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, 156 { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
154 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
155 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
156 { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
157 { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, 157 { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
158 { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, 158 { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
159 { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, 159 { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
160 { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, 160 { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
161 { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, 161 { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
162 { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, 162 { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
163 { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, 163 { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
164 { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, 164 { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
165 { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, 165 { USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 },
166 { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, 166 { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
167 { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
167 { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, 168 { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
168 { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, 169 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
170 { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
171 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
172 { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
173 { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
174 { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
169 175
170 /* Atheros AR5BBU12 with sflash firmware */ 176 /* Atheros AR5BBU12 with sflash firmware */
171 { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, 177 { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
172 178
173 /* Atheros AR5BBU12 with sflash firmware */ 179 /* Atheros AR5BBU12 with sflash firmware */
174 { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
175 { USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 }, 180 { USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },
181 { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
176 182
177 /* Broadcom BCM2035 */ 183 /* Broadcom BCM2035 */
178 { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
179 { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
180 { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, 184 { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
185 { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
186 { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
181 187
182 /* Broadcom BCM2045 */ 188 /* Broadcom BCM2045 */
183 { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU }, 189 { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU },
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 1ef6990a5c7e..add1c6a72063 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -359,7 +359,7 @@ static const struct file_operations vhci_fops = {
359static struct miscdevice vhci_miscdev= { 359static struct miscdevice vhci_miscdev= {
360 .name = "vhci", 360 .name = "vhci",
361 .fops = &vhci_fops, 361 .fops = &vhci_fops,
362 .minor = MISC_DYNAMIC_MINOR, 362 .minor = VHCI_MINOR,
363}; 363};
364 364
365static int __init vhci_init(void) 365static int __init vhci_init(void)
@@ -385,3 +385,4 @@ MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
385MODULE_VERSION(VERSION); 385MODULE_VERSION(VERSION);
386MODULE_LICENSE("GPL"); 386MODULE_LICENSE("GPL");
387MODULE_ALIAS("devname:vhci"); 387MODULE_ALIAS("devname:vhci");
388MODULE_ALIAS_MISCDEV(VHCI_MINOR);
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 200020eb3005..d1fab435f5a3 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -53,7 +53,7 @@ config LIBERTAS_THINFIRM_USB
53 53
54config AIRO 54config AIRO
55 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" 55 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
56 depends on ISA_DMA_API && (PCI || BROKEN) 56 depends on CFG80211 && ISA_DMA_API && (PCI || BROKEN)
57 select WIRELESS_EXT 57 select WIRELESS_EXT
58 select CRYPTO 58 select CRYPTO
59 select WEXT_SPY 59 select WEXT_SPY
@@ -73,7 +73,7 @@ config AIRO
73 73
74config ATMEL 74config ATMEL
75 tristate "Atmel at76c50x chipset 802.11b support" 75 tristate "Atmel at76c50x chipset 802.11b support"
76 depends on (PCI || PCMCIA) 76 depends on CFG80211 && (PCI || PCMCIA)
77 select WIRELESS_EXT 77 select WIRELESS_EXT
78 select WEXT_PRIV 78 select WEXT_PRIV
79 select FW_LOADER 79 select FW_LOADER
@@ -138,7 +138,7 @@ config AIRO_CS
138 138
139config PCMCIA_WL3501 139config PCMCIA_WL3501
140 tristate "Planet WL3501 PCMCIA cards" 140 tristate "Planet WL3501 PCMCIA cards"
141 depends on PCMCIA 141 depends on CFG80211 && PCMCIA
142 select WIRELESS_EXT 142 select WIRELESS_EXT
143 select WEXT_SPY 143 select WEXT_SPY
144 help 144 help
@@ -168,7 +168,7 @@ config PRISM54
168 168
169config USB_ZD1201 169config USB_ZD1201
170 tristate "USB ZD1201 based Wireless device support" 170 tristate "USB ZD1201 based Wireless device support"
171 depends on USB 171 depends on CFG80211 && USB
172 select WIRELESS_EXT 172 select WIRELESS_EXT
173 select WEXT_PRIV 173 select WEXT_PRIV
174 select FW_LOADER 174 select FW_LOADER
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index edf4b57c4aaa..64747d457bb3 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -36,7 +36,7 @@
36#include <linux/bitops.h> 36#include <linux/bitops.h>
37#include <linux/scatterlist.h> 37#include <linux/scatterlist.h>
38#include <linux/crypto.h> 38#include <linux/crypto.h>
39#include <asm/io.h> 39#include <linux/io.h>
40#include <asm/unaligned.h> 40#include <asm/unaligned.h>
41 41
42#include <linux/netdevice.h> 42#include <linux/netdevice.h>
@@ -45,11 +45,11 @@
45#include <linux/if_arp.h> 45#include <linux/if_arp.h>
46#include <linux/ioport.h> 46#include <linux/ioport.h>
47#include <linux/pci.h> 47#include <linux/pci.h>
48#include <asm/uaccess.h> 48#include <linux/uaccess.h>
49#include <linux/kthread.h> 49#include <linux/kthread.h>
50#include <linux/freezer.h> 50#include <linux/freezer.h>
51 51
52#include <linux/ieee80211.h> 52#include <net/cfg80211.h>
53#include <net/iw_handler.h> 53#include <net/iw_handler.h>
54 54
55#include "airo.h" 55#include "airo.h"
@@ -5797,7 +5797,7 @@ static int airo_set_freq(struct net_device *dev,
5797 5797
5798 /* Hack to fall through... */ 5798 /* Hack to fall through... */
5799 fwrq->e = 0; 5799 fwrq->e = 0;
5800 fwrq->m = ieee80211_freq_to_dsss_chan(f); 5800 fwrq->m = ieee80211_frequency_to_channel(f);
5801 } 5801 }
5802 /* Setting by channel number */ 5802 /* Setting by channel number */
5803 if((fwrq->m > 1000) || (fwrq->e > 0)) 5803 if((fwrq->m > 1000) || (fwrq->e > 0))
@@ -5841,7 +5841,8 @@ static int airo_get_freq(struct net_device *dev,
5841 5841
5842 ch = le16_to_cpu(status_rid.channel); 5842 ch = le16_to_cpu(status_rid.channel);
5843 if((ch > 0) && (ch < 15)) { 5843 if((ch > 0) && (ch < 15)) {
5844 fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000; 5844 fwrq->m = 100000 *
5845 ieee80211_channel_to_frequency(ch, IEEE80211_BAND_2GHZ);
5845 fwrq->e = 1; 5846 fwrq->e = 1;
5846 } else { 5847 } else {
5847 fwrq->m = ch; 5848 fwrq->m = ch;
@@ -6898,7 +6899,8 @@ static int airo_get_range(struct net_device *dev,
6898 k = 0; 6899 k = 0;
6899 for(i = 0; i < 14; i++) { 6900 for(i = 0; i < 14; i++) {
6900 range->freq[k].i = i + 1; /* List index */ 6901 range->freq[k].i = i + 1; /* List index */
6901 range->freq[k].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000; 6902 range->freq[k].m = 100000 *
6903 ieee80211_channel_to_frequency(i + 1, IEEE80211_BAND_2GHZ);
6902 range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */ 6904 range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
6903 } 6905 }
6904 range->num_frequency = k; 6906 range->num_frequency = k;
@@ -7297,7 +7299,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
7297 /* Add frequency */ 7299 /* Add frequency */
7298 iwe.cmd = SIOCGIWFREQ; 7300 iwe.cmd = SIOCGIWFREQ;
7299 iwe.u.freq.m = le16_to_cpu(bss->dsChannel); 7301 iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7300 iwe.u.freq.m = ieee80211_dsss_chan_to_freq(iwe.u.freq.m) * 100000; 7302 iwe.u.freq.m = 100000 *
7303 ieee80211_channel_to_frequency(iwe.u.freq.m, IEEE80211_BAND_2GHZ);
7301 iwe.u.freq.e = 1; 7304 iwe.u.freq.e = 1;
7302 current_ev = iwe_stream_add_event(info, current_ev, end_buf, 7305 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7303 &iwe, IW_EV_FREQ_LEN); 7306 &iwe, IW_EV_FREQ_LEN);
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 6260b834a86f..d239acc26125 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -63,7 +63,7 @@ enum ath_bus_type {
63}; 63};
64 64
65struct reg_dmn_pair_mapping { 65struct reg_dmn_pair_mapping {
66 u16 regDmnEnum; 66 u16 reg_domain;
67 u16 reg_5ghz_ctl; 67 u16 reg_5ghz_ctl;
68 u16 reg_2ghz_ctl; 68 u16 reg_2ghz_ctl;
69}; 69};
@@ -163,6 +163,7 @@ struct ath_common {
163 bool bt_ant_diversity; 163 bool bt_ant_diversity;
164 164
165 int last_rssi; 165 int last_rssi;
166 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
166}; 167};
167 168
168struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, 169struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 3b59af3bddf4..ebc5fc2ede75 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -55,8 +55,7 @@ static void ath10k_send_suspend_complete(struct ath10k *ar)
55{ 55{
56 ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n"); 56 ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n");
57 57
58 ar->is_target_paused = true; 58 complete(&ar->target_suspend);
59 wake_up(&ar->event_queue);
60} 59}
61 60
62static int ath10k_init_connect_htc(struct ath10k *ar) 61static int ath10k_init_connect_htc(struct ath10k *ar)
@@ -470,8 +469,12 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
470 if (index == ie_len) 469 if (index == ie_len)
471 break; 470 break;
472 471
473 if (data[index] & (1 << bit)) 472 if (data[index] & (1 << bit)) {
473 ath10k_dbg(ATH10K_DBG_BOOT,
474 "Enabling feature bit: %i\n",
475 i);
474 __set_bit(i, ar->fw_features); 476 __set_bit(i, ar->fw_features);
477 }
475 } 478 }
476 479
477 ath10k_dbg_dump(ATH10K_DBG_BOOT, "features", "", 480 ath10k_dbg_dump(ATH10K_DBG_BOOT, "features", "",
@@ -699,6 +702,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
699 init_completion(&ar->scan.started); 702 init_completion(&ar->scan.started);
700 init_completion(&ar->scan.completed); 703 init_completion(&ar->scan.completed);
701 init_completion(&ar->scan.on_channel); 704 init_completion(&ar->scan.on_channel);
705 init_completion(&ar->target_suspend);
702 706
703 init_completion(&ar->install_key_done); 707 init_completion(&ar->install_key_done);
704 init_completion(&ar->vdev_setup_done); 708 init_completion(&ar->vdev_setup_done);
@@ -722,8 +726,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
722 INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); 726 INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work);
723 skb_queue_head_init(&ar->wmi_mgmt_tx_queue); 727 skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
724 728
725 init_waitqueue_head(&ar->event_queue);
726
727 INIT_WORK(&ar->restart_work, ath10k_core_restart); 729 INIT_WORK(&ar->restart_work, ath10k_core_restart);
728 730
729 return ar; 731 return ar;
@@ -856,10 +858,34 @@ err:
856} 858}
857EXPORT_SYMBOL(ath10k_core_start); 859EXPORT_SYMBOL(ath10k_core_start);
858 860
861int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
862{
863 int ret;
864
865 reinit_completion(&ar->target_suspend);
866
867 ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
868 if (ret) {
869 ath10k_warn("could not suspend target (%d)\n", ret);
870 return ret;
871 }
872
873 ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
874
875 if (ret == 0) {
876 ath10k_warn("suspend timed out - target pause event never came\n");
877 return -ETIMEDOUT;
878 }
879
880 return 0;
881}
882
859void ath10k_core_stop(struct ath10k *ar) 883void ath10k_core_stop(struct ath10k *ar)
860{ 884{
861 lockdep_assert_held(&ar->conf_mutex); 885 lockdep_assert_held(&ar->conf_mutex);
862 886
887 /* try to suspend target */
888 ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
863 ath10k_debug_stop(ar); 889 ath10k_debug_stop(ar);
864 ath10k_htc_stop(&ar->htc); 890 ath10k_htc_stop(&ar->htc);
865 ath10k_htt_detach(&ar->htt); 891 ath10k_htt_detach(&ar->htt);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index ade1781c7186..1fc26fe057e8 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -46,6 +46,18 @@
46 46
47#define ATH10K_MAX_NUM_MGMT_PENDING 128 47#define ATH10K_MAX_NUM_MGMT_PENDING 128
48 48
49/* number of failed packets */
50#define ATH10K_KICKOUT_THRESHOLD 50
51
52/*
53 * Use insanely high numbers to make sure that the firmware implementation
54 * won't start, we have the same functionality already in hostapd. Unit
55 * is seconds.
56 */
57#define ATH10K_KEEPALIVE_MIN_IDLE 3747
58#define ATH10K_KEEPALIVE_MAX_IDLE 3895
59#define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900
60
49struct ath10k; 61struct ath10k;
50 62
51struct ath10k_skb_cb { 63struct ath10k_skb_cb {
@@ -61,6 +73,11 @@ struct ath10k_skb_cb {
61 u8 frag_len; 73 u8 frag_len;
62 u8 pad_len; 74 u8 pad_len;
63 } __packed htt; 75 } __packed htt;
76
77 struct {
78 bool dtim_zero;
79 bool deliver_cab;
80 } bcn;
64} __packed; 81} __packed;
65 82
66static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb) 83static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb)
@@ -211,6 +228,18 @@ struct ath10k_peer {
211 struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; 228 struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
212}; 229};
213 230
231struct ath10k_sta {
232 struct ath10k_vif *arvif;
233
234 /* the following are protected by ar->data_lock */
235 u32 changed; /* IEEE80211_RC_* */
236 u32 bw;
237 u32 nss;
238 u32 smps;
239
240 struct work_struct update_wk;
241};
242
214#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ) 243#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ)
215 244
216struct ath10k_vif { 245struct ath10k_vif {
@@ -222,10 +251,17 @@ struct ath10k_vif {
222 u32 beacon_interval; 251 u32 beacon_interval;
223 u32 dtim_period; 252 u32 dtim_period;
224 struct sk_buff *beacon; 253 struct sk_buff *beacon;
254 /* protected by data_lock */
255 bool beacon_sent;
225 256
226 struct ath10k *ar; 257 struct ath10k *ar;
227 struct ieee80211_vif *vif; 258 struct ieee80211_vif *vif;
228 259
260 bool is_started;
261 bool is_up;
262 u32 aid;
263 u8 bssid[ETH_ALEN];
264
229 struct work_struct wep_key_work; 265 struct work_struct wep_key_work;
230 struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1]; 266 struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1];
231 u8 def_wep_key_idx; 267 u8 def_wep_key_idx;
@@ -235,7 +271,6 @@ struct ath10k_vif {
235 271
236 union { 272 union {
237 struct { 273 struct {
238 u8 bssid[ETH_ALEN];
239 u32 uapsd; 274 u32 uapsd;
240 } sta; 275 } sta;
241 struct { 276 struct {
@@ -249,9 +284,6 @@ struct ath10k_vif {
249 u32 noa_len; 284 u32 noa_len;
250 u8 *noa_data; 285 u8 *noa_data;
251 } ap; 286 } ap;
252 struct {
253 u8 bssid[ETH_ALEN];
254 } ibss;
255 } u; 287 } u;
256 288
257 u8 fixed_rate; 289 u8 fixed_rate;
@@ -355,8 +387,7 @@ struct ath10k {
355 const struct ath10k_hif_ops *ops; 387 const struct ath10k_hif_ops *ops;
356 } hif; 388 } hif;
357 389
358 wait_queue_head_t event_queue; 390 struct completion target_suspend;
359 bool is_target_paused;
360 391
361 struct ath10k_bmi bmi; 392 struct ath10k_bmi bmi;
362 struct ath10k_wmi wmi; 393 struct ath10k_wmi wmi;
@@ -412,6 +443,9 @@ struct ath10k {
412 /* valid during scan; needed for mgmt rx during scan */ 443 /* valid during scan; needed for mgmt rx during scan */
413 struct ieee80211_channel *scan_channel; 444 struct ieee80211_channel *scan_channel;
414 445
446 /* current operating channel definition */
447 struct cfg80211_chan_def chandef;
448
415 int free_vdev_map; 449 int free_vdev_map;
416 int monitor_vdev_id; 450 int monitor_vdev_id;
417 bool monitor_enabled; 451 bool monitor_enabled;
@@ -470,6 +504,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
470void ath10k_core_destroy(struct ath10k *ar); 504void ath10k_core_destroy(struct ath10k *ar);
471 505
472int ath10k_core_start(struct ath10k *ar); 506int ath10k_core_start(struct ath10k *ar);
507int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt);
473void ath10k_core_stop(struct ath10k *ar); 508void ath10k_core_stop(struct ath10k *ar);
474int ath10k_core_register(struct ath10k *ar, u32 chip_id); 509int ath10k_core_register(struct ath10k *ar, u32 chip_id);
475void ath10k_core_unregister(struct ath10k *ar); 510void ath10k_core_unregister(struct ath10k *ar);
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index 1773c36c71a0..a5824990bd2a 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -92,7 +92,7 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar,
92 92
93#ifdef CONFIG_ATH10K_DEBUG 93#ifdef CONFIG_ATH10K_DEBUG
94__printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask, 94__printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask,
95 const char *fmt, ...); 95 const char *fmt, ...);
96void ath10k_dbg_dump(enum ath10k_debug_mask mask, 96void ath10k_dbg_dump(enum ath10k_debug_mask mask,
97 const char *msg, const char *prefix, 97 const char *msg, const char *prefix,
98 const void *buf, size_t len); 98 const void *buf, size_t len);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index fe8bd1b59f0e..4767c24bf819 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -324,7 +324,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
324 msdu->len + skb_tailroom(msdu), 324 msdu->len + skb_tailroom(msdu),
325 DMA_FROM_DEVICE); 325 DMA_FROM_DEVICE);
326 326
327 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx: ", 327 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx pop: ",
328 msdu->data, msdu->len + skb_tailroom(msdu)); 328 msdu->data, msdu->len + skb_tailroom(msdu));
329 329
330 rx_desc = (struct htt_rx_desc *)msdu->data; 330 rx_desc = (struct htt_rx_desc *)msdu->data;
@@ -417,8 +417,8 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
417 next->len + skb_tailroom(next), 417 next->len + skb_tailroom(next),
418 DMA_FROM_DEVICE); 418 DMA_FROM_DEVICE);
419 419
420 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx: ", 420 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL,
421 next->data, 421 "htt rx chained: ", next->data,
422 next->len + skb_tailroom(next)); 422 next->len + skb_tailroom(next));
423 423
424 skb_trim(next, 0); 424 skb_trim(next, 0);
@@ -430,12 +430,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
430 msdu_chaining = 1; 430 msdu_chaining = 1;
431 } 431 }
432 432
433 if (msdu_len > 0) {
434 /* This may suggest FW bug? */
435 ath10k_warn("htt rx msdu len not consumed (%d)\n",
436 msdu_len);
437 }
438
439 last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) & 433 last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
440 RX_MSDU_END_INFO0_LAST_MSDU; 434 RX_MSDU_END_INFO0_LAST_MSDU;
441 435
@@ -751,7 +745,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
751 745
752 /* This shouldn't happen. If it does than it may be a FW bug. */ 746 /* This shouldn't happen. If it does than it may be a FW bug. */
753 if (skb->next) { 747 if (skb->next) {
754 ath10k_warn("received chained non A-MSDU frame\n"); 748 ath10k_warn("htt rx received chained non A-MSDU frame\n");
755 ath10k_htt_rx_free_msdu_chain(skb->next); 749 ath10k_htt_rx_free_msdu_chain(skb->next);
756 skb->next = NULL; 750 skb->next = NULL;
757 } 751 }
@@ -937,6 +931,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
937 } 931 }
938 932
939 if (ath10k_htt_rx_has_decrypt_err(msdu_head)) { 933 if (ath10k_htt_rx_has_decrypt_err(msdu_head)) {
934 ath10k_dbg(ATH10K_DBG_HTT,
935 "htt rx dropping due to decrypt-err\n");
940 ath10k_htt_rx_free_msdu_chain(msdu_head); 936 ath10k_htt_rx_free_msdu_chain(msdu_head);
941 continue; 937 continue;
942 } 938 }
@@ -945,12 +941,14 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
945 941
946 /* Skip mgmt frames while we handle this in WMI */ 942 /* Skip mgmt frames while we handle this in WMI */
947 if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL) { 943 if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL) {
944 ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
948 ath10k_htt_rx_free_msdu_chain(msdu_head); 945 ath10k_htt_rx_free_msdu_chain(msdu_head);
949 continue; 946 continue;
950 } 947 }
951 948
952 if (status != HTT_RX_IND_MPDU_STATUS_OK && 949 if (status != HTT_RX_IND_MPDU_STATUS_OK &&
953 status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR && 950 status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
951 status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER &&
954 !htt->ar->monitor_enabled) { 952 !htt->ar->monitor_enabled) {
955 ath10k_dbg(ATH10K_DBG_HTT, 953 ath10k_dbg(ATH10K_DBG_HTT,
956 "htt rx ignoring frame w/ status %d\n", 954 "htt rx ignoring frame w/ status %d\n",
@@ -960,6 +958,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
960 } 958 }
961 959
962 if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) { 960 if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
961 ath10k_dbg(ATH10K_DBG_HTT,
962 "htt rx CAC running\n");
963 ath10k_htt_rx_free_msdu_chain(msdu_head); 963 ath10k_htt_rx_free_msdu_chain(msdu_head);
964 continue; 964 continue;
965 } 965 }
@@ -967,7 +967,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
967 /* FIXME: we do not support chaining yet. 967 /* FIXME: we do not support chaining yet.
968 * this needs investigation */ 968 * this needs investigation */
969 if (msdu_chaining) { 969 if (msdu_chaining) {
970 ath10k_warn("msdu_chaining is true\n"); 970 ath10k_warn("htt rx msdu_chaining is true\n");
971 ath10k_htt_rx_free_msdu_chain(msdu_head); 971 ath10k_htt_rx_free_msdu_chain(msdu_head);
972 continue; 972 continue;
973 } 973 }
@@ -975,6 +975,15 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
975 info.skb = msdu_head; 975 info.skb = msdu_head;
976 info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head); 976 info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
977 info.mic_err = ath10k_htt_rx_has_mic_err(msdu_head); 977 info.mic_err = ath10k_htt_rx_has_mic_err(msdu_head);
978
979 if (info.fcs_err)
980 ath10k_dbg(ATH10K_DBG_HTT,
981 "htt rx has FCS err\n");
982
983 if (info.mic_err)
984 ath10k_dbg(ATH10K_DBG_HTT,
985 "htt rx has MIC err\n");
986
978 info.signal = ATH10K_DEFAULT_NOISE_FLOOR; 987 info.signal = ATH10K_DEFAULT_NOISE_FLOOR;
979 info.signal += rx->ppdu.combined_rssi; 988 info.signal += rx->ppdu.combined_rssi;
980 989
@@ -1095,7 +1104,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
1095 1104
1096 skb_trim(info.skb, info.skb->len - trim); 1105 skb_trim(info.skb, info.skb->len - trim);
1097 1106
1098 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt frag mpdu: ", 1107 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ",
1099 info.skb->data, info.skb->len); 1108 info.skb->data, info.skb->len);
1100 ath10k_process_rx(htt->ar, &info); 1109 ath10k_process_rx(htt->ar, &info);
1101 1110
@@ -1116,7 +1125,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
1116 if (!IS_ALIGNED((unsigned long)skb->data, 4)) 1125 if (!IS_ALIGNED((unsigned long)skb->data, 4))
1117 ath10k_warn("unaligned htt message, expect trouble\n"); 1126 ath10k_warn("unaligned htt message, expect trouble\n");
1118 1127
1119 ath10k_dbg(ATH10K_DBG_HTT, "HTT RX, msg_type: 0x%0X\n", 1128 ath10k_dbg(ATH10K_DBG_HTT, "htt rx, msg_type: 0x%0X\n",
1120 resp->hdr.msg_type); 1129 resp->hdr.msg_type);
1121 switch (resp->hdr.msg_type) { 1130 switch (resp->hdr.msg_type) {
1122 case HTT_T2H_MSG_TYPE_VERSION_CONF: { 1131 case HTT_T2H_MSG_TYPE_VERSION_CONF: {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index f1d36d2d2723..acaa046dc93b 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -460,9 +460,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
460 DMA_TO_DEVICE); 460 DMA_TO_DEVICE);
461 } 461 }
462 462
463 ath10k_dbg(ATH10K_DBG_HTT, "msdu 0x%llx\n", 463 ath10k_dbg(ATH10K_DBG_HTT, "tx-msdu 0x%llx\n",
464 (unsigned long long) ATH10K_SKB_CB(msdu)->paddr); 464 (unsigned long long) ATH10K_SKB_CB(msdu)->paddr);
465 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "msdu: ", 465 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "tx-msdu: ",
466 msdu->data, msdu->len); 466 msdu->data, msdu->len);
467 467
468 skb_put(txdesc, desc_len); 468 skb_put(txdesc, desc_len);
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index f1505a25d810..35fc44e281f5 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -205,8 +205,11 @@ enum ath10k_mcast2ucast_mode {
205#define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000 205#define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000
206#define PCIE_LOCAL_BASE_ADDRESS 0x00080000 206#define PCIE_LOCAL_BASE_ADDRESS 0x00080000
207 207
208#define SOC_RESET_CONTROL_ADDRESS 0x00000000
208#define SOC_RESET_CONTROL_OFFSET 0x00000000 209#define SOC_RESET_CONTROL_OFFSET 0x00000000
209#define SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001 210#define SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001
211#define SOC_RESET_CONTROL_CE_RST_MASK 0x00040000
212#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040
210#define SOC_CPU_CLOCK_OFFSET 0x00000020 213#define SOC_CPU_CLOCK_OFFSET 0x00000020
211#define SOC_CPU_CLOCK_STANDARD_LSB 0 214#define SOC_CPU_CLOCK_STANDARD_LSB 0
212#define SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 215#define SOC_CPU_CLOCK_STANDARD_MASK 0x00000003
@@ -216,6 +219,8 @@ enum ath10k_mcast2ucast_mode {
216#define SOC_LPO_CAL_OFFSET 0x000000e0 219#define SOC_LPO_CAL_OFFSET 0x000000e0
217#define SOC_LPO_CAL_ENABLE_LSB 20 220#define SOC_LPO_CAL_ENABLE_LSB 20
218#define SOC_LPO_CAL_ENABLE_MASK 0x00100000 221#define SOC_LPO_CAL_ENABLE_MASK 0x00100000
222#define SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050
223#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004
219 224
220#define SOC_CHIP_ID_ADDRESS 0x000000ec 225#define SOC_CHIP_ID_ADDRESS 0x000000ec
221#define SOC_CHIP_ID_REV_LSB 8 226#define SOC_CHIP_ID_REV_LSB 8
@@ -273,6 +278,7 @@ enum ath10k_mcast2ucast_mode {
273#define PCIE_INTR_CAUSE_ADDRESS 0x000c 278#define PCIE_INTR_CAUSE_ADDRESS 0x000c
274#define PCIE_INTR_CLR_ADDRESS 0x0014 279#define PCIE_INTR_CLR_ADDRESS 0x0014
275#define SCRATCH_3_ADDRESS 0x0030 280#define SCRATCH_3_ADDRESS 0x0030
281#define CPU_INTR_ADDRESS 0x0010
276 282
277/* Firmware indications to the Host via SCRATCH_3 register. */ 283/* Firmware indications to the Host via SCRATCH_3 register. */
278#define FW_INDICATOR_ADDRESS (SOC_CORE_BASE_ADDRESS + SCRATCH_3_ADDRESS) 284#define FW_INDICATOR_ADDRESS (SOC_CORE_BASE_ADDRESS + SCRATCH_3_ADDRESS)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 776e364eadcd..e17f5d732b5a 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -339,6 +339,50 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
339 return 0; 339 return 0;
340} 340}
341 341
342static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
343{
344 struct ath10k *ar = arvif->ar;
345 u32 param;
346 int ret;
347
348 param = ar->wmi.pdev_param->sta_kickout_th;
349 ret = ath10k_wmi_pdev_set_param(ar, param,
350 ATH10K_KICKOUT_THRESHOLD);
351 if (ret) {
352 ath10k_warn("Failed to set kickout threshold: %d\n", ret);
353 return ret;
354 }
355
356 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
357 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
358 ATH10K_KEEPALIVE_MIN_IDLE);
359 if (ret) {
360 ath10k_warn("Failed to set keepalive minimum idle time : %d\n",
361 ret);
362 return ret;
363 }
364
365 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
366 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
367 ATH10K_KEEPALIVE_MAX_IDLE);
368 if (ret) {
369 ath10k_warn("Failed to set keepalive maximum idle time: %d\n",
370 ret);
371 return ret;
372 }
373
374 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
375 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
376 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
377 if (ret) {
378 ath10k_warn("Failed to set keepalive maximum unresponsive time: %d\n",
379 ret);
380 return ret;
381 }
382
383 return 0;
384}
385
342static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value) 386static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
343{ 387{
344 struct ath10k *ar = arvif->ar; 388 struct ath10k *ar = arvif->ar;
@@ -444,8 +488,7 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
444static int ath10k_vdev_start(struct ath10k_vif *arvif) 488static int ath10k_vdev_start(struct ath10k_vif *arvif)
445{ 489{
446 struct ath10k *ar = arvif->ar; 490 struct ath10k *ar = arvif->ar;
447 struct ieee80211_conf *conf = &ar->hw->conf; 491 struct cfg80211_chan_def *chandef = &ar->chandef;
448 struct ieee80211_channel *channel = conf->chandef.chan;
449 struct wmi_vdev_start_request_arg arg = {}; 492 struct wmi_vdev_start_request_arg arg = {};
450 int ret = 0; 493 int ret = 0;
451 494
@@ -457,16 +500,14 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
457 arg.dtim_period = arvif->dtim_period; 500 arg.dtim_period = arvif->dtim_period;
458 arg.bcn_intval = arvif->beacon_interval; 501 arg.bcn_intval = arvif->beacon_interval;
459 502
460 arg.channel.freq = channel->center_freq; 503 arg.channel.freq = chandef->chan->center_freq;
461 504 arg.channel.band_center_freq1 = chandef->center_freq1;
462 arg.channel.band_center_freq1 = conf->chandef.center_freq1; 505 arg.channel.mode = chan_to_phymode(chandef);
463
464 arg.channel.mode = chan_to_phymode(&conf->chandef);
465 506
466 arg.channel.min_power = 0; 507 arg.channel.min_power = 0;
467 arg.channel.max_power = channel->max_power * 2; 508 arg.channel.max_power = chandef->chan->max_power * 2;
468 arg.channel.max_reg_power = channel->max_reg_power * 2; 509 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
469 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; 510 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
470 511
471 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 512 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
472 arg.ssid = arvif->u.ap.ssid; 513 arg.ssid = arvif->u.ap.ssid;
@@ -475,7 +516,7 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
475 516
476 /* For now allow DFS for AP mode */ 517 /* For now allow DFS for AP mode */
477 arg.channel.chan_radar = 518 arg.channel.chan_radar =
478 !!(channel->flags & IEEE80211_CHAN_RADAR); 519 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
479 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { 520 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
480 arg.ssid = arvif->vif->bss_conf.ssid; 521 arg.ssid = arvif->vif->bss_conf.ssid;
481 arg.ssid_len = arvif->vif->bss_conf.ssid_len; 522 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
@@ -527,7 +568,8 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
527 568
528static int ath10k_monitor_start(struct ath10k *ar, int vdev_id) 569static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
529{ 570{
530 struct ieee80211_channel *channel = ar->hw->conf.chandef.chan; 571 struct cfg80211_chan_def *chandef = &ar->chandef;
572 struct ieee80211_channel *channel = chandef->chan;
531 struct wmi_vdev_start_request_arg arg = {}; 573 struct wmi_vdev_start_request_arg arg = {};
532 int ret = 0; 574 int ret = 0;
533 575
@@ -540,11 +582,11 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
540 582
541 arg.vdev_id = vdev_id; 583 arg.vdev_id = vdev_id;
542 arg.channel.freq = channel->center_freq; 584 arg.channel.freq = channel->center_freq;
543 arg.channel.band_center_freq1 = ar->hw->conf.chandef.center_freq1; 585 arg.channel.band_center_freq1 = chandef->center_freq1;
544 586
545 /* TODO setup this dynamically, what in case we 587 /* TODO setup this dynamically, what in case we
546 don't have any vifs? */ 588 don't have any vifs? */
547 arg.channel.mode = chan_to_phymode(&ar->hw->conf.chandef); 589 arg.channel.mode = chan_to_phymode(chandef);
548 arg.channel.chan_radar = 590 arg.channel.chan_radar =
549 !!(channel->flags & IEEE80211_CHAN_RADAR); 591 !!(channel->flags & IEEE80211_CHAN_RADAR);
550 592
@@ -791,6 +833,20 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
791 833
792 if (!info->enable_beacon) { 834 if (!info->enable_beacon) {
793 ath10k_vdev_stop(arvif); 835 ath10k_vdev_stop(arvif);
836
837 arvif->is_started = false;
838 arvif->is_up = false;
839
840 spin_lock_bh(&arvif->ar->data_lock);
841 if (arvif->beacon) {
842 ath10k_skb_unmap(arvif->ar->dev, arvif->beacon);
843 dev_kfree_skb_any(arvif->beacon);
844
845 arvif->beacon = NULL;
846 arvif->beacon_sent = false;
847 }
848 spin_unlock_bh(&arvif->ar->data_lock);
849
794 return; 850 return;
795 } 851 }
796 852
@@ -800,12 +856,21 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
800 if (ret) 856 if (ret)
801 return; 857 return;
802 858
803 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, 0, info->bssid); 859 arvif->aid = 0;
860 memcpy(arvif->bssid, info->bssid, ETH_ALEN);
861
862 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
863 arvif->bssid);
804 if (ret) { 864 if (ret) {
805 ath10k_warn("Failed to bring up VDEV: %d\n", 865 ath10k_warn("Failed to bring up VDEV: %d\n",
806 arvif->vdev_id); 866 arvif->vdev_id);
867 ath10k_vdev_stop(arvif);
807 return; 868 return;
808 } 869 }
870
871 arvif->is_started = true;
872 arvif->is_up = true;
873
809 ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id); 874 ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
810} 875}
811 876
@@ -824,18 +889,18 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
824 ath10k_warn("Failed to delete IBSS self peer:%pM for VDEV:%d ret:%d\n", 889 ath10k_warn("Failed to delete IBSS self peer:%pM for VDEV:%d ret:%d\n",
825 self_peer, arvif->vdev_id, ret); 890 self_peer, arvif->vdev_id, ret);
826 891
827 if (is_zero_ether_addr(arvif->u.ibss.bssid)) 892 if (is_zero_ether_addr(arvif->bssid))
828 return; 893 return;
829 894
830 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, 895 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id,
831 arvif->u.ibss.bssid); 896 arvif->bssid);
832 if (ret) { 897 if (ret) {
833 ath10k_warn("Failed to delete IBSS BSSID peer:%pM for VDEV:%d ret:%d\n", 898 ath10k_warn("Failed to delete IBSS BSSID peer:%pM for VDEV:%d ret:%d\n",
834 arvif->u.ibss.bssid, arvif->vdev_id, ret); 899 arvif->bssid, arvif->vdev_id, ret);
835 return; 900 return;
836 } 901 }
837 902
838 memset(arvif->u.ibss.bssid, 0, ETH_ALEN); 903 memset(arvif->bssid, 0, ETH_ALEN);
839 904
840 return; 905 return;
841 } 906 }
@@ -1017,7 +1082,6 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
1017 struct wmi_peer_assoc_complete_arg *arg) 1082 struct wmi_peer_assoc_complete_arg *arg)
1018{ 1083{
1019 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 1084 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1020 int smps;
1021 int i, n; 1085 int i, n;
1022 1086
1023 lockdep_assert_held(&ar->conf_mutex); 1087 lockdep_assert_held(&ar->conf_mutex);
@@ -1063,17 +1127,6 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
1063 arg->peer_flags |= WMI_PEER_STBC; 1127 arg->peer_flags |= WMI_PEER_STBC;
1064 } 1128 }
1065 1129
1066 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
1067 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
1068
1069 if (smps == WLAN_HT_CAP_SM_PS_STATIC) {
1070 arg->peer_flags |= WMI_PEER_SPATIAL_MUX;
1071 arg->peer_flags |= WMI_PEER_STATIC_MIMOPS;
1072 } else if (smps == WLAN_HT_CAP_SM_PS_DYNAMIC) {
1073 arg->peer_flags |= WMI_PEER_SPATIAL_MUX;
1074 arg->peer_flags |= WMI_PEER_DYN_MIMOPS;
1075 }
1076
1077 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2]) 1130 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
1078 arg->peer_rate_caps |= WMI_RC_TS_FLAG; 1131 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
1079 else if (ht_cap->mcs.rx_mask[1]) 1132 else if (ht_cap->mcs.rx_mask[1])
@@ -1083,8 +1136,23 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
1083 if (ht_cap->mcs.rx_mask[i/8] & (1 << i%8)) 1136 if (ht_cap->mcs.rx_mask[i/8] & (1 << i%8))
1084 arg->peer_ht_rates.rates[n++] = i; 1137 arg->peer_ht_rates.rates[n++] = i;
1085 1138
1086 arg->peer_ht_rates.num_rates = n; 1139 /*
1087 arg->peer_num_spatial_streams = max((n+7) / 8, 1); 1140 * This is a workaround for HT-enabled STAs which break the spec
1141 * and have no HT capabilities RX mask (no HT RX MCS map).
1142 *
1143 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
1144 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
1145 *
1146 * Firmware asserts if such situation occurs.
1147 */
1148 if (n == 0) {
1149 arg->peer_ht_rates.num_rates = 8;
1150 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
1151 arg->peer_ht_rates.rates[i] = i;
1152 } else {
1153 arg->peer_ht_rates.num_rates = n;
1154 arg->peer_num_spatial_streams = sta->rx_nss;
1155 }
1088 1156
1089 ath10k_dbg(ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", 1157 ath10k_dbg(ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
1090 arg->addr, 1158 arg->addr,
@@ -1092,27 +1160,20 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
1092 arg->peer_num_spatial_streams); 1160 arg->peer_num_spatial_streams);
1093} 1161}
1094 1162
1095static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar, 1163static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
1096 struct ath10k_vif *arvif, 1164 struct ath10k_vif *arvif,
1097 struct ieee80211_sta *sta, 1165 struct ieee80211_sta *sta)
1098 struct ieee80211_bss_conf *bss_conf,
1099 struct wmi_peer_assoc_complete_arg *arg)
1100{ 1166{
1101 u32 uapsd = 0; 1167 u32 uapsd = 0;
1102 u32 max_sp = 0; 1168 u32 max_sp = 0;
1169 int ret = 0;
1103 1170
1104 lockdep_assert_held(&ar->conf_mutex); 1171 lockdep_assert_held(&ar->conf_mutex);
1105 1172
1106 if (sta->wme)
1107 arg->peer_flags |= WMI_PEER_QOS;
1108
1109 if (sta->wme && sta->uapsd_queues) { 1173 if (sta->wme && sta->uapsd_queues) {
1110 ath10k_dbg(ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n", 1174 ath10k_dbg(ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
1111 sta->uapsd_queues, sta->max_sp); 1175 sta->uapsd_queues, sta->max_sp);
1112 1176
1113 arg->peer_flags |= WMI_PEER_APSD;
1114 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
1115
1116 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) 1177 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
1117 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN | 1178 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
1118 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN; 1179 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
@@ -1130,35 +1191,40 @@ static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar,
1130 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP) 1191 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
1131 max_sp = sta->max_sp; 1192 max_sp = sta->max_sp;
1132 1193
1133 ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, 1194 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
1134 sta->addr, 1195 sta->addr,
1135 WMI_AP_PS_PEER_PARAM_UAPSD, 1196 WMI_AP_PS_PEER_PARAM_UAPSD,
1136 uapsd); 1197 uapsd);
1198 if (ret) {
1199 ath10k_warn("failed to set ap ps peer param uapsd: %d\n",
1200 ret);
1201 return ret;
1202 }
1137 1203
1138 ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, 1204 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
1139 sta->addr, 1205 sta->addr,
1140 WMI_AP_PS_PEER_PARAM_MAX_SP, 1206 WMI_AP_PS_PEER_PARAM_MAX_SP,
1141 max_sp); 1207 max_sp);
1208 if (ret) {
1209 ath10k_warn("failed to set ap ps peer param max sp: %d\n",
1210 ret);
1211 return ret;
1212 }
1142 1213
1143 /* TODO setup this based on STA listen interval and 1214 /* TODO setup this based on STA listen interval and
1144 beacon interval. Currently we don't know 1215 beacon interval. Currently we don't know
1145 sta->listen_interval - mac80211 patch required. 1216 sta->listen_interval - mac80211 patch required.
1146 Currently use 10 seconds */ 1217 Currently use 10 seconds */
1147 ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, 1218 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
1148 sta->addr, 1219 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, 10);
1149 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, 1220 if (ret) {
1150 10); 1221 ath10k_warn("failed to set ap ps peer param ageout time: %d\n",
1222 ret);
1223 return ret;
1224 }
1151 } 1225 }
1152}
1153 1226
1154static void ath10k_peer_assoc_h_qos_sta(struct ath10k *ar, 1227 return 0;
1155 struct ath10k_vif *arvif,
1156 struct ieee80211_sta *sta,
1157 struct ieee80211_bss_conf *bss_conf,
1158 struct wmi_peer_assoc_complete_arg *arg)
1159{
1160 if (bss_conf->qos)
1161 arg->peer_flags |= WMI_PEER_QOS;
1162} 1228}
1163 1229
1164static void ath10k_peer_assoc_h_vht(struct ath10k *ar, 1230static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
@@ -1211,10 +1277,17 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
1211{ 1277{
1212 switch (arvif->vdev_type) { 1278 switch (arvif->vdev_type) {
1213 case WMI_VDEV_TYPE_AP: 1279 case WMI_VDEV_TYPE_AP:
1214 ath10k_peer_assoc_h_qos_ap(ar, arvif, sta, bss_conf, arg); 1280 if (sta->wme)
1281 arg->peer_flags |= WMI_PEER_QOS;
1282
1283 if (sta->wme && sta->uapsd_queues) {
1284 arg->peer_flags |= WMI_PEER_APSD;
1285 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
1286 }
1215 break; 1287 break;
1216 case WMI_VDEV_TYPE_STA: 1288 case WMI_VDEV_TYPE_STA:
1217 ath10k_peer_assoc_h_qos_sta(ar, arvif, sta, bss_conf, arg); 1289 if (bss_conf->qos)
1290 arg->peer_flags |= WMI_PEER_QOS;
1218 break; 1291 break;
1219 default: 1292 default:
1220 break; 1293 break;
@@ -1293,6 +1366,33 @@ static int ath10k_peer_assoc_prepare(struct ath10k *ar,
1293 return 0; 1366 return 0;
1294} 1367}
1295 1368
1369static const u32 ath10k_smps_map[] = {
1370 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
1371 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
1372 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
1373 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
1374};
1375
1376static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
1377 const u8 *addr,
1378 const struct ieee80211_sta_ht_cap *ht_cap)
1379{
1380 int smps;
1381
1382 if (!ht_cap->ht_supported)
1383 return 0;
1384
1385 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
1386 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
1387
1388 if (smps >= ARRAY_SIZE(ath10k_smps_map))
1389 return -EINVAL;
1390
1391 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
1392 WMI_PEER_SMPS_STATE,
1393 ath10k_smps_map[smps]);
1394}
1395
1296/* can be called only in mac80211 callbacks due to `key_count` usage */ 1396/* can be called only in mac80211 callbacks due to `key_count` usage */
1297static void ath10k_bss_assoc(struct ieee80211_hw *hw, 1397static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1298 struct ieee80211_vif *vif, 1398 struct ieee80211_vif *vif,
@@ -1300,6 +1400,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1300{ 1400{
1301 struct ath10k *ar = hw->priv; 1401 struct ath10k *ar = hw->priv;
1302 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 1402 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1403 struct ieee80211_sta_ht_cap ht_cap;
1303 struct wmi_peer_assoc_complete_arg peer_arg; 1404 struct wmi_peer_assoc_complete_arg peer_arg;
1304 struct ieee80211_sta *ap_sta; 1405 struct ieee80211_sta *ap_sta;
1305 int ret; 1406 int ret;
@@ -1316,6 +1417,10 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1316 return; 1417 return;
1317 } 1418 }
1318 1419
1420 /* ap_sta must be accessed only within rcu section which must be left
1421 * before calling ath10k_setup_peer_smps() which might sleep. */
1422 ht_cap = ap_sta->ht_cap;
1423
1319 ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta, 1424 ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta,
1320 bss_conf, &peer_arg); 1425 bss_conf, &peer_arg);
1321 if (ret) { 1426 if (ret) {
@@ -1334,15 +1439,27 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1334 return; 1439 return;
1335 } 1440 }
1336 1441
1442 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
1443 if (ret) {
1444 ath10k_warn("failed to setup peer SMPS: %d\n", ret);
1445 return;
1446 }
1447
1337 ath10k_dbg(ATH10K_DBG_MAC, 1448 ath10k_dbg(ATH10K_DBG_MAC,
1338 "mac vdev %d up (associated) bssid %pM aid %d\n", 1449 "mac vdev %d up (associated) bssid %pM aid %d\n",
1339 arvif->vdev_id, bss_conf->bssid, bss_conf->aid); 1450 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
1340 1451
1341 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, bss_conf->aid, 1452 arvif->aid = bss_conf->aid;
1342 bss_conf->bssid); 1453 memcpy(arvif->bssid, bss_conf->bssid, ETH_ALEN);
1343 if (ret) 1454
1455 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
1456 if (ret) {
1344 ath10k_warn("VDEV: %d up failed: ret %d\n", 1457 ath10k_warn("VDEV: %d up failed: ret %d\n",
1345 arvif->vdev_id, ret); 1458 arvif->vdev_id, ret);
1459 return;
1460 }
1461
1462 arvif->is_up = true;
1346} 1463}
1347 1464
1348/* 1465/*
@@ -1382,6 +1499,9 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1382 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); 1499 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1383 1500
1384 arvif->def_wep_key_idx = 0; 1501 arvif->def_wep_key_idx = 0;
1502
1503 arvif->is_started = false;
1504 arvif->is_up = false;
1385} 1505}
1386 1506
1387static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, 1507static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
@@ -1406,12 +1526,25 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
1406 return ret; 1526 return ret;
1407 } 1527 }
1408 1528
1529 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, &sta->ht_cap);
1530 if (ret) {
1531 ath10k_warn("failed to setup peer SMPS: %d\n", ret);
1532 return ret;
1533 }
1534
1409 ret = ath10k_install_peer_wep_keys(arvif, sta->addr); 1535 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
1410 if (ret) { 1536 if (ret) {
1411 ath10k_warn("could not install peer wep keys (%d)\n", ret); 1537 ath10k_warn("could not install peer wep keys (%d)\n", ret);
1412 return ret; 1538 return ret;
1413 } 1539 }
1414 1540
1541 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
1542 if (ret) {
1543 ath10k_warn("could not set qos params for STA %pM, %d\n",
1544 sta->addr, ret);
1545 return ret;
1546 }
1547
1415 return ret; 1548 return ret;
1416} 1549}
1417 1550
@@ -1547,9 +1680,9 @@ static void ath10k_regd_update(struct ath10k *ar)
1547 /* Target allows setting up per-band regdomain but ath_common provides 1680 /* Target allows setting up per-band regdomain but ath_common provides
1548 * a combined one only */ 1681 * a combined one only */
1549 ret = ath10k_wmi_pdev_set_regdomain(ar, 1682 ret = ath10k_wmi_pdev_set_regdomain(ar,
1550 regpair->regDmnEnum, 1683 regpair->reg_domain,
1551 regpair->regDmnEnum, /* 2ghz */ 1684 regpair->reg_domain, /* 2ghz */
1552 regpair->regDmnEnum, /* 5ghz */ 1685 regpair->reg_domain, /* 5ghz */
1553 regpair->reg_2ghz_ctl, 1686 regpair->reg_2ghz_ctl,
1554 regpair->reg_5ghz_ctl); 1687 regpair->reg_5ghz_ctl);
1555 if (ret) 1688 if (ret)
@@ -2100,11 +2233,29 @@ static int ath10k_start(struct ieee80211_hw *hw)
2100 ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n", 2233 ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n",
2101 ret); 2234 ret);
2102 2235
2236 /*
2237 * By default FW set ARP frames ac to voice (6). In that case ARP
2238 * exchange is not working properly for UAPSD enabled AP. ARP requests
2239 * which arrives with access category 0 are processed by network stack
2240 * and send back with access category 0, but FW changes access category
2241 * to 6. Set ARP frames access category to best effort (0) solves
2242 * this problem.
2243 */
2244
2245 ret = ath10k_wmi_pdev_set_param(ar,
2246 ar->wmi.pdev_param->arp_ac_override, 0);
2247 if (ret) {
2248 ath10k_warn("could not set arp ac override parameter: %d\n",
2249 ret);
2250 goto exit;
2251 }
2252
2103 ath10k_regd_update(ar); 2253 ath10k_regd_update(ar);
2254 ret = 0;
2104 2255
2105exit: 2256exit:
2106 mutex_unlock(&ar->conf_mutex); 2257 mutex_unlock(&ar->conf_mutex);
2107 return 0; 2258 return ret;
2108} 2259}
2109 2260
2110static void ath10k_stop(struct ieee80211_hw *hw) 2261static void ath10k_stop(struct ieee80211_hw *hw)
@@ -2145,6 +2296,98 @@ static int ath10k_config_ps(struct ath10k *ar)
2145 return ret; 2296 return ret;
2146} 2297}
2147 2298
2299static const char *chandef_get_width(enum nl80211_chan_width width)
2300{
2301 switch (width) {
2302 case NL80211_CHAN_WIDTH_20_NOHT:
2303 return "20 (noht)";
2304 case NL80211_CHAN_WIDTH_20:
2305 return "20";
2306 case NL80211_CHAN_WIDTH_40:
2307 return "40";
2308 case NL80211_CHAN_WIDTH_80:
2309 return "80";
2310 case NL80211_CHAN_WIDTH_80P80:
2311 return "80+80";
2312 case NL80211_CHAN_WIDTH_160:
2313 return "160";
2314 case NL80211_CHAN_WIDTH_5:
2315 return "5";
2316 case NL80211_CHAN_WIDTH_10:
2317 return "10";
2318 }
2319 return "?";
2320}
2321
2322static void ath10k_config_chan(struct ath10k *ar)
2323{
2324 struct ath10k_vif *arvif;
2325 bool monitor_was_enabled;
2326 int ret;
2327
2328 lockdep_assert_held(&ar->conf_mutex);
2329
2330 ath10k_dbg(ATH10K_DBG_MAC,
2331 "mac config channel to %dMHz (cf1 %dMHz cf2 %dMHz width %s)\n",
2332 ar->chandef.chan->center_freq,
2333 ar->chandef.center_freq1,
2334 ar->chandef.center_freq2,
2335 chandef_get_width(ar->chandef.width));
2336
2337 /* First stop monitor interface. Some FW versions crash if there's a
2338 * lone monitor interface. */
2339 monitor_was_enabled = ar->monitor_enabled;
2340
2341 if (ar->monitor_enabled)
2342 ath10k_monitor_stop(ar);
2343
2344 list_for_each_entry(arvif, &ar->arvifs, list) {
2345 if (!arvif->is_started)
2346 continue;
2347
2348 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
2349 continue;
2350
2351 ret = ath10k_vdev_stop(arvif);
2352 if (ret) {
2353 ath10k_warn("could not stop vdev %d (%d)\n",
2354 arvif->vdev_id, ret);
2355 continue;
2356 }
2357 }
2358
2359 /* all vdevs are now stopped - now attempt to restart them */
2360
2361 list_for_each_entry(arvif, &ar->arvifs, list) {
2362 if (!arvif->is_started)
2363 continue;
2364
2365 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
2366 continue;
2367
2368 ret = ath10k_vdev_start(arvif);
2369 if (ret) {
2370 ath10k_warn("could not start vdev %d (%d)\n",
2371 arvif->vdev_id, ret);
2372 continue;
2373 }
2374
2375 if (!arvif->is_up)
2376 continue;
2377
2378 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
2379 arvif->bssid);
2380 if (ret) {
2381 ath10k_warn("could not bring vdev up %d (%d)\n",
2382 arvif->vdev_id, ret);
2383 continue;
2384 }
2385 }
2386
2387 if (monitor_was_enabled)
2388 ath10k_monitor_start(ar, ar->monitor_vdev_id);
2389}
2390
2148static int ath10k_config(struct ieee80211_hw *hw, u32 changed) 2391static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
2149{ 2392{
2150 struct ath10k *ar = hw->priv; 2393 struct ath10k *ar = hw->priv;
@@ -2165,6 +2408,11 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
2165 spin_unlock_bh(&ar->data_lock); 2408 spin_unlock_bh(&ar->data_lock);
2166 2409
2167 ath10k_config_radar_detection(ar); 2410 ath10k_config_radar_detection(ar);
2411
2412 if (!cfg80211_chandef_identical(&ar->chandef, &conf->chandef)) {
2413 ar->chandef = conf->chandef;
2414 ath10k_config_chan(ar);
2415 }
2168 } 2416 }
2169 2417
2170 if (changed & IEEE80211_CONF_CHANGE_POWER) { 2418 if (changed & IEEE80211_CONF_CHANGE_POWER) {
@@ -2214,7 +2462,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2214 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 2462 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2215 enum wmi_sta_powersave_param param; 2463 enum wmi_sta_powersave_param param;
2216 int ret = 0; 2464 int ret = 0;
2217 u32 value, param_id; 2465 u32 value;
2218 int bit; 2466 int bit;
2219 u32 vdev_param; 2467 u32 vdev_param;
2220 2468
@@ -2307,12 +2555,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2307 goto err_vdev_delete; 2555 goto err_vdev_delete;
2308 } 2556 }
2309 2557
2310 param_id = ar->wmi.pdev_param->sta_kickout_th; 2558 ret = ath10k_mac_set_kickout(arvif);
2311 2559 if (ret) {
2312 /* Disable STA KICKOUT functionality in FW */ 2560 ath10k_warn("Failed to set kickout parameters: %d\n",
2313 ret = ath10k_wmi_pdev_set_param(ar, param_id, 0); 2561 ret);
2314 if (ret) 2562 goto err_peer_delete;
2315 ath10k_warn("Failed to disable STA KICKOUT\n"); 2563 }
2316 } 2564 }
2317 2565
2318 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { 2566 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
@@ -2559,15 +2807,20 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
2559 * this is never erased as we it for crypto key 2807 * this is never erased as we it for crypto key
2560 * clearing; this is FW requirement 2808 * clearing; this is FW requirement
2561 */ 2809 */
2562 memcpy(arvif->u.sta.bssid, info->bssid, 2810 memcpy(arvif->bssid, info->bssid, ETH_ALEN);
2563 ETH_ALEN);
2564 2811
2565 ath10k_dbg(ATH10K_DBG_MAC, 2812 ath10k_dbg(ATH10K_DBG_MAC,
2566 "mac vdev %d start %pM\n", 2813 "mac vdev %d start %pM\n",
2567 arvif->vdev_id, info->bssid); 2814 arvif->vdev_id, info->bssid);
2568 2815
2569 /* FIXME: check return value */
2570 ret = ath10k_vdev_start(arvif); 2816 ret = ath10k_vdev_start(arvif);
2817 if (ret) {
2818 ath10k_warn("failed to start vdev: %d\n",
2819 ret);
2820 goto exit;
2821 }
2822
2823 arvif->is_started = true;
2571 } 2824 }
2572 2825
2573 /* 2826 /*
@@ -2576,7 +2829,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
2576 * IBSS in order to remove BSSID peer. 2829 * IBSS in order to remove BSSID peer.
2577 */ 2830 */
2578 if (vif->type == NL80211_IFTYPE_ADHOC) 2831 if (vif->type == NL80211_IFTYPE_ADHOC)
2579 memcpy(arvif->u.ibss.bssid, info->bssid, 2832 memcpy(arvif->bssid, info->bssid,
2580 ETH_ALEN); 2833 ETH_ALEN);
2581 } 2834 }
2582 } 2835 }
@@ -2645,6 +2898,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
2645 ath10k_bss_assoc(hw, vif, info); 2898 ath10k_bss_assoc(hw, vif, info);
2646 } 2899 }
2647 2900
2901exit:
2648 mutex_unlock(&ar->conf_mutex); 2902 mutex_unlock(&ar->conf_mutex);
2649} 2903}
2650 2904
@@ -2850,6 +3104,69 @@ exit:
2850 return ret; 3104 return ret;
2851} 3105}
2852 3106
3107static void ath10k_sta_rc_update_wk(struct work_struct *wk)
3108{
3109 struct ath10k *ar;
3110 struct ath10k_vif *arvif;
3111 struct ath10k_sta *arsta;
3112 struct ieee80211_sta *sta;
3113 u32 changed, bw, nss, smps;
3114 int err;
3115
3116 arsta = container_of(wk, struct ath10k_sta, update_wk);
3117 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
3118 arvif = arsta->arvif;
3119 ar = arvif->ar;
3120
3121 spin_lock_bh(&ar->data_lock);
3122
3123 changed = arsta->changed;
3124 arsta->changed = 0;
3125
3126 bw = arsta->bw;
3127 nss = arsta->nss;
3128 smps = arsta->smps;
3129
3130 spin_unlock_bh(&ar->data_lock);
3131
3132 mutex_lock(&ar->conf_mutex);
3133
3134 if (changed & IEEE80211_RC_BW_CHANGED) {
3135 ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
3136 sta->addr, bw);
3137
3138 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
3139 WMI_PEER_CHAN_WIDTH, bw);
3140 if (err)
3141 ath10k_warn("failed to update STA %pM peer bw %d: %d\n",
3142 sta->addr, bw, err);
3143 }
3144
3145 if (changed & IEEE80211_RC_NSS_CHANGED) {
3146 ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
3147 sta->addr, nss);
3148
3149 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
3150 WMI_PEER_NSS, nss);
3151 if (err)
3152 ath10k_warn("failed to update STA %pM nss %d: %d\n",
3153 sta->addr, nss, err);
3154 }
3155
3156 if (changed & IEEE80211_RC_SMPS_CHANGED) {
3157 ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
3158 sta->addr, smps);
3159
3160 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
3161 WMI_PEER_SMPS_STATE, smps);
3162 if (err)
3163 ath10k_warn("failed to update STA %pM smps %d: %d\n",
3164 sta->addr, smps, err);
3165 }
3166
3167 mutex_unlock(&ar->conf_mutex);
3168}
3169
2853static int ath10k_sta_state(struct ieee80211_hw *hw, 3170static int ath10k_sta_state(struct ieee80211_hw *hw,
2854 struct ieee80211_vif *vif, 3171 struct ieee80211_vif *vif,
2855 struct ieee80211_sta *sta, 3172 struct ieee80211_sta *sta,
@@ -2858,9 +3175,15 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
2858{ 3175{
2859 struct ath10k *ar = hw->priv; 3176 struct ath10k *ar = hw->priv;
2860 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 3177 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3178 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
2861 int max_num_peers; 3179 int max_num_peers;
2862 int ret = 0; 3180 int ret = 0;
2863 3181
3182 /* cancel must be done outside the mutex to avoid deadlock */
3183 if ((old_state == IEEE80211_STA_NONE &&
3184 new_state == IEEE80211_STA_NOTEXIST))
3185 cancel_work_sync(&arsta->update_wk);
3186
2864 mutex_lock(&ar->conf_mutex); 3187 mutex_lock(&ar->conf_mutex);
2865 3188
2866 if (old_state == IEEE80211_STA_NOTEXIST && 3189 if (old_state == IEEE80211_STA_NOTEXIST &&
@@ -2885,6 +3208,10 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
2885 "mac vdev %d peer create %pM (new sta) num_peers %d\n", 3208 "mac vdev %d peer create %pM (new sta) num_peers %d\n",
2886 arvif->vdev_id, sta->addr, ar->num_peers); 3209 arvif->vdev_id, sta->addr, ar->num_peers);
2887 3210
3211 memset(arsta, 0, sizeof(*arsta));
3212 arsta->arvif = arvif;
3213 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
3214
2888 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); 3215 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
2889 if (ret) 3216 if (ret)
2890 ath10k_warn("Failed to add peer %pM for vdev %d when adding a new sta: %i\n", 3217 ath10k_warn("Failed to add peer %pM for vdev %d when adding a new sta: %i\n",
@@ -3234,23 +3561,14 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
3234 struct ath10k *ar = hw->priv; 3561 struct ath10k *ar = hw->priv;
3235 int ret; 3562 int ret;
3236 3563
3237 ar->is_target_paused = false; 3564 mutex_lock(&ar->conf_mutex);
3238 3565
3239 ret = ath10k_wmi_pdev_suspend_target(ar); 3566 ret = ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND);
3240 if (ret) { 3567 if (ret) {
3241 ath10k_warn("could not suspend target (%d)\n", ret); 3568 if (ret == -ETIMEDOUT)
3242 return 1; 3569 goto resume;
3243 } 3570 ret = 1;
3244 3571 goto exit;
3245 ret = wait_event_interruptible_timeout(ar->event_queue,
3246 ar->is_target_paused == true,
3247 1 * HZ);
3248 if (ret < 0) {
3249 ath10k_warn("suspend interrupted (%d)\n", ret);
3250 goto resume;
3251 } else if (ret == 0) {
3252 ath10k_warn("suspend timed out - target pause event never came\n");
3253 goto resume;
3254 } 3572 }
3255 3573
3256 ret = ath10k_hif_suspend(ar); 3574 ret = ath10k_hif_suspend(ar);
@@ -3259,12 +3577,17 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
3259 goto resume; 3577 goto resume;
3260 } 3578 }
3261 3579
3262 return 0; 3580 ret = 0;
3581 goto exit;
3263resume: 3582resume:
3264 ret = ath10k_wmi_pdev_resume_target(ar); 3583 ret = ath10k_wmi_pdev_resume_target(ar);
3265 if (ret) 3584 if (ret)
3266 ath10k_warn("could not resume target (%d)\n", ret); 3585 ath10k_warn("could not resume target (%d)\n", ret);
3267 return 1; 3586
3587 ret = 1;
3588exit:
3589 mutex_unlock(&ar->conf_mutex);
3590 return ret;
3268} 3591}
3269 3592
3270static int ath10k_resume(struct ieee80211_hw *hw) 3593static int ath10k_resume(struct ieee80211_hw *hw)
@@ -3272,19 +3595,26 @@ static int ath10k_resume(struct ieee80211_hw *hw)
3272 struct ath10k *ar = hw->priv; 3595 struct ath10k *ar = hw->priv;
3273 int ret; 3596 int ret;
3274 3597
3598 mutex_lock(&ar->conf_mutex);
3599
3275 ret = ath10k_hif_resume(ar); 3600 ret = ath10k_hif_resume(ar);
3276 if (ret) { 3601 if (ret) {
3277 ath10k_warn("could not resume hif (%d)\n", ret); 3602 ath10k_warn("could not resume hif (%d)\n", ret);
3278 return 1; 3603 ret = 1;
3604 goto exit;
3279 } 3605 }
3280 3606
3281 ret = ath10k_wmi_pdev_resume_target(ar); 3607 ret = ath10k_wmi_pdev_resume_target(ar);
3282 if (ret) { 3608 if (ret) {
3283 ath10k_warn("could not resume target (%d)\n", ret); 3609 ath10k_warn("could not resume target (%d)\n", ret);
3284 return 1; 3610 ret = 1;
3611 goto exit;
3285 } 3612 }
3286 3613
3287 return 0; 3614 ret = 0;
3615exit:
3616 mutex_unlock(&ar->conf_mutex);
3617 return ret;
3288} 3618}
3289#endif 3619#endif
3290 3620
@@ -3640,6 +3970,96 @@ static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw,
3640 return ath10k_set_fixed_rate_param(arvif, fixed_rate, fixed_nss); 3970 return ath10k_set_fixed_rate_param(arvif, fixed_rate, fixed_nss);
3641} 3971}
3642 3972
3973static void ath10k_channel_switch_beacon(struct ieee80211_hw *hw,
3974 struct ieee80211_vif *vif,
3975 struct cfg80211_chan_def *chandef)
3976{
3977 /* there's no need to do anything here. vif->csa_active is enough */
3978 return;
3979}
3980
3981static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
3982 struct ieee80211_vif *vif,
3983 struct ieee80211_sta *sta,
3984 u32 changed)
3985{
3986 struct ath10k *ar = hw->priv;
3987 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
3988 u32 bw, smps;
3989
3990 spin_lock_bh(&ar->data_lock);
3991
3992 ath10k_dbg(ATH10K_DBG_MAC,
3993 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
3994 sta->addr, changed, sta->bandwidth, sta->rx_nss,
3995 sta->smps_mode);
3996
3997 if (changed & IEEE80211_RC_BW_CHANGED) {
3998 bw = WMI_PEER_CHWIDTH_20MHZ;
3999
4000 switch (sta->bandwidth) {
4001 case IEEE80211_STA_RX_BW_20:
4002 bw = WMI_PEER_CHWIDTH_20MHZ;
4003 break;
4004 case IEEE80211_STA_RX_BW_40:
4005 bw = WMI_PEER_CHWIDTH_40MHZ;
4006 break;
4007 case IEEE80211_STA_RX_BW_80:
4008 bw = WMI_PEER_CHWIDTH_80MHZ;
4009 break;
4010 case IEEE80211_STA_RX_BW_160:
4011 ath10k_warn("mac sta rc update for %pM: invalid bw %d\n",
4012 sta->addr, sta->bandwidth);
4013 bw = WMI_PEER_CHWIDTH_20MHZ;
4014 break;
4015 }
4016
4017 arsta->bw = bw;
4018 }
4019
4020 if (changed & IEEE80211_RC_NSS_CHANGED)
4021 arsta->nss = sta->rx_nss;
4022
4023 if (changed & IEEE80211_RC_SMPS_CHANGED) {
4024 smps = WMI_PEER_SMPS_PS_NONE;
4025
4026 switch (sta->smps_mode) {
4027 case IEEE80211_SMPS_AUTOMATIC:
4028 case IEEE80211_SMPS_OFF:
4029 smps = WMI_PEER_SMPS_PS_NONE;
4030 break;
4031 case IEEE80211_SMPS_STATIC:
4032 smps = WMI_PEER_SMPS_STATIC;
4033 break;
4034 case IEEE80211_SMPS_DYNAMIC:
4035 smps = WMI_PEER_SMPS_DYNAMIC;
4036 break;
4037 case IEEE80211_SMPS_NUM_MODES:
4038 ath10k_warn("mac sta rc update for %pM: invalid smps: %d\n",
4039 sta->addr, sta->smps_mode);
4040 smps = WMI_PEER_SMPS_PS_NONE;
4041 break;
4042 }
4043
4044 arsta->smps = smps;
4045 }
4046
4047 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
4048 /* FIXME: Not implemented. Probably the only way to do it would
4049 * be to re-assoc the peer. */
4050 changed &= ~IEEE80211_RC_SUPP_RATES_CHANGED;
4051 ath10k_dbg(ATH10K_DBG_MAC,
4052 "mac sta rc update for %pM: changing supported rates not implemented\n",
4053 sta->addr);
4054 }
4055
4056 arsta->changed |= changed;
4057
4058 spin_unlock_bh(&ar->data_lock);
4059
4060 ieee80211_queue_work(hw, &arsta->update_wk);
4061}
4062
3643static const struct ieee80211_ops ath10k_ops = { 4063static const struct ieee80211_ops ath10k_ops = {
3644 .tx = ath10k_tx, 4064 .tx = ath10k_tx,
3645 .start = ath10k_start, 4065 .start = ath10k_start,
@@ -3663,6 +4083,8 @@ static const struct ieee80211_ops ath10k_ops = {
3663 .restart_complete = ath10k_restart_complete, 4083 .restart_complete = ath10k_restart_complete,
3664 .get_survey = ath10k_get_survey, 4084 .get_survey = ath10k_get_survey,
3665 .set_bitrate_mask = ath10k_set_bitrate_mask, 4085 .set_bitrate_mask = ath10k_set_bitrate_mask,
4086 .channel_switch_beacon = ath10k_channel_switch_beacon,
4087 .sta_rc_update = ath10k_sta_rc_update,
3666#ifdef CONFIG_PM 4088#ifdef CONFIG_PM
3667 .suspend = ath10k_suspend, 4089 .suspend = ath10k_suspend,
3668 .resume = ath10k_resume, 4090 .resume = ath10k_resume,
@@ -4038,10 +4460,12 @@ int ath10k_mac_register(struct ath10k *ar)
4038 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN; 4460 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
4039 4461
4040 ar->hw->vif_data_size = sizeof(struct ath10k_vif); 4462 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
4463 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
4041 4464
4042 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL; 4465 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
4043 4466
4044 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 4467 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4468 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
4045 ar->hw->wiphy->max_remain_on_channel_duration = 5000; 4469 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
4046 4470
4047 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 4471 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 29fd197d1fd8..34f09106f423 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -64,7 +64,8 @@ static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
64 int num); 64 int num);
65static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info); 65static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info);
66static void ath10k_pci_stop_ce(struct ath10k *ar); 66static void ath10k_pci_stop_ce(struct ath10k *ar);
67static int ath10k_pci_device_reset(struct ath10k *ar); 67static int ath10k_pci_cold_reset(struct ath10k *ar);
68static int ath10k_pci_warm_reset(struct ath10k *ar);
68static int ath10k_pci_wait_for_target_init(struct ath10k *ar); 69static int ath10k_pci_wait_for_target_init(struct ath10k *ar);
69static int ath10k_pci_init_irq(struct ath10k *ar); 70static int ath10k_pci_init_irq(struct ath10k *ar);
70static int ath10k_pci_deinit_irq(struct ath10k *ar); 71static int ath10k_pci_deinit_irq(struct ath10k *ar);
@@ -833,9 +834,7 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
833 ath10k_err("firmware crashed!\n"); 834 ath10k_err("firmware crashed!\n");
834 ath10k_err("hardware name %s version 0x%x\n", 835 ath10k_err("hardware name %s version 0x%x\n",
835 ar->hw_params.name, ar->target_version); 836 ar->hw_params.name, ar->target_version);
836 ath10k_err("firmware version: %u.%u.%u.%u\n", ar->fw_version_major, 837 ath10k_err("firmware version: %s\n", ar->hw->wiphy->fw_version);
837 ar->fw_version_minor, ar->fw_version_release,
838 ar->fw_version_build);
839 838
840 host_addr = host_interest_item_address(HI_ITEM(hi_failure_state)); 839 host_addr = host_interest_item_address(HI_ITEM(hi_failure_state));
841 ret = ath10k_pci_diag_read_mem(ar, host_addr, 840 ret = ath10k_pci_diag_read_mem(ar, host_addr,
@@ -1502,7 +1501,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
1502 * configuration during init. If ringbuffers are freed and the device 1501 * configuration during init. If ringbuffers are freed and the device
1503 * were to access them this could lead to memory corruption on the 1502 * were to access them this could lead to memory corruption on the
1504 * host. */ 1503 * host. */
1505 ath10k_pci_device_reset(ar); 1504 ath10k_pci_warm_reset(ar);
1506 1505
1507 ar_pci->started = 0; 1506 ar_pci->started = 0;
1508} 1507}
@@ -1993,7 +1992,94 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
1993 ath10k_pci_sleep(ar); 1992 ath10k_pci_sleep(ar);
1994} 1993}
1995 1994
1996static int ath10k_pci_hif_power_up(struct ath10k *ar) 1995static int ath10k_pci_warm_reset(struct ath10k *ar)
1996{
1997 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1998 int ret = 0;
1999 u32 val;
2000
2001 ath10k_dbg(ATH10K_DBG_BOOT, "boot performing warm chip reset\n");
2002
2003 ret = ath10k_do_pci_wake(ar);
2004 if (ret) {
2005 ath10k_err("failed to wake up target: %d\n", ret);
2006 return ret;
2007 }
2008
2009 /* debug */
2010 val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
2011 PCIE_INTR_CAUSE_ADDRESS);
2012 ath10k_dbg(ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", val);
2013
2014 val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
2015 CPU_INTR_ADDRESS);
2016 ath10k_dbg(ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n",
2017 val);
2018
2019 /* disable pending irqs */
2020 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
2021 PCIE_INTR_ENABLE_ADDRESS, 0);
2022
2023 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
2024 PCIE_INTR_CLR_ADDRESS, ~0);
2025
2026 msleep(100);
2027
2028 /* clear fw indicator */
2029 ath10k_pci_write32(ar, ar_pci->fw_indicator_address, 0);
2030
2031 /* clear target LF timer interrupts */
2032 val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
2033 SOC_LF_TIMER_CONTROL0_ADDRESS);
2034 ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS +
2035 SOC_LF_TIMER_CONTROL0_ADDRESS,
2036 val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK);
2037
2038 /* reset CE */
2039 val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
2040 SOC_RESET_CONTROL_ADDRESS);
2041 ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS,
2042 val | SOC_RESET_CONTROL_CE_RST_MASK);
2043 val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
2044 SOC_RESET_CONTROL_ADDRESS);
2045 msleep(10);
2046
2047 /* unreset CE */
2048 ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS,
2049 val & ~SOC_RESET_CONTROL_CE_RST_MASK);
2050 val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
2051 SOC_RESET_CONTROL_ADDRESS);
2052 msleep(10);
2053
2054 /* debug */
2055 val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
2056 PCIE_INTR_CAUSE_ADDRESS);
2057 ath10k_dbg(ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", val);
2058
2059 val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
2060 CPU_INTR_ADDRESS);
2061 ath10k_dbg(ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n",
2062 val);
2063
2064 /* CPU warm reset */
2065 val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
2066 SOC_RESET_CONTROL_ADDRESS);
2067 ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS,
2068 val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK);
2069
2070 val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
2071 SOC_RESET_CONTROL_ADDRESS);
2072 ath10k_dbg(ATH10K_DBG_BOOT, "boot target reset state: 0x%08x\n", val);
2073
2074 msleep(100);
2075
2076 ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset complete\n");
2077
2078 ath10k_do_pci_sleep(ar);
2079 return ret;
2080}
2081
2082static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset)
1997{ 2083{
1998 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2084 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1999 const char *irq_mode; 2085 const char *irq_mode;
@@ -2009,7 +2095,11 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
2009 * is in an unexpected state. We try to catch that here in order to 2095 * is in an unexpected state. We try to catch that here in order to
2010 * reset the Target and retry the probe. 2096 * reset the Target and retry the probe.
2011 */ 2097 */
2012 ret = ath10k_pci_device_reset(ar); 2098 if (cold_reset)
2099 ret = ath10k_pci_cold_reset(ar);
2100 else
2101 ret = ath10k_pci_warm_reset(ar);
2102
2013 if (ret) { 2103 if (ret) {
2014 ath10k_err("failed to reset target: %d\n", ret); 2104 ath10k_err("failed to reset target: %d\n", ret);
2015 goto err; 2105 goto err;
@@ -2079,7 +2169,7 @@ err_deinit_irq:
2079 ath10k_pci_deinit_irq(ar); 2169 ath10k_pci_deinit_irq(ar);
2080err_ce: 2170err_ce:
2081 ath10k_pci_ce_deinit(ar); 2171 ath10k_pci_ce_deinit(ar);
2082 ath10k_pci_device_reset(ar); 2172 ath10k_pci_warm_reset(ar);
2083err_ps: 2173err_ps:
2084 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) 2174 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
2085 ath10k_do_pci_sleep(ar); 2175 ath10k_do_pci_sleep(ar);
@@ -2087,6 +2177,34 @@ err:
2087 return ret; 2177 return ret;
2088} 2178}
2089 2179
2180static int ath10k_pci_hif_power_up(struct ath10k *ar)
2181{
2182 int ret;
2183
2184 /*
2185 * Hardware CUS232 version 2 has some issues with cold reset and the
2186 * preferred (and safer) way to perform a device reset is through a
2187 * warm reset.
2188 *
2189 * Warm reset doesn't always work though (notably after a firmware
2190 * crash) so fall back to cold reset if necessary.
2191 */
2192 ret = __ath10k_pci_hif_power_up(ar, false);
2193 if (ret) {
2194 ath10k_warn("failed to power up target using warm reset (%d), trying cold reset\n",
2195 ret);
2196
2197 ret = __ath10k_pci_hif_power_up(ar, true);
2198 if (ret) {
2199 ath10k_err("failed to power up target using cold reset too (%d)\n",
2200 ret);
2201 return ret;
2202 }
2203 }
2204
2205 return 0;
2206}
2207
2090static void ath10k_pci_hif_power_down(struct ath10k *ar) 2208static void ath10k_pci_hif_power_down(struct ath10k *ar)
2091{ 2209{
2092 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2210 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
@@ -2094,7 +2212,7 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar)
2094 ath10k_pci_free_early_irq(ar); 2212 ath10k_pci_free_early_irq(ar);
2095 ath10k_pci_kill_tasklet(ar); 2213 ath10k_pci_kill_tasklet(ar);
2096 ath10k_pci_deinit_irq(ar); 2214 ath10k_pci_deinit_irq(ar);
2097 ath10k_pci_device_reset(ar); 2215 ath10k_pci_warm_reset(ar);
2098 2216
2099 ath10k_pci_ce_deinit(ar); 2217 ath10k_pci_ce_deinit(ar);
2100 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) 2218 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
@@ -2411,11 +2529,10 @@ static int ath10k_pci_init_irq(struct ath10k *ar)
2411 /* Try MSI-X */ 2529 /* Try MSI-X */
2412 if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO && msix_supported) { 2530 if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO && msix_supported) {
2413 ar_pci->num_msi_intrs = MSI_NUM_REQUEST; 2531 ar_pci->num_msi_intrs = MSI_NUM_REQUEST;
2414 ret = pci_enable_msi_block(ar_pci->pdev, ar_pci->num_msi_intrs); 2532 ret = pci_enable_msi_range(ar_pci->pdev, ar_pci->num_msi_intrs,
2415 if (ret == 0) 2533 ar_pci->num_msi_intrs);
2416 return 0;
2417 if (ret > 0) 2534 if (ret > 0)
2418 pci_disable_msi(ar_pci->pdev); 2535 return 0;
2419 2536
2420 /* fall-through */ 2537 /* fall-through */
2421 } 2538 }
@@ -2482,6 +2599,8 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar)
2482 case MSI_NUM_REQUEST: 2599 case MSI_NUM_REQUEST:
2483 pci_disable_msi(ar_pci->pdev); 2600 pci_disable_msi(ar_pci->pdev);
2484 return 0; 2601 return 0;
2602 default:
2603 pci_disable_msi(ar_pci->pdev);
2485 } 2604 }
2486 2605
2487 ath10k_warn("unknown irq configuration upon deinit\n"); 2606 ath10k_warn("unknown irq configuration upon deinit\n");
@@ -2523,7 +2642,7 @@ out:
2523 return ret; 2642 return ret;
2524} 2643}
2525 2644
2526static int ath10k_pci_device_reset(struct ath10k *ar) 2645static int ath10k_pci_cold_reset(struct ath10k *ar)
2527{ 2646{
2528 int i, ret; 2647 int i, ret;
2529 u32 val; 2648 u32 val;
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 27f20e0510f7..ec6f82521b0e 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -259,7 +259,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
259 status->freq = ch->center_freq; 259 status->freq = ch->center_freq;
260 260
261 ath10k_dbg(ATH10K_DBG_DATA, 261 ath10k_dbg(ATH10K_DBG_DATA,
262 "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u\n", 262 "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i\n",
263 info->skb, 263 info->skb,
264 info->skb->len, 264 info->skb->len,
265 status->flag == 0 ? "legacy" : "", 265 status->flag == 0 ? "legacy" : "",
@@ -271,7 +271,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
271 status->rate_idx, 271 status->rate_idx,
272 status->vht_nss, 272 status->vht_nss,
273 status->freq, 273 status->freq,
274 status->band); 274 status->band, status->flag, info->fcs_err);
275 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ", 275 ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
276 info->skb->data, info->skb->len); 276 info->skb->data, info->skb->len);
277 277
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 712a606a080a..91e501b5499e 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -213,7 +213,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
213 .p2p_go_set_beacon_ie = WMI_10X_P2P_GO_SET_BEACON_IE, 213 .p2p_go_set_beacon_ie = WMI_10X_P2P_GO_SET_BEACON_IE,
214 .p2p_go_set_probe_resp_ie = WMI_10X_P2P_GO_SET_PROBE_RESP_IE, 214 .p2p_go_set_probe_resp_ie = WMI_10X_P2P_GO_SET_PROBE_RESP_IE,
215 .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, 215 .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED,
216 .ap_ps_peer_param_cmdid = WMI_CMD_UNSUPPORTED, 216 .ap_ps_peer_param_cmdid = WMI_10X_AP_PS_PEER_PARAM_CMDID,
217 .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, 217 .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED,
218 .peer_rate_retry_sched_cmdid = WMI_10X_PEER_RATE_RETRY_SCHED_CMDID, 218 .peer_rate_retry_sched_cmdid = WMI_10X_PEER_RATE_RETRY_SCHED_CMDID,
219 .wlan_profile_trigger_cmdid = WMI_10X_WLAN_PROFILE_TRIGGER_CMDID, 219 .wlan_profile_trigger_cmdid = WMI_10X_WLAN_PROFILE_TRIGGER_CMDID,
@@ -420,7 +420,6 @@ static struct wmi_pdev_param_map wmi_pdev_param_map = {
420 .bcnflt_stats_update_period = WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 420 .bcnflt_stats_update_period = WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
421 .pmf_qos = WMI_PDEV_PARAM_PMF_QOS, 421 .pmf_qos = WMI_PDEV_PARAM_PMF_QOS,
422 .arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 422 .arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
423 .arpdhcp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
424 .dcs = WMI_PDEV_PARAM_DCS, 423 .dcs = WMI_PDEV_PARAM_DCS,
425 .ani_enable = WMI_PDEV_PARAM_ANI_ENABLE, 424 .ani_enable = WMI_PDEV_PARAM_ANI_ENABLE,
426 .ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 425 .ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD,
@@ -472,8 +471,7 @@ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
472 .bcnflt_stats_update_period = 471 .bcnflt_stats_update_period =
473 WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 472 WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
474 .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS, 473 .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS,
475 .arp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, 474 .arp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
476 .arpdhcp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
477 .dcs = WMI_10X_PDEV_PARAM_DCS, 475 .dcs = WMI_10X_PDEV_PARAM_DCS,
478 .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE, 476 .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE,
479 .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD, 477 .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD,
@@ -561,7 +559,6 @@ err_pull:
561 559
562static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) 560static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
563{ 561{
564 struct wmi_bcn_tx_arg arg = {0};
565 int ret; 562 int ret;
566 563
567 lockdep_assert_held(&arvif->ar->data_lock); 564 lockdep_assert_held(&arvif->ar->data_lock);
@@ -569,18 +566,16 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
569 if (arvif->beacon == NULL) 566 if (arvif->beacon == NULL)
570 return; 567 return;
571 568
572 arg.vdev_id = arvif->vdev_id; 569 if (arvif->beacon_sent)
573 arg.tx_rate = 0; 570 return;
574 arg.tx_power = 0;
575 arg.bcn = arvif->beacon->data;
576 arg.bcn_len = arvif->beacon->len;
577 571
578 ret = ath10k_wmi_beacon_send_nowait(arvif->ar, &arg); 572 ret = ath10k_wmi_beacon_send_ref_nowait(arvif);
579 if (ret) 573 if (ret)
580 return; 574 return;
581 575
582 dev_kfree_skb_any(arvif->beacon); 576 /* We need to retain the arvif->beacon reference for DMA unmapping and
583 arvif->beacon = NULL; 577 * freeing the skbuff later. */
578 arvif->beacon_sent = true;
584} 579}
585 580
586static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac, 581static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac,
@@ -1116,7 +1111,27 @@ static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar,
1116static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, 1111static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar,
1117 struct sk_buff *skb) 1112 struct sk_buff *skb)
1118{ 1113{
1119 ath10k_dbg(ATH10K_DBG_WMI, "WMI_PEER_STA_KICKOUT_EVENTID\n"); 1114 struct wmi_peer_sta_kickout_event *ev;
1115 struct ieee80211_sta *sta;
1116
1117 ev = (struct wmi_peer_sta_kickout_event *)skb->data;
1118
1119 ath10k_dbg(ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n",
1120 ev->peer_macaddr.addr);
1121
1122 rcu_read_lock();
1123
1124 sta = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL);
1125 if (!sta) {
1126 ath10k_warn("Spurious quick kickout for STA %pM\n",
1127 ev->peer_macaddr.addr);
1128 goto exit;
1129 }
1130
1131 ieee80211_report_low_ack(sta, 10);
1132
1133exit:
1134 rcu_read_unlock();
1120} 1135}
1121 1136
1122/* 1137/*
@@ -1217,6 +1232,13 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
1217 tim->bitmap_ctrl = !!__le32_to_cpu(bcn_info->tim_info.tim_mcast); 1232 tim->bitmap_ctrl = !!__le32_to_cpu(bcn_info->tim_info.tim_mcast);
1218 memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len); 1233 memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);
1219 1234
1235 if (tim->dtim_count == 0) {
1236 ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true;
1237
1238 if (__le32_to_cpu(bcn_info->tim_info.tim_mcast) == 1)
1239 ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true;
1240 }
1241
1220 ath10k_dbg(ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n", 1242 ath10k_dbg(ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n",
1221 tim->dtim_count, tim->dtim_period, 1243 tim->dtim_count, tim->dtim_period,
1222 tim->bitmap_ctrl, pvm_len); 1244 tim->bitmap_ctrl, pvm_len);
@@ -1385,6 +1407,17 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1385 continue; 1407 continue;
1386 } 1408 }
1387 1409
1410 /* There are no completions for beacons so wait for next SWBA
1411 * before telling mac80211 to decrement CSA counter
1412 *
1413 * Once CSA counter is completed stop sending beacons until
1414 * actual channel switch is done */
1415 if (arvif->vif->csa_active &&
1416 ieee80211_csa_is_complete(arvif->vif)) {
1417 ieee80211_csa_finish(arvif->vif);
1418 continue;
1419 }
1420
1388 bcn = ieee80211_beacon_get(ar->hw, arvif->vif); 1421 bcn = ieee80211_beacon_get(ar->hw, arvif->vif);
1389 if (!bcn) { 1422 if (!bcn) {
1390 ath10k_warn("could not get mac80211 beacon\n"); 1423 ath10k_warn("could not get mac80211 beacon\n");
@@ -1396,13 +1429,20 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1396 ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info); 1429 ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info);
1397 1430
1398 spin_lock_bh(&ar->data_lock); 1431 spin_lock_bh(&ar->data_lock);
1432
1399 if (arvif->beacon) { 1433 if (arvif->beacon) {
1400 ath10k_warn("SWBA overrun on vdev %d\n", 1434 if (!arvif->beacon_sent)
1401 arvif->vdev_id); 1435 ath10k_warn("SWBA overrun on vdev %d\n",
1436 arvif->vdev_id);
1437
1438 ath10k_skb_unmap(ar->dev, arvif->beacon);
1402 dev_kfree_skb_any(arvif->beacon); 1439 dev_kfree_skb_any(arvif->beacon);
1403 } 1440 }
1404 1441
1442 ath10k_skb_map(ar->dev, bcn);
1443
1405 arvif->beacon = bcn; 1444 arvif->beacon = bcn;
1445 arvif->beacon_sent = false;
1406 1446
1407 ath10k_wmi_tx_beacon_nowait(arvif); 1447 ath10k_wmi_tx_beacon_nowait(arvif);
1408 spin_unlock_bh(&ar->data_lock); 1448 spin_unlock_bh(&ar->data_lock);
@@ -2031,11 +2071,11 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb)
2031 memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN); 2071 memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN);
2032 2072
2033 ath10k_dbg(ATH10K_DBG_WMI, 2073 ath10k_dbg(ATH10K_DBG_WMI,
2034 "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d\n", 2074 "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n",
2035 __le32_to_cpu(ev->sw_version), 2075 __le32_to_cpu(ev->sw_version),
2036 __le32_to_cpu(ev->abi_version), 2076 __le32_to_cpu(ev->abi_version),
2037 ev->mac_addr.addr, 2077 ev->mac_addr.addr,
2038 __le32_to_cpu(ev->status)); 2078 __le32_to_cpu(ev->status), skb->len, sizeof(*ev));
2039 2079
2040 complete(&ar->wmi.unified_ready); 2080 complete(&ar->wmi.unified_ready);
2041 return 0; 2081 return 0;
@@ -2403,7 +2443,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
2403 ar->wmi.cmd->pdev_set_channel_cmdid); 2443 ar->wmi.cmd->pdev_set_channel_cmdid);
2404} 2444}
2405 2445
2406int ath10k_wmi_pdev_suspend_target(struct ath10k *ar) 2446int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
2407{ 2447{
2408 struct wmi_pdev_suspend_cmd *cmd; 2448 struct wmi_pdev_suspend_cmd *cmd;
2409 struct sk_buff *skb; 2449 struct sk_buff *skb;
@@ -2413,7 +2453,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar)
2413 return -ENOMEM; 2453 return -ENOMEM;
2414 2454
2415 cmd = (struct wmi_pdev_suspend_cmd *)skb->data; 2455 cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
2416 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2456 cmd->suspend_opt = __cpu_to_le32(suspend_opt);
2417 2457
2418 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); 2458 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid);
2419} 2459}
@@ -3411,25 +3451,41 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar,
3411 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); 3451 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid);
3412} 3452}
3413 3453
3414int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, 3454/* This function assumes the beacon is already DMA mapped */
3415 const struct wmi_bcn_tx_arg *arg) 3455int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif)
3416{ 3456{
3417 struct wmi_bcn_tx_cmd *cmd; 3457 struct wmi_bcn_tx_ref_cmd *cmd;
3418 struct sk_buff *skb; 3458 struct sk_buff *skb;
3459 struct sk_buff *beacon = arvif->beacon;
3460 struct ath10k *ar = arvif->ar;
3461 struct ieee80211_hdr *hdr;
3419 int ret; 3462 int ret;
3463 u16 fc;
3420 3464
3421 skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->bcn_len); 3465 skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
3422 if (!skb) 3466 if (!skb)
3423 return -ENOMEM; 3467 return -ENOMEM;
3424 3468
3425 cmd = (struct wmi_bcn_tx_cmd *)skb->data; 3469 hdr = (struct ieee80211_hdr *)beacon->data;
3426 cmd->hdr.vdev_id = __cpu_to_le32(arg->vdev_id); 3470 fc = le16_to_cpu(hdr->frame_control);
3427 cmd->hdr.tx_rate = __cpu_to_le32(arg->tx_rate); 3471
3428 cmd->hdr.tx_power = __cpu_to_le32(arg->tx_power); 3472 cmd = (struct wmi_bcn_tx_ref_cmd *)skb->data;
3429 cmd->hdr.bcn_len = __cpu_to_le32(arg->bcn_len); 3473 cmd->vdev_id = __cpu_to_le32(arvif->vdev_id);
3430 memcpy(cmd->bcn, arg->bcn, arg->bcn_len); 3474 cmd->data_len = __cpu_to_le32(beacon->len);
3475 cmd->data_ptr = __cpu_to_le32(ATH10K_SKB_CB(beacon)->paddr);
3476 cmd->msdu_id = 0;
3477 cmd->frame_control = __cpu_to_le32(fc);
3478 cmd->flags = 0;
3479
3480 if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero)
3481 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
3482
3483 if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab)
3484 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
3485
3486 ret = ath10k_wmi_cmd_send_nowait(ar, skb,
3487 ar->wmi.cmd->pdev_send_bcn_cmdid);
3431 3488
3432 ret = ath10k_wmi_cmd_send_nowait(ar, skb, ar->wmi.cmd->bcn_tx_cmdid);
3433 if (ret) 3489 if (ret)
3434 dev_kfree_skb(skb); 3490 dev_kfree_skb(skb);
3435 3491
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 4b5e7d3d32b6..4fcc96aa9513 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -2277,7 +2277,6 @@ struct wmi_pdev_param_map {
2277 u32 bcnflt_stats_update_period; 2277 u32 bcnflt_stats_update_period;
2278 u32 pmf_qos; 2278 u32 pmf_qos;
2279 u32 arp_ac_override; 2279 u32 arp_ac_override;
2280 u32 arpdhcp_ac_override;
2281 u32 dcs; 2280 u32 dcs;
2282 u32 ani_enable; 2281 u32 ani_enable;
2283 u32 ani_poll_period; 2282 u32 ani_poll_period;
@@ -3403,6 +3402,24 @@ struct wmi_bcn_tx_arg {
3403 const void *bcn; 3402 const void *bcn;
3404}; 3403};
3405 3404
3405enum wmi_bcn_tx_ref_flags {
3406 WMI_BCN_TX_REF_FLAG_DTIM_ZERO = 0x1,
3407 WMI_BCN_TX_REF_FLAG_DELIVER_CAB = 0x2,
3408};
3409
3410struct wmi_bcn_tx_ref_cmd {
3411 __le32 vdev_id;
3412 __le32 data_len;
3413 /* physical address of the frame - dma pointer */
3414 __le32 data_ptr;
3415 /* id for host to track */
3416 __le32 msdu_id;
3417 /* frame ctrl to setup PPDU desc */
3418 __le32 frame_control;
3419 /* to control CABQ traffic: WMI_BCN_TX_REF_FLAG_ */
3420 __le32 flags;
3421} __packed;
3422
3406/* Beacon filter */ 3423/* Beacon filter */
3407#define WMI_BCN_FILTER_ALL 0 /* Filter all beacons */ 3424#define WMI_BCN_FILTER_ALL 0 /* Filter all beacons */
3408#define WMI_BCN_FILTER_NONE 1 /* Pass all beacons */ 3425#define WMI_BCN_FILTER_NONE 1 /* Pass all beacons */
@@ -3859,6 +3876,12 @@ enum wmi_peer_smps_state {
3859 WMI_PEER_SMPS_DYNAMIC = 0x2 3876 WMI_PEER_SMPS_DYNAMIC = 0x2
3860}; 3877};
3861 3878
3879enum wmi_peer_chwidth {
3880 WMI_PEER_CHWIDTH_20MHZ = 0,
3881 WMI_PEER_CHWIDTH_40MHZ = 1,
3882 WMI_PEER_CHWIDTH_80MHZ = 2,
3883};
3884
3862enum wmi_peer_param { 3885enum wmi_peer_param {
3863 WMI_PEER_SMPS_STATE = 0x1, /* see %wmi_peer_smps_state */ 3886 WMI_PEER_SMPS_STATE = 0x1, /* see %wmi_peer_smps_state */
3864 WMI_PEER_AMPDU = 0x2, 3887 WMI_PEER_AMPDU = 0x2,
@@ -4039,6 +4062,10 @@ struct wmi_chan_info_event {
4039 __le32 cycle_count; 4062 __le32 cycle_count;
4040} __packed; 4063} __packed;
4041 4064
4065struct wmi_peer_sta_kickout_event {
4066 struct wmi_mac_addr peer_macaddr;
4067} __packed;
4068
4042#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0) 4069#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
4043 4070
4044/* FIXME: empirically extrapolated */ 4071/* FIXME: empirically extrapolated */
@@ -4172,7 +4199,7 @@ int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
4172int ath10k_wmi_connect_htc_service(struct ath10k *ar); 4199int ath10k_wmi_connect_htc_service(struct ath10k *ar);
4173int ath10k_wmi_pdev_set_channel(struct ath10k *ar, 4200int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
4174 const struct wmi_channel_arg *); 4201 const struct wmi_channel_arg *);
4175int ath10k_wmi_pdev_suspend_target(struct ath10k *ar); 4202int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt);
4176int ath10k_wmi_pdev_resume_target(struct ath10k *ar); 4203int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
4177int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, 4204int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
4178 u16 rd5g, u16 ctl2g, u16 ctl5g); 4205 u16 rd5g, u16 ctl2g, u16 ctl5g);
@@ -4219,8 +4246,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
4219 enum wmi_ap_ps_peer_param param_id, u32 value); 4246 enum wmi_ap_ps_peer_param param_id, u32 value);
4220int ath10k_wmi_scan_chan_list(struct ath10k *ar, 4247int ath10k_wmi_scan_chan_list(struct ath10k *ar,
4221 const struct wmi_scan_chan_list_arg *arg); 4248 const struct wmi_scan_chan_list_arg *arg);
4222int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, 4249int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif);
4223 const struct wmi_bcn_tx_arg *arg);
4224int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, 4250int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
4225 const struct wmi_pdev_set_wmm_params_arg *arg); 4251 const struct wmi_pdev_set_wmm_params_arg *arg);
4226int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); 4252int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id);
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 4ee01f654235..afb23b3cc7be 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -681,6 +681,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
681 survey->channel = conf->chandef.chan; 681 survey->channel = conf->chandef.chan;
682 survey->noise = ah->ah_noise_floor; 682 survey->noise = ah->ah_noise_floor;
683 survey->filled = SURVEY_INFO_NOISE_DBM | 683 survey->filled = SURVEY_INFO_NOISE_DBM |
684 SURVEY_INFO_IN_USE |
684 SURVEY_INFO_CHANNEL_TIME | 685 SURVEY_INFO_CHANNEL_TIME |
685 SURVEY_INFO_CHANNEL_TIME_BUSY | 686 SURVEY_INFO_CHANNEL_TIME_BUSY |
686 SURVEY_INFO_CHANNEL_TIME_RX | 687 SURVEY_INFO_CHANNEL_TIME_RX |
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index f38ff6a6255e..56c3fd5cef65 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -24,7 +24,7 @@
24/* constants */ 24/* constants */
25#define TX_URB_COUNT 32 25#define TX_URB_COUNT 32
26#define RX_URB_COUNT 32 26#define RX_URB_COUNT 32
27#define ATH6KL_USB_RX_BUFFER_SIZE 1700 27#define ATH6KL_USB_RX_BUFFER_SIZE 4096
28 28
29/* tx/rx pipes for usb */ 29/* tx/rx pipes for usb */
30enum ATH6KL_USB_PIPE_ID { 30enum ATH6KL_USB_PIPE_ID {
@@ -481,8 +481,8 @@ static void ath6kl_usb_start_recv_pipes(struct ath6kl_usb *ar_usb)
481 * ATH6KL_USB_RX_BUFFER_SIZE); 481 * ATH6KL_USB_RX_BUFFER_SIZE);
482 */ 482 */
483 483
484 ar_usb->pipes[ATH6KL_USB_PIPE_RX_DATA].urb_cnt_thresh = 484 ar_usb->pipes[ATH6KL_USB_PIPE_RX_DATA].urb_cnt_thresh = 1;
485 ar_usb->pipes[ATH6KL_USB_PIPE_RX_DATA].urb_alloc / 2; 485
486 ath6kl_usb_post_recv_transfers(&ar_usb->pipes[ATH6KL_USB_PIPE_RX_DATA], 486 ath6kl_usb_post_recv_transfers(&ar_usb->pipes[ATH6KL_USB_PIPE_RX_DATA],
487 ATH6KL_USB_RX_BUFFER_SIZE); 487 ATH6KL_USB_RX_BUFFER_SIZE);
488} 488}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 4f16d79c9eb1..8b4ce28e3ce8 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -914,7 +914,7 @@ ath6kl_get_regpair(u16 regdmn)
914 return NULL; 914 return NULL;
915 915
916 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { 916 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
917 if (regDomainPairs[i].regDmnEnum == regdmn) 917 if (regDomainPairs[i].reg_domain == regdmn)
918 return &regDomainPairs[i]; 918 return &regDomainPairs[i];
919 } 919 }
920 920
@@ -954,7 +954,7 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
954 country = ath6kl_regd_find_country_by_rd((u16) reg_code); 954 country = ath6kl_regd_find_country_by_rd((u16) reg_code);
955 if (regpair) 955 if (regpair)
956 ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", 956 ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
957 regpair->regDmnEnum); 957 regpair->reg_domain);
958 else 958 else
959 ath6kl_warn("Regpair not found reg_code 0x%0x\n", 959 ath6kl_warn("Regpair not found reg_code 0x%0x\n",
960 reg_code); 960 reg_code);
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 747975e1860a..b58fe99ef745 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -51,7 +51,8 @@ ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
51obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o 51obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
52 52
53obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o 53obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
54ath9k_common-y:= common.o 54ath9k_common-y:= common.o \
55 common-init.o
55 56
56ath9k_htc-y += htc_hst.o \ 57ath9k_htc-y += htc_hst.o \
57 hif_usb.o \ 58 hif_usb.o \
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index d28923b7435b..2ce5079007b6 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -176,16 +176,26 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
176 if (ah->opmode == NL80211_IFTYPE_STATION && 176 if (ah->opmode == NL80211_IFTYPE_STATION &&
177 BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH) 177 BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
178 weak_sig = true; 178 weak_sig = true;
179
180 /* 179 /*
181 * OFDM Weak signal detection is always enabled for AP mode. 180 * Newer chipsets are better at dealing with high PHY error counts -
181 * keep weak signal detection enabled when no RSSI threshold is
182 * available to determine if it is needed (mode != STA)
182 */ 183 */
183 if (ah->opmode != NL80211_IFTYPE_AP && 184 else if (AR_SREV_9300_20_OR_LATER(ah) &&
184 aniState->ofdmWeakSigDetect != weak_sig) { 185 ah->opmode != NL80211_IFTYPE_STATION)
185 ath9k_hw_ani_control(ah, 186 weak_sig = true;
186 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 187
187 entry_ofdm->ofdm_weak_signal_on); 188 /* Older chipsets are more sensitive to high PHY error counts */
188 } 189 else if (!AR_SREV_9300_20_OR_LATER(ah) &&
190 aniState->ofdmNoiseImmunityLevel >= 8)
191 weak_sig = false;
192
193 if (aniState->ofdmWeakSigDetect != weak_sig)
194 ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
195 weak_sig);
196
197 if (!AR_SREV_9300_20_OR_LATER(ah))
198 return;
189 199
190 if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) { 200 if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
191 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; 201 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
@@ -483,10 +493,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
483 493
484 ath_dbg(common, ANI, "Initialize ANI\n"); 494 ath_dbg(common, ANI, "Initialize ANI\n");
485 495
486 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; 496 if (AR_SREV_9300_20_OR_LATER(ah)) {
487 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; 497 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
488 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; 498 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
489 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; 499 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
500 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
501 } else {
502 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
503 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
504 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
505 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
506 }
490 507
491 ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 508 ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
492 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 509 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 21e7b83c3f6a..c40965b4c1e2 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -22,12 +22,16 @@
22/* units are errors per second */ 22/* units are errors per second */
23#define ATH9K_ANI_OFDM_TRIG_HIGH 3500 23#define ATH9K_ANI_OFDM_TRIG_HIGH 3500
24#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000 24#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
25#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
25 26
26#define ATH9K_ANI_OFDM_TRIG_LOW 400 27#define ATH9K_ANI_OFDM_TRIG_LOW 400
27#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900 28#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
29#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
28 30
29#define ATH9K_ANI_CCK_TRIG_HIGH 600 31#define ATH9K_ANI_CCK_TRIG_HIGH 600
32#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
30#define ATH9K_ANI_CCK_TRIG_LOW 300 33#define ATH9K_ANI_CCK_TRIG_LOW 300
34#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100
31 35
32#define ATH9K_ANI_SPUR_IMMUNE_LVL 3 36#define ATH9K_ANI_SPUR_IMMUNE_LVL 3
33#define ATH9K_ANI_FIRSTEP_LVL 2 37#define ATH9K_ANI_FIRSTEP_LVL 2
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 09facba1dc6d..8927fc34d84c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -868,10 +868,6 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah,
868 868
869 if (IS_CHAN_A_FAST_CLOCK(ah, chan)) 869 if (IS_CHAN_A_FAST_CLOCK(ah, chan))
870 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); 870 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
871 if (IS_CHAN_QUARTER_RATE(chan))
872 rfMode |= AR_PHY_MODE_QUARTER;
873 if (IS_CHAN_HALF_RATE(chan))
874 rfMode |= AR_PHY_MODE_HALF;
875 871
876 if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF)) 872 if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF))
877 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, 873 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 21d13bc99c5a..f995c374a9b4 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -410,7 +410,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
410 410
411struct ath_beacon_config { 411struct ath_beacon_config {
412 int beacon_interval; 412 int beacon_interval;
413 u16 listen_interval;
414 u16 dtim_period; 413 u16 dtim_period;
415 u16 bmiss_timeout; 414 u16 bmiss_timeout;
416 u8 dtim_count; 415 u8 dtim_count;
@@ -753,7 +752,6 @@ struct ath_softc {
753 struct ath_rx rx; 752 struct ath_rx rx;
754 struct ath_tx tx; 753 struct ath_tx tx;
755 struct ath_beacon beacon; 754 struct ath_beacon beacon;
756 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
757 755
758#ifdef CONFIG_MAC80211_LEDS 756#ifdef CONFIG_MAC80211_LEDS
759 bool led_registered; 757 bool led_registered;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 32d00e8cfd0c..02eb4f10332b 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -80,7 +80,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
80 u8 chainmask = ah->txchainmask; 80 u8 chainmask = ah->txchainmask;
81 u8 rate = 0; 81 u8 rate = 0;
82 82
83 sband = &sc->sbands[common->hw->conf.chandef.chan->band]; 83 sband = &common->sbands[common->hw->conf.chandef.chan->band];
84 rate = sband->bitrates[rateidx].hw_value; 84 rate = sband->bitrates[rateidx].hw_value;
85 if (vif->bss_conf.use_short_preamble) 85 if (vif->bss_conf.use_short_preamble)
86 rate |= sband->bitrates[rateidx].hw_value_short; 86 rate |= sband->bitrates[rateidx].hw_value_short;
@@ -519,7 +519,7 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
519 struct ath_hw *ah = sc->sc_ah; 519 struct ath_hw *ah = sc->sc_ah;
520 struct ath_common *common = ath9k_hw_common(ah); 520 struct ath_common *common = ath9k_hw_common(ah);
521 struct ath9k_beacon_state bs; 521 struct ath9k_beacon_state bs;
522 int dtim_intval, sleepduration; 522 int dtim_intval;
523 u32 nexttbtt = 0, intval; 523 u32 nexttbtt = 0, intval;
524 u64 tsf; 524 u64 tsf;
525 525
@@ -538,7 +538,6 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
538 * last beacon we received (which may be none). 538 * last beacon we received (which may be none).
539 */ 539 */
540 dtim_intval = intval * conf->dtim_period; 540 dtim_intval = intval * conf->dtim_period;
541 sleepduration = conf->listen_interval * intval;
542 541
543 /* 542 /*
544 * Pull nexttbtt forward to reflect the current 543 * Pull nexttbtt forward to reflect the current
@@ -560,16 +559,11 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
560 * need calculate based on the beacon interval. Note that we clamp the 559 * need calculate based on the beacon interval. Note that we clamp the
561 * result to at most 15 beacons. 560 * result to at most 15 beacons.
562 */ 561 */
563 if (sleepduration > intval) { 562 bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval);
564 bs.bs_bmissthreshold = conf->listen_interval * 563 if (bs.bs_bmissthreshold > 15)
565 ATH_DEFAULT_BMISS_LIMIT / 2; 564 bs.bs_bmissthreshold = 15;
566 } else { 565 else if (bs.bs_bmissthreshold <= 0)
567 bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval); 566 bs.bs_bmissthreshold = 1;
568 if (bs.bs_bmissthreshold > 15)
569 bs.bs_bmissthreshold = 15;
570 else if (bs.bs_bmissthreshold <= 0)
571 bs.bs_bmissthreshold = 1;
572 }
573 567
574 /* 568 /*
575 * Calculate sleep duration. The configuration is given in ms. 569 * Calculate sleep duration. The configuration is given in ms.
@@ -581,7 +575,7 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
581 */ 575 */
582 576
583 bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100), 577 bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
584 sleepduration)); 578 intval));
585 if (bs.bs_sleepduration > bs.bs_dtimperiod) 579 if (bs.bs_sleepduration > bs.bs_dtimperiod)
586 bs.bs_sleepduration = bs.bs_dtimperiod; 580 bs.bs_sleepduration = bs.bs_dtimperiod;
587 581
@@ -677,7 +671,6 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc,
677 671
678 cur_conf->beacon_interval = bss_conf->beacon_int; 672 cur_conf->beacon_interval = bss_conf->beacon_int;
679 cur_conf->dtim_period = bss_conf->dtim_period; 673 cur_conf->dtim_period = bss_conf->dtim_period;
680 cur_conf->listen_interval = 1;
681 cur_conf->dtim_count = 1; 674 cur_conf->dtim_count = 1;
682 cur_conf->ibss_creator = bss_conf->ibss_creator; 675 cur_conf->ibss_creator = bss_conf->ibss_creator;
683 cur_conf->bmiss_timeout = 676 cur_conf->bmiss_timeout =
diff --git a/drivers/net/wireless/ath/ath9k/common-init.c b/drivers/net/wireless/ath/ath9k/common-init.c
new file mode 100644
index 000000000000..a006c1499728
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/common-init.c
@@ -0,0 +1,244 @@
1/*
2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/* We use the hw_value as an index into our private channel structure */
18
19#include "common.h"
20
21#define CHAN2G(_freq, _idx) { \
22 .band = IEEE80211_BAND_2GHZ, \
23 .center_freq = (_freq), \
24 .hw_value = (_idx), \
25 .max_power = 20, \
26}
27
28#define CHAN5G(_freq, _idx) { \
29 .band = IEEE80211_BAND_5GHZ, \
30 .center_freq = (_freq), \
31 .hw_value = (_idx), \
32 .max_power = 20, \
33}
34
35/* Some 2 GHz radios are actually tunable on 2312-2732
36 * on 5 MHz steps, we support the channels which we know
37 * we have calibration data for all cards though to make
38 * this static */
39static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
40 CHAN2G(2412, 0), /* Channel 1 */
41 CHAN2G(2417, 1), /* Channel 2 */
42 CHAN2G(2422, 2), /* Channel 3 */
43 CHAN2G(2427, 3), /* Channel 4 */
44 CHAN2G(2432, 4), /* Channel 5 */
45 CHAN2G(2437, 5), /* Channel 6 */
46 CHAN2G(2442, 6), /* Channel 7 */
47 CHAN2G(2447, 7), /* Channel 8 */
48 CHAN2G(2452, 8), /* Channel 9 */
49 CHAN2G(2457, 9), /* Channel 10 */
50 CHAN2G(2462, 10), /* Channel 11 */
51 CHAN2G(2467, 11), /* Channel 12 */
52 CHAN2G(2472, 12), /* Channel 13 */
53 CHAN2G(2484, 13), /* Channel 14 */
54};
55
56/* Some 5 GHz radios are actually tunable on XXXX-YYYY
57 * on 5 MHz steps, we support the channels which we know
58 * we have calibration data for all cards though to make
59 * this static */
60static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
61 /* _We_ call this UNII 1 */
62 CHAN5G(5180, 14), /* Channel 36 */
63 CHAN5G(5200, 15), /* Channel 40 */
64 CHAN5G(5220, 16), /* Channel 44 */
65 CHAN5G(5240, 17), /* Channel 48 */
66 /* _We_ call this UNII 2 */
67 CHAN5G(5260, 18), /* Channel 52 */
68 CHAN5G(5280, 19), /* Channel 56 */
69 CHAN5G(5300, 20), /* Channel 60 */
70 CHAN5G(5320, 21), /* Channel 64 */
71 /* _We_ call this "Middle band" */
72 CHAN5G(5500, 22), /* Channel 100 */
73 CHAN5G(5520, 23), /* Channel 104 */
74 CHAN5G(5540, 24), /* Channel 108 */
75 CHAN5G(5560, 25), /* Channel 112 */
76 CHAN5G(5580, 26), /* Channel 116 */
77 CHAN5G(5600, 27), /* Channel 120 */
78 CHAN5G(5620, 28), /* Channel 124 */
79 CHAN5G(5640, 29), /* Channel 128 */
80 CHAN5G(5660, 30), /* Channel 132 */
81 CHAN5G(5680, 31), /* Channel 136 */
82 CHAN5G(5700, 32), /* Channel 140 */
83 /* _We_ call this UNII 3 */
84 CHAN5G(5745, 33), /* Channel 149 */
85 CHAN5G(5765, 34), /* Channel 153 */
86 CHAN5G(5785, 35), /* Channel 157 */
87 CHAN5G(5805, 36), /* Channel 161 */
88 CHAN5G(5825, 37), /* Channel 165 */
89};
90
91/* Atheros hardware rate code addition for short premble */
92#define SHPCHECK(__hw_rate, __flags) \
93 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
94
95#define RATE(_bitrate, _hw_rate, _flags) { \
96 .bitrate = (_bitrate), \
97 .flags = (_flags), \
98 .hw_value = (_hw_rate), \
99 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
100}
101
102static struct ieee80211_rate ath9k_legacy_rates[] = {
103 RATE(10, 0x1b, 0),
104 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
105 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
106 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
107 RATE(60, 0x0b, (IEEE80211_RATE_SUPPORTS_5MHZ |
108 IEEE80211_RATE_SUPPORTS_10MHZ)),
109 RATE(90, 0x0f, (IEEE80211_RATE_SUPPORTS_5MHZ |
110 IEEE80211_RATE_SUPPORTS_10MHZ)),
111 RATE(120, 0x0a, (IEEE80211_RATE_SUPPORTS_5MHZ |
112 IEEE80211_RATE_SUPPORTS_10MHZ)),
113 RATE(180, 0x0e, (IEEE80211_RATE_SUPPORTS_5MHZ |
114 IEEE80211_RATE_SUPPORTS_10MHZ)),
115 RATE(240, 0x09, (IEEE80211_RATE_SUPPORTS_5MHZ |
116 IEEE80211_RATE_SUPPORTS_10MHZ)),
117 RATE(360, 0x0d, (IEEE80211_RATE_SUPPORTS_5MHZ |
118 IEEE80211_RATE_SUPPORTS_10MHZ)),
119 RATE(480, 0x08, (IEEE80211_RATE_SUPPORTS_5MHZ |
120 IEEE80211_RATE_SUPPORTS_10MHZ)),
121 RATE(540, 0x0c, (IEEE80211_RATE_SUPPORTS_5MHZ |
122 IEEE80211_RATE_SUPPORTS_10MHZ)),
123};
124
125int ath9k_cmn_init_channels_rates(struct ath_common *common)
126{
127 struct ath_hw *ah = (struct ath_hw *)common->ah;
128 void *channels;
129
130 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
131 ARRAY_SIZE(ath9k_5ghz_chantable) !=
132 ATH9K_NUM_CHANNELS);
133
134 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
135 channels = devm_kzalloc(ah->dev,
136 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
137 if (!channels)
138 return -ENOMEM;
139
140 memcpy(channels, ath9k_2ghz_chantable,
141 sizeof(ath9k_2ghz_chantable));
142 common->sbands[IEEE80211_BAND_2GHZ].channels = channels;
143 common->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
144 common->sbands[IEEE80211_BAND_2GHZ].n_channels =
145 ARRAY_SIZE(ath9k_2ghz_chantable);
146 common->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
147 common->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
148 ARRAY_SIZE(ath9k_legacy_rates);
149 }
150
151 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
152 channels = devm_kzalloc(ah->dev,
153 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
154 if (!channels)
155 return -ENOMEM;
156
157 memcpy(channels, ath9k_5ghz_chantable,
158 sizeof(ath9k_5ghz_chantable));
159 common->sbands[IEEE80211_BAND_5GHZ].channels = channels;
160 common->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
161 common->sbands[IEEE80211_BAND_5GHZ].n_channels =
162 ARRAY_SIZE(ath9k_5ghz_chantable);
163 common->sbands[IEEE80211_BAND_5GHZ].bitrates =
164 ath9k_legacy_rates + 4;
165 common->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
166 ARRAY_SIZE(ath9k_legacy_rates) - 4;
167 }
168 return 0;
169}
170EXPORT_SYMBOL(ath9k_cmn_init_channels_rates);
171
172void ath9k_cmn_setup_ht_cap(struct ath_hw *ah,
173 struct ieee80211_sta_ht_cap *ht_info)
174{
175 struct ath_common *common = ath9k_hw_common(ah);
176 u8 tx_streams, rx_streams;
177 int i, max_streams;
178
179 ht_info->ht_supported = true;
180 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
181 IEEE80211_HT_CAP_SM_PS |
182 IEEE80211_HT_CAP_SGI_40 |
183 IEEE80211_HT_CAP_DSSSCCK40;
184
185 if (ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
186 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
187
188 if (ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
189 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
190
191 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
192 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
193
194 if (AR_SREV_9271(ah) || AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah))
195 max_streams = 1;
196 else if (AR_SREV_9462(ah))
197 max_streams = 2;
198 else if (AR_SREV_9300_20_OR_LATER(ah))
199 max_streams = 3;
200 else
201 max_streams = 2;
202
203 if (AR_SREV_9280_20_OR_LATER(ah)) {
204 if (max_streams >= 2)
205 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
206 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
207 }
208
209 /* set up supported mcs set */
210 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
211 tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams);
212 rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams);
213
214 ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n",
215 tx_streams, rx_streams);
216
217 if (tx_streams != rx_streams) {
218 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
219 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
220 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
221 }
222
223 for (i = 0; i < rx_streams; i++)
224 ht_info->mcs.rx_mask[i] = 0xff;
225
226 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
227}
228EXPORT_SYMBOL(ath9k_cmn_setup_ht_cap);
229
230void ath9k_cmn_reload_chainmask(struct ath_hw *ah)
231{
232 struct ath_common *common = ath9k_hw_common(ah);
233
234 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_HT))
235 return;
236
237 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
238 ath9k_cmn_setup_ht_cap(ah,
239 &common->sbands[IEEE80211_BAND_2GHZ].ht_cap);
240 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
241 ath9k_cmn_setup_ht_cap(ah,
242 &common->sbands[IEEE80211_BAND_5GHZ].ht_cap);
243}
244EXPORT_SYMBOL(ath9k_cmn_reload_chainmask);
diff --git a/drivers/net/wireless/ath/ath9k/common-init.h b/drivers/net/wireless/ath/ath9k/common-init.h
new file mode 100644
index 000000000000..ac03fca5ffdd
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/common-init.h
@@ -0,0 +1,20 @@
1/*
2 * Copyright (c) 2009-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17int ath9k_cmn_init_channels_rates(struct ath_common *common);
18void ath9k_cmn_setup_ht_cap(struct ath_hw *ah,
19 struct ieee80211_sta_ht_cap *ht_info);
20void ath9k_cmn_reload_chainmask(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 38b5609a4018..4c449e35bd65 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -21,6 +21,8 @@
21#include "hw.h" 21#include "hw.h"
22#include "hw-ops.h" 22#include "hw-ops.h"
23 23
24#include "common-init.h"
25
24/* Common header for Atheros 802.11n base driver cores */ 26/* Common header for Atheros 802.11n base driver cores */
25 27
26#define WME_BA_BMP_SIZE 64 28#define WME_BA_BMP_SIZE 64
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index ab7264c1d8f7..f8924efdad55 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -135,7 +135,8 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
135 struct ath_softc *sc = file->private_data; 135 struct ath_softc *sc = file->private_data;
136 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 136 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
137 struct ath_hw *ah = sc->sc_ah; 137 struct ath_hw *ah = sc->sc_ah;
138 unsigned int len = 0, size = 1024; 138 unsigned int len = 0;
139 const unsigned int size = 1024;
139 ssize_t retval = 0; 140 ssize_t retval = 0;
140 char *buf; 141 char *buf;
141 142
@@ -307,13 +308,13 @@ static ssize_t read_file_antenna_diversity(struct file *file,
307 struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN]; 308 struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
308 struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT]; 309 struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
309 struct ath_hw_antcomb_conf div_ant_conf; 310 struct ath_hw_antcomb_conf div_ant_conf;
310 unsigned int len = 0, size = 1024; 311 unsigned int len = 0;
312 const unsigned int size = 1024;
311 ssize_t retval = 0; 313 ssize_t retval = 0;
312 char *buf; 314 char *buf;
313 char *lna_conf_str[4] = {"LNA1_MINUS_LNA2", 315 static const char *lna_conf_str[4] = {
314 "LNA2", 316 "LNA1_MINUS_LNA2", "LNA2", "LNA1", "LNA1_PLUS_LNA2"
315 "LNA1", 317 };
316 "LNA1_PLUS_LNA2"};
317 318
318 buf = kzalloc(size, GFP_KERNEL); 319 buf = kzalloc(size, GFP_KERNEL);
319 if (buf == NULL) 320 if (buf == NULL)
@@ -716,10 +717,13 @@ static ssize_t read_file_queues(struct file *file, char __user *user_buf,
716 struct ath_softc *sc = file->private_data; 717 struct ath_softc *sc = file->private_data;
717 struct ath_txq *txq; 718 struct ath_txq *txq;
718 char *buf; 719 char *buf;
719 unsigned int len = 0, size = 1024; 720 unsigned int len = 0;
721 const unsigned int size = 1024;
720 ssize_t retval = 0; 722 ssize_t retval = 0;
721 int i; 723 int i;
722 char *qname[4] = {"VO", "VI", "BE", "BK"}; 724 static const char *qname[4] = {
725 "VO", "VI", "BE", "BK"
726 };
723 727
724 buf = kzalloc(size, GFP_KERNEL); 728 buf = kzalloc(size, GFP_KERNEL);
725 if (buf == NULL) 729 if (buf == NULL)
@@ -866,6 +870,12 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf,
866 "%17s: %2d\n", "PLL RX Hang", 870 "%17s: %2d\n", "PLL RX Hang",
867 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); 871 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
868 len += scnprintf(buf + len, sizeof(buf) - len, 872 len += scnprintf(buf + len, sizeof(buf) - len,
873 "%17s: %2d\n", "MAC Hang",
874 sc->debug.stats.reset[RESET_TYPE_MAC_HANG]);
875 len += scnprintf(buf + len, sizeof(buf) - len,
876 "%17s: %2d\n", "Stuck Beacon",
877 sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]);
878 len += scnprintf(buf + len, sizeof(buf) - len,
869 "%17s: %2d\n", "MCI Reset", 879 "%17s: %2d\n", "MCI Reset",
870 sc->debug.stats.reset[RESET_TYPE_MCI]); 880 sc->debug.stats.reset[RESET_TYPE_MCI]);
871 881
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index ba83f582bf4a..3baf9ceae601 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -487,7 +487,6 @@ struct ath9k_htc_priv {
487 unsigned long op_flags; 487 unsigned long op_flags;
488 488
489 struct ath9k_hw_cal_data caldata; 489 struct ath9k_hw_cal_data caldata;
490 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
491 490
492 spinlock_t beacon_lock; 491 spinlock_t beacon_lock;
493 struct htc_beacon_config cur_beacon_conf; 492 struct htc_beacon_config cur_beacon_conf;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 8b5757734596..a00ddb9e737e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -69,7 +69,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
69 struct ath_common *common = ath9k_hw_common(priv->ah); 69 struct ath_common *common = ath9k_hw_common(priv->ah);
70 struct ath9k_beacon_state bs; 70 struct ath9k_beacon_state bs;
71 enum ath9k_int imask = 0; 71 enum ath9k_int imask = 0;
72 int dtimperiod, dtimcount, sleepduration; 72 int dtimperiod, dtimcount;
73 int bmiss_timeout; 73 int bmiss_timeout;
74 u32 nexttbtt = 0, intval, tsftu; 74 u32 nexttbtt = 0, intval, tsftu;
75 __be32 htc_imask = 0; 75 __be32 htc_imask = 0;
@@ -94,10 +94,6 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
94 if (dtimcount >= dtimperiod) /* NB: sanity check */ 94 if (dtimcount >= dtimperiod) /* NB: sanity check */
95 dtimcount = 0; 95 dtimcount = 0;
96 96
97 sleepduration = intval;
98 if (sleepduration <= 0)
99 sleepduration = intval;
100
101 /* 97 /*
102 * Pull nexttbtt forward to reflect the current 98 * Pull nexttbtt forward to reflect the current
103 * TSF and calculate dtim state for the result. 99 * TSF and calculate dtim state for the result.
@@ -128,15 +124,11 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
128 * need calculate based on the beacon interval. Note that we clamp the 124 * need calculate based on the beacon interval. Note that we clamp the
129 * result to at most 15 beacons. 125 * result to at most 15 beacons.
130 */ 126 */
131 if (sleepduration > intval) { 127 bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval);
132 bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2; 128 if (bs.bs_bmissthreshold > 15)
133 } else { 129 bs.bs_bmissthreshold = 15;
134 bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval); 130 else if (bs.bs_bmissthreshold <= 0)
135 if (bs.bs_bmissthreshold > 15) 131 bs.bs_bmissthreshold = 1;
136 bs.bs_bmissthreshold = 15;
137 else if (bs.bs_bmissthreshold <= 0)
138 bs.bs_bmissthreshold = 1;
139 }
140 132
141 /* 133 /*
142 * Calculate sleep duration. The configuration is given in ms. 134 * Calculate sleep duration. The configuration is given in ms.
@@ -148,7 +140,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
148 */ 140 */
149 141
150 bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100), 142 bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
151 sleepduration)); 143 intval));
152 if (bs.bs_sleepduration > bs.bs_dtimperiod) 144 if (bs.bs_sleepduration > bs.bs_dtimperiod)
153 bs.bs_sleepduration = bs.bs_dtimperiod; 145 bs.bs_sleepduration = bs.bs_dtimperiod;
154 146
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 8d0b9bcb47b4..b22fb64403d9 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -38,93 +38,6 @@ static int ath9k_ps_enable;
38module_param_named(ps_enable, ath9k_ps_enable, int, 0444); 38module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
39MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); 39MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
40 40
41#define CHAN2G(_freq, _idx) { \
42 .center_freq = (_freq), \
43 .hw_value = (_idx), \
44 .max_power = 20, \
45}
46
47#define CHAN5G(_freq, _idx) { \
48 .band = IEEE80211_BAND_5GHZ, \
49 .center_freq = (_freq), \
50 .hw_value = (_idx), \
51 .max_power = 20, \
52}
53
54static struct ieee80211_channel ath9k_2ghz_channels[] = {
55 CHAN2G(2412, 0), /* Channel 1 */
56 CHAN2G(2417, 1), /* Channel 2 */
57 CHAN2G(2422, 2), /* Channel 3 */
58 CHAN2G(2427, 3), /* Channel 4 */
59 CHAN2G(2432, 4), /* Channel 5 */
60 CHAN2G(2437, 5), /* Channel 6 */
61 CHAN2G(2442, 6), /* Channel 7 */
62 CHAN2G(2447, 7), /* Channel 8 */
63 CHAN2G(2452, 8), /* Channel 9 */
64 CHAN2G(2457, 9), /* Channel 10 */
65 CHAN2G(2462, 10), /* Channel 11 */
66 CHAN2G(2467, 11), /* Channel 12 */
67 CHAN2G(2472, 12), /* Channel 13 */
68 CHAN2G(2484, 13), /* Channel 14 */
69};
70
71static struct ieee80211_channel ath9k_5ghz_channels[] = {
72 /* _We_ call this UNII 1 */
73 CHAN5G(5180, 14), /* Channel 36 */
74 CHAN5G(5200, 15), /* Channel 40 */
75 CHAN5G(5220, 16), /* Channel 44 */
76 CHAN5G(5240, 17), /* Channel 48 */
77 /* _We_ call this UNII 2 */
78 CHAN5G(5260, 18), /* Channel 52 */
79 CHAN5G(5280, 19), /* Channel 56 */
80 CHAN5G(5300, 20), /* Channel 60 */
81 CHAN5G(5320, 21), /* Channel 64 */
82 /* _We_ call this "Middle band" */
83 CHAN5G(5500, 22), /* Channel 100 */
84 CHAN5G(5520, 23), /* Channel 104 */
85 CHAN5G(5540, 24), /* Channel 108 */
86 CHAN5G(5560, 25), /* Channel 112 */
87 CHAN5G(5580, 26), /* Channel 116 */
88 CHAN5G(5600, 27), /* Channel 120 */
89 CHAN5G(5620, 28), /* Channel 124 */
90 CHAN5G(5640, 29), /* Channel 128 */
91 CHAN5G(5660, 30), /* Channel 132 */
92 CHAN5G(5680, 31), /* Channel 136 */
93 CHAN5G(5700, 32), /* Channel 140 */
94 /* _We_ call this UNII 3 */
95 CHAN5G(5745, 33), /* Channel 149 */
96 CHAN5G(5765, 34), /* Channel 153 */
97 CHAN5G(5785, 35), /* Channel 157 */
98 CHAN5G(5805, 36), /* Channel 161 */
99 CHAN5G(5825, 37), /* Channel 165 */
100};
101
102/* Atheros hardware rate code addition for short premble */
103#define SHPCHECK(__hw_rate, __flags) \
104 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0)
105
106#define RATE(_bitrate, _hw_rate, _flags) { \
107 .bitrate = (_bitrate), \
108 .flags = (_flags), \
109 .hw_value = (_hw_rate), \
110 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
111}
112
113static struct ieee80211_rate ath9k_legacy_rates[] = {
114 RATE(10, 0x1b, 0),
115 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */
116 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */
117 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */
118 RATE(60, 0x0b, 0),
119 RATE(90, 0x0f, 0),
120 RATE(120, 0x0a, 0),
121 RATE(180, 0x0e, 0),
122 RATE(240, 0x09, 0),
123 RATE(360, 0x0d, 0),
124 RATE(480, 0x08, 0),
125 RATE(540, 0x0c, 0),
126};
127
128#ifdef CONFIG_MAC80211_LEDS 41#ifdef CONFIG_MAC80211_LEDS
129static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { 42static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
130 { .throughput = 0 * 1024, .blink_time = 334 }, 43 { .throughput = 0 * 1024, .blink_time = 334 },
@@ -343,6 +256,25 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr,
343 } 256 }
344} 257}
345 258
259static void ath9k_regwrite_multi(struct ath_common *common)
260{
261 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
262 u32 rsp_status;
263 int r;
264
265 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
266 (u8 *) &priv->wmi->multi_write,
267 sizeof(struct register_write) * priv->wmi->multi_write_idx,
268 (u8 *) &rsp_status, sizeof(rsp_status),
269 100);
270 if (unlikely(r)) {
271 ath_dbg(common, WMI,
272 "REGISTER WRITE FAILED, multi len: %d\n",
273 priv->wmi->multi_write_idx);
274 }
275 priv->wmi->multi_write_idx = 0;
276}
277
346static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) 278static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
347{ 279{
348 struct ath_hw *ah = (struct ath_hw *) hw_priv; 280 struct ath_hw *ah = (struct ath_hw *) hw_priv;
@@ -369,8 +301,6 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
369 struct ath_hw *ah = (struct ath_hw *) hw_priv; 301 struct ath_hw *ah = (struct ath_hw *) hw_priv;
370 struct ath_common *common = ath9k_hw_common(ah); 302 struct ath_common *common = ath9k_hw_common(ah);
371 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; 303 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
372 u32 rsp_status;
373 int r;
374 304
375 mutex_lock(&priv->wmi->multi_write_mutex); 305 mutex_lock(&priv->wmi->multi_write_mutex);
376 306
@@ -383,19 +313,8 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
383 priv->wmi->multi_write_idx++; 313 priv->wmi->multi_write_idx++;
384 314
385 /* If the buffer is full, send it out. */ 315 /* If the buffer is full, send it out. */
386 if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER) { 316 if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER)
387 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID, 317 ath9k_regwrite_multi(common);
388 (u8 *) &priv->wmi->multi_write,
389 sizeof(struct register_write) * priv->wmi->multi_write_idx,
390 (u8 *) &rsp_status, sizeof(rsp_status),
391 100);
392 if (unlikely(r)) {
393 ath_dbg(common, WMI,
394 "REGISTER WRITE FAILED, multi len: %d\n",
395 priv->wmi->multi_write_idx);
396 }
397 priv->wmi->multi_write_idx = 0;
398 }
399 318
400 mutex_unlock(&priv->wmi->multi_write_mutex); 319 mutex_unlock(&priv->wmi->multi_write_mutex);
401} 320}
@@ -426,26 +345,13 @@ static void ath9k_regwrite_flush(void *hw_priv)
426 struct ath_hw *ah = (struct ath_hw *) hw_priv; 345 struct ath_hw *ah = (struct ath_hw *) hw_priv;
427 struct ath_common *common = ath9k_hw_common(ah); 346 struct ath_common *common = ath9k_hw_common(ah);
428 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; 347 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
429 u32 rsp_status;
430 int r;
431 348
432 atomic_dec(&priv->wmi->mwrite_cnt); 349 atomic_dec(&priv->wmi->mwrite_cnt);
433 350
434 mutex_lock(&priv->wmi->multi_write_mutex); 351 mutex_lock(&priv->wmi->multi_write_mutex);
435 352
436 if (priv->wmi->multi_write_idx) { 353 if (priv->wmi->multi_write_idx)
437 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID, 354 ath9k_regwrite_multi(common);
438 (u8 *) &priv->wmi->multi_write,
439 sizeof(struct register_write) * priv->wmi->multi_write_idx,
440 (u8 *) &rsp_status, sizeof(rsp_status),
441 100);
442 if (unlikely(r)) {
443 ath_dbg(common, WMI,
444 "REGISTER WRITE FAILED, multi len: %d\n",
445 priv->wmi->multi_write_idx);
446 }
447 priv->wmi->multi_write_idx = 0;
448 }
449 355
450 mutex_unlock(&priv->wmi->multi_write_mutex); 356 mutex_unlock(&priv->wmi->multi_write_mutex);
451} 357}
@@ -491,51 +397,6 @@ static const struct ath_bus_ops ath9k_usb_bus_ops = {
491 .eeprom_read = ath_usb_eeprom_read, 397 .eeprom_read = ath_usb_eeprom_read,
492}; 398};
493 399
494static void setup_ht_cap(struct ath9k_htc_priv *priv,
495 struct ieee80211_sta_ht_cap *ht_info)
496{
497 struct ath_common *common = ath9k_hw_common(priv->ah);
498 u8 tx_streams, rx_streams;
499 int i;
500
501 ht_info->ht_supported = true;
502 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
503 IEEE80211_HT_CAP_SM_PS |
504 IEEE80211_HT_CAP_SGI_40 |
505 IEEE80211_HT_CAP_DSSSCCK40;
506
507 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
508 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
509
510 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
511
512 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
513 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
514
515 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
516
517 /* ath9k_htc supports only 1 or 2 stream devices */
518 tx_streams = ath9k_cmn_count_streams(priv->ah->txchainmask, 2);
519 rx_streams = ath9k_cmn_count_streams(priv->ah->rxchainmask, 2);
520
521 ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n",
522 tx_streams, rx_streams);
523
524 if (tx_streams >= 2)
525 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
526
527 if (tx_streams != rx_streams) {
528 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
529 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
530 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
531 }
532
533 for (i = 0; i < rx_streams; i++)
534 ht_info->mcs.rx_mask[i] = 0xff;
535
536 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
537}
538
539static int ath9k_init_queues(struct ath9k_htc_priv *priv) 400static int ath9k_init_queues(struct ath9k_htc_priv *priv)
540{ 401{
541 struct ath_common *common = ath9k_hw_common(priv->ah); 402 struct ath_common *common = ath9k_hw_common(priv->ah);
@@ -580,31 +441,6 @@ err:
580 return -EINVAL; 441 return -EINVAL;
581} 442}
582 443
583static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
584{
585 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
586 priv->sbands[IEEE80211_BAND_2GHZ].channels =
587 ath9k_2ghz_channels;
588 priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
589 priv->sbands[IEEE80211_BAND_2GHZ].n_channels =
590 ARRAY_SIZE(ath9k_2ghz_channels);
591 priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
592 priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
593 ARRAY_SIZE(ath9k_legacy_rates);
594 }
595
596 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
597 priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels;
598 priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
599 priv->sbands[IEEE80211_BAND_5GHZ].n_channels =
600 ARRAY_SIZE(ath9k_5ghz_channels);
601 priv->sbands[IEEE80211_BAND_5GHZ].bitrates =
602 ath9k_legacy_rates + 4;
603 priv->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
604 ARRAY_SIZE(ath9k_legacy_rates) - 4;
605 }
606}
607
608static void ath9k_init_misc(struct ath9k_htc_priv *priv) 444static void ath9k_init_misc(struct ath9k_htc_priv *priv)
609{ 445{
610 struct ath_common *common = ath9k_hw_common(priv->ah); 446 struct ath_common *common = ath9k_hw_common(priv->ah);
@@ -629,6 +465,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
629 if (!ah) 465 if (!ah)
630 return -ENOMEM; 466 return -ENOMEM;
631 467
468 ah->dev = priv->dev;
632 ah->hw_version.devid = devid; 469 ah->hw_version.devid = devid;
633 ah->hw_version.usbdev = drv_info; 470 ah->hw_version.usbdev = drv_info;
634 ah->ah_flags |= AH_USE_EEPROM; 471 ah->ah_flags |= AH_USE_EEPROM;
@@ -685,8 +522,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
685 for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) 522 for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
686 priv->cur_beacon_conf.bslot[i] = NULL; 523 priv->cur_beacon_conf.bslot[i] = NULL;
687 524
525 ath9k_cmn_init_channels_rates(common);
688 ath9k_cmn_init_crypto(ah); 526 ath9k_cmn_init_crypto(ah);
689 ath9k_init_channels_rates(priv);
690 ath9k_init_misc(priv); 527 ath9k_init_misc(priv);
691 ath9k_htc_init_btcoex(priv, product); 528 ath9k_htc_init_btcoex(priv, product);
692 529
@@ -722,6 +559,7 @@ static const struct ieee80211_iface_combination if_comb = {
722static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, 559static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
723 struct ieee80211_hw *hw) 560 struct ieee80211_hw *hw)
724{ 561{
562 struct ath_hw *ah = priv->ah;
725 struct ath_common *common = ath9k_hw_common(priv->ah); 563 struct ath_common *common = ath9k_hw_common(priv->ah);
726 struct base_eep_header *pBase; 564 struct base_eep_header *pBase;
727 565
@@ -766,19 +604,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
766 604
767 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) 605 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
768 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 606 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
769 &priv->sbands[IEEE80211_BAND_2GHZ]; 607 &common->sbands[IEEE80211_BAND_2GHZ];
770 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) 608 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
771 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 609 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
772 &priv->sbands[IEEE80211_BAND_5GHZ]; 610 &common->sbands[IEEE80211_BAND_5GHZ];
773 611
774 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) { 612 ath9k_cmn_reload_chainmask(ah);
775 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
776 setup_ht_cap(priv,
777 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
778 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
779 setup_ht_cap(priv,
780 &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
781 }
782 613
783 pBase = ath9k_htc_get_eeprom_base(priv); 614 pBase = ath9k_htc_get_eeprom_base(priv);
784 if (pBase) { 615 if (pBase) {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 07a0315dd2f6..c0a4e866edca 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -62,111 +62,6 @@ module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
62MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); 62MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
63 63
64bool is_ath9k_unloaded; 64bool is_ath9k_unloaded;
65/* We use the hw_value as an index into our private channel structure */
66
67#define CHAN2G(_freq, _idx) { \
68 .band = IEEE80211_BAND_2GHZ, \
69 .center_freq = (_freq), \
70 .hw_value = (_idx), \
71 .max_power = 20, \
72}
73
74#define CHAN5G(_freq, _idx) { \
75 .band = IEEE80211_BAND_5GHZ, \
76 .center_freq = (_freq), \
77 .hw_value = (_idx), \
78 .max_power = 20, \
79}
80
81/* Some 2 GHz radios are actually tunable on 2312-2732
82 * on 5 MHz steps, we support the channels which we know
83 * we have calibration data for all cards though to make
84 * this static */
85static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
86 CHAN2G(2412, 0), /* Channel 1 */
87 CHAN2G(2417, 1), /* Channel 2 */
88 CHAN2G(2422, 2), /* Channel 3 */
89 CHAN2G(2427, 3), /* Channel 4 */
90 CHAN2G(2432, 4), /* Channel 5 */
91 CHAN2G(2437, 5), /* Channel 6 */
92 CHAN2G(2442, 6), /* Channel 7 */
93 CHAN2G(2447, 7), /* Channel 8 */
94 CHAN2G(2452, 8), /* Channel 9 */
95 CHAN2G(2457, 9), /* Channel 10 */
96 CHAN2G(2462, 10), /* Channel 11 */
97 CHAN2G(2467, 11), /* Channel 12 */
98 CHAN2G(2472, 12), /* Channel 13 */
99 CHAN2G(2484, 13), /* Channel 14 */
100};
101
102/* Some 5 GHz radios are actually tunable on XXXX-YYYY
103 * on 5 MHz steps, we support the channels which we know
104 * we have calibration data for all cards though to make
105 * this static */
106static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
107 /* _We_ call this UNII 1 */
108 CHAN5G(5180, 14), /* Channel 36 */
109 CHAN5G(5200, 15), /* Channel 40 */
110 CHAN5G(5220, 16), /* Channel 44 */
111 CHAN5G(5240, 17), /* Channel 48 */
112 /* _We_ call this UNII 2 */
113 CHAN5G(5260, 18), /* Channel 52 */
114 CHAN5G(5280, 19), /* Channel 56 */
115 CHAN5G(5300, 20), /* Channel 60 */
116 CHAN5G(5320, 21), /* Channel 64 */
117 /* _We_ call this "Middle band" */
118 CHAN5G(5500, 22), /* Channel 100 */
119 CHAN5G(5520, 23), /* Channel 104 */
120 CHAN5G(5540, 24), /* Channel 108 */
121 CHAN5G(5560, 25), /* Channel 112 */
122 CHAN5G(5580, 26), /* Channel 116 */
123 CHAN5G(5600, 27), /* Channel 120 */
124 CHAN5G(5620, 28), /* Channel 124 */
125 CHAN5G(5640, 29), /* Channel 128 */
126 CHAN5G(5660, 30), /* Channel 132 */
127 CHAN5G(5680, 31), /* Channel 136 */
128 CHAN5G(5700, 32), /* Channel 140 */
129 /* _We_ call this UNII 3 */
130 CHAN5G(5745, 33), /* Channel 149 */
131 CHAN5G(5765, 34), /* Channel 153 */
132 CHAN5G(5785, 35), /* Channel 157 */
133 CHAN5G(5805, 36), /* Channel 161 */
134 CHAN5G(5825, 37), /* Channel 165 */
135};
136
137/* Atheros hardware rate code addition for short premble */
138#define SHPCHECK(__hw_rate, __flags) \
139 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
140
141#define RATE(_bitrate, _hw_rate, _flags) { \
142 .bitrate = (_bitrate), \
143 .flags = (_flags), \
144 .hw_value = (_hw_rate), \
145 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
146}
147
148static struct ieee80211_rate ath9k_legacy_rates[] = {
149 RATE(10, 0x1b, 0),
150 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
151 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
152 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
153 RATE(60, 0x0b, (IEEE80211_RATE_SUPPORTS_5MHZ |
154 IEEE80211_RATE_SUPPORTS_10MHZ)),
155 RATE(90, 0x0f, (IEEE80211_RATE_SUPPORTS_5MHZ |
156 IEEE80211_RATE_SUPPORTS_10MHZ)),
157 RATE(120, 0x0a, (IEEE80211_RATE_SUPPORTS_5MHZ |
158 IEEE80211_RATE_SUPPORTS_10MHZ)),
159 RATE(180, 0x0e, (IEEE80211_RATE_SUPPORTS_5MHZ |
160 IEEE80211_RATE_SUPPORTS_10MHZ)),
161 RATE(240, 0x09, (IEEE80211_RATE_SUPPORTS_5MHZ |
162 IEEE80211_RATE_SUPPORTS_10MHZ)),
163 RATE(360, 0x0d, (IEEE80211_RATE_SUPPORTS_5MHZ |
164 IEEE80211_RATE_SUPPORTS_10MHZ)),
165 RATE(480, 0x08, (IEEE80211_RATE_SUPPORTS_5MHZ |
166 IEEE80211_RATE_SUPPORTS_10MHZ)),
167 RATE(540, 0x0c, (IEEE80211_RATE_SUPPORTS_5MHZ |
168 IEEE80211_RATE_SUPPORTS_10MHZ)),
169};
170 65
171#ifdef CONFIG_MAC80211_LEDS 66#ifdef CONFIG_MAC80211_LEDS
172static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { 67static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
@@ -258,64 +153,6 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl
258/* Initialization */ 153/* Initialization */
259/**************************/ 154/**************************/
260 155
261static void setup_ht_cap(struct ath_softc *sc,
262 struct ieee80211_sta_ht_cap *ht_info)
263{
264 struct ath_hw *ah = sc->sc_ah;
265 struct ath_common *common = ath9k_hw_common(ah);
266 u8 tx_streams, rx_streams;
267 int i, max_streams;
268
269 ht_info->ht_supported = true;
270 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
271 IEEE80211_HT_CAP_SM_PS |
272 IEEE80211_HT_CAP_SGI_40 |
273 IEEE80211_HT_CAP_DSSSCCK40;
274
275 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
276 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
277
278 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
279 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
280
281 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
282 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
283
284 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah))
285 max_streams = 1;
286 else if (AR_SREV_9462(ah))
287 max_streams = 2;
288 else if (AR_SREV_9300_20_OR_LATER(ah))
289 max_streams = 3;
290 else
291 max_streams = 2;
292
293 if (AR_SREV_9280_20_OR_LATER(ah)) {
294 if (max_streams >= 2)
295 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
296 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
297 }
298
299 /* set up supported mcs set */
300 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
301 tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams);
302 rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams);
303
304 ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n",
305 tx_streams, rx_streams);
306
307 if (tx_streams != rx_streams) {
308 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
309 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
310 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
311 }
312
313 for (i = 0; i < rx_streams; i++)
314 ht_info->mcs.rx_mask[i] = 0xff;
315
316 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
317}
318
319static void ath9k_reg_notifier(struct wiphy *wiphy, 156static void ath9k_reg_notifier(struct wiphy *wiphy,
320 struct regulatory_request *request) 157 struct regulatory_request *request)
321{ 158{
@@ -486,51 +323,6 @@ static int ath9k_init_queues(struct ath_softc *sc)
486 return 0; 323 return 0;
487} 324}
488 325
489static int ath9k_init_channels_rates(struct ath_softc *sc)
490{
491 void *channels;
492
493 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
494 ARRAY_SIZE(ath9k_5ghz_chantable) !=
495 ATH9K_NUM_CHANNELS);
496
497 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
498 channels = devm_kzalloc(sc->dev,
499 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
500 if (!channels)
501 return -ENOMEM;
502
503 memcpy(channels, ath9k_2ghz_chantable,
504 sizeof(ath9k_2ghz_chantable));
505 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
506 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
507 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
508 ARRAY_SIZE(ath9k_2ghz_chantable);
509 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
510 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
511 ARRAY_SIZE(ath9k_legacy_rates);
512 }
513
514 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
515 channels = devm_kzalloc(sc->dev,
516 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
517 if (!channels)
518 return -ENOMEM;
519
520 memcpy(channels, ath9k_5ghz_chantable,
521 sizeof(ath9k_5ghz_chantable));
522 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
523 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
524 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
525 ARRAY_SIZE(ath9k_5ghz_chantable);
526 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
527 ath9k_legacy_rates + 4;
528 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
529 ARRAY_SIZE(ath9k_legacy_rates) - 4;
530 }
531 return 0;
532}
533
534static void ath9k_init_misc(struct ath_softc *sc) 326static void ath9k_init_misc(struct ath_softc *sc)
535{ 327{
536 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 328 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -793,7 +585,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
793 if (ret) 585 if (ret)
794 goto err_btcoex; 586 goto err_btcoex;
795 587
796 ret = ath9k_init_channels_rates(sc); 588 ret = ath9k_cmn_init_channels_rates(common);
797 if (ret) 589 if (ret)
798 goto err_btcoex; 590 goto err_btcoex;
799 591
@@ -823,10 +615,11 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
823 struct ieee80211_supported_band *sband; 615 struct ieee80211_supported_band *sband;
824 struct ieee80211_channel *chan; 616 struct ieee80211_channel *chan;
825 struct ath_hw *ah = sc->sc_ah; 617 struct ath_hw *ah = sc->sc_ah;
618 struct ath_common *common = ath9k_hw_common(ah);
826 struct cfg80211_chan_def chandef; 619 struct cfg80211_chan_def chandef;
827 int i; 620 int i;
828 621
829 sband = &sc->sbands[band]; 622 sband = &common->sbands[band];
830 for (i = 0; i < sband->n_channels; i++) { 623 for (i = 0; i < sband->n_channels; i++) {
831 chan = &sband->channels[i]; 624 chan = &sband->channels[i];
832 ah->curchan = &ah->channels[chan->hw_value]; 625 ah->curchan = &ah->channels[chan->hw_value];
@@ -849,17 +642,6 @@ static void ath9k_init_txpower_limits(struct ath_softc *sc)
849 ah->curchan = curchan; 642 ah->curchan = curchan;
850} 643}
851 644
852void ath9k_reload_chainmask_settings(struct ath_softc *sc)
853{
854 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT))
855 return;
856
857 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
858 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
859 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
860 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
861}
862
863static const struct ieee80211_iface_limit if_limits[] = { 645static const struct ieee80211_iface_limit if_limits[] = {
864 { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | 646 { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
865 BIT(NL80211_IFTYPE_P2P_CLIENT) | 647 BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -949,6 +731,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
949 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 731 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
950 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; 732 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
951 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; 733 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
734 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
952 735
953 hw->queues = 4; 736 hw->queues = 4;
954 hw->max_rates = 4; 737 hw->max_rates = 4;
@@ -969,13 +752,13 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
969 752
970 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) 753 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
971 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 754 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
972 &sc->sbands[IEEE80211_BAND_2GHZ]; 755 &common->sbands[IEEE80211_BAND_2GHZ];
973 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) 756 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
974 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 757 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
975 &sc->sbands[IEEE80211_BAND_5GHZ]; 758 &common->sbands[IEEE80211_BAND_5GHZ];
976 759
977 ath9k_init_wow(hw); 760 ath9k_init_wow(hw);
978 ath9k_reload_chainmask_settings(sc); 761 ath9k_cmn_reload_chainmask(ah);
979 762
980 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); 763 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
981} 764}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index afce549a097b..42a18037004e 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -451,7 +451,7 @@ void ath9k_tasklet(unsigned long data)
451 * interrupts are enabled in the reset routine. 451 * interrupts are enabled in the reset routine.
452 */ 452 */
453 atomic_inc(&ah->intr_ref_cnt); 453 atomic_inc(&ah->intr_ref_cnt);
454 ath_dbg(common, ANY, "FATAL: Skipping interrupts\n"); 454 ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
455 goto out; 455 goto out;
456 } 456 }
457 457
@@ -471,7 +471,7 @@ void ath9k_tasklet(unsigned long data)
471 * interrupts are enabled in the reset routine. 471 * interrupts are enabled in the reset routine.
472 */ 472 */
473 atomic_inc(&ah->intr_ref_cnt); 473 atomic_inc(&ah->intr_ref_cnt);
474 ath_dbg(common, ANY, 474 ath_dbg(common, RESET,
475 "BB_WATCHDOG: Skipping interrupts\n"); 475 "BB_WATCHDOG: Skipping interrupts\n");
476 goto out; 476 goto out;
477 } 477 }
@@ -484,7 +484,7 @@ void ath9k_tasklet(unsigned long data)
484 type = RESET_TYPE_TX_GTT; 484 type = RESET_TYPE_TX_GTT;
485 ath9k_queue_reset(sc, type); 485 ath9k_queue_reset(sc, type);
486 atomic_inc(&ah->intr_ref_cnt); 486 atomic_inc(&ah->intr_ref_cnt);
487 ath_dbg(common, ANY, 487 ath_dbg(common, RESET,
488 "GTT: Skipping interrupts\n"); 488 "GTT: Skipping interrupts\n");
489 goto out; 489 goto out;
490 } 490 }
@@ -2053,7 +2053,7 @@ static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
2053 ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant); 2053 ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant);
2054 2054
2055 ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant); 2055 ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant);
2056 ath9k_reload_chainmask_settings(sc); 2056 ath9k_cmn_reload_chainmask(ah);
2057 2057
2058 return 0; 2058 return 0;
2059} 2059}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 425e34f94af4..6c9accdb52e4 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -871,8 +871,16 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
871 if (WARN_ON(!ah->curchan)) 871 if (WARN_ON(!ah->curchan))
872 return -EINVAL; 872 return -EINVAL;
873 873
874 if (ath9k_cmn_process_rate(common, hw, rx_stats, rx_status)) 874 if (ath9k_cmn_process_rate(common, hw, rx_stats, rx_status)) {
875 /*
876 * No valid hardware bitrate found -- we should not get here
877 * because hardware has already validated this frame as OK.
878 */
879 ath_dbg(common, ANY, "unsupported hw bitrate detected 0x%02x using 1 Mbit\n",
880 rx_stats->rs_rate);
881 RX_STAT_INC(rx_rate_err);
875 return -EINVAL; 882 return -EINVAL;
883 }
876 884
877 ath9k_cmn_process_rssi(common, hw, rx_stats, rx_status); 885 ath9k_cmn_process_rssi(common, hw, rx_stats, rx_status);
878 886
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 312314ce7642..fafacfed44ea 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1040,11 +1040,11 @@ static int ath_max_framelen(int usec, int mcs, bool ht40, bool sgi)
1040 int symbols, bits; 1040 int symbols, bits;
1041 int bytes = 0; 1041 int bytes = 0;
1042 1042
1043 usec -= L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
1043 symbols = sgi ? TIME_SYMBOLS_HALFGI(usec) : TIME_SYMBOLS(usec); 1044 symbols = sgi ? TIME_SYMBOLS_HALFGI(usec) : TIME_SYMBOLS(usec);
1044 bits = symbols * bits_per_symbol[mcs % 8][ht40] * streams; 1045 bits = symbols * bits_per_symbol[mcs % 8][ht40] * streams;
1045 bits -= OFDM_PLCP_BITS; 1046 bits -= OFDM_PLCP_BITS;
1046 bytes = bits / 8; 1047 bytes = bits / 8;
1047 bytes -= L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
1048 if (bytes > 65532) 1048 if (bytes > 65532)
1049 bytes = 65532; 1049 bytes = 65532;
1050 1050
@@ -1076,6 +1076,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1076 struct ath_tx_info *info, int len, bool rts) 1076 struct ath_tx_info *info, int len, bool rts)
1077{ 1077{
1078 struct ath_hw *ah = sc->sc_ah; 1078 struct ath_hw *ah = sc->sc_ah;
1079 struct ath_common *common = ath9k_hw_common(ah);
1079 struct sk_buff *skb; 1080 struct sk_buff *skb;
1080 struct ieee80211_tx_info *tx_info; 1081 struct ieee80211_tx_info *tx_info;
1081 struct ieee80211_tx_rate *rates; 1082 struct ieee80211_tx_rate *rates;
@@ -1145,7 +1146,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1145 } 1146 }
1146 1147
1147 /* legacy rates */ 1148 /* legacy rates */
1148 rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; 1149 rate = &common->sbands[tx_info->band].bitrates[rates[i].idx];
1149 if ((tx_info->band == IEEE80211_BAND_2GHZ) && 1150 if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
1150 !(rate->flags & IEEE80211_RATE_ERP_G)) 1151 !(rate->flags & IEEE80211_RATE_ERP_G))
1151 phy = WLAN_RC_PHY_CCK; 1152 phy = WLAN_RC_PHY_CCK;
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index e5e905910db4..415393dfb6fc 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -222,7 +222,7 @@ static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
222static const struct 222static const struct
223ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) 223ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
224{ 224{
225 switch (reg->regpair->regDmnEnum) { 225 switch (reg->regpair->reg_domain) {
226 case 0x60: 226 case 0x60:
227 case 0x61: 227 case 0x61:
228 case 0x62: 228 case 0x62:
@@ -431,7 +431,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
431 enum nl80211_reg_initiator initiator, 431 enum nl80211_reg_initiator initiator,
432 struct ath_regulatory *reg) 432 struct ath_regulatory *reg)
433{ 433{
434 switch (reg->regpair->regDmnEnum) { 434 switch (reg->regpair->reg_domain) {
435 case 0x60: 435 case 0x60:
436 case 0x63: 436 case 0x63:
437 case 0x66: 437 case 0x66:
@@ -560,7 +560,7 @@ static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
560 printk(KERN_DEBUG "ath: EEPROM indicates we " 560 printk(KERN_DEBUG "ath: EEPROM indicates we "
561 "should expect a direct regpair map\n"); 561 "should expect a direct regpair map\n");
562 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) 562 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
563 if (regDomainPairs[i].regDmnEnum == rd) 563 if (regDomainPairs[i].reg_domain == rd)
564 return true; 564 return true;
565 } 565 }
566 printk(KERN_DEBUG 566 printk(KERN_DEBUG
@@ -617,7 +617,7 @@ ath_get_regpair(int regdmn)
617 if (regdmn == NO_ENUMRD) 617 if (regdmn == NO_ENUMRD)
618 return NULL; 618 return NULL;
619 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { 619 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
620 if (regDomainPairs[i].regDmnEnum == regdmn) 620 if (regDomainPairs[i].reg_domain == regdmn)
621 return &regDomainPairs[i]; 621 return &regDomainPairs[i];
622 } 622 }
623 return NULL; 623 return NULL;
@@ -741,7 +741,7 @@ static int __ath_regd_init(struct ath_regulatory *reg)
741 printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", 741 printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
742 reg->alpha2[0], reg->alpha2[1]); 742 reg->alpha2[0], reg->alpha2[1]);
743 printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n", 743 printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
744 reg->regpair->regDmnEnum); 744 reg->regpair->reg_domain);
745 745
746 return 0; 746 return 0;
747} 747}
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile
index 990dd42ae79e..c7a3465fd02a 100644
--- a/drivers/net/wireless/ath/wil6210/Makefile
+++ b/drivers/net/wireless/ath/wil6210/Makefile
@@ -9,6 +9,7 @@ wil6210-y += wmi.o
9wil6210-y += interrupt.o 9wil6210-y += interrupt.o
10wil6210-y += txrx.o 10wil6210-y += txrx.o
11wil6210-y += debug.o 11wil6210-y += debug.o
12wil6210-y += rx_reorder.o
12wil6210-$(CONFIG_WIL6210_TRACING) += trace.o 13wil6210-$(CONFIG_WIL6210_TRACING) += trace.o
13 14
14# for tracing framework to find trace.h 15# for tracing framework to find trace.h
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 5b340769d5bb..743930357061 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -104,41 +104,125 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)
104 return -EOPNOTSUPP; 104 return -EOPNOTSUPP;
105} 105}
106 106
107static int wil_cfg80211_get_station(struct wiphy *wiphy, 107static int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
108 struct net_device *ndev, 108 struct station_info *sinfo)
109 u8 *mac, struct station_info *sinfo)
110{ 109{
111 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
112 int rc;
113 struct wmi_notify_req_cmd cmd = { 110 struct wmi_notify_req_cmd cmd = {
114 .cid = 0, 111 .cid = cid,
115 .interval_usec = 0, 112 .interval_usec = 0,
116 }; 113 };
114 struct {
115 struct wil6210_mbox_hdr_wmi wmi;
116 struct wmi_notify_req_done_event evt;
117 } __packed reply;
118 struct wil_net_stats *stats = &wil->sta[cid].stats;
119 int rc;
117 120
118 if (memcmp(mac, wil->dst_addr[0], ETH_ALEN))
119 return -ENOENT;
120
121 /* WMI_NOTIFY_REQ_DONE_EVENTID handler fills wil->stats.bf_mcs */
122 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd), 121 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
123 WMI_NOTIFY_REQ_DONE_EVENTID, NULL, 0, 20); 122 WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
124 if (rc) 123 if (rc)
125 return rc; 124 return rc;
126 125
126 wil_dbg_wmi(wil, "Link status for CID %d: {\n"
127 " MCS %d TSF 0x%016llx\n"
128 " BF status 0x%08x SNR 0x%08x SQI %d%%\n"
129 " Tx Tpt %d goodput %d Rx goodput %d\n"
130 " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
131 cid, le16_to_cpu(reply.evt.bf_mcs),
132 le64_to_cpu(reply.evt.tsf), reply.evt.status,
133 le32_to_cpu(reply.evt.snr_val),
134 reply.evt.sqi,
135 le32_to_cpu(reply.evt.tx_tpt),
136 le32_to_cpu(reply.evt.tx_goodput),
137 le32_to_cpu(reply.evt.rx_goodput),
138 le16_to_cpu(reply.evt.my_rx_sector),
139 le16_to_cpu(reply.evt.my_tx_sector),
140 le16_to_cpu(reply.evt.other_rx_sector),
141 le16_to_cpu(reply.evt.other_tx_sector));
142
127 sinfo->generation = wil->sinfo_gen; 143 sinfo->generation = wil->sinfo_gen;
128 144
129 sinfo->filled |= STATION_INFO_TX_BITRATE; 145 sinfo->filled = STATION_INFO_RX_BYTES |
146 STATION_INFO_TX_BYTES |
147 STATION_INFO_RX_PACKETS |
148 STATION_INFO_TX_PACKETS |
149 STATION_INFO_RX_BITRATE |
150 STATION_INFO_TX_BITRATE |
151 STATION_INFO_RX_DROP_MISC |
152 STATION_INFO_TX_FAILED;
153
130 sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; 154 sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
131 sinfo->txrate.mcs = wil->stats.bf_mcs; 155 sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
132 sinfo->filled |= STATION_INFO_RX_BITRATE;
133 sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; 156 sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
134 sinfo->rxrate.mcs = wil->stats.last_mcs_rx; 157 sinfo->rxrate.mcs = stats->last_mcs_rx;
158 sinfo->rx_bytes = stats->rx_bytes;
159 sinfo->rx_packets = stats->rx_packets;
160 sinfo->rx_dropped_misc = stats->rx_dropped;
161 sinfo->tx_bytes = stats->tx_bytes;
162 sinfo->tx_packets = stats->tx_packets;
163 sinfo->tx_failed = stats->tx_errors;
135 164
136 if (test_bit(wil_status_fwconnected, &wil->status)) { 165 if (test_bit(wil_status_fwconnected, &wil->status)) {
137 sinfo->filled |= STATION_INFO_SIGNAL; 166 sinfo->filled |= STATION_INFO_SIGNAL;
138 sinfo->signal = 12; /* TODO: provide real value */ 167 sinfo->signal = reply.evt.sqi;
139 } 168 }
140 169
141 return 0; 170 return rc;
171}
172
173static int wil_cfg80211_get_station(struct wiphy *wiphy,
174 struct net_device *ndev,
175 u8 *mac, struct station_info *sinfo)
176{
177 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
178 int rc;
179
180 int cid = wil_find_cid(wil, mac);
181
182 wil_info(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
183 if (cid < 0)
184 return cid;
185
186 rc = wil_cid_fill_sinfo(wil, cid, sinfo);
187
188 return rc;
189}
190
191/*
192 * Find @idx-th active STA for station dump.
193 */
194static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx)
195{
196 int i;
197
198 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
199 if (wil->sta[i].status == wil_sta_unused)
200 continue;
201 if (idx == 0)
202 return i;
203 idx--;
204 }
205
206 return -ENOENT;
207}
208
209static int wil_cfg80211_dump_station(struct wiphy *wiphy,
210 struct net_device *dev, int idx,
211 u8 *mac, struct station_info *sinfo)
212{
213 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
214 int rc;
215 int cid = wil_find_cid_by_idx(wil, idx);
216
217 if (cid < 0)
218 return -ENOENT;
219
220 memcpy(mac, wil->sta[cid].addr, ETH_ALEN);
221 wil_info(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
222
223 rc = wil_cid_fill_sinfo(wil, cid, sinfo);
224
225 return rc;
142} 226}
143 227
144static int wil_cfg80211_change_iface(struct wiphy *wiphy, 228static int wil_cfg80211_change_iface(struct wiphy *wiphy,
@@ -352,6 +436,40 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
352 return rc; 436 return rc;
353} 437}
354 438
439static int wil_cfg80211_mgmt_tx(struct wiphy *wiphy,
440 struct wireless_dev *wdev,
441 struct cfg80211_mgmt_tx_params *params,
442 u64 *cookie)
443{
444 const u8 *buf = params->buf;
445 size_t len = params->len;
446 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
447 int rc;
448 struct ieee80211_mgmt *mgmt_frame = (void *)buf;
449 struct wmi_sw_tx_req_cmd *cmd;
450 struct {
451 struct wil6210_mbox_hdr_wmi wmi;
452 struct wmi_sw_tx_complete_event evt;
453 } __packed evt;
454
455 cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
456 if (!cmd)
457 return -ENOMEM;
458
459 memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
460 cmd->len = cpu_to_le16(len);
461 memcpy(cmd->payload, buf, len);
462
463 rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len,
464 WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
465 if (rc == 0)
466 rc = evt.evt.status;
467
468 kfree(cmd);
469
470 return rc;
471}
472
355static int wil_cfg80211_set_channel(struct wiphy *wiphy, 473static int wil_cfg80211_set_channel(struct wiphy *wiphy,
356 struct cfg80211_chan_def *chandef) 474 struct cfg80211_chan_def *chandef)
357{ 475{
@@ -402,6 +520,41 @@ static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
402 return 0; 520 return 0;
403} 521}
404 522
523static int wil_remain_on_channel(struct wiphy *wiphy,
524 struct wireless_dev *wdev,
525 struct ieee80211_channel *chan,
526 unsigned int duration,
527 u64 *cookie)
528{
529 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
530 int rc;
531
532 /* TODO: handle duration */
533 wil_info(wil, "%s(%d, %d ms)\n", __func__, chan->center_freq, duration);
534
535 rc = wmi_set_channel(wil, chan->hw_value);
536 if (rc)
537 return rc;
538
539 rc = wmi_rxon(wil, true);
540
541 return rc;
542}
543
544static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
545 struct wireless_dev *wdev,
546 u64 cookie)
547{
548 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
549 int rc;
550
551 wil_info(wil, "%s()\n", __func__);
552
553 rc = wmi_rxon(wil, false);
554
555 return rc;
556}
557
405static int wil_fix_bcon(struct wil6210_priv *wil, 558static int wil_fix_bcon(struct wil6210_priv *wil,
406 struct cfg80211_beacon_data *bcon) 559 struct cfg80211_beacon_data *bcon)
407{ 560{
@@ -504,12 +657,24 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
504 return rc; 657 return rc;
505} 658}
506 659
660static int wil_cfg80211_del_station(struct wiphy *wiphy,
661 struct net_device *dev, u8 *mac)
662{
663 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
664 wil6210_disconnect(wil, mac);
665 return 0;
666}
667
507static struct cfg80211_ops wil_cfg80211_ops = { 668static struct cfg80211_ops wil_cfg80211_ops = {
508 .scan = wil_cfg80211_scan, 669 .scan = wil_cfg80211_scan,
509 .connect = wil_cfg80211_connect, 670 .connect = wil_cfg80211_connect,
510 .disconnect = wil_cfg80211_disconnect, 671 .disconnect = wil_cfg80211_disconnect,
511 .change_virtual_intf = wil_cfg80211_change_iface, 672 .change_virtual_intf = wil_cfg80211_change_iface,
512 .get_station = wil_cfg80211_get_station, 673 .get_station = wil_cfg80211_get_station,
674 .dump_station = wil_cfg80211_dump_station,
675 .remain_on_channel = wil_remain_on_channel,
676 .cancel_remain_on_channel = wil_cancel_remain_on_channel,
677 .mgmt_tx = wil_cfg80211_mgmt_tx,
513 .set_monitor_channel = wil_cfg80211_set_channel, 678 .set_monitor_channel = wil_cfg80211_set_channel,
514 .add_key = wil_cfg80211_add_key, 679 .add_key = wil_cfg80211_add_key,
515 .del_key = wil_cfg80211_del_key, 680 .del_key = wil_cfg80211_del_key,
@@ -517,6 +682,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
517 /* AP mode */ 682 /* AP mode */
518 .start_ap = wil_cfg80211_start_ap, 683 .start_ap = wil_cfg80211_start_ap,
519 .stop_ap = wil_cfg80211_stop_ap, 684 .stop_ap = wil_cfg80211_stop_ap,
685 .del_station = wil_cfg80211_del_station,
520}; 686};
521 687
522static void wil_wiphy_init(struct wiphy *wiphy) 688static void wil_wiphy_init(struct wiphy *wiphy)
@@ -542,7 +708,7 @@ static void wil_wiphy_init(struct wiphy *wiphy)
542 wiphy->bands[IEEE80211_BAND_60GHZ] = &wil_band_60ghz; 708 wiphy->bands[IEEE80211_BAND_60GHZ] = &wil_band_60ghz;
543 709
544 /* TODO: figure this out */ 710 /* TODO: figure this out */
545 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 711 wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
546 712
547 wiphy->cipher_suites = wil_cipher_suites; 713 wiphy->cipher_suites = wil_cipher_suites;
548 wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites); 714 wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 1caa31992a7e..1d09a4b0a0f4 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -26,9 +26,11 @@
26/* Nasty hack. Better have per device instances */ 26/* Nasty hack. Better have per device instances */
27static u32 mem_addr; 27static u32 mem_addr;
28static u32 dbg_txdesc_index; 28static u32 dbg_txdesc_index;
29static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */
29 30
30static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, 31static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
31 const char *name, struct vring *vring) 32 const char *name, struct vring *vring,
33 char _s, char _h)
32{ 34{
33 void __iomem *x = wmi_addr(wil, vring->hwtail); 35 void __iomem *x = wmi_addr(wil, vring->hwtail);
34 36
@@ -50,8 +52,8 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
50 volatile struct vring_tx_desc *d = &vring->va[i].tx; 52 volatile struct vring_tx_desc *d = &vring->va[i].tx;
51 if ((i % 64) == 0 && (i != 0)) 53 if ((i % 64) == 0 && (i != 0))
52 seq_printf(s, "\n"); 54 seq_printf(s, "\n");
53 seq_printf(s, "%s", (d->dma.status & BIT(0)) ? 55 seq_printf(s, "%c", (d->dma.status & BIT(0)) ?
54 "S" : (vring->ctx[i].skb ? "H" : "h")); 56 _s : (vring->ctx[i].skb ? _h : 'h'));
55 } 57 }
56 seq_printf(s, "\n"); 58 seq_printf(s, "\n");
57 } 59 }
@@ -63,14 +65,19 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
63 uint i; 65 uint i;
64 struct wil6210_priv *wil = s->private; 66 struct wil6210_priv *wil = s->private;
65 67
66 wil_print_vring(s, wil, "rx", &wil->vring_rx); 68 wil_print_vring(s, wil, "rx", &wil->vring_rx, 'S', '_');
67 69
68 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 70 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
69 struct vring *vring = &(wil->vring_tx[i]); 71 struct vring *vring = &(wil->vring_tx[i]);
70 if (vring->va) { 72 if (vring->va) {
73 int cid = wil->vring2cid_tid[i][0];
74 int tid = wil->vring2cid_tid[i][1];
71 char name[10]; 75 char name[10];
72 snprintf(name, sizeof(name), "tx_%2d", i); 76 snprintf(name, sizeof(name), "tx_%2d", i);
73 wil_print_vring(s, wil, name, vring); 77
78 seq_printf(s, "\n%pM CID %d TID %d\n",
79 wil->sta[cid].addr, cid, tid);
80 wil_print_vring(s, wil, name, vring, '_', 'H');
74 } 81 }
75 } 82 }
76 83
@@ -390,25 +397,40 @@ static const struct file_operations fops_reset = {
390 .write = wil_write_file_reset, 397 .write = wil_write_file_reset,
391 .open = simple_open, 398 .open = simple_open,
392}; 399};
393/*---------Tx descriptor------------*/
394 400
401/*---------Tx/Rx descriptor------------*/
395static int wil_txdesc_debugfs_show(struct seq_file *s, void *data) 402static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
396{ 403{
397 struct wil6210_priv *wil = s->private; 404 struct wil6210_priv *wil = s->private;
398 struct vring *vring = &(wil->vring_tx[0]); 405 struct vring *vring;
406 bool tx = (dbg_vring_index < WIL6210_MAX_TX_RINGS);
407 if (tx)
408 vring = &(wil->vring_tx[dbg_vring_index]);
409 else
410 vring = &wil->vring_rx;
399 411
400 if (!vring->va) { 412 if (!vring->va) {
401 seq_printf(s, "No Tx VRING\n"); 413 if (tx)
414 seq_printf(s, "No Tx[%2d] VRING\n", dbg_vring_index);
415 else
416 seq_puts(s, "No Rx VRING\n");
402 return 0; 417 return 0;
403 } 418 }
404 419
405 if (dbg_txdesc_index < vring->size) { 420 if (dbg_txdesc_index < vring->size) {
421 /* use struct vring_tx_desc for Rx as well,
422 * only field used, .dma.length, is the same
423 */
406 volatile struct vring_tx_desc *d = 424 volatile struct vring_tx_desc *d =
407 &(vring->va[dbg_txdesc_index].tx); 425 &(vring->va[dbg_txdesc_index].tx);
408 volatile u32 *u = (volatile u32 *)d; 426 volatile u32 *u = (volatile u32 *)d;
409 struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb; 427 struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb;
410 428
411 seq_printf(s, "Tx[%3d] = {\n", dbg_txdesc_index); 429 if (tx)
430 seq_printf(s, "Tx[%2d][%3d] = {\n", dbg_vring_index,
431 dbg_txdesc_index);
432 else
433 seq_printf(s, "Rx[%3d] = {\n", dbg_txdesc_index);
412 seq_printf(s, " MAC = 0x%08x 0x%08x 0x%08x 0x%08x\n", 434 seq_printf(s, " MAC = 0x%08x 0x%08x 0x%08x 0x%08x\n",
413 u[0], u[1], u[2], u[3]); 435 u[0], u[1], u[2], u[3]);
414 seq_printf(s, " DMA = 0x%08x 0x%08x 0x%08x 0x%08x\n", 436 seq_printf(s, " DMA = 0x%08x 0x%08x 0x%08x 0x%08x\n",
@@ -439,8 +461,13 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
439 } 461 }
440 seq_printf(s, "}\n"); 462 seq_printf(s, "}\n");
441 } else { 463 } else {
442 seq_printf(s, "TxDesc index (%d) >= size (%d)\n", 464 if (tx)
443 dbg_txdesc_index, vring->size); 465 seq_printf(s, "[%2d] TxDesc index (%d) >= size (%d)\n",
466 dbg_vring_index, dbg_txdesc_index,
467 vring->size);
468 else
469 seq_printf(s, "RxDesc index (%d) >= size (%d)\n",
470 dbg_txdesc_index, vring->size);
444 } 471 }
445 472
446 return 0; 473 return 0;
@@ -570,6 +597,68 @@ static const struct file_operations fops_temp = {
570 .llseek = seq_lseek, 597 .llseek = seq_lseek,
571}; 598};
572 599
600/*---------Station matrix------------*/
601static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
602{
603 int i;
604 u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size;
605 seq_printf(s, "0x%03x [", r->head_seq_num);
606 for (i = 0; i < r->buf_size; i++) {
607 if (i == index)
608 seq_printf(s, "%c", r->reorder_buf[i] ? 'O' : '|');
609 else
610 seq_printf(s, "%c", r->reorder_buf[i] ? '*' : '_');
611 }
612 seq_puts(s, "]\n");
613}
614
615static int wil_sta_debugfs_show(struct seq_file *s, void *data)
616{
617 struct wil6210_priv *wil = s->private;
618 int i, tid;
619
620 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
621 struct wil_sta_info *p = &wil->sta[i];
622 char *status = "unknown";
623 switch (p->status) {
624 case wil_sta_unused:
625 status = "unused ";
626 break;
627 case wil_sta_conn_pending:
628 status = "pending ";
629 break;
630 case wil_sta_connected:
631 status = "connected";
632 break;
633 }
634 seq_printf(s, "[%d] %pM %s\n", i, p->addr, status);
635
636 if (p->status == wil_sta_connected) {
637 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
638 struct wil_tid_ampdu_rx *r = p->tid_rx[tid];
639 if (r) {
640 seq_printf(s, "[%2d] ", tid);
641 wil_print_rxtid(s, r);
642 }
643 }
644 }
645 }
646
647 return 0;
648}
649
650static int wil_sta_seq_open(struct inode *inode, struct file *file)
651{
652 return single_open(file, wil_sta_debugfs_show, inode->i_private);
653}
654
655static const struct file_operations fops_sta = {
656 .open = wil_sta_seq_open,
657 .release = single_release,
658 .read = seq_read,
659 .llseek = seq_lseek,
660};
661
573/*----------------*/ 662/*----------------*/
574int wil6210_debugfs_init(struct wil6210_priv *wil) 663int wil6210_debugfs_init(struct wil6210_priv *wil)
575{ 664{
@@ -581,9 +670,13 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
581 670
582 debugfs_create_file("mbox", S_IRUGO, dbg, wil, &fops_mbox); 671 debugfs_create_file("mbox", S_IRUGO, dbg, wil, &fops_mbox);
583 debugfs_create_file("vrings", S_IRUGO, dbg, wil, &fops_vring); 672 debugfs_create_file("vrings", S_IRUGO, dbg, wil, &fops_vring);
584 debugfs_create_file("txdesc", S_IRUGO, dbg, wil, &fops_txdesc); 673 debugfs_create_file("stations", S_IRUGO, dbg, wil, &fops_sta);
585 debugfs_create_u32("txdesc_index", S_IRUGO | S_IWUSR, dbg, 674 debugfs_create_file("desc", S_IRUGO, dbg, wil, &fops_txdesc);
675 debugfs_create_u32("desc_index", S_IRUGO | S_IWUSR, dbg,
586 &dbg_txdesc_index); 676 &dbg_txdesc_index);
677 debugfs_create_u32("vring_index", S_IRUGO | S_IWUSR, dbg,
678 &dbg_vring_index);
679
587 debugfs_create_file("bf", S_IRUGO, dbg, wil, &fops_bf); 680 debugfs_create_file("bf", S_IRUGO, dbg, wil, &fops_bf);
588 debugfs_create_file("ssid", S_IRUGO | S_IWUSR, dbg, wil, &fops_ssid); 681 debugfs_create_file("ssid", S_IRUGO | S_IWUSR, dbg, wil, &fops_ssid);
589 debugfs_create_u32("secure_pcp", S_IRUGO | S_IWUSR, dbg, 682 debugfs_create_u32("secure_pcp", S_IRUGO | S_IWUSR, dbg,
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index fd30cddd5882..41c362dee032 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -16,8 +16,10 @@
16 16
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/if_arp.h> 18#include <linux/if_arp.h>
19#include <linux/etherdevice.h>
19 20
20#include "wil6210.h" 21#include "wil6210.h"
22#include "txrx.h"
21 23
22/* 24/*
23 * Due to a hardware issue, 25 * Due to a hardware issue,
@@ -52,29 +54,75 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
52 __raw_writel(*s++, d++); 54 __raw_writel(*s++, d++);
53} 55}
54 56
55static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) 57static void wil_disconnect_cid(struct wil6210_priv *wil, int cid)
56{ 58{
57 uint i; 59 uint i;
58 struct net_device *ndev = wil_to_ndev(wil); 60 struct wil_sta_info *sta = &wil->sta[cid];
59 61
60 wil_dbg_misc(wil, "%s()\n", __func__); 62 if (sta->status != wil_sta_unused) {
63 wmi_disconnect_sta(wil, sta->addr, WLAN_REASON_DEAUTH_LEAVING);
64 sta->status = wil_sta_unused;
65 }
66
67 for (i = 0; i < WIL_STA_TID_NUM; i++) {
68 struct wil_tid_ampdu_rx *r = sta->tid_rx[i];
69 sta->tid_rx[i] = NULL;
70 wil_tid_ampdu_rx_free(wil, r);
71 }
72 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
73 if (wil->vring2cid_tid[i][0] == cid)
74 wil_vring_fini_tx(wil, i);
75 }
76 memset(&sta->stats, 0, sizeof(sta->stats));
77}
78
79static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
80{
81 int cid = -ENOENT;
82 struct net_device *ndev = wil_to_ndev(wil);
83 struct wireless_dev *wdev = wil->wdev;
61 84
62 wil_link_off(wil); 85 might_sleep();
63 if (test_bit(wil_status_fwconnected, &wil->status)) { 86 if (bssid) {
64 clear_bit(wil_status_fwconnected, &wil->status); 87 cid = wil_find_cid(wil, bssid);
65 cfg80211_disconnected(ndev, 88 wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid);
66 WLAN_STATUS_UNSPECIFIED_FAILURE, 89 } else {
67 NULL, 0, GFP_KERNEL); 90 wil_dbg_misc(wil, "%s(all)\n", __func__);
68 } else if (test_bit(wil_status_fwconnecting, &wil->status)) {
69 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
70 WLAN_STATUS_UNSPECIFIED_FAILURE,
71 GFP_KERNEL);
72 } 91 }
73 clear_bit(wil_status_fwconnecting, &wil->status);
74 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
75 wil_vring_fini_tx(wil, i);
76 92
77 clear_bit(wil_status_dontscan, &wil->status); 93 if (cid >= 0) /* disconnect 1 peer */
94 wil_disconnect_cid(wil, cid);
95 else /* disconnect all */
96 for (cid = 0; cid < WIL6210_MAX_CID; cid++)
97 wil_disconnect_cid(wil, cid);
98
99 /* link state */
100 switch (wdev->iftype) {
101 case NL80211_IFTYPE_STATION:
102 case NL80211_IFTYPE_P2P_CLIENT:
103 wil_link_off(wil);
104 if (test_bit(wil_status_fwconnected, &wil->status)) {
105 clear_bit(wil_status_fwconnected, &wil->status);
106 cfg80211_disconnected(ndev,
107 WLAN_STATUS_UNSPECIFIED_FAILURE,
108 NULL, 0, GFP_KERNEL);
109 } else if (test_bit(wil_status_fwconnecting, &wil->status)) {
110 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
111 WLAN_STATUS_UNSPECIFIED_FAILURE,
112 GFP_KERNEL);
113 }
114 clear_bit(wil_status_fwconnecting, &wil->status);
115 wil_dbg_misc(wil, "clear_bit(wil_status_dontscan)\n");
116 clear_bit(wil_status_dontscan, &wil->status);
117 break;
118 default:
119 /* AP-like interface and monitor:
120 * never scan, always connected
121 */
122 if (bssid)
123 cfg80211_del_sta(ndev, bssid, GFP_KERNEL);
124 break;
125 }
78} 126}
79 127
80static void wil_disconnect_worker(struct work_struct *work) 128static void wil_disconnect_worker(struct work_struct *work)
@@ -97,12 +145,23 @@ static void wil_connect_timer_fn(ulong x)
97 schedule_work(&wil->disconnect_worker); 145 schedule_work(&wil->disconnect_worker);
98} 146}
99 147
148static int wil_find_free_vring(struct wil6210_priv *wil)
149{
150 int i;
151 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
152 if (!wil->vring_tx[i].va)
153 return i;
154 }
155 return -EINVAL;
156}
157
100static void wil_connect_worker(struct work_struct *work) 158static void wil_connect_worker(struct work_struct *work)
101{ 159{
102 int rc; 160 int rc;
103 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 161 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
104 connect_worker); 162 connect_worker);
105 int cid = wil->pending_connect_cid; 163 int cid = wil->pending_connect_cid;
164 int ringid = wil_find_free_vring(wil);
106 165
107 if (cid < 0) { 166 if (cid < 0) {
108 wil_err(wil, "No connection pending\n"); 167 wil_err(wil, "No connection pending\n");
@@ -111,16 +170,22 @@ static void wil_connect_worker(struct work_struct *work)
111 170
112 wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid); 171 wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid);
113 172
114 rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, cid, 0); 173 rc = wil_vring_init_tx(wil, ringid, WIL6210_TX_RING_SIZE, cid, 0);
115 wil->pending_connect_cid = -1; 174 wil->pending_connect_cid = -1;
116 if (rc == 0) 175 if (rc == 0) {
176 wil->sta[cid].status = wil_sta_connected;
117 wil_link_on(wil); 177 wil_link_on(wil);
178 } else {
179 wil->sta[cid].status = wil_sta_unused;
180 }
118} 181}
119 182
120int wil_priv_init(struct wil6210_priv *wil) 183int wil_priv_init(struct wil6210_priv *wil)
121{ 184{
122 wil_dbg_misc(wil, "%s()\n", __func__); 185 wil_dbg_misc(wil, "%s()\n", __func__);
123 186
187 memset(wil->sta, 0, sizeof(wil->sta));
188
124 mutex_init(&wil->mutex); 189 mutex_init(&wil->mutex);
125 mutex_init(&wil->wmi_mutex); 190 mutex_init(&wil->wmi_mutex);
126 191
@@ -370,3 +435,19 @@ int wil_down(struct wil6210_priv *wil)
370 435
371 return rc; 436 return rc;
372} 437}
438
439int wil_find_cid(struct wil6210_priv *wil, const u8 *mac)
440{
441 int i;
442 int rc = -ENOENT;
443
444 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
445 if ((wil->sta[i].status != wil_sta_unused) &&
446 ether_addr_equal(wil->sta[i].addr, mac)) {
447 rc = i;
448 break;
449 }
450 }
451
452 return rc;
453}
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
new file mode 100644
index 000000000000..d04629fe053f
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -0,0 +1,177 @@
1#include "wil6210.h"
2#include "txrx.h"
3
4#define SEQ_MODULO 0x1000
5#define SEQ_MASK 0xfff
6
7static inline int seq_less(u16 sq1, u16 sq2)
8{
9 return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1);
10}
11
12static inline u16 seq_inc(u16 sq)
13{
14 return (sq + 1) & SEQ_MASK;
15}
16
17static inline u16 seq_sub(u16 sq1, u16 sq2)
18{
19 return (sq1 - sq2) & SEQ_MASK;
20}
21
22static inline int reorder_index(struct wil_tid_ampdu_rx *r, u16 seq)
23{
24 return seq_sub(seq, r->ssn) % r->buf_size;
25}
26
27static void wil_release_reorder_frame(struct wil6210_priv *wil,
28 struct wil_tid_ampdu_rx *r,
29 int index)
30{
31 struct net_device *ndev = wil_to_ndev(wil);
32 struct sk_buff *skb = r->reorder_buf[index];
33
34 if (!skb)
35 goto no_frame;
36
37 /* release the frame from the reorder ring buffer */
38 r->stored_mpdu_num--;
39 r->reorder_buf[index] = NULL;
40 wil_netif_rx_any(skb, ndev);
41
42no_frame:
43 r->head_seq_num = seq_inc(r->head_seq_num);
44}
45
46static void wil_release_reorder_frames(struct wil6210_priv *wil,
47 struct wil_tid_ampdu_rx *r,
48 u16 hseq)
49{
50 int index;
51
52 while (seq_less(r->head_seq_num, hseq)) {
53 index = reorder_index(r, r->head_seq_num);
54 wil_release_reorder_frame(wil, r, index);
55 }
56}
57
58static void wil_reorder_release(struct wil6210_priv *wil,
59 struct wil_tid_ampdu_rx *r)
60{
61 int index = reorder_index(r, r->head_seq_num);
62
63 while (r->reorder_buf[index]) {
64 wil_release_reorder_frame(wil, r, index);
65 index = reorder_index(r, r->head_seq_num);
66 }
67}
68
69void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
70{
71 struct net_device *ndev = wil_to_ndev(wil);
72 struct vring_rx_desc *d = wil_skb_rxdesc(skb);
73 int tid = wil_rxdesc_tid(d);
74 int cid = wil_rxdesc_cid(d);
75 int mid = wil_rxdesc_mid(d);
76 u16 seq = wil_rxdesc_seq(d);
77 struct wil_sta_info *sta = &wil->sta[cid];
78 struct wil_tid_ampdu_rx *r = sta->tid_rx[tid];
79 u16 hseq;
80 int index;
81
82 wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x\n",
83 mid, cid, tid, seq);
84
85 if (!r) {
86 wil_netif_rx_any(skb, ndev);
87 return;
88 }
89
90 hseq = r->head_seq_num;
91
92 spin_lock(&r->reorder_lock);
93
94 /* frame with out of date sequence number */
95 if (seq_less(seq, r->head_seq_num)) {
96 dev_kfree_skb(skb);
97 goto out;
98 }
99
100 /*
101 * If frame the sequence number exceeds our buffering window
102 * size release some previous frames to make room for this one.
103 */
104 if (!seq_less(seq, r->head_seq_num + r->buf_size)) {
105 hseq = seq_inc(seq_sub(seq, r->buf_size));
106 /* release stored frames up to new head to stack */
107 wil_release_reorder_frames(wil, r, hseq);
108 }
109
110 /* Now the new frame is always in the range of the reordering buffer */
111
112 index = reorder_index(r, seq);
113
114 /* check if we already stored this frame */
115 if (r->reorder_buf[index]) {
116 dev_kfree_skb(skb);
117 goto out;
118 }
119
120 /*
121 * If the current MPDU is in the right order and nothing else
122 * is stored we can process it directly, no need to buffer it.
123 * If it is first but there's something stored, we may be able
124 * to release frames after this one.
125 */
126 if (seq == r->head_seq_num && r->stored_mpdu_num == 0) {
127 r->head_seq_num = seq_inc(r->head_seq_num);
128 wil_netif_rx_any(skb, ndev);
129 goto out;
130 }
131
132 /* put the frame in the reordering buffer */
133 r->reorder_buf[index] = skb;
134 r->reorder_time[index] = jiffies;
135 r->stored_mpdu_num++;
136 wil_reorder_release(wil, r);
137
138out:
139 spin_unlock(&r->reorder_lock);
140}
141
142struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
143 int size, u16 ssn)
144{
145 struct wil_tid_ampdu_rx *r = kzalloc(sizeof(*r), GFP_KERNEL);
146 if (!r)
147 return NULL;
148
149 r->reorder_buf =
150 kcalloc(size, sizeof(struct sk_buff *), GFP_KERNEL);
151 r->reorder_time =
152 kcalloc(size, sizeof(unsigned long), GFP_KERNEL);
153 if (!r->reorder_buf || !r->reorder_time) {
154 kfree(r->reorder_buf);
155 kfree(r->reorder_time);
156 kfree(r);
157 return NULL;
158 }
159
160 spin_lock_init(&r->reorder_lock);
161 r->ssn = ssn;
162 r->head_seq_num = ssn;
163 r->buf_size = size;
164 r->stored_mpdu_num = 0;
165 return r;
166}
167
168void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
169 struct wil_tid_ampdu_rx *r)
170{
171 if (!r)
172 return;
173 wil_release_reorder_frames(wil, r, r->head_seq_num + r->buf_size);
174 kfree(r->reorder_buf);
175 kfree(r->reorder_time);
176 kfree(r);
177}
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 0b0975d88b43..092081e209da 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -344,6 +344,9 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
344 u16 dmalen; 344 u16 dmalen;
345 u8 ftype; 345 u8 ftype;
346 u8 ds_bits; 346 u8 ds_bits;
347 int cid;
348 struct wil_net_stats *stats;
349
347 350
348 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); 351 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
349 352
@@ -383,8 +386,10 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
383 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, 386 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
384 skb->data, skb_headlen(skb), false); 387 skb->data, skb_headlen(skb), false);
385 388
386 389 cid = wil_rxdesc_cid(d);
387 wil->stats.last_mcs_rx = wil_rxdesc_mcs(d); 390 stats = &wil->sta[cid].stats;
391 stats->last_mcs_rx = wil_rxdesc_mcs(d);
392 wil->stats.last_mcs_rx = stats->last_mcs_rx;
388 393
389 /* use radiotap header only if required */ 394 /* use radiotap header only if required */
390 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) 395 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
@@ -472,10 +477,14 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
472 * Pass Rx packet to the netif. Update statistics. 477 * Pass Rx packet to the netif. Update statistics.
473 * Called in softirq context (NAPI poll). 478 * Called in softirq context (NAPI poll).
474 */ 479 */
475static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) 480void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
476{ 481{
477 int rc; 482 int rc;
483 struct wil6210_priv *wil = ndev_to_wil(ndev);
478 unsigned int len = skb->len; 484 unsigned int len = skb->len;
485 struct vring_rx_desc *d = wil_skb_rxdesc(skb);
486 int cid = wil_rxdesc_cid(d);
487 struct wil_net_stats *stats = &wil->sta[cid].stats;
479 488
480 skb_orphan(skb); 489 skb_orphan(skb);
481 490
@@ -483,10 +492,13 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
483 492
484 if (likely(rc == NET_RX_SUCCESS)) { 493 if (likely(rc == NET_RX_SUCCESS)) {
485 ndev->stats.rx_packets++; 494 ndev->stats.rx_packets++;
495 stats->rx_packets++;
486 ndev->stats.rx_bytes += len; 496 ndev->stats.rx_bytes += len;
497 stats->rx_bytes += len;
487 498
488 } else { 499 } else {
489 ndev->stats.rx_dropped++; 500 ndev->stats.rx_dropped++;
501 stats->rx_dropped++;
490 } 502 }
491} 503}
492 504
@@ -515,12 +527,18 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
515 skb->ip_summed = CHECKSUM_UNNECESSARY; 527 skb->ip_summed = CHECKSUM_UNNECESSARY;
516 skb->pkt_type = PACKET_OTHERHOST; 528 skb->pkt_type = PACKET_OTHERHOST;
517 skb->protocol = htons(ETH_P_802_2); 529 skb->protocol = htons(ETH_P_802_2);
518 530 wil_netif_rx_any(skb, ndev);
519 } else { 531 } else {
532 struct ethhdr *eth = (void *)skb->data;
533
520 skb->protocol = eth_type_trans(skb, ndev); 534 skb->protocol = eth_type_trans(skb, ndev);
535
536 if (is_unicast_ether_addr(eth->h_dest))
537 wil_rx_reorder(wil, skb);
538 else
539 wil_netif_rx_any(skb, ndev);
521 } 540 }
522 541
523 wil_netif_rx_any(skb, ndev);
524 } 542 }
525 wil_rx_refill(wil, v->size); 543 wil_rx_refill(wil, v->size);
526} 544}
@@ -598,6 +616,9 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
598 if (rc) 616 if (rc)
599 goto out; 617 goto out;
600 618
619 wil->vring2cid_tid[id][0] = cid;
620 wil->vring2cid_tid[id][1] = tid;
621
601 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); 622 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
602 623
603 rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), 624 rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd),
@@ -634,12 +655,83 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
634static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, 655static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
635 struct sk_buff *skb) 656 struct sk_buff *skb)
636{ 657{
637 struct vring *v = &wil->vring_tx[0]; 658 int i;
659 struct ethhdr *eth = (void *)skb->data;
660 int cid = wil_find_cid(wil, eth->h_dest);
661
662 if (cid < 0)
663 return NULL;
664
665 /* TODO: fix for multiple TID */
666 for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) {
667 if (wil->vring2cid_tid[i][0] == cid) {
668 struct vring *v = &wil->vring_tx[i];
669 wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n",
670 __func__, eth->h_dest, i);
671 if (v->va) {
672 return v;
673 } else {
674 wil_dbg_txrx(wil, "vring[%d] not valid\n", i);
675 return NULL;
676 }
677 }
678 }
679
680 return NULL;
681}
682
683static void wil_set_da_for_vring(struct wil6210_priv *wil,
684 struct sk_buff *skb, int vring_index)
685{
686 struct ethhdr *eth = (void *)skb->data;
687 int cid = wil->vring2cid_tid[vring_index][0];
688 memcpy(eth->h_dest, wil->sta[cid].addr, ETH_ALEN);
689}
690
691static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
692 struct sk_buff *skb);
693/*
694 * Find 1-st vring and return it; set dest address for this vring in skb
695 * duplicate skb and send it to other active vrings
696 */
697static struct vring *wil_tx_bcast(struct wil6210_priv *wil,
698 struct sk_buff *skb)
699{
700 struct vring *v, *v2;
701 struct sk_buff *skb2;
702 int i;
703
704 /* find 1-st vring */
705 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
706 v = &wil->vring_tx[i];
707 if (v->va)
708 goto found;
709 }
638 710
639 if (v->va) 711 wil_err(wil, "Tx while no vrings active?\n");
640 return v;
641 712
642 return NULL; 713 return NULL;
714
715found:
716 wil_dbg_txrx(wil, "BCAST -> ring %d\n", i);
717 wil_set_da_for_vring(wil, skb, i);
718
719 /* find other active vrings and duplicate skb for each */
720 for (i++; i < WIL6210_MAX_TX_RINGS; i++) {
721 v2 = &wil->vring_tx[i];
722 if (!v2->va)
723 continue;
724 skb2 = skb_copy(skb, GFP_ATOMIC);
725 if (skb2) {
726 wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i);
727 wil_set_da_for_vring(wil, skb2, i);
728 wil_tx_vring(wil, v2, skb2);
729 } else {
730 wil_err(wil, "skb_copy failed\n");
731 }
732 }
733
734 return v;
643} 735}
644 736
645static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len, 737static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
@@ -740,9 +832,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
740 } 832 }
741 _d = &(vring->va[i].tx); 833 _d = &(vring->va[i].tx);
742 834
743 /* FIXME FW can accept only unicast frames for the peer */
744 memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN);
745
746 pa = dma_map_single(dev, skb->data, 835 pa = dma_map_single(dev, skb->data,
747 skb_headlen(skb), DMA_TO_DEVICE); 836 skb_headlen(skb), DMA_TO_DEVICE);
748 837
@@ -836,6 +925,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
836netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) 925netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
837{ 926{
838 struct wil6210_priv *wil = ndev_to_wil(ndev); 927 struct wil6210_priv *wil = ndev_to_wil(ndev);
928 struct ethhdr *eth = (void *)skb->data;
839 struct vring *vring; 929 struct vring *vring;
840 int rc; 930 int rc;
841 931
@@ -854,9 +944,13 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
854 } 944 }
855 945
856 /* find vring */ 946 /* find vring */
857 vring = wil_find_tx_vring(wil, skb); 947 if (is_unicast_ether_addr(eth->h_dest)) {
948 vring = wil_find_tx_vring(wil, skb);
949 } else {
950 vring = wil_tx_bcast(wil, skb);
951 }
858 if (!vring) { 952 if (!vring) {
859 wil_err(wil, "No Tx VRING available\n"); 953 wil_err(wil, "No Tx VRING found for %pM\n", eth->h_dest);
860 goto drop; 954 goto drop;
861 } 955 }
862 /* set up vring entry */ 956 /* set up vring entry */
@@ -892,6 +986,8 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
892 struct device *dev = wil_to_dev(wil); 986 struct device *dev = wil_to_dev(wil);
893 struct vring *vring = &wil->vring_tx[ringid]; 987 struct vring *vring = &wil->vring_tx[ringid];
894 int done = 0; 988 int done = 0;
989 int cid = wil->vring2cid_tid[ringid][0];
990 struct wil_net_stats *stats = &wil->sta[cid].stats;
895 991
896 if (!vring->va) { 992 if (!vring->va) {
897 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); 993 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
@@ -933,9 +1029,12 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
933 if (skb) { 1029 if (skb) {
934 if (d->dma.error == 0) { 1030 if (d->dma.error == 0) {
935 ndev->stats.tx_packets++; 1031 ndev->stats.tx_packets++;
1032 stats->tx_packets++;
936 ndev->stats.tx_bytes += skb->len; 1033 ndev->stats.tx_bytes += skb->len;
1034 stats->tx_bytes += skb->len;
937 } else { 1035 } else {
938 ndev->stats.tx_errors++; 1036 ndev->stats.tx_errors++;
1037 stats->tx_errors++;
939 } 1038 }
940 1039
941 dev_kfree_skb_any(skb); 1040 dev_kfree_skb_any(skb);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index b3828279204c..bc5706a4f007 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -436,4 +436,11 @@ static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb)
436 return (void *)skb->cb; 436 return (void *)skb->cb;
437} 437}
438 438
439void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev);
440void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb);
441struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
442 int size, u16 ssn);
443void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
444 struct wil_tid_ampdu_rx *r);
445
439#endif /* WIL6210_TXRX_H */ 446#endif /* WIL6210_TXRX_H */
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 1f91eaf95bbe..980dccc82b32 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -215,6 +215,46 @@ enum { /* for wil6210_priv.status */
215 215
216struct pci_dev; 216struct pci_dev;
217 217
218/**
219 * struct tid_ampdu_rx - TID aggregation information (Rx).
220 *
221 * @reorder_buf: buffer to reorder incoming aggregated MPDUs
222 * @reorder_time: jiffies when skb was added
223 * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
224 * @reorder_timer: releases expired frames from the reorder buffer.
225 * @last_rx: jiffies of last rx activity
226 * @head_seq_num: head sequence number in reordering buffer.
227 * @stored_mpdu_num: number of MPDUs in reordering buffer
228 * @ssn: Starting Sequence Number expected to be aggregated.
229 * @buf_size: buffer size for incoming A-MPDUs
230 * @timeout: reset timer value (in TUs).
231 * @dialog_token: dialog token for aggregation session
232 * @rcu_head: RCU head used for freeing this struct
233 * @reorder_lock: serializes access to reorder buffer, see below.
234 *
235 * This structure's lifetime is managed by RCU, assignments to
236 * the array holding it must hold the aggregation mutex.
237 *
238 * The @reorder_lock is used to protect the members of this
239 * struct, except for @timeout, @buf_size and @dialog_token,
240 * which are constant across the lifetime of the struct (the
241 * dialog token being used only for debugging).
242 */
243struct wil_tid_ampdu_rx {
244 spinlock_t reorder_lock; /* see above */
245 struct sk_buff **reorder_buf;
246 unsigned long *reorder_time;
247 struct timer_list session_timer;
248 struct timer_list reorder_timer;
249 unsigned long last_rx;
250 u16 head_seq_num;
251 u16 stored_mpdu_num;
252 u16 ssn;
253 u16 buf_size;
254 u16 timeout;
255 u8 dialog_token;
256};
257
218struct wil6210_stats { 258struct wil6210_stats {
219 u64 tsf; 259 u64 tsf;
220 u32 snr; 260 u32 snr;
@@ -226,6 +266,42 @@ struct wil6210_stats {
226 u16 peer_tx_sector; 266 u16 peer_tx_sector;
227}; 267};
228 268
269enum wil_sta_status {
270 wil_sta_unused = 0,
271 wil_sta_conn_pending = 1,
272 wil_sta_connected = 2,
273};
274
275#define WIL_STA_TID_NUM (16)
276
277struct wil_net_stats {
278 unsigned long rx_packets;
279 unsigned long tx_packets;
280 unsigned long rx_bytes;
281 unsigned long tx_bytes;
282 unsigned long tx_errors;
283 unsigned long rx_dropped;
284 u16 last_mcs_rx;
285};
286
287/**
288 * struct wil_sta_info - data for peer
289 *
290 * Peer identified by its CID (connection ID)
291 * NIC performs beam forming for each peer;
292 * if no beam forming done, frame exchange is not
293 * possible.
294 */
295struct wil_sta_info {
296 u8 addr[ETH_ALEN];
297 enum wil_sta_status status;
298 struct wil_net_stats stats;
299 /* Rx BACK */
300 struct wil_tid_ampdu_rx *tid_rx[WIL_STA_TID_NUM];
301 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(WIL_STA_TID_NUM)];
302 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)];
303};
304
229struct wil6210_priv { 305struct wil6210_priv {
230 struct pci_dev *pdev; 306 struct pci_dev *pdev;
231 int n_msi; 307 int n_msi;
@@ -267,7 +343,8 @@ struct wil6210_priv {
267 /* DMA related */ 343 /* DMA related */
268 struct vring vring_rx; 344 struct vring vring_rx;
269 struct vring vring_tx[WIL6210_MAX_TX_RINGS]; 345 struct vring vring_tx[WIL6210_MAX_TX_RINGS];
270 u8 dst_addr[WIL6210_MAX_TX_RINGS][ETH_ALEN]; 346 u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
347 struct wil_sta_info sta[WIL6210_MAX_CID];
271 /* scan */ 348 /* scan */
272 struct cfg80211_scan_request *scan_request; 349 struct cfg80211_scan_request *scan_request;
273 350
@@ -334,6 +411,7 @@ void wil_link_off(struct wil6210_priv *wil);
334int wil_up(struct wil6210_priv *wil); 411int wil_up(struct wil6210_priv *wil);
335int wil_down(struct wil6210_priv *wil); 412int wil_down(struct wil6210_priv *wil);
336void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); 413void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
414int wil_find_cid(struct wil6210_priv *wil, const u8 *mac);
337 415
338void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr); 416void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr);
339void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); 417void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr);
@@ -357,7 +435,9 @@ int wmi_echo(struct wil6210_priv *wil);
357int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); 435int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
358int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); 436int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
359int wmi_p2p_cfg(struct wil6210_priv *wil, int channel); 437int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
438int wmi_rxon(struct wil6210_priv *wil, bool on);
360int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); 439int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
440int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason);
361 441
362int wil6210_init_irq(struct wil6210_priv *wil, int irq); 442int wil6210_init_irq(struct wil6210_priv *wil, int irq);
363void wil6210_fini_irq(struct wil6210_priv *wil, int irq); 443void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 063963ee422a..24eed0963581 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -307,14 +307,14 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
307 u32 freq = ieee80211_channel_to_frequency(ch_no, 307 u32 freq = ieee80211_channel_to_frequency(ch_no,
308 IEEE80211_BAND_60GHZ); 308 IEEE80211_BAND_60GHZ);
309 struct ieee80211_channel *channel = ieee80211_get_channel(wiphy, freq); 309 struct ieee80211_channel *channel = ieee80211_get_channel(wiphy, freq);
310 /* TODO convert LE to CPU */ 310 s32 signal = data->info.sqi;
311 s32 signal = 0; /* TODO */
312 __le16 fc = rx_mgmt_frame->frame_control; 311 __le16 fc = rx_mgmt_frame->frame_control;
313 u32 d_len = le32_to_cpu(data->info.len); 312 u32 d_len = le32_to_cpu(data->info.len);
314 u16 d_status = le16_to_cpu(data->info.status); 313 u16 d_status = le16_to_cpu(data->info.status);
315 314
316 wil_dbg_wmi(wil, "MGMT: channel %d MCS %d SNR %d\n", 315 wil_dbg_wmi(wil, "MGMT: channel %d MCS %d SNR %d SQI %d%%\n",
317 data->info.channel, data->info.mcs, data->info.snr); 316 data->info.channel, data->info.mcs, data->info.snr,
317 data->info.sqi);
318 wil_dbg_wmi(wil, "status 0x%04x len %d fc 0x%04x\n", d_status, d_len, 318 wil_dbg_wmi(wil, "status 0x%04x len %d fc 0x%04x\n", d_status, d_len,
319 le16_to_cpu(fc)); 319 le16_to_cpu(fc));
320 wil_dbg_wmi(wil, "qid %d mid %d cid %d\n", 320 wil_dbg_wmi(wil, "qid %d mid %d cid %d\n",
@@ -384,6 +384,11 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
384 evt->assoc_req_len, evt->assoc_resp_len); 384 evt->assoc_req_len, evt->assoc_resp_len);
385 return; 385 return;
386 } 386 }
387 if (evt->cid >= WIL6210_MAX_CID) {
388 wil_err(wil, "Connect CID invalid : %d\n", evt->cid);
389 return;
390 }
391
387 ch = evt->channel + 1; 392 ch = evt->channel + 1;
388 wil_dbg_wmi(wil, "Connect %pM channel [%d] cid %d\n", 393 wil_dbg_wmi(wil, "Connect %pM channel [%d] cid %d\n",
389 evt->bssid, ch, evt->cid); 394 evt->bssid, ch, evt->cid);
@@ -439,7 +444,8 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
439 444
440 /* FIXME FW can transmit only ucast frames to peer */ 445 /* FIXME FW can transmit only ucast frames to peer */
441 /* FIXME real ring_id instead of hard coded 0 */ 446 /* FIXME real ring_id instead of hard coded 0 */
442 memcpy(wil->dst_addr[0], evt->bssid, ETH_ALEN); 447 memcpy(wil->sta[evt->cid].addr, evt->bssid, ETH_ALEN);
448 wil->sta[evt->cid].status = wil_sta_conn_pending;
443 449
444 wil->pending_connect_cid = evt->cid; 450 wil->pending_connect_cid = evt->cid;
445 queue_work(wil->wmi_wq_conn, &wil->connect_worker); 451 queue_work(wil->wmi_wq_conn, &wil->connect_worker);
@@ -476,11 +482,11 @@ static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)
476 wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector); 482 wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector);
477 wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector); 483 wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector);
478 wil_dbg_wmi(wil, "Link status, MCS %d TSF 0x%016llx\n" 484 wil_dbg_wmi(wil, "Link status, MCS %d TSF 0x%016llx\n"
479 "BF status 0x%08x SNR 0x%08x\n" 485 "BF status 0x%08x SNR 0x%08x SQI %d%%\n"
480 "Tx Tpt %d goodput %d Rx goodput %d\n" 486 "Tx Tpt %d goodput %d Rx goodput %d\n"
481 "Sectors(rx:tx) my %d:%d peer %d:%d\n", 487 "Sectors(rx:tx) my %d:%d peer %d:%d\n",
482 wil->stats.bf_mcs, wil->stats.tsf, evt->status, 488 wil->stats.bf_mcs, wil->stats.tsf, evt->status,
483 wil->stats.snr, le32_to_cpu(evt->tx_tpt), 489 wil->stats.snr, evt->sqi, le32_to_cpu(evt->tx_tpt),
484 le32_to_cpu(evt->tx_goodput), le32_to_cpu(evt->rx_goodput), 490 le32_to_cpu(evt->tx_goodput), le32_to_cpu(evt->rx_goodput),
485 wil->stats.my_rx_sector, wil->stats.my_tx_sector, 491 wil->stats.my_rx_sector, wil->stats.my_tx_sector,
486 wil->stats.peer_rx_sector, wil->stats.peer_tx_sector); 492 wil->stats.peer_rx_sector, wil->stats.peer_tx_sector);
@@ -499,10 +505,16 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
499 int sz = eapol_len + ETH_HLEN; 505 int sz = eapol_len + ETH_HLEN;
500 struct sk_buff *skb; 506 struct sk_buff *skb;
501 struct ethhdr *eth; 507 struct ethhdr *eth;
508 int cid;
509 struct wil_net_stats *stats = NULL;
502 510
503 wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len, 511 wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len,
504 evt->src_mac); 512 evt->src_mac);
505 513
514 cid = wil_find_cid(wil, evt->src_mac);
515 if (cid >= 0)
516 stats = &wil->sta[cid].stats;
517
506 if (eapol_len > 196) { /* TODO: revisit size limit */ 518 if (eapol_len > 196) { /* TODO: revisit size limit */
507 wil_err(wil, "EAPOL too large\n"); 519 wil_err(wil, "EAPOL too large\n");
508 return; 520 return;
@@ -513,6 +525,7 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
513 wil_err(wil, "Failed to allocate skb\n"); 525 wil_err(wil, "Failed to allocate skb\n");
514 return; 526 return;
515 } 527 }
528
516 eth = (struct ethhdr *)skb_put(skb, ETH_HLEN); 529 eth = (struct ethhdr *)skb_put(skb, ETH_HLEN);
517 memcpy(eth->h_dest, ndev->dev_addr, ETH_ALEN); 530 memcpy(eth->h_dest, ndev->dev_addr, ETH_ALEN);
518 memcpy(eth->h_source, evt->src_mac, ETH_ALEN); 531 memcpy(eth->h_source, evt->src_mac, ETH_ALEN);
@@ -521,9 +534,15 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
521 skb->protocol = eth_type_trans(skb, ndev); 534 skb->protocol = eth_type_trans(skb, ndev);
522 if (likely(netif_rx_ni(skb) == NET_RX_SUCCESS)) { 535 if (likely(netif_rx_ni(skb) == NET_RX_SUCCESS)) {
523 ndev->stats.rx_packets++; 536 ndev->stats.rx_packets++;
524 ndev->stats.rx_bytes += skb->len; 537 ndev->stats.rx_bytes += sz;
538 if (stats) {
539 stats->rx_packets++;
540 stats->rx_bytes += sz;
541 }
525 } else { 542 } else {
526 ndev->stats.rx_dropped++; 543 ndev->stats.rx_dropped++;
544 if (stats)
545 stats->rx_dropped++;
527 } 546 }
528} 547}
529 548
@@ -552,10 +571,42 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
552 int len) 571 int len)
553{ 572{
554 struct wmi_vring_ba_status_event *evt = d; 573 struct wmi_vring_ba_status_event *evt = d;
574 struct wil_sta_info *sta;
575 uint i, cid;
576
577 /* TODO: use Rx BA status, not Tx one */
555 578
556 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n", 579 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n",
557 evt->ringid, evt->status ? "N/A" : "OK", evt->agg_wsize, 580 evt->ringid,
558 __le16_to_cpu(evt->ba_timeout)); 581 evt->status == WMI_BA_AGREED ? "OK" : "N/A",
582 evt->agg_wsize, __le16_to_cpu(evt->ba_timeout));
583
584 if (evt->ringid >= WIL6210_MAX_TX_RINGS) {
585 wil_err(wil, "invalid ring id %d\n", evt->ringid);
586 return;
587 }
588
589 cid = wil->vring2cid_tid[evt->ringid][0];
590 if (cid >= WIL6210_MAX_CID) {
591 wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid);
592 return;
593 }
594
595 sta = &wil->sta[cid];
596 if (sta->status == wil_sta_unused) {
597 wil_err(wil, "CID %d unused\n", cid);
598 return;
599 }
600
601 wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr);
602 for (i = 0; i < WIL_STA_TID_NUM; i++) {
603 struct wil_tid_ampdu_rx *r = sta->tid_rx[i];
604 sta->tid_rx[i] = NULL;
605 wil_tid_ampdu_rx_free(wil, r);
606 if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize)
607 sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil,
608 evt->agg_wsize, 0);
609 }
559} 610}
560 611
561static const struct { 612static const struct {
@@ -893,6 +944,38 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
893 return rc; 944 return rc;
894} 945}
895 946
947/**
948 * wmi_rxon - turn radio on/off
949 * @on: turn on if true, off otherwise
950 *
951 * Only switch radio. Channel should be set separately.
952 * No timeout for rxon - radio turned on forever unless some other call
953 * turns it off
954 */
955int wmi_rxon(struct wil6210_priv *wil, bool on)
956{
957 int rc;
958 struct {
959 struct wil6210_mbox_hdr_wmi wmi;
960 struct wmi_listen_started_event evt;
961 } __packed reply;
962
963 wil_info(wil, "%s(%s)\n", __func__, on ? "on" : "off");
964
965 if (on) {
966 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0,
967 WMI_LISTEN_STARTED_EVENTID,
968 &reply, sizeof(reply), 100);
969 if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS))
970 rc = -EINVAL;
971 } else {
972 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0,
973 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20);
974 }
975
976 return rc;
977}
978
896int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) 979int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
897{ 980{
898 struct wireless_dev *wdev = wil->wdev; 981 struct wireless_dev *wdev = wil->wdev;
@@ -906,6 +989,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
906 }, 989 },
907 .mid = 0, /* TODO - what is it? */ 990 .mid = 0, /* TODO - what is it? */
908 .decap_trans_type = WMI_DECAP_TYPE_802_3, 991 .decap_trans_type = WMI_DECAP_TYPE_802_3,
992 .reorder_type = WMI_RX_SW_REORDER,
909 }; 993 };
910 struct { 994 struct {
911 struct wil6210_mbox_hdr_wmi wmi; 995 struct wil6210_mbox_hdr_wmi wmi;
@@ -973,6 +1057,18 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r)
973 return 0; 1057 return 0;
974} 1058}
975 1059
1060int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason)
1061{
1062 struct wmi_disconnect_sta_cmd cmd = {
1063 .disconnect_reason = cpu_to_le16(reason),
1064 };
1065 memcpy(cmd.dst_mac, mac, ETH_ALEN);
1066
1067 wil_dbg_wmi(wil, "%s(%pM, reason %d)\n", __func__, mac, reason);
1068
1069 return wmi_send(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd));
1070}
1071
976void wmi_event_flush(struct wil6210_priv *wil) 1072void wmi_event_flush(struct wil6210_priv *wil)
977{ 1073{
978 struct pending_wmi_event *evt, *t; 1074 struct pending_wmi_event *evt, *t;
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index bf93ea859f2d..1fe41af81a59 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -67,7 +67,7 @@
67#include <linux/moduleparam.h> 67#include <linux/moduleparam.h>
68#include <linux/firmware.h> 68#include <linux/firmware.h>
69#include <linux/jiffies.h> 69#include <linux/jiffies.h>
70#include <linux/ieee80211.h> 70#include <net/cfg80211.h>
71#include "atmel.h" 71#include "atmel.h"
72 72
73#define DRIVER_MAJOR 0 73#define DRIVER_MAJOR 0
@@ -2273,7 +2273,7 @@ static int atmel_set_freq(struct net_device *dev,
2273 2273
2274 /* Hack to fall through... */ 2274 /* Hack to fall through... */
2275 fwrq->e = 0; 2275 fwrq->e = 0;
2276 fwrq->m = ieee80211_freq_to_dsss_chan(f); 2276 fwrq->m = ieee80211_frequency_to_channel(f);
2277 } 2277 }
2278 /* Setting by channel number */ 2278 /* Setting by channel number */
2279 if ((fwrq->m > 1000) || (fwrq->e > 0)) 2279 if ((fwrq->m > 1000) || (fwrq->e > 0))
@@ -2434,8 +2434,8 @@ static int atmel_get_range(struct net_device *dev,
2434 range->freq[k].i = i; /* List index */ 2434 range->freq[k].i = i; /* List index */
2435 2435
2436 /* Values in MHz -> * 10^5 * 10 */ 2436 /* Values in MHz -> * 10^5 * 10 */
2437 range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) * 2437 range->freq[k].m = 100000 *
2438 100000); 2438 ieee80211_channel_to_frequency(i, IEEE80211_BAND_2GHZ);
2439 range->freq[k++].e = 1; 2439 range->freq[k++].e = 1;
2440 } 2440 }
2441 range->num_frequency = k; 2441 range->num_frequency = k;
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 51ff0b198d0a..088d544ec63f 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -92,7 +92,7 @@ config B43_SDIO
92# if we can do DMA. 92# if we can do DMA.
93config B43_BCMA_PIO 93config B43_BCMA_PIO
94 bool 94 bool
95 depends on B43_BCMA 95 depends on B43 && B43_BCMA
96 select BCMA_BLOCKIO 96 select BCMA_BLOCKIO
97 default y 97 default y
98 98
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index 822aad8842f4..50517b801cb4 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -86,7 +86,7 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev,
86 86
87static inline bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature) 87static inline bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
88{ 88{
89 return 0; 89 return false;
90} 90}
91 91
92static inline void b43_debugfs_init(void) 92static inline void b43_debugfs_init(void)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c75237eb55a1..69fc3d65531a 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1549,7 +1549,7 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
1549 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon); 1549 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
1550 1550
1551 bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); 1551 bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
1552 len = min((size_t) dev->wl->current_beacon->len, 1552 len = min_t(size_t, dev->wl->current_beacon->len,
1553 0x200 - sizeof(struct b43_plcp_hdr6)); 1553 0x200 - sizeof(struct b43_plcp_hdr6));
1554 rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value; 1554 rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
1555 1555
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index f01676ac481b..dbaa51890198 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -133,9 +133,9 @@ void b43_phy_exit(struct b43_wldev *dev)
133bool b43_has_hardware_pctl(struct b43_wldev *dev) 133bool b43_has_hardware_pctl(struct b43_wldev *dev)
134{ 134{
135 if (!dev->phy.hardware_power_control) 135 if (!dev->phy.hardware_power_control)
136 return 0; 136 return false;
137 if (!dev->phy.ops->supports_hwpctl) 137 if (!dev->phy.ops->supports_hwpctl)
138 return 0; 138 return false;
139 return dev->phy.ops->supports_hwpctl(dev); 139 return dev->phy.ops->supports_hwpctl(dev);
140} 140}
141 141
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index a73ff8c9deb5..a4ff5e2a42b9 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -637,7 +637,7 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q)
637 637
638 ctl = b43_piorx_read32(q, B43_PIO8_RXCTL); 638 ctl = b43_piorx_read32(q, B43_PIO8_RXCTL);
639 if (!(ctl & B43_PIO8_RXCTL_FRAMERDY)) 639 if (!(ctl & B43_PIO8_RXCTL_FRAMERDY))
640 return 0; 640 return false;
641 b43_piorx_write32(q, B43_PIO8_RXCTL, 641 b43_piorx_write32(q, B43_PIO8_RXCTL,
642 B43_PIO8_RXCTL_FRAMERDY); 642 B43_PIO8_RXCTL_FRAMERDY);
643 for (i = 0; i < 10; i++) { 643 for (i = 0; i < 10; i++) {
@@ -651,7 +651,7 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q)
651 651
652 ctl = b43_piorx_read16(q, B43_PIO_RXCTL); 652 ctl = b43_piorx_read16(q, B43_PIO_RXCTL);
653 if (!(ctl & B43_PIO_RXCTL_FRAMERDY)) 653 if (!(ctl & B43_PIO_RXCTL_FRAMERDY))
654 return 0; 654 return false;
655 b43_piorx_write16(q, B43_PIO_RXCTL, 655 b43_piorx_write16(q, B43_PIO_RXCTL,
656 B43_PIO_RXCTL_FRAMERDY); 656 B43_PIO_RXCTL_FRAMERDY);
657 for (i = 0; i < 10; i++) { 657 for (i = 0; i < 10; i++) {
@@ -662,7 +662,7 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q)
662 } 662 }
663 } 663 }
664 b43dbg(q->dev->wl, "PIO RX timed out\n"); 664 b43dbg(q->dev->wl, "PIO RX timed out\n");
665 return 1; 665 return true;
666data_ready: 666data_ready:
667 667
668 /* Get the preamble (RX header) */ 668 /* Get the preamble (RX header) */
@@ -759,7 +759,7 @@ data_ready:
759 759
760 b43_rx(q->dev, skb, rxhdr); 760 b43_rx(q->dev, skb, rxhdr);
761 761
762 return 1; 762 return true;
763 763
764rx_error: 764rx_error:
765 if (err_msg) 765 if (err_msg)
@@ -769,7 +769,7 @@ rx_error:
769 else 769 else
770 b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY); 770 b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY);
771 771
772 return 1; 772 return true;
773} 773}
774 774
775void b43_pio_rx(struct b43_pio_rxqueue *q) 775void b43_pio_rx(struct b43_pio_rxqueue *q)
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c
index 8e8431d4eb0c..3190493bd07f 100644
--- a/drivers/net/wireless/b43/sysfs.c
+++ b/drivers/net/wireless/b43/sysfs.c
@@ -40,7 +40,7 @@ static int get_integer(const char *buf, size_t count)
40 40
41 if (count == 0) 41 if (count == 0)
42 goto out; 42 goto out;
43 count = min(count, (size_t) 10); 43 count = min_t(size_t, count, 10);
44 memcpy(tmp, buf, count); 44 memcpy(tmp, buf, count);
45 ret = simple_strtol(tmp, NULL, 10); 45 ret = simple_strtol(tmp, NULL, 10);
46 out: 46 out:
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 218a0f37af46..31adb8cf0291 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -337,7 +337,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
337 /* iv16 */ 337 /* iv16 */
338 memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3); 338 memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3);
339 } else { 339 } else {
340 iv_len = min((size_t) info->control.hw_key->iv_len, 340 iv_len = min_t(size_t, info->control.hw_key->iv_len,
341 ARRAY_SIZE(txhdr->iv)); 341 ARRAY_SIZE(txhdr->iv));
342 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); 342 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
343 } 343 }
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 349c77605231..1aec2146a2bf 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -978,7 +978,7 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
978 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon); 978 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
979 979
980 bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); 980 bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
981 len = min((size_t)dev->wl->current_beacon->len, 981 len = min_t(size_t, dev->wl->current_beacon->len,
982 0x200 - sizeof(struct b43legacy_plcp_hdr6)); 982 0x200 - sizeof(struct b43legacy_plcp_hdr6));
983 rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value; 983 rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
984 984
@@ -1155,7 +1155,7 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
1155 b43legacy_write_probe_resp_plcp(dev, 0x350, size, 1155 b43legacy_write_probe_resp_plcp(dev, 0x350, size,
1156 &b43legacy_b_ratetable[3]); 1156 &b43legacy_b_ratetable[3]);
1157 1157
1158 size = min((size_t)size, 1158 size = min_t(size_t, size,
1159 0x200 - sizeof(struct b43legacy_plcp_hdr6)); 1159 0x200 - sizeof(struct b43legacy_plcp_hdr6));
1160 b43legacy_write_template_common(dev, probe_resp_data, 1160 b43legacy_write_template_common(dev, probe_resp_data,
1161 size, ram_offset, 1161 size, ram_offset,
diff --git a/drivers/net/wireless/b43legacy/sysfs.c b/drivers/net/wireless/b43legacy/sysfs.c
index 57f8b089767c..2a1da15c913b 100644
--- a/drivers/net/wireless/b43legacy/sysfs.c
+++ b/drivers/net/wireless/b43legacy/sysfs.c
@@ -42,7 +42,7 @@ static int get_integer(const char *buf, size_t count)
42 42
43 if (count == 0) 43 if (count == 0)
44 goto out; 44 goto out;
45 count = min(count, (size_t)10); 45 count = min_t(size_t, count, 10);
46 memcpy(tmp, buf, count); 46 memcpy(tmp, buf, count);
47 ret = simple_strtol(tmp, NULL, 10); 47 ret = simple_strtol(tmp, NULL, 10);
48out: 48out:
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index 86588c9ff0f2..34bf3f0b729f 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -254,7 +254,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
254 B43legacy_TX4_MAC_KEYALG_SHIFT) & 254 B43legacy_TX4_MAC_KEYALG_SHIFT) &
255 B43legacy_TX4_MAC_KEYALG; 255 B43legacy_TX4_MAC_KEYALG;
256 wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control); 256 wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control);
257 iv_len = min((size_t)info->control.hw_key->iv_len, 257 iv_len = min_t(size_t, info->control.hw_key->iv_len,
258 ARRAY_SIZE(txhdr->iv)); 258 ARRAY_SIZE(txhdr->iv));
259 memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len); 259 memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
260 } else { 260 } else {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 07e7d2520257..4a6508e7e3a1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -53,6 +53,12 @@
53/* Maximum milliseconds to wait for F2 to come up */ 53/* Maximum milliseconds to wait for F2 to come up */
54#define SDIO_WAIT_F2RDY 3000 54#define SDIO_WAIT_F2RDY 3000
55 55
56#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
57#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
58
59static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
60module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
61MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
56 62
57static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id) 63static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
58{ 64{
@@ -487,7 +493,6 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
487 struct mmc_request mmc_req; 493 struct mmc_request mmc_req;
488 struct mmc_command mmc_cmd; 494 struct mmc_command mmc_cmd;
489 struct mmc_data mmc_dat; 495 struct mmc_data mmc_dat;
490 struct sg_table st;
491 struct scatterlist *sgl; 496 struct scatterlist *sgl;
492 int ret = 0; 497 int ret = 0;
493 498
@@ -532,16 +537,11 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
532 pkt_offset = 0; 537 pkt_offset = 0;
533 pkt_next = target_list->next; 538 pkt_next = target_list->next;
534 539
535 if (sg_alloc_table(&st, max_seg_cnt, GFP_KERNEL)) {
536 ret = -ENOMEM;
537 goto exit;
538 }
539
540 memset(&mmc_req, 0, sizeof(struct mmc_request)); 540 memset(&mmc_req, 0, sizeof(struct mmc_request));
541 memset(&mmc_cmd, 0, sizeof(struct mmc_command)); 541 memset(&mmc_cmd, 0, sizeof(struct mmc_command));
542 memset(&mmc_dat, 0, sizeof(struct mmc_data)); 542 memset(&mmc_dat, 0, sizeof(struct mmc_data));
543 543
544 mmc_dat.sg = st.sgl; 544 mmc_dat.sg = sdiodev->sgtable.sgl;
545 mmc_dat.blksz = func_blk_sz; 545 mmc_dat.blksz = func_blk_sz;
546 mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; 546 mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
547 mmc_cmd.opcode = SD_IO_RW_EXTENDED; 547 mmc_cmd.opcode = SD_IO_RW_EXTENDED;
@@ -557,7 +557,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
557 while (seg_sz) { 557 while (seg_sz) {
558 req_sz = 0; 558 req_sz = 0;
559 sg_cnt = 0; 559 sg_cnt = 0;
560 sgl = st.sgl; 560 sgl = sdiodev->sgtable.sgl;
561 /* prep sg table */ 561 /* prep sg table */
562 while (pkt_next != (struct sk_buff *)target_list) { 562 while (pkt_next != (struct sk_buff *)target_list) {
563 pkt_data = pkt_next->data + pkt_offset; 563 pkt_data = pkt_next->data + pkt_offset;
@@ -639,7 +639,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
639 } 639 }
640 640
641exit: 641exit:
642 sg_free_table(&st); 642 sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);
643 while ((pkt_next = __skb_dequeue(&local_list)) != NULL) 643 while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
644 brcmu_pkt_buf_free_skb(pkt_next); 644 brcmu_pkt_buf_free_skb(pkt_next);
645 645
@@ -863,6 +863,29 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
863 return 0; 863 return 0;
864} 864}
865 865
866static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
867{
868 uint nents;
869 int err;
870
871 if (!sdiodev->sg_support)
872 return;
873
874 nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
875 nents += (nents >> 4) + 1;
876
877 WARN_ON(nents > sdiodev->max_segment_count);
878
879 brcmf_dbg(TRACE, "nents=%d\n", nents);
880 err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);
881 if (err < 0) {
882 brcmf_err("allocation failed: disable scatter-gather");
883 sdiodev->sg_support = false;
884 }
885
886 sdiodev->txglomsz = brcmf_sdiod_txglomsz;
887}
888
866static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) 889static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
867{ 890{
868 if (sdiodev->bus) { 891 if (sdiodev->bus) {
@@ -880,6 +903,7 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
880 sdio_disable_func(sdiodev->func[1]); 903 sdio_disable_func(sdiodev->func[1]);
881 sdio_release_host(sdiodev->func[1]); 904 sdio_release_host(sdiodev->func[1]);
882 905
906 sg_free_table(&sdiodev->sgtable);
883 sdiodev->sbwad = 0; 907 sdiodev->sbwad = 0;
884 908
885 return 0; 909 return 0;
@@ -935,6 +959,11 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
935 SG_MAX_SINGLE_ALLOC); 959 SG_MAX_SINGLE_ALLOC);
936 sdiodev->max_segment_size = host->max_seg_size; 960 sdiodev->max_segment_size = host->max_seg_size;
937 961
962 /* allocate scatter-gather table. sg support
963 * will be disabled upon allocation failure.
964 */
965 brcmf_sdiod_sgtable_alloc(sdiodev);
966
938 /* try to attach to the target device */ 967 /* try to attach to the target device */
939 sdiodev->bus = brcmf_sdio_probe(sdiodev); 968 sdiodev->bus = brcmf_sdio_probe(sdiodev);
940 if (!sdiodev->bus) { 969 if (!sdiodev->bus) {
@@ -1072,9 +1101,7 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
1072 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1101 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1073 int ret = 0; 1102 int ret = 0;
1074 1103
1075 brcmf_dbg(SDIO, "\n"); 1104 brcmf_dbg(SDIO, "Enter\n");
1076
1077 atomic_set(&sdiodev->suspend, true);
1078 1105
1079 sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]); 1106 sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
1080 if (!(sdio_flags & MMC_PM_KEEP_POWER)) { 1107 if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
@@ -1082,9 +1109,12 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
1082 return -EINVAL; 1109 return -EINVAL;
1083 } 1110 }
1084 1111
1112 atomic_set(&sdiodev->suspend, true);
1113
1085 ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER); 1114 ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
1086 if (ret) { 1115 if (ret) {
1087 brcmf_err("Failed to set pm_flags\n"); 1116 brcmf_err("Failed to set pm_flags\n");
1117 atomic_set(&sdiodev->suspend, false);
1088 return ret; 1118 return ret;
1089 } 1119 }
1090 1120
@@ -1098,6 +1128,7 @@ static int brcmf_ops_sdio_resume(struct device *dev)
1098 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1128 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1099 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1129 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1100 1130
1131 brcmf_dbg(SDIO, "Enter\n");
1101 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); 1132 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
1102 atomic_set(&sdiodev->suspend, false); 1133 atomic_set(&sdiodev->suspend, false);
1103 return 0; 1134 return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index d4d966beb840..7d28cd385092 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1040,12 +1040,12 @@ void brcmf_detach(struct device *dev)
1040 1040
1041 brcmf_cfg80211_detach(drvr->config); 1041 brcmf_cfg80211_detach(drvr->config);
1042 1042
1043 brcmf_fws_deinit(drvr);
1044
1043 brcmf_bus_detach(drvr); 1045 brcmf_bus_detach(drvr);
1044 1046
1045 brcmf_proto_detach(drvr); 1047 brcmf_proto_detach(drvr);
1046 1048
1047 brcmf_fws_deinit(drvr);
1048
1049 brcmf_debugfs_detach(drvr); 1049 brcmf_debugfs_detach(drvr);
1050 bus_if->drvr = NULL; 1050 bus_if->drvr = NULL;
1051 kfree(drvr); 1051 kfree(drvr);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 49d4196ef9d2..a111b6fbbeba 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -113,8 +113,6 @@ struct rte_console {
113#define BRCMF_TXBOUND 20 /* Default for max tx frames in 113#define BRCMF_TXBOUND 20 /* Default for max tx frames in
114 one scheduling */ 114 one scheduling */
115 115
116#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
117
118#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ 116#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
119 117
120#define MEMBLOCK 2048 /* Block size used for downloading 118#define MEMBLOCK 2048 /* Block size used for downloading
@@ -304,7 +302,6 @@ struct rte_console {
304/* Flags for SDH calls */ 302/* Flags for SDH calls */
305#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) 303#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
306 304
307#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */
308#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change 305#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
309 * when idle 306 * when idle
310 */ 307 */
@@ -511,10 +508,6 @@ static const uint max_roundup = 512;
511 508
512#define ALIGNMENT 4 509#define ALIGNMENT 4
513 510
514static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
515module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
516MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
517
518enum brcmf_sdio_frmtype { 511enum brcmf_sdio_frmtype {
519 BRCMF_SDIO_FT_NORMAL, 512 BRCMF_SDIO_FT_NORMAL,
520 BRCMF_SDIO_FT_SUPER, 513 BRCMF_SDIO_FT_SUPER,
@@ -770,8 +763,6 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
770 return err; 763 return err;
771} 764}
772 765
773#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
774
775#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) 766#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
776 767
777/* Turn backplane clock on or off */ 768/* Turn backplane clock on or off */
@@ -870,7 +861,6 @@ static int brcmf_sdio_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
870 } 861 }
871#endif /* defined (DEBUG) */ 862#endif /* defined (DEBUG) */
872 863
873 bus->activity = true;
874 } else { 864 } else {
875 clkreq = 0; 865 clkreq = 0;
876 866
@@ -1240,6 +1230,28 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1240 bus->cur_read.len = 0; 1230 bus->cur_read.len = 0;
1241} 1231}
1242 1232
1233static void brcmf_sdio_txfail(struct brcmf_sdio *bus)
1234{
1235 struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
1236 u8 i, hi, lo;
1237
1238 /* On failure, abort the command and terminate the frame */
1239 brcmf_err("sdio error, abort command and terminate frame\n");
1240 bus->sdcnt.tx_sderrs++;
1241
1242 brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
1243 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
1244 bus->sdcnt.f1regdata++;
1245
1246 for (i = 0; i < 3; i++) {
1247 hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
1248 lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
1249 bus->sdcnt.f1regdata += 2;
1250 if ((hi == 0) && (lo == 0))
1251 break;
1252 }
1253}
1254
1243/* return total length of buffer chain */ 1255/* return total length of buffer chain */
1244static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus) 1256static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus)
1245{ 1257{
@@ -2110,7 +2122,7 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
2110 memcpy(pkt_pad->data, 2122 memcpy(pkt_pad->data,
2111 pkt->data + pkt->len - tail_chop, 2123 pkt->data + pkt->len - tail_chop,
2112 tail_chop); 2124 tail_chop);
2113 *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; 2125 *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
2114 skb_trim(pkt, pkt->len - tail_chop); 2126 skb_trim(pkt, pkt->len - tail_chop);
2115 skb_trim(pkt_pad, tail_pad + tail_chop); 2127 skb_trim(pkt_pad, tail_pad + tail_chop);
2116 __skb_queue_after(pktq, pkt, pkt_pad); 2128 __skb_queue_after(pktq, pkt, pkt_pad);
@@ -2158,7 +2170,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2158 * already properly aligned and does not 2170 * already properly aligned and does not
2159 * need an sdpcm header. 2171 * need an sdpcm header.
2160 */ 2172 */
2161 if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG) 2173 if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
2162 continue; 2174 continue;
2163 2175
2164 /* align packet data pointer */ 2176 /* align packet data pointer */
@@ -2192,10 +2204,10 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2192 if (BRCMF_BYTES_ON() && 2204 if (BRCMF_BYTES_ON() &&
2193 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || 2205 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
2194 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL))) 2206 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
2195 brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, 2207 brcmf_dbg_hex_dump(true, pkt_next->data, hd_info.len,
2196 "Tx Frame:\n"); 2208 "Tx Frame:\n");
2197 else if (BRCMF_HDRS_ON()) 2209 else if (BRCMF_HDRS_ON())
2198 brcmf_dbg_hex_dump(true, pkt_next, 2210 brcmf_dbg_hex_dump(true, pkt_next->data,
2199 head_pad + bus->tx_hdrlen, 2211 head_pad + bus->tx_hdrlen,
2200 "Tx Header:\n"); 2212 "Tx Header:\n");
2201 } 2213 }
@@ -2222,11 +2234,11 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
2222 u8 *hdr; 2234 u8 *hdr;
2223 u32 dat_offset; 2235 u32 dat_offset;
2224 u16 tail_pad; 2236 u16 tail_pad;
2225 u32 dummy_flags, chop_len; 2237 u16 dummy_flags, chop_len;
2226 struct sk_buff *pkt_next, *tmp, *pkt_prev; 2238 struct sk_buff *pkt_next, *tmp, *pkt_prev;
2227 2239
2228 skb_queue_walk_safe(pktq, pkt_next, tmp) { 2240 skb_queue_walk_safe(pktq, pkt_next, tmp) {
2229 dummy_flags = *(u32 *)(pkt_next->cb); 2241 dummy_flags = *(u16 *)(pkt_next->cb);
2230 if (dummy_flags & ALIGN_SKB_FLAG) { 2242 if (dummy_flags & ALIGN_SKB_FLAG) {
2231 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; 2243 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
2232 if (chop_len) { 2244 if (chop_len) {
@@ -2255,7 +2267,6 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2255 uint chan) 2267 uint chan)
2256{ 2268{
2257 int ret; 2269 int ret;
2258 int i;
2259 struct sk_buff *pkt_next, *tmp; 2270 struct sk_buff *pkt_next, *tmp;
2260 2271
2261 brcmf_dbg(TRACE, "Enter\n"); 2272 brcmf_dbg(TRACE, "Enter\n");
@@ -2268,28 +2279,9 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2268 ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq); 2279 ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq);
2269 bus->sdcnt.f2txdata++; 2280 bus->sdcnt.f2txdata++;
2270 2281
2271 if (ret < 0) { 2282 if (ret < 0)
2272 /* On failure, abort the command and terminate the frame */ 2283 brcmf_sdio_txfail(bus);
2273 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2274 ret);
2275 bus->sdcnt.tx_sderrs++;
2276 2284
2277 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2278 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2279 SFC_WF_TERM, NULL);
2280 bus->sdcnt.f1regdata++;
2281
2282 for (i = 0; i < 3; i++) {
2283 u8 hi, lo;
2284 hi = brcmf_sdiod_regrb(bus->sdiodev,
2285 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2286 lo = brcmf_sdiod_regrb(bus->sdiodev,
2287 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2288 bus->sdcnt.f1regdata += 2;
2289 if ((hi == 0) && (lo == 0))
2290 break;
2291 }
2292 }
2293 sdio_release_host(bus->sdiodev->func[1]); 2285 sdio_release_host(bus->sdiodev->func[1]);
2294 2286
2295done: 2287done:
@@ -2322,7 +2314,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2322 __skb_queue_head_init(&pktq); 2314 __skb_queue_head_init(&pktq);
2323 if (bus->txglom) 2315 if (bus->txglom)
2324 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq, 2316 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
2325 brcmf_sdio_txglomsz); 2317 bus->sdiodev->txglomsz);
2326 pkt_num = min_t(u32, pkt_num, 2318 pkt_num = min_t(u32, pkt_num,
2327 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)); 2319 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
2328 spin_lock_bh(&bus->txqlock); 2320 spin_lock_bh(&bus->txqlock);
@@ -2341,7 +2333,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2341 cnt += i; 2333 cnt += i;
2342 2334
2343 /* In poll mode, need to check for other events */ 2335 /* In poll mode, need to check for other events */
2344 if (!bus->intr && cnt) { 2336 if (!bus->intr) {
2345 /* Check device status, signal pending interrupt */ 2337 /* Check device status, signal pending interrupt */
2346 sdio_claim_host(bus->sdiodev->func[1]); 2338 sdio_claim_host(bus->sdiodev->func[1]);
2347 ret = r_sdreg32(bus, &intstatus, 2339 ret = r_sdreg32(bus, &intstatus,
@@ -2447,12 +2439,21 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus)
2447 } 2439 }
2448} 2440}
2449 2441
2442static void atomic_orr(int val, atomic_t *v)
2443{
2444 int old_val;
2445
2446 old_val = atomic_read(v);
2447 while (atomic_cmpxchg(v, old_val, val | old_val) != old_val)
2448 old_val = atomic_read(v);
2449}
2450
2450static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) 2451static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2451{ 2452{
2452 struct brcmf_core *buscore; 2453 struct brcmf_core *buscore;
2453 u32 addr; 2454 u32 addr;
2454 unsigned long val; 2455 unsigned long val;
2455 int n, ret; 2456 int ret;
2456 2457
2457 buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); 2458 buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
2458 addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus); 2459 addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
@@ -2460,7 +2461,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2460 val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret); 2461 val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
2461 bus->sdcnt.f1regdata++; 2462 bus->sdcnt.f1regdata++;
2462 if (ret != 0) 2463 if (ret != 0)
2463 val = 0; 2464 return ret;
2464 2465
2465 val &= bus->hostintmask; 2466 val &= bus->hostintmask;
2466 atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE)); 2467 atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE));
@@ -2469,13 +2470,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2469 if (val) { 2470 if (val) {
2470 brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); 2471 brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
2471 bus->sdcnt.f1regdata++; 2472 bus->sdcnt.f1regdata++;
2472 } 2473 atomic_orr(val, &bus->intstatus);
2473
2474 if (ret) {
2475 atomic_set(&bus->intstatus, 0);
2476 } else if (val) {
2477 for_each_set_bit(n, &val, 32)
2478 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2479 } 2474 }
2480 2475
2481 return ret; 2476 return ret;
@@ -2485,10 +2480,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2485{ 2480{
2486 u32 newstatus = 0; 2481 u32 newstatus = 0;
2487 unsigned long intstatus; 2482 unsigned long intstatus;
2488 uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
2489 uint txlimit = bus->txbound; /* Tx frames to send before resched */ 2483 uint txlimit = bus->txbound; /* Tx frames to send before resched */
2490 uint framecnt = 0; /* Temporary counter of tx/rx frames */ 2484 uint framecnt; /* Temporary counter of tx/rx frames */
2491 int err = 0, n; 2485 int err = 0;
2492 2486
2493 brcmf_dbg(TRACE, "Enter\n"); 2487 brcmf_dbg(TRACE, "Enter\n");
2494 2488
@@ -2585,58 +2579,30 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2585 intstatus &= ~I_HMB_FRAME_IND; 2579 intstatus &= ~I_HMB_FRAME_IND;
2586 2580
2587 /* On frame indication, read available frames */ 2581 /* On frame indication, read available frames */
2588 if (PKT_AVAILABLE() && bus->clkstate == CLK_AVAIL) { 2582 if ((intstatus & I_HMB_FRAME_IND) && (bus->clkstate == CLK_AVAIL)) {
2589 framecnt = brcmf_sdio_readframes(bus, rxlimit); 2583 brcmf_sdio_readframes(bus, bus->rxbound);
2590 if (!bus->rxpending) 2584 if (!bus->rxpending)
2591 intstatus &= ~I_HMB_FRAME_IND; 2585 intstatus &= ~I_HMB_FRAME_IND;
2592 rxlimit -= min(framecnt, rxlimit);
2593 } 2586 }
2594 2587
2595 /* Keep still-pending events for next scheduling */ 2588 /* Keep still-pending events for next scheduling */
2596 if (intstatus) { 2589 if (intstatus)
2597 for_each_set_bit(n, &intstatus, 32) 2590 atomic_orr(intstatus, &bus->intstatus);
2598 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2599 }
2600 2591
2601 brcmf_sdio_clrintr(bus); 2592 brcmf_sdio_clrintr(bus);
2602 2593
2603 if (data_ok(bus) && bus->ctrl_frame_stat && 2594 if (data_ok(bus) && bus->ctrl_frame_stat &&
2604 (bus->clkstate == CLK_AVAIL)) { 2595 (bus->clkstate == CLK_AVAIL)) {
2605 int i;
2606 2596
2607 sdio_claim_host(bus->sdiodev->func[1]); 2597 sdio_claim_host(bus->sdiodev->func[1]);
2608 err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf, 2598 err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf,
2609 (u32)bus->ctrl_frame_len); 2599 (u32)bus->ctrl_frame_len);
2610 2600
2611 if (err < 0) { 2601 if (err < 0)
2612 /* On failure, abort the command and 2602 brcmf_sdio_txfail(bus);
2613 terminate the frame */ 2603 else
2614 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2615 err);
2616 bus->sdcnt.tx_sderrs++;
2617
2618 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2619
2620 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2621 SFC_WF_TERM, &err);
2622 bus->sdcnt.f1regdata++;
2623
2624 for (i = 0; i < 3; i++) {
2625 u8 hi, lo;
2626 hi = brcmf_sdiod_regrb(bus->sdiodev,
2627 SBSDIO_FUNC1_WFRAMEBCHI,
2628 &err);
2629 lo = brcmf_sdiod_regrb(bus->sdiodev,
2630 SBSDIO_FUNC1_WFRAMEBCLO,
2631 &err);
2632 bus->sdcnt.f1regdata += 2;
2633 if ((hi == 0) && (lo == 0))
2634 break;
2635 }
2636
2637 } else {
2638 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP; 2604 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2639 } 2605
2640 sdio_release_host(bus->sdiodev->func[1]); 2606 sdio_release_host(bus->sdiodev->func[1]);
2641 bus->ctrl_frame_stat = false; 2607 bus->ctrl_frame_stat = false;
2642 brcmf_sdio_wait_event_wakeup(bus); 2608 brcmf_sdio_wait_event_wakeup(bus);
@@ -2647,8 +2613,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2647 && data_ok(bus)) { 2613 && data_ok(bus)) {
2648 framecnt = bus->rxpending ? min(txlimit, bus->txminmax) : 2614 framecnt = bus->rxpending ? min(txlimit, bus->txminmax) :
2649 txlimit; 2615 txlimit;
2650 framecnt = brcmf_sdio_sendfromq(bus, framecnt); 2616 brcmf_sdio_sendfromq(bus, framecnt);
2651 txlimit -= framecnt;
2652 } 2617 }
2653 2618
2654 if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) { 2619 if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) {
@@ -2658,19 +2623,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2658 atomic_read(&bus->ipend) > 0 || 2623 atomic_read(&bus->ipend) > 0 ||
2659 (!atomic_read(&bus->fcstate) && 2624 (!atomic_read(&bus->fcstate) &&
2660 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && 2625 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
2661 data_ok(bus)) || PKT_AVAILABLE()) { 2626 data_ok(bus))) {
2662 atomic_inc(&bus->dpc_tskcnt); 2627 atomic_inc(&bus->dpc_tskcnt);
2663 } 2628 }
2664
2665 /* If we're done for now, turn off clock request. */
2666 if ((bus->clkstate != CLK_PENDING)
2667 && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
2668 bus->activity = false;
2669 brcmf_dbg(SDIO, "idle state\n");
2670 sdio_claim_host(bus->sdiodev->func[1]);
2671 brcmf_sdio_bus_sleep(bus, true, false);
2672 sdio_release_host(bus->sdiodev->func[1]);
2673 }
2674} 2629}
2675 2630
2676static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev) 2631static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
@@ -2685,15 +2640,13 @@ static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
2685static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) 2640static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2686{ 2641{
2687 int ret = -EBADE; 2642 int ret = -EBADE;
2688 uint datalen, prec; 2643 uint prec;
2689 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2644 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2690 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2645 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2691 struct brcmf_sdio *bus = sdiodev->bus; 2646 struct brcmf_sdio *bus = sdiodev->bus;
2692 ulong flags; 2647 ulong flags;
2693 2648
2694 brcmf_dbg(TRACE, "Enter\n"); 2649 brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len);
2695
2696 datalen = pkt->len;
2697 2650
2698 /* Add space for the header */ 2651 /* Add space for the header */
2699 skb_push(pkt, bus->tx_hdrlen); 2652 skb_push(pkt, bus->tx_hdrlen);
@@ -2708,6 +2661,8 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2708 2661
2709 /* Priority based enq */ 2662 /* Priority based enq */
2710 spin_lock_irqsave(&bus->txqlock, flags); 2663 spin_lock_irqsave(&bus->txqlock, flags);
2664 /* reset bus_flags in packet cb */
2665 *(u16 *)(pkt->cb) = 0;
2711 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { 2666 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
2712 skb_pull(pkt, bus->tx_hdrlen); 2667 skb_pull(pkt, bus->tx_hdrlen);
2713 brcmf_err("out of bus->txq !!!\n"); 2668 brcmf_err("out of bus->txq !!!\n");
@@ -2817,38 +2772,15 @@ break2:
2817 2772
2818static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) 2773static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2819{ 2774{
2820 int i;
2821 int ret; 2775 int ret;
2822 2776
2823 bus->ctrl_frame_stat = false; 2777 bus->ctrl_frame_stat = false;
2824 ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len); 2778 ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
2825 2779
2826 if (ret < 0) { 2780 if (ret < 0)
2827 /* On failure, abort the command and terminate the frame */ 2781 brcmf_sdio_txfail(bus);
2828 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", 2782 else
2829 ret); 2783 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2830 bus->sdcnt.tx_sderrs++;
2831
2832 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2833
2834 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2835 SFC_WF_TERM, NULL);
2836 bus->sdcnt.f1regdata++;
2837
2838 for (i = 0; i < 3; i++) {
2839 u8 hi, lo;
2840 hi = brcmf_sdiod_regrb(bus->sdiodev,
2841 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2842 lo = brcmf_sdiod_regrb(bus->sdiodev,
2843 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2844 bus->sdcnt.f1regdata += 2;
2845 if (hi == 0 && lo == 0)
2846 break;
2847 }
2848 return ret;
2849 }
2850
2851 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2852 2784
2853 return ret; 2785 return ret;
2854} 2786}
@@ -2947,15 +2879,6 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2947 } while (ret < 0 && retries++ < TXRETRIES); 2879 } while (ret < 0 && retries++ < TXRETRIES);
2948 } 2880 }
2949 2881
2950 if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) &&
2951 atomic_read(&bus->dpc_tskcnt) == 0) {
2952 bus->activity = false;
2953 sdio_claim_host(bus->sdiodev->func[1]);
2954 brcmf_dbg(INFO, "idle\n");
2955 brcmf_sdio_clkctl(bus, CLK_NONE, true);
2956 sdio_release_host(bus->sdiodev->func[1]);
2957 }
2958
2959 if (ret) 2882 if (ret)
2960 bus->sdcnt.tx_ctlerrs++; 2883 bus->sdcnt.tx_ctlerrs++;
2961 else 2884 else
@@ -3753,8 +3676,8 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
3753 datawork); 3676 datawork);
3754 3677
3755 while (atomic_read(&bus->dpc_tskcnt)) { 3678 while (atomic_read(&bus->dpc_tskcnt)) {
3679 atomic_set(&bus->dpc_tskcnt, 0);
3756 brcmf_sdio_dpc(bus); 3680 brcmf_sdio_dpc(bus);
3757 atomic_dec(&bus->dpc_tskcnt);
3758 } 3681 }
3759} 3682}
3760 3683
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 5e53eb1b2ffa..3deab7959a0d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -180,6 +180,8 @@ struct brcmf_sdio_dev {
180 uint max_request_size; 180 uint max_request_size;
181 ushort max_segment_count; 181 ushort max_segment_count;
182 uint max_segment_size; 182 uint max_segment_size;
183 uint txglomsz;
184 struct sg_table sgtable;
183}; 185};
184 186
185/* sdio core registers */ 187/* sdio core registers */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index a54db9185747..00bd1e16c3ce 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
21#include <linux/module.h>
21#include <net/cfg80211.h> 22#include <net/cfg80211.h>
22#include <net/netlink.h> 23#include <net/netlink.h>
23 24
@@ -251,6 +252,10 @@ struct parsed_vndr_ies {
251 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT]; 252 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
252}; 253};
253 254
255static int brcmf_roamoff;
256module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
257MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
258
254/* Quarter dBm units to mW 259/* Quarter dBm units to mW
255 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 260 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
256 * Table is offset so the last entry is largest mW value that fits in 261 * Table is offset so the last entry is largest mW value that fits in
@@ -4444,7 +4449,9 @@ static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4444 u32 event = e->event_code; 4449 u32 event = e->event_code;
4445 u16 flags = e->flags; 4450 u16 flags = e->flags;
4446 4451
4447 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { 4452 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4453 (event == BRCMF_E_DISASSOC_IND) ||
4454 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4448 brcmf_dbg(CONN, "Processing link down\n"); 4455 brcmf_dbg(CONN, "Processing link down\n");
4449 return true; 4456 return true;
4450 } 4457 }
@@ -4688,6 +4695,7 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4688 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 4695 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4689 struct ieee80211_channel *chan; 4696 struct ieee80211_channel *chan;
4690 s32 err = 0; 4697 s32 err = 0;
4698 u16 reason;
4691 4699
4692 if (ifp->vif->mode == WL_MODE_AP) { 4700 if (ifp->vif->mode == WL_MODE_AP) {
4693 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); 4701 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
@@ -4709,9 +4717,15 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4709 if (!brcmf_is_ibssmode(ifp->vif)) { 4717 if (!brcmf_is_ibssmode(ifp->vif)) {
4710 brcmf_bss_connect_done(cfg, ndev, e, false); 4718 brcmf_bss_connect_done(cfg, ndev, e, false);
4711 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, 4719 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4712 &ifp->vif->sme_state)) 4720 &ifp->vif->sme_state)) {
4713 cfg80211_disconnected(ndev, 0, NULL, 0, 4721 reason = 0;
4722 if (((e->event_code == BRCMF_E_DEAUTH_IND) ||
4723 (e->event_code == BRCMF_E_DISASSOC_IND)) &&
4724 (e->reason != WLAN_REASON_UNSPECIFIED))
4725 reason = e->reason;
4726 cfg80211_disconnected(ndev, reason, NULL, 0,
4714 GFP_KERNEL); 4727 GFP_KERNEL);
4728 }
4715 } 4729 }
4716 brcmf_link_down(ifp->vif); 4730 brcmf_link_down(ifp->vif);
4717 brcmf_init_prof(ndev_to_prof(ndev)); 4731 brcmf_init_prof(ndev_to_prof(ndev));
@@ -4905,11 +4919,8 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4905 4919
4906 cfg->scan_request = NULL; 4920 cfg->scan_request = NULL;
4907 cfg->pwr_save = true; 4921 cfg->pwr_save = true;
4908 cfg->roam_on = true; /* roam on & off switch. 4922 cfg->active_scan = true; /* we do active scan per default */
4909 we enable roam per default */ 4923 cfg->dongle_up = false; /* dongle is not up yet */
4910 cfg->active_scan = true; /* we do active scan for
4911 specific scan per default */
4912 cfg->dongle_up = false; /* dongle is not up yet */
4913 err = brcmf_init_priv_mem(cfg); 4924 err = brcmf_init_priv_mem(cfg);
4914 if (err) 4925 if (err)
4915 return err; 4926 return err;
@@ -5029,7 +5040,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5029} 5040}
5030 5041
5031static s32 5042static s32
5032brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout) 5043brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5033{ 5044{
5034 s32 err = 0; 5045 s32 err = 0;
5035 __le32 roamtrigger[2]; 5046 __le32 roamtrigger[2];
@@ -5039,7 +5050,7 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5039 * Setup timeout if Beacons are lost and roam is 5050 * Setup timeout if Beacons are lost and roam is
5040 * off to report link down 5051 * off to report link down
5041 */ 5052 */
5042 if (roamvar) { 5053 if (brcmf_roamoff) {
5043 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout); 5054 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5044 if (err) { 5055 if (err) {
5045 brcmf_err("bcn_timeout error (%d)\n", err); 5056 brcmf_err("bcn_timeout error (%d)\n", err);
@@ -5051,8 +5062,9 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5051 * Enable/Disable built-in roaming to allow supplicant 5062 * Enable/Disable built-in roaming to allow supplicant
5052 * to take care of roaming 5063 * to take care of roaming
5053 */ 5064 */
5054 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On"); 5065 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5055 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar); 5066 brcmf_roamoff ? "Off" : "On");
5067 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5056 if (err) { 5068 if (err) {
5057 brcmf_err("roam_off error (%d)\n", err); 5069 brcmf_err("roam_off error (%d)\n", err);
5058 goto dongle_rom_out; 5070 goto dongle_rom_out;
@@ -5294,6 +5306,8 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5294 u32 band_list[3]; 5306 u32 band_list[3];
5295 u32 nmode; 5307 u32 nmode;
5296 u32 bw_cap[2] = { 0, 0 }; 5308 u32 bw_cap[2] = { 0, 0 };
5309 u32 rxchain;
5310 u32 nchain;
5297 s8 phy; 5311 s8 phy;
5298 s32 err; 5312 s32 err;
5299 u32 nband; 5313 u32 nband;
@@ -5330,6 +5344,16 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5330 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode, 5344 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
5331 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]); 5345 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
5332 5346
5347 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5348 if (err) {
5349 brcmf_err("rxchain error (%d)\n", err);
5350 nchain = 1;
5351 } else {
5352 for (nchain = 0; rxchain; nchain++)
5353 rxchain = rxchain & (rxchain - 1);
5354 }
5355 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5356
5333 err = brcmf_construct_reginfo(cfg, bw_cap); 5357 err = brcmf_construct_reginfo(cfg, bw_cap);
5334 if (err) { 5358 if (err) {
5335 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err); 5359 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
@@ -5358,10 +5382,7 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5358 band->ht_cap.ht_supported = true; 5382 band->ht_cap.ht_supported = true;
5359 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 5383 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5360 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; 5384 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5361 /* An HT shall support all EQM rates for one spatial 5385 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5362 * stream
5363 */
5364 band->ht_cap.mcs.rx_mask[0] = 0xff;
5365 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 5386 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5366 bands[band->band] = band; 5387 bands[band->band] = band;
5367 } 5388 }
@@ -5408,7 +5429,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5408 brcmf_dbg(INFO, "power save set to %s\n", 5429 brcmf_dbg(INFO, "power save set to %s\n",
5409 (power_mode ? "enabled" : "disabled")); 5430 (power_mode ? "enabled" : "disabled"));
5410 5431
5411 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT); 5432 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5412 if (err) 5433 if (err)
5413 goto default_conf_out; 5434 goto default_conf_out;
5414 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, 5435 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 254feed2860e..5715bb0708cf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -402,7 +402,6 @@ struct brcmf_cfg80211_info {
402 bool ibss_starter; 402 bool ibss_starter;
403 bool pwr_save; 403 bool pwr_save;
404 bool dongle_up; 404 bool dongle_up;
405 bool roam_on;
406 bool scan_tried; 405 bool scan_tried;
407 u8 *dcmd_buf; 406 u8 *dcmd_buf;
408 u8 *extra_buf; 407 u8 *extra_buf;
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
index 5a9ffd3a6a6c..e23d67e0bfe6 100644
--- a/drivers/net/wireless/cw1200/fwio.c
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -202,8 +202,8 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
202 } 202 }
203 203
204 /* calculate the block size */ 204 /* calculate the block size */
205 tx_size = block_size = min((size_t)(firmware->size - put), 205 tx_size = block_size = min_t(size_t, firmware->size - put,
206 (size_t)DOWNLOAD_BLOCK_SIZE); 206 DOWNLOAD_BLOCK_SIZE);
207 207
208 memcpy(buf, &firmware->data[put], block_size); 208 memcpy(buf, &firmware->data[put], block_size);
209 if (block_size < DOWNLOAD_BLOCK_SIZE) { 209 if (block_size < DOWNLOAD_BLOCK_SIZE) {
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 9f825f2620da..b6ec51923b20 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -677,6 +677,8 @@ static const struct pcmcia_device_id hostap_cs_ids[] = {
677 PCMCIA_DEVICE_PROD_ID12( 677 PCMCIA_DEVICE_PROD_ID12(
678 "ZoomAir 11Mbps High", "Rate wireless Networking", 678 "ZoomAir 11Mbps High", "Rate wireless Networking",
679 0x273fe3db, 0x32a1eaee), 679 0x273fe3db, 0x32a1eaee),
680 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card",
681 0xa37434e9, 0x9762e8f1),
680 PCMCIA_DEVICE_PROD_ID123( 682 PCMCIA_DEVICE_PROD_ID123(
681 "Pretec", "CompactWLAN Card 802.11b", "2.5", 683 "Pretec", "CompactWLAN Card 802.11b", "2.5",
682 0x1cadd3e5, 0xe697636c, 0x7a5bfcf1), 684 0x1cadd3e5, 0xe697636c, 0x7a5bfcf1),
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 3aba49259ef1..dfc6dfc56d52 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -7065,7 +7065,7 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
7065 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 7065 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7066 return -E2BIG; 7066 return -E2BIG;
7067 7067
7068 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); 7068 wrqu->data.length = min_t(size_t, wrqu->data.length, sizeof(priv->nick));
7069 memset(priv->nick, 0, sizeof(priv->nick)); 7069 memset(priv->nick, 0, sizeof(priv->nick));
7070 memcpy(priv->nick, extra, wrqu->data.length); 7070 memcpy(priv->nick, extra, wrqu->data.length);
7071 7071
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 139326065bd9..c5aa404069f3 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -9169,7 +9169,7 @@ static int ipw_wx_set_nick(struct net_device *dev,
9169 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 9169 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
9170 return -E2BIG; 9170 return -E2BIG;
9171 mutex_lock(&priv->mutex); 9171 mutex_lock(&priv->mutex);
9172 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); 9172 wrqu->data.length = min_t(size_t, wrqu->data.length, sizeof(priv->nick));
9173 memset(priv->nick, 0, sizeof(priv->nick)); 9173 memset(priv->nick, 0, sizeof(priv->nick));
9174 memcpy(priv->nick, extra, wrqu->data.length); 9174 memcpy(priv->nick, extra, wrqu->data.length);
9175 IPW_DEBUG_TRACE("<<\n"); 9175 IPW_DEBUG_TRACE("<<\n");
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index 0487461ae4da..dc1d20cf64ee 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -1248,14 +1248,7 @@ il3945_rx_handle(struct il_priv *il)
1248 len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK; 1248 len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK;
1249 len += sizeof(u32); /* account for status word */ 1249 len += sizeof(u32); /* account for status word */
1250 1250
1251 /* Reclaim a command buffer only if this packet is a response 1251 reclaim = il_need_reclaim(il, pkt);
1252 * to a (driver-originated) command.
1253 * If the packet (e.g. Rx frame) originated from uCode,
1254 * there is no command buffer to reclaim.
1255 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
1256 * but apparently a few don't get set; catch them here. */
1257 reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
1258 pkt->hdr.cmd != N_STATS && pkt->hdr.cmd != C_TX;
1259 1252
1260 /* Based on type of command response or notification, 1253 /* Based on type of command response or notification,
1261 * handle those that need handling via function in 1254 * handle those that need handling via function in
@@ -1495,12 +1488,14 @@ il3945_irq_tasklet(struct il_priv *il)
1495 if (inta & CSR_INT_BIT_WAKEUP) { 1488 if (inta & CSR_INT_BIT_WAKEUP) {
1496 D_ISR("Wakeup interrupt\n"); 1489 D_ISR("Wakeup interrupt\n");
1497 il_rx_queue_update_write_ptr(il, &il->rxq); 1490 il_rx_queue_update_write_ptr(il, &il->rxq);
1491
1492 spin_lock_irqsave(&il->lock, flags);
1498 il_txq_update_write_ptr(il, &il->txq[0]); 1493 il_txq_update_write_ptr(il, &il->txq[0]);
1499 il_txq_update_write_ptr(il, &il->txq[1]); 1494 il_txq_update_write_ptr(il, &il->txq[1]);
1500 il_txq_update_write_ptr(il, &il->txq[2]); 1495 il_txq_update_write_ptr(il, &il->txq[2]);
1501 il_txq_update_write_ptr(il, &il->txq[3]); 1496 il_txq_update_write_ptr(il, &il->txq[3]);
1502 il_txq_update_write_ptr(il, &il->txq[4]); 1497 il_txq_update_write_ptr(il, &il->txq[4]);
1503 il_txq_update_write_ptr(il, &il->txq[5]); 1498 spin_unlock_irqrestore(&il->lock, flags);
1504 1499
1505 il->isr_stats.wakeup++; 1500 il->isr_stats.wakeup++;
1506 handled |= CSR_INT_BIT_WAKEUP; 1501 handled |= CSR_INT_BIT_WAKEUP;
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 43f488a8cda2..888ad5c74639 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -92,7 +92,6 @@ il4965_check_abort_status(struct il_priv *il, u8 frame_count, u32 status)
92 * EEPROM 92 * EEPROM
93 */ 93 */
94struct il_mod_params il4965_mod_params = { 94struct il_mod_params il4965_mod_params = {
95 .amsdu_size_8K = 1,
96 .restart_fw = 1, 95 .restart_fw = 1,
97 /* the rest are 0 by default */ 96 /* the rest are 0 by default */
98}; 97};
@@ -4274,17 +4273,7 @@ il4965_rx_handle(struct il_priv *il)
4274 len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK; 4273 len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK;
4275 len += sizeof(u32); /* account for status word */ 4274 len += sizeof(u32); /* account for status word */
4276 4275
4277 /* Reclaim a command buffer only if this packet is a response 4276 reclaim = il_need_reclaim(il, pkt);
4278 * to a (driver-originated) command.
4279 * If the packet (e.g. Rx frame) originated from uCode,
4280 * there is no command buffer to reclaim.
4281 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
4282 * but apparently a few don't get set; catch them here. */
4283 reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
4284 (pkt->hdr.cmd != N_RX_PHY) && (pkt->hdr.cmd != N_RX) &&
4285 (pkt->hdr.cmd != N_RX_MPDU) &&
4286 (pkt->hdr.cmd != N_COMPRESSED_BA) &&
4287 (pkt->hdr.cmd != N_STATS) && (pkt->hdr.cmd != C_TX);
4288 4277
4289 /* Based on type of command response or notification, 4278 /* Based on type of command response or notification,
4290 * handle those that need handling via function in 4279 * handle those that need handling via function in
@@ -6876,6 +6865,6 @@ module_param_named(11n_disable, il4965_mod_params.disable_11n, int, S_IRUGO);
6876MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); 6865MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
6877module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K, int, 6866module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K, int,
6878 S_IRUGO); 6867 S_IRUGO);
6879MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); 6868MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0 [disabled])");
6880module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO); 6869module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO);
6881MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 6870MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlegacy/commands.h b/drivers/net/wireless/iwlegacy/commands.h
index 048421511988..dd744135c956 100644
--- a/drivers/net/wireless/iwlegacy/commands.h
+++ b/drivers/net/wireless/iwlegacy/commands.h
@@ -2270,7 +2270,8 @@ struct il_spectrum_notification {
2270 */ 2270 */
2271#define IL_POWER_VEC_SIZE 5 2271#define IL_POWER_VEC_SIZE 5
2272 2272
2273#define IL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) 2273#define IL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0))
2274#define IL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2))
2274#define IL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) 2275#define IL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3))
2275 2276
2276struct il3945_powertable_cmd { 2277struct il3945_powertable_cmd {
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 02e8233ccf29..4f42174d9994 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -1078,29 +1078,82 @@ EXPORT_SYMBOL(il_get_channel_info);
1078 * Setting power level allows the card to go to sleep when not busy. 1078 * Setting power level allows the card to go to sleep when not busy.
1079 * 1079 *
1080 * We calculate a sleep command based on the required latency, which 1080 * We calculate a sleep command based on the required latency, which
1081 * we get from mac80211. In order to handle thermal throttling, we can 1081 * we get from mac80211.
1082 * also use pre-defined power levels.
1083 */ 1082 */
1084 1083
1085/* 1084#define SLP_VEC(X0, X1, X2, X3, X4) { \
1086 * This defines the old power levels. They are still used by default 1085 cpu_to_le32(X0), \
1087 * (level 1) and for thermal throttle (levels 3 through 5) 1086 cpu_to_le32(X1), \
1088 */ 1087 cpu_to_le32(X2), \
1089 1088 cpu_to_le32(X3), \
1090struct il_power_vec_entry { 1089 cpu_to_le32(X4) \
1091 struct il_powertable_cmd cmd; 1090}
1092 u8 no_dtim; /* number of skip dtim */
1093};
1094 1091
1095static void 1092static void
1096il_power_sleep_cam_cmd(struct il_priv *il, struct il_powertable_cmd *cmd) 1093il_build_powertable_cmd(struct il_priv *il, struct il_powertable_cmd *cmd)
1097{ 1094{
1095 const __le32 interval[3][IL_POWER_VEC_SIZE] = {
1096 SLP_VEC(2, 2, 4, 6, 0xFF),
1097 SLP_VEC(2, 4, 7, 10, 10),
1098 SLP_VEC(4, 7, 10, 10, 0xFF)
1099 };
1100 int i, dtim_period, no_dtim;
1101 u32 max_sleep;
1102 bool skip;
1103
1098 memset(cmd, 0, sizeof(*cmd)); 1104 memset(cmd, 0, sizeof(*cmd));
1099 1105
1100 if (il->power_data.pci_pm) 1106 if (il->power_data.pci_pm)
1101 cmd->flags |= IL_POWER_PCI_PM_MSK; 1107 cmd->flags |= IL_POWER_PCI_PM_MSK;
1102 1108
1103 D_POWER("Sleep command for CAM\n"); 1109 /* if no Power Save, we are done */
1110 if (il->power_data.ps_disabled)
1111 return;
1112
1113 cmd->flags = IL_POWER_DRIVER_ALLOW_SLEEP_MSK;
1114 cmd->keep_alive_seconds = 0;
1115 cmd->debug_flags = 0;
1116 cmd->rx_data_timeout = cpu_to_le32(25 * 1024);
1117 cmd->tx_data_timeout = cpu_to_le32(25 * 1024);
1118 cmd->keep_alive_beacons = 0;
1119
1120 dtim_period = il->vif ? il->vif->bss_conf.dtim_period : 0;
1121
1122 if (dtim_period <= 2) {
1123 memcpy(cmd->sleep_interval, interval[0], sizeof(interval[0]));
1124 no_dtim = 2;
1125 } else if (dtim_period <= 10) {
1126 memcpy(cmd->sleep_interval, interval[1], sizeof(interval[1]));
1127 no_dtim = 2;
1128 } else {
1129 memcpy(cmd->sleep_interval, interval[2], sizeof(interval[2]));
1130 no_dtim = 0;
1131 }
1132
1133 if (dtim_period == 0) {
1134 dtim_period = 1;
1135 skip = false;
1136 } else {
1137 skip = !!no_dtim;
1138 }
1139
1140 if (skip) {
1141 __le32 tmp = cmd->sleep_interval[IL_POWER_VEC_SIZE - 1];
1142
1143 max_sleep = le32_to_cpu(tmp);
1144 if (max_sleep == 0xFF)
1145 max_sleep = dtim_period * (skip + 1);
1146 else if (max_sleep > dtim_period)
1147 max_sleep = (max_sleep / dtim_period) * dtim_period;
1148 cmd->flags |= IL_POWER_SLEEP_OVER_DTIM_MSK;
1149 } else {
1150 max_sleep = dtim_period;
1151 cmd->flags &= ~IL_POWER_SLEEP_OVER_DTIM_MSK;
1152 }
1153
1154 for (i = 0; i < IL_POWER_VEC_SIZE; i++)
1155 if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
1156 cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
1104} 1157}
1105 1158
1106static int 1159static int
@@ -1173,7 +1226,8 @@ il_power_update_mode(struct il_priv *il, bool force)
1173{ 1226{
1174 struct il_powertable_cmd cmd; 1227 struct il_powertable_cmd cmd;
1175 1228
1176 il_power_sleep_cam_cmd(il, &cmd); 1229 il_build_powertable_cmd(il, &cmd);
1230
1177 return il_power_set_mode(il, &cmd, force); 1231 return il_power_set_mode(il, &cmd, force);
1178} 1232}
1179EXPORT_SYMBOL(il_power_update_mode); 1233EXPORT_SYMBOL(il_power_update_mode);
@@ -5081,6 +5135,7 @@ set_ch_out:
5081 } 5135 }
5082 5136
5083 if (changed & (IEEE80211_CONF_CHANGE_PS | IEEE80211_CONF_CHANGE_IDLE)) { 5137 if (changed & (IEEE80211_CONF_CHANGE_PS | IEEE80211_CONF_CHANGE_IDLE)) {
5138 il->power_data.ps_disabled = !(conf->flags & IEEE80211_CONF_PS);
5084 ret = il_power_update_mode(il, false); 5139 ret = il_power_update_mode(il, false);
5085 if (ret) 5140 if (ret)
5086 D_MAC80211("Error setting sleep level\n"); 5141 D_MAC80211("Error setting sleep level\n");
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index ad123d66ab6c..dfb13c70efe8 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1123,6 +1123,7 @@ struct il_power_mgr {
1123 struct il_powertable_cmd sleep_cmd_next; 1123 struct il_powertable_cmd sleep_cmd_next;
1124 int debug_sleep_level_override; 1124 int debug_sleep_level_override;
1125 bool pci_pm; 1125 bool pci_pm;
1126 bool ps_disabled;
1126}; 1127};
1127 1128
1128struct il_priv { 1129struct il_priv {
@@ -1597,7 +1598,7 @@ struct il_mod_params {
1597 int disable_hw_scan; /* def: 0 = use h/w scan */ 1598 int disable_hw_scan; /* def: 0 = use h/w scan */
1598 int num_of_queues; /* def: HW dependent */ 1599 int num_of_queues; /* def: HW dependent */
1599 int disable_11n; /* def: 0 = 11n capabilities enabled */ 1600 int disable_11n; /* def: 0 = 11n capabilities enabled */
1600 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ 1601 int amsdu_size_8K; /* def: 0 = disable 8K amsdu size */
1601 int antenna; /* def: 0 = both antennas (use diversity) */ 1602 int antenna; /* def: 0 = both antennas (use diversity) */
1602 int restart_fw; /* def: 1 = restart firmware */ 1603 int restart_fw; /* def: 1 = restart firmware */
1603}; 1604};
@@ -1978,6 +1979,20 @@ void il_wr_prph(struct il_priv *il, u32 addr, u32 val);
1978u32 il_read_targ_mem(struct il_priv *il, u32 addr); 1979u32 il_read_targ_mem(struct il_priv *il, u32 addr);
1979void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val); 1980void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val);
1980 1981
1982static inline bool il_need_reclaim(struct il_priv *il, struct il_rx_pkt *pkt)
1983{
1984 /* Reclaim a command buffer only if this packet is a response
1985 * to a (driver-originated) command. If the packet (e.g. Rx frame)
1986 * originated from uCode, there is no command buffer to reclaim.
1987 * Ucode should set SEQ_RX_FRAME bit if ucode-originated, but
1988 * apparently a few don't get set; catch them here.
1989 */
1990 return !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
1991 pkt->hdr.cmd != N_STATS && pkt->hdr.cmd != C_TX &&
1992 pkt->hdr.cmd != N_RX_PHY && pkt->hdr.cmd != N_RX &&
1993 pkt->hdr.cmd != N_RX_MPDU && pkt->hdr.cmd != N_COMPRESSED_BA;
1994}
1995
1981static inline void 1996static inline void
1982_il_write8(struct il_priv *il, u32 ofs, u8 val) 1997_il_write8(struct il_priv *il, u32 ofs, u8 val)
1983{ 1998{
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 562772d85102..c160dad03037 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -109,7 +109,7 @@ extern const struct iwl_dvm_cfg iwl_dvm_6030_cfg;
109 109
110struct iwl_ucode_capabilities; 110struct iwl_ucode_capabilities;
111 111
112extern struct ieee80211_ops iwlagn_hw_ops; 112extern const struct ieee80211_ops iwlagn_hw_ops;
113 113
114static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) 114static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
115{ 115{
@@ -480,7 +480,7 @@ do { \
480} while (0) 480} while (0)
481#endif /* CONFIG_IWLWIFI_DEBUG */ 481#endif /* CONFIG_IWLWIFI_DEBUG */
482 482
483extern const char *iwl_dvm_cmd_strings[REPLY_MAX]; 483extern const char *const iwl_dvm_cmd_strings[REPLY_MAX];
484 484
485static inline const char *iwl_dvm_get_cmd_string(u8 cmd) 485static inline const char *iwl_dvm_get_cmd_string(u8 cmd)
486{ 486{
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c
index 7b140e487deb..758c54eeb206 100644
--- a/drivers/net/wireless/iwlwifi/dvm/devices.c
+++ b/drivers/net/wireless/iwlwifi/dvm/devices.c
@@ -317,7 +317,7 @@ static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
317 .nrg_th_cca = 62, 317 .nrg_th_cca = 62,
318}; 318};
319 319
320static struct iwl_sensitivity_ranges iwl5150_sensitivity = { 320static const struct iwl_sensitivity_ranges iwl5150_sensitivity = {
321 .min_nrg_cck = 95, 321 .min_nrg_cck = 95,
322 .auto_corr_min_ofdm = 90, 322 .auto_corr_min_ofdm = 90,
323 .auto_corr_min_ofdm_mrc = 170, 323 .auto_corr_min_ofdm_mrc = 170,
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 73086c1629ca..dd55c9cf7ba8 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1582,7 +1582,7 @@ static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
1582 IWL_DEBUG_MAC80211(priv, "leave\n"); 1582 IWL_DEBUG_MAC80211(priv, "leave\n");
1583} 1583}
1584 1584
1585struct ieee80211_ops iwlagn_hw_ops = { 1585const struct ieee80211_ops iwlagn_hw_ops = {
1586 .tx = iwlagn_mac_tx, 1586 .tx = iwlagn_mac_tx,
1587 .start = iwlagn_mac_start, 1587 .start = iwlagn_mac_start,
1588 .stop = iwlagn_mac_stop, 1588 .stop = iwlagn_mac_stop,
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index 7a1bc1c547e1..cd8377346aff 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -39,7 +39,7 @@
39 39
40#define IWL_CMD_ENTRY(x) [x] = #x 40#define IWL_CMD_ENTRY(x) [x] = #x
41 41
42const char *iwl_dvm_cmd_strings[REPLY_MAX] = { 42const char *const iwl_dvm_cmd_strings[REPLY_MAX] = {
43 IWL_CMD_ENTRY(REPLY_ALIVE), 43 IWL_CMD_ENTRY(REPLY_ALIVE),
44 IWL_CMD_ENTRY(REPLY_ERROR), 44 IWL_CMD_ENTRY(REPLY_ERROR),
45 IWL_CMD_ENTRY(REPLY_ECHO), 45 IWL_CMD_ENTRY(REPLY_ECHO),
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index bcfdcfb4485e..0a3e841b44a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -404,6 +404,38 @@ static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data)
404 return 0; 404 return 0;
405} 405}
406 406
407static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
408 struct iwl_ucode_capabilities *capa)
409{
410 const struct iwl_ucode_api *ucode_api = (void *)data;
411 u32 api_index = le32_to_cpu(ucode_api->api_index);
412
413 if (api_index >= IWL_API_ARRAY_SIZE) {
414 IWL_ERR(drv, "api_index larger than supported by driver\n");
415 return -EINVAL;
416 }
417
418 capa->api[api_index] = le32_to_cpu(ucode_api->api_flags);
419
420 return 0;
421}
422
423static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
424 struct iwl_ucode_capabilities *capa)
425{
426 const struct iwl_ucode_capa *ucode_capa = (void *)data;
427 u32 api_index = le32_to_cpu(ucode_capa->api_index);
428
429 if (api_index >= IWL_CAPABILITIES_ARRAY_SIZE) {
430 IWL_ERR(drv, "api_index larger than supported by driver\n");
431 return -EINVAL;
432 }
433
434 capa->capa[api_index] = le32_to_cpu(ucode_capa->api_capa);
435
436 return 0;
437}
438
407static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, 439static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
408 const struct firmware *ucode_raw, 440 const struct firmware *ucode_raw,
409 struct iwl_firmware_pieces *pieces) 441 struct iwl_firmware_pieces *pieces)
@@ -638,6 +670,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
638 */ 670 */
639 capa->flags = le32_to_cpup((__le32 *)tlv_data); 671 capa->flags = le32_to_cpup((__le32 *)tlv_data);
640 break; 672 break;
673 case IWL_UCODE_TLV_API_CHANGES_SET:
674 if (tlv_len != sizeof(struct iwl_ucode_api))
675 goto invalid_tlv_len;
676 if (iwl_set_ucode_api_flags(drv, tlv_data, capa))
677 goto tlv_error;
678 break;
679 case IWL_UCODE_TLV_ENABLED_CAPABILITIES:
680 if (tlv_len != sizeof(struct iwl_ucode_capa))
681 goto invalid_tlv_len;
682 if (iwl_set_ucode_capabilities(drv, tlv_data, capa))
683 goto tlv_error;
684 break;
641 case IWL_UCODE_TLV_INIT_EVTLOG_PTR: 685 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
642 if (tlv_len != sizeof(u32)) 686 if (tlv_len != sizeof(u32))
643 goto invalid_tlv_len; 687 goto invalid_tlv_len;
@@ -728,6 +772,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
728 if (tlv_len != sizeof(u32)) 772 if (tlv_len != sizeof(u32))
729 goto invalid_tlv_len; 773 goto invalid_tlv_len;
730 drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); 774 drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
775 drv->fw.valid_tx_ant = (drv->fw.phy_config &
776 FW_PHY_CFG_TX_CHAIN) >>
777 FW_PHY_CFG_TX_CHAIN_POS;
778 drv->fw.valid_rx_ant = (drv->fw.phy_config &
779 FW_PHY_CFG_RX_CHAIN) >>
780 FW_PHY_CFG_RX_CHAIN_POS;
731 break; 781 break;
732 case IWL_UCODE_TLV_SECURE_SEC_RT: 782 case IWL_UCODE_TLV_SECURE_SEC_RT:
733 iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, 783 iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
@@ -1301,8 +1351,7 @@ MODULE_PARM_DESC(antenna_coupling,
1301 1351
1302module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); 1352module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
1303MODULE_PARM_DESC(wd_disable, 1353MODULE_PARM_DESC(wd_disable,
1304 "Disable stuck queue watchdog timer 0=system default, " 1354 "Disable stuck queue watchdog timer 0=system default, 1=disable (default: 1)");
1305 "1=disable, 2=enable (default: 0)");
1306 1355
1307module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); 1356module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
1308MODULE_PARM_DESC(nvm_file, "NVM file name"); 1357MODULE_PARM_DESC(nvm_file, "NVM file name");
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index 592c01e11013..3c72cb710b0c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -70,6 +70,20 @@
70#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation" 70#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation"
71#define DRV_AUTHOR "<ilw@linux.intel.com>" 71#define DRV_AUTHOR "<ilw@linux.intel.com>"
72 72
73/* radio config bits (actual values from NVM definition) */
74#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
75#define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
76#define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
77#define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
78#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
79#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
80
81#define NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(x) (x & 0xF)
82#define NVM_RF_CFG_DASH_MSK_FAMILY_8000(x) ((x >> 4) & 0xF)
83#define NVM_RF_CFG_STEP_MSK_FAMILY_8000(x) ((x >> 8) & 0xF)
84#define NVM_RF_CFG_TYPE_MSK_FAMILY_8000(x) ((x >> 12) & 0xFFF)
85#define NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(x) ((x >> 24) & 0xF)
86#define NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(x) ((x >> 28) & 0xF)
73 87
74/** 88/**
75 * DOC: Driver system flows - drv component 89 * DOC: Driver system flows - drv component
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index e3c7deafabe6..f0548b8a64b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -81,16 +81,17 @@ struct iwl_nvm_data {
81 bool sku_cap_band_24GHz_enable; 81 bool sku_cap_band_24GHz_enable;
82 bool sku_cap_band_52GHz_enable; 82 bool sku_cap_band_52GHz_enable;
83 bool sku_cap_11n_enable; 83 bool sku_cap_11n_enable;
84 bool sku_cap_11ac_enable;
84 bool sku_cap_amt_enable; 85 bool sku_cap_amt_enable;
85 bool sku_cap_ipan_enable; 86 bool sku_cap_ipan_enable;
86 87
87 u8 radio_cfg_type; 88 u16 radio_cfg_type;
88 u8 radio_cfg_step; 89 u8 radio_cfg_step;
89 u8 radio_cfg_dash; 90 u8 radio_cfg_dash;
90 u8 radio_cfg_pnum; 91 u8 radio_cfg_pnum;
91 u8 valid_tx_ant, valid_rx_ant; 92 u8 valid_tx_ant, valid_rx_ant;
92 93
93 u16 nvm_version; 94 u32 nvm_version;
94 s8 max_tx_pwr_half_dbm; 95 s8 max_tx_pwr_half_dbm;
95 96
96 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 97 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 88e2d6eb569f..b45e576a4b57 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -126,6 +126,8 @@ enum iwl_ucode_tlv_type {
126 IWL_UCODE_TLV_SECURE_SEC_WOWLAN = 26, 126 IWL_UCODE_TLV_SECURE_SEC_WOWLAN = 26,
127 IWL_UCODE_TLV_NUM_OF_CPU = 27, 127 IWL_UCODE_TLV_NUM_OF_CPU = 27,
128 IWL_UCODE_TLV_CSCHEME = 28, 128 IWL_UCODE_TLV_CSCHEME = 28,
129 IWL_UCODE_TLV_API_CHANGES_SET = 29,
130 IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
129}; 131};
130 132
131struct iwl_ucode_tlv { 133struct iwl_ucode_tlv {
@@ -158,4 +160,19 @@ struct iwl_tlv_ucode_header {
158 u8 data[0]; 160 u8 data[0];
159}; 161};
160 162
163/*
164 * ucode TLVs
165 *
166 * ability to get extension for: flags & capabilities from ucode binaries files
167 */
168struct iwl_ucode_api {
169 __le32 api_index;
170 __le32 api_flags;
171} __packed;
172
173struct iwl_ucode_capa {
174 __le32 api_index;
175 __le32 api_capa;
176} __packed;
177
161#endif /* __iwl_fw_file_h__ */ 178#endif /* __iwl_fw_file_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index f80ba586c253..f04ff871dc6d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -92,8 +92,8 @@
92 * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API 92 * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
93 * @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command 93 * @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
94 * containing CAM (Continuous Active Mode) indication. 94 * containing CAM (Continuous Active Mode) indication.
95 * @IWL_UCODE_TLV_FLAGS_P2P_PS: P2P client power save is supported (only on a 95 * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
96 * single bound interface). 96 * P2P client interfaces simultaneously if they are in different bindings.
97 * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save 97 * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
98 * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering. 98 * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
99 * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients 99 * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
@@ -118,7 +118,7 @@ enum iwl_ucode_tlv_flag {
118 IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17), 118 IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17),
119 IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19), 119 IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
120 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20), 120 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20),
121 IWL_UCODE_TLV_FLAGS_P2P_PS = BIT(21), 121 IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
122 IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24), 122 IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
123 IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26), 123 IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
124 IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29), 124 IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
@@ -165,11 +165,15 @@ enum iwl_ucode_sec {
165 * just an offset to the HW address. 165 * just an offset to the HW address.
166 */ 166 */
167#define IWL_UCODE_SECTION_MAX 12 167#define IWL_UCODE_SECTION_MAX 12
168#define IWL_API_ARRAY_SIZE 1
169#define IWL_CAPABILITIES_ARRAY_SIZE 1
168 170
169struct iwl_ucode_capabilities { 171struct iwl_ucode_capabilities {
170 u32 max_probe_length; 172 u32 max_probe_length;
171 u32 standard_phy_calibration_size; 173 u32 standard_phy_calibration_size;
172 u32 flags; 174 u32 flags;
175 u32 api[IWL_API_ARRAY_SIZE];
176 u32 capa[IWL_CAPABILITIES_ARRAY_SIZE];
173}; 177};
174 178
175/* one for each uCode image (inst/data, init/runtime/wowlan) */ 179/* one for each uCode image (inst/data, init/runtime/wowlan) */
@@ -288,22 +292,12 @@ struct iwl_fw {
288 292
289 struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX]; 293 struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX];
290 u32 phy_config; 294 u32 phy_config;
295 u8 valid_tx_ant;
296 u8 valid_rx_ant;
291 297
292 bool mvm_fw; 298 bool mvm_fw;
293 299
294 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS]; 300 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
295}; 301};
296 302
297static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw)
298{
299 return (fw->phy_config & FW_PHY_CFG_TX_CHAIN) >>
300 FW_PHY_CFG_TX_CHAIN_POS;
301}
302
303static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw)
304{
305 return (fw->phy_config & FW_PHY_CFG_RX_CHAIN) >>
306 FW_PHY_CFG_RX_CHAIN_POS;
307}
308
309#endif /* __iwl_fw_h__ */ 303#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index b29075c3da8e..d994317db85b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -96,7 +96,7 @@ enum iwl_disable_11n {
96 * use IWL_[DIS,EN]ABLE_HT_* constants 96 * use IWL_[DIS,EN]ABLE_HT_* constants
97 * @amsdu_size_8K: enable 8K amsdu size, default = 0 97 * @amsdu_size_8K: enable 8K amsdu size, default = 0
98 * @restart_fw: restart firmware, default = 1 98 * @restart_fw: restart firmware, default = 1
99 * @wd_disable: enable stuck queue check, default = 0 99 * @wd_disable: disable stuck queue check, default = 1
100 * @bt_coex_active: enable bt coex, default = true 100 * @bt_coex_active: enable bt coex, default = true
101 * @led_mode: system default, default = 0 101 * @led_mode: system default, default = 0
102 * @power_save: disable power save, default = false 102 * @power_save: disable power save, default = false
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 53b9cad50477..2f962ec0b750 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -71,7 +71,7 @@ enum wkp_nvm_offsets {
71 /* NVM HW-Section offset (in words) definitions */ 71 /* NVM HW-Section offset (in words) definitions */
72 HW_ADDR = 0x15, 72 HW_ADDR = 0x15,
73 73
74/* NVM SW-Section offset (in words) definitions */ 74 /* NVM SW-Section offset (in words) definitions */
75 NVM_SW_SECTION = 0x1C0, 75 NVM_SW_SECTION = 0x1C0,
76 NVM_VERSION = 0, 76 NVM_VERSION = 0,
77 RADIO_CFG = 1, 77 RADIO_CFG = 1,
@@ -79,11 +79,32 @@ enum wkp_nvm_offsets {
79 N_HW_ADDRS = 3, 79 N_HW_ADDRS = 3,
80 NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION, 80 NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
81 81
82/* NVM calibration section offset (in words) definitions */ 82 /* NVM calibration section offset (in words) definitions */
83 NVM_CALIB_SECTION = 0x2B8, 83 NVM_CALIB_SECTION = 0x2B8,
84 XTAL_CALIB = 0x316 - NVM_CALIB_SECTION 84 XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
85}; 85};
86 86
87enum family_8000_nvm_offsets {
88 /* NVM HW-Section offset (in words) definitions */
89 HW_ADDR0_FAMILY_8000 = 0x12,
90 HW_ADDR1_FAMILY_8000 = 0x16,
91 MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,
92
93 /* NVM SW-Section offset (in words) definitions */
94 NVM_SW_SECTION_FAMILY_8000 = 0x1C0,
95 NVM_VERSION_FAMILY_8000 = 0,
96 RADIO_CFG_FAMILY_8000 = 2,
97 SKU_FAMILY_8000 = 4,
98 N_HW_ADDRS_FAMILY_8000 = 5,
99
100 /* NVM REGULATORY -Section offset (in words) definitions */
101 NVM_CHANNELS_FAMILY_8000 = 0,
102
103 /* NVM calibration section offset (in words) definitions */
104 NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
105 XTAL_CALIB_FAMILY_8000 = 0x316 - NVM_CALIB_SECTION_FAMILY_8000
106};
107
87/* SKU Capabilities (actual values from NVM definition) */ 108/* SKU Capabilities (actual values from NVM definition) */
88enum nvm_sku_bits { 109enum nvm_sku_bits {
89 NVM_SKU_CAP_BAND_24GHZ = BIT(0), 110 NVM_SKU_CAP_BAND_24GHZ = BIT(0),
@@ -92,14 +113,6 @@ enum nvm_sku_bits {
92 NVM_SKU_CAP_11AC_ENABLE = BIT(3), 113 NVM_SKU_CAP_11AC_ENABLE = BIT(3),
93}; 114};
94 115
95/* radio config bits (actual values from NVM definition) */
96#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
97#define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
98#define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
99#define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
100#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
101#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
102
103/* 116/*
104 * These are the channel numbers in the order that they are stored in the NVM 117 * These are the channel numbers in the order that they are stored in the NVM
105 */ 118 */
@@ -112,7 +125,17 @@ static const u8 iwl_nvm_channels[] = {
112 149, 153, 157, 161, 165 125 149, 153, 157, 161, 165
113}; 126};
114 127
128static const u8 iwl_nvm_channels_family_8000[] = {
129 /* 2.4 GHz */
130 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
131 /* 5 GHz */
132 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
133 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
134 149, 153, 157, 161, 165, 169, 173, 177, 181
135};
136
115#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels) 137#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
138#define IWL_NUM_CHANNELS_FAMILY_8000 ARRAY_SIZE(iwl_nvm_channels_family_8000)
116#define NUM_2GHZ_CHANNELS 14 139#define NUM_2GHZ_CHANNELS 14
117#define FIRST_2GHZ_HT_MINUS 5 140#define FIRST_2GHZ_HT_MINUS 5
118#define LAST_2GHZ_HT_PLUS 9 141#define LAST_2GHZ_HT_PLUS 9
@@ -179,8 +202,18 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
179 struct ieee80211_channel *channel; 202 struct ieee80211_channel *channel;
180 u16 ch_flags; 203 u16 ch_flags;
181 bool is_5ghz; 204 bool is_5ghz;
205 int num_of_ch;
206 const u8 *nvm_chan;
207
208 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
209 num_of_ch = IWL_NUM_CHANNELS;
210 nvm_chan = &iwl_nvm_channels[0];
211 } else {
212 num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
213 nvm_chan = &iwl_nvm_channels_family_8000[0];
214 }
182 215
183 for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { 216 for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
184 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); 217 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
185 218
186 if (ch_idx >= NUM_2GHZ_CHANNELS && 219 if (ch_idx >= NUM_2GHZ_CHANNELS &&
@@ -190,7 +223,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
190 if (!(ch_flags & NVM_CHANNEL_VALID)) { 223 if (!(ch_flags & NVM_CHANNEL_VALID)) {
191 IWL_DEBUG_EEPROM(dev, 224 IWL_DEBUG_EEPROM(dev,
192 "Ch. %d Flags %x [%sGHz] - No traffic\n", 225 "Ch. %d Flags %x [%sGHz] - No traffic\n",
193 iwl_nvm_channels[ch_idx], 226 nvm_chan[ch_idx],
194 ch_flags, 227 ch_flags,
195 (ch_idx >= NUM_2GHZ_CHANNELS) ? 228 (ch_idx >= NUM_2GHZ_CHANNELS) ?
196 "5.2" : "2.4"); 229 "5.2" : "2.4");
@@ -200,7 +233,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
200 channel = &data->channels[n_channels]; 233 channel = &data->channels[n_channels];
201 n_channels++; 234 n_channels++;
202 235
203 channel->hw_value = iwl_nvm_channels[ch_idx]; 236 channel->hw_value = nvm_chan[ch_idx];
204 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ? 237 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
205 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; 238 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
206 channel->center_freq = 239 channel->center_freq =
@@ -211,11 +244,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
211 channel->flags = IEEE80211_CHAN_NO_HT40; 244 channel->flags = IEEE80211_CHAN_NO_HT40;
212 if (ch_idx < NUM_2GHZ_CHANNELS && 245 if (ch_idx < NUM_2GHZ_CHANNELS &&
213 (ch_flags & NVM_CHANNEL_40MHZ)) { 246 (ch_flags & NVM_CHANNEL_40MHZ)) {
214 if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS) 247 if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
215 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS; 248 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
216 if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS) 249 if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
217 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; 250 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
218 } else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT && 251 } else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
219 (ch_flags & NVM_CHANNEL_40MHZ)) { 252 (ch_flags & NVM_CHANNEL_40MHZ)) {
220 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0) 253 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
221 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS; 254 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
@@ -307,14 +340,23 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
307} 340}
308 341
309static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 342static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
310 struct iwl_nvm_data *data, const __le16 *nvm_sw, 343 struct iwl_nvm_data *data,
311 bool enable_vht, u8 tx_chains, u8 rx_chains) 344 const __le16 *ch_section, bool enable_vht,
345 u8 tx_chains, u8 rx_chains)
312{ 346{
313 int n_channels = iwl_init_channel_map(dev, cfg, data, 347 int n_channels;
314 &nvm_sw[NVM_CHANNELS]);
315 int n_used = 0; 348 int n_used = 0;
316 struct ieee80211_supported_band *sband; 349 struct ieee80211_supported_band *sband;
317 350
351 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
352 n_channels = iwl_init_channel_map(
353 dev, cfg, data,
354 &ch_section[NVM_CHANNELS]);
355 else
356 n_channels = iwl_init_channel_map(
357 dev, cfg, data,
358 &ch_section[NVM_CHANNELS_FAMILY_8000]);
359
318 sband = &data->bands[IEEE80211_BAND_2GHZ]; 360 sband = &data->bands[IEEE80211_BAND_2GHZ];
319 sband->band = IEEE80211_BAND_2GHZ; 361 sband->band = IEEE80211_BAND_2GHZ;
320 sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS]; 362 sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
@@ -340,67 +382,150 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
340 n_used, n_channels); 382 n_used, n_channels);
341} 383}
342 384
385static int iwl_get_sku(const struct iwl_cfg *cfg,
386 const __le16 *nvm_sw)
387{
388 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
389 return le16_to_cpup(nvm_sw + SKU);
390 else
391 return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000));
392}
393
394static int iwl_get_nvm_version(const struct iwl_cfg *cfg,
395 const __le16 *nvm_sw)
396{
397 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
398 return le16_to_cpup(nvm_sw + NVM_VERSION);
399 else
400 return le32_to_cpup((__le32 *)(nvm_sw +
401 NVM_VERSION_FAMILY_8000));
402}
403
404static int iwl_get_radio_cfg(const struct iwl_cfg *cfg,
405 const __le16 *nvm_sw)
406{
407 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
408 return le16_to_cpup(nvm_sw + RADIO_CFG);
409 else
410 return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000));
411}
412
413#define N_HW_ADDRS_MASK_FAMILY_8000 0xF
414static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg,
415 const __le16 *nvm_sw)
416{
417 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
418 return le16_to_cpup(nvm_sw + N_HW_ADDRS);
419 else
420 return le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000))
421 & N_HW_ADDRS_MASK_FAMILY_8000;
422}
423
424static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
425 struct iwl_nvm_data *data,
426 u32 radio_cfg)
427{
428 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
429 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
430 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
431 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
432 data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
433 return;
434 }
435
436 /* set the radio configuration for family 8000 */
437 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK_FAMILY_8000(radio_cfg);
438 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg);
439 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg);
440 data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg);
441}
442
443static void iwl_set_hw_address(const struct iwl_cfg *cfg,
444 struct iwl_nvm_data *data,
445 const __le16 *nvm_sec)
446{
447 u8 hw_addr[ETH_ALEN];
448
449 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
450 memcpy(hw_addr, nvm_sec + HW_ADDR, ETH_ALEN);
451 else
452 memcpy(hw_addr, nvm_sec + MAC_ADDRESS_OVERRIDE_FAMILY_8000,
453 ETH_ALEN);
454
455 /* The byte order is little endian 16 bit, meaning 214365 */
456 data->hw_addr[0] = hw_addr[1];
457 data->hw_addr[1] = hw_addr[0];
458 data->hw_addr[2] = hw_addr[3];
459 data->hw_addr[3] = hw_addr[2];
460 data->hw_addr[4] = hw_addr[5];
461 data->hw_addr[5] = hw_addr[4];
462}
463
343struct iwl_nvm_data * 464struct iwl_nvm_data *
344iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 465iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
345 const __le16 *nvm_hw, const __le16 *nvm_sw, 466 const __le16 *nvm_hw, const __le16 *nvm_sw,
346 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains) 467 const __le16 *nvm_calib, const __le16 *regulatory,
468 const __le16 *mac_override, u8 tx_chains, u8 rx_chains)
347{ 469{
348 struct iwl_nvm_data *data; 470 struct iwl_nvm_data *data;
349 u8 hw_addr[ETH_ALEN]; 471 u32 sku;
350 u16 radio_cfg, sku; 472 u32 radio_cfg;
351 473
352 data = kzalloc(sizeof(*data) + 474 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
353 sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, 475 data = kzalloc(sizeof(*data) +
354 GFP_KERNEL); 476 sizeof(struct ieee80211_channel) *
477 IWL_NUM_CHANNELS,
478 GFP_KERNEL);
479 else
480 data = kzalloc(sizeof(*data) +
481 sizeof(struct ieee80211_channel) *
482 IWL_NUM_CHANNELS_FAMILY_8000,
483 GFP_KERNEL);
355 if (!data) 484 if (!data)
356 return NULL; 485 return NULL;
357 486
358 data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION); 487 data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw);
359 488
360 radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG); 489 radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw);
361 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg); 490 iwl_set_radio_cfg(cfg, data, radio_cfg);
362 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
363 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
364 data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
365 data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
366 data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
367 491
368 sku = le16_to_cpup(nvm_sw + SKU); 492 sku = iwl_get_sku(cfg, nvm_sw);
369 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; 493 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
370 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; 494 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
371 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; 495 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
496 data->sku_cap_11ac_enable = sku & NVM_SKU_CAP_11AC_ENABLE;
372 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) 497 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
373 data->sku_cap_11n_enable = false; 498 data->sku_cap_11n_enable = false;
374 499
375 /* check overrides (some devices have wrong NVM) */ 500 data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
376 if (cfg->valid_tx_ant)
377 data->valid_tx_ant = cfg->valid_tx_ant;
378 if (cfg->valid_rx_ant)
379 data->valid_rx_ant = cfg->valid_rx_ant;
380 501
381 if (!data->valid_tx_ant || !data->valid_rx_ant) { 502 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
382 IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n", 503 /* Checking for required sections */
383 data->valid_tx_ant, data->valid_rx_ant); 504 if (!nvm_calib) {
384 kfree(data); 505 IWL_ERR_DEV(dev,
385 return NULL; 506 "Can't parse empty Calib NVM sections\n");
507 kfree(data);
508 return NULL;
509 }
510 /* in family 8000 Xtal calibration values moved to OTP */
511 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
512 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
386 } 513 }
387 514
388 data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS); 515 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
516 iwl_set_hw_address(cfg, data, nvm_hw);
389 517
390 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); 518 iwl_init_sbands(dev, cfg, data, nvm_sw,
391 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); 519 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
520 rx_chains);
521 } else {
522 /* MAC address in family 8000 */
523 iwl_set_hw_address(cfg, data, mac_override);
392 524
393 /* The byte order is little endian 16 bit, meaning 214365 */ 525 iwl_init_sbands(dev, cfg, data, regulatory,
394 memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN); 526 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
395 data->hw_addr[0] = hw_addr[1]; 527 rx_chains);
396 data->hw_addr[1] = hw_addr[0]; 528 }
397 data->hw_addr[2] = hw_addr[3];
398 data->hw_addr[3] = hw_addr[2];
399 data->hw_addr[4] = hw_addr[5];
400 data->hw_addr[5] = hw_addr[4];
401
402 iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE,
403 tx_chains, rx_chains);
404 529
405 data->calib_version = 255; 530 data->calib_version = 255;
406 531
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index 0c4399aba8c6..c9c45a39d212 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -75,6 +75,7 @@
75struct iwl_nvm_data * 75struct iwl_nvm_data *
76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
77 const __le16 *nvm_hw, const __le16 *nvm_sw, 77 const __le16 *nvm_hw, const __le16 *nvm_sw,
78 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains); 78 const __le16 *nvm_calib, const __le16 *regulatory,
79 const __le16 *mac_override, u8 tx_chains, u8 rx_chains);
79 80
80#endif /* __iwl_nvm_parse_h__ */ 81#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 7b19274b550f..8cdb0dd618a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -393,7 +393,7 @@ struct iwl_trans_config {
393 bool rx_buf_size_8k; 393 bool rx_buf_size_8k;
394 bool bc_table_dword; 394 bool bc_table_dword;
395 unsigned int queue_watchdog_timeout; 395 unsigned int queue_watchdog_timeout;
396 const char **command_names; 396 const char *const *command_names;
397}; 397};
398 398
399struct iwl_trans; 399struct iwl_trans;
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
index 29b4396018b1..f64e972191eb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -591,7 +591,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
591 iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM && 591 iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
592 ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) || 592 ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
593 (vif->type == NL80211_IFTYPE_STATION && vif->p2p && 593 (vif->type == NL80211_IFTYPE_STATION && vif->p2p &&
594 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))) 594 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)))
595 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR | 595 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
596 S_IRUSR); 596 S_IRUSR);
597 597
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 6853e5efe522..e0ff43ed2482 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -531,6 +531,76 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
531} 531}
532#undef PRINT_STAT_LE32 532#undef PRINT_STAT_LE32
533 533
534static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
535 char __user *user_buf, size_t count,
536 loff_t *ppos,
537 struct iwl_mvm_frame_stats *stats)
538{
539 char *buff;
540 int pos = 0, idx, i;
541 int ret;
542 size_t bufsz = 1024;
543
544 buff = kmalloc(bufsz, GFP_KERNEL);
545 if (!buff)
546 return -ENOMEM;
547
548 spin_lock_bh(&mvm->drv_stats_lock);
549 pos += scnprintf(buff + pos, bufsz - pos,
550 "Legacy/HT/VHT\t:\t%d/%d/%d\n",
551 stats->legacy_frames,
552 stats->ht_frames,
553 stats->vht_frames);
554 pos += scnprintf(buff + pos, bufsz - pos, "20/40/80\t:\t%d/%d/%d\n",
555 stats->bw_20_frames,
556 stats->bw_40_frames,
557 stats->bw_80_frames);
558 pos += scnprintf(buff + pos, bufsz - pos, "NGI/SGI\t\t:\t%d/%d\n",
559 stats->ngi_frames,
560 stats->sgi_frames);
561 pos += scnprintf(buff + pos, bufsz - pos, "SISO/MIMO2\t:\t%d/%d\n",
562 stats->siso_frames,
563 stats->mimo2_frames);
564 pos += scnprintf(buff + pos, bufsz - pos, "FAIL/SCSS\t:\t%d/%d\n",
565 stats->fail_frames,
566 stats->success_frames);
567 pos += scnprintf(buff + pos, bufsz - pos, "MPDUs agg\t:\t%d\n",
568 stats->agg_frames);
569 pos += scnprintf(buff + pos, bufsz - pos, "A-MPDUs\t\t:\t%d\n",
570 stats->ampdu_count);
571 pos += scnprintf(buff + pos, bufsz - pos, "Avg MPDUs/A-MPDU:\t%d\n",
572 stats->ampdu_count > 0 ?
573 (stats->agg_frames / stats->ampdu_count) : 0);
574
575 pos += scnprintf(buff + pos, bufsz - pos, "Last Rates\n");
576
577 idx = stats->last_frame_idx - 1;
578 for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) {
579 idx = (idx + 1) % ARRAY_SIZE(stats->last_rates);
580 if (stats->last_rates[idx] == 0)
581 continue;
582 pos += scnprintf(buff + pos, bufsz - pos, "Rate[%d]: ",
583 (int)(ARRAY_SIZE(stats->last_rates) - i));
584 pos += rs_pretty_print_rate(buff + pos, stats->last_rates[idx]);
585 }
586 spin_unlock_bh(&mvm->drv_stats_lock);
587
588 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos);
589 kfree(buff);
590
591 return ret;
592}
593
594static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file,
595 char __user *user_buf, size_t count,
596 loff_t *ppos)
597{
598 struct iwl_mvm *mvm = file->private_data;
599
600 return iwl_dbgfs_frame_stats_read(mvm, user_buf, count, ppos,
601 &mvm->drv_rx_stats);
602}
603
534static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf, 604static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
535 size_t count, loff_t *ppos) 605 size_t count, loff_t *ppos)
536{ 606{
@@ -591,7 +661,7 @@ iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
591 return -EINVAL; 661 return -EINVAL;
592 if (scan_rx_ant > ANT_ABC) 662 if (scan_rx_ant > ANT_ABC)
593 return -EINVAL; 663 return -EINVAL;
594 if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw)) 664 if (scan_rx_ant & ~mvm->fw->valid_rx_ant)
595 return -EINVAL; 665 return -EINVAL;
596 666
597 mvm->scan_rx_ant = scan_rx_ant; 667 mvm->scan_rx_ant = scan_rx_ant;
@@ -907,6 +977,49 @@ static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf,
907#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \ 977#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
908 MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode) 978 MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
909 979
980static ssize_t
981iwl_dbgfs_prph_reg_read(struct file *file,
982 char __user *user_buf,
983 size_t count, loff_t *ppos)
984{
985 struct iwl_mvm *mvm = file->private_data;
986 int pos = 0;
987 char buf[32];
988 const size_t bufsz = sizeof(buf);
989
990 if (!mvm->dbgfs_prph_reg_addr)
991 return -EINVAL;
992
993 pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
994 mvm->dbgfs_prph_reg_addr,
995 iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
996
997 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
998}
999
1000static ssize_t
1001iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
1002 size_t count, loff_t *ppos)
1003{
1004 u8 args;
1005 u32 value;
1006
1007 args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
1008 /* if we only want to set the reg address - nothing more to do */
1009 if (args == 1)
1010 goto out;
1011
1012 /* otherwise, make sure we have both address and value */
1013 if (args != 2)
1014 return -EINVAL;
1015
1016 iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
1017out:
1018 return count;
1019}
1020
1021MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
1022
910/* Device wide debugfs entries */ 1023/* Device wide debugfs entries */
911MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); 1024MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
912MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8); 1025MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
@@ -916,6 +1029,7 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
916MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); 1029MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
917MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64); 1030MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
918MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); 1031MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1032MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
919MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10); 1033MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
920MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10); 1034MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
921MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); 1035MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
@@ -947,10 +1061,12 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
947 MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 1061 MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
948 S_IRUSR | S_IWUSR); 1062 S_IRUSR | S_IWUSR);
949 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); 1063 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
1064 MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR);
950 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 1065 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
951 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR); 1066 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
952 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 1067 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
953 S_IWUSR | S_IRUSR); 1068 S_IWUSR | S_IRUSR);
1069 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
954 MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 1070 MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
955 1071
956#ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1072#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index 85057219cc43..39148b5bb332 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -257,7 +257,8 @@ enum {
257 257
258/* Bit 17-18: (0) SS, (1) SS*2 */ 258/* Bit 17-18: (0) SS, (1) SS*2 */
259#define RATE_MCS_STBC_POS 17 259#define RATE_MCS_STBC_POS 17
260#define RATE_MCS_STBC_MSK (1 << RATE_MCS_STBC_POS) 260#define RATE_MCS_HT_STBC_MSK (3 << RATE_MCS_STBC_POS)
261#define RATE_MCS_VHT_STBC_MSK (1 << RATE_MCS_STBC_POS)
261 262
262/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */ 263/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */
263#define RATE_MCS_BF_POS 19 264#define RATE_MCS_BF_POS 19
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index a7c88f1402e9..807fa525cafe 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -306,7 +306,6 @@ struct iwl_phy_cfg_cmd {
306#define PHY_CFG_RX_CHAIN_B BIT(13) 306#define PHY_CFG_RX_CHAIN_B BIT(13)
307#define PHY_CFG_RX_CHAIN_C BIT(14) 307#define PHY_CFG_RX_CHAIN_C BIT(14)
308 308
309#define NVM_MAX_NUM_SECTIONS 11
310 309
311/* Target of the NVM_ACCESS_CMD */ 310/* Target of the NVM_ACCESS_CMD */
312enum { 311enum {
@@ -318,8 +317,11 @@ enum {
318/* Section types for NVM_ACCESS_CMD */ 317/* Section types for NVM_ACCESS_CMD */
319enum { 318enum {
320 NVM_SECTION_TYPE_SW = 1, 319 NVM_SECTION_TYPE_SW = 1,
320 NVM_SECTION_TYPE_REGULATORY = 3,
321 NVM_SECTION_TYPE_CALIBRATION = 4, 321 NVM_SECTION_TYPE_CALIBRATION = 4,
322 NVM_SECTION_TYPE_PRODUCTION = 5, 322 NVM_SECTION_TYPE_PRODUCTION = 5,
323 NVM_SECTION_TYPE_MAC_OVERRIDE = 11,
324 NVM_MAX_NUM_SECTIONS = 12,
323}; 325};
324 326
325/** 327/**
@@ -710,6 +712,7 @@ enum {
710 TE_V2_NOTIF_HOST_FRAG_END = BIT(5), 712 TE_V2_NOTIF_HOST_FRAG_END = BIT(5),
711 TE_V2_NOTIF_INTERNAL_FRAG_START = BIT(6), 713 TE_V2_NOTIF_INTERNAL_FRAG_START = BIT(6),
712 TE_V2_NOTIF_INTERNAL_FRAG_END = BIT(7), 714 TE_V2_NOTIF_INTERNAL_FRAG_END = BIT(7),
715 T2_V2_START_IMMEDIATELY = BIT(11),
713 716
714 TE_V2_NOTIF_MSK = 0xff, 717 TE_V2_NOTIF_MSK = 0xff,
715 718
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index bae75b308fc0..7ce20062f32d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -130,7 +130,6 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
130 } else { 130 } else {
131 palive2 = (void *)pkt->data; 131 palive2 = (void *)pkt->data;
132 132
133 mvm->support_umac_log = true;
134 mvm->error_event_table = 133 mvm->error_event_table =
135 le32_to_cpu(palive2->error_event_table_ptr); 134 le32_to_cpu(palive2->error_event_table_ptr);
136 mvm->log_event_table = 135 mvm->log_event_table =
@@ -141,6 +140,9 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
141 140
142 alive_data->valid = le16_to_cpu(palive2->status) == 141 alive_data->valid = le16_to_cpu(palive2->status) ==
143 IWL_ALIVE_STATUS_OK; 142 IWL_ALIVE_STATUS_OK;
143 if (mvm->umac_error_event_table)
144 mvm->support_umac_log = true;
145
144 IWL_DEBUG_FW(mvm, 146 IWL_DEBUG_FW(mvm,
145 "Alive VER2 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n", 147 "Alive VER2 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
146 le16_to_cpu(palive2->status), palive2->ver_type, 148 le16_to_cpu(palive2->status), palive2->ver_type,
@@ -320,7 +322,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
320 } 322 }
321 323
322 /* Send TX valid antennas before triggering calibrations */ 324 /* Send TX valid antennas before triggering calibrations */
323 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); 325 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
324 if (ret) 326 if (ret)
325 goto error; 327 goto error;
326 328
@@ -356,8 +358,6 @@ out:
356 GFP_KERNEL); 358 GFP_KERNEL);
357 if (!mvm->nvm_data) 359 if (!mvm->nvm_data)
358 return -ENOMEM; 360 return -ENOMEM;
359 mvm->nvm_data->valid_rx_ant = 1;
360 mvm->nvm_data->valid_tx_ant = 1;
361 mvm->nvm_data->bands[0].channels = mvm->nvm_data->channels; 361 mvm->nvm_data->bands[0].channels = mvm->nvm_data->channels;
362 mvm->nvm_data->bands[0].n_channels = 1; 362 mvm->nvm_data->bands[0].n_channels = 1;
363 mvm->nvm_data->bands[0].n_bitrates = 1; 363 mvm->nvm_data->bands[0].n_bitrates = 1;
@@ -369,8 +369,6 @@ out:
369 return ret; 369 return ret;
370} 370}
371 371
372#define UCODE_CALIB_TIMEOUT (2*HZ)
373
374int iwl_mvm_up(struct iwl_mvm *mvm) 372int iwl_mvm_up(struct iwl_mvm *mvm)
375{ 373{
376 int ret, i; 374 int ret, i;
@@ -422,7 +420,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
422 if (ret) 420 if (ret)
423 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n"); 421 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
424 422
425 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); 423 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
426 if (ret) 424 if (ret)
427 goto error; 425 goto error;
428 426
@@ -507,7 +505,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
507 goto error; 505 goto error;
508 } 506 }
509 507
510 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); 508 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
511 if (ret) 509 if (ret)
512 goto error; 510 goto error;
513 511
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 5c21aabb40cb..9ccec10bba16 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -952,7 +952,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
952 TX_CMD_FLG_TSF); 952 TX_CMD_FLG_TSF);
953 953
954 mvm->mgmt_last_antenna_idx = 954 mvm->mgmt_last_antenna_idx =
955 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), 955 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
956 mvm->mgmt_last_antenna_idx); 956 mvm->mgmt_last_antenna_idx);
957 957
958 beacon_cmd.tx.rate_n_flags = 958 beacon_cmd.tx.rate_n_flags =
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index a49d1ef13f42..c2ab6a3318cb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -68,6 +68,7 @@
68#include <linux/ip.h> 68#include <linux/ip.h>
69#include <linux/if_arp.h> 69#include <linux/if_arp.h>
70#include <net/mac80211.h> 70#include <net/mac80211.h>
71#include <net/ieee80211_radiotap.h>
71#include <net/tcp.h> 72#include <net/tcp.h>
72 73
73#include "iwl-op-mode.h" 74#include "iwl-op-mode.h"
@@ -280,6 +281,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
280 281
281 hw->queues = mvm->first_agg_queue; 282 hw->queues = mvm->first_agg_queue;
282 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 283 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
284 hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC |
285 IEEE80211_RADIOTAP_MCS_HAVE_STBC;
286 hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC;
283 hw->rate_control_algorithm = "iwl-mvm-rs"; 287 hw->rate_control_algorithm = "iwl-mvm-rs";
284 288
285 /* 289 /*
@@ -1319,7 +1323,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
1319 mvmvif->ap_ibss_active = true; 1323 mvmvif->ap_ibss_active = true;
1320 1324
1321 /* power updated needs to be done before quotas */ 1325 /* power updated needs to be done before quotas */
1322 mvm->bound_vif_cnt++;
1323 iwl_mvm_power_update_mac(mvm, vif); 1326 iwl_mvm_power_update_mac(mvm, vif);
1324 1327
1325 ret = iwl_mvm_update_quotas(mvm, vif); 1328 ret = iwl_mvm_update_quotas(mvm, vif);
@@ -1338,7 +1341,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
1338 return 0; 1341 return 0;
1339 1342
1340out_quota_failed: 1343out_quota_failed:
1341 mvm->bound_vif_cnt--;
1342 iwl_mvm_power_update_mac(mvm, vif); 1344 iwl_mvm_power_update_mac(mvm, vif);
1343 mvmvif->ap_ibss_active = false; 1345 mvmvif->ap_ibss_active = false;
1344 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1346 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
@@ -1375,7 +1377,6 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
1375 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1377 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
1376 iwl_mvm_binding_remove_vif(mvm, vif); 1378 iwl_mvm_binding_remove_vif(mvm, vif);
1377 1379
1378 mvm->bound_vif_cnt--;
1379 iwl_mvm_power_update_mac(mvm, vif); 1380 iwl_mvm_power_update_mac(mvm, vif);
1380 1381
1381 iwl_mvm_mac_ctxt_remove(mvm, vif); 1382 iwl_mvm_mac_ctxt_remove(mvm, vif);
@@ -1764,14 +1765,16 @@ out:
1764 return ret; 1765 return ret;
1765} 1766}
1766 1767
1767static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw, 1768static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
1768 struct ieee80211_vif *vif) 1769 struct ieee80211_vif *vif)
1769{ 1770{
1770 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1771 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1771 1772
1772 mutex_lock(&mvm->mutex); 1773 mutex_lock(&mvm->mutex);
1773 iwl_mvm_sched_scan_stop(mvm); 1774 iwl_mvm_sched_scan_stop(mvm);
1774 mutex_unlock(&mvm->mutex); 1775 mutex_unlock(&mvm->mutex);
1776
1777 return 0;
1775} 1778}
1776 1779
1777static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, 1780static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
@@ -2109,7 +2112,6 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
2109 * Power state must be updated before quotas, 2112 * Power state must be updated before quotas,
2110 * otherwise fw will complain. 2113 * otherwise fw will complain.
2111 */ 2114 */
2112 mvm->bound_vif_cnt++;
2113 iwl_mvm_power_update_mac(mvm, vif); 2115 iwl_mvm_power_update_mac(mvm, vif);
2114 2116
2115 /* Setting the quota at this stage is only required for monitor 2117 /* Setting the quota at this stage is only required for monitor
@@ -2127,7 +2129,6 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
2127 2129
2128 out_remove_binding: 2130 out_remove_binding:
2129 iwl_mvm_binding_remove_vif(mvm, vif); 2131 iwl_mvm_binding_remove_vif(mvm, vif);
2130 mvm->bound_vif_cnt--;
2131 iwl_mvm_power_update_mac(mvm, vif); 2132 iwl_mvm_power_update_mac(mvm, vif);
2132 out_unlock: 2133 out_unlock:
2133 mutex_unlock(&mvm->mutex); 2134 mutex_unlock(&mvm->mutex);
@@ -2160,7 +2161,6 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
2160 } 2161 }
2161 2162
2162 iwl_mvm_binding_remove_vif(mvm, vif); 2163 iwl_mvm_binding_remove_vif(mvm, vif);
2163 mvm->bound_vif_cnt--;
2164 iwl_mvm_power_update_mac(mvm, vif); 2164 iwl_mvm_power_update_mac(mvm, vif);
2165 2165
2166out_unlock: 2166out_unlock:
@@ -2251,7 +2251,7 @@ static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw,
2251} 2251}
2252#endif 2252#endif
2253 2253
2254struct ieee80211_ops iwl_mvm_hw_ops = { 2254const struct ieee80211_ops iwl_mvm_hw_ops = {
2255 .tx = iwl_mvm_mac_tx, 2255 .tx = iwl_mvm_mac_tx,
2256 .ampdu_action = iwl_mvm_mac_ampdu_action, 2256 .ampdu_action = iwl_mvm_mac_ampdu_action,
2257 .start = iwl_mvm_mac_start, 2257 .start = iwl_mvm_mac_start,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index ad0315abf765..302cf779c172 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -91,8 +91,7 @@ enum iwl_mvm_tx_fifo {
91 IWL_MVM_TX_FIFO_MCAST = 5, 91 IWL_MVM_TX_FIFO_MCAST = 5,
92}; 92};
93 93
94extern struct ieee80211_ops iwl_mvm_hw_ops; 94extern const struct ieee80211_ops iwl_mvm_hw_ops;
95extern const struct iwl_mvm_power_ops pm_mac_ops;
96 95
97/** 96/**
98 * struct iwl_mvm_mod_params - module parameters for iwlmvm 97 * struct iwl_mvm_mod_params - module parameters for iwlmvm
@@ -426,6 +425,28 @@ struct iwl_mvm_tt_mgmt {
426 bool throttle; 425 bool throttle;
427}; 426};
428 427
428#define IWL_MVM_NUM_LAST_FRAMES_UCODE_RATES 8
429
430struct iwl_mvm_frame_stats {
431 u32 legacy_frames;
432 u32 ht_frames;
433 u32 vht_frames;
434 u32 bw_20_frames;
435 u32 bw_40_frames;
436 u32 bw_80_frames;
437 u32 bw_160_frames;
438 u32 sgi_frames;
439 u32 ngi_frames;
440 u32 siso_frames;
441 u32 mimo2_frames;
442 u32 agg_frames;
443 u32 ampdu_count;
444 u32 success_frames;
445 u32 fail_frames;
446 u32 last_rates[IWL_MVM_NUM_LAST_FRAMES_UCODE_RATES];
447 int last_frame_idx;
448};
449
429struct iwl_mvm { 450struct iwl_mvm {
430 /* for logger access */ 451 /* for logger access */
431 struct device *dev; 452 struct device *dev;
@@ -519,6 +540,7 @@ struct iwl_mvm {
519#ifdef CONFIG_IWLWIFI_DEBUGFS 540#ifdef CONFIG_IWLWIFI_DEBUGFS
520 struct dentry *debugfs_dir; 541 struct dentry *debugfs_dir;
521 u32 dbgfs_sram_offset, dbgfs_sram_len; 542 u32 dbgfs_sram_offset, dbgfs_sram_len;
543 u32 dbgfs_prph_reg_addr;
522 bool disable_power_off; 544 bool disable_power_off;
523 bool disable_power_off_d3; 545 bool disable_power_off_d3;
524 546
@@ -526,6 +548,9 @@ struct iwl_mvm {
526 struct debugfs_blob_wrapper nvm_sw_blob; 548 struct debugfs_blob_wrapper nvm_sw_blob;
527 struct debugfs_blob_wrapper nvm_calib_blob; 549 struct debugfs_blob_wrapper nvm_calib_blob;
528 struct debugfs_blob_wrapper nvm_prod_blob; 550 struct debugfs_blob_wrapper nvm_prod_blob;
551
552 struct iwl_mvm_frame_stats drv_rx_stats;
553 spinlock_t drv_stats_lock;
529#endif 554#endif
530 555
531 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; 556 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
@@ -587,8 +612,6 @@ struct iwl_mvm {
587 u8 first_agg_queue; 612 u8 first_agg_queue;
588 u8 last_agg_queue; 613 u8 last_agg_queue;
589 614
590 u8 bound_vif_cnt;
591
592 /* Indicate if device power save is allowed */ 615 /* Indicate if device power save is allowed */
593 bool ps_disabled; 616 bool ps_disabled;
594 /* Indicate if device power management is allowed */ 617 /* Indicate if device power management is allowed */
@@ -812,6 +835,10 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
812 835
813/* rate scaling */ 836/* rate scaling */
814int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init); 837int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
838void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm,
839 struct iwl_mvm_frame_stats *stats,
840 u32 rate, bool agg);
841int rs_pretty_print_rate(char *buf, const u32 rate);
815 842
816/* power management */ 843/* power management */
817int iwl_power_legacy_set_cam_mode(struct iwl_mvm *mvm); 844int iwl_power_legacy_set_cam_mode(struct iwl_mvm *mvm);
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 2d5251b3600c..cf2d09f53782 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -228,13 +228,23 @@ static struct iwl_nvm_data *
228iwl_parse_nvm_sections(struct iwl_mvm *mvm) 228iwl_parse_nvm_sections(struct iwl_mvm *mvm)
229{ 229{
230 struct iwl_nvm_section *sections = mvm->nvm_sections; 230 struct iwl_nvm_section *sections = mvm->nvm_sections;
231 const __le16 *hw, *sw, *calib; 231 const __le16 *hw, *sw, *calib, *regulatory, *mac_override;
232 232
233 /* Checking for required sections */ 233 /* Checking for required sections */
234 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || 234 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
235 !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) { 235 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
236 IWL_ERR(mvm, "Can't parse empty NVM sections\n"); 236 !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) {
237 return NULL; 237 IWL_ERR(mvm, "Can't parse empty NVM sections\n");
238 return NULL;
239 }
240 } else {
241 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
242 !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data ||
243 !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) {
244 IWL_ERR(mvm,
245 "Can't parse empty family 8000 NVM sections\n");
246 return NULL;
247 }
238 } 248 }
239 249
240 if (WARN_ON(!mvm->cfg)) 250 if (WARN_ON(!mvm->cfg))
@@ -243,9 +253,14 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
243 hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data; 253 hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
244 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; 254 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
245 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; 255 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
256 regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
257 mac_override =
258 (const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data;
259
246 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib, 260 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
247 iwl_fw_valid_tx_ant(mvm->fw), 261 regulatory, mac_override,
248 iwl_fw_valid_rx_ant(mvm->fw)); 262 mvm->fw->valid_tx_ant,
263 mvm->fw->valid_rx_ant);
249} 264}
250 265
251#define MAX_NVM_FILE_LEN 16384 266#define MAX_NVM_FILE_LEN 16384
@@ -285,6 +300,8 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
285 300
286#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF)) 301#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
287#define NVM_WORD2_ID(x) (x >> 12) 302#define NVM_WORD2_ID(x) (x >> 12)
303#define NVM_WORD2_LEN_FAMILY_8000(x) (2 * ((x & 0xFF) << 8 | x >> 8))
304#define NVM_WORD1_ID_FAMILY_8000(x) (x >> 4)
288 305
289 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); 306 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
290 307
@@ -335,8 +352,16 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
335 break; 352 break;
336 } 353 }
337 354
338 section_size = 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1)); 355 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
339 section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2)); 356 section_size =
357 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
358 section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
359 } else {
360 section_size = 2 * NVM_WORD2_LEN_FAMILY_8000(
361 le16_to_cpu(file_sec->word2));
362 section_id = NVM_WORD1_ID_FAMILY_8000(
363 le16_to_cpu(file_sec->word1));
364 }
340 365
341 if (section_size > IWL_MAX_NVM_SECTION_SIZE) { 366 if (section_size > IWL_MAX_NVM_SECTION_SIZE) {
342 IWL_ERR(mvm, "ERROR - section too large (%d)\n", 367 IWL_ERR(mvm, "ERROR - section too large (%d)\n",
@@ -406,6 +431,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
406{ 431{
407 int ret, i, section; 432 int ret, i, section;
408 u8 *nvm_buffer, *temp; 433 u8 *nvm_buffer, *temp;
434 int nvm_to_read[NVM_MAX_NUM_SECTIONS];
435 int num_of_sections_to_read;
409 436
410 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) 437 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS))
411 return -EINVAL; 438 return -EINVAL;
@@ -418,12 +445,20 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
418 return ret; 445 return ret;
419 } else { 446 } else {
420 /* list of NVM sections we are allowed/need to read */ 447 /* list of NVM sections we are allowed/need to read */
421 int nvm_to_read[] = { 448 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
422 mvm->cfg->nvm_hw_section_num, 449 nvm_to_read[0] = mvm->cfg->nvm_hw_section_num;
423 NVM_SECTION_TYPE_SW, 450 nvm_to_read[1] = NVM_SECTION_TYPE_SW;
424 NVM_SECTION_TYPE_CALIBRATION, 451 nvm_to_read[2] = NVM_SECTION_TYPE_CALIBRATION;
425 NVM_SECTION_TYPE_PRODUCTION, 452 nvm_to_read[3] = NVM_SECTION_TYPE_PRODUCTION;
426 }; 453 num_of_sections_to_read = 4;
454 } else {
455 nvm_to_read[0] = NVM_SECTION_TYPE_SW;
456 nvm_to_read[1] = NVM_SECTION_TYPE_CALIBRATION;
457 nvm_to_read[2] = NVM_SECTION_TYPE_PRODUCTION;
458 nvm_to_read[3] = NVM_SECTION_TYPE_REGULATORY;
459 nvm_to_read[4] = NVM_SECTION_TYPE_MAC_OVERRIDE;
460 num_of_sections_to_read = 5;
461 }
427 462
428 /* Read From FW NVM */ 463 /* Read From FW NVM */
429 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); 464 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
@@ -433,7 +468,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
433 GFP_KERNEL); 468 GFP_KERNEL);
434 if (!nvm_buffer) 469 if (!nvm_buffer)
435 return -ENOMEM; 470 return -ENOMEM;
436 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 471 for (i = 0; i < num_of_sections_to_read; i++) {
437 section = nvm_to_read[i]; 472 section = nvm_to_read[i];
438 /* we override the constness for initial read */ 473 /* we override the constness for initial read */
439 ret = iwl_nvm_read_section(mvm, section, nvm_buffer); 474 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index a46f0b8b0870..ae347fb16a5d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -245,7 +245,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
245#undef RX_HANDLER 245#undef RX_HANDLER
246#define CMD(x) [x] = #x 246#define CMD(x) [x] = #x
247 247
248static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { 248static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
249 CMD(MVM_ALIVE), 249 CMD(MVM_ALIVE),
250 CMD(REPLY_ERROR), 250 CMD(REPLY_ERROR),
251 CMD(INIT_COMPLETE_NOTIF), 251 CMD(INIT_COMPLETE_NOTIF),
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index b7268c0b3333..237efe0ac1c4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -156,13 +156,13 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
156 idle_cnt = chains_static; 156 idle_cnt = chains_static;
157 active_cnt = chains_dynamic; 157 active_cnt = chains_dynamic;
158 158
159 cmd->rxchain_info = cpu_to_le32(iwl_fw_valid_rx_ant(mvm->fw) << 159 cmd->rxchain_info = cpu_to_le32(mvm->fw->valid_rx_ant <<
160 PHY_RX_CHAIN_VALID_POS); 160 PHY_RX_CHAIN_VALID_POS);
161 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); 161 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
162 cmd->rxchain_info |= cpu_to_le32(active_cnt << 162 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
163 PHY_RX_CHAIN_MIMO_CNT_POS); 163 PHY_RX_CHAIN_MIMO_CNT_POS);
164 164
165 cmd->txchain_info = cpu_to_le32(iwl_fw_valid_tx_ant(mvm->fw)); 165 cmd->txchain_info = cpu_to_le32(mvm->fw->valid_tx_ant);
166} 166}
167 167
168/* 168/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 4da1ea44f39a..def6ec5173b9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -425,7 +425,7 @@ static int iwl_mvm_power_send_cmd(struct iwl_mvm *mvm,
425 return 0; 425 return 0;
426 426
427 if (vif->p2p && 427 if (vif->p2p &&
428 !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS)) 428 !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM))
429 return 0; 429 return 0;
430 430
431 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 431 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
@@ -511,8 +511,11 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
511struct iwl_power_constraint { 511struct iwl_power_constraint {
512 struct ieee80211_vif *bf_vif; 512 struct ieee80211_vif *bf_vif;
513 struct ieee80211_vif *bss_vif; 513 struct ieee80211_vif *bss_vif;
514 u16 bss_phyctx_id;
515 u16 p2p_phyctx_id;
514 bool pm_disabled; 516 bool pm_disabled;
515 bool ps_disabled; 517 bool ps_disabled;
518 struct iwl_mvm *mvm;
516}; 519};
517 520
518static void iwl_mvm_power_iterator(void *_data, u8 *mac, 521static void iwl_mvm_power_iterator(void *_data, u8 *mac,
@@ -520,6 +523,7 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
520{ 523{
521 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 524 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
522 struct iwl_power_constraint *power_iterator = _data; 525 struct iwl_power_constraint *power_iterator = _data;
526 struct iwl_mvm *mvm = power_iterator->mvm;
523 527
524 switch (ieee80211_vif_type_p2p(vif)) { 528 switch (ieee80211_vif_type_p2p(vif)) {
525 case NL80211_IFTYPE_P2P_DEVICE: 529 case NL80211_IFTYPE_P2P_DEVICE:
@@ -539,11 +543,28 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
539 break; 543 break;
540 544
541 case NL80211_IFTYPE_P2P_CLIENT: 545 case NL80211_IFTYPE_P2P_CLIENT:
542 /* no BSS power mgmt if we have a P2P client*/ 546 if (mvmvif->phy_ctxt)
543 power_iterator->pm_disabled = true; 547 power_iterator->p2p_phyctx_id = mvmvif->phy_ctxt->id;
548
549 IWL_DEBUG_POWER(mvm, "p2p: p2p_id=%d, bss_id=%d\n",
550 power_iterator->p2p_phyctx_id,
551 power_iterator->bss_phyctx_id);
552 if (!(mvm->fw->ucode_capa.flags &
553 IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)) {
554 /* no BSS power mgmt if we have a P2P client*/
555 power_iterator->pm_disabled = true;
556 } else if (power_iterator->p2p_phyctx_id < MAX_PHYS &&
557 power_iterator->bss_phyctx_id < MAX_PHYS &&
558 power_iterator->p2p_phyctx_id ==
559 power_iterator->bss_phyctx_id) {
560 power_iterator->pm_disabled = true;
561 }
544 break; 562 break;
545 563
546 case NL80211_IFTYPE_STATION: 564 case NL80211_IFTYPE_STATION:
565 if (mvmvif->phy_ctxt)
566 power_iterator->bss_phyctx_id = mvmvif->phy_ctxt->id;
567
547 /* we should have only one BSS vif */ 568 /* we should have only one BSS vif */
548 WARN_ON(power_iterator->bss_vif); 569 WARN_ON(power_iterator->bss_vif);
549 power_iterator->bss_vif = vif; 570 power_iterator->bss_vif = vif;
@@ -551,6 +572,17 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
551 if (mvmvif->bf_data.bf_enabled && 572 if (mvmvif->bf_data.bf_enabled &&
552 !WARN_ON(power_iterator->bf_vif)) 573 !WARN_ON(power_iterator->bf_vif))
553 power_iterator->bf_vif = vif; 574 power_iterator->bf_vif = vif;
575
576 IWL_DEBUG_POWER(mvm, "bss: p2p_id=%d, bss_id=%d\n",
577 power_iterator->p2p_phyctx_id,
578 power_iterator->bss_phyctx_id);
579 if (mvm->fw->ucode_capa.flags &
580 IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM &&
581 (power_iterator->p2p_phyctx_id < MAX_PHYS &&
582 power_iterator->bss_phyctx_id < MAX_PHYS &&
583 power_iterator->p2p_phyctx_id ==
584 power_iterator->bss_phyctx_id))
585 power_iterator->pm_disabled = true;
554 break; 586 break;
555 587
556 default: 588 default:
@@ -572,16 +604,16 @@ iwl_mvm_power_get_global_constraint(struct iwl_mvm *mvm,
572 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 604 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
573 IEEE80211_IFACE_ITER_NORMAL, 605 IEEE80211_IFACE_ITER_NORMAL,
574 iwl_mvm_power_iterator, constraint); 606 iwl_mvm_power_iterator, constraint);
575
576 /* TODO: remove this and determine this variable in the iterator */
577 if (mvm->bound_vif_cnt > 1)
578 constraint->pm_disabled = true;
579} 607}
580 608
581int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 609int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
582{ 610{
583 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 611 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
584 struct iwl_power_constraint constraint = {}; 612 struct iwl_power_constraint constraint = {
613 .p2p_phyctx_id = MAX_PHYS,
614 .bss_phyctx_id = MAX_PHYS,
615 .mvm = mvm,
616 };
585 bool ba_enable; 617 bool ba_enable;
586 int ret; 618 int ret;
587 619
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 32bb8075121c..399709f2be2e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -166,7 +166,7 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
166 if (sta->smps_mode == IEEE80211_SMPS_STATIC) 166 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
167 return false; 167 return false;
168 168
169 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2) 169 if (num_of_ant(mvm->fw->valid_tx_ant) < 2)
170 return false; 170 return false;
171 171
172 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 172 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
@@ -917,7 +917,7 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
917 917
918 918
919 if (num_of_ant(rate->ant) > 1) 919 if (num_of_ant(rate->ant) > 1)
920 rate->ant = first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 920 rate->ant = first_antenna(mvm->fw->valid_tx_ant);
921 921
922 /* Relevant in both switching to SISO or Legacy */ 922 /* Relevant in both switching to SISO or Legacy */
923 rate->sgi = false; 923 rate->sgi = false;
@@ -1477,7 +1477,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1477 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column]; 1477 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
1478 const struct rs_tx_column *next_col; 1478 const struct rs_tx_column *next_col;
1479 allow_column_func_t allow_func; 1479 allow_column_func_t allow_func;
1480 u8 valid_ants = iwl_fw_valid_tx_ant(mvm->fw); 1480 u8 valid_ants = mvm->fw->valid_tx_ant;
1481 const u16 *expected_tpt_tbl; 1481 const u16 *expected_tpt_tbl;
1482 s32 tpt, max_expected_tpt; 1482 s32 tpt, max_expected_tpt;
1483 1483
@@ -2089,7 +2089,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2089 2089
2090 i = lq_sta->last_txrate_idx; 2090 i = lq_sta->last_txrate_idx;
2091 2091
2092 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); 2092 valid_tx_ant = mvm->fw->valid_tx_ant;
2093 2093
2094 if (!lq_sta->search_better_tbl) 2094 if (!lq_sta->search_better_tbl)
2095 active_tbl = lq_sta->active_tbl; 2095 active_tbl = lq_sta->active_tbl;
@@ -2240,6 +2240,73 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
2240 } 2240 }
2241} 2241}
2242 2242
2243#ifdef CONFIG_IWLWIFI_DEBUGFS
2244static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm,
2245 struct iwl_mvm_frame_stats *stats)
2246{
2247 spin_lock_bh(&mvm->drv_stats_lock);
2248 memset(stats, 0, sizeof(*stats));
2249 spin_unlock_bh(&mvm->drv_stats_lock);
2250}
2251
2252void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm,
2253 struct iwl_mvm_frame_stats *stats,
2254 u32 rate, bool agg)
2255{
2256 u8 nss = 0, mcs = 0;
2257
2258 spin_lock(&mvm->drv_stats_lock);
2259
2260 if (agg)
2261 stats->agg_frames++;
2262
2263 stats->success_frames++;
2264
2265 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
2266 case RATE_MCS_CHAN_WIDTH_20:
2267 stats->bw_20_frames++;
2268 break;
2269 case RATE_MCS_CHAN_WIDTH_40:
2270 stats->bw_40_frames++;
2271 break;
2272 case RATE_MCS_CHAN_WIDTH_80:
2273 stats->bw_80_frames++;
2274 break;
2275 default:
2276 WARN_ONCE(1, "bad BW. rate 0x%x", rate);
2277 }
2278
2279 if (rate & RATE_MCS_HT_MSK) {
2280 stats->ht_frames++;
2281 mcs = rate & RATE_HT_MCS_RATE_CODE_MSK;
2282 nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1;
2283 } else if (rate & RATE_MCS_VHT_MSK) {
2284 stats->vht_frames++;
2285 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
2286 nss = ((rate & RATE_VHT_MCS_NSS_MSK) >>
2287 RATE_VHT_MCS_NSS_POS) + 1;
2288 } else {
2289 stats->legacy_frames++;
2290 }
2291
2292 if (nss == 1)
2293 stats->siso_frames++;
2294 else if (nss == 2)
2295 stats->mimo2_frames++;
2296
2297 if (rate & RATE_MCS_SGI_MSK)
2298 stats->sgi_frames++;
2299 else
2300 stats->ngi_frames++;
2301
2302 stats->last_rates[stats->last_frame_idx] = rate;
2303 stats->last_frame_idx = (stats->last_frame_idx + 1) %
2304 ARRAY_SIZE(stats->last_rates);
2305
2306 spin_unlock(&mvm->drv_stats_lock);
2307}
2308#endif
2309
2243/* 2310/*
2244 * Called after adding a new station to initialize rate scaling 2311 * Called after adding a new station to initialize rate scaling
2245 */ 2312 */
@@ -2319,7 +2386,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2319 2386
2320 /* These values will be overridden later */ 2387 /* These values will be overridden later */
2321 lq_sta->lq.single_stream_ant_msk = 2388 lq_sta->lq.single_stream_ant_msk =
2322 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 2389 first_antenna(mvm->fw->valid_tx_ant);
2323 lq_sta->lq.dual_stream_ant_msk = ANT_AB; 2390 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2324 2391
2325 /* as default allow aggregation for all tids */ 2392 /* as default allow aggregation for all tids */
@@ -2334,7 +2401,9 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2334#ifdef CONFIG_MAC80211_DEBUGFS 2401#ifdef CONFIG_MAC80211_DEBUGFS
2335 lq_sta->dbg_fixed_rate = 0; 2402 lq_sta->dbg_fixed_rate = 0;
2336#endif 2403#endif
2337 2404#ifdef CONFIG_IWLWIFI_DEBUGFS
2405 iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats);
2406#endif
2338 rs_initialize_lq(mvm, sta, lq_sta, band, init); 2407 rs_initialize_lq(mvm, sta, lq_sta, band, init);
2339} 2408}
2340 2409
@@ -2445,7 +2514,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2445 2514
2446 memcpy(&rate, initial_rate, sizeof(rate)); 2515 memcpy(&rate, initial_rate, sizeof(rate));
2447 2516
2448 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); 2517 valid_tx_ant = mvm->fw->valid_tx_ant;
2449 2518
2450 if (is_siso(&rate)) { 2519 if (is_siso(&rate)) {
2451 num_rates = RS_INITIAL_SISO_NUM_RATES; 2520 num_rates = RS_INITIAL_SISO_NUM_RATES;
@@ -2546,7 +2615,7 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
2546} 2615}
2547 2616
2548#ifdef CONFIG_MAC80211_DEBUGFS 2617#ifdef CONFIG_MAC80211_DEBUGFS
2549static int rs_pretty_print_rate(char *buf, const u32 rate) 2618int rs_pretty_print_rate(char *buf, const u32 rate)
2550{ 2619{
2551 2620
2552 char *type, *bw; 2621 char *type, *bw;
@@ -2595,7 +2664,7 @@ static int rs_pretty_print_rate(char *buf, const u32 rate)
2595 return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n", 2664 return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n",
2596 type, rs_pretty_ant(ant), bw, mcs, nss, 2665 type, rs_pretty_ant(ant), bw, mcs, nss,
2597 (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ", 2666 (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ",
2598 (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", 2667 (rate & RATE_MCS_HT_STBC_MSK) ? "STBC " : "",
2599 (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "", 2668 (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
2600 (rate & RATE_MCS_BF_MSK) ? "BF " : "", 2669 (rate & RATE_MCS_BF_MSK) ? "BF " : "",
2601 (rate & RATE_MCS_ZLF_MSK) ? "ZLF " : ""); 2670 (rate & RATE_MCS_ZLF_MSK) ? "ZLF " : "");
@@ -2676,9 +2745,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2676 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 2745 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2677 lq_sta->dbg_fixed_rate); 2746 lq_sta->dbg_fixed_rate);
2678 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 2747 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2679 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_A) ? "ANT_A," : "", 2748 (mvm->fw->valid_tx_ant & ANT_A) ? "ANT_A," : "",
2680 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", 2749 (mvm->fw->valid_tx_ant & ANT_B) ? "ANT_B," : "",
2681 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); 2750 (mvm->fw->valid_tx_ant & ANT_C) ? "ANT_C" : "");
2682 desc += sprintf(buff+desc, "lq type %s\n", 2751 desc += sprintf(buff+desc, "lq type %s\n",
2683 (is_legacy(rate)) ? "legacy" : 2752 (is_legacy(rate)) ? "legacy" :
2684 is_vht(rate) ? "VHT" : "HT"); 2753 is_vht(rate) ? "VHT" : "HT");
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index fa3c1393e103..6061553a5e44 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -77,6 +77,15 @@ int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
77 77
78 memcpy(&mvm->last_phy_info, pkt->data, sizeof(mvm->last_phy_info)); 78 memcpy(&mvm->last_phy_info, pkt->data, sizeof(mvm->last_phy_info));
79 mvm->ampdu_ref++; 79 mvm->ampdu_ref++;
80
81#ifdef CONFIG_IWLWIFI_DEBUGFS
82 if (mvm->last_phy_info.phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_AGG)) {
83 spin_lock(&mvm->drv_stats_lock);
84 mvm->drv_rx_stats.ampdu_count++;
85 spin_unlock(&mvm->drv_stats_lock);
86 }
87#endif
88
80 return 0; 89 return 0;
81} 90}
82 91
@@ -368,21 +377,33 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
368 rx_status.flag |= RX_FLAG_SHORT_GI; 377 rx_status.flag |= RX_FLAG_SHORT_GI;
369 if (rate_n_flags & RATE_HT_MCS_GF_MSK) 378 if (rate_n_flags & RATE_HT_MCS_GF_MSK)
370 rx_status.flag |= RX_FLAG_HT_GF; 379 rx_status.flag |= RX_FLAG_HT_GF;
380 if (rate_n_flags & RATE_MCS_LDPC_MSK)
381 rx_status.flag |= RX_FLAG_LDPC;
371 if (rate_n_flags & RATE_MCS_HT_MSK) { 382 if (rate_n_flags & RATE_MCS_HT_MSK) {
383 u8 stbc = (rate_n_flags & RATE_MCS_HT_STBC_MSK) >>
384 RATE_MCS_STBC_POS;
372 rx_status.flag |= RX_FLAG_HT; 385 rx_status.flag |= RX_FLAG_HT;
373 rx_status.rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; 386 rx_status.rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
387 rx_status.flag |= stbc << RX_FLAG_STBC_SHIFT;
374 } else if (rate_n_flags & RATE_MCS_VHT_MSK) { 388 } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
389 u8 stbc = (rate_n_flags & RATE_MCS_VHT_STBC_MSK) >>
390 RATE_MCS_STBC_POS;
375 rx_status.vht_nss = 391 rx_status.vht_nss =
376 ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> 392 ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
377 RATE_VHT_MCS_NSS_POS) + 1; 393 RATE_VHT_MCS_NSS_POS) + 1;
378 rx_status.rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; 394 rx_status.rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
379 rx_status.flag |= RX_FLAG_VHT; 395 rx_status.flag |= RX_FLAG_VHT;
396 rx_status.flag |= stbc << RX_FLAG_STBC_SHIFT;
380 } else { 397 } else {
381 rx_status.rate_idx = 398 rx_status.rate_idx =
382 iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, 399 iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
383 rx_status.band); 400 rx_status.band);
384 } 401 }
385 402
403#ifdef CONFIG_IWLWIFI_DEBUGFS
404 iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags,
405 rx_status.flag & RX_FLAG_AMPDU_DETAILS);
406#endif
386 iwl_mvm_pass_packet_to_mac80211(mvm, hdr, len, ampdu_status, 407 iwl_mvm_pass_packet_to_mac80211(mvm, hdr, len, ampdu_status,
387 rxb, &rx_status); 408 rxb, &rx_status);
388 return 0; 409 return 0;
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index eba55cc3352d..713efd71efe2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -82,7 +82,7 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
82 if (mvm->scan_rx_ant != ANT_NONE) 82 if (mvm->scan_rx_ant != ANT_NONE)
83 rx_ant = mvm->scan_rx_ant; 83 rx_ant = mvm->scan_rx_ant;
84 else 84 else
85 rx_ant = iwl_fw_valid_rx_ant(mvm->fw); 85 rx_ant = mvm->fw->valid_rx_ant;
86 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; 86 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
87 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; 87 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
88 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS; 88 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS;
@@ -124,7 +124,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
124 u32 tx_ant; 124 u32 tx_ant;
125 125
126 mvm->scan_last_antenna_idx = 126 mvm->scan_last_antenna_idx =
127 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), 127 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
128 mvm->scan_last_antenna_idx); 128 mvm->scan_last_antenna_idx);
129 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS; 129 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
130 130
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index e145dd41e85e..61331245ad93 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -438,7 +438,8 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
438 time_cmd.duration = cpu_to_le32(duration); 438 time_cmd.duration = cpu_to_le32(duration);
439 time_cmd.repeat = 1; 439 time_cmd.repeat = 1;
440 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START | 440 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
441 TE_V2_NOTIF_HOST_EVENT_END); 441 TE_V2_NOTIF_HOST_EVENT_END |
442 T2_V2_START_IMMEDIATELY);
442 443
443 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 444 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
444} 445}
@@ -553,7 +554,8 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
553 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); 554 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
554 time_cmd.repeat = 1; 555 time_cmd.repeat = 1;
555 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START | 556 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
556 TE_V2_NOTIF_HOST_EVENT_END); 557 TE_V2_NOTIF_HOST_EVENT_END |
558 T2_V2_START_IMMEDIATELY);
557 559
558 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 560 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
559} 561}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 98096fa364cd..0ba96654d2c3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -122,7 +122,7 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
122 * it 122 * it
123 */ 123 */
124 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU); 124 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU);
125 } else if (skb->protocol == cpu_to_be16(ETH_P_PAE)) { 125 } else if (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
126 tx_cmd->pm_frame_timeout = cpu_to_le16(2); 126 tx_cmd->pm_frame_timeout = cpu_to_le16(2);
127 } else { 127 } else {
128 tx_cmd->pm_frame_timeout = 0; 128 tx_cmd->pm_frame_timeout = 0;
@@ -207,7 +207,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
207 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); 207 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
208 208
209 mvm->mgmt_last_antenna_idx = 209 mvm->mgmt_last_antenna_idx =
210 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), 210 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
211 mvm->mgmt_last_antenna_idx); 211 mvm->mgmt_last_antenna_idx);
212 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; 212 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
213 213
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 1493f79e67e0..bbfe529d7b64 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -289,8 +289,8 @@ u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx)
289 return last_idx; 289 return last_idx;
290} 290}
291 291
292static struct { 292static const struct {
293 char *name; 293 const char *name;
294 u8 num; 294 u8 num;
295} advanced_lookup[] = { 295} advanced_lookup[] = {
296 { "NMI_INTERRUPT_WDG", 0x34 }, 296 { "NMI_INTERRUPT_WDG", 0x34 },
@@ -589,7 +589,7 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
589 lockdep_assert_held(&mvm->mutex); 589 lockdep_assert_held(&mvm->mutex);
590 590
591 /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */ 591 /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */
592 if (num_of_ant(iwl_fw_valid_rx_ant(mvm->fw)) == 1) 592 if (num_of_ant(mvm->fw->valid_rx_ant) == 1)
593 return; 593 return;
594 594
595 if (vif->type == NL80211_IFTYPE_AP) 595 if (vif->type == NL80211_IFTYPE_AP)
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index e851f26fd44c..3120bc5bb12d 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -304,7 +304,7 @@ struct iwl_trans_pcie {
304 bool bc_table_dword; 304 bool bc_table_dword;
305 u32 rx_page_order; 305 u32 rx_page_order;
306 306
307 const char **command_names; 307 const char *const *command_names;
308 308
309 /* queue watchdog */ 309 /* queue watchdog */
310 unsigned long wd_timeout; 310 unsigned long wd_timeout;
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 41f684deff97..cf49f6ce0ff8 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -155,37 +155,26 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
155 if (rxq->need_update == 0) 155 if (rxq->need_update == 0)
156 goto exit_unlock; 156 goto exit_unlock;
157 157
158 if (trans->cfg->base_params->shadow_reg_enable) { 158 /*
159 /* shadow register enabled */ 159 * explicitly wake up the NIC if:
160 /* Device expects a multiple of 8 */ 160 * 1. shadow registers aren't enabled
161 rxq->write_actual = (rxq->write & ~0x7); 161 * 2. there is a chance that the NIC is asleep
162 iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual); 162 */
163 } else { 163 if (!trans->cfg->base_params->shadow_reg_enable &&
164 /* If power-saving is in use, make sure device is awake */ 164 test_bit(STATUS_TPOWER_PMI, &trans->status)) {
165 if (test_bit(STATUS_TPOWER_PMI, &trans->status)) { 165 reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
166 reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); 166
167 167 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
168 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { 168 IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup, GP1 = 0x%x\n",
169 IWL_DEBUG_INFO(trans, 169 reg);
170 "Rx queue requesting wakeup," 170 iwl_set_bit(trans, CSR_GP_CNTRL,
171 " GP1 = 0x%x\n", reg); 171 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
172 iwl_set_bit(trans, CSR_GP_CNTRL, 172 goto exit_unlock;
173 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
174 goto exit_unlock;
175 }
176
177 rxq->write_actual = (rxq->write & ~0x7);
178 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
179 rxq->write_actual);
180
181 /* Else device is assumed to be awake */
182 } else {
183 /* Device expects a multiple of 8 */
184 rxq->write_actual = (rxq->write & ~0x7);
185 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
186 rxq->write_actual);
187 } 173 }
188 } 174 }
175
176 rxq->write_actual = round_down(rxq->write, 8);
177 iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
189 rxq->need_update = 0; 178 rxq->need_update = 0;
190 179
191 exit_unlock: 180 exit_unlock:
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 254126447c68..3b0c72c10054 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -207,7 +207,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
207 IWL_ERR(trans, "scratch %d = 0x%08x\n", i, 207 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
208 le32_to_cpu(txq->scratchbufs[i].scratch)); 208 le32_to_cpu(txq->scratchbufs[i].scratch));
209 209
210 iwl_trans_fw_error(trans); 210 iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
211} 211}
212 212
213/* 213/*
@@ -296,43 +296,38 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq)
296 if (txq->need_update == 0) 296 if (txq->need_update == 0)
297 return; 297 return;
298 298
299 if (trans->cfg->base_params->shadow_reg_enable || 299 /*
300 txq_id == trans_pcie->cmd_queue) { 300 * explicitly wake up the NIC if:
301 /* shadow register enabled */ 301 * 1. shadow registers aren't enabled
302 iwl_write32(trans, HBUS_TARG_WRPTR, 302 * 2. NIC is woken up for CMD regardless of shadow outside this function
303 txq->q.write_ptr | (txq_id << 8)); 303 * 3. there is a chance that the NIC is asleep
304 } else { 304 */
305 /* if we're trying to save power */ 305 if (!trans->cfg->base_params->shadow_reg_enable &&
306 if (test_bit(STATUS_TPOWER_PMI, &trans->status)) { 306 txq_id != trans_pcie->cmd_queue &&
307 /* wake up nic if it's powered down ... 307 test_bit(STATUS_TPOWER_PMI, &trans->status)) {
308 * uCode will wake up, and interrupt us again, so next
309 * time we'll skip this part. */
310 reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
311
312 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
313 IWL_DEBUG_INFO(trans,
314 "Tx queue %d requesting wakeup,"
315 " GP1 = 0x%x\n", txq_id, reg);
316 iwl_set_bit(trans, CSR_GP_CNTRL,
317 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
318 return;
319 }
320
321 IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id,
322 txq->q.write_ptr);
323
324 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
325 txq->q.write_ptr | (txq_id << 8));
326
327 /* 308 /*
328 * else not in power-save mode, 309 * wake up nic if it's powered down ...
329 * uCode will never sleep when we're 310 * uCode will wake up, and interrupt us again, so next
330 * trying to tx (during RFKILL, we're not trying to tx). 311 * time we'll skip this part.
331 */ 312 */
332 } else 313 reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
333 iwl_write32(trans, HBUS_TARG_WRPTR, 314
334 txq->q.write_ptr | (txq_id << 8)); 315 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
316 IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
317 txq_id, reg);
318 iwl_set_bit(trans, CSR_GP_CNTRL,
319 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
320 return;
321 }
335 } 322 }
323
324 /*
325 * if not in power-save mode, uCode will never sleep when we're
326 * trying to tx (during RFKILL, we're not trying to tx).
327 */
328 IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, txq->q.write_ptr);
329 iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8));
330
336 txq->need_update = 0; 331 txq->need_update = 0;
337} 332}
338 333
@@ -1029,7 +1024,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1029 if (nfreed++ > 0) { 1024 if (nfreed++ > 0) {
1030 IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", 1025 IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
1031 idx, q->write_ptr, q->read_ptr); 1026 idx, q->write_ptr, q->read_ptr);
1032 iwl_trans_fw_error(trans); 1027 iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
1033 } 1028 }
1034 } 1029 }
1035 1030
@@ -1588,6 +1583,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1588 get_cmd_string(trans_pcie, cmd->id)); 1583 get_cmd_string(trans_pcie, cmd->id));
1589 ret = -ETIMEDOUT; 1584 ret = -ETIMEDOUT;
1590 1585
1586 iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
1591 iwl_trans_fw_error(trans); 1587 iwl_trans_fw_error(trans);
1592 1588
1593 goto cancel; 1589 goto cancel;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 58c6ee5de98f..33ceda296c9c 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -498,7 +498,7 @@ static int if_sdio_prog_helper(struct if_sdio_card *card,
498 */ 498 */
499 mdelay(2); 499 mdelay(2);
500 500
501 chunk_size = min(size, (size_t)60); 501 chunk_size = min_t(size_t, size, 60);
502 502
503 *((__le32*)chunk_buffer) = cpu_to_le32(chunk_size); 503 *((__le32*)chunk_buffer) = cpu_to_le32(chunk_size);
504 memcpy(chunk_buffer + 4, firmware, chunk_size); 504 memcpy(chunk_buffer + 4, firmware, chunk_size);
@@ -639,7 +639,7 @@ static int if_sdio_prog_real(struct if_sdio_card *card,
639 req_size = size; 639 req_size = size;
640 640
641 while (req_size) { 641 while (req_size) {
642 chunk_size = min(req_size, (size_t)512); 642 chunk_size = min_t(size_t, req_size, 512);
643 643
644 memcpy(chunk_buffer, firmware, chunk_size); 644 memcpy(chunk_buffer, firmware, chunk_size);
645/* 645/*
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index f7e3562542fe..9d7a52f5a410 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -411,6 +411,7 @@ struct mac80211_hwsim_data {
411 411
412 struct mac_address addresses[2]; 412 struct mac_address addresses[2];
413 int channels, idx; 413 int channels, idx;
414 bool use_chanctx;
414 415
415 struct ieee80211_channel *tmp_chan; 416 struct ieee80211_channel *tmp_chan;
416 struct delayed_work roc_done; 417 struct delayed_work roc_done;
@@ -1088,7 +1089,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
1088 return; 1089 return;
1089 } 1090 }
1090 1091
1091 if (data->channels == 1) { 1092 if (!data->use_chanctx) {
1092 channel = data->channel; 1093 channel = data->channel;
1093 } else if (txi->hw_queue == 4) { 1094 } else if (txi->hw_queue == 4) {
1094 channel = data->tmp_chan; 1095 channel = data->tmp_chan;
@@ -1354,7 +1355,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
1354 1355
1355 data->channel = conf->chandef.chan; 1356 data->channel = conf->chandef.chan;
1356 1357
1357 WARN_ON(data->channel && data->channels > 1); 1358 WARN_ON(data->channel && data->use_chanctx);
1358 1359
1359 data->power_level = conf->power_level; 1360 data->power_level = conf->power_level;
1360 if (!data->started || !data->beacon_int) 1361 if (!data->started || !data->beacon_int)
@@ -1940,7 +1941,8 @@ static struct ieee80211_ops mac80211_hwsim_mchan_ops;
1940 1941
1941static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, 1942static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
1942 const struct ieee80211_regdomain *regd, 1943 const struct ieee80211_regdomain *regd,
1943 bool reg_strict, bool p2p_device) 1944 bool reg_strict, bool p2p_device,
1945 bool use_chanctx)
1944{ 1946{
1945 int err; 1947 int err;
1946 u8 addr[ETH_ALEN]; 1948 u8 addr[ETH_ALEN];
@@ -1950,11 +1952,14 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
1950 const struct ieee80211_ops *ops = &mac80211_hwsim_ops; 1952 const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
1951 int idx; 1953 int idx;
1952 1954
1955 if (WARN_ON(channels > 1 && !use_chanctx))
1956 return -EINVAL;
1957
1953 spin_lock_bh(&hwsim_radio_lock); 1958 spin_lock_bh(&hwsim_radio_lock);
1954 idx = hwsim_radio_idx++; 1959 idx = hwsim_radio_idx++;
1955 spin_unlock_bh(&hwsim_radio_lock); 1960 spin_unlock_bh(&hwsim_radio_lock);
1956 1961
1957 if (channels > 1) 1962 if (use_chanctx)
1958 ops = &mac80211_hwsim_mchan_ops; 1963 ops = &mac80211_hwsim_mchan_ops;
1959 hw = ieee80211_alloc_hw(sizeof(*data), ops); 1964 hw = ieee80211_alloc_hw(sizeof(*data), ops);
1960 if (!hw) { 1965 if (!hw) {
@@ -1995,20 +2000,21 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
1995 hw->wiphy->addresses = data->addresses; 2000 hw->wiphy->addresses = data->addresses;
1996 2001
1997 data->channels = channels; 2002 data->channels = channels;
2003 data->use_chanctx = use_chanctx;
1998 data->idx = idx; 2004 data->idx = idx;
1999 2005
2000 if (data->channels > 1) { 2006 if (data->use_chanctx) {
2001 hw->wiphy->max_scan_ssids = 255; 2007 hw->wiphy->max_scan_ssids = 255;
2002 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 2008 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
2003 hw->wiphy->max_remain_on_channel_duration = 1000; 2009 hw->wiphy->max_remain_on_channel_duration = 1000;
2004 /* For channels > 1 DFS is not allowed */ 2010 /* For channels > 1 DFS is not allowed */
2005 hw->wiphy->n_iface_combinations = 1; 2011 hw->wiphy->n_iface_combinations = 1;
2006 hw->wiphy->iface_combinations = &data->if_combination; 2012 hw->wiphy->iface_combinations = &data->if_combination;
2007 data->if_combination.num_different_channels = data->channels;
2008 if (p2p_device) 2013 if (p2p_device)
2009 data->if_combination = hwsim_if_comb_p2p_dev[0]; 2014 data->if_combination = hwsim_if_comb_p2p_dev[0];
2010 else 2015 else
2011 data->if_combination = hwsim_if_comb[0]; 2016 data->if_combination = hwsim_if_comb[0];
2017 data->if_combination.num_different_channels = data->channels;
2012 } else if (p2p_device) { 2018 } else if (p2p_device) {
2013 hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev; 2019 hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev;
2014 hw->wiphy->n_iface_combinations = 2020 hw->wiphy->n_iface_combinations =
@@ -2156,7 +2162,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
2156 debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); 2162 debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps);
2157 debugfs_create_file("group", 0666, data->debugfs, data, 2163 debugfs_create_file("group", 0666, data->debugfs, data,
2158 &hwsim_fops_group); 2164 &hwsim_fops_group);
2159 if (data->channels == 1) 2165 if (!data->use_chanctx)
2160 debugfs_create_file("dfs_simulate_radar", 0222, 2166 debugfs_create_file("dfs_simulate_radar", 0222,
2161 data->debugfs, 2167 data->debugfs,
2162 data, &hwsim_simulate_radar); 2168 data, &hwsim_simulate_radar);
@@ -2423,10 +2429,16 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
2423 const struct ieee80211_regdomain *regd = NULL; 2429 const struct ieee80211_regdomain *regd = NULL;
2424 bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; 2430 bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
2425 bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; 2431 bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE];
2432 bool use_chanctx;
2426 2433
2427 if (info->attrs[HWSIM_ATTR_CHANNELS]) 2434 if (info->attrs[HWSIM_ATTR_CHANNELS])
2428 chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); 2435 chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]);
2429 2436
2437 if (info->attrs[HWSIM_ATTR_USE_CHANCTX])
2438 use_chanctx = true;
2439 else
2440 use_chanctx = (chans > 1);
2441
2430 if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]) 2442 if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2])
2431 alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); 2443 alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]);
2432 2444
@@ -2439,7 +2451,7 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
2439 } 2451 }
2440 2452
2441 return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, 2453 return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict,
2442 p2p_device); 2454 p2p_device, use_chanctx);
2443} 2455}
2444 2456
2445static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) 2457static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info)
@@ -2658,7 +2670,8 @@ static int __init init_mac80211_hwsim(void)
2658 2670
2659 err = mac80211_hwsim_create_radio(channels, reg_alpha2, 2671 err = mac80211_hwsim_create_radio(channels, reg_alpha2,
2660 regd, reg_strict, 2672 regd, reg_strict,
2661 support_p2p_device); 2673 support_p2p_device,
2674 channels > 1);
2662 if (err < 0) 2675 if (err < 0)
2663 goto out_free_radios; 2676 goto out_free_radios;
2664 } 2677 }
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index 6e72996ec8c1..c9d0315575ba 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -108,6 +108,9 @@ enum {
108 * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute) 108 * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute)
109 * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute) 109 * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute)
110 * @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag) 110 * @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag)
111 * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO
112 * command to force use of channel contexts even when only a
113 * single channel is supported
111 * @__HWSIM_ATTR_MAX: enum limit 114 * @__HWSIM_ATTR_MAX: enum limit
112 */ 115 */
113 116
@@ -128,6 +131,7 @@ enum {
128 HWSIM_ATTR_REG_CUSTOM_REG, 131 HWSIM_ATTR_REG_CUSTOM_REG,
129 HWSIM_ATTR_REG_STRICT_REG, 132 HWSIM_ATTR_REG_STRICT_REG,
130 HWSIM_ATTR_SUPPORT_P2P_DEVICE, 133 HWSIM_ATTR_SUPPORT_P2P_DEVICE,
134 HWSIM_ATTR_USE_CHANCTX,
131 __HWSIM_ATTR_MAX, 135 __HWSIM_ATTR_MAX,
132}; 136};
133#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) 137#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index 8d683070bdb3..e76b0db4e3e6 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -73,8 +73,8 @@ static int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag)
73{ 73{
74 u32 enable = flag; 74 u32 enable = flag;
75 75
76 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 76 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
77 HostCmd_ACT_GEN_SET, DOT11H_I, &enable); 77 HostCmd_ACT_GEN_SET, DOT11H_I, &enable, true);
78} 78}
79 79
80/* This functions processes TLV buffer for a pending BSS Join command. 80/* This functions processes TLV buffer for a pending BSS Join command.
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 37677af8d2fc..79ead928a64e 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -574,8 +574,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
574 memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); 574 memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN);
575 575
576 /* We don't wait for the response of this command */ 576 /* We don't wait for the response of this command */
577 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ, 577 ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ,
578 0, 0, &add_ba_req); 578 0, 0, &add_ba_req, false);
579 579
580 return ret; 580 return ret;
581} 581}
@@ -602,8 +602,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
602 memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); 602 memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
603 603
604 /* We don't wait for the response of this command */ 604 /* We don't wait for the response of this command */
605 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 605 ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_DELBA,
606 HostCmd_ACT_GEN_SET, 0, &delba); 606 HostCmd_ACT_GEN_SET, 0, &delba, false);
607 607
608 return ret; 608 return ret;
609} 609}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index b361257fb65e..c3323c492614 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -142,7 +142,7 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
142 mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) & 142 mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) &
143 (MAX_TID_VALUE - 1)); 143 (MAX_TID_VALUE - 1));
144 144
145 del_timer(&tbl->timer_context.timer); 145 del_timer_sync(&tbl->timer_context.timer);
146 146
147 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); 147 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
148 list_del(&tbl->list); 148 list_del(&tbl->list);
@@ -279,6 +279,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
279 new_node->tid = tid; 279 new_node->tid = tid;
280 memcpy(new_node->ta, ta, ETH_ALEN); 280 memcpy(new_node->ta, ta, ETH_ALEN);
281 new_node->start_win = seq_num; 281 new_node->start_win = seq_num;
282 new_node->init_win = seq_num;
283 new_node->flags = 0;
282 284
283 if (mwifiex_queuing_ra_based(priv)) { 285 if (mwifiex_queuing_ra_based(priv)) {
284 dev_dbg(priv->adapter->dev, 286 dev_dbg(priv->adapter->dev,
@@ -298,11 +300,12 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
298 } 300 }
299 301
300 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && 302 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM &&
301 last_seq >= new_node->start_win) 303 last_seq >= new_node->start_win) {
302 new_node->start_win = last_seq + 1; 304 new_node->start_win = last_seq + 1;
305 new_node->flags |= RXREOR_INIT_WINDOW_SHIFT;
306 }
303 307
304 new_node->win_size = win_size; 308 new_node->win_size = win_size;
305 new_node->flags = 0;
306 309
307 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size, 310 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
308 GFP_KERNEL); 311 GFP_KERNEL);
@@ -452,6 +455,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
452 struct mwifiex_rx_reorder_tbl *tbl; 455 struct mwifiex_rx_reorder_tbl *tbl;
453 int start_win, end_win, win_size; 456 int start_win, end_win, win_size;
454 u16 pkt_index; 457 u16 pkt_index;
458 bool init_window_shift = false;
455 459
456 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); 460 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
457 if (!tbl) { 461 if (!tbl) {
@@ -466,19 +470,29 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
466 start_win = tbl->start_win; 470 start_win = tbl->start_win;
467 win_size = tbl->win_size; 471 win_size = tbl->win_size;
468 end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); 472 end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
469 del_timer(&tbl->timer_context.timer); 473 if (tbl->flags & RXREOR_INIT_WINDOW_SHIFT) {
474 init_window_shift = true;
475 tbl->flags &= ~RXREOR_INIT_WINDOW_SHIFT;
476 }
470 mod_timer(&tbl->timer_context.timer, 477 mod_timer(&tbl->timer_context.timer,
471 jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size)); 478 jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size));
472 479
473 /*
474 * If seq_num is less then starting win then ignore and drop the
475 * packet
476 */
477 if (tbl->flags & RXREOR_FORCE_NO_DROP) { 480 if (tbl->flags & RXREOR_FORCE_NO_DROP) {
478 dev_dbg(priv->adapter->dev, 481 dev_dbg(priv->adapter->dev,
479 "RXREOR_FORCE_NO_DROP when HS is activated\n"); 482 "RXREOR_FORCE_NO_DROP when HS is activated\n");
480 tbl->flags &= ~RXREOR_FORCE_NO_DROP; 483 tbl->flags &= ~RXREOR_FORCE_NO_DROP;
484 } else if (init_window_shift && seq_num < start_win &&
485 seq_num >= tbl->init_win) {
486 dev_dbg(priv->adapter->dev,
487 "Sender TID sequence number reset %d->%d for SSN %d\n",
488 start_win, seq_num, tbl->init_win);
489 tbl->start_win = start_win = seq_num;
490 end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
481 } else { 491 } else {
492 /*
493 * If seq_num is less then starting win then ignore and drop
494 * the packet
495 */
482 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) { 496 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {
483 if (seq_num >= ((start_win + TWOPOW11) & 497 if (seq_num >= ((start_win + TWOPOW11) &
484 (MAX_TID_VALUE - 1)) && 498 (MAX_TID_VALUE - 1)) &&
@@ -636,7 +650,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
636 delba.del_ba_param_set |= cpu_to_le16( 650 delba.del_ba_param_set |= cpu_to_le16(
637 (u16) event->origninator << DELBA_INITIATOR_POS); 651 (u16) event->origninator << DELBA_INITIATOR_POS);
638 delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); 652 delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
639 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba); 653 mwifiex_send_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba, false);
640} 654}
641 655
642/* 656/*
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 4064041ac852..0fc76e4a60f8 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -42,7 +42,8 @@
42#define BA_SETUP_PACKET_OFFSET 16 42#define BA_SETUP_PACKET_OFFSET 16
43 43
44enum mwifiex_rxreor_flags { 44enum mwifiex_rxreor_flags {
45 RXREOR_FORCE_NO_DROP = 1<<0, 45 RXREOR_FORCE_NO_DROP = 1<<0,
46 RXREOR_INIT_WINDOW_SHIFT = 1<<1,
46}; 47};
47 48
48static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) 49static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv)
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
index 3d64613ebb29..b9242c3dca43 100644
--- a/drivers/net/wireless/mwifiex/README
+++ b/drivers/net/wireless/mwifiex/README
@@ -131,7 +131,7 @@ info
131 hs_configured = <0/1, host sleep not configured/configured> 131 hs_configured = <0/1, host sleep not configured/configured>
132 hs_activated = <0/1, extended host sleep not activated/activated> 132 hs_activated = <0/1, extended host sleep not activated/activated>
133 num_tx_timeout = <number of Tx timeout> 133 num_tx_timeout = <number of Tx timeout>
134 num_cmd_timeout = <number of timeout commands> 134 is_cmd_timedout = <0/1 command timeout not occurred/occurred>
135 timeout_cmd_id = <command id of the last timeout command> 135 timeout_cmd_id = <command id of the last timeout command>
136 timeout_cmd_act = <command action of the last timeout command> 136 timeout_cmd_act = <command action of the last timeout command>
137 last_cmd_id = <command id of the last several commands sent to device> 137 last_cmd_id = <command id of the last several commands sent to device>
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 436ba437a4ba..51ce99cfcfb9 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -252,9 +252,9 @@ mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
252 252
253 if (mask != priv->mgmt_frame_mask) { 253 if (mask != priv->mgmt_frame_mask) {
254 priv->mgmt_frame_mask = mask; 254 priv->mgmt_frame_mask = mask;
255 mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG, 255 mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
256 HostCmd_ACT_GEN_SET, 0, 256 HostCmd_ACT_GEN_SET, 0,
257 &priv->mgmt_frame_mask); 257 &priv->mgmt_frame_mask, false);
258 wiphy_dbg(wiphy, "info: mgmt frame registered\n"); 258 wiphy_dbg(wiphy, "info: mgmt frame registered\n");
259 } 259 }
260} 260}
@@ -515,8 +515,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
515 515
516 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 516 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
517 517
518 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 518 if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
519 HostCmd_ACT_GEN_SET, 0, NULL)) { 519 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
520 wiphy_err(wiphy, "11D: setting domain info in FW\n"); 520 wiphy_err(wiphy, "11D: setting domain info in FW\n");
521 return -1; 521 return -1;
522 } 522 }
@@ -580,9 +580,9 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
580 frag_thr > MWIFIEX_FRAG_MAX_VALUE) 580 frag_thr > MWIFIEX_FRAG_MAX_VALUE)
581 frag_thr = MWIFIEX_FRAG_MAX_VALUE; 581 frag_thr = MWIFIEX_FRAG_MAX_VALUE;
582 582
583 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 583 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
584 HostCmd_ACT_GEN_SET, FRAG_THRESH_I, 584 HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
585 &frag_thr); 585 &frag_thr, true);
586} 586}
587 587
588/* 588/*
@@ -597,9 +597,9 @@ mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
597 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) 597 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
598 rts_thr = MWIFIEX_RTS_MAX_VALUE; 598 rts_thr = MWIFIEX_RTS_MAX_VALUE;
599 599
600 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 600 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
601 HostCmd_ACT_GEN_SET, RTS_THRESH_I, 601 HostCmd_ACT_GEN_SET, RTS_THRESH_I,
602 &rts_thr); 602 &rts_thr, true);
603} 603}
604 604
605/* 605/*
@@ -637,20 +637,19 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
637 637
638 bss_started = priv->bss_started; 638 bss_started = priv->bss_started;
639 639
640 ret = mwifiex_send_cmd_sync(priv, 640 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
641 HostCmd_CMD_UAP_BSS_STOP, 641 HostCmd_ACT_GEN_SET, 0,
642 HostCmd_ACT_GEN_SET, 0, 642 NULL, true);
643 NULL);
644 if (ret) { 643 if (ret) {
645 wiphy_err(wiphy, "Failed to stop the BSS\n"); 644 wiphy_err(wiphy, "Failed to stop the BSS\n");
646 kfree(bss_cfg); 645 kfree(bss_cfg);
647 return ret; 646 return ret;
648 } 647 }
649 648
650 ret = mwifiex_send_cmd_async(priv, 649 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
651 HostCmd_CMD_UAP_SYS_CONFIG, 650 HostCmd_ACT_GEN_SET,
652 HostCmd_ACT_GEN_SET, 651 UAP_BSS_PARAMS_I, bss_cfg,
653 UAP_BSS_PARAMS_I, bss_cfg); 652 false);
654 653
655 kfree(bss_cfg); 654 kfree(bss_cfg);
656 655
@@ -662,10 +661,9 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
662 if (!bss_started) 661 if (!bss_started)
663 break; 662 break;
664 663
665 ret = mwifiex_send_cmd_async(priv, 664 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
666 HostCmd_CMD_UAP_BSS_START, 665 HostCmd_ACT_GEN_SET, 0,
667 HostCmd_ACT_GEN_SET, 0, 666 NULL, false);
668 NULL);
669 if (ret) { 667 if (ret) {
670 wiphy_err(wiphy, "Failed to start BSS\n"); 668 wiphy_err(wiphy, "Failed to start BSS\n");
671 return ret; 669 return ret;
@@ -700,8 +698,8 @@ mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
700 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) 698 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA)
701 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA); 699 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA);
702 700
703 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 701 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
704 HostCmd_ACT_GEN_SET, 0, &mode)) 702 HostCmd_ACT_GEN_SET, 0, &mode, true))
705 return -1; 703 return -1;
706 704
707 return 0; 705 return 0;
@@ -721,13 +719,13 @@ mwifiex_cfg80211_init_p2p_client(struct mwifiex_private *priv)
721 return -1; 719 return -1;
722 720
723 mode = P2P_MODE_DEVICE; 721 mode = P2P_MODE_DEVICE;
724 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 722 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
725 HostCmd_ACT_GEN_SET, 0, &mode)) 723 HostCmd_ACT_GEN_SET, 0, &mode, true))
726 return -1; 724 return -1;
727 725
728 mode = P2P_MODE_CLIENT; 726 mode = P2P_MODE_CLIENT;
729 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 727 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
730 HostCmd_ACT_GEN_SET, 0, &mode)) 728 HostCmd_ACT_GEN_SET, 0, &mode, true))
731 return -1; 729 return -1;
732 730
733 return 0; 731 return 0;
@@ -747,13 +745,13 @@ mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
747 return -1; 745 return -1;
748 746
749 mode = P2P_MODE_DEVICE; 747 mode = P2P_MODE_DEVICE;
750 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 748 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
751 HostCmd_ACT_GEN_SET, 0, &mode)) 749 HostCmd_ACT_GEN_SET, 0, &mode, true))
752 return -1; 750 return -1;
753 751
754 mode = P2P_MODE_GO; 752 mode = P2P_MODE_GO;
755 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 753 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
756 HostCmd_ACT_GEN_SET, 0, &mode)) 754 HostCmd_ACT_GEN_SET, 0, &mode, true))
757 return -1; 755 return -1;
758 756
759 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) 757 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
@@ -853,8 +851,8 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
853 851
854 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; 852 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
855 853
856 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, 854 ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
857 HostCmd_ACT_GEN_SET, 0, NULL); 855 HostCmd_ACT_GEN_SET, 0, NULL, true);
858 856
859 return ret; 857 return ret;
860} 858}
@@ -942,8 +940,8 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
942 STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; 940 STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
943 941
944 /* Get signal information from the firmware */ 942 /* Get signal information from the firmware */
945 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO, 943 if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
946 HostCmd_ACT_GEN_GET, 0, NULL)) { 944 HostCmd_ACT_GEN_GET, 0, NULL, true)) {
947 dev_err(priv->adapter->dev, "failed to get signal information\n"); 945 dev_err(priv->adapter->dev, "failed to get signal information\n");
948 return -EFAULT; 946 return -EFAULT;
949 } 947 }
@@ -954,9 +952,9 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
954 } 952 }
955 953
956 /* Get DTIM period information from firmware */ 954 /* Get DTIM period information from firmware */
957 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 955 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
958 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I, 956 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
959 &priv->dtim_period); 957 &priv->dtim_period, true);
960 958
961 mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate); 959 mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate);
962 960
@@ -1186,8 +1184,8 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
1186 if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) 1184 if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2)
1187 bitmap_rates[2] |= mask->control[band].ht_mcs[1] << 8; 1185 bitmap_rates[2] |= mask->control[band].ht_mcs[1] << 8;
1188 1186
1189 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, 1187 return mwifiex_send_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
1190 HostCmd_ACT_GEN_SET, 0, bitmap_rates); 1188 HostCmd_ACT_GEN_SET, 0, bitmap_rates, true);
1191} 1189}
1192 1190
1193/* 1191/*
@@ -1216,14 +1214,14 @@ static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
1216 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(rssi_thold); 1214 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(rssi_thold);
1217 subsc_evt.bcn_l_rssi_cfg.evt_freq = 1; 1215 subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
1218 subsc_evt.bcn_h_rssi_cfg.evt_freq = 1; 1216 subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
1219 return mwifiex_send_cmd_sync(priv, 1217 return mwifiex_send_cmd(priv,
1220 HostCmd_CMD_802_11_SUBSCRIBE_EVENT, 1218 HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
1221 0, 0, &subsc_evt); 1219 0, 0, &subsc_evt, true);
1222 } else { 1220 } else {
1223 subsc_evt.action = HostCmd_ACT_BITWISE_CLR; 1221 subsc_evt.action = HostCmd_ACT_BITWISE_CLR;
1224 return mwifiex_send_cmd_sync(priv, 1222 return mwifiex_send_cmd(priv,
1225 HostCmd_CMD_802_11_SUBSCRIBE_EVENT, 1223 HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
1226 0, 0, &subsc_evt); 1224 0, 0, &subsc_evt, true);
1227 } 1225 }
1228 1226
1229 return 0; 1227 return 0;
@@ -1276,10 +1274,9 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1276 if (!mac || is_broadcast_ether_addr(mac)) { 1274 if (!mac || is_broadcast_ether_addr(mac)) {
1277 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__); 1275 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__);
1278 list_for_each_entry(sta_node, &priv->sta_list, list) { 1276 list_for_each_entry(sta_node, &priv->sta_list, list) {
1279 if (mwifiex_send_cmd_sync(priv, 1277 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH,
1280 HostCmd_CMD_UAP_STA_DEAUTH, 1278 HostCmd_ACT_GEN_SET, 0,
1281 HostCmd_ACT_GEN_SET, 0, 1279 sta_node->mac_addr, true))
1282 sta_node->mac_addr))
1283 return -1; 1280 return -1;
1284 mwifiex_uap_del_sta_data(priv, sta_node); 1281 mwifiex_uap_del_sta_data(priv, sta_node);
1285 } 1282 }
@@ -1289,10 +1286,9 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1289 sta_node = mwifiex_get_sta_entry(priv, mac); 1286 sta_node = mwifiex_get_sta_entry(priv, mac);
1290 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); 1287 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
1291 if (sta_node) { 1288 if (sta_node) {
1292 if (mwifiex_send_cmd_sync(priv, 1289 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH,
1293 HostCmd_CMD_UAP_STA_DEAUTH, 1290 HostCmd_ACT_GEN_SET, 0,
1294 HostCmd_ACT_GEN_SET, 0, 1291 sta_node->mac_addr, true))
1295 sta_node->mac_addr))
1296 return -1; 1292 return -1;
1297 mwifiex_uap_del_sta_data(priv, sta_node); 1293 mwifiex_uap_del_sta_data(priv, sta_node);
1298 } 1294 }
@@ -1328,13 +1324,40 @@ mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
1328 tx_ant = RF_ANTENNA_AUTO; 1324 tx_ant = RF_ANTENNA_AUTO;
1329 rx_ant = RF_ANTENNA_AUTO; 1325 rx_ant = RF_ANTENNA_AUTO;
1330 } 1326 }
1327 } else {
1328 struct ieee80211_sta_ht_cap *ht_info;
1329 int rx_mcs_supp;
1330 enum ieee80211_band band;
1331
1332 if ((tx_ant == 0x1 && rx_ant == 0x1)) {
1333 adapter->user_dev_mcs_support = HT_STREAM_1X1;
1334 if (adapter->is_hw_11ac_capable)
1335 adapter->usr_dot_11ac_mcs_support =
1336 MWIFIEX_11AC_MCS_MAP_1X1;
1337 } else {
1338 adapter->user_dev_mcs_support = HT_STREAM_2X2;
1339 if (adapter->is_hw_11ac_capable)
1340 adapter->usr_dot_11ac_mcs_support =
1341 MWIFIEX_11AC_MCS_MAP_2X2;
1342 }
1343
1344 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1345 if (!adapter->wiphy->bands[band])
1346 continue;
1347
1348 ht_info = &adapter->wiphy->bands[band]->ht_cap;
1349 rx_mcs_supp =
1350 GET_RXMCSSUPP(adapter->user_dev_mcs_support);
1351 memset(&ht_info->mcs, 0, adapter->number_of_antenna);
1352 memset(&ht_info->mcs, 0xff, rx_mcs_supp);
1353 }
1331 } 1354 }
1332 1355
1333 ant_cfg.tx_ant = tx_ant; 1356 ant_cfg.tx_ant = tx_ant;
1334 ant_cfg.rx_ant = rx_ant; 1357 ant_cfg.rx_ant = rx_ant;
1335 1358
1336 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_ANTENNA, 1359 return mwifiex_send_cmd(priv, HostCmd_CMD_RF_ANTENNA,
1337 HostCmd_ACT_GEN_SET, 0, &ant_cfg); 1360 HostCmd_ACT_GEN_SET, 0, &ant_cfg, true);
1338} 1361}
1339 1362
1340/* cfg80211 operation handler for stop ap. 1363/* cfg80211 operation handler for stop ap.
@@ -1349,8 +1372,8 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1349 1372
1350 priv->ap_11n_enabled = 0; 1373 priv->ap_11n_enabled = 0;
1351 1374
1352 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, 1375 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1353 HostCmd_ACT_GEN_SET, 0, NULL)) { 1376 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
1354 wiphy_err(wiphy, "Failed to stop the BSS\n"); 1377 wiphy_err(wiphy, "Failed to stop the BSS\n");
1355 return -1; 1378 return -1;
1356 } 1379 }
@@ -1461,16 +1484,16 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1461 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout; 1484 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout;
1462 } 1485 }
1463 1486
1464 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, 1487 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1465 HostCmd_ACT_GEN_SET, 0, NULL)) { 1488 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
1466 wiphy_err(wiphy, "Failed to stop the BSS\n"); 1489 wiphy_err(wiphy, "Failed to stop the BSS\n");
1467 kfree(bss_cfg); 1490 kfree(bss_cfg);
1468 return -1; 1491 return -1;
1469 } 1492 }
1470 1493
1471 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, 1494 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
1472 HostCmd_ACT_GEN_SET, 1495 HostCmd_ACT_GEN_SET,
1473 UAP_BSS_PARAMS_I, bss_cfg)) { 1496 UAP_BSS_PARAMS_I, bss_cfg, false)) {
1474 wiphy_err(wiphy, "Failed to set the SSID\n"); 1497 wiphy_err(wiphy, "Failed to set the SSID\n");
1475 kfree(bss_cfg); 1498 kfree(bss_cfg);
1476 return -1; 1499 return -1;
@@ -1478,8 +1501,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1478 1501
1479 kfree(bss_cfg); 1502 kfree(bss_cfg);
1480 1503
1481 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_BSS_START, 1504 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
1482 HostCmd_ACT_GEN_SET, 0, NULL)) { 1505 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
1483 wiphy_err(wiphy, "Failed to start the BSS\n"); 1506 wiphy_err(wiphy, "Failed to start the BSS\n");
1484 return -1; 1507 return -1;
1485 } 1508 }
@@ -1489,9 +1512,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1489 else 1512 else
1490 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; 1513 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
1491 1514
1492 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, 1515 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1493 HostCmd_ACT_GEN_SET, 0, 1516 HostCmd_ACT_GEN_SET, 0,
1494 &priv->curr_pkt_filter)) 1517 &priv->curr_pkt_filter, true))
1495 return -1; 1518 return -1;
1496 1519
1497 return 0; 1520 return 0;
@@ -2097,8 +2120,8 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
2097 ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; 2120 ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
2098 ht_info->cap |= IEEE80211_HT_CAP_SM_PS; 2121 ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
2099 2122
2100 rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); 2123 rx_mcs_supp = GET_RXMCSSUPP(adapter->user_dev_mcs_support);
2101 /* Set MCS for 1x1 */ 2124 /* Set MCS for 1x1/2x2 */
2102 memset(mcs, 0xff, rx_mcs_supp); 2125 memset(mcs, 0xff, rx_mcs_supp);
2103 /* Clear all the other values */ 2126 /* Clear all the other values */
2104 memset(&mcs[rx_mcs_supp], 0, 2127 memset(&mcs[rx_mcs_supp], 0,
@@ -2459,9 +2482,8 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2459 MWIFIEX_CRITERIA_UNICAST | 2482 MWIFIEX_CRITERIA_UNICAST |
2460 MWIFIEX_CRITERIA_MULTICAST; 2483 MWIFIEX_CRITERIA_MULTICAST;
2461 2484
2462 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MEF_CFG, 2485 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
2463 HostCmd_ACT_GEN_SET, 0, 2486 HostCmd_ACT_GEN_SET, 0, &mef_cfg, true);
2464 &mef_cfg);
2465 2487
2466 kfree(mef_entry); 2488 kfree(mef_entry);
2467 return ret; 2489 return ret;
@@ -2573,9 +2595,9 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
2573 if (!coalesce) { 2595 if (!coalesce) {
2574 dev_dbg(adapter->dev, 2596 dev_dbg(adapter->dev,
2575 "Disable coalesce and reset all previous rules\n"); 2597 "Disable coalesce and reset all previous rules\n");
2576 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_COALESCE_CFG, 2598 return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
2577 HostCmd_ACT_GEN_SET, 0, 2599 HostCmd_ACT_GEN_SET, 0,
2578 &coalesce_cfg); 2600 &coalesce_cfg, true);
2579 } 2601 }
2580 2602
2581 coalesce_cfg.num_of_rules = coalesce->n_rules; 2603 coalesce_cfg.num_of_rules = coalesce->n_rules;
@@ -2590,8 +2612,8 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
2590 } 2612 }
2591 } 2613 }
2592 2614
2593 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_COALESCE_CFG, 2615 return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
2594 HostCmd_ACT_GEN_SET, 0, &coalesce_cfg); 2616 HostCmd_ACT_GEN_SET, 0, &coalesce_cfg, true);
2595} 2617}
2596 2618
2597/* cfg80211 ops handler for tdls_mgmt. 2619/* cfg80211 ops handler for tdls_mgmt.
@@ -2600,8 +2622,8 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
2600static int 2622static int
2601mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, 2623mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
2602 u8 *peer, u8 action_code, u8 dialog_token, 2624 u8 *peer, u8 action_code, u8 dialog_token,
2603 u16 status_code, const u8 *extra_ies, 2625 u16 status_code, u32 peer_capability,
2604 size_t extra_ies_len) 2626 const u8 *extra_ies, size_t extra_ies_len)
2605{ 2627{
2606 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 2628 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2607 int ret; 2629 int ret;
@@ -2908,7 +2930,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2908 2930
2909 wiphy->features |= NL80211_FEATURE_HT_IBSS | 2931 wiphy->features |= NL80211_FEATURE_HT_IBSS |
2910 NL80211_FEATURE_INACTIVITY_TIMER | 2932 NL80211_FEATURE_INACTIVITY_TIMER |
2911 NL80211_FEATURE_LOW_PRIORITY_SCAN; 2933 NL80211_FEATURE_LOW_PRIORITY_SCAN |
2934 NL80211_FEATURE_NEED_OBSS_SCAN;
2912 2935
2913 /* Reserve space for mwifiex specific private data for BSS */ 2936 /* Reserve space for mwifiex specific private data for BSS */
2914 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); 2937 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
@@ -2939,17 +2962,17 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2939 country_code); 2962 country_code);
2940 } 2963 }
2941 2964
2942 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2965 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2943 HostCmd_ACT_GEN_GET, FRAG_THRESH_I, &thr); 2966 HostCmd_ACT_GEN_GET, FRAG_THRESH_I, &thr, true);
2944 wiphy->frag_threshold = thr; 2967 wiphy->frag_threshold = thr;
2945 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2968 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2946 HostCmd_ACT_GEN_GET, RTS_THRESH_I, &thr); 2969 HostCmd_ACT_GEN_GET, RTS_THRESH_I, &thr, true);
2947 wiphy->rts_threshold = thr; 2970 wiphy->rts_threshold = thr;
2948 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2971 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2949 HostCmd_ACT_GEN_GET, SHORT_RETRY_LIM_I, &retry); 2972 HostCmd_ACT_GEN_GET, SHORT_RETRY_LIM_I, &retry, true);
2950 wiphy->retry_short = (u8) retry; 2973 wiphy->retry_short = (u8) retry;
2951 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2974 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2952 HostCmd_ACT_GEN_GET, LONG_RETRY_LIM_I, &retry); 2975 HostCmd_ACT_GEN_GET, LONG_RETRY_LIM_I, &retry, true);
2953 wiphy->retry_long = (u8) retry; 2976 wiphy->retry_long = (u8) retry;
2954 2977
2955 adapter->wiphy = wiphy; 2978 adapter->wiphy = wiphy;
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 2c3226bf86f8..0ddec3d4b059 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -253,7 +253,7 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv,
253 u8 index, u8 ht_info) 253 u8 index, u8 ht_info)
254{ 254{
255 u32 mcs_num_supp = 255 u32 mcs_num_supp =
256 (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8; 256 (priv->adapter->user_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8;
257 u32 rate; 257 u32 rate;
258 258
259 if (priv->adapter->is_hw_11ac_capable) 259 if (priv->adapter->is_hw_11ac_capable)
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 21544602043c..14e05c9f4663 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -37,13 +37,12 @@
37static void 37static void
38mwifiex_init_cmd_node(struct mwifiex_private *priv, 38mwifiex_init_cmd_node(struct mwifiex_private *priv,
39 struct cmd_ctrl_node *cmd_node, 39 struct cmd_ctrl_node *cmd_node,
40 u32 cmd_oid, void *data_buf) 40 u32 cmd_oid, void *data_buf, bool sync)
41{ 41{
42 cmd_node->priv = priv; 42 cmd_node->priv = priv;
43 cmd_node->cmd_oid = cmd_oid; 43 cmd_node->cmd_oid = cmd_oid;
44 if (priv->adapter->cmd_wait_q_required) { 44 if (sync) {
45 cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; 45 cmd_node->wait_q_enabled = true;
46 priv->adapter->cmd_wait_q_required = false;
47 cmd_node->cmd_wait_q_woken = false; 46 cmd_node->cmd_wait_q_woken = false;
48 cmd_node->condition = &cmd_node->cmd_wait_q_woken; 47 cmd_node->condition = &cmd_node->cmd_wait_q_woken;
49 } 48 }
@@ -166,8 +165,10 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
166 dev_err(adapter->dev, 165 dev_err(adapter->dev,
167 "DNLD_CMD: FW in reset state, ignore cmd %#x\n", 166 "DNLD_CMD: FW in reset state, ignore cmd %#x\n",
168 cmd_code); 167 cmd_code);
169 mwifiex_complete_cmd(adapter, cmd_node); 168 if (cmd_node->wait_q_enabled)
169 mwifiex_complete_cmd(adapter, cmd_node);
170 mwifiex_recycle_cmd_node(adapter, cmd_node); 170 mwifiex_recycle_cmd_node(adapter, cmd_node);
171 queue_work(adapter->workqueue, &adapter->main_work);
171 return -1; 172 return -1;
172 } 173 }
173 174
@@ -480,28 +481,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
480} 481}
481 482
482/* 483/*
483 * This function is used to send synchronous command to the firmware. 484 * This function prepares a command and send it to the firmware.
484 *
485 * it allocates a wait queue for the command and wait for the command
486 * response.
487 */
488int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
489 u16 cmd_action, u32 cmd_oid, void *data_buf)
490{
491 int ret = 0;
492 struct mwifiex_adapter *adapter = priv->adapter;
493
494 adapter->cmd_wait_q_required = true;
495
496 ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
497 data_buf);
498
499 return ret;
500}
501
502
503/*
504 * This function prepares a command and asynchronously send it to the firmware.
505 * 485 *
506 * Preparation includes - 486 * Preparation includes -
507 * - Sanity tests to make sure the card is still present or the FW 487 * - Sanity tests to make sure the card is still present or the FW
@@ -511,8 +491,8 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
511 * - Fill up the non-default parameters and buffer pointers 491 * - Fill up the non-default parameters and buffer pointers
512 * - Add the command to pending queue 492 * - Add the command to pending queue
513 */ 493 */
514int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, 494int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
515 u16 cmd_action, u32 cmd_oid, void *data_buf) 495 u16 cmd_action, u32 cmd_oid, void *data_buf, bool sync)
516{ 496{
517 int ret; 497 int ret;
518 struct mwifiex_adapter *adapter = priv->adapter; 498 struct mwifiex_adapter *adapter = priv->adapter;
@@ -534,6 +514,11 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
534 return -1; 514 return -1;
535 } 515 }
536 516
517 if (adapter->is_cmd_timedout) {
518 dev_err(adapter->dev, "PREP_CMD: FW is in bad state\n");
519 return -1;
520 }
521
537 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) { 522 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) {
538 if (cmd_no != HostCmd_CMD_FUNC_INIT) { 523 if (cmd_no != HostCmd_CMD_FUNC_INIT) {
539 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n"); 524 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n");
@@ -550,7 +535,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
550 } 535 }
551 536
552 /* Initialize the command node */ 537 /* Initialize the command node */
553 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf); 538 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf, sync);
554 539
555 if (!cmd_node->cmd_skb) { 540 if (!cmd_node->cmd_skb) {
556 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); 541 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
@@ -786,7 +771,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
786 unsigned long flags; 771 unsigned long flags;
787 772
788 /* Now we got response from FW, cancel the command timer */ 773 /* Now we got response from FW, cancel the command timer */
789 del_timer(&adapter->cmd_timer); 774 del_timer_sync(&adapter->cmd_timer);
790 775
791 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { 776 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
792 resp = (struct host_cmd_ds_command *) adapter->upld_buf; 777 resp = (struct host_cmd_ds_command *) adapter->upld_buf;
@@ -795,7 +780,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
795 return -1; 780 return -1;
796 } 781 }
797 782
798 adapter->num_cmd_timeout = 0; 783 adapter->is_cmd_timedout = 0;
799 784
800 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; 785 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
801 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { 786 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
@@ -906,8 +891,7 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
906 struct cmd_ctrl_node *cmd_node; 891 struct cmd_ctrl_node *cmd_node;
907 struct timeval tstamp; 892 struct timeval tstamp;
908 893
909 adapter->num_cmd_timeout++; 894 adapter->is_cmd_timedout = 1;
910 adapter->dbg.num_cmd_timeout++;
911 if (!adapter->curr_cmd) { 895 if (!adapter->curr_cmd) {
912 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n"); 896 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n");
913 return; 897 return;
@@ -930,8 +914,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
930 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", 914 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
931 adapter->dbg.num_cmd_host_to_card_failure); 915 adapter->dbg.num_cmd_host_to_card_failure);
932 916
933 dev_err(adapter->dev, "num_cmd_timeout = %d\n", 917 dev_err(adapter->dev, "is_cmd_timedout = %d\n",
934 adapter->dbg.num_cmd_timeout); 918 adapter->is_cmd_timedout);
935 dev_err(adapter->dev, "num_tx_timeout = %d\n", 919 dev_err(adapter->dev, "num_tx_timeout = %d\n",
936 adapter->dbg.num_tx_timeout); 920 adapter->dbg.num_tx_timeout);
937 921
@@ -988,7 +972,9 @@ void
988mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) 972mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
989{ 973{
990 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node; 974 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
991 unsigned long flags; 975 unsigned long flags, cmd_flags;
976 struct mwifiex_private *priv;
977 int i;
992 978
993 /* Cancel current cmd */ 979 /* Cancel current cmd */
994 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { 980 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
@@ -1028,9 +1014,21 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1028 } 1014 }
1029 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 1015 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1030 1016
1031 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 1017 if (adapter->scan_processing) {
1032 adapter->scan_processing = false; 1018 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1033 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 1019 adapter->scan_processing = false;
1020 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1021 for (i = 0; i < adapter->priv_num; i++) {
1022 priv = adapter->priv[i];
1023 if (!priv)
1024 continue;
1025 if (priv->scan_request) {
1026 dev_dbg(adapter->dev, "info: aborting scan\n");
1027 cfg80211_scan_done(priv->scan_request, 1);
1028 priv->scan_request = NULL;
1029 }
1030 }
1031 }
1034} 1032}
1035 1033
1036/* 1034/*
@@ -1049,7 +1047,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1049 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 1047 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
1050 unsigned long cmd_flags; 1048 unsigned long cmd_flags;
1051 unsigned long scan_pending_q_flags; 1049 unsigned long scan_pending_q_flags;
1052 bool cancel_scan_cmd = false; 1050 struct mwifiex_private *priv;
1051 int i;
1053 1052
1054 if ((adapter->curr_cmd) && 1053 if ((adapter->curr_cmd) &&
1055 (adapter->curr_cmd->wait_q_enabled)) { 1054 (adapter->curr_cmd->wait_q_enabled)) {
@@ -1075,15 +1074,24 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1075 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1074 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1076 spin_lock_irqsave(&adapter->scan_pending_q_lock, 1075 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1077 scan_pending_q_flags); 1076 scan_pending_q_flags);
1078 cancel_scan_cmd = true;
1079 } 1077 }
1080 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1078 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1081 scan_pending_q_flags); 1079 scan_pending_q_flags);
1082 1080
1083 if (cancel_scan_cmd) { 1081 if (adapter->scan_processing) {
1084 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); 1082 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1085 adapter->scan_processing = false; 1083 adapter->scan_processing = false;
1086 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); 1084 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1085 for (i = 0; i < adapter->priv_num; i++) {
1086 priv = adapter->priv[i];
1087 if (!priv)
1088 continue;
1089 if (priv->scan_request) {
1090 dev_dbg(adapter->dev, "info: aborting scan\n");
1091 cfg80211_scan_done(priv->scan_request, 1);
1092 priv->scan_request = NULL;
1093 }
1094 }
1087 } 1095 }
1088 adapter->cmd_wait_q.status = -1; 1096 adapter->cmd_wait_q.status = -1;
1089} 1097}
@@ -1584,6 +1592,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1584 1592
1585 adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); 1593 adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
1586 adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support; 1594 adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
1595 adapter->user_dev_mcs_support = adapter->hw_dev_mcs_support;
1587 1596
1588 if (adapter->if_ops.update_mp_end_port) 1597 if (adapter->if_ops.update_mp_end_port)
1589 adapter->if_ops.update_mp_end_port(adapter, 1598 adapter->if_ops.update_mp_end_port(adapter,
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index a5f9875cfd6e..b8a49aad12fd 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -85,8 +85,8 @@ static struct mwifiex_debug_data items[] = {
85 item_addr(hs_activated), 1}, 85 item_addr(hs_activated), 1},
86 {"num_tx_timeout", item_size(num_tx_timeout), 86 {"num_tx_timeout", item_size(num_tx_timeout),
87 item_addr(num_tx_timeout), 1}, 87 item_addr(num_tx_timeout), 1},
88 {"num_cmd_timeout", item_size(num_cmd_timeout), 88 {"is_cmd_timedout", item_size(is_cmd_timedout),
89 item_addr(num_cmd_timeout), 1}, 89 item_addr(is_cmd_timedout), 1},
90 {"timeout_cmd_id", item_size(timeout_cmd_id), 90 {"timeout_cmd_id", item_size(timeout_cmd_id),
91 item_addr(timeout_cmd_id), 1}, 91 item_addr(timeout_cmd_id), 1},
92 {"timeout_cmd_act", item_size(timeout_cmd_act), 92 {"timeout_cmd_act", item_size(timeout_cmd_act),
@@ -493,7 +493,7 @@ mwifiex_regrdwr_write(struct file *file,
493{ 493{
494 unsigned long addr = get_zeroed_page(GFP_KERNEL); 494 unsigned long addr = get_zeroed_page(GFP_KERNEL);
495 char *buf = (char *) addr; 495 char *buf = (char *) addr;
496 size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1)); 496 size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
497 int ret; 497 int ret;
498 u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX; 498 u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
499 499
@@ -594,7 +594,7 @@ mwifiex_rdeeprom_write(struct file *file,
594{ 594{
595 unsigned long addr = get_zeroed_page(GFP_KERNEL); 595 unsigned long addr = get_zeroed_page(GFP_KERNEL);
596 char *buf = (char *) addr; 596 char *buf = (char *) addr;
597 size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1)); 597 size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
598 int ret = 0; 598 int ret = 0;
599 int offset = -1, bytes = -1; 599 int offset = -1, bytes = -1;
600 600
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index aa8abef58349..39cb3542f79c 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -236,8 +236,21 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
236 */ 236 */
237#define MWIFIEX_FW_DEF_HTTXCFG (BIT(1) | BIT(4) | BIT(5) | BIT(6)) 237#define MWIFIEX_FW_DEF_HTTXCFG (BIT(1) | BIT(4) | BIT(5) | BIT(6))
238 238
239/* 11AC Tx and Rx MCS map for 1x1 mode:
240 * IEEE80211_VHT_MCS_SUPPORT_0_9 for stream 1
241 * IEEE80211_VHT_MCS_NOT_SUPPORTED for remaining 7 streams
242 */
243#define MWIFIEX_11AC_MCS_MAP_1X1 0xfffefffe
244
245/* 11AC Tx and Rx MCS map for 2x2 mode:
246 * IEEE80211_VHT_MCS_SUPPORT_0_9 for stream 1 and 2
247 * IEEE80211_VHT_MCS_NOT_SUPPORTED for remaining 6 streams
248 */
249#define MWIFIEX_11AC_MCS_MAP_2X2 0xfffafffa
250
239#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) 251#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f)
240#define SETHT_MCS32(x) (x[4] |= 1) 252#define SETHT_MCS32(x) (x[4] |= 1)
253#define HT_STREAM_1X1 0x11
241#define HT_STREAM_2X2 0x22 254#define HT_STREAM_2X2 0x22
242 255
243#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4)) 256#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4))
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index 81ac001ee741..3bf3d58bbc02 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -138,9 +138,9 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
138 } 138 }
139 139
140 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) 140 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
141 return mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, 141 return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
142 HostCmd_ACT_GEN_SET, 142 HostCmd_ACT_GEN_SET,
143 UAP_CUSTOM_IE_I, ie_list); 143 UAP_CUSTOM_IE_I, ie_list, false);
144 144
145 return 0; 145 return 0;
146} 146}
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index a4cd2cb066ed..4ecd0b208ac6 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -234,7 +234,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
234 234
235 adapter->pm_wakeup_fw_try = false; 235 adapter->pm_wakeup_fw_try = false;
236 236
237 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
238 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; 237 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
239 238
240 adapter->is_hs_configured = false; 239 adapter->is_hs_configured = false;
@@ -620,7 +619,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
620 /* cancel current command */ 619 /* cancel current command */
621 if (adapter->curr_cmd) { 620 if (adapter->curr_cmd) {
622 dev_warn(adapter->dev, "curr_cmd is still in processing\n"); 621 dev_warn(adapter->dev, "curr_cmd is still in processing\n");
623 del_timer(&adapter->cmd_timer); 622 del_timer_sync(&adapter->cmd_timer);
624 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd); 623 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
625 adapter->curr_cmd = NULL; 624 adapter->curr_cmd = NULL;
626 } 625 }
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 5974642f38b1..1fb2212079ae 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -209,7 +209,7 @@ struct mwifiex_debug_info {
209 u32 num_cmd_assoc_success; 209 u32 num_cmd_assoc_success;
210 u32 num_cmd_assoc_failure; 210 u32 num_cmd_assoc_failure;
211 u32 num_tx_timeout; 211 u32 num_tx_timeout;
212 u32 num_cmd_timeout; 212 u8 is_cmd_timedout;
213 u16 timeout_cmd_id; 213 u16 timeout_cmd_id;
214 u16 timeout_cmd_act; 214 u16 timeout_cmd_act;
215 u16 last_cmd_id[DBG_CMD_NUM]; 215 u16 last_cmd_id[DBG_CMD_NUM];
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 34472ea53841..89dc62a467f4 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -901,9 +901,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
901 mwifiex_get_active_data_rates(priv, adhoc_start->data_rate); 901 mwifiex_get_active_data_rates(priv, adhoc_start->data_rate);
902 if ((adapter->adhoc_start_band & BAND_G) && 902 if ((adapter->adhoc_start_band & BAND_G) &&
903 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { 903 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
904 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 904 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
905 HostCmd_ACT_GEN_SET, 0, 905 HostCmd_ACT_GEN_SET, 0,
906 &priv->curr_pkt_filter)) { 906 &priv->curr_pkt_filter, false)) {
907 dev_err(adapter->dev, 907 dev_err(adapter->dev,
908 "ADHOC_S_CMD: G Protection config failed\n"); 908 "ADHOC_S_CMD: G Protection config failed\n");
909 return -1; 909 return -1;
@@ -1073,9 +1073,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1073 priv-> 1073 priv->
1074 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; 1074 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
1075 1075
1076 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 1076 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1077 HostCmd_ACT_GEN_SET, 0, 1077 HostCmd_ACT_GEN_SET, 0,
1078 &curr_pkt_filter)) { 1078 &curr_pkt_filter, false)) {
1079 dev_err(priv->adapter->dev, 1079 dev_err(priv->adapter->dev,
1080 "ADHOC_J_CMD: G Protection config failed\n"); 1080 "ADHOC_J_CMD: G Protection config failed\n");
1081 return -1; 1081 return -1;
@@ -1312,8 +1312,8 @@ int mwifiex_associate(struct mwifiex_private *priv,
1312 retrieval */ 1312 retrieval */
1313 priv->assoc_rsp_size = 0; 1313 priv->assoc_rsp_size = 0;
1314 1314
1315 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE, 1315 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE,
1316 HostCmd_ACT_GEN_SET, 0, bss_desc); 1316 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1317} 1317}
1318 1318
1319/* 1319/*
@@ -1338,8 +1338,8 @@ mwifiex_adhoc_start(struct mwifiex_private *priv,
1338 else 1338 else
1339 mwifiex_set_ba_params(priv); 1339 mwifiex_set_ba_params(priv);
1340 1340
1341 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, 1341 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START,
1342 HostCmd_ACT_GEN_SET, 0, adhoc_ssid); 1342 HostCmd_ACT_GEN_SET, 0, adhoc_ssid, true);
1343} 1343}
1344 1344
1345/* 1345/*
@@ -1383,8 +1383,8 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
1383 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", 1383 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
1384 priv->curr_bss_params.band); 1384 priv->curr_bss_params.band);
1385 1385
1386 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, 1386 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
1387 HostCmd_ACT_GEN_SET, 0, bss_desc); 1387 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1388} 1388}
1389 1389
1390/* 1390/*
@@ -1403,8 +1403,8 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1403 else 1403 else
1404 memcpy(mac_address, mac, ETH_ALEN); 1404 memcpy(mac_address, mac, ETH_ALEN);
1405 1405
1406 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, 1406 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1407 HostCmd_ACT_GEN_SET, 0, mac_address); 1407 HostCmd_ACT_GEN_SET, 0, mac_address, true);
1408 1408
1409 return ret; 1409 return ret;
1410} 1410}
@@ -1432,19 +1432,31 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1432 GFP_KERNEL); 1432 GFP_KERNEL);
1433 break; 1433 break;
1434 case NL80211_IFTYPE_ADHOC: 1434 case NL80211_IFTYPE_ADHOC:
1435 return mwifiex_send_cmd_sync(priv, 1435 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_STOP,
1436 HostCmd_CMD_802_11_AD_HOC_STOP, 1436 HostCmd_ACT_GEN_SET, 0, NULL, true);
1437 HostCmd_ACT_GEN_SET, 0, NULL);
1438 case NL80211_IFTYPE_AP: 1437 case NL80211_IFTYPE_AP:
1439 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, 1438 return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1440 HostCmd_ACT_GEN_SET, 0, NULL); 1439 HostCmd_ACT_GEN_SET, 0, NULL, true);
1441 default: 1440 default:
1442 break; 1441 break;
1443 } 1442 }
1444 1443
1445 return ret; 1444 return ret;
1446} 1445}
1447EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); 1446
1447/* This function deauthenticates/disconnects from all BSS. */
1448void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter)
1449{
1450 struct mwifiex_private *priv;
1451 int i;
1452
1453 for (i = 0; i < adapter->priv_num; i++) {
1454 priv = adapter->priv[i];
1455 if (priv)
1456 mwifiex_deauthenticate(priv, NULL);
1457 }
1458}
1459EXPORT_SYMBOL_GPL(mwifiex_deauthenticate_all);
1448 1460
1449/* 1461/*
1450 * This function converts band to radio type used in channel TLV. 1462 * This function converts band to radio type used in channel TLV.
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 9d3d2758ec35..7b4502fefec3 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -194,7 +194,7 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
194 if (adapter->if_ops.cleanup_if) 194 if (adapter->if_ops.cleanup_if)
195 adapter->if_ops.cleanup_if(adapter); 195 adapter->if_ops.cleanup_if(adapter);
196 196
197 del_timer(&adapter->cmd_timer); 197 del_timer_sync(&adapter->cmd_timer);
198 198
199 /* Free private structures */ 199 /* Free private structures */
200 for (i = 0; i < adapter->priv_num; i++) { 200 for (i = 0; i < adapter->priv_num; i++) {
@@ -678,8 +678,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr)
678 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); 678 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
679 679
680 /* Send request to firmware */ 680 /* Send request to firmware */
681 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS, 681 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
682 HostCmd_ACT_GEN_SET, 0, NULL); 682 HostCmd_ACT_GEN_SET, 0, NULL, true);
683 683
684 if (!ret) 684 if (!ret)
685 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); 685 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
@@ -871,7 +871,6 @@ mwifiex_add_card(void *card, struct semaphore *sem,
871 adapter->is_suspended = false; 871 adapter->is_suspended = false;
872 adapter->hs_activated = false; 872 adapter->hs_activated = false;
873 init_waitqueue_head(&adapter->hs_activate_wait_q); 873 init_waitqueue_head(&adapter->hs_activate_wait_q);
874 adapter->cmd_wait_q_required = false;
875 init_waitqueue_head(&adapter->cmd_wait_q.wait); 874 init_waitqueue_head(&adapter->cmd_wait_q.wait);
876 adapter->cmd_wait_q.status = 0; 875 adapter->cmd_wait_q.status = 0;
877 adapter->scan_wait_q_woken = false; 876 adapter->scan_wait_q_woken = false;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 407f8eada720..f0289c12e041 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -145,7 +145,6 @@ struct mwifiex_dbg {
145 u32 num_cmd_assoc_success; 145 u32 num_cmd_assoc_success;
146 u32 num_cmd_assoc_failure; 146 u32 num_cmd_assoc_failure;
147 u32 num_tx_timeout; 147 u32 num_tx_timeout;
148 u32 num_cmd_timeout;
149 u16 timeout_cmd_id; 148 u16 timeout_cmd_id;
150 u16 timeout_cmd_act; 149 u16 timeout_cmd_act;
151 u16 last_cmd_id[DBG_CMD_NUM]; 150 u16 last_cmd_id[DBG_CMD_NUM];
@@ -575,6 +574,7 @@ struct mwifiex_rx_reorder_tbl {
575 struct list_head list; 574 struct list_head list;
576 int tid; 575 int tid;
577 u8 ta[ETH_ALEN]; 576 u8 ta[ETH_ALEN];
577 int init_win;
578 int start_win; 578 int start_win;
579 int win_size; 579 int win_size;
580 void **rx_reorder_ptr; 580 void **rx_reorder_ptr;
@@ -719,7 +719,7 @@ struct mwifiex_adapter {
719 struct cmd_ctrl_node *curr_cmd; 719 struct cmd_ctrl_node *curr_cmd;
720 /* spin lock for command */ 720 /* spin lock for command */
721 spinlock_t mwifiex_cmd_lock; 721 spinlock_t mwifiex_cmd_lock;
722 u32 num_cmd_timeout; 722 u8 is_cmd_timedout;
723 u16 last_init_cmd; 723 u16 last_init_cmd;
724 struct timer_list cmd_timer; 724 struct timer_list cmd_timer;
725 struct list_head cmd_free_q; 725 struct list_head cmd_free_q;
@@ -773,12 +773,12 @@ struct mwifiex_adapter {
773 u8 event_body[MAX_EVENT_SIZE]; 773 u8 event_body[MAX_EVENT_SIZE];
774 u32 hw_dot_11n_dev_cap; 774 u32 hw_dot_11n_dev_cap;
775 u8 hw_dev_mcs_support; 775 u8 hw_dev_mcs_support;
776 u8 user_dev_mcs_support;
776 u8 adhoc_11n_enabled; 777 u8 adhoc_11n_enabled;
777 u8 sec_chan_offset; 778 u8 sec_chan_offset;
778 struct mwifiex_dbg dbg; 779 struct mwifiex_dbg dbg;
779 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; 780 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE];
780 u32 arp_filter_size; 781 u32 arp_filter_size;
781 u16 cmd_wait_q_required;
782 struct mwifiex_wait_queue cmd_wait_q; 782 struct mwifiex_wait_queue cmd_wait_q;
783 u8 scan_wait_q_woken; 783 u8 scan_wait_q_woken;
784 spinlock_t queue_lock; /* lock for tx queues */ 784 spinlock_t queue_lock; /* lock for tx queues */
@@ -838,11 +838,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter);
838int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, 838int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
839 struct cmd_ctrl_node *cmd_node); 839 struct cmd_ctrl_node *cmd_node);
840 840
841int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, 841int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
842 u16 cmd_action, u32 cmd_oid, void *data_buf); 842 u16 cmd_action, u32 cmd_oid, void *data_buf, bool sync);
843
844int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
845 u16 cmd_action, u32 cmd_oid, void *data_buf);
846 843
847void mwifiex_cmd_timeout_func(unsigned long function_context); 844void mwifiex_cmd_timeout_func(unsigned long function_context);
848 845
@@ -930,6 +927,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
930void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason); 927void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason);
931u8 mwifiex_band_to_radio_type(u8 band); 928u8 mwifiex_band_to_radio_type(u8 band);
932int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); 929int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
930void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter);
933int mwifiex_adhoc_start(struct mwifiex_private *priv, 931int mwifiex_adhoc_start(struct mwifiex_private *priv,
934 struct cfg80211_ssid *adhoc_ssid); 932 struct cfg80211_ssid *adhoc_ssid);
935int mwifiex_adhoc_join(struct mwifiex_private *priv, 933int mwifiex_adhoc_join(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 31d8a9df1331..9f1683b5f28f 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -190,6 +190,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
190 card->pcie.firmware = data->firmware; 190 card->pcie.firmware = data->firmware;
191 card->pcie.reg = data->reg; 191 card->pcie.reg = data->reg;
192 card->pcie.blksz_fw_dl = data->blksz_fw_dl; 192 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
193 card->pcie.tx_buf_size = data->tx_buf_size;
193 } 194 }
194 195
195 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, 196 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
@@ -210,7 +211,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
210 struct pcie_service_card *card; 211 struct pcie_service_card *card;
211 struct mwifiex_adapter *adapter; 212 struct mwifiex_adapter *adapter;
212 struct mwifiex_private *priv; 213 struct mwifiex_private *priv;
213 int i;
214 214
215 card = pci_get_drvdata(pdev); 215 card = pci_get_drvdata(pdev);
216 if (!card) 216 if (!card)
@@ -229,11 +229,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
229 mwifiex_pcie_resume(&pdev->dev); 229 mwifiex_pcie_resume(&pdev->dev);
230#endif 230#endif
231 231
232 for (i = 0; i < adapter->priv_num; i++) 232 mwifiex_deauthenticate_all(adapter);
233 if ((GET_BSS_ROLE(adapter->priv[i]) ==
234 MWIFIEX_BSS_ROLE_STA) &&
235 adapter->priv[i]->media_connected)
236 mwifiex_deauthenticate(adapter->priv[i], NULL);
237 233
238 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 234 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
239 235
@@ -2320,6 +2316,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2320 } 2316 }
2321 2317
2322 adapter->dev = &pdev->dev; 2318 adapter->dev = &pdev->dev;
2319 adapter->tx_buf_size = card->pcie.tx_buf_size;
2323 strcpy(adapter->fw_name, card->pcie.firmware); 2320 strcpy(adapter->fw_name, card->pcie.firmware);
2324 2321
2325 return 0; 2322 return 0;
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index d322ab8604ea..193af75bf582 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -195,18 +195,21 @@ struct mwifiex_pcie_device {
195 const char *firmware; 195 const char *firmware;
196 const struct mwifiex_pcie_card_reg *reg; 196 const struct mwifiex_pcie_card_reg *reg;
197 u16 blksz_fw_dl; 197 u16 blksz_fw_dl;
198 u16 tx_buf_size;
198}; 199};
199 200
200static const struct mwifiex_pcie_device mwifiex_pcie8766 = { 201static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
201 .firmware = PCIE8766_DEFAULT_FW_NAME, 202 .firmware = PCIE8766_DEFAULT_FW_NAME,
202 .reg = &mwifiex_reg_8766, 203 .reg = &mwifiex_reg_8766,
203 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 204 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
205 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
204}; 206};
205 207
206static const struct mwifiex_pcie_device mwifiex_pcie8897 = { 208static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
207 .firmware = PCIE8897_DEFAULT_FW_NAME, 209 .firmware = PCIE8897_DEFAULT_FW_NAME,
208 .reg = &mwifiex_reg_8897, 210 .reg = &mwifiex_reg_8897,
209 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 211 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
212 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
210}; 213};
211 214
212struct mwifiex_evt_buf_desc { 215struct mwifiex_evt_buf_desc {
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 92adbb1ebabc..0e8ca7bab3e7 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -738,8 +738,8 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
738 else 738 else
739 cmd_no = HostCmd_CMD_802_11_SCAN; 739 cmd_no = HostCmd_CMD_802_11_SCAN;
740 740
741 ret = mwifiex_send_cmd_async(priv, cmd_no, HostCmd_ACT_GEN_SET, 741 ret = mwifiex_send_cmd(priv, cmd_no, HostCmd_ACT_GEN_SET,
742 0, scan_cfg_out); 742 0, scan_cfg_out, false);
743 743
744 /* rate IE is updated per scan command but same starting 744 /* rate IE is updated per scan command but same starting
745 * pointer is used each time so that rate IE from earlier 745 * pointer is used each time so that rate IE from earlier
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index b44a31523461..e0dcd3ed7a69 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -84,6 +84,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
84 card->mp_agg_pkt_limit = data->mp_agg_pkt_limit; 84 card->mp_agg_pkt_limit = data->mp_agg_pkt_limit;
85 card->supports_sdio_new_mode = data->supports_sdio_new_mode; 85 card->supports_sdio_new_mode = data->supports_sdio_new_mode;
86 card->has_control_mask = data->has_control_mask; 86 card->has_control_mask = data->has_control_mask;
87 card->tx_buf_size = data->tx_buf_size;
87 } 88 }
88 89
89 sdio_claim_host(func); 90 sdio_claim_host(func);
@@ -165,7 +166,6 @@ mwifiex_sdio_remove(struct sdio_func *func)
165 struct sdio_mmc_card *card; 166 struct sdio_mmc_card *card;
166 struct mwifiex_adapter *adapter; 167 struct mwifiex_adapter *adapter;
167 struct mwifiex_private *priv; 168 struct mwifiex_private *priv;
168 int i;
169 169
170 pr_debug("info: SDIO func num=%d\n", func->num); 170 pr_debug("info: SDIO func num=%d\n", func->num);
171 171
@@ -184,11 +184,7 @@ mwifiex_sdio_remove(struct sdio_func *func)
184 if (adapter->is_suspended) 184 if (adapter->is_suspended)
185 mwifiex_sdio_resume(adapter->dev); 185 mwifiex_sdio_resume(adapter->dev);
186 186
187 for (i = 0; i < adapter->priv_num; i++) 187 mwifiex_deauthenticate_all(adapter);
188 if ((GET_BSS_ROLE(adapter->priv[i]) ==
189 MWIFIEX_BSS_ROLE_STA) &&
190 adapter->priv[i]->media_connected)
191 mwifiex_deauthenticate(adapter->priv[i], NULL);
192 188
193 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 189 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
194 mwifiex_disable_auto_ds(priv); 190 mwifiex_disable_auto_ds(priv);
@@ -1760,6 +1756,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1760 1756
1761 /* save adapter pointer in card */ 1757 /* save adapter pointer in card */
1762 card->adapter = adapter; 1758 card->adapter = adapter;
1759 adapter->tx_buf_size = card->tx_buf_size;
1763 1760
1764 sdio_claim_host(func); 1761 sdio_claim_host(func);
1765 1762
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 532ae0ac4dfb..c71201b2e2a3 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -233,6 +233,7 @@ struct sdio_mmc_card {
233 u8 mp_agg_pkt_limit; 233 u8 mp_agg_pkt_limit;
234 bool supports_sdio_new_mode; 234 bool supports_sdio_new_mode;
235 bool has_control_mask; 235 bool has_control_mask;
236 u16 tx_buf_size;
236 237
237 u32 mp_rd_bitmap; 238 u32 mp_rd_bitmap;
238 u32 mp_wr_bitmap; 239 u32 mp_wr_bitmap;
@@ -256,6 +257,7 @@ struct mwifiex_sdio_device {
256 u8 mp_agg_pkt_limit; 257 u8 mp_agg_pkt_limit;
257 bool supports_sdio_new_mode; 258 bool supports_sdio_new_mode;
258 bool has_control_mask; 259 bool has_control_mask;
260 u16 tx_buf_size;
259}; 261};
260 262
261static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = { 263static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
@@ -312,6 +314,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
312 .mp_agg_pkt_limit = 8, 314 .mp_agg_pkt_limit = 8,
313 .supports_sdio_new_mode = false, 315 .supports_sdio_new_mode = false,
314 .has_control_mask = true, 316 .has_control_mask = true,
317 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
315}; 318};
316 319
317static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { 320static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -321,6 +324,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
321 .mp_agg_pkt_limit = 8, 324 .mp_agg_pkt_limit = 8,
322 .supports_sdio_new_mode = false, 325 .supports_sdio_new_mode = false,
323 .has_control_mask = true, 326 .has_control_mask = true,
327 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
324}; 328};
325 329
326static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { 330static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -330,6 +334,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
330 .mp_agg_pkt_limit = 8, 334 .mp_agg_pkt_limit = 8,
331 .supports_sdio_new_mode = false, 335 .supports_sdio_new_mode = false,
332 .has_control_mask = true, 336 .has_control_mask = true,
337 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
333}; 338};
334 339
335static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { 340static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -339,6 +344,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
339 .mp_agg_pkt_limit = 16, 344 .mp_agg_pkt_limit = 16,
340 .supports_sdio_new_mode = true, 345 .supports_sdio_new_mode = true,
341 .has_control_mask = false, 346 .has_control_mask = false,
347 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
342}; 348};
343 349
344/* 350/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 5aa3d39e48bc..4315a3ba3b92 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1411,9 +1411,9 @@ int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv,
1411 /* property header is 6 bytes, data must fit in cmd buffer */ 1411 /* property header is 6 bytes, data must fit in cmd buffer */
1412 if (prop && prop->value && prop->length > 6 && 1412 if (prop && prop->value && prop->length > 6 &&
1413 prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) { 1413 prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) {
1414 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, 1414 ret = mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA,
1415 HostCmd_ACT_GEN_SET, 0, 1415 HostCmd_ACT_GEN_SET, 0,
1416 prop); 1416 prop, true);
1417 if (ret) 1417 if (ret)
1418 return ret; 1418 return ret;
1419 } 1419 }
@@ -1912,15 +1912,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1912 1912
1913 if (first_sta) { 1913 if (first_sta) {
1914 if (priv->adapter->iface_type == MWIFIEX_PCIE) { 1914 if (priv->adapter->iface_type == MWIFIEX_PCIE) {
1915 ret = mwifiex_send_cmd_sync(priv, 1915 ret = mwifiex_send_cmd(priv,
1916 HostCmd_CMD_PCIE_DESC_DETAILS, 1916 HostCmd_CMD_PCIE_DESC_DETAILS,
1917 HostCmd_ACT_GEN_SET, 0, NULL); 1917 HostCmd_ACT_GEN_SET, 0, NULL,
1918 true);
1918 if (ret) 1919 if (ret)
1919 return -1; 1920 return -1;
1920 } 1921 }
1921 1922
1922 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_FUNC_INIT, 1923 ret = mwifiex_send_cmd(priv, HostCmd_CMD_FUNC_INIT,
1923 HostCmd_ACT_GEN_SET, 0, NULL); 1924 HostCmd_ACT_GEN_SET, 0, NULL, true);
1924 if (ret) 1925 if (ret)
1925 return -1; 1926 return -1;
1926 1927
@@ -1938,55 +1939,57 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1938 } 1939 }
1939 1940
1940 if (adapter->cal_data) { 1941 if (adapter->cal_data) {
1941 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, 1942 ret = mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA,
1942 HostCmd_ACT_GEN_SET, 0, NULL); 1943 HostCmd_ACT_GEN_SET, 0, NULL,
1944 true);
1943 if (ret) 1945 if (ret)
1944 return -1; 1946 return -1;
1945 } 1947 }
1946 1948
1947 /* Read MAC address from HW */ 1949 /* Read MAC address from HW */
1948 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC, 1950 ret = mwifiex_send_cmd(priv, HostCmd_CMD_GET_HW_SPEC,
1949 HostCmd_ACT_GEN_GET, 0, NULL); 1951 HostCmd_ACT_GEN_GET, 0, NULL, true);
1950 if (ret) 1952 if (ret)
1951 return -1; 1953 return -1;
1952 1954
1953 /* Reconfigure tx buf size */ 1955 /* Reconfigure tx buf size */
1954 ret = mwifiex_send_cmd_sync(priv, 1956 ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
1955 HostCmd_CMD_RECONFIGURE_TX_BUFF, 1957 HostCmd_ACT_GEN_SET, 0,
1956 HostCmd_ACT_GEN_SET, 0, 1958 &priv->adapter->tx_buf_size, true);
1957 &priv->adapter->tx_buf_size);
1958 if (ret) 1959 if (ret)
1959 return -1; 1960 return -1;
1960 1961
1961 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 1962 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1962 /* Enable IEEE PS by default */ 1963 /* Enable IEEE PS by default */
1963 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; 1964 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1964 ret = mwifiex_send_cmd_sync( 1965 ret = mwifiex_send_cmd(priv,
1965 priv, HostCmd_CMD_802_11_PS_MODE_ENH, 1966 HostCmd_CMD_802_11_PS_MODE_ENH,
1966 EN_AUTO_PS, BITMAP_STA_PS, NULL); 1967 EN_AUTO_PS, BITMAP_STA_PS, NULL,
1968 true);
1967 if (ret) 1969 if (ret)
1968 return -1; 1970 return -1;
1969 } 1971 }
1970 } 1972 }
1971 1973
1972 /* get tx rate */ 1974 /* get tx rate */
1973 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, 1975 ret = mwifiex_send_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
1974 HostCmd_ACT_GEN_GET, 0, NULL); 1976 HostCmd_ACT_GEN_GET, 0, NULL, true);
1975 if (ret) 1977 if (ret)
1976 return -1; 1978 return -1;
1977 priv->data_rate = 0; 1979 priv->data_rate = 0;
1978 1980
1979 /* get tx power */ 1981 /* get tx power */
1980 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_TX_PWR, 1982 ret = mwifiex_send_cmd(priv, HostCmd_CMD_RF_TX_PWR,
1981 HostCmd_ACT_GEN_GET, 0, NULL); 1983 HostCmd_ACT_GEN_GET, 0, NULL, true);
1982 if (ret) 1984 if (ret)
1983 return -1; 1985 return -1;
1984 1986
1985 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { 1987 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
1986 /* set ibss coalescing_status */ 1988 /* set ibss coalescing_status */
1987 ret = mwifiex_send_cmd_sync( 1989 ret = mwifiex_send_cmd(
1988 priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 1990 priv,
1989 HostCmd_ACT_GEN_SET, 0, &enable); 1991 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
1992 HostCmd_ACT_GEN_SET, 0, &enable, true);
1990 if (ret) 1993 if (ret)
1991 return -1; 1994 return -1;
1992 } 1995 }
@@ -1994,16 +1997,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1994 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); 1997 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
1995 amsdu_aggr_ctrl.enable = true; 1998 amsdu_aggr_ctrl.enable = true;
1996 /* Send request to firmware */ 1999 /* Send request to firmware */
1997 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, 2000 ret = mwifiex_send_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
1998 HostCmd_ACT_GEN_SET, 0, 2001 HostCmd_ACT_GEN_SET, 0,
1999 &amsdu_aggr_ctrl); 2002 &amsdu_aggr_ctrl, true);
2000 if (ret) 2003 if (ret)
2001 return -1; 2004 return -1;
2002 /* MAC Control must be the last command in init_fw */ 2005 /* MAC Control must be the last command in init_fw */
2003 /* set MAC Control */ 2006 /* set MAC Control */
2004 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, 2007 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
2005 HostCmd_ACT_GEN_SET, 0, 2008 HostCmd_ACT_GEN_SET, 0,
2006 &priv->curr_pkt_filter); 2009 &priv->curr_pkt_filter, true);
2007 if (ret) 2010 if (ret)
2008 return -1; 2011 return -1;
2009 2012
@@ -2012,10 +2015,9 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
2012 /* Enable auto deep sleep */ 2015 /* Enable auto deep sleep */
2013 auto_ds.auto_ds = DEEP_SLEEP_ON; 2016 auto_ds.auto_ds = DEEP_SLEEP_ON;
2014 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; 2017 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
2015 ret = mwifiex_send_cmd_sync(priv, 2018 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
2016 HostCmd_CMD_802_11_PS_MODE_ENH, 2019 EN_AUTO_PS, BITMAP_AUTO_DS,
2017 EN_AUTO_PS, BITMAP_AUTO_DS, 2020 &auto_ds, true);
2018 &auto_ds);
2019 if (ret) 2021 if (ret)
2020 return -1; 2022 return -1;
2021 } 2023 }
@@ -2023,9 +2025,9 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
2023 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 2025 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
2024 /* Send cmd to FW to enable/disable 11D function */ 2026 /* Send cmd to FW to enable/disable 11D function */
2025 state_11d = ENABLE_11D; 2027 state_11d = ENABLE_11D;
2026 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 2028 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2027 HostCmd_ACT_GEN_SET, DOT11D_I, 2029 HostCmd_ACT_GEN_SET, DOT11D_I,
2028 &state_11d); 2030 &state_11d, true);
2029 if (ret) 2031 if (ret)
2030 dev_err(priv->adapter->dev, 2032 dev_err(priv->adapter->dev,
2031 "11D: failed to enable 11D\n"); 2033 "11D: failed to enable 11D\n");
@@ -2038,8 +2040,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
2038 * (Short GI, Channel BW, Green field support etc.) for transmit 2040 * (Short GI, Channel BW, Green field support etc.) for transmit
2039 */ 2041 */
2040 tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG; 2042 tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG;
2041 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_11N_CFG, 2043 ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_CFG,
2042 HostCmd_ACT_GEN_SET, 0, &tx_cfg); 2044 HostCmd_ACT_GEN_SET, 0, &tx_cfg, true);
2043 2045
2044 ret = -EINPROGRESS; 2046 ret = -EINPROGRESS;
2045 2047
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 1c5e18804074..a8f7d545e22a 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -158,8 +158,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
158 158
159 priv->subsc_evt_rssi_state = EVENT_HANDLED; 159 priv->subsc_evt_rssi_state = EVENT_HANDLED;
160 160
161 mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT, 161 mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
162 0, 0, subsc_evt); 162 0, 0, subsc_evt, false);
163 163
164 return 0; 164 return 0;
165} 165}
@@ -317,9 +317,8 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
317 if (priv->is_data_rate_auto) 317 if (priv->is_data_rate_auto)
318 priv->data_rate = 0; 318 priv->data_rate = 0;
319 else 319 else
320 return mwifiex_send_cmd_async(priv, 320 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_TX_RATE_QUERY,
321 HostCmd_CMD_802_11_TX_RATE_QUERY, 321 HostCmd_ACT_GEN_GET, 0, NULL, false);
322 HostCmd_ACT_GEN_GET, 0, NULL);
323 322
324 return 0; 323 return 0;
325} 324}
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 92ff7b324b00..368450cc56c7 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -116,7 +116,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
116 adapter->tx_lock_flag = false; 116 adapter->tx_lock_flag = false;
117 adapter->pps_uapsd_mode = false; 117 adapter->pps_uapsd_mode = false;
118 118
119 if (adapter->num_cmd_timeout && adapter->curr_cmd) 119 if (adapter->is_cmd_timedout && adapter->curr_cmd)
120 return; 120 return;
121 priv->media_connected = false; 121 priv->media_connected = false;
122 dev_dbg(adapter->dev, 122 dev_dbg(adapter->dev,
@@ -293,9 +293,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
293 293
294 case EVENT_HS_ACT_REQ: 294 case EVENT_HS_ACT_REQ:
295 dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); 295 dev_dbg(adapter->dev, "event: HS_ACT_REQ\n");
296 ret = mwifiex_send_cmd_async(priv, 296 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH,
297 HostCmd_CMD_802_11_HS_CFG_ENH, 297 0, 0, NULL, false);
298 0, 0, NULL);
299 break; 298 break;
300 299
301 case EVENT_MIC_ERR_UNICAST: 300 case EVENT_MIC_ERR_UNICAST:
@@ -326,9 +325,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
326 325
327 case EVENT_BG_SCAN_REPORT: 326 case EVENT_BG_SCAN_REPORT:
328 dev_dbg(adapter->dev, "event: BGS_REPORT\n"); 327 dev_dbg(adapter->dev, "event: BGS_REPORT\n");
329 ret = mwifiex_send_cmd_async(priv, 328 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_QUERY,
330 HostCmd_CMD_802_11_BG_SCAN_QUERY, 329 HostCmd_ACT_GEN_GET, 0, NULL, false);
331 HostCmd_ACT_GEN_GET, 0, NULL);
332 break; 330 break;
333 331
334 case EVENT_PORT_RELEASE: 332 case EVENT_PORT_RELEASE:
@@ -345,16 +343,16 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
345 343
346 case EVENT_WMM_STATUS_CHANGE: 344 case EVENT_WMM_STATUS_CHANGE:
347 dev_dbg(adapter->dev, "event: WMM status changed\n"); 345 dev_dbg(adapter->dev, "event: WMM status changed\n");
348 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS, 346 ret = mwifiex_send_cmd(priv, HostCmd_CMD_WMM_GET_STATUS,
349 0, 0, NULL); 347 0, 0, NULL, false);
350 break; 348 break;
351 349
352 case EVENT_RSSI_LOW: 350 case EVENT_RSSI_LOW:
353 cfg80211_cqm_rssi_notify(priv->netdev, 351 cfg80211_cqm_rssi_notify(priv->netdev,
354 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, 352 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
355 GFP_KERNEL); 353 GFP_KERNEL);
356 mwifiex_send_cmd_async(priv, HostCmd_CMD_RSSI_INFO, 354 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
357 HostCmd_ACT_GEN_GET, 0, NULL); 355 HostCmd_ACT_GEN_GET, 0, NULL, false);
358 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD; 356 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD;
359 dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n"); 357 dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n");
360 break; 358 break;
@@ -368,8 +366,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
368 cfg80211_cqm_rssi_notify(priv->netdev, 366 cfg80211_cqm_rssi_notify(priv->netdev,
369 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, 367 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
370 GFP_KERNEL); 368 GFP_KERNEL);
371 mwifiex_send_cmd_async(priv, HostCmd_CMD_RSSI_INFO, 369 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
372 HostCmd_ACT_GEN_GET, 0, NULL); 370 HostCmd_ACT_GEN_GET, 0, NULL, false);
373 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD; 371 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD;
374 dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n"); 372 dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n");
375 break; 373 break;
@@ -396,15 +394,15 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
396 break; 394 break;
397 case EVENT_IBSS_COALESCED: 395 case EVENT_IBSS_COALESCED:
398 dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); 396 dev_dbg(adapter->dev, "event: IBSS_COALESCED\n");
399 ret = mwifiex_send_cmd_async(priv, 397 ret = mwifiex_send_cmd(priv,
400 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 398 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
401 HostCmd_ACT_GEN_GET, 0, NULL); 399 HostCmd_ACT_GEN_GET, 0, NULL, false);
402 break; 400 break;
403 case EVENT_ADDBA: 401 case EVENT_ADDBA:
404 dev_dbg(adapter->dev, "event: ADDBA Request\n"); 402 dev_dbg(adapter->dev, "event: ADDBA Request\n");
405 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP, 403 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
406 HostCmd_ACT_GEN_SET, 0, 404 HostCmd_ACT_GEN_SET, 0,
407 adapter->event_body); 405 adapter->event_body, false);
408 break; 406 break;
409 case EVENT_DELBA: 407 case EVENT_DELBA:
410 dev_dbg(adapter->dev, "event: DELBA Request\n"); 408 dev_dbg(adapter->dev, "event: DELBA Request\n");
@@ -455,10 +453,10 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
455 priv->csa_expire_time = 453 priv->csa_expire_time =
456 jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME); 454 jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME);
457 priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel; 455 priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel;
458 ret = mwifiex_send_cmd_async(priv, 456 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
459 HostCmd_CMD_802_11_DEAUTHENTICATE,
460 HostCmd_ACT_GEN_SET, 0, 457 HostCmd_ACT_GEN_SET, 0,
461 priv->curr_bss_params.bss_descriptor.mac_address); 458 priv->curr_bss_params.bss_descriptor.mac_address,
459 false);
462 break; 460 break;
463 461
464 default: 462 default:
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index b393d55b3aa0..33170af150f6 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -108,19 +108,19 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
108 "info: Set multicast list=%d\n", 108 "info: Set multicast list=%d\n",
109 mcast_list->num_multicast_addr); 109 mcast_list->num_multicast_addr);
110 /* Send multicast addresses to firmware */ 110 /* Send multicast addresses to firmware */
111 ret = mwifiex_send_cmd_async(priv, 111 ret = mwifiex_send_cmd(priv,
112 HostCmd_CMD_MAC_MULTICAST_ADR, 112 HostCmd_CMD_MAC_MULTICAST_ADR,
113 HostCmd_ACT_GEN_SET, 0, 113 HostCmd_ACT_GEN_SET, 0,
114 mcast_list); 114 mcast_list, false);
115 } 115 }
116 } 116 }
117 dev_dbg(priv->adapter->dev, 117 dev_dbg(priv->adapter->dev,
118 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", 118 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n",
119 old_pkt_filter, priv->curr_pkt_filter); 119 old_pkt_filter, priv->curr_pkt_filter);
120 if (old_pkt_filter != priv->curr_pkt_filter) { 120 if (old_pkt_filter != priv->curr_pkt_filter) {
121 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 121 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
122 HostCmd_ACT_GEN_SET, 122 HostCmd_ACT_GEN_SET,
123 0, &priv->curr_pkt_filter); 123 0, &priv->curr_pkt_filter, false);
124 } 124 }
125 125
126 return ret; 126 return ret;
@@ -237,8 +237,8 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
237 237
238 rcu_read_unlock(); 238 rcu_read_unlock();
239 239
240 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 240 if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
241 HostCmd_ACT_GEN_SET, 0, NULL)) { 241 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
242 wiphy_err(priv->adapter->wiphy, 242 wiphy_err(priv->adapter->wiphy,
243 "11D: setting domain info in FW\n"); 243 "11D: setting domain info in FW\n");
244 return -1; 244 return -1;
@@ -429,16 +429,13 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
429 status = -1; 429 status = -1;
430 break; 430 break;
431 } 431 }
432 if (cmd_type == MWIFIEX_SYNC_CMD) 432
433 status = mwifiex_send_cmd_sync(priv, 433 status = mwifiex_send_cmd(priv,
434 HostCmd_CMD_802_11_HS_CFG_ENH, 434 HostCmd_CMD_802_11_HS_CFG_ENH,
435 HostCmd_ACT_GEN_SET, 0, 435 HostCmd_ACT_GEN_SET, 0,
436 &adapter->hs_cfg); 436 &adapter->hs_cfg,
437 else 437 cmd_type == MWIFIEX_SYNC_CMD);
438 status = mwifiex_send_cmd_async(priv, 438
439 HostCmd_CMD_802_11_HS_CFG_ENH,
440 HostCmd_ACT_GEN_SET, 0,
441 &adapter->hs_cfg);
442 if (hs_cfg->conditions == HS_CFG_CANCEL) 439 if (hs_cfg->conditions == HS_CFG_CANCEL)
443 /* Restore previous condition */ 440 /* Restore previous condition */
444 adapter->hs_cfg.conditions = 441 adapter->hs_cfg.conditions =
@@ -586,8 +583,8 @@ int mwifiex_disable_auto_ds(struct mwifiex_private *priv)
586 583
587 auto_ds.auto_ds = DEEP_SLEEP_OFF; 584 auto_ds.auto_ds = DEEP_SLEEP_OFF;
588 585
589 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 586 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
590 DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds); 587 DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds, true);
591} 588}
592EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds); 589EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds);
593 590
@@ -601,8 +598,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, u32 *rate)
601{ 598{
602 int ret; 599 int ret;
603 600
604 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, 601 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_TX_RATE_QUERY,
605 HostCmd_ACT_GEN_GET, 0, NULL); 602 HostCmd_ACT_GEN_GET, 0, NULL, true);
606 603
607 if (!ret) { 604 if (!ret) {
608 if (priv->is_data_rate_auto) 605 if (priv->is_data_rate_auto)
@@ -698,8 +695,8 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
698 pg->power_max = (s8) dbm; 695 pg->power_max = (s8) dbm;
699 pg->ht_bandwidth = HT_BW_40; 696 pg->ht_bandwidth = HT_BW_40;
700 } 697 }
701 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, 698 ret = mwifiex_send_cmd(priv, HostCmd_CMD_TXPWR_CFG,
702 HostCmd_ACT_GEN_SET, 0, buf); 699 HostCmd_ACT_GEN_SET, 0, buf, true);
703 700
704 kfree(buf); 701 kfree(buf);
705 return ret; 702 return ret;
@@ -722,12 +719,11 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
722 else 719 else
723 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; 720 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
724 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; 721 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS;
725 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 722 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
726 sub_cmd, BITMAP_STA_PS, NULL); 723 sub_cmd, BITMAP_STA_PS, NULL, true);
727 if ((!ret) && (sub_cmd == DIS_AUTO_PS)) 724 if ((!ret) && (sub_cmd == DIS_AUTO_PS))
728 ret = mwifiex_send_cmd_async(priv, 725 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
729 HostCmd_CMD_802_11_PS_MODE_ENH, 726 GET_PS, 0, NULL, false);
730 GET_PS, 0, NULL);
731 727
732 return ret; 728 return ret;
733} 729}
@@ -851,9 +847,9 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
851 struct mwifiex_ds_encrypt_key *encrypt_key) 847 struct mwifiex_ds_encrypt_key *encrypt_key)
852{ 848{
853 849
854 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 850 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
855 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, 851 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
856 encrypt_key); 852 encrypt_key, true);
857} 853}
858 854
859/* 855/*
@@ -917,9 +913,8 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
917 enc_key = NULL; 913 enc_key = NULL;
918 914
919 /* Send request to firmware */ 915 /* Send request to firmware */
920 ret = mwifiex_send_cmd_async(priv, 916 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
921 HostCmd_CMD_802_11_KEY_MATERIAL, 917 HostCmd_ACT_GEN_SET, 0, enc_key, false);
922 HostCmd_ACT_GEN_SET, 0, enc_key);
923 if (ret) 918 if (ret)
924 return ret; 919 return ret;
925 } 920 }
@@ -929,9 +924,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
929 else 924 else
930 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; 925 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
931 926
932 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, 927 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
933 HostCmd_ACT_GEN_SET, 0, 928 HostCmd_ACT_GEN_SET, 0,
934 &priv->curr_pkt_filter); 929 &priv->curr_pkt_filter, true);
935 930
936 return ret; 931 return ret;
937} 932}
@@ -966,10 +961,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
966 */ 961 */
967 /* Send the key as PTK to firmware */ 962 /* Send the key as PTK to firmware */
968 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 963 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
969 ret = mwifiex_send_cmd_async(priv, 964 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
970 HostCmd_CMD_802_11_KEY_MATERIAL, 965 HostCmd_ACT_GEN_SET,
971 HostCmd_ACT_GEN_SET, 966 KEY_INFO_ENABLED, encrypt_key, false);
972 KEY_INFO_ENABLED, encrypt_key);
973 if (ret) 967 if (ret)
974 return ret; 968 return ret;
975 969
@@ -993,15 +987,13 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
993 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 987 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
994 988
995 if (remove_key) 989 if (remove_key)
996 ret = mwifiex_send_cmd_sync(priv, 990 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
997 HostCmd_CMD_802_11_KEY_MATERIAL, 991 HostCmd_ACT_GEN_SET,
998 HostCmd_ACT_GEN_SET, 992 !KEY_INFO_ENABLED, encrypt_key, true);
999 !KEY_INFO_ENABLED, encrypt_key);
1000 else 993 else
1001 ret = mwifiex_send_cmd_sync(priv, 994 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
1002 HostCmd_CMD_802_11_KEY_MATERIAL, 995 HostCmd_ACT_GEN_SET,
1003 HostCmd_ACT_GEN_SET, 996 KEY_INFO_ENABLED, encrypt_key, true);
1004 KEY_INFO_ENABLED, encrypt_key);
1005 997
1006 return ret; 998 return ret;
1007} 999}
@@ -1105,8 +1097,8 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
1105 struct mwifiex_ver_ext ver_ext; 1097 struct mwifiex_ver_ext ver_ext;
1106 1098
1107 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); 1099 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
1108 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, 1100 if (mwifiex_send_cmd(priv, HostCmd_CMD_VERSION_EXT,
1109 HostCmd_ACT_GEN_GET, 0, &ver_ext)) 1101 HostCmd_ACT_GEN_GET, 0, &ver_ext, true))
1110 return -1; 1102 return -1;
1111 1103
1112 return 0; 1104 return 0;
@@ -1131,8 +1123,8 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1131 ieee80211_frequency_to_channel(chan->center_freq); 1123 ieee80211_frequency_to_channel(chan->center_freq);
1132 roc_cfg.duration = cpu_to_le32(duration); 1124 roc_cfg.duration = cpu_to_le32(duration);
1133 } 1125 }
1134 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_REMAIN_ON_CHAN, 1126 if (mwifiex_send_cmd(priv, HostCmd_CMD_REMAIN_ON_CHAN,
1135 action, 0, &roc_cfg)) { 1127 action, 0, &roc_cfg, true)) {
1136 dev_err(priv->adapter->dev, "failed to remain on channel\n"); 1128 dev_err(priv->adapter->dev, "failed to remain on channel\n");
1137 return -1; 1129 return -1;
1138 } 1130 }
@@ -1164,8 +1156,8 @@ mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role)
1164 break; 1156 break;
1165 } 1157 }
1166 1158
1167 mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, 1159 mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
1168 HostCmd_ACT_GEN_SET, 0, NULL); 1160 HostCmd_ACT_GEN_SET, 0, NULL, true);
1169 1161
1170 return mwifiex_sta_init_cmd(priv, false); 1162 return mwifiex_sta_init_cmd(priv, false);
1171} 1163}
@@ -1180,8 +1172,8 @@ int
1180mwifiex_get_stats_info(struct mwifiex_private *priv, 1172mwifiex_get_stats_info(struct mwifiex_private *priv,
1181 struct mwifiex_ds_get_stats *log) 1173 struct mwifiex_ds_get_stats *log)
1182{ 1174{
1183 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, 1175 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_GET_LOG,
1184 HostCmd_ACT_GEN_GET, 0, log); 1176 HostCmd_ACT_GEN_GET, 0, log, true);
1185} 1177}
1186 1178
1187/* 1179/*
@@ -1223,8 +1215,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv,
1223 return -1; 1215 return -1;
1224 } 1216 }
1225 1217
1226 return mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); 1218 return mwifiex_send_cmd(priv, cmd_no, action, 0, reg_rw, true);
1227
1228} 1219}
1229 1220
1230/* 1221/*
@@ -1289,8 +1280,8 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
1289 rd_eeprom.byte_count = cpu_to_le16((u16) bytes); 1280 rd_eeprom.byte_count = cpu_to_le16((u16) bytes);
1290 1281
1291 /* Send request to firmware */ 1282 /* Send request to firmware */
1292 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, 1283 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS,
1293 HostCmd_ACT_GEN_GET, 0, &rd_eeprom); 1284 HostCmd_ACT_GEN_GET, 0, &rd_eeprom, true);
1294 1285
1295 if (!ret) 1286 if (!ret)
1296 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); 1287 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA);
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index 5efd456af571..8cec6e4ba8c4 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -180,7 +180,7 @@ static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv,
180 memset(&vht_cap, 0, sizeof(struct ieee80211_vht_cap)); 180 memset(&vht_cap, 0, sizeof(struct ieee80211_vht_cap));
181 181
182 mwifiex_fill_vht_cap_tlv(priv, &vht_cap, priv->curr_bss_params.band); 182 mwifiex_fill_vht_cap_tlv(priv, &vht_cap, priv->curr_bss_params.band);
183 memcpy(pos, &vht_cap, sizeof(struct ieee80211_ht_cap)); 183 memcpy(pos, &vht_cap, sizeof(vht_cap));
184 184
185 return 0; 185 return 0;
186} 186}
@@ -864,8 +864,8 @@ mwifiex_tdls_process_config_link(struct mwifiex_private *priv, u8 *peer)
864 864
865 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 865 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
866 tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK; 866 tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK;
867 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TDLS_OPER, 867 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
868 HostCmd_ACT_GEN_SET, 0, &tdls_oper); 868 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
869} 869}
870 870
871static int 871static int
@@ -891,8 +891,8 @@ mwifiex_tdls_process_create_link(struct mwifiex_private *priv, u8 *peer)
891 mwifiex_hold_tdls_packets(priv, peer); 891 mwifiex_hold_tdls_packets(priv, peer);
892 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 892 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
893 tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK; 893 tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK;
894 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TDLS_OPER, 894 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
895 HostCmd_ACT_GEN_SET, 0, &tdls_oper); 895 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
896} 896}
897 897
898static int 898static int
@@ -920,8 +920,8 @@ mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, u8 *peer)
920 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); 920 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
921 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 921 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
922 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; 922 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
923 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TDLS_OPER, 923 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
924 HostCmd_ACT_GEN_SET, 0, &tdls_oper); 924 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
925} 925}
926 926
927static int 927static int
@@ -1033,8 +1033,8 @@ void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv)
1033 TDLS_LINK_TEARDOWN); 1033 TDLS_LINK_TEARDOWN);
1034 memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN); 1034 memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN);
1035 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; 1035 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
1036 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_TDLS_OPER, 1036 if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1037 HostCmd_ACT_GEN_SET, 0, &tdls_oper)) 1037 HostCmd_ACT_GEN_SET, 0, &tdls_oper, false))
1038 dev_warn(priv->adapter->dev, 1038 dev_warn(priv->adapter->dev,
1039 "Disable link failed for TDLS peer %pM", 1039 "Disable link failed for TDLS peer %pM",
1040 sta_ptr->mac_addr); 1040 sta_ptr->mac_addr);
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 64424c81b44f..a6a6a53cda40 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -226,8 +226,8 @@ void mwifiex_set_vht_width(struct mwifiex_private *priv,
226 if (ap_11ac_enable && width >= NL80211_CHAN_WIDTH_80) 226 if (ap_11ac_enable && width >= NL80211_CHAN_WIDTH_80)
227 vht_cfg.misc_config |= VHT_BW_80_160_80P80; 227 vht_cfg.misc_config |= VHT_BW_80_160_80P80;
228 228
229 mwifiex_send_cmd_sync(priv, HostCmd_CMD_11AC_CFG, 229 mwifiex_send_cmd(priv, HostCmd_CMD_11AC_CFG,
230 HostCmd_ACT_GEN_SET, 0, &vht_cfg); 230 HostCmd_ACT_GEN_SET, 0, &vht_cfg, true);
231 231
232 return; 232 return;
233} 233}
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 2d47ba70225c..ae50e916d8f2 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -150,9 +150,9 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
150 case EVENT_ADDBA: 150 case EVENT_ADDBA:
151 dev_dbg(adapter->dev, "event: ADDBA Request\n"); 151 dev_dbg(adapter->dev, "event: ADDBA Request\n");
152 if (priv->media_connected) 152 if (priv->media_connected)
153 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP, 153 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
154 HostCmd_ACT_GEN_SET, 0, 154 HostCmd_ACT_GEN_SET, 0,
155 adapter->event_body); 155 adapter->event_body, false);
156 break; 156 break;
157 case EVENT_DELBA: 157 case EVENT_DELBA:
158 dev_dbg(adapter->dev, "event: DELBA Request\n"); 158 dev_dbg(adapter->dev, "event: DELBA Request\n");
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 208748804a55..ae30c390ebd3 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -766,11 +766,13 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
766 switch (le16_to_cpu(card->udev->descriptor.idProduct)) { 766 switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
767 case USB8897_PID_1: 767 case USB8897_PID_1:
768 case USB8897_PID_2: 768 case USB8897_PID_2:
769 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
769 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME); 770 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME);
770 break; 771 break;
771 case USB8797_PID_1: 772 case USB8797_PID_1:
772 case USB8797_PID_2: 773 case USB8797_PID_2:
773 default: 774 default:
775 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
774 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME); 776 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
775 break; 777 break;
776 } 778 }
@@ -1024,7 +1026,6 @@ static void mwifiex_usb_cleanup_module(void)
1024 1026
1025 if (usb_card && usb_card->adapter) { 1027 if (usb_card && usb_card->adapter) {
1026 struct mwifiex_adapter *adapter = usb_card->adapter; 1028 struct mwifiex_adapter *adapter = usb_card->adapter;
1027 int i;
1028 1029
1029 /* In case driver is removed when asynchronous FW downloading is 1030 /* In case driver is removed when asynchronous FW downloading is
1030 * in progress 1031 * in progress
@@ -1035,11 +1036,8 @@ static void mwifiex_usb_cleanup_module(void)
1035 if (adapter->is_suspended) 1036 if (adapter->is_suspended)
1036 mwifiex_usb_resume(usb_card->intf); 1037 mwifiex_usb_resume(usb_card->intf);
1037#endif 1038#endif
1038 for (i = 0; i < adapter->priv_num; i++) 1039
1039 if ((GET_BSS_ROLE(adapter->priv[i]) == 1040 mwifiex_deauthenticate_all(adapter);
1040 MWIFIEX_BSS_ROLE_STA) &&
1041 adapter->priv[i]->media_connected)
1042 mwifiex_deauthenticate(adapter->priv[i], NULL);
1043 1041
1044 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, 1042 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
1045 MWIFIEX_BSS_ROLE_ANY), 1043 MWIFIEX_BSS_ROLE_ANY),
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 8d37bfc578bd..c3824e37f3f2 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -72,7 +72,7 @@ int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
72 return -1; 72 return -1;
73 } 73 }
74 74
75 return mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); 75 return mwifiex_send_cmd(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL, true);
76} 76}
77EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw); 77EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw);
78 78
@@ -104,6 +104,7 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
104 info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try; 104 info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try;
105 info->is_hs_configured = adapter->is_hs_configured; 105 info->is_hs_configured = adapter->is_hs_configured;
106 info->hs_activated = adapter->hs_activated; 106 info->hs_activated = adapter->hs_activated;
107 info->is_cmd_timedout = adapter->is_cmd_timedout;
107 info->num_cmd_host_to_card_failure 108 info->num_cmd_host_to_card_failure
108 = adapter->dbg.num_cmd_host_to_card_failure; 109 = adapter->dbg.num_cmd_host_to_card_failure;
109 info->num_cmd_sleep_cfm_host_to_card_failure 110 info->num_cmd_sleep_cfm_host_to_card_failure
@@ -119,7 +120,6 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
119 info->num_cmd_assoc_failure = 120 info->num_cmd_assoc_failure =
120 adapter->dbg.num_cmd_assoc_failure; 121 adapter->dbg.num_cmd_assoc_failure;
121 info->num_tx_timeout = adapter->dbg.num_tx_timeout; 122 info->num_tx_timeout = adapter->dbg.num_tx_timeout;
122 info->num_cmd_timeout = adapter->dbg.num_cmd_timeout;
123 info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; 123 info->timeout_cmd_id = adapter->dbg.timeout_cmd_id;
124 info->timeout_cmd_act = adapter->dbg.timeout_cmd_act; 124 info->timeout_cmd_act = adapter->dbg.timeout_cmd_act;
125 memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id, 125 memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id,
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 4987c3f942ce..3c0a0a86ba12 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -81,6 +81,9 @@ MODULE_PARM_DESC(ap_mode_default,
81 */ 81 */
82 82
83#define MWL8K_HW_TIMER_REGISTER 0x0000a600 83#define MWL8K_HW_TIMER_REGISTER 0x0000a600
84#define BBU_RXRDY_CNT_REG 0x0000a860
85#define NOK_CCA_CNT_REG 0x0000a6a0
86#define BBU_AVG_NOISE_VAL 0x67
84 87
85#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \ 88#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \
86 MWL8K_A2H_INT_CHNL_SWITCHED | \ 89 MWL8K_A2H_INT_CHNL_SWITCHED | \
@@ -112,6 +115,8 @@ MODULE_PARM_DESC(ap_mode_default,
112 */ 115 */
113#define MWL8K_NUM_AMPDU_STREAMS (TOTAL_HW_TX_QUEUES - 1) 116#define MWL8K_NUM_AMPDU_STREAMS (TOTAL_HW_TX_QUEUES - 1)
114 117
118#define MWL8K_NUM_CHANS 18
119
115struct rxd_ops { 120struct rxd_ops {
116 int rxd_size; 121 int rxd_size;
117 void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr); 122 void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
@@ -289,6 +294,12 @@ struct mwl8k_priv {
289 294
290 /* bitmap of running BSSes */ 295 /* bitmap of running BSSes */
291 u32 running_bsses; 296 u32 running_bsses;
297
298 /* ACS related */
299 bool sw_scan_start;
300 struct ieee80211_channel *acs_chan;
301 unsigned long channel_time;
302 struct survey_info survey[MWL8K_NUM_CHANS];
292}; 303};
293 304
294#define MAX_WEP_KEY_LEN 13 305#define MAX_WEP_KEY_LEN 13
@@ -396,6 +407,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
396#define MWL8K_CMD_SET_HW_SPEC 0x0004 407#define MWL8K_CMD_SET_HW_SPEC 0x0004
397#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010 408#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010
398#define MWL8K_CMD_GET_STAT 0x0014 409#define MWL8K_CMD_GET_STAT 0x0014
410#define MWL8K_CMD_BBP_REG_ACCESS 0x001a
399#define MWL8K_CMD_RADIO_CONTROL 0x001c 411#define MWL8K_CMD_RADIO_CONTROL 0x001c
400#define MWL8K_CMD_RF_TX_POWER 0x001e 412#define MWL8K_CMD_RF_TX_POWER 0x001e
401#define MWL8K_CMD_TX_POWER 0x001f 413#define MWL8K_CMD_TX_POWER 0x001f
@@ -2987,6 +2999,47 @@ static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
2987} 2999}
2988 3000
2989/* 3001/*
3002 * CMD_BBP_REG_ACCESS.
3003 */
3004struct mwl8k_cmd_bbp_reg_access {
3005 struct mwl8k_cmd_pkt header;
3006 __le16 action;
3007 __le16 offset;
3008 u8 value;
3009 u8 rsrv[3];
3010} __packed;
3011
3012static int
3013mwl8k_cmd_bbp_reg_access(struct ieee80211_hw *hw,
3014 u16 action,
3015 u16 offset,
3016 u8 *value)
3017{
3018 struct mwl8k_cmd_bbp_reg_access *cmd;
3019 int rc;
3020
3021 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3022 if (cmd == NULL)
3023 return -ENOMEM;
3024
3025 cmd->header.code = cpu_to_le16(MWL8K_CMD_BBP_REG_ACCESS);
3026 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3027 cmd->action = cpu_to_le16(action);
3028 cmd->offset = cpu_to_le16(offset);
3029
3030 rc = mwl8k_post_cmd(hw, &cmd->header);
3031
3032 if (!rc)
3033 *value = cmd->value;
3034 else
3035 *value = 0;
3036
3037 kfree(cmd);
3038
3039 return rc;
3040}
3041
3042/*
2990 * CMD_SET_POST_SCAN. 3043 * CMD_SET_POST_SCAN.
2991 */ 3044 */
2992struct mwl8k_cmd_set_post_scan { 3045struct mwl8k_cmd_set_post_scan {
@@ -3016,6 +3069,64 @@ mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac)
3016 return rc; 3069 return rc;
3017} 3070}
3018 3071
3072static int freq_to_idx(struct mwl8k_priv *priv, int freq)
3073{
3074 struct ieee80211_supported_band *sband;
3075 int band, ch, idx = 0;
3076
3077 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
3078 sband = priv->hw->wiphy->bands[band];
3079 if (!sband)
3080 continue;
3081
3082 for (ch = 0; ch < sband->n_channels; ch++, idx++)
3083 if (sband->channels[ch].center_freq == freq)
3084 goto exit;
3085 }
3086
3087exit:
3088 return idx;
3089}
3090
3091static void mwl8k_update_survey(struct mwl8k_priv *priv,
3092 struct ieee80211_channel *channel)
3093{
3094 u32 cca_cnt, rx_rdy;
3095 s8 nf = 0, idx;
3096 struct survey_info *survey;
3097
3098 idx = freq_to_idx(priv, priv->acs_chan->center_freq);
3099 if (idx >= MWL8K_NUM_CHANS) {
3100 wiphy_err(priv->hw->wiphy, "Failed to update survey\n");
3101 return;
3102 }
3103
3104 survey = &priv->survey[idx];
3105
3106 cca_cnt = ioread32(priv->regs + NOK_CCA_CNT_REG);
3107 cca_cnt /= 1000; /* uSecs to mSecs */
3108 survey->channel_time_busy = (u64) cca_cnt;
3109
3110 rx_rdy = ioread32(priv->regs + BBU_RXRDY_CNT_REG);
3111 rx_rdy /= 1000; /* uSecs to mSecs */
3112 survey->channel_time_rx = (u64) rx_rdy;
3113
3114 priv->channel_time = jiffies - priv->channel_time;
3115 survey->channel_time = jiffies_to_msecs(priv->channel_time);
3116
3117 survey->channel = channel;
3118
3119 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &nf);
3120
3121 /* Make sure sign is negative else ACS at hostapd fails */
3122 survey->noise = nf * -1;
3123
3124 survey->filled = SURVEY_INFO_NOISE_DBM |
3125 SURVEY_INFO_CHANNEL_TIME |
3126 SURVEY_INFO_CHANNEL_TIME_BUSY |
3127 SURVEY_INFO_CHANNEL_TIME_RX;
3128}
3129
3019/* 3130/*
3020 * CMD_SET_RF_CHANNEL. 3131 * CMD_SET_RF_CHANNEL.
3021 */ 3132 */
@@ -3033,6 +3144,7 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
3033 enum nl80211_channel_type channel_type = 3144 enum nl80211_channel_type channel_type =
3034 cfg80211_get_chandef_type(&conf->chandef); 3145 cfg80211_get_chandef_type(&conf->chandef);
3035 struct mwl8k_cmd_set_rf_channel *cmd; 3146 struct mwl8k_cmd_set_rf_channel *cmd;
3147 struct mwl8k_priv *priv = hw->priv;
3036 int rc; 3148 int rc;
3037 3149
3038 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 3150 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -3049,13 +3161,29 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
3049 else if (channel->band == IEEE80211_BAND_5GHZ) 3161 else if (channel->band == IEEE80211_BAND_5GHZ)
3050 cmd->channel_flags |= cpu_to_le32(0x00000004); 3162 cmd->channel_flags |= cpu_to_le32(0x00000004);
3051 3163
3052 if (channel_type == NL80211_CHAN_NO_HT || 3164 if (!priv->sw_scan_start) {
3053 channel_type == NL80211_CHAN_HT20) 3165 if (channel_type == NL80211_CHAN_NO_HT ||
3166 channel_type == NL80211_CHAN_HT20)
3167 cmd->channel_flags |= cpu_to_le32(0x00000080);
3168 else if (channel_type == NL80211_CHAN_HT40MINUS)
3169 cmd->channel_flags |= cpu_to_le32(0x000001900);
3170 else if (channel_type == NL80211_CHAN_HT40PLUS)
3171 cmd->channel_flags |= cpu_to_le32(0x000000900);
3172 } else {
3054 cmd->channel_flags |= cpu_to_le32(0x00000080); 3173 cmd->channel_flags |= cpu_to_le32(0x00000080);
3055 else if (channel_type == NL80211_CHAN_HT40MINUS) 3174 }
3056 cmd->channel_flags |= cpu_to_le32(0x000001900); 3175
3057 else if (channel_type == NL80211_CHAN_HT40PLUS) 3176 if (priv->sw_scan_start) {
3058 cmd->channel_flags |= cpu_to_le32(0x000000900); 3177 /* Store current channel stats
3178 * before switching to newer one.
3179 * This will be processed only for AP fw.
3180 */
3181 if (priv->channel_time != 0)
3182 mwl8k_update_survey(priv, priv->acs_chan);
3183
3184 priv->channel_time = jiffies;
3185 priv->acs_chan = channel;
3186 }
3059 3187
3060 rc = mwl8k_post_cmd(hw, &cmd->header); 3188 rc = mwl8k_post_cmd(hw, &cmd->header);
3061 kfree(cmd); 3189 kfree(cmd);
@@ -5263,6 +5391,27 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
5263{ 5391{
5264 struct mwl8k_priv *priv = hw->priv; 5392 struct mwl8k_priv *priv = hw->priv;
5265 struct ieee80211_conf *conf = &hw->conf; 5393 struct ieee80211_conf *conf = &hw->conf;
5394 struct ieee80211_supported_band *sband;
5395
5396 if (priv->ap_fw) {
5397 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
5398
5399 if (sband && idx >= sband->n_channels) {
5400 idx -= sband->n_channels;
5401 sband = NULL;
5402 }
5403
5404 if (!sband)
5405 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
5406
5407 if (!sband || idx >= sband->n_channels)
5408 return -ENOENT;
5409
5410 memcpy(survey, &priv->survey[idx], sizeof(*survey));
5411 survey->channel = &sband->channels[idx];
5412
5413 return 0;
5414 }
5266 5415
5267 if (idx != 0) 5416 if (idx != 0)
5268 return -ENOENT; 5417 return -ENOENT;
@@ -5406,6 +5555,40 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5406 return rc; 5555 return rc;
5407} 5556}
5408 5557
5558static void mwl8k_sw_scan_start(struct ieee80211_hw *hw)
5559{
5560 struct mwl8k_priv *priv = hw->priv;
5561 u8 tmp;
5562
5563 if (!priv->ap_fw)
5564 return;
5565
5566 /* clear all stats */
5567 priv->channel_time = 0;
5568 ioread32(priv->regs + BBU_RXRDY_CNT_REG);
5569 ioread32(priv->regs + NOK_CCA_CNT_REG);
5570 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp);
5571
5572 priv->sw_scan_start = true;
5573}
5574
5575static void mwl8k_sw_scan_complete(struct ieee80211_hw *hw)
5576{
5577 struct mwl8k_priv *priv = hw->priv;
5578 u8 tmp;
5579
5580 if (!priv->ap_fw)
5581 return;
5582
5583 priv->sw_scan_start = false;
5584
5585 /* clear all stats */
5586 priv->channel_time = 0;
5587 ioread32(priv->regs + BBU_RXRDY_CNT_REG);
5588 ioread32(priv->regs + NOK_CCA_CNT_REG);
5589 mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp);
5590}
5591
5409static const struct ieee80211_ops mwl8k_ops = { 5592static const struct ieee80211_ops mwl8k_ops = {
5410 .tx = mwl8k_tx, 5593 .tx = mwl8k_tx,
5411 .start = mwl8k_start, 5594 .start = mwl8k_start,
@@ -5424,6 +5607,8 @@ static const struct ieee80211_ops mwl8k_ops = {
5424 .get_stats = mwl8k_get_stats, 5607 .get_stats = mwl8k_get_stats,
5425 .get_survey = mwl8k_get_survey, 5608 .get_survey = mwl8k_get_survey,
5426 .ampdu_action = mwl8k_ampdu_action, 5609 .ampdu_action = mwl8k_ampdu_action,
5610 .sw_scan_start = mwl8k_sw_scan_start,
5611 .sw_scan_complete = mwl8k_sw_scan_complete,
5427}; 5612};
5428 5613
5429static void mwl8k_finalize_join_worker(struct work_struct *work) 5614static void mwl8k_finalize_join_worker(struct work_struct *work)
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index d01edd2c50c5..a9e94b6db5b7 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -59,7 +59,8 @@ int orinoco_wiphy_register(struct wiphy *wiphy)
59 for (i = 0; i < NUM_CHANNELS; i++) { 59 for (i = 0; i < NUM_CHANNELS; i++) {
60 if (priv->channel_mask & (1 << i)) { 60 if (priv->channel_mask & (1 << i)) {
61 priv->channels[i].center_freq = 61 priv->channels[i].center_freq =
62 ieee80211_dsss_chan_to_freq(i + 1); 62 ieee80211_channel_to_frequency(i + 1,
63 IEEE80211_BAND_2GHZ);
63 channels++; 64 channels++;
64 } 65 }
65 } 66 }
@@ -177,7 +178,7 @@ static int orinoco_set_monitor_channel(struct wiphy *wiphy,
177 if (chandef->chan->band != IEEE80211_BAND_2GHZ) 178 if (chandef->chan->band != IEEE80211_BAND_2GHZ)
178 return -EINVAL; 179 return -EINVAL;
179 180
180 channel = ieee80211_freq_to_dsss_chan(chandef->chan->center_freq); 181 channel = ieee80211_frequency_to_channel(chandef->chan->center_freq);
181 182
182 if ((channel < 1) || (channel > NUM_CHANNELS) || 183 if ((channel < 1) || (channel > NUM_CHANNELS) ||
183 !(priv->channel_mask & (1 << (channel - 1)))) 184 !(priv->channel_mask & (1 << (channel - 1))))
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index c09c8437c0b8..49300d04efdf 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -1193,7 +1193,7 @@ int orinoco_hw_get_freq(struct orinoco_private *priv)
1193 goto out; 1193 goto out;
1194 1194
1195 } 1195 }
1196 freq = ieee80211_dsss_chan_to_freq(channel); 1196 freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
1197 1197
1198 out: 1198 out:
1199 orinoco_unlock(priv, &flags); 1199 orinoco_unlock(priv, &flags);
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index e8c5714bfd11..e175b9b8561b 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -110,7 +110,8 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv,
110 break; 110 break;
111 } 111 }
112 112
113 freq = ieee80211_dsss_chan_to_freq(le16_to_cpu(bss->a.channel)); 113 freq = ieee80211_channel_to_frequency(
114 le16_to_cpu(bss->a.channel), IEEE80211_BAND_2GHZ);
114 channel = ieee80211_get_channel(wiphy, freq); 115 channel = ieee80211_get_channel(wiphy, freq);
115 if (!channel) { 116 if (!channel) {
116 printk(KERN_DEBUG "Invalid channel designation %04X(%04X)", 117 printk(KERN_DEBUG "Invalid channel designation %04X(%04X)",
@@ -146,7 +147,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
146 ie_len = len - sizeof(*bss); 147 ie_len = len - sizeof(*bss);
147 ie = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bss->data, ie_len); 148 ie = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bss->data, ie_len);
148 chan = ie ? ie[2] : 0; 149 chan = ie ? ie[2] : 0;
149 freq = ieee80211_dsss_chan_to_freq(chan); 150 freq = ieee80211_channel_to_frequency(chan, IEEE80211_BAND_2GHZ);
150 channel = ieee80211_get_channel(wiphy, freq); 151 channel = ieee80211_get_channel(wiphy, freq);
151 152
152 timestamp = le64_to_cpu(bss->timestamp); 153 timestamp = le64_to_cpu(bss->timestamp);
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 3b5508f982e8..b7a867b50b94 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -444,7 +444,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
444 for (i = 0; i < (6 - frq->e); i++) 444 for (i = 0; i < (6 - frq->e); i++)
445 denom *= 10; 445 denom *= 10;
446 446
447 chan = ieee80211_freq_to_dsss_chan(frq->m / denom); 447 chan = ieee80211_frequency_to_channel(frq->m / denom);
448 } 448 }
449 449
450 if ((chan < 1) || (chan > NUM_CHANNELS) || 450 if ((chan < 1) || (chan > NUM_CHANNELS) ||
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 6e635cfa24c8..b7ab3dfb3de8 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -513,7 +513,7 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
513 if (!buf) 513 if (!buf)
514 return -ENOMEM; 514 return -ENOMEM;
515 515
516 left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size); 516 left = block_size = min_t(size_t, P54U_FW_BLOCK, priv->fw->size);
517 strcpy(buf, p54u_firmware_upload_3887); 517 strcpy(buf, p54u_firmware_upload_3887);
518 left -= strlen(p54u_firmware_upload_3887); 518 left -= strlen(p54u_firmware_upload_3887);
519 tmp += strlen(p54u_firmware_upload_3887); 519 tmp += strlen(p54u_firmware_upload_3887);
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 78fa64d3f223..ecbb0546cf3e 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -644,7 +644,7 @@ prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
644 wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie); 644 wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
645 if (wpa_ie_len > 0) { 645 if (wpa_ie_len > 0) {
646 iwe.cmd = IWEVGENIE; 646 iwe.cmd = IWEVGENIE;
647 iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN); 647 iwe.u.data.length = min_t(size_t, wpa_ie_len, MAX_WPA_IE_LEN);
648 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 648 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
649 &iwe, wpa_ie); 649 &iwe, wpa_ie);
650 } 650 }
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 2e89a865a67d..39d22a154341 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -1290,7 +1290,8 @@ static int set_channel(struct usbnet *usbdev, int channel)
1290 if (is_associated(usbdev)) 1290 if (is_associated(usbdev))
1291 return 0; 1291 return 0;
1292 1292
1293 dsconfig = ieee80211_dsss_chan_to_freq(channel) * 1000; 1293 dsconfig = 1000 *
1294 ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
1294 1295
1295 len = sizeof(config); 1296 len = sizeof(config);
1296 ret = rndis_query_oid(usbdev, 1297 ret = rndis_query_oid(usbdev,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 14a90ddf585c..a49c3d73ea2c 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -764,7 +764,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
764 /* 764 /*
765 * Overwrite TX done handler 765 * Overwrite TX done handler
766 */ 766 */
767 PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone); 767 INIT_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone);
768 768
769 return 0; 769 return 0;
770} 770}
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 2e3d1645e68b..90fdb02b55e7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -286,7 +286,7 @@ static ssize_t rt2x00debug_read_queue_dump(struct file *file,
286 if (retval) 286 if (retval)
287 return retval; 287 return retval;
288 288
289 status = min((size_t)skb->len, length); 289 status = min_t(size_t, skb->len, length);
290 if (copy_to_user(buf, skb->data, status)) { 290 if (copy_to_user(buf, skb->data, status)) {
291 status = -EFAULT; 291 status = -EFAULT;
292 goto exit; 292 goto exit;
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 7980ab1f9eca..959e699702e8 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -335,7 +335,18 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
335 entry->flags2 = info->control.rates[1].idx >= 0 ? 335 entry->flags2 = info->control.rates[1].idx >= 0 ?
336 ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; 336 ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
337 entry->retry_limit = info->control.rates[0].count; 337 entry->retry_limit = info->control.rates[0].count;
338
339 /* We must be sure that tx_flags is written last because the HW
340 * looks at it to check if the rest of data is valid or not
341 */
342 wmb();
338 entry->flags = cpu_to_le32(tx_flags); 343 entry->flags = cpu_to_le32(tx_flags);
344 /* We must be sure this has been written before followings HW
345 * register write, because this write will made the HW attempts
346 * to DMA the just-written data
347 */
348 wmb();
349
339 __skb_queue_tail(&ring->queue, skb); 350 __skb_queue_tail(&ring->queue, skb);
340 if (ring->entries - skb_queue_len(&ring->queue) < 2) 351 if (ring->entries - skb_queue_len(&ring->queue) < 2)
341 ieee80211_stop_queue(dev, prio); 352 ieee80211_stop_queue(dev, prio);
@@ -476,13 +487,21 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
476 struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); 487 struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE);
477 dma_addr_t *mapping; 488 dma_addr_t *mapping;
478 entry = &priv->rx_ring[i]; 489 entry = &priv->rx_ring[i];
479 if (!skb) 490 if (!skb) {
480 return 0; 491 wiphy_err(dev->wiphy, "Cannot allocate RX skb\n");
481 492 return -ENOMEM;
493 }
482 priv->rx_buf[i] = skb; 494 priv->rx_buf[i] = skb;
483 mapping = (dma_addr_t *)skb->cb; 495 mapping = (dma_addr_t *)skb->cb;
484 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb), 496 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
485 MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 497 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
498
499 if (pci_dma_mapping_error(priv->pdev, *mapping)) {
500 kfree_skb(skb);
501 wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n");
502 return -ENOMEM;
503 }
504
486 entry->rx_buf = cpu_to_le32(*mapping); 505 entry->rx_buf = cpu_to_le32(*mapping);
487 entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | 506 entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
488 MAX_RX_SIZE); 507 MAX_RX_SIZE);
@@ -619,11 +638,23 @@ static int rtl8180_start(struct ieee80211_hw *dev)
619 638
620 if (priv->r8185) { 639 if (priv->r8185) {
621 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); 640 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
641
642 /* CW is not on per-packet basis.
643 * in rtl8185 the CW_VALUE reg is used.
644 */
622 reg &= ~RTL818X_CW_CONF_PERPACKET_CW; 645 reg &= ~RTL818X_CW_CONF_PERPACKET_CW;
646 /* retry limit IS on per-packet basis.
647 * the short and long retry limit in TX_CONF
648 * reg are ignored
649 */
623 reg |= RTL818X_CW_CONF_PERPACKET_RETRY; 650 reg |= RTL818X_CW_CONF_PERPACKET_RETRY;
624 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); 651 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
625 652
626 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); 653 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
654 /* TX antenna and TX gain are not on per-packet basis.
655 * TX Antenna is selected by ANTSEL reg (RX in BB regs).
656 * TX gain is selected with CCK_TX_AGC and OFDM_TX_AGC regs
657 */
627 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN; 658 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN;
628 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL; 659 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL;
629 reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT; 660 reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
@@ -642,6 +673,8 @@ static int rtl8180_start(struct ieee80211_hw *dev)
642 else 673 else
643 reg &= ~RTL818X_TX_CONF_HW_SEQNUM; 674 reg &= ~RTL818X_TX_CONF_HW_SEQNUM;
644 675
676 reg &= ~RTL818X_TX_CONF_DISCW;
677
645 /* different meaning, same value on both rtl8185 and rtl8180 */ 678 /* different meaning, same value on both rtl8185 and rtl8180 */
646 reg &= ~RTL818X_TX_CONF_SAT_HWPLCP; 679 reg &= ~RTL818X_TX_CONF_SAT_HWPLCP;
647 680
@@ -1135,7 +1168,7 @@ static int rtl8180_probe(struct pci_dev *pdev,
1135 return 0; 1168 return 0;
1136 1169
1137 err_iounmap: 1170 err_iounmap:
1138 iounmap(priv->map); 1171 pci_iounmap(pdev, priv->map);
1139 1172
1140 err_free_dev: 1173 err_free_dev:
1141 ieee80211_free_hw(dev); 1174 ieee80211_free_hw(dev);
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
index c2ffce7a907c..bf3cf124e4ea 100644
--- a/drivers/net/wireless/rtlwifi/Kconfig
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -5,7 +5,7 @@ menuconfig RTL_CARDS
5 ---help--- 5 ---help---
6 This option will enable support for the Realtek mac80211-based 6 This option will enable support for the Realtek mac80211-based
7 wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de, 7 wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de,
8 rtl8723eu, and rtl8188eu share some common code. 8 rtl8723ae, rtl8723be, and rtl8188ae share some common code.
9 9
10if RTL_CARDS 10if RTL_CARDS
11 11
@@ -48,12 +48,27 @@ config RTL8723AE
48 depends on PCI 48 depends on PCI
49 select RTLWIFI 49 select RTLWIFI
50 select RTLWIFI_PCI 50 select RTLWIFI_PCI
51 select RTL8723_COMMON
52 select RTLBTCOEXIST
51 ---help--- 53 ---help---
52 This is the driver for Realtek RTL8723AE 802.11n PCIe 54 This is the driver for Realtek RTL8723AE 802.11n PCIe
53 wireless network adapters. 55 wireless network adapters.
54 56
55 If you choose to build it as a module, it will be called rtl8723ae 57 If you choose to build it as a module, it will be called rtl8723ae
56 58
59config RTL8723BE
60 tristate "Realtek RTL8723BE PCIe Wireless Network Adapter"
61 depends on PCI
62 select RTLWIFI
63 select RTLWIFI_PCI
64 select RTL8723_COMMON
65 select RTLBTCOEXIST
66 ---help---
67 This is the driver for Realtek RTL8723BE 802.11n PCIe
68 wireless network adapters.
69
70 If you choose to build it as a module, it will be called rtl8723be
71
57config RTL8188EE 72config RTL8188EE
58 tristate "Realtek RTL8188EE Wireless Network Adapter" 73 tristate "Realtek RTL8188EE Wireless Network Adapter"
59 depends on PCI 74 depends on PCI
@@ -101,4 +116,14 @@ config RTL8192C_COMMON
101 depends on RTL8192CE || RTL8192CU 116 depends on RTL8192CE || RTL8192CU
102 default y 117 default y
103 118
119config RTL8723_COMMON
120 tristate
121 depends on RTL8723AE || RTL8723BE
122 default y
123
124config RTLBTCOEXIST
125 tristate
126 depends on RTL8723AE || RTL8723BE
127 default y
128
104endif 129endif
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile
index d56f023a4b90..bba36a06abcc 100644
--- a/drivers/net/wireless/rtlwifi/Makefile
+++ b/drivers/net/wireless/rtlwifi/Makefile
@@ -24,6 +24,9 @@ obj-$(CONFIG_RTL8192CU) += rtl8192cu/
24obj-$(CONFIG_RTL8192SE) += rtl8192se/ 24obj-$(CONFIG_RTL8192SE) += rtl8192se/
25obj-$(CONFIG_RTL8192DE) += rtl8192de/ 25obj-$(CONFIG_RTL8192DE) += rtl8192de/
26obj-$(CONFIG_RTL8723AE) += rtl8723ae/ 26obj-$(CONFIG_RTL8723AE) += rtl8723ae/
27obj-$(CONFIG_RTL8723BE) += rtl8723be/
27obj-$(CONFIG_RTL8188EE) += rtl8188ee/ 28obj-$(CONFIG_RTL8188EE) += rtl8188ee/
29obj-$(CONFIG_RTLBTCOEXIST) += btcoexist/
30obj-$(CONFIG_RTL8723_COMMON) += rtl8723com/
28 31
29ccflags-y += -D__CHECK_ENDIAN__ 32ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/Makefile b/drivers/net/wireless/rtlwifi/btcoexist/Makefile
new file mode 100644
index 000000000000..47ceecfcb7dc
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/Makefile
@@ -0,0 +1,7 @@
1btcoexist-objs := halbtc8723b2ant.o \
2 halbtcoutsrc.o \
3 rtl_btc.o
4
5obj-$(CONFIG_RTLBTCOEXIST) += btcoexist.o
6
7ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h
new file mode 100644
index 000000000000..d76684eb24d0
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h
@@ -0,0 +1,75 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 * Larry Finger <Larry.Finger@lwfinger.net>
22 *
23 ******************************************************************************/
24
25#ifndef __HALBT_PRECOMP_H__
26#define __HALBT_PRECOMP_H__
27/*************************************************************
28 * include files
29 *************************************************************/
30#include "../wifi.h"
31#include "../efuse.h"
32#include "../base.h"
33#include "../regd.h"
34#include "../cam.h"
35#include "../ps.h"
36#include "../pci.h"
37
38#include "halbtcoutsrc.h"
39
40#include "halbtc8723b2ant.h"
41
42#define BIT0 0x00000001
43#define BIT1 0x00000002
44#define BIT2 0x00000004
45#define BIT3 0x00000008
46#define BIT4 0x00000010
47#define BIT5 0x00000020
48#define BIT6 0x00000040
49#define BIT7 0x00000080
50#define BIT8 0x00000100
51#define BIT9 0x00000200
52#define BIT10 0x00000400
53#define BIT11 0x00000800
54#define BIT12 0x00001000
55#define BIT13 0x00002000
56#define BIT14 0x00004000
57#define BIT15 0x00008000
58#define BIT16 0x00010000
59#define BIT17 0x00020000
60#define BIT18 0x00040000
61#define BIT19 0x00080000
62#define BIT20 0x00100000
63#define BIT21 0x00200000
64#define BIT22 0x00400000
65#define BIT23 0x00800000
66#define BIT24 0x01000000
67#define BIT25 0x02000000
68#define BIT26 0x04000000
69#define BIT27 0x08000000
70#define BIT28 0x10000000
71#define BIT29 0x20000000
72#define BIT30 0x40000000
73#define BIT31 0x80000000
74
75#endif /* __HALBT_PRECOMP_H__ */
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
new file mode 100644
index 000000000000..d916ab9f3c38
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
@@ -0,0 +1,3698 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25/***************************************************************
26 * Description:
27 *
28 * This file is for RTL8723B Co-exist mechanism
29 *
30 * History
31 * 2012/11/15 Cosa first check in.
32 *
33 **************************************************************/
34/**************************************************************
35 * include files
36 **************************************************************/
37#include "halbt_precomp.h"
38/**************************************************************
39 * Global variables, these are static variables
40 **************************************************************/
41static struct coex_dm_8723b_2ant glcoex_dm_8723b_2ant;
42static struct coex_dm_8723b_2ant *coex_dm = &glcoex_dm_8723b_2ant;
43static struct coex_sta_8723b_2ant glcoex_sta_8723b_2ant;
44static struct coex_sta_8723b_2ant *coex_sta = &glcoex_sta_8723b_2ant;
45
46static const char *const glbt_info_src_8723b_2ant[] = {
47 "BT Info[wifi fw]",
48 "BT Info[bt rsp]",
49 "BT Info[bt auto report]",
50};
51
52static u32 glcoex_ver_date_8723b_2ant = 20130731;
53static u32 glcoex_ver_8723b_2ant = 0x3b;
54
55/**************************************************************
56 * local function proto type if needed
57 **************************************************************/
58/**************************************************************
59 * local function start with btc8723b2ant_
60 **************************************************************/
61static u8 btc8723b2ant_bt_rssi_state(u8 level_num, u8 rssi_thresh,
62 u8 rssi_thresh1)
63{
64 s32 bt_rssi = 0;
65 u8 bt_rssi_state = coex_sta->pre_bt_rssi_state;
66
67 bt_rssi = coex_sta->bt_rssi;
68
69 if (level_num == 2) {
70 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
71 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
72 if (bt_rssi >= rssi_thresh +
73 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) {
74 bt_rssi_state = BTC_RSSI_STATE_HIGH;
75 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
76 "[BTCoex], BT Rssi state "
77 "switch to High\n");
78 } else {
79 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
80 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
81 "[BTCoex], BT Rssi state "
82 "stay at Low\n");
83 }
84 } else {
85 if (bt_rssi < rssi_thresh) {
86 bt_rssi_state = BTC_RSSI_STATE_LOW;
87 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
88 "[BTCoex], BT Rssi state "
89 "switch to Low\n");
90 } else {
91 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
92 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
93 "[BTCoex], BT Rssi state "
94 "stay at High\n");
95 }
96 }
97 } else if (level_num == 3) {
98 if (rssi_thresh > rssi_thresh1) {
99 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
100 "[BTCoex], BT Rssi thresh error!!\n");
101 return coex_sta->pre_bt_rssi_state;
102 }
103
104 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
105 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
106 if (bt_rssi >= rssi_thresh +
107 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) {
108 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
109 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
110 "[BTCoex], BT Rssi state "
111 "switch to Medium\n");
112 } else {
113 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
114 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
115 "[BTCoex], BT Rssi state "
116 "stay at Low\n");
117 }
118 } else if ((coex_sta->pre_bt_rssi_state ==
119 BTC_RSSI_STATE_MEDIUM) ||
120 (coex_sta->pre_bt_rssi_state ==
121 BTC_RSSI_STATE_STAY_MEDIUM)) {
122 if (bt_rssi >= rssi_thresh1 +
123 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) {
124 bt_rssi_state = BTC_RSSI_STATE_HIGH;
125 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
126 "[BTCoex], BT Rssi state "
127 "switch to High\n");
128 } else if (bt_rssi < rssi_thresh) {
129 bt_rssi_state = BTC_RSSI_STATE_LOW;
130 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
131 "[BTCoex], BT Rssi state "
132 "switch to Low\n");
133 } else {
134 bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
135 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
136 "[BTCoex], BT Rssi state "
137 "stay at Medium\n");
138 }
139 } else {
140 if (bt_rssi < rssi_thresh1) {
141 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
142 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
143 "[BTCoex], BT Rssi state "
144 "switch to Medium\n");
145 } else {
146 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
147 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
148 "[BTCoex], BT Rssi state "
149 "stay at High\n");
150 }
151 }
152 }
153
154 coex_sta->pre_bt_rssi_state = bt_rssi_state;
155
156 return bt_rssi_state;
157}
158
159static u8 btc8723b2ant_wifi_rssi_state(struct btc_coexist *btcoexist,
160 u8 index, u8 level_num,
161 u8 rssi_thresh, u8 rssi_thresh1)
162{
163 s32 wifi_rssi = 0;
164 u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];
165
166 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
167
168 if (level_num == 2) {
169 if ((coex_sta->pre_wifi_rssi_state[index] ==
170 BTC_RSSI_STATE_LOW) ||
171 (coex_sta->pre_wifi_rssi_state[index] ==
172 BTC_RSSI_STATE_STAY_LOW)) {
173 if (wifi_rssi >= rssi_thresh +
174 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) {
175 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
176 BTC_PRINT(BTC_MSG_ALGORITHM,
177 ALGO_WIFI_RSSI_STATE,
178 "[BTCoex], wifi RSSI state "
179 "switch to High\n");
180 } else {
181 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
182 BTC_PRINT(BTC_MSG_ALGORITHM,
183 ALGO_WIFI_RSSI_STATE,
184 "[BTCoex], wifi RSSI state "
185 "stay at Low\n");
186 }
187 } else {
188 if (wifi_rssi < rssi_thresh) {
189 wifi_rssi_state = BTC_RSSI_STATE_LOW;
190 BTC_PRINT(BTC_MSG_ALGORITHM,
191 ALGO_WIFI_RSSI_STATE,
192 "[BTCoex], wifi RSSI state "
193 "switch to Low\n");
194 } else {
195 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
196 BTC_PRINT(BTC_MSG_ALGORITHM,
197 ALGO_WIFI_RSSI_STATE,
198 "[BTCoex], wifi RSSI state "
199 "stay at High\n");
200 }
201 }
202 } else if (level_num == 3) {
203 if (rssi_thresh > rssi_thresh1) {
204 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE,
205 "[BTCoex], wifi RSSI thresh error!!\n");
206 return coex_sta->pre_wifi_rssi_state[index];
207 }
208
209 if ((coex_sta->pre_wifi_rssi_state[index] ==
210 BTC_RSSI_STATE_LOW) ||
211 (coex_sta->pre_wifi_rssi_state[index] ==
212 BTC_RSSI_STATE_STAY_LOW)) {
213 if (wifi_rssi >= rssi_thresh +
214 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) {
215 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
216 BTC_PRINT(BTC_MSG_ALGORITHM,
217 ALGO_WIFI_RSSI_STATE,
218 "[BTCoex], wifi RSSI state "
219 "switch to Medium\n");
220 } else {
221 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
222 BTC_PRINT(BTC_MSG_ALGORITHM,
223 ALGO_WIFI_RSSI_STATE,
224 "[BTCoex], wifi RSSI state "
225 "stay at Low\n");
226 }
227 } else if ((coex_sta->pre_wifi_rssi_state[index] ==
228 BTC_RSSI_STATE_MEDIUM) ||
229 (coex_sta->pre_wifi_rssi_state[index] ==
230 BTC_RSSI_STATE_STAY_MEDIUM)) {
231 if (wifi_rssi >= rssi_thresh1 +
232 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) {
233 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
234 BTC_PRINT(BTC_MSG_ALGORITHM,
235 ALGO_WIFI_RSSI_STATE,
236 "[BTCoex], wifi RSSI state "
237 "switch to High\n");
238 } else if (wifi_rssi < rssi_thresh) {
239 wifi_rssi_state = BTC_RSSI_STATE_LOW;
240 BTC_PRINT(BTC_MSG_ALGORITHM,
241 ALGO_WIFI_RSSI_STATE,
242 "[BTCoex], wifi RSSI state "
243 "switch to Low\n");
244 } else {
245 wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
246 BTC_PRINT(BTC_MSG_ALGORITHM,
247 ALGO_WIFI_RSSI_STATE,
248 "[BTCoex], wifi RSSI state "
249 "stay at Medium\n");
250 }
251 } else {
252 if (wifi_rssi < rssi_thresh1) {
253 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
254 BTC_PRINT(BTC_MSG_ALGORITHM,
255 ALGO_WIFI_RSSI_STATE,
256 "[BTCoex], wifi RSSI state "
257 "switch to Medium\n");
258 } else {
259 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
260 BTC_PRINT(BTC_MSG_ALGORITHM,
261 ALGO_WIFI_RSSI_STATE,
262 "[BTCoex], wifi RSSI state "
263 "stay at High\n");
264 }
265 }
266 }
267
268 coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;
269
270 return wifi_rssi_state;
271}
272
273static void btc8723b2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
274{
275 u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
276 u32 reg_hp_tx = 0, reg_hp_rx = 0;
277 u32 reg_lp_tx = 0, reg_lp_rx = 0;
278
279 reg_hp_txrx = 0x770;
280 reg_lp_txrx = 0x774;
281
282 u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx);
283 reg_hp_tx = u32tmp & MASKLWORD;
284 reg_hp_rx = (u32tmp & MASKHWORD) >> 16;
285
286 u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx);
287 reg_lp_tx = u32tmp & MASKLWORD;
288 reg_lp_rx = (u32tmp & MASKHWORD) >> 16;
289
290 coex_sta->high_priority_tx = reg_hp_tx;
291 coex_sta->high_priority_rx = reg_hp_rx;
292 coex_sta->low_priority_tx = reg_lp_tx;
293 coex_sta->low_priority_rx = reg_lp_rx;
294
295 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
296 "[BTCoex], High Priority Tx/Rx(reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
297 reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx);
298 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
299 "[BTCoex], Low Priority Tx/Rx(reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
300 reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx);
301
302 /* reset counter */
303 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
304}
305
306static bool btc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
307{
308 static bool pre_wifi_busy;
309 static bool pre_under_4way;
310 static bool pre_bt_hs_on;
311 bool wifi_busy = false, under_4way = false, bt_hs_on = false;
312 bool wifi_connected = false;
313
314 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
315 &wifi_connected);
316 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
317 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
318 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
319 &under_4way);
320
321 if (wifi_connected) {
322 if (wifi_busy != pre_wifi_busy) {
323 pre_wifi_busy = wifi_busy;
324 return true;
325 }
326
327 if (under_4way != pre_under_4way) {
328 pre_under_4way = under_4way;
329 return true;
330 }
331
332 if (bt_hs_on != pre_bt_hs_on) {
333 pre_bt_hs_on = bt_hs_on;
334 return true;
335 }
336 }
337
338 return false;
339}
340
341static void btc8723b2ant_update_bt_link_info(struct btc_coexist *btcoexist)
342{
343 /*struct btc_stack_info *stack_info = &btcoexist->stack_info;*/
344 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
345 bool bt_hs_on = false;
346
347#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) /* profile from bt patch */
348 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
349
350 bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
351 bt_link_info->sco_exist = coex_sta->sco_exist;
352 bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
353 bt_link_info->pan_exist = coex_sta->pan_exist;
354 bt_link_info->hid_exist = coex_sta->hid_exist;
355
356 /* work around for HS mode. */
357 if (bt_hs_on) {
358 bt_link_info->pan_exist = true;
359 bt_link_info->bt_link_exist = true;
360 }
361#else /* profile from bt stack */
362 bt_link_info->bt_link_exist = stack_info->bt_link_exist;
363 bt_link_info->sco_exist = stack_info->sco_exist;
364 bt_link_info->a2dp_exist = stack_info->a2dp_exist;
365 bt_link_info->pan_exist = stack_info->pan_exist;
366 bt_link_info->hid_exist = stack_info->hid_exist;
367
368 /*for win-8 stack HID report error*/
369 if (!stack_info->hid_exist)
370 stack_info->hid_exist = coex_sta->hid_exist;
371 /*sync BTInfo with BT firmware and stack*/
372 /* when stack HID report error, here we use the info from bt fw.*/
373 if (!stack_info->bt_link_exist)
374 stack_info->bt_link_exist = coex_sta->bt_link_exist;
375#endif
376 /* check if Sco only */
377 if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
378 !bt_link_info->pan_exist && !bt_link_info->hid_exist)
379 bt_link_info->sco_only = true;
380 else
381 bt_link_info->sco_only = false;
382
383 /* check if A2dp only */
384 if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist &&
385 !bt_link_info->pan_exist && !bt_link_info->hid_exist)
386 bt_link_info->a2dp_only = true;
387 else
388 bt_link_info->a2dp_only = false;
389
390 /* check if Pan only */
391 if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
392 bt_link_info->pan_exist && !bt_link_info->hid_exist)
393 bt_link_info->pan_only = true;
394 else
395 bt_link_info->pan_only = false;
396
397 /* check if Hid only */
398 if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
399 !bt_link_info->pan_exist && bt_link_info->hid_exist)
400 bt_link_info->hid_only = true;
401 else
402 bt_link_info->hid_only = false;
403}
404
405static u8 btc8723b2ant_action_algorithm(struct btc_coexist *btcoexist)
406{
407 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
408 bool bt_hs_on = false;
409 u8 algorithm = BT_8723B_2ANT_COEX_ALGO_UNDEFINED;
410 u8 num_of_diff_profile = 0;
411
412 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
413
414 if (!bt_link_info->bt_link_exist) {
415 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
416 "[BTCoex], No BT link exists!!!\n");
417 return algorithm;
418 }
419
420 if (bt_link_info->sco_exist)
421 num_of_diff_profile++;
422 if (bt_link_info->hid_exist)
423 num_of_diff_profile++;
424 if (bt_link_info->pan_exist)
425 num_of_diff_profile++;
426 if (bt_link_info->a2dp_exist)
427 num_of_diff_profile++;
428
429 if (num_of_diff_profile == 1) {
430 if (bt_link_info->sco_exist) {
431 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
432 "[BTCoex], SCO only\n");
433 algorithm = BT_8723B_2ANT_COEX_ALGO_SCO;
434 } else {
435 if (bt_link_info->hid_exist) {
436 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
437 "[BTCoex], HID only\n");
438 algorithm = BT_8723B_2ANT_COEX_ALGO_HID;
439 } else if (bt_link_info->a2dp_exist) {
440 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
441 "[BTCoex], A2DP only\n");
442 algorithm = BT_8723B_2ANT_COEX_ALGO_A2DP;
443 } else if (bt_link_info->pan_exist) {
444 if (bt_hs_on) {
445 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
446 "[BTCoex], PAN(HS) only\n");
447 algorithm =
448 BT_8723B_2ANT_COEX_ALGO_PANHS;
449 } else {
450 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
451 "[BTCoex], PAN(EDR) only\n");
452 algorithm =
453 BT_8723B_2ANT_COEX_ALGO_PANEDR;
454 }
455 }
456 }
457 } else if (num_of_diff_profile == 2) {
458 if (bt_link_info->sco_exist) {
459 if (bt_link_info->hid_exist) {
460 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
461 "[BTCoex], SCO + HID\n");
462 algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
463 } else if (bt_link_info->a2dp_exist) {
464 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
465 "[BTCoex], SCO + A2DP ==> SCO\n");
466 algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
467 } else if (bt_link_info->pan_exist) {
468 if (bt_hs_on) {
469 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
470 "[BTCoex], SCO + PAN(HS)\n");
471 algorithm = BT_8723B_2ANT_COEX_ALGO_SCO;
472 } else {
473 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
474 "[BTCoex], SCO + PAN(EDR)\n");
475 algorithm =
476 BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
477 }
478 }
479 } else {
480 if (bt_link_info->hid_exist &&
481 bt_link_info->a2dp_exist) {
482 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
483 "[BTCoex], HID + A2DP\n");
484 algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP;
485 } else if (bt_link_info->hid_exist &&
486 bt_link_info->pan_exist) {
487 if (bt_hs_on) {
488 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
489 "[BTCoex], HID + PAN(HS)\n");
490 algorithm = BT_8723B_2ANT_COEX_ALGO_HID;
491 } else {
492 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
493 "[BTCoex], HID + PAN(EDR)\n");
494 algorithm =
495 BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
496 }
497 } else if (bt_link_info->pan_exist &&
498 bt_link_info->a2dp_exist) {
499 if (bt_hs_on) {
500 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
501 "[BTCoex], A2DP + PAN(HS)\n");
502 algorithm =
503 BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS;
504 } else {
505 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
506 "[BTCoex],A2DP + PAN(EDR)\n");
507 algorithm =
508 BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP;
509 }
510 }
511 }
512 } else if (num_of_diff_profile == 3) {
513 if (bt_link_info->sco_exist) {
514 if (bt_link_info->hid_exist &&
515 bt_link_info->a2dp_exist) {
516 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
517 "[BTCoex], SCO + HID + A2DP"
518 " ==> HID\n");
519 algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
520 } else if (bt_link_info->hid_exist &&
521 bt_link_info->pan_exist) {
522 if (bt_hs_on) {
523 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
524 "[BTCoex], SCO + HID + "
525 "PAN(HS)\n");
526 algorithm =
527 BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
528 } else {
529 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
530 "[BTCoex], SCO + HID + "
531 "PAN(EDR)\n");
532 algorithm =
533 BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
534 }
535 } else if (bt_link_info->pan_exist &&
536 bt_link_info->a2dp_exist) {
537 if (bt_hs_on) {
538 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
539 "[BTCoex], SCO + A2DP + "
540 "PAN(HS)\n");
541 algorithm =
542 BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
543 } else {
544 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
545 "[BTCoex], SCO + A2DP + "
546 "PAN(EDR) ==> HID\n");
547 algorithm =
548 BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
549 }
550 }
551 } else {
552 if (bt_link_info->hid_exist &&
553 bt_link_info->pan_exist &&
554 bt_link_info->a2dp_exist) {
555 if (bt_hs_on) {
556 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
557 "[BTCoex], HID + A2DP + "
558 "PAN(HS)\n");
559 algorithm =
560 BT_8723B_2ANT_COEX_ALGO_HID_A2DP;
561 } else {
562 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
563 "[BTCoex], HID + A2DP + "
564 "PAN(EDR)\n");
565 algorithm =
566 BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
567 }
568 }
569 }
570 } else if (num_of_diff_profile >= 3) {
571 if (bt_link_info->sco_exist) {
572 if (bt_link_info->hid_exist &&
573 bt_link_info->pan_exist &&
574 bt_link_info->a2dp_exist) {
575 if (bt_hs_on) {
576 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
577 "[BTCoex], Error!!! SCO + HID"
578 " + A2DP + PAN(HS)\n");
579 } else {
580 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
581 "[BTCoex], SCO + HID + A2DP +"
582 " PAN(EDR)==>PAN(EDR)+HID\n");
583 algorithm =
584 BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
585 }
586 }
587 }
588 }
589 return algorithm;
590}
591
592static bool btc8723b_need_dec_pwr(struct btc_coexist *btcoexist)
593{
594 bool ret = false;
595 bool bt_hs_on = false, wifi_connected = false;
596 s32 bt_hs_rssi = 0;
597 u8 bt_rssi_state;
598
599 if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on))
600 return false;
601 if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
602 &wifi_connected))
603 return false;
604 if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi))
605 return false;
606
607 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0);
608
609 if (wifi_connected) {
610 if (bt_hs_on) {
611 if (bt_hs_rssi > 37) {
612 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
613 "[BTCoex], Need to decrease bt "
614 "power for HS mode!!\n");
615 ret = true;
616 }
617 } else {
618 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
619 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
620 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
621 "[BTCoex], Need to decrease bt "
622 "power for Wifi is connected!!\n");
623 ret = true;
624 }
625 }
626 }
627
628 return ret;
629}
630
631static void btc8723b2ant_set_fw_dac_swing_level(struct btc_coexist *btcoexist,
632 u8 dac_swing_lvl)
633{
634 u8 h2c_parameter[1] = {0};
635
636 /* There are several type of dacswing
637 * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6
638 */
639 h2c_parameter[0] = dac_swing_lvl;
640
641 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
642 "[BTCoex], Set Dac Swing Level=0x%x\n", dac_swing_lvl);
643 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
644 "[BTCoex], FW write 0x64=0x%x\n", h2c_parameter[0]);
645
646 btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter);
647}
648
649static void btc8723b2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist,
650 bool dec_bt_pwr)
651{
652 u8 h2c_parameter[1] = {0};
653
654 h2c_parameter[0] = 0;
655
656 if (dec_bt_pwr)
657 h2c_parameter[0] |= BIT1;
658
659 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
660 "[BTCoex], decrease Bt Power : %s, FW write 0x62=0x%x\n",
661 (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]);
662
663 btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
664}
665
666static void btc8723b2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
667 bool force_exec, bool dec_bt_pwr)
668{
669 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
670 "[BTCoex], %s Dec BT power = %s\n",
671 (force_exec ? "force to" : ""), (dec_bt_pwr ? "ON" : "OFF"));
672 coex_dm->cur_dec_bt_pwr = dec_bt_pwr;
673
674 if (!force_exec) {
675 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
676 "[BTCoex], bPreDecBtPwr=%d, bCurDecBtPwr=%d\n",
677 coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr);
678
679 if (coex_dm->pre_dec_bt_pwr == coex_dm->cur_dec_bt_pwr)
680 return;
681 }
682 btc8723b2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr);
683
684 coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr;
685}
686
687static void btc8723b2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist,
688 bool force_exec, u8 fw_dac_swing_lvl)
689{
690 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
691 "[BTCoex], %s set FW Dac Swing level = %d\n",
692 (force_exec ? "force to" : ""), fw_dac_swing_lvl);
693 coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl;
694
695 if (!force_exec) {
696 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
697 "[BTCoex], preFwDacSwingLvl=%d, "
698 "curFwDacSwingLvl=%d\n",
699 coex_dm->pre_fw_dac_swing_lvl,
700 coex_dm->cur_fw_dac_swing_lvl);
701
702 if (coex_dm->pre_fw_dac_swing_lvl ==
703 coex_dm->cur_fw_dac_swing_lvl)
704 return;
705 }
706
707 btc8723b2ant_set_fw_dac_swing_level(btcoexist,
708 coex_dm->cur_fw_dac_swing_lvl);
709 coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
710}
711
712static void btc8723b2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist,
713 bool rx_rf_shrink_on)
714{
715 if (rx_rf_shrink_on) {
716 /* Shrink RF Rx LPF corner */
717 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
718 "[BTCoex], Shrink RF Rx LPF corner!!\n");
719 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e,
720 0xfffff, 0xffffc);
721 } else {
722 /* Resume RF Rx LPF corner */
723 /* After initialized, we can use coex_dm->btRf0x1eBackup */
724 if (btcoexist->initilized) {
725 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
726 "[BTCoex], Resume RF Rx LPF corner!!\n");
727 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e,
728 0xfffff,
729 coex_dm->bt_rf0x1e_backup);
730 }
731 }
732}
733
734static void btc8723b2ant_rf_shrink(struct btc_coexist *btcoexist,
735 bool force_exec, bool rx_rf_shrink_on)
736{
737 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
738 "[BTCoex], %s turn Rx RF Shrink = %s\n",
739 (force_exec ? "force to" : ""), (rx_rf_shrink_on ?
740 "ON" : "OFF"));
741 coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on;
742
743 if (!force_exec) {
744 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
745 "[BTCoex], bPreRfRxLpfShrink=%d, "
746 "bCurRfRxLpfShrink=%d\n",
747 coex_dm->pre_rf_rx_lpf_shrink,
748 coex_dm->cur_rf_rx_lpf_shrink);
749
750 if (coex_dm->pre_rf_rx_lpf_shrink ==
751 coex_dm->cur_rf_rx_lpf_shrink)
752 return;
753 }
754 btc8723b2ant_set_sw_rf_rx_lpf_corner(btcoexist,
755 coex_dm->cur_rf_rx_lpf_shrink);
756
757 coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink;
758}
759
760static void btc8723b_set_penalty_txrate(struct btc_coexist *btcoexist,
761 bool low_penalty_ra)
762{
763 u8 h2c_parameter[6] = {0};
764
765 h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty*/
766
767 if (low_penalty_ra) {
768 h2c_parameter[1] |= BIT0;
769 /*normal rate except MCS7/6/5, OFDM54/48/36*/
770 h2c_parameter[2] = 0x00;
771 h2c_parameter[3] = 0xf7; /*MCS7 or OFDM54*/
772 h2c_parameter[4] = 0xf8; /*MCS6 or OFDM48*/
773 h2c_parameter[5] = 0xf9; /*MCS5 or OFDM36*/
774 }
775
776 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
777 "[BTCoex], set WiFi Low-Penalty Retry: %s",
778 (low_penalty_ra ? "ON!!" : "OFF!!"));
779
780 btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter);
781}
782
783static void btc8723b2ant_low_penalty_ra(struct btc_coexist *btcoexist,
784 bool force_exec, bool low_penalty_ra)
785{
786 /*return; */
787 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
788 "[BTCoex], %s turn LowPenaltyRA = %s\n",
789 (force_exec ? "force to" : ""), (low_penalty_ra ?
790 "ON" : "OFF"));
791 coex_dm->cur_low_penalty_ra = low_penalty_ra;
792
793 if (!force_exec) {
794 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
795 "[BTCoex], bPreLowPenaltyRa=%d, "
796 "bCurLowPenaltyRa=%d\n",
797 coex_dm->pre_low_penalty_ra,
798 coex_dm->cur_low_penalty_ra);
799
800 if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
801 return;
802 }
803 btc8723b_set_penalty_txrate(btcoexist, coex_dm->cur_low_penalty_ra);
804
805 coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
806}
807
808static void btc8723b2ant_set_dac_swing_reg(struct btc_coexist *btcoexist,
809 u32 level)
810{
811 u8 val = (u8) level;
812 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
813 "[BTCoex], Write SwDacSwing = 0x%x\n", level);
814 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val);
815}
816
817static void btc8723b2ant_set_sw_fulltime_dac_swing(struct btc_coexist *btcoex,
818 bool sw_dac_swing_on,
819 u32 sw_dac_swing_lvl)
820{
821 if (sw_dac_swing_on)
822 btc8723b2ant_set_dac_swing_reg(btcoex, sw_dac_swing_lvl);
823 else
824 btc8723b2ant_set_dac_swing_reg(btcoex, 0x18);
825}
826
827
828static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist,
829 bool force_exec, bool dac_swing_on,
830 u32 dac_swing_lvl)
831{
832 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
833 "[BTCoex], %s turn DacSwing=%s, dac_swing_lvl=0x%x\n",
834 (force_exec ? "force to" : ""),
835 (dac_swing_on ? "ON" : "OFF"), dac_swing_lvl);
836 coex_dm->cur_dac_swing_on = dac_swing_on;
837 coex_dm->cur_dac_swing_lvl = dac_swing_lvl;
838
839 if (!force_exec) {
840 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
841 "[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl=0x%x,"
842 " bCurDacSwingOn=%d, curDacSwingLvl=0x%x\n",
843 coex_dm->pre_dac_swing_on, coex_dm->pre_dac_swing_lvl,
844 coex_dm->cur_dac_swing_on,
845 coex_dm->cur_dac_swing_lvl);
846
847 if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) &&
848 (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl))
849 return;
850 }
851 mdelay(30);
852 btc8723b2ant_set_sw_fulltime_dac_swing(btcoexist, dac_swing_on,
853 dac_swing_lvl);
854
855 coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on;
856 coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl;
857}
858
859static void btc8723b2ant_set_agc_table(struct btc_coexist *btcoexist,
860 bool agc_table_en)
861{
862 u8 rssi_adjust_val = 0;
863
864 /* BB AGC Gain Table */
865 if (agc_table_en) {
866 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
867 "[BTCoex], BB Agc Table On!\n");
868 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6e1A0001);
869 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6d1B0001);
870 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6c1C0001);
871 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6b1D0001);
872 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6a1E0001);
873 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x691F0001);
874 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x68200001);
875 } else {
876 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
877 "[BTCoex], BB Agc Table Off!\n");
878 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001);
879 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa91B0001);
880 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa81C0001);
881 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa71D0001);
882 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa61E0001);
883 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa51F0001);
884 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa4200001);
885 }
886
887
888 /* RF Gain */
889 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000);
890 if (agc_table_en) {
891 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
892 "[BTCoex], Agc Table On!\n");
893 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b,
894 0xfffff, 0x38fff);
895 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b,
896 0xfffff, 0x38ffe);
897 } else {
898 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
899 "[BTCoex], Agc Table Off!\n");
900 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b,
901 0xfffff, 0x380c3);
902 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b,
903 0xfffff, 0x28ce6);
904 }
905 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x0);
906
907 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xed, 0xfffff, 0x1);
908
909 if (agc_table_en) {
910 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
911 "[BTCoex], Agc Table On!\n");
912 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40,
913 0xfffff, 0x38fff);
914 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40,
915 0xfffff, 0x38ffe);
916 } else {
917 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
918 "[BTCoex], Agc Table Off!\n");
919 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40,
920 0xfffff, 0x380c3);
921 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40,
922 0xfffff, 0x28ce6);
923 }
924 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xed, 0xfffff, 0x0);
925
926 /* set rssiAdjustVal for wifi module. */
927 if (agc_table_en)
928 rssi_adjust_val = 8;
929 btcoexist->btc_set(btcoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON,
930 &rssi_adjust_val);
931}
932
933static void btc8723b2ant_agc_table(struct btc_coexist *btcoexist,
934 bool force_exec, bool agc_table_en)
935{
936 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
937 "[BTCoex], %s %s Agc Table\n",
938 (force_exec ? "force to" : ""),
939 (agc_table_en ? "Enable" : "Disable"));
940 coex_dm->cur_agc_table_en = agc_table_en;
941
942 if (!force_exec) {
943 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
944 "[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n",
945 coex_dm->pre_agc_table_en, coex_dm->cur_agc_table_en);
946
947 if (coex_dm->pre_agc_table_en == coex_dm->cur_agc_table_en)
948 return;
949 }
950 btc8723b2ant_set_agc_table(btcoexist, agc_table_en);
951
952 coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en;
953}
954
955static void btc8723b2ant_set_coex_table(struct btc_coexist *btcoexist,
956 u32 val0x6c0, u32 val0x6c4,
957 u32 val0x6c8, u8 val0x6cc)
958{
959 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
960 "[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0);
961 btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
962
963 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
964 "[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4);
965 btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
966
967 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
968 "[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8);
969 btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
970
971 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
972 "[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc);
973 btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
974}
975
976static void btc8723b2ant_coex_table(struct btc_coexist *btcoexist,
977 bool force_exec, u32 val0x6c0,
978 u32 val0x6c4, u32 val0x6c8,
979 u8 val0x6cc)
980{
981 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
982 "[BTCoex], %s write Coex Table 0x6c0=0x%x,"
983 " 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n",
984 (force_exec ? "force to" : ""), val0x6c0,
985 val0x6c4, val0x6c8, val0x6cc);
986 coex_dm->cur_val0x6c0 = val0x6c0;
987 coex_dm->cur_val0x6c4 = val0x6c4;
988 coex_dm->cur_val0x6c8 = val0x6c8;
989 coex_dm->cur_val0x6cc = val0x6cc;
990
991 if (!force_exec) {
992 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
993 "[BTCoex], preVal0x6c0=0x%x, "
994 "preVal0x6c4=0x%x, preVal0x6c8=0x%x, "
995 "preVal0x6cc=0x%x !!\n",
996 coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4,
997 coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc);
998 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
999 "[BTCoex], curVal0x6c0=0x%x, "
1000 "curVal0x6c4=0x%x, curVal0x6c8=0x%x, "
1001 "curVal0x6cc=0x%x !!\n",
1002 coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4,
1003 coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc);
1004
1005 if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
1006 (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
1007 (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
1008 (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc))
1009 return;
1010 }
1011 btc8723b2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4,
1012 val0x6c8, val0x6cc);
1013
1014 coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
1015 coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
1016 coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
1017 coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
1018}
1019
1020static void btc8723b_coex_tbl_type(struct btc_coexist *btcoexist,
1021 bool force_exec, u8 type)
1022{
1023 switch (type) {
1024 case 0:
1025 btc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555,
1026 0x55555555, 0xffff, 0x3);
1027 break;
1028 case 1:
1029 btc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555,
1030 0x5afa5afa, 0xffff, 0x3);
1031 break;
1032 case 2:
1033 btc8723b2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
1034 0x5a5a5a5a, 0xffff, 0x3);
1035 break;
1036 case 3:
1037 btc8723b2ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa,
1038 0xaaaaaaaa, 0xffff, 0x3);
1039 break;
1040 case 4:
1041 btc8723b2ant_coex_table(btcoexist, force_exec, 0xffffffff,
1042 0xffffffff, 0xffff, 0x3);
1043 break;
1044 case 5:
1045 btc8723b2ant_coex_table(btcoexist, force_exec, 0x5fff5fff,
1046 0x5fff5fff, 0xffff, 0x3);
1047 break;
1048 case 6:
1049 btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
1050 0x5a5a5a5a, 0xffff, 0x3);
1051 break;
1052 case 7:
1053 btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
1054 0x5afa5afa, 0xffff, 0x3);
1055 break;
1056 case 8:
1057 btc8723b2ant_coex_table(btcoexist, force_exec, 0x5aea5aea,
1058 0x5aea5aea, 0xffff, 0x3);
1059 break;
1060 case 9:
1061 btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
1062 0x5aea5aea, 0xffff, 0x3);
1063 break;
1064 case 10:
1065 btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
1066 0x5aff5aff, 0xffff, 0x3);
1067 break;
1068 case 11:
1069 btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
1070 0x5a5f5a5f, 0xffff, 0x3);
1071 break;
1072 case 12:
1073 btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
1074 0x5f5f5f5f, 0xffff, 0x3);
1075 break;
1076 default:
1077 break;
1078 }
1079}
1080
1081static void btc8723b2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
1082 bool enable)
1083{
1084 u8 h2c_parameter[1] = {0};
1085
1086 if (enable)
1087 h2c_parameter[0] |= BIT0;/* function enable*/
1088
1089 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
1090 "[BTCoex], set FW for BT Ignore Wlan_Act, "
1091 "FW write 0x63=0x%x\n", h2c_parameter[0]);
1092
1093 btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
1094}
1095
1096static void btc8723b2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
1097 bool force_exec, bool enable)
1098{
1099 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1100 "[BTCoex], %s turn Ignore WlanAct %s\n",
1101 (force_exec ? "force to" : ""), (enable ? "ON" : "OFF"));
1102 coex_dm->cur_ignore_wlan_act = enable;
1103
1104 if (!force_exec) {
1105 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1106 "[BTCoex], bPreIgnoreWlanAct = %d, "
1107 "bCurIgnoreWlanAct = %d!!\n",
1108 coex_dm->pre_ignore_wlan_act,
1109 coex_dm->cur_ignore_wlan_act);
1110
1111 if (coex_dm->pre_ignore_wlan_act ==
1112 coex_dm->cur_ignore_wlan_act)
1113 return;
1114 }
1115 btc8723b2ant_set_fw_ignore_wlan_act(btcoexist, enable);
1116
1117 coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
1118}
1119
1120static void btc8723b2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1,
1121 u8 byte2, u8 byte3, u8 byte4, u8 byte5)
1122{
1123 u8 h2c_parameter[5];
1124
1125 h2c_parameter[0] = byte1;
1126 h2c_parameter[1] = byte2;
1127 h2c_parameter[2] = byte3;
1128 h2c_parameter[3] = byte4;
1129 h2c_parameter[4] = byte5;
1130
1131 coex_dm->ps_tdma_para[0] = byte1;
1132 coex_dm->ps_tdma_para[1] = byte2;
1133 coex_dm->ps_tdma_para[2] = byte3;
1134 coex_dm->ps_tdma_para[3] = byte4;
1135 coex_dm->ps_tdma_para[4] = byte5;
1136
1137 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
1138 "[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n",
1139 h2c_parameter[0],
1140 h2c_parameter[1] << 24 | h2c_parameter[2] << 16 |
1141 h2c_parameter[3] << 8 | h2c_parameter[4]);
1142
1143 btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
1144}
1145
1146static void btc8723b2ant_sw_mechanism1(struct btc_coexist *btcoexist,
1147 bool shrink_rx_lpf, bool low_penalty_ra,
1148 bool limited_dig, bool bt_lna_constrain)
1149{
1150 btc8723b2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf);
1151 btc8723b2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
1152}
1153
1154static void btc8723b2ant_sw_mechanism2(struct btc_coexist *btcoexist,
1155 bool agc_table_shift, bool adc_backoff,
1156 bool sw_dac_swing, u32 dac_swing_lvl)
1157{
1158 btc8723b2ant_agc_table(btcoexist, NORMAL_EXEC, agc_table_shift);
1159 btc8723b2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing,
1160 dac_swing_lvl);
1161}
1162
1163static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec,
1164 bool turn_on, u8 type)
1165{
1166 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1167 "[BTCoex], %s turn %s PS TDMA, type=%d\n",
1168 (force_exec ? "force to" : ""),
1169 (turn_on ? "ON" : "OFF"), type);
1170 coex_dm->cur_ps_tdma_on = turn_on;
1171 coex_dm->cur_ps_tdma = type;
1172
1173 if (!force_exec) {
1174 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1175 "[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n",
1176 coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on);
1177 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1178 "[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n",
1179 coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma);
1180
1181 if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
1182 (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
1183 return;
1184 }
1185 if (turn_on) {
1186 switch (type) {
1187 case 1:
1188 default:
1189 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
1190 0x1a, 0xe1, 0x90);
1191 break;
1192 case 2:
1193 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
1194 0x12, 0xe1, 0x90);
1195 break;
1196 case 3:
1197 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
1198 0x3, 0xf1, 0x90);
1199 break;
1200 case 4:
1201 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10,
1202 0x03, 0xf1, 0x90);
1203 break;
1204 case 5:
1205 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
1206 0x1a, 0x60, 0x90);
1207 break;
1208 case 6:
1209 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
1210 0x12, 0x60, 0x90);
1211 break;
1212 case 7:
1213 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
1214 0x3, 0x70, 0x90);
1215 break;
1216 case 8:
1217 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x10,
1218 0x3, 0x70, 0x90);
1219 break;
1220 case 9:
1221 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
1222 0x1a, 0xe1, 0x90);
1223 break;
1224 case 10:
1225 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
1226 0x12, 0xe1, 0x90);
1227 break;
1228 case 11:
1229 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
1230 0xa, 0xe1, 0x90);
1231 break;
1232 case 12:
1233 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
1234 0x5, 0xe1, 0x90);
1235 break;
1236 case 13:
1237 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
1238 0x1a, 0x60, 0x90);
1239 break;
1240 case 14:
1241 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
1242 0x12, 0x60, 0x90);
1243 break;
1244 case 15:
1245 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
1246 0xa, 0x60, 0x90);
1247 break;
1248 case 16:
1249 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
1250 0x5, 0x60, 0x90);
1251 break;
1252 case 17:
1253 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x2f,
1254 0x2f, 0x60, 0x90);
1255 break;
1256 case 18:
1257 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
1258 0x5, 0xe1, 0x90);
1259 break;
1260 case 19:
1261 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
1262 0x25, 0xe1, 0x90);
1263 break;
1264 case 20:
1265 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
1266 0x25, 0x60, 0x90);
1267 break;
1268 case 21:
1269 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15,
1270 0x03, 0x70, 0x90);
1271 break;
1272 case 71:
1273 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
1274 0x1a, 0xe1, 0x90);
1275 break;
1276 }
1277 } else {
1278 /* disable PS tdma */
1279 switch (type) {
1280 case 0:
1281 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
1282 0x40, 0x0);
1283 break;
1284 case 1:
1285 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
1286 0x48, 0x0);
1287 break;
1288 default:
1289 btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
1290 0x40, 0x0);
1291 break;
1292 }
1293 }
1294
1295 /* update pre state */
1296 coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
1297 coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
1298}
1299
1300static void btc8723b2ant_coex_alloff(struct btc_coexist *btcoexist)
1301{
1302 /* fw all off */
1303 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1304 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1305 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1306
1307 /* sw all off */
1308 btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false);
1309 btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
1310
1311 /* hw all off */
1312 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
1313 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0);
1314}
1315
1316static void btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist)
1317{
1318 /* force to reset coex mechanism*/
1319
1320 btc8723b2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1);
1321 btc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6);
1322 btc8723b2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, false);
1323
1324 btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false);
1325 btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
1326}
1327
1328static void btc8723b2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
1329{
1330 bool wifi_connected = false;
1331 bool low_pwr_disable = true;
1332
1333 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1334 &low_pwr_disable);
1335 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1336 &wifi_connected);
1337
1338 if (wifi_connected) {
1339 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
1340 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1341 } else {
1342 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0);
1343 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1344 }
1345 btc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6);
1346 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1347
1348 btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false);
1349 btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
1350
1351 coex_dm->need_recover_0x948 = true;
1352 coex_dm->backup_0x948 = btcoexist->btc_read_2byte(btcoexist, 0x948);
1353
1354 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
1355}
1356
1357static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist)
1358{
1359 bool common = false, wifi_connected = false;
1360 bool wifi_busy = false;
1361 bool bt_hs_on = false, low_pwr_disable = false;
1362
1363 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
1364 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1365 &wifi_connected);
1366 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1367
1368 if (!wifi_connected) {
1369 low_pwr_disable = false;
1370 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1371 &low_pwr_disable);
1372
1373 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1374 "[BTCoex], Wifi non-connected idle!!\n");
1375
1376 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff,
1377 0x0);
1378 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0);
1379 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1380 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1381 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1382
1383 btc8723b2ant_sw_mechanism1(btcoexist, false, false, false,
1384 false);
1385 btc8723b2ant_sw_mechanism2(btcoexist, false, false, false,
1386 0x18);
1387
1388 common = true;
1389 } else {
1390 if (BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
1391 coex_dm->bt_status) {
1392 low_pwr_disable = false;
1393 btcoexist->btc_set(btcoexist,
1394 BTC_SET_ACT_DISABLE_LOW_POWER,
1395 &low_pwr_disable);
1396
1397 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1398 "[BTCoex], Wifi connected + "
1399 "BT non connected-idle!!\n");
1400
1401 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1,
1402 0xfffff, 0x0);
1403 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0);
1404 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1405 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC,
1406 0xb);
1407 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
1408 false);
1409
1410 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
1411 false, false);
1412 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
1413 false, 0x18);
1414
1415 common = true;
1416 } else if (BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE ==
1417 coex_dm->bt_status) {
1418 low_pwr_disable = true;
1419 btcoexist->btc_set(btcoexist,
1420 BTC_SET_ACT_DISABLE_LOW_POWER,
1421 &low_pwr_disable);
1422
1423 if (bt_hs_on)
1424 return false;
1425 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1426 "[BTCoex], Wifi connected + "
1427 "BT connected-idle!!\n");
1428
1429 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1,
1430 0xfffff, 0x0);
1431 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0);
1432 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1433 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC,
1434 0xb);
1435 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
1436 false);
1437
1438 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
1439 false, false);
1440 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
1441 false, 0x18);
1442
1443 common = true;
1444 } else {
1445 low_pwr_disable = true;
1446 btcoexist->btc_set(btcoexist,
1447 BTC_SET_ACT_DISABLE_LOW_POWER,
1448 &low_pwr_disable);
1449
1450 if (wifi_busy) {
1451 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1452 "[BTCoex], Wifi Connected-Busy + "
1453 "BT Busy!!\n");
1454 common = false;
1455 } else {
1456 if (bt_hs_on)
1457 return false;
1458
1459 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1460 "[BTCoex], Wifi Connected-Idle + "
1461 "BT Busy!!\n");
1462
1463 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A,
1464 0x1, 0xfffff, 0x0);
1465 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC,
1466 7);
1467 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1468 true, 21);
1469 btc8723b2ant_fw_dac_swing_lvl(btcoexist,
1470 NORMAL_EXEC,
1471 0xb);
1472 if (btc8723b_need_dec_pwr(btcoexist))
1473 btc8723b2ant_dec_bt_pwr(btcoexist,
1474 NORMAL_EXEC,
1475 true);
1476 else
1477 btc8723b2ant_dec_bt_pwr(btcoexist,
1478 NORMAL_EXEC,
1479 false);
1480 btc8723b2ant_sw_mechanism1(btcoexist, false,
1481 false, false,
1482 false);
1483 btc8723b2ant_sw_mechanism2(btcoexist, false,
1484 false, false,
1485 0x18);
1486 common = true;
1487 }
1488 }
1489 }
1490
1491 return common;
1492}
1493
1494static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause,
1495 s32 result)
1496{
1497 /* Set PS TDMA for max interval == 1 */
1498 if (tx_pause) {
1499 BTC_PRINT(BTC_MSG_ALGORITHM,
1500 ALGO_TRACE_FW_DETAIL,
1501 "[BTCoex], TxPause = 1\n");
1502
1503 if (coex_dm->cur_ps_tdma == 71) {
1504 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1505 true, 5);
1506 coex_dm->tdma_adj_type = 5;
1507 } else if (coex_dm->cur_ps_tdma == 1) {
1508 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1509 true, 5);
1510 coex_dm->tdma_adj_type = 5;
1511 } else if (coex_dm->cur_ps_tdma == 2) {
1512 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1513 true, 6);
1514 coex_dm->tdma_adj_type = 6;
1515 } else if (coex_dm->cur_ps_tdma == 3) {
1516 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1517 true, 7);
1518 coex_dm->tdma_adj_type = 7;
1519 } else if (coex_dm->cur_ps_tdma == 4) {
1520 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1521 true, 8);
1522 coex_dm->tdma_adj_type = 8;
1523 } else if (coex_dm->cur_ps_tdma == 9) {
1524 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1525 true, 13);
1526 coex_dm->tdma_adj_type = 13;
1527 } else if (coex_dm->cur_ps_tdma == 10) {
1528 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1529 true, 14);
1530 coex_dm->tdma_adj_type = 14;
1531 } else if (coex_dm->cur_ps_tdma == 11) {
1532 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1533 true, 15);
1534 coex_dm->tdma_adj_type = 15;
1535 } else if (coex_dm->cur_ps_tdma == 12) {
1536 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1537 true, 16);
1538 coex_dm->tdma_adj_type = 16;
1539 }
1540
1541 if (result == -1) {
1542 if (coex_dm->cur_ps_tdma == 5) {
1543 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1544 true, 6);
1545 coex_dm->tdma_adj_type = 6;
1546 } else if (coex_dm->cur_ps_tdma == 6) {
1547 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1548 true, 7);
1549 coex_dm->tdma_adj_type = 7;
1550 } else if (coex_dm->cur_ps_tdma == 7) {
1551 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1552 true, 8);
1553 coex_dm->tdma_adj_type = 8;
1554 } else if (coex_dm->cur_ps_tdma == 13) {
1555 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1556 true, 14);
1557 coex_dm->tdma_adj_type = 14;
1558 } else if (coex_dm->cur_ps_tdma == 14) {
1559 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1560 true, 15);
1561 coex_dm->tdma_adj_type = 15;
1562 } else if (coex_dm->cur_ps_tdma == 15) {
1563 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1564 true, 16);
1565 coex_dm->tdma_adj_type = 16;
1566 }
1567 } else if (result == 1) {
1568 if (coex_dm->cur_ps_tdma == 8) {
1569 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1570 true, 7);
1571 coex_dm->tdma_adj_type = 7;
1572 } else if (coex_dm->cur_ps_tdma == 7) {
1573 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1574 true, 6);
1575 coex_dm->tdma_adj_type = 6;
1576 } else if (coex_dm->cur_ps_tdma == 6) {
1577 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1578 true, 5);
1579 coex_dm->tdma_adj_type = 5;
1580 } else if (coex_dm->cur_ps_tdma == 16) {
1581 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1582 true, 15);
1583 coex_dm->tdma_adj_type = 15;
1584 } else if (coex_dm->cur_ps_tdma == 15) {
1585 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1586 true, 14);
1587 coex_dm->tdma_adj_type = 14;
1588 } else if (coex_dm->cur_ps_tdma == 14) {
1589 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1590 true, 13);
1591 coex_dm->tdma_adj_type = 13;
1592 }
1593 }
1594 } else {
1595 BTC_PRINT(BTC_MSG_ALGORITHM,
1596 ALGO_TRACE_FW_DETAIL,
1597 "[BTCoex], TxPause = 0\n");
1598 if (coex_dm->cur_ps_tdma == 5) {
1599 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 71);
1600 coex_dm->tdma_adj_type = 71;
1601 } else if (coex_dm->cur_ps_tdma == 6) {
1602 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2);
1603 coex_dm->tdma_adj_type = 2;
1604 } else if (coex_dm->cur_ps_tdma == 7) {
1605 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1606 coex_dm->tdma_adj_type = 3;
1607 } else if (coex_dm->cur_ps_tdma == 8) {
1608 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4);
1609 coex_dm->tdma_adj_type = 4;
1610 } else if (coex_dm->cur_ps_tdma == 13) {
1611 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
1612 coex_dm->tdma_adj_type = 9;
1613 } else if (coex_dm->cur_ps_tdma == 14) {
1614 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
1615 coex_dm->tdma_adj_type = 10;
1616 } else if (coex_dm->cur_ps_tdma == 15) {
1617 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1618 coex_dm->tdma_adj_type = 11;
1619 } else if (coex_dm->cur_ps_tdma == 16) {
1620 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12);
1621 coex_dm->tdma_adj_type = 12;
1622 }
1623
1624 if (result == -1) {
1625 if (coex_dm->cur_ps_tdma == 71) {
1626 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1627 true, 1);
1628 coex_dm->tdma_adj_type = 1;
1629 } else if (coex_dm->cur_ps_tdma == 1) {
1630 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1631 true, 2);
1632 coex_dm->tdma_adj_type = 2;
1633 } else if (coex_dm->cur_ps_tdma == 2) {
1634 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1635 true, 3);
1636 coex_dm->tdma_adj_type = 3;
1637 } else if (coex_dm->cur_ps_tdma == 3) {
1638 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1639 true, 4);
1640 coex_dm->tdma_adj_type = 4;
1641 } else if (coex_dm->cur_ps_tdma == 9) {
1642 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1643 true, 10);
1644 coex_dm->tdma_adj_type = 10;
1645 } else if (coex_dm->cur_ps_tdma == 10) {
1646 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1647 true, 11);
1648 coex_dm->tdma_adj_type = 11;
1649 } else if (coex_dm->cur_ps_tdma == 11) {
1650 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1651 true, 12);
1652 coex_dm->tdma_adj_type = 12;
1653 }
1654 } else if (result == 1) {
1655 int tmp = coex_dm->cur_ps_tdma;
1656 switch (tmp) {
1657 case 4:
1658 case 3:
1659 case 2:
1660 case 12:
1661 case 11:
1662 case 10:
1663 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1664 true, tmp - 1);
1665 coex_dm->tdma_adj_type = tmp - 1;
1666 break;
1667 case 1:
1668 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1669 true, 71);
1670 coex_dm->tdma_adj_type = 71;
1671 break;
1672 }
1673 }
1674 }
1675}
1676
1677static void set_tdma_int2(struct btc_coexist *btcoexist, bool tx_pause,
1678 s32 result)
1679{
1680 /* Set PS TDMA for max interval == 2 */
1681 if (tx_pause) {
1682 BTC_PRINT(BTC_MSG_ALGORITHM,
1683 ALGO_TRACE_FW_DETAIL,
1684 "[BTCoex], TxPause = 1\n");
1685 if (coex_dm->cur_ps_tdma == 1) {
1686 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6);
1687 coex_dm->tdma_adj_type = 6;
1688 } else if (coex_dm->cur_ps_tdma == 2) {
1689 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6);
1690 coex_dm->tdma_adj_type = 6;
1691 } else if (coex_dm->cur_ps_tdma == 3) {
1692 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7);
1693 coex_dm->tdma_adj_type = 7;
1694 } else if (coex_dm->cur_ps_tdma == 4) {
1695 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8);
1696 coex_dm->tdma_adj_type = 8;
1697 } else if (coex_dm->cur_ps_tdma == 9) {
1698 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1699 coex_dm->tdma_adj_type = 14;
1700 } else if (coex_dm->cur_ps_tdma == 10) {
1701 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1702 coex_dm->tdma_adj_type = 14;
1703 } else if (coex_dm->cur_ps_tdma == 11) {
1704 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15);
1705 coex_dm->tdma_adj_type = 15;
1706 } else if (coex_dm->cur_ps_tdma == 12) {
1707 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 16);
1708 coex_dm->tdma_adj_type = 16;
1709 }
1710 if (result == -1) {
1711 if (coex_dm->cur_ps_tdma == 5) {
1712 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1713 true, 6);
1714 coex_dm->tdma_adj_type = 6;
1715 } else if (coex_dm->cur_ps_tdma == 6) {
1716 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1717 true, 7);
1718 coex_dm->tdma_adj_type = 7;
1719 } else if (coex_dm->cur_ps_tdma == 7) {
1720 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1721 true, 8);
1722 coex_dm->tdma_adj_type = 8;
1723 } else if (coex_dm->cur_ps_tdma == 13) {
1724 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1725 true, 14);
1726 coex_dm->tdma_adj_type = 14;
1727 } else if (coex_dm->cur_ps_tdma == 14) {
1728 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1729 true, 15);
1730 coex_dm->tdma_adj_type = 15;
1731 } else if (coex_dm->cur_ps_tdma == 15) {
1732 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1733 true, 16);
1734 coex_dm->tdma_adj_type = 16;
1735 }
1736 } else if (result == 1) {
1737 if (coex_dm->cur_ps_tdma == 8) {
1738 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1739 true, 7);
1740 coex_dm->tdma_adj_type = 7;
1741 } else if (coex_dm->cur_ps_tdma == 7) {
1742 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1743 true, 6);
1744 coex_dm->tdma_adj_type = 6;
1745 } else if (coex_dm->cur_ps_tdma == 6) {
1746 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1747 true, 6);
1748 coex_dm->tdma_adj_type = 6;
1749 } else if (coex_dm->cur_ps_tdma == 16) {
1750 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1751 true, 15);
1752 coex_dm->tdma_adj_type = 15;
1753 } else if (coex_dm->cur_ps_tdma == 15) {
1754 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1755 true, 14);
1756 coex_dm->tdma_adj_type = 14;
1757 } else if (coex_dm->cur_ps_tdma == 14) {
1758 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1759 true, 14);
1760 coex_dm->tdma_adj_type = 14;
1761 }
1762 }
1763 } else {
1764 BTC_PRINT(BTC_MSG_ALGORITHM,
1765 ALGO_TRACE_FW_DETAIL,
1766 "[BTCoex], TxPause = 0\n");
1767 if (coex_dm->cur_ps_tdma == 5) {
1768 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2);
1769 coex_dm->tdma_adj_type = 2;
1770 } else if (coex_dm->cur_ps_tdma == 6) {
1771 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2);
1772 coex_dm->tdma_adj_type = 2;
1773 } else if (coex_dm->cur_ps_tdma == 7) {
1774 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1775 coex_dm->tdma_adj_type = 3;
1776 } else if (coex_dm->cur_ps_tdma == 8) {
1777 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4);
1778 coex_dm->tdma_adj_type = 4;
1779 } else if (coex_dm->cur_ps_tdma == 13) {
1780 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
1781 coex_dm->tdma_adj_type = 10;
1782 } else if (coex_dm->cur_ps_tdma == 14) {
1783 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
1784 coex_dm->tdma_adj_type = 10;
1785 } else if (coex_dm->cur_ps_tdma == 15) {
1786 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1787 coex_dm->tdma_adj_type = 11;
1788 } else if (coex_dm->cur_ps_tdma == 16) {
1789 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12);
1790 coex_dm->tdma_adj_type = 12;
1791 }
1792 if (result == -1) {
1793 if (coex_dm->cur_ps_tdma == 1) {
1794 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1795 true, 2);
1796 coex_dm->tdma_adj_type = 2;
1797 } else if (coex_dm->cur_ps_tdma == 2) {
1798 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1799 true, 3);
1800 coex_dm->tdma_adj_type = 3;
1801 } else if (coex_dm->cur_ps_tdma == 3) {
1802 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1803 true, 4);
1804 coex_dm->tdma_adj_type = 4;
1805 } else if (coex_dm->cur_ps_tdma == 9) {
1806 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1807 true, 10);
1808 coex_dm->tdma_adj_type = 10;
1809 } else if (coex_dm->cur_ps_tdma == 10) {
1810 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1811 true, 11);
1812 coex_dm->tdma_adj_type = 11;
1813 } else if (coex_dm->cur_ps_tdma == 11) {
1814 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1815 true, 12);
1816 coex_dm->tdma_adj_type = 12;
1817 }
1818 } else if (result == 1) {
1819 if (coex_dm->cur_ps_tdma == 4) {
1820 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1821 true, 3);
1822 coex_dm->tdma_adj_type = 3;
1823 } else if (coex_dm->cur_ps_tdma == 3) {
1824 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1825 true, 2);
1826 coex_dm->tdma_adj_type = 2;
1827 } else if (coex_dm->cur_ps_tdma == 2) {
1828 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1829 true, 2);
1830 coex_dm->tdma_adj_type = 2;
1831 } else if (coex_dm->cur_ps_tdma == 12) {
1832 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1833 true, 11);
1834 coex_dm->tdma_adj_type = 11;
1835 } else if (coex_dm->cur_ps_tdma == 11) {
1836 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1837 true, 10);
1838 coex_dm->tdma_adj_type = 10;
1839 } else if (coex_dm->cur_ps_tdma == 10) {
1840 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1841 true, 10);
1842 coex_dm->tdma_adj_type = 10;
1843 }
1844 }
1845 }
1846}
1847
1848static void set_tdma_int3(struct btc_coexist *btcoexist, bool tx_pause,
1849 s32 result)
1850{
1851 /* Set PS TDMA for max interval == 3 */
1852 if (tx_pause) {
1853 BTC_PRINT(BTC_MSG_ALGORITHM,
1854 ALGO_TRACE_FW_DETAIL,
1855 "[BTCoex], TxPause = 1\n");
1856 if (coex_dm->cur_ps_tdma == 1) {
1857 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7);
1858 coex_dm->tdma_adj_type = 7;
1859 } else if (coex_dm->cur_ps_tdma == 2) {
1860 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7);
1861 coex_dm->tdma_adj_type = 7;
1862 } else if (coex_dm->cur_ps_tdma == 3) {
1863 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7);
1864 coex_dm->tdma_adj_type = 7;
1865 } else if (coex_dm->cur_ps_tdma == 4) {
1866 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8);
1867 coex_dm->tdma_adj_type = 8;
1868 } else if (coex_dm->cur_ps_tdma == 9) {
1869 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15);
1870 coex_dm->tdma_adj_type = 15;
1871 } else if (coex_dm->cur_ps_tdma == 10) {
1872 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15);
1873 coex_dm->tdma_adj_type = 15;
1874 } else if (coex_dm->cur_ps_tdma == 11) {
1875 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15);
1876 coex_dm->tdma_adj_type = 15;
1877 } else if (coex_dm->cur_ps_tdma == 12) {
1878 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 16);
1879 coex_dm->tdma_adj_type = 16;
1880 }
1881 if (result == -1) {
1882 if (coex_dm->cur_ps_tdma == 5) {
1883 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1884 true, 7);
1885 coex_dm->tdma_adj_type = 7;
1886 } else if (coex_dm->cur_ps_tdma == 6) {
1887 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1888 true, 7);
1889 coex_dm->tdma_adj_type = 7;
1890 } else if (coex_dm->cur_ps_tdma == 7) {
1891 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1892 true, 8);
1893 coex_dm->tdma_adj_type = 8;
1894 } else if (coex_dm->cur_ps_tdma == 13) {
1895 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1896 true, 15);
1897 coex_dm->tdma_adj_type = 15;
1898 } else if (coex_dm->cur_ps_tdma == 14) {
1899 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1900 true, 15);
1901 coex_dm->tdma_adj_type = 15;
1902 } else if (coex_dm->cur_ps_tdma == 15) {
1903 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1904 true, 16);
1905 coex_dm->tdma_adj_type = 16;
1906 }
1907 } else if (result == 1) {
1908 if (coex_dm->cur_ps_tdma == 8) {
1909 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1910 true, 7);
1911 coex_dm->tdma_adj_type = 7;
1912 } else if (coex_dm->cur_ps_tdma == 7) {
1913 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1914 true, 7);
1915 coex_dm->tdma_adj_type = 7;
1916 } else if (coex_dm->cur_ps_tdma == 6) {
1917 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1918 true, 7);
1919 coex_dm->tdma_adj_type = 7;
1920 } else if (coex_dm->cur_ps_tdma == 16) {
1921 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1922 true, 15);
1923 coex_dm->tdma_adj_type = 15;
1924 } else if (coex_dm->cur_ps_tdma == 15) {
1925 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1926 true, 15);
1927 coex_dm->tdma_adj_type = 15;
1928 } else if (coex_dm->cur_ps_tdma == 14) {
1929 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1930 true, 15);
1931 coex_dm->tdma_adj_type = 15;
1932 }
1933 }
1934 } else {
1935 BTC_PRINT(BTC_MSG_ALGORITHM,
1936 ALGO_TRACE_FW_DETAIL,
1937 "[BTCoex], TxPause = 0\n");
1938 switch (coex_dm->cur_ps_tdma) {
1939 case 5:
1940 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1941 coex_dm->tdma_adj_type = 3;
1942 break;
1943 case 6:
1944 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1945 coex_dm->tdma_adj_type = 3;
1946 break;
1947 case 7:
1948 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1949 coex_dm->tdma_adj_type = 3;
1950 break;
1951 case 8:
1952 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4);
1953 coex_dm->tdma_adj_type = 4;
1954 break;
1955 case 13:
1956 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1957 coex_dm->tdma_adj_type = 11;
1958 break;
1959 case 14:
1960 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1961 coex_dm->tdma_adj_type = 11;
1962 break;
1963 case 15:
1964 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1965 coex_dm->tdma_adj_type = 11;
1966 break;
1967 case 16:
1968 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12);
1969 coex_dm->tdma_adj_type = 12;
1970 break;
1971 }
1972 if (result == -1) {
1973 switch (coex_dm->cur_ps_tdma) {
1974 case 1:
1975 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1976 true, 3);
1977 coex_dm->tdma_adj_type = 3;
1978 break;
1979 case 2:
1980 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1981 true, 3);
1982 coex_dm->tdma_adj_type = 3;
1983 break;
1984 case 3:
1985 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1986 true, 4);
1987 coex_dm->tdma_adj_type = 4;
1988 break;
1989 case 9:
1990 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1991 true, 11);
1992 coex_dm->tdma_adj_type = 11;
1993 break;
1994 case 10:
1995 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1996 true, 11);
1997 coex_dm->tdma_adj_type = 11;
1998 break;
1999 case 11:
2000 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2001 true, 12);
2002 coex_dm->tdma_adj_type = 12;
2003 break;
2004 }
2005 } else if (result == 1) {
2006 switch (coex_dm->cur_ps_tdma) {
2007 case 4:
2008 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2009 true, 3);
2010 coex_dm->tdma_adj_type = 3;
2011 break;
2012 case 3:
2013 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2014 true, 3);
2015 coex_dm->tdma_adj_type = 3;
2016 break;
2017 case 2:
2018 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2019 true, 3);
2020 coex_dm->tdma_adj_type = 3;
2021 break;
2022 case 12:
2023 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2024 true, 11);
2025 coex_dm->tdma_adj_type = 11;
2026 break;
2027 case 11:
2028 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2029 true, 11);
2030 coex_dm->tdma_adj_type = 11;
2031 break;
2032 case 10:
2033 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2034 true, 11);
2035 coex_dm->tdma_adj_type = 11;
2036 }
2037 }
2038 }
2039}
2040
2041static void btc8723b2ant_tdma_duration_adjust(struct btc_coexist *btcoexist,
2042 bool sco_hid, bool tx_pause,
2043 u8 max_interval)
2044{
2045 static s32 up, dn, m, n, wait_count;
2046 /*0: no change, +1: increase WiFi duration, -1: decrease WiFi duration*/
2047 s32 result;
2048 u8 retry_count = 0;
2049
2050 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
2051 "[BTCoex], TdmaDurationAdjust()\n");
2052
2053 if (!coex_dm->auto_tdma_adjust) {
2054 coex_dm->auto_tdma_adjust = true;
2055 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2056 "[BTCoex], first run TdmaDurationAdjust()!!\n");
2057 if (sco_hid) {
2058 if (tx_pause) {
2059 if (max_interval == 1) {
2060 btc8723b2ant_ps_tdma(btcoexist,
2061 NORMAL_EXEC,
2062 true, 13);
2063 coex_dm->tdma_adj_type = 13;
2064 } else if (max_interval == 2) {
2065 btc8723b2ant_ps_tdma(btcoexist,
2066 NORMAL_EXEC,
2067 true, 14);
2068 coex_dm->tdma_adj_type = 14;
2069 } else if (max_interval == 3) {
2070 btc8723b2ant_ps_tdma(btcoexist,
2071 NORMAL_EXEC,
2072 true, 15);
2073 coex_dm->tdma_adj_type = 15;
2074 } else {
2075 btc8723b2ant_ps_tdma(btcoexist,
2076 NORMAL_EXEC,
2077 true, 15);
2078 coex_dm->tdma_adj_type = 15;
2079 }
2080 } else {
2081 if (max_interval == 1) {
2082 btc8723b2ant_ps_tdma(btcoexist,
2083 NORMAL_EXEC,
2084 true, 9);
2085 coex_dm->tdma_adj_type = 9;
2086 } else if (max_interval == 2) {
2087 btc8723b2ant_ps_tdma(btcoexist,
2088 NORMAL_EXEC,
2089 true, 10);
2090 coex_dm->tdma_adj_type = 10;
2091 } else if (max_interval == 3) {
2092 btc8723b2ant_ps_tdma(btcoexist,
2093 NORMAL_EXEC,
2094 true, 11);
2095 coex_dm->tdma_adj_type = 11;
2096 } else {
2097 btc8723b2ant_ps_tdma(btcoexist,
2098 NORMAL_EXEC,
2099 true, 11);
2100 coex_dm->tdma_adj_type = 11;
2101 }
2102 }
2103 } else {
2104 if (tx_pause) {
2105 if (max_interval == 1) {
2106 btc8723b2ant_ps_tdma(btcoexist,
2107 NORMAL_EXEC,
2108 true, 5);
2109 coex_dm->tdma_adj_type = 5;
2110 } else if (max_interval == 2) {
2111 btc8723b2ant_ps_tdma(btcoexist,
2112 NORMAL_EXEC,
2113 true, 6);
2114 coex_dm->tdma_adj_type = 6;
2115 } else if (max_interval == 3) {
2116 btc8723b2ant_ps_tdma(btcoexist,
2117 NORMAL_EXEC,
2118 true, 7);
2119 coex_dm->tdma_adj_type = 7;
2120 } else {
2121 btc8723b2ant_ps_tdma(btcoexist,
2122 NORMAL_EXEC,
2123 true, 7);
2124 coex_dm->tdma_adj_type = 7;
2125 }
2126 } else {
2127 if (max_interval == 1) {
2128 btc8723b2ant_ps_tdma(btcoexist,
2129 NORMAL_EXEC,
2130 true, 1);
2131 coex_dm->tdma_adj_type = 1;
2132 } else if (max_interval == 2) {
2133 btc8723b2ant_ps_tdma(btcoexist,
2134 NORMAL_EXEC,
2135 true, 2);
2136 coex_dm->tdma_adj_type = 2;
2137 } else if (max_interval == 3) {
2138 btc8723b2ant_ps_tdma(btcoexist,
2139 NORMAL_EXEC,
2140 true, 3);
2141 coex_dm->tdma_adj_type = 3;
2142 } else {
2143 btc8723b2ant_ps_tdma(btcoexist,
2144 NORMAL_EXEC,
2145 true, 3);
2146 coex_dm->tdma_adj_type = 3;
2147 }
2148 }
2149 }
2150
2151 up = 0;
2152 dn = 0;
2153 m = 1;
2154 n = 3;
2155 result = 0;
2156 wait_count = 0;
2157 } else {
2158 /*accquire the BT TRx retry count from BT_Info byte2*/
2159 retry_count = coex_sta->bt_retry_cnt;
2160 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2161 "[BTCoex], retry_count = %d\n", retry_count);
2162 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2163 "[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_count=%d\n",
2164 up, dn, m, n, wait_count);
2165 result = 0;
2166 wait_count++;
2167 /* no retry in the last 2-second duration*/
2168 if (retry_count == 0) {
2169 up++;
2170 dn--;
2171
2172 if (dn <= 0)
2173 dn = 0;
2174
2175 if (up >= n) {
2176 wait_count = 0;
2177 n = 3;
2178 up = 0;
2179 dn = 0;
2180 result = 1;
2181 BTC_PRINT(BTC_MSG_ALGORITHM,
2182 ALGO_TRACE_FW_DETAIL,
2183 "[BTCoex], Increase wifi "
2184 "duration!!\n");
2185 } /* <=3 retry in the last 2-second duration*/
2186 } else if (retry_count <= 3) {
2187 up--;
2188 dn++;
2189
2190 if (up <= 0)
2191 up = 0;
2192
2193 if (dn == 2) {
2194 if (wait_count <= 2)
2195 m++;
2196 else
2197 m = 1;
2198
2199 if (m >= 20)
2200 m = 20;
2201
2202 n = 3 * m;
2203 up = 0;
2204 dn = 0;
2205 wait_count = 0;
2206 result = -1;
2207 BTC_PRINT(BTC_MSG_ALGORITHM,
2208 ALGO_TRACE_FW_DETAIL,
2209 "[BTCoex], Decrease wifi duration "
2210 "for retry_counter<3!!\n");
2211 }
2212 } else {
2213 if (wait_count == 1)
2214 m++;
2215 else
2216 m = 1;
2217
2218 if (m >= 20)
2219 m = 20;
2220
2221 n = 3 * m;
2222 up = 0;
2223 dn = 0;
2224 wait_count = 0;
2225 result = -1;
2226 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2227 "[BTCoex], Decrease wifi duration "
2228 "for retry_counter>3!!\n");
2229 }
2230
2231 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2232 "[BTCoex], max Interval = %d\n", max_interval);
2233 if (max_interval == 1)
2234 set_tdma_int1(btcoexist, tx_pause, result);
2235 else if (max_interval == 2)
2236 set_tdma_int2(btcoexist, tx_pause, result);
2237 else if (max_interval == 3)
2238 set_tdma_int3(btcoexist, tx_pause, result);
2239 }
2240
2241 /*if current PsTdma not match with the recorded one (when scan, dhcp..),
2242 *then we have to adjust it back to the previous recorded one.
2243 */
2244 if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) {
2245 bool scan = false, link = false, roam = false;
2246 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2247 "[BTCoex], PsTdma type dismatch!!!, "
2248 "curPsTdma=%d, recordPsTdma=%d\n",
2249 coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type);
2250
2251 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2252 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2253 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2254
2255 if (!scan && !link && !roam)
2256 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
2257 coex_dm->tdma_adj_type);
2258 else
2259 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2260 "[BTCoex], roaming/link/scan is under"
2261 " progress, will adjust next time!!!\n");
2262 }
2263}
2264
2265/* SCO only or SCO+PAN(HS) */
2266static void btc8723b2ant_action_sco(struct btc_coexist *btcoexist)
2267{
2268 u8 wifi_rssi_state;
2269 u32 wifi_bw;
2270
2271 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2272 0, 2, 15, 0);
2273
2274 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2275
2276 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4);
2277
2278 if (btc8723b_need_dec_pwr(btcoexist))
2279 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2280 else
2281 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2282
2283 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2284
2285 /*for SCO quality at 11b/g mode*/
2286 if (BTC_WIFI_BW_LEGACY == wifi_bw)
2287 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 2);
2288 else /*for SCO quality & wifi performance balance at 11n mode*/
2289 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 8);
2290
2291 /*for voice quality */
2292 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
2293
2294 /* sw mechanism */
2295 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2296 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2297 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2298 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2299 false, false);
2300 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2301 true, 0x4);
2302 } else {
2303 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2304 false, false);
2305 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2306 true, 0x4);
2307 }
2308 } else {
2309 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2310 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2311 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2312 false, false);
2313 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2314 true, 0x4);
2315 } else {
2316 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2317 false, false);
2318 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2319 true, 0x4);
2320 }
2321 }
2322}
2323
2324static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist)
2325{
2326 u8 wifi_rssi_state, bt_rssi_state;
2327 u32 wifi_bw;
2328
2329 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2330 0, 2, 15, 0);
2331 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0);
2332
2333 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2334
2335 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2336
2337 if (btc8723b_need_dec_pwr(btcoexist))
2338 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2339 else
2340 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2341
2342 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2343
2344 if (BTC_WIFI_BW_LEGACY == wifi_bw) /*/for HID at 11b/g mode*/
2345 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
2346 else /*for HID quality & wifi performance balance at 11n mode*/
2347 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 9);
2348
2349 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2350 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
2351 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
2352 else
2353 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
2354
2355 /* sw mechanism */
2356 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2357 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2358 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2359 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2360 false, false);
2361 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2362 false, 0x18);
2363 } else {
2364 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2365 false, false);
2366 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2367 false, 0x18);
2368 }
2369 } else {
2370 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2371 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2372 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2373 false, false);
2374 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2375 false, 0x18);
2376 } else {
2377 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2378 false, false);
2379 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2380 false, 0x18);
2381 }
2382 }
2383}
2384
2385/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/
2386static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist)
2387{
2388 u8 wifi_rssi_state, bt_rssi_state;
2389 u32 wifi_bw;
2390
2391 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2392 0, 2, 15, 0);
2393 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0);
2394
2395 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2396
2397 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2398
2399 if (btc8723b_need_dec_pwr(btcoexist))
2400 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2401 else
2402 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2403
2404 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
2405
2406 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2407 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
2408 btc8723b2ant_tdma_duration_adjust(btcoexist, false,
2409 false, 1);
2410 else
2411 btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 1);
2412
2413 /* sw mechanism */
2414 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2415 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2416 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2417 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2418 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2419 false, false);
2420 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2421 false, 0x18);
2422 } else {
2423 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2424 false, false);
2425 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2426 false, 0x18);
2427 }
2428 } else {
2429 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2430 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2431 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2432 false, false);
2433 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2434 false, 0x18);
2435 } else {
2436 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2437 false, false);
2438 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2439 false, 0x18);
2440 }
2441 }
2442}
2443
2444static void btc8723b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
2445{
2446 u8 wifi_rssi_state;
2447 u32 wifi_bw;
2448
2449 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2450 0, 2, 15, 0);
2451
2452 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2453
2454 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2455
2456 if (btc8723b_need_dec_pwr(btcoexist))
2457 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2458 else
2459 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2460
2461 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
2462
2463 btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 2);
2464
2465 /* sw mechanism */
2466 btcoexist->btc_get(btcoexist,
2467 BTC_GET_U4_WIFI_BW, &wifi_bw);
2468 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2469 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2470 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2471 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2472 false, false);
2473 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2474 false, 0x18);
2475 } else {
2476 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2477 false, false);
2478 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2479 false, 0x18);
2480 }
2481 } else {
2482 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2483 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2484 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2485 false, false);
2486 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2487 false, 0x18);
2488 } else {
2489 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2490 false, false);
2491 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2492 false, 0x18);
2493 }
2494 }
2495}
2496
2497static void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist)
2498{
2499 u8 wifi_rssi_state, bt_rssi_state;
2500 u32 wifi_bw;
2501
2502 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2503 0, 2, 15, 0);
2504 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0);
2505
2506 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2507
2508 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2509
2510 if (btc8723b_need_dec_pwr(btcoexist))
2511 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2512 else
2513 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2514
2515 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 10);
2516
2517 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2518 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
2519 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1);
2520 else
2521 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
2522
2523 /* sw mechanism */
2524 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2525 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2526 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2527 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2528 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2529 false, false);
2530 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2531 false, 0x18);
2532 } else {
2533 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2534 false, false);
2535 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2536 false, 0x18);
2537 }
2538 } else {
2539 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2540 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2541 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2542 false, false);
2543 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2544 false, 0x18);
2545 } else {
2546 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2547 false, false);
2548 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2549 false, 0x18);
2550 }
2551 }
2552}
2553
2554/*PAN(HS) only*/
2555static void btc8723b2ant_action_pan_hs(struct btc_coexist *btcoexist)
2556{
2557 u8 wifi_rssi_state;
2558 u32 wifi_bw;
2559
2560 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2561 0, 2, 15, 0);
2562
2563 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2564
2565 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2566
2567 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2568 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
2569 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2570 else
2571 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2572
2573 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
2574
2575 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
2576
2577 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2578 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2579 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2580 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2581 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2582 false, false);
2583 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2584 false, 0x18);
2585 } else {
2586 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2587 false, false);
2588 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2589 false, 0x18);
2590 }
2591 } else {
2592 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2593 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2594 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2595 false, false);
2596 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2597 false, 0x18);
2598 } else {
2599 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2600 false, false);
2601 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2602 false, 0x18);
2603 }
2604 }
2605}
2606
2607/*PAN(EDR)+A2DP*/
2608static void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
2609{
2610 u8 wifi_rssi_state, bt_rssi_state;
2611 u32 wifi_bw;
2612
2613 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2614 0, 2, 15, 0);
2615 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0);
2616
2617 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2618
2619 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2620
2621 if (btc8723b_need_dec_pwr(btcoexist))
2622 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2623 else
2624 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2625
2626 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2627
2628 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2629 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2630 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 12);
2631 if (BTC_WIFI_BW_HT40 == wifi_bw)
2632 btc8723b2ant_tdma_duration_adjust(btcoexist, false,
2633 true, 3);
2634 else
2635 btc8723b2ant_tdma_duration_adjust(btcoexist, false,
2636 false, 3);
2637 } else {
2638 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
2639 btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 3);
2640 }
2641
2642 /* sw mechanism */
2643 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2644 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2645 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2646 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2647 false, false);
2648 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2649 false, 0x18);
2650 } else {
2651 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2652 false, false);
2653 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2654 false, 0x18);
2655 }
2656 } else {
2657 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2658 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2659 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2660 false, false);
2661 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2662 false, 0x18);
2663 } else {
2664 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2665 false, false);
2666 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2667 false, 0x18);
2668 }
2669 }
2670}
2671
2672static void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
2673{
2674 u8 wifi_rssi_state, bt_rssi_state;
2675 u32 wifi_bw;
2676
2677 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2678 0, 2, 15, 0);
2679 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0);
2680 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2681
2682 if (btc8723b_need_dec_pwr(btcoexist))
2683 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2684 else
2685 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2686
2687 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2688 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2689 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2690 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC,
2691 3);
2692 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 11);
2693 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1,
2694 0xfffff, 0x780);
2695 } else {
2696 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC,
2697 6);
2698 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
2699 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1,
2700 0xfffff, 0x0);
2701 }
2702 btc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2);
2703 } else {
2704 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2705 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 11);
2706 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff,
2707 0x0);
2708 btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2);
2709 }
2710
2711 /* sw mechanism */
2712 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2713 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2714 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2715 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2716 false, false);
2717 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2718 false, 0x18);
2719 } else {
2720 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2721 false, false);
2722 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2723 false, 0x18);
2724 }
2725 } else {
2726 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2727 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2728 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2729 false, false);
2730 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2731 false, 0x18);
2732 } else {
2733 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2734 false, false);
2735 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2736 false, 0x18);
2737 }
2738 }
2739}
2740
2741/* HID+A2DP+PAN(EDR) */
2742static void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
2743{
2744 u8 wifi_rssi_state, bt_rssi_state;
2745 u32 wifi_bw;
2746
2747 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2748 0, 2, 15, 0);
2749 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0);
2750
2751 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2752
2753 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2754
2755 if (btc8723b_need_dec_pwr(btcoexist))
2756 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2757 else
2758 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2759
2760 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2761
2762 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
2763
2764 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2765 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2766 if (BTC_WIFI_BW_HT40 == wifi_bw)
2767 btc8723b2ant_tdma_duration_adjust(btcoexist, true,
2768 true, 2);
2769 else
2770 btc8723b2ant_tdma_duration_adjust(btcoexist, true,
2771 false, 3);
2772 } else {
2773 btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 3);
2774 }
2775
2776 /* sw mechanism */
2777 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2778 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2779 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2780 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2781 false, false);
2782 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2783 false, 0x18);
2784 } else {
2785 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2786 false, false);
2787 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2788 false, 0x18);
2789 }
2790 } else {
2791 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2792 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2793 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2794 false, false);
2795 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2796 false, 0x18);
2797 } else {
2798 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2799 false, false);
2800 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2801 false, 0x18);
2802 }
2803 }
2804}
2805
2806static void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
2807{
2808 u8 wifi_rssi_state, bt_rssi_state;
2809 u32 wifi_bw;
2810
2811 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2812 0, 2, 15, 0);
2813 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0);
2814
2815 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2816
2817 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2818
2819 if (btc8723b_need_dec_pwr(btcoexist))
2820 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2821 else
2822 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2823
2824 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2825
2826 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7);
2827
2828 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2829 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
2830 btc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2);
2831 else
2832 btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2);
2833
2834 /* sw mechanism */
2835 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2836 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2837 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2838 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2839 false, false);
2840 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2841 false, 0x18);
2842 } else {
2843 btc8723b2ant_sw_mechanism1(btcoexist, true, true,
2844 false, false);
2845 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2846 false, 0x18);
2847 }
2848 } else {
2849 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2850 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2851 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2852 false, false);
2853 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2854 false, 0x18);
2855 } else {
2856 btc8723b2ant_sw_mechanism1(btcoexist, false, true,
2857 false, false);
2858 btc8723b2ant_sw_mechanism2(btcoexist, false, false,
2859 false, 0x18);
2860 }
2861 }
2862}
2863
2864static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
2865{
2866 u8 algorithm = 0;
2867
2868 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2869 "[BTCoex], RunCoexistMechanism()===>\n");
2870
2871 if (btcoexist->manual_control) {
2872 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2873 "[BTCoex], RunCoexistMechanism(), "
2874 "return for Manual CTRL <===\n");
2875 return;
2876 }
2877
2878 if (coex_sta->under_ips) {
2879 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2880 "[BTCoex], wifi is under IPS !!!\n");
2881 return;
2882 }
2883
2884 algorithm = btc8723b2ant_action_algorithm(btcoexist);
2885 if (coex_sta->c2h_bt_inquiry_page &&
2886 (BT_8723B_2ANT_COEX_ALGO_PANHS != algorithm)) {
2887 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2888 "[BTCoex], BT is under inquiry/page scan !!\n");
2889 btc8723b2ant_action_bt_inquiry(btcoexist);
2890 return;
2891 } else {
2892 if (coex_dm->need_recover_0x948) {
2893 coex_dm->need_recover_0x948 = false;
2894 btcoexist->btc_write_2byte(btcoexist, 0x948,
2895 coex_dm->backup_0x948);
2896 }
2897 }
2898
2899 coex_dm->cur_algorithm = algorithm;
2900 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, "[BTCoex], Algorithm = %d\n",
2901 coex_dm->cur_algorithm);
2902
2903 if (btc8723b2ant_is_common_action(btcoexist)) {
2904 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2905 "[BTCoex], Action 2-Ant common.\n");
2906 coex_dm->auto_tdma_adjust = false;
2907 } else {
2908 if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) {
2909 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2910 "[BTCoex], preAlgorithm=%d, "
2911 "curAlgorithm=%d\n", coex_dm->pre_algorithm,
2912 coex_dm->cur_algorithm);
2913 coex_dm->auto_tdma_adjust = false;
2914 }
2915 switch (coex_dm->cur_algorithm) {
2916 case BT_8723B_2ANT_COEX_ALGO_SCO:
2917 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2918 "[BTCoex], Action 2-Ant, algorithm = SCO.\n");
2919 btc8723b2ant_action_sco(btcoexist);
2920 break;
2921 case BT_8723B_2ANT_COEX_ALGO_HID:
2922 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2923 "[BTCoex], Action 2-Ant, algorithm = HID.\n");
2924 btc8723b2ant_action_hid(btcoexist);
2925 break;
2926 case BT_8723B_2ANT_COEX_ALGO_A2DP:
2927 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2928 "[BTCoex], Action 2-Ant, "
2929 "algorithm = A2DP.\n");
2930 btc8723b2ant_action_a2dp(btcoexist);
2931 break;
2932 case BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS:
2933 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2934 "[BTCoex], Action 2-Ant, "
2935 "algorithm = A2DP+PAN(HS).\n");
2936 btc8723b2ant_action_a2dp_pan_hs(btcoexist);
2937 break;
2938 case BT_8723B_2ANT_COEX_ALGO_PANEDR:
2939 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2940 "[BTCoex], Action 2-Ant, "
2941 "algorithm = PAN(EDR).\n");
2942 btc8723b2ant_action_pan_edr(btcoexist);
2943 break;
2944 case BT_8723B_2ANT_COEX_ALGO_PANHS:
2945 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2946 "[BTCoex], Action 2-Ant, "
2947 "algorithm = HS mode.\n");
2948 btc8723b2ant_action_pan_hs(btcoexist);
2949 break;
2950 case BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP:
2951 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2952 "[BTCoex], Action 2-Ant, "
2953 "algorithm = PAN+A2DP.\n");
2954 btc8723b2ant_action_pan_edr_a2dp(btcoexist);
2955 break;
2956 case BT_8723B_2ANT_COEX_ALGO_PANEDR_HID:
2957 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2958 "[BTCoex], Action 2-Ant, "
2959 "algorithm = PAN(EDR)+HID.\n");
2960 btc8723b2ant_action_pan_edr_hid(btcoexist);
2961 break;
2962 case BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
2963 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2964 "[BTCoex], Action 2-Ant, "
2965 "algorithm = HID+A2DP+PAN.\n");
2966 btc8723b2ant_action_hid_a2dp_pan_edr(btcoexist);
2967 break;
2968 case BT_8723B_2ANT_COEX_ALGO_HID_A2DP:
2969 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2970 "[BTCoex], Action 2-Ant, "
2971 "algorithm = HID+A2DP.\n");
2972 btc8723b2ant_action_hid_a2dp(btcoexist);
2973 break;
2974 default:
2975 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2976 "[BTCoex], Action 2-Ant, "
2977 "algorithm = coexist All Off!!\n");
2978 btc8723b2ant_coex_alloff(btcoexist);
2979 break;
2980 }
2981 coex_dm->pre_algorithm = coex_dm->cur_algorithm;
2982 }
2983}
2984
2985
2986
2987/*********************************************************************
2988 * work around function start with wa_btc8723b2ant_
2989 *********************************************************************/
2990/*********************************************************************
2991 * extern function start with EXbtc8723b2ant_
2992 *********************************************************************/
2993void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist)
2994{
2995 struct btc_board_info *board_info = &btcoexist->board_info;
2996 u32 u32tmp = 0, fw_ver;
2997 u8 u8tmp = 0;
2998 u8 h2c_parameter[2] = {0};
2999
3000
3001 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3002 "[BTCoex], 2Ant Init HW Config!!\n");
3003
3004 /* backup rf 0x1e value */
3005 coex_dm->bt_rf0x1e_backup = btcoexist->btc_get_rf_reg(btcoexist,
3006 BTC_RF_A, 0x1e,
3007 0xfffff);
3008
3009 /* 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT */
3010 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
3011 u32tmp &= ~BIT23;
3012 u32tmp |= BIT24;
3013 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
3014
3015 btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
3016 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3);
3017 btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77);
3018 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1);
3019
3020 /* Antenna switch control parameter */
3021 /* btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555);*/
3022
3023 /*Force GNT_BT to low*/
3024 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
3025 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
3026
3027 /* 0x790[5:0]=0x5 */
3028 u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
3029 u8tmp &= 0xc0;
3030 u8tmp |= 0x5;
3031 btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp);
3032
3033
3034 /*Antenna config */
3035 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3036
3037 /*ext switch for fw ver < 0xc */
3038 if (fw_ver < 0xc00) {
3039 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
3040 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
3041 0x3, 0x1);
3042 /*Main Ant to BT for IPS case 0x4c[23]=1*/
3043 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1,
3044 0x1);
3045
3046 /*tell firmware "no antenna inverse"*/
3047 h2c_parameter[0] = 0;
3048 h2c_parameter[1] = 1; /* ext switch type */
3049 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
3050 h2c_parameter);
3051 } else {
3052 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
3053 0x3, 0x2);
3054 /*Aux Ant to BT for IPS case 0x4c[23]=1*/
3055 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1,
3056 0x0);
3057
3058 /*tell firmware "antenna inverse"*/
3059 h2c_parameter[0] = 1;
3060 h2c_parameter[1] = 1; /*ext switch type*/
3061 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
3062 h2c_parameter);
3063 }
3064 } else {
3065 /*ext switch always at s1 (if exist) */
3066 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, 0x3, 0x1);
3067 /*Main Ant to BT for IPS case 0x4c[23]=1*/
3068 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, 0x1);
3069
3070 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
3071 /*tell firmware "no antenna inverse"*/
3072 h2c_parameter[0] = 0;
3073 h2c_parameter[1] = 0; /*ext switch type*/
3074 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
3075 h2c_parameter);
3076 } else {
3077 /*tell firmware "antenna inverse"*/
3078 h2c_parameter[0] = 1;
3079 h2c_parameter[1] = 0; /*ext switch type*/
3080 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
3081 h2c_parameter);
3082 }
3083 }
3084
3085 /* PTA parameter */
3086 btc8723b_coex_tbl_type(btcoexist, FORCE_EXEC, 0);
3087
3088 /* Enable counter statistics */
3089 /*0x76e[3] =1, WLAN_Act control by PTA*/
3090 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
3091 btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3);
3092 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
3093}
3094
3095void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist)
3096{
3097 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3098 "[BTCoex], Coex Mechanism Init!!\n");
3099 btc8723b2ant_init_coex_dm(btcoexist);
3100}
3101
3102void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
3103{
3104 struct btc_board_info *board_info = &btcoexist->board_info;
3105 struct btc_stack_info *stack_info = &btcoexist->stack_info;
3106 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
3107 u8 *cli_buf = btcoexist->cli_buf;
3108 u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0;
3109 u32 u32tmp[4];
3110 bool roam = false, scan = false;
3111 bool link = false, wifi_under_5g = false;
3112 bool bt_hs_on = false, wifi_busy = false;
3113 s32 wifi_rssi = 0, bt_hs_rssi = 0;
3114 u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck;
3115 u8 wifi_dot11_chnl, wifi_hs_chnl;
3116 u32 fw_ver = 0, bt_patch_ver = 0;
3117
3118 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3119 "\r\n ============[BT Coexist info]============");
3120 CL_PRINTF(cli_buf);
3121
3122 if (btcoexist->manual_control) {
3123 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3124 "\r\n ==========[Under Manual Control]============");
3125 CL_PRINTF(cli_buf);
3126 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3127 "\r\n ==========================================");
3128 CL_PRINTF(cli_buf);
3129 }
3130
3131 if (!board_info->bt_exist) {
3132 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
3133 CL_PRINTF(cli_buf);
3134 return;
3135 }
3136
3137 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ",
3138 "Ant PG number/ Ant mechanism:",
3139 board_info->pg_ant_num, board_info->btdm_ant_num);
3140 CL_PRINTF(cli_buf);
3141
3142 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d",
3143 "BT stack/ hci ext ver",
3144 ((stack_info->profile_notified) ? "Yes" : "No"),
3145 stack_info->hci_version);
3146 CL_PRINTF(cli_buf);
3147
3148 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
3149 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3150 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3151 "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
3152 "CoexVer/ FwVer/ PatchVer",
3153 glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant,
3154 fw_ver, bt_patch_ver, bt_patch_ver);
3155 CL_PRINTF(cli_buf);
3156
3157 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
3158 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
3159 &wifi_dot11_chnl);
3160 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
3161
3162 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)",
3163 "Dot11 channel / HsChnl(HsMode)",
3164 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
3165 CL_PRINTF(cli_buf);
3166
3167 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ",
3168 "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0],
3169 coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]);
3170 CL_PRINTF(cli_buf);
3171
3172 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
3173 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
3174 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
3175 "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi);
3176 CL_PRINTF(cli_buf);
3177
3178 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
3179 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
3180 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
3181 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
3182 "Wifi link/ roam/ scan", link, roam, scan);
3183 CL_PRINTF(cli_buf);
3184
3185 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
3186 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
3187 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3188 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
3189 &wifi_traffic_dir);
3190 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ",
3191 "Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
3192 ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
3193 (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
3194 ((!wifi_busy) ? "idle" :
3195 ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
3196 "uplink" : "downlink")));
3197 CL_PRINTF(cli_buf);
3198
3199 CL_PRINTF(cli_buf);
3200
3201 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d",
3202 "SCO/HID/PAN/A2DP",
3203 bt_link_info->sco_exist, bt_link_info->hid_exist,
3204 bt_link_info->pan_exist, bt_link_info->a2dp_exist);
3205 CL_PRINTF(cli_buf);
3206 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
3207
3208 bt_info_ext = coex_sta->bt_info_ext;
3209 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s",
3210 "BT Info A2DP rate",
3211 (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
3212 CL_PRINTF(cli_buf);
3213
3214 for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) {
3215 if (coex_sta->bt_info_c2h_cnt[i]) {
3216 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3217 "\r\n %-35s = %02x %02x %02x "
3218 "%02x %02x %02x %02x(%d)",
3219 glbt_info_src_8723b_2ant[i],
3220 coex_sta->bt_info_c2h[i][0],
3221 coex_sta->bt_info_c2h[i][1],
3222 coex_sta->bt_info_c2h[i][2],
3223 coex_sta->bt_info_c2h[i][3],
3224 coex_sta->bt_info_c2h[i][4],
3225 coex_sta->bt_info_c2h[i][5],
3226 coex_sta->bt_info_c2h[i][6],
3227 coex_sta->bt_info_c2h_cnt[i]);
3228 CL_PRINTF(cli_buf);
3229 }
3230 }
3231
3232 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s",
3233 "PS state, IPS/LPS",
3234 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
3235 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
3236 CL_PRINTF(cli_buf);
3237 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
3238
3239 /* Sw mechanism */
3240 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3241 "\r\n %-35s", "============[Sw mechanism]============");
3242 CL_PRINTF(cli_buf);
3243 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
3244 "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink,
3245 coex_dm->cur_low_penalty_ra, coex_dm->limited_dig);
3246 CL_PRINTF(cli_buf);
3247 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
3248 "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
3249 coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
3250 coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
3251 CL_PRINTF(cli_buf);
3252
3253 /* Fw mechanism */
3254 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
3255 "============[Fw mechanism]============");
3256 CL_PRINTF(cli_buf);
3257
3258 ps_tdma_case = coex_dm->cur_ps_tdma;
3259 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3260 "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
3261 "PS TDMA", coex_dm->ps_tdma_para[0],
3262 coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2],
3263 coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4],
3264 ps_tdma_case, coex_dm->auto_tdma_adjust);
3265 CL_PRINTF(cli_buf);
3266
3267 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ",
3268 "DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr,
3269 coex_dm->cur_ignore_wlan_act);
3270 CL_PRINTF(cli_buf);
3271
3272 /* Hw setting */
3273 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
3274 "============[Hw setting]============");
3275 CL_PRINTF(cli_buf);
3276
3277 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x",
3278 "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup);
3279 CL_PRINTF(cli_buf);
3280
3281 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
3282 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880);
3283 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
3284 "0x778/0x880[29:25]", u8tmp[0],
3285 (u32tmp[0]&0x3e000000) >> 25);
3286 CL_PRINTF(cli_buf);
3287
3288 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948);
3289 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67);
3290 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765);
3291 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3292 "0x948/ 0x67[5] / 0x765",
3293 u32tmp[0], ((u8tmp[0]&0x20) >> 5), u8tmp[1]);
3294 CL_PRINTF(cli_buf);
3295
3296 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c);
3297 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930);
3298 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944);
3299 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3300 "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]",
3301 u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3);
3302 CL_PRINTF(cli_buf);
3303
3304
3305 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39);
3306 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
3307 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
3308 u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
3309 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3310 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
3311 "0x38[11]/0x40/0x4c[24:23]/0x64[0]",
3312 ((u8tmp[0] & 0x8)>>3), u8tmp[1],
3313 ((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1);
3314 CL_PRINTF(cli_buf);
3315
3316 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
3317 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
3318 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
3319 "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]);
3320 CL_PRINTF(cli_buf);
3321
3322 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
3323 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c);
3324 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
3325 "0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]);
3326 CL_PRINTF(cli_buf);
3327
3328 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0);
3329 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4);
3330 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8);
3331 u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0);
3332
3333 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b);
3334 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
3335
3336 fa_ofdm = ((u32tmp[0]&0xffff0000) >> 16) +
3337 ((u32tmp[1]&0xffff0000) >> 16) +
3338 (u32tmp[1] & 0xffff) +
3339 (u32tmp[2] & 0xffff) +
3340 ((u32tmp[3]&0xffff0000) >> 16) +
3341 (u32tmp[3] & 0xffff);
3342 fa_cck = (u8tmp[0] << 8) + u8tmp[1];
3343
3344 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3345 "OFDM-CCA/OFDM-FA/CCK-FA",
3346 u32tmp[0]&0xffff, fa_ofdm, fa_cck);
3347 CL_PRINTF(cli_buf);
3348
3349 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
3350 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
3351 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
3352 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
3353 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3354 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
3355 "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
3356 u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]);
3357 CL_PRINTF(cli_buf);
3358
3359 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
3360 "0x770(high-pri rx/tx)",
3361 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
3362 CL_PRINTF(cli_buf);
3363 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
3364 "0x774(low-pri rx/tx)", coex_sta->low_priority_rx,
3365 coex_sta->low_priority_tx);
3366 CL_PRINTF(cli_buf);
3367#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1)
3368 btc8723b2ant_monitor_bt_ctr(btcoexist);
3369#endif
3370 btcoexist->btc_disp_dbg_msg(btcoexist,
3371 BTC_DBG_DISP_COEX_STATISTICS);
3372}
3373
3374
3375void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
3376{
3377 if (BTC_IPS_ENTER == type) {
3378 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3379 "[BTCoex], IPS ENTER notify\n");
3380 coex_sta->under_ips = true;
3381 btc8723b2ant_coex_alloff(btcoexist);
3382 } else if (BTC_IPS_LEAVE == type) {
3383 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3384 "[BTCoex], IPS LEAVE notify\n");
3385 coex_sta->under_ips = false;
3386 }
3387}
3388
3389void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
3390{
3391 if (BTC_LPS_ENABLE == type) {
3392 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3393 "[BTCoex], LPS ENABLE notify\n");
3394 coex_sta->under_lps = true;
3395 } else if (BTC_LPS_DISABLE == type) {
3396 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3397 "[BTCoex], LPS DISABLE notify\n");
3398 coex_sta->under_lps = false;
3399 }
3400}
3401
3402void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
3403{
3404 if (BTC_SCAN_START == type)
3405 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3406 "[BTCoex], SCAN START notify\n");
3407 else if (BTC_SCAN_FINISH == type)
3408 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3409 "[BTCoex], SCAN FINISH notify\n");
3410}
3411
3412void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
3413{
3414 if (BTC_ASSOCIATE_START == type)
3415 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3416 "[BTCoex], CONNECT START notify\n");
3417 else if (BTC_ASSOCIATE_FINISH == type)
3418 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3419 "[BTCoex], CONNECT FINISH notify\n");
3420}
3421
3422void btc8723b_med_stat_notify(struct btc_coexist *btcoexist,
3423 u8 type)
3424{
3425 u8 h2c_parameter[3] = {0};
3426 u32 wifi_bw;
3427 u8 wifi_central_chnl;
3428
3429 if (BTC_MEDIA_CONNECT == type)
3430 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3431 "[BTCoex], MEDIA connect notify\n");
3432 else
3433 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3434 "[BTCoex], MEDIA disconnect notify\n");
3435
3436 /* only 2.4G we need to inform bt the chnl mask */
3437 btcoexist->btc_get(btcoexist,
3438 BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl);
3439 if ((BTC_MEDIA_CONNECT == type) &&
3440 (wifi_central_chnl <= 14)) {
3441 h2c_parameter[0] = 0x1;
3442 h2c_parameter[1] = wifi_central_chnl;
3443 btcoexist->btc_get(btcoexist,
3444 BTC_GET_U4_WIFI_BW, &wifi_bw);
3445 if (BTC_WIFI_BW_HT40 == wifi_bw)
3446 h2c_parameter[2] = 0x30;
3447 else
3448 h2c_parameter[2] = 0x20;
3449 }
3450
3451 coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
3452 coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
3453 coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
3454
3455 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
3456 "[BTCoex], FW write 0x66=0x%x\n",
3457 h2c_parameter[0] << 16 | h2c_parameter[1] << 8 |
3458 h2c_parameter[2]);
3459
3460 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
3461}
3462
3463void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist,
3464 u8 type)
3465{
3466 if (type == BTC_PACKET_DHCP)
3467 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3468 "[BTCoex], DHCP Packet notify\n");
3469}
3470
3471void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
3472 u8 *tmpbuf, u8 length)
3473{
3474 u8 bt_info = 0;
3475 u8 i, rsp_source = 0;
3476 bool bt_busy = false, limited_dig = false;
3477 bool wifi_connected = false;
3478
3479 coex_sta->c2h_bt_info_req_sent = false;
3480
3481 rsp_source = tmpbuf[0]&0xf;
3482 if (rsp_source >= BT_INFO_SRC_8723B_2ANT_MAX)
3483 rsp_source = BT_INFO_SRC_8723B_2ANT_WIFI_FW;
3484 coex_sta->bt_info_c2h_cnt[rsp_source]++;
3485
3486 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3487 "[BTCoex], Bt info[%d], length=%d, hex data=[",
3488 rsp_source, length);
3489 for (i = 0; i < length; i++) {
3490 coex_sta->bt_info_c2h[rsp_source][i] = tmpbuf[i];
3491 if (i == 1)
3492 bt_info = tmpbuf[i];
3493 if (i == length-1)
3494 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3495 "0x%02x]\n", tmpbuf[i]);
3496 else
3497 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3498 "0x%02x, ", tmpbuf[i]);
3499 }
3500
3501 if (btcoexist->manual_control) {
3502 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3503 "[BTCoex], BtInfoNotify(), "
3504 "return for Manual CTRL<===\n");
3505 return;
3506 }
3507
3508 if (BT_INFO_SRC_8723B_2ANT_WIFI_FW != rsp_source) {
3509 coex_sta->bt_retry_cnt = /* [3:0]*/
3510 coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
3511
3512 coex_sta->bt_rssi =
3513 coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10;
3514
3515 coex_sta->bt_info_ext =
3516 coex_sta->bt_info_c2h[rsp_source][4];
3517
3518 /* Here we need to resend some wifi info to BT
3519 * because bt is reset and loss of the info.
3520 */
3521 if ((coex_sta->bt_info_ext & BIT1)) {
3522 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3523 "[BTCoex], BT ext info bit1 check,"
3524 " send wifi BW&Chnl to BT!!\n");
3525 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
3526 &wifi_connected);
3527 if (wifi_connected)
3528 btc8723b_med_stat_notify(btcoexist,
3529 BTC_MEDIA_CONNECT);
3530 else
3531 btc8723b_med_stat_notify(btcoexist,
3532 BTC_MEDIA_DISCONNECT);
3533 }
3534
3535 if ((coex_sta->bt_info_ext & BIT3)) {
3536 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3537 "[BTCoex], BT ext info bit3 check, "
3538 "set BT NOT to ignore Wlan active!!\n");
3539 btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC,
3540 false);
3541 } else {
3542 /* BT already NOT ignore Wlan active, do nothing here.*/
3543 }
3544#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 0)
3545 if ((coex_sta->bt_info_ext & BIT4)) {
3546 /* BT auto report already enabled, do nothing*/
3547 } else {
3548 btc8723b2ant_bt_auto_report(btcoexist, FORCE_EXEC,
3549 true);
3550 }
3551#endif
3552 }
3553
3554 /* check BIT2 first ==> check if bt is under inquiry or page scan*/
3555 if (bt_info & BT_INFO_8723B_2ANT_B_INQ_PAGE)
3556 coex_sta->c2h_bt_inquiry_page = true;
3557 else
3558 coex_sta->c2h_bt_inquiry_page = false;
3559
3560 /* set link exist status*/
3561 if (!(bt_info & BT_INFO_8723B_2ANT_B_CONNECTION)) {
3562 coex_sta->bt_link_exist = false;
3563 coex_sta->pan_exist = false;
3564 coex_sta->a2dp_exist = false;
3565 coex_sta->hid_exist = false;
3566 coex_sta->sco_exist = false;
3567 } else { /* connection exists */
3568 coex_sta->bt_link_exist = true;
3569 if (bt_info & BT_INFO_8723B_2ANT_B_FTP)
3570 coex_sta->pan_exist = true;
3571 else
3572 coex_sta->pan_exist = false;
3573 if (bt_info & BT_INFO_8723B_2ANT_B_A2DP)
3574 coex_sta->a2dp_exist = true;
3575 else
3576 coex_sta->a2dp_exist = false;
3577 if (bt_info & BT_INFO_8723B_2ANT_B_HID)
3578 coex_sta->hid_exist = true;
3579 else
3580 coex_sta->hid_exist = false;
3581 if (bt_info & BT_INFO_8723B_2ANT_B_SCO_ESCO)
3582 coex_sta->sco_exist = true;
3583 else
3584 coex_sta->sco_exist = false;
3585 }
3586
3587 btc8723b2ant_update_bt_link_info(btcoexist);
3588
3589 if (!(bt_info & BT_INFO_8723B_2ANT_B_CONNECTION)) {
3590 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE;
3591 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3592 "[BTCoex], BtInfoNotify(), "
3593 "BT Non-Connected idle!!!\n");
3594 /* connection exists but no busy */
3595 } else if (bt_info == BT_INFO_8723B_2ANT_B_CONNECTION) {
3596 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE;
3597 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3598 "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
3599 } else if ((bt_info & BT_INFO_8723B_2ANT_B_SCO_ESCO) ||
3600 (bt_info & BT_INFO_8723B_2ANT_B_SCO_BUSY)) {
3601 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_SCO_BUSY;
3602 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3603 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
3604 } else if (bt_info & BT_INFO_8723B_2ANT_B_ACL_BUSY) {
3605 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_ACL_BUSY;
3606 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3607 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
3608 } else {
3609 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_MAX;
3610 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3611 "[BTCoex], BtInfoNotify(), "
3612 "BT Non-Defined state!!!\n");
3613 }
3614
3615 if ((BT_8723B_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
3616 (BT_8723B_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
3617 (BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) {
3618 bt_busy = true;
3619 limited_dig = true;
3620 } else {
3621 bt_busy = false;
3622 limited_dig = false;
3623 }
3624
3625 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
3626
3627 coex_dm->limited_dig = limited_dig;
3628 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
3629
3630 btc8723b2ant_run_coexist_mechanism(btcoexist);
3631}
3632
3633void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist,
3634 u8 type)
3635{
3636 if (BTC_STACK_OP_INQ_PAGE_PAIR_START == type)
3637 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3638 "[BTCoex],StackOP Inquiry/page/pair start notify\n");
3639 else if (BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type)
3640 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3641 "[BTCoex],StackOP Inquiry/page/pair finish notify\n");
3642}
3643
3644void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist)
3645{
3646 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n");
3647
3648 btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
3649 btc8723b_med_stat_notify(btcoexist, BTC_MEDIA_DISCONNECT);
3650}
3651
3652void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist)
3653{
3654 struct btc_board_info *board_info = &btcoexist->board_info;
3655 struct btc_stack_info *stack_info = &btcoexist->stack_info;
3656 static u8 dis_ver_info_cnt;
3657 u32 fw_ver = 0, bt_patch_ver = 0;
3658
3659 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3660 "[BTCoex], =========================="
3661 "Periodical===========================\n");
3662
3663 if (dis_ver_info_cnt <= 5) {
3664 dis_ver_info_cnt += 1;
3665 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3666 "[BTCoex], ****************************"
3667 "************************************\n");
3668 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3669 "[BTCoex], Ant PG Num/ Ant Mech/ "
3670 "Ant Pos = %d/ %d/ %d\n", board_info->pg_ant_num,
3671 board_info->btdm_ant_num, board_info->btdm_ant_pos);
3672 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3673 "[BTCoex], BT stack/ hci ext ver = %s / %d\n",
3674 ((stack_info->profile_notified) ? "Yes" : "No"),
3675 stack_info->hci_version);
3676 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
3677 &bt_patch_ver);
3678 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3679 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3680 "[BTCoex], CoexVer/ FwVer/ PatchVer = "
3681 "%d_%x/ 0x%x/ 0x%x(%d)\n",
3682 glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant,
3683 fw_ver, bt_patch_ver, bt_patch_ver);
3684 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3685 "[BTCoex], *****************************"
3686 "***********************************\n");
3687 }
3688
3689#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 0)
3690 btc8723b2ant_query_bt_info(btcoexist);
3691 btc8723b2ant_monitor_bt_ctr(btcoexist);
3692 btc8723b2ant_monitor_bt_enable_disable(btcoexist);
3693#else
3694 if (btc8723b2ant_is_wifi_status_changed(btcoexist) ||
3695 coex_dm->auto_tdma_adjust)
3696 btc8723b2ant_run_coexist_mechanism(btcoexist);
3697#endif
3698}
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h
new file mode 100644
index 000000000000..e0ad8e545f82
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h
@@ -0,0 +1,173 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25#ifndef _HAL8723B_2_ANT
26#define _HAL8723B_2_ANT
27
28/************************************************************************
29 * The following is for 8723B 2Ant BT Co-exist definition
30 ************************************************************************/
31#define BT_AUTO_REPORT_ONLY_8723B_2ANT 1
32
33#define BT_INFO_8723B_2ANT_B_FTP BIT7
34#define BT_INFO_8723B_2ANT_B_A2DP BIT6
35#define BT_INFO_8723B_2ANT_B_HID BIT5
36#define BT_INFO_8723B_2ANT_B_SCO_BUSY BIT4
37#define BT_INFO_8723B_2ANT_B_ACL_BUSY BIT3
38#define BT_INFO_8723B_2ANT_B_INQ_PAGE BIT2
39#define BT_INFO_8723B_2ANT_B_SCO_ESCO BIT1
40#define BT_INFO_8723B_2ANT_B_CONNECTION BIT0
41
42#define BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT 2
43
44enum BT_INFO_SRC_8723B_2ANT {
45 BT_INFO_SRC_8723B_2ANT_WIFI_FW = 0x0,
46 BT_INFO_SRC_8723B_2ANT_BT_RSP = 0x1,
47 BT_INFO_SRC_8723B_2ANT_BT_ACTIVE_SEND = 0x2,
48 BT_INFO_SRC_8723B_2ANT_MAX
49};
50
51enum BT_8723B_2ANT_BT_STATUS {
52 BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
53 BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
54 BT_8723B_2ANT_BT_STATUS_INQ_PAGE = 0x2,
55 BT_8723B_2ANT_BT_STATUS_ACL_BUSY = 0x3,
56 BT_8723B_2ANT_BT_STATUS_SCO_BUSY = 0x4,
57 BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
58 BT_8723B_2ANT_BT_STATUS_MAX
59};
60
61enum BT_8723B_2ANT_COEX_ALGO {
62 BT_8723B_2ANT_COEX_ALGO_UNDEFINED = 0x0,
63 BT_8723B_2ANT_COEX_ALGO_SCO = 0x1,
64 BT_8723B_2ANT_COEX_ALGO_HID = 0x2,
65 BT_8723B_2ANT_COEX_ALGO_A2DP = 0x3,
66 BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS = 0x4,
67 BT_8723B_2ANT_COEX_ALGO_PANEDR = 0x5,
68 BT_8723B_2ANT_COEX_ALGO_PANHS = 0x6,
69 BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
70 BT_8723B_2ANT_COEX_ALGO_PANEDR_HID = 0x8,
71 BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
72 BT_8723B_2ANT_COEX_ALGO_HID_A2DP = 0xa,
73 BT_8723B_2ANT_COEX_ALGO_MAX = 0xb,
74};
75
76struct coex_dm_8723b_2ant {
77 /* fw mechanism */
78 bool pre_dec_bt_pwr;
79 bool cur_dec_bt_pwr;
80 u8 pre_fw_dac_swing_lvl;
81 u8 cur_fw_dac_swing_lvl;
82 bool cur_ignore_wlan_act;
83 bool pre_ignore_wlan_act;
84 u8 pre_ps_tdma;
85 u8 cur_ps_tdma;
86 u8 ps_tdma_para[5];
87 u8 tdma_adj_type;
88 bool reset_tdma_adjust;
89 bool auto_tdma_adjust;
90 bool pre_ps_tdma_on;
91 bool cur_ps_tdma_on;
92 bool pre_bt_auto_report;
93 bool cur_bt_auto_report;
94
95 /* sw mechanism */
96 bool pre_rf_rx_lpf_shrink;
97 bool cur_rf_rx_lpf_shrink;
98 u32 bt_rf0x1e_backup;
99 bool pre_low_penalty_ra;
100 bool cur_low_penalty_ra;
101 bool pre_dac_swing_on;
102 u32 pre_dac_swing_lvl;
103 bool cur_dac_swing_on;
104 u32 cur_dac_swing_lvl;
105 bool pre_adc_back_off;
106 bool cur_adc_back_off;
107 bool pre_agc_table_en;
108 bool cur_agc_table_en;
109 u32 pre_val0x6c0;
110 u32 cur_val0x6c0;
111 u32 pre_val0x6c4;
112 u32 cur_val0x6c4;
113 u32 pre_val0x6c8;
114 u32 cur_val0x6c8;
115 u8 pre_val0x6cc;
116 u8 cur_val0x6cc;
117 bool limited_dig;
118
119 /* algorithm related */
120 u8 pre_algorithm;
121 u8 cur_algorithm;
122 u8 bt_status;
123 u8 wifi_chnl_info[3];
124
125 bool need_recover_0x948;
126 u16 backup_0x948;
127};
128
129struct coex_sta_8723b_2ant {
130 bool bt_link_exist;
131 bool sco_exist;
132 bool a2dp_exist;
133 bool hid_exist;
134 bool pan_exist;
135
136 bool under_lps;
137 bool under_ips;
138 u32 high_priority_tx;
139 u32 high_priority_rx;
140 u32 low_priority_tx;
141 u32 low_priority_rx;
142 u8 bt_rssi;
143 u8 pre_bt_rssi_state;
144 u8 pre_wifi_rssi_state[4];
145 bool c2h_bt_info_req_sent;
146 u8 bt_info_c2h[BT_INFO_SRC_8723B_2ANT_MAX][10];
147 u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_2ANT_MAX];
148 bool c2h_bt_inquiry_page;
149 u8 bt_retry_cnt;
150 u8 bt_info_ext;
151};
152
153/*********************************************************************
154 * The following is interface which will notify coex module.
155 *********************************************************************/
156void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist);
157void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist);
158void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
159void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
160void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
161void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
162void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, u8 type);
163void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist,
164 u8 type);
165void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
166 u8 *tmpbuf, u8 length);
167void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist,
168 u8 type);
169void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist);
170void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist);
171void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist);
172
173#endif
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
new file mode 100644
index 000000000000..b6722de64a31
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -0,0 +1,1011 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 ******************************************************************************/
25
26#include "halbt_precomp.h"
27
28/***********************************************
29 * Global variables
30 ***********************************************/
31
32struct btc_coexist gl_bt_coexist;
33
34u32 btc_dbg_type[BTC_MSG_MAX];
35static u8 btc_dbg_buf[100];
36
37/***************************************************
38 * Debug related function
39 ***************************************************/
40static bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist)
41{
42 if (!btcoexist->binded || NULL == btcoexist->adapter)
43 return false;
44
45 return true;
46}
47
48static bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv)
49{
50 if (rtlpriv->link_info.busytraffic)
51 return true;
52 else
53 return false;
54}
55
56static void halbtc_dbg_init(void)
57{
58 u8 i;
59
60 for (i = 0; i < BTC_MSG_MAX; i++)
61 btc_dbg_type[i] = 0;
62
63 btc_dbg_type[BTC_MSG_INTERFACE] =
64/* INTF_INIT | */
65/* INTF_NOTIFY | */
66 0;
67
68 btc_dbg_type[BTC_MSG_ALGORITHM] =
69/* ALGO_BT_RSSI_STATE | */
70/* ALGO_WIFI_RSSI_STATE | */
71/* ALGO_BT_MONITOR | */
72/* ALGO_TRACE | */
73/* ALGO_TRACE_FW | */
74/* ALGO_TRACE_FW_DETAIL | */
75/* ALGO_TRACE_FW_EXEC | */
76/* ALGO_TRACE_SW | */
77/* ALGO_TRACE_SW_DETAIL | */
78/* ALGO_TRACE_SW_EXEC | */
79 0;
80}
81
82static bool halbtc_is_bt40(struct rtl_priv *adapter)
83{
84 struct rtl_priv *rtlpriv = adapter;
85 struct rtl_phy *rtlphy = &(rtlpriv->phy);
86 bool is_ht40 = true;
87 enum ht_channel_width bw = rtlphy->current_chan_bw;
88
89 if (bw == HT_CHANNEL_WIDTH_20)
90 is_ht40 = false;
91 else if (bw == HT_CHANNEL_WIDTH_20_40)
92 is_ht40 = true;
93
94 return is_ht40;
95}
96
97static bool halbtc_legacy(struct rtl_priv *adapter)
98{
99 struct rtl_priv *rtlpriv = adapter;
100 struct rtl_mac *mac = rtl_mac(rtlpriv);
101
102 bool is_legacy = false;
103
104 if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_B))
105 is_legacy = true;
106
107 return is_legacy;
108}
109
110bool halbtc_is_wifi_uplink(struct rtl_priv *adapter)
111{
112 struct rtl_priv *rtlpriv = adapter;
113
114 if (rtlpriv->link_info.tx_busy_traffic)
115 return true;
116 else
117 return false;
118}
119
120static u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist)
121{
122 struct rtl_priv *rtlpriv =
123 (struct rtl_priv *)btcoexist->adapter;
124 u32 wifi_bw = BTC_WIFI_BW_HT20;
125
126 if (halbtc_is_bt40(rtlpriv)) {
127 wifi_bw = BTC_WIFI_BW_HT40;
128 } else {
129 if (halbtc_legacy(rtlpriv))
130 wifi_bw = BTC_WIFI_BW_LEGACY;
131 else
132 wifi_bw = BTC_WIFI_BW_HT20;
133 }
134 return wifi_bw;
135}
136
137static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist)
138{
139 struct rtl_priv *rtlpriv = btcoexist->adapter;
140 struct rtl_phy *rtlphy = &(rtlpriv->phy);
141 u8 chnl = 1;
142
143 if (rtlphy->current_channel != 0)
144 chnl = rtlphy->current_channel;
145 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
146 "static halbtc_get_wifi_central_chnl:%d\n", chnl);
147 return chnl;
148}
149
150static void halbtc_leave_lps(struct btc_coexist *btcoexist)
151{
152 struct rtl_priv *rtlpriv;
153 struct rtl_ps_ctl *ppsc;
154 bool ap_enable = false;
155
156 rtlpriv = btcoexist->adapter;
157 ppsc = rtl_psc(rtlpriv);
158
159 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
160 &ap_enable);
161
162 if (ap_enable) {
163 pr_info("halbtc_leave_lps()<--dont leave lps under AP mode\n");
164 return;
165 }
166
167 btcoexist->bt_info.bt_ctrl_lps = true;
168 btcoexist->bt_info.bt_lps_on = false;
169}
170
171static void halbtc_enter_lps(struct btc_coexist *btcoexist)
172{
173 struct rtl_priv *rtlpriv;
174 struct rtl_ps_ctl *ppsc;
175 bool ap_enable = false;
176
177 rtlpriv = btcoexist->adapter;
178 ppsc = rtl_psc(rtlpriv);
179
180 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
181 &ap_enable);
182
183 if (ap_enable) {
184 pr_info("halbtc_enter_lps()<--dont enter lps under AP mode\n");
185 return;
186 }
187
188 btcoexist->bt_info.bt_ctrl_lps = true;
189 btcoexist->bt_info.bt_lps_on = false;
190}
191
192static void halbtc_normal_lps(struct btc_coexist *btcoexist)
193{
194 if (btcoexist->bt_info.bt_ctrl_lps) {
195 btcoexist->bt_info.bt_lps_on = false;
196 btcoexist->bt_info.bt_ctrl_lps = false;
197 }
198}
199
200static void halbtc_leave_low_power(void)
201{
202}
203
204static void halbtc_nomal_low_power(void)
205{
206}
207
208static void halbtc_disable_low_power(void)
209{
210}
211
212static void halbtc_aggregation_check(void)
213{
214}
215
216static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist)
217{
218 return 0;
219}
220
221static s32 halbtc_get_wifi_rssi(struct rtl_priv *adapter)
222{
223 struct rtl_priv *rtlpriv = adapter;
224 s32 undec_sm_pwdb = 0;
225
226 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
227 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
228 else /* associated entry pwdb */
229 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
230 return undec_sm_pwdb;
231}
232
233static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
234{
235 struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
236 struct rtl_priv *rtlpriv = btcoexist->adapter;
237 struct rtl_phy *rtlphy = &(rtlpriv->phy);
238 struct rtl_mac *mac = rtl_mac(rtlpriv);
239 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
240 bool *bool_tmp = (bool *)out_buf;
241 int *s32_tmp = (int *)out_buf;
242 u32 *u32_tmp = (u32 *)out_buf;
243 u8 *u8_tmp = (u8 *)out_buf;
244 bool tmp = false;
245
246 if (!halbtc_is_bt_coexist_available(btcoexist))
247 return false;
248
249 switch (get_type) {
250 case BTC_GET_BL_HS_OPERATION:
251 *bool_tmp = false;
252 break;
253 case BTC_GET_BL_HS_CONNECTING:
254 *bool_tmp = false;
255 break;
256 case BTC_GET_BL_WIFI_CONNECTED:
257 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
258 tmp = true;
259 *bool_tmp = tmp;
260 break;
261 case BTC_GET_BL_WIFI_BUSY:
262 if (halbtc_is_wifi_busy(rtlpriv))
263 *bool_tmp = true;
264 else
265 *bool_tmp = false;
266 break;
267 case BTC_GET_BL_WIFI_SCAN:
268 if (mac->act_scanning)
269 *bool_tmp = true;
270 else
271 *bool_tmp = false;
272 break;
273 case BTC_GET_BL_WIFI_LINK:
274 if (mac->link_state == MAC80211_LINKING)
275 *bool_tmp = true;
276 else
277 *bool_tmp = false;
278 break;
279 case BTC_GET_BL_WIFI_ROAM: /*TODO*/
280 if (mac->link_state == MAC80211_LINKING)
281 *bool_tmp = true;
282 else
283 *bool_tmp = false;
284 break;
285 case BTC_GET_BL_WIFI_4_WAY_PROGRESS: /*TODO*/
286 *bool_tmp = false;
287
288 break;
289 case BTC_GET_BL_WIFI_UNDER_5G:
290 *bool_tmp = false; /*TODO*/
291
292 case BTC_GET_BL_WIFI_DHCP: /*TODO*/
293 break;
294 case BTC_GET_BL_WIFI_SOFTAP_IDLE:
295 *bool_tmp = true;
296 break;
297 case BTC_GET_BL_WIFI_SOFTAP_LINKING:
298 *bool_tmp = false;
299 break;
300 case BTC_GET_BL_WIFI_IN_EARLY_SUSPEND:
301 *bool_tmp = false;
302 break;
303 case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
304 *bool_tmp = false;
305 break;
306 case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
307 if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm)
308 *bool_tmp = false;
309 else
310 *bool_tmp = true;
311 break;
312 case BTC_GET_BL_WIFI_UNDER_B_MODE:
313 *bool_tmp = false; /*TODO*/
314 break;
315 case BTC_GET_BL_EXT_SWITCH:
316 *bool_tmp = false;
317 break;
318 case BTC_GET_S4_WIFI_RSSI:
319 *s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
320 break;
321 case BTC_GET_S4_HS_RSSI: /*TODO*/
322 *s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
323 break;
324 case BTC_GET_U4_WIFI_BW:
325 *u32_tmp = halbtc_get_wifi_bw(btcoexist);
326 break;
327 case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION:
328 if (halbtc_is_wifi_uplink(rtlpriv))
329 *u32_tmp = BTC_WIFI_TRAFFIC_TX;
330 else
331 *u32_tmp = BTC_WIFI_TRAFFIC_RX;
332 break;
333 case BTC_GET_U4_WIFI_FW_VER:
334 *u32_tmp = rtlhal->fw_version;
335 break;
336 case BTC_GET_U4_BT_PATCH_VER:
337 *u32_tmp = halbtc_get_bt_patch_version(btcoexist);
338 break;
339 case BTC_GET_U1_WIFI_DOT11_CHNL:
340 *u8_tmp = rtlphy->current_channel;
341 break;
342 case BTC_GET_U1_WIFI_CENTRAL_CHNL:
343 *u8_tmp = halbtc_get_wifi_central_chnl(btcoexist);
344 break;
345 case BTC_GET_U1_WIFI_HS_CHNL:
346 *u8_tmp = 1;/*BT_OperateChnl(rtlpriv);*/
347 break;
348 case BTC_GET_U1_MAC_PHY_MODE:
349 *u8_tmp = BTC_MP_UNKNOWN;
350 break;
351
352 /************* 1Ant **************/
353 case BTC_GET_U1_LPS_MODE:
354 *u8_tmp = btcoexist->pwr_mode_val[0];
355 break;
356
357 default:
358 break;
359 }
360
361 return true;
362}
363
364static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
365{
366 struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
367 bool *bool_tmp = (bool *)in_buf;
368 u8 *u8_tmp = (u8 *)in_buf;
369 u32 *u32_tmp = (u32 *)in_buf;
370
371 if (!halbtc_is_bt_coexist_available(btcoexist))
372 return false;
373
374 switch (set_type) {
375 /* set some bool type variables. */
376 case BTC_SET_BL_BT_DISABLE:
377 btcoexist->bt_info.bt_disabled = *bool_tmp;
378 break;
379 case BTC_SET_BL_BT_TRAFFIC_BUSY:
380 btcoexist->bt_info.bt_busy = *bool_tmp;
381 break;
382 case BTC_SET_BL_BT_LIMITED_DIG:
383 btcoexist->bt_info.limited_dig = *bool_tmp;
384 break;
385 case BTC_SET_BL_FORCE_TO_ROAM:
386 btcoexist->bt_info.force_to_roam = *bool_tmp;
387 break;
388 case BTC_SET_BL_TO_REJ_AP_AGG_PKT:
389 btcoexist->bt_info.reject_agg_pkt = *bool_tmp;
390 break;
391 case BTC_SET_BL_BT_CTRL_AGG_SIZE:
392 btcoexist->bt_info.b_bt_ctrl_buf_size = *bool_tmp;
393 break;
394 case BTC_SET_BL_INC_SCAN_DEV_NUM:
395 btcoexist->bt_info.increase_scan_dev_num = *bool_tmp;
396 break;
397 /* set some u1Byte type variables. */
398 case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON:
399 btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp;
400 break;
401 case BTC_SET_U1_AGG_BUF_SIZE:
402 btcoexist->bt_info.agg_buf_size = *u8_tmp;
403 break;
404 /* the following are some action which will be triggered */
405 case BTC_SET_ACT_GET_BT_RSSI:
406 /*BTHCI_SendGetBtRssiEvent(rtlpriv);*/
407 break;
408 case BTC_SET_ACT_AGGREGATE_CTRL:
409 halbtc_aggregation_check();
410 break;
411
412 /* 1Ant */
413 case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE:
414 btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp;
415 break;
416 case BTC_SET_UI_SCAN_SIG_COMPENSATION:
417 /* rtlpriv->mlmepriv.scan_compensation = *u8_tmp; */
418 break;
419 case BTC_SET_U1_1ANT_LPS:
420 btcoexist->bt_info.lps_1ant = *u8_tmp;
421 break;
422 case BTC_SET_U1_1ANT_RPWM:
423 btcoexist->bt_info.rpwm_1ant = *u8_tmp;
424 break;
425 /* the following are some action which will be triggered */
426 case BTC_SET_ACT_LEAVE_LPS:
427 halbtc_leave_lps(btcoexist);
428 break;
429 case BTC_SET_ACT_ENTER_LPS:
430 halbtc_enter_lps(btcoexist);
431 break;
432 case BTC_SET_ACT_NORMAL_LPS:
433 halbtc_normal_lps(btcoexist);
434 break;
435 case BTC_SET_ACT_DISABLE_LOW_POWER:
436 halbtc_disable_low_power();
437 break;
438 case BTC_SET_ACT_UPDATE_ra_mask:
439 btcoexist->bt_info.ra_mask = *u32_tmp;
440 break;
441 case BTC_SET_ACT_SEND_MIMO_PS:
442 break;
443 case BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT:
444 btcoexist->bt_info.force_exec_pwr_cmd_cnt++;
445 break;
446 case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/
447 break;
448 case BTC_SET_ACT_CTRL_BT_COEX:
449 break;
450 default:
451 break;
452 }
453
454 return true;
455}
456
457static void halbtc_display_coex_statistics(struct btc_coexist *btcoexist)
458{
459}
460
461static void halbtc_display_bt_link_info(struct btc_coexist *btcoexist)
462{
463}
464
465static void halbtc_display_bt_fw_info(struct btc_coexist *btcoexist)
466{
467}
468
469static void halbtc_display_fw_pwr_mode_cmd(struct btc_coexist *btcoexist)
470{
471}
472
473/************************************************************
474 * IO related function
475 ************************************************************/
476static u8 halbtc_read_1byte(void *bt_context, u32 reg_addr)
477{
478 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
479 struct rtl_priv *rtlpriv = btcoexist->adapter;
480
481 return rtl_read_byte(rtlpriv, reg_addr);
482}
483
484static u16 halbtc_read_2byte(void *bt_context, u32 reg_addr)
485{
486 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
487 struct rtl_priv *rtlpriv = btcoexist->adapter;
488
489 return rtl_read_word(rtlpriv, reg_addr);
490}
491
492static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr)
493{
494 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
495 struct rtl_priv *rtlpriv = btcoexist->adapter;
496
497 return rtl_read_dword(rtlpriv, reg_addr);
498}
499
500static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u8 data)
501{
502 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
503 struct rtl_priv *rtlpriv = btcoexist->adapter;
504
505 rtl_write_byte(rtlpriv, reg_addr, data);
506}
507
508static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr,
509 u32 bit_mask, u8 data)
510{
511 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
512 struct rtl_priv *rtlpriv = btcoexist->adapter;
513 u8 original_value, bit_shift = 0;
514 u8 i;
515
516 if (bit_mask != MASKDWORD) {/*if not "double word" write*/
517 original_value = rtl_read_byte(rtlpriv, reg_addr);
518 for (i = 0; i <= 7; i++) {
519 if ((bit_mask>>i) & 0x1)
520 break;
521 }
522 bit_shift = i;
523 data = (original_value & (~bit_mask)) |
524 ((data << bit_shift) & bit_mask);
525 }
526 rtl_write_byte(rtlpriv, reg_addr, data);
527}
528
529static void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data)
530{
531 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
532 struct rtl_priv *rtlpriv = btcoexist->adapter;
533
534 rtl_write_word(rtlpriv, reg_addr, data);
535}
536
537static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data)
538{
539 struct btc_coexist *btcoexist =
540 (struct btc_coexist *)bt_context;
541 struct rtl_priv *rtlpriv = btcoexist->adapter;
542
543 rtl_write_dword(rtlpriv, reg_addr, data);
544}
545
546static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask,
547 u32 data)
548{
549 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
550 struct rtl_priv *rtlpriv = btcoexist->adapter;
551
552 rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
553}
554
555static u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask)
556{
557 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
558 struct rtl_priv *rtlpriv = btcoexist->adapter;
559
560 return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
561}
562
563static void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
564 u32 bit_mask, u32 data)
565{
566 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
567 struct rtl_priv *rtlpriv = btcoexist->adapter;
568
569 rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data);
570}
571
572static u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
573 u32 bit_mask)
574{
575 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
576 struct rtl_priv *rtlpriv = btcoexist->adapter;
577
578 return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask);
579}
580
581static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id,
582 u32 cmd_len, u8 *cmd_buf)
583{
584 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
585 struct rtl_priv *rtlpriv = btcoexist->adapter;
586
587 rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id,
588 cmd_len, cmd_buf);
589}
590
591static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type)
592{
593 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
594 switch (disp_type) {
595 case BTC_DBG_DISP_COEX_STATISTICS:
596 halbtc_display_coex_statistics(btcoexist);
597 break;
598 case BTC_DBG_DISP_BT_LINK_INFO:
599 halbtc_display_bt_link_info(btcoexist);
600 break;
601 case BTC_DBG_DISP_BT_FW_VER:
602 halbtc_display_bt_fw_info(btcoexist);
603 break;
604 case BTC_DBG_DISP_FW_PWR_MODE_CMD:
605 halbtc_display_fw_pwr_mode_cmd(btcoexist);
606 break;
607 default:
608 break;
609 }
610}
611
612/*****************************************************************
613 * Extern functions called by other module
614 *****************************************************************/
615bool exhalbtc_initlize_variables(struct rtl_priv *adapter)
616{
617 struct btc_coexist *btcoexist = &gl_bt_coexist;
618
619 btcoexist->statistics.cnt_bind++;
620
621 halbtc_dbg_init();
622
623 if (btcoexist->binded)
624 return false;
625 else
626 btcoexist->binded = true;
627
628#if (defined(CONFIG_PCI_HCI))
629 btcoexist->chip_interface = BTC_INTF_PCI;
630#elif (defined(CONFIG_USB_HCI))
631 btcoexist->chip_interface = BTC_INTF_USB;
632#elif (defined(CONFIG_SDIO_HCI))
633 btcoexist->chip_interface = BTC_INTF_SDIO;
634#elif (defined(CONFIG_GSPI_HCI))
635 btcoexist->chip_interface = BTC_INTF_GSPI;
636#else
637 btcoexist->chip_interface = BTC_INTF_UNKNOWN;
638#endif
639
640 if (NULL == btcoexist->adapter)
641 btcoexist->adapter = adapter;
642
643 btcoexist->stack_info.profile_notified = false;
644
645 btcoexist->btc_read_1byte = halbtc_read_1byte;
646 btcoexist->btc_write_1byte = halbtc_write_1byte;
647 btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte;
648 btcoexist->btc_read_2byte = halbtc_read_2byte;
649 btcoexist->btc_write_2byte = halbtc_write_2byte;
650 btcoexist->btc_read_4byte = halbtc_read_4byte;
651 btcoexist->btc_write_4byte = halbtc_write_4byte;
652
653 btcoexist->btc_set_bb_reg = halbtc_set_bbreg;
654 btcoexist->btc_get_bb_reg = halbtc_get_bbreg;
655
656 btcoexist->btc_set_rf_reg = halbtc_set_rfreg;
657 btcoexist->btc_get_rf_reg = halbtc_get_rfreg;
658
659 btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd;
660 btcoexist->btc_disp_dbg_msg = halbtc_display_dbg_msg;
661
662 btcoexist->btc_get = halbtc_get;
663 btcoexist->btc_set = halbtc_set;
664
665 btcoexist->cli_buf = &btc_dbg_buf[0];
666
667 btcoexist->bt_info.b_bt_ctrl_buf_size = false;
668 btcoexist->bt_info.agg_buf_size = 5;
669
670 btcoexist->bt_info.increase_scan_dev_num = false;
671 return true;
672}
673
674void exhalbtc_init_hw_config(struct btc_coexist *btcoexist)
675{
676 struct rtl_priv *rtlpriv = btcoexist->adapter;
677 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
678
679 if (!halbtc_is_bt_coexist_available(btcoexist))
680 return;
681
682 btcoexist->statistics.cnt_init_hw_config++;
683
684 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
685 ex_halbtc8723b2ant_init_hwconfig(btcoexist);
686}
687
688void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist)
689{
690 struct rtl_priv *rtlpriv = btcoexist->adapter;
691 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
692
693 if (!halbtc_is_bt_coexist_available(btcoexist))
694 return;
695
696 btcoexist->statistics.cnt_init_coex_dm++;
697
698 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
699 ex_halbtc8723b2ant_init_coex_dm(btcoexist);
700
701 btcoexist->initilized = true;
702}
703
704void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type)
705{
706 struct rtl_priv *rtlpriv = btcoexist->adapter;
707 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
708 u8 ips_type;
709
710 if (!halbtc_is_bt_coexist_available(btcoexist))
711 return;
712 btcoexist->statistics.cnt_ips_notify++;
713 if (btcoexist->manual_control)
714 return;
715
716 if (ERFOFF == type)
717 ips_type = BTC_IPS_ENTER;
718 else
719 ips_type = BTC_IPS_LEAVE;
720
721 halbtc_leave_low_power();
722
723 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
724 ex_halbtc8723b2ant_ips_notify(btcoexist, ips_type);
725
726 halbtc_nomal_low_power();
727}
728
729void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type)
730{
731 struct rtl_priv *rtlpriv = btcoexist->adapter;
732 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
733 u8 lps_type;
734
735 if (!halbtc_is_bt_coexist_available(btcoexist))
736 return;
737 btcoexist->statistics.cnt_lps_notify++;
738 if (btcoexist->manual_control)
739 return;
740
741 if (EACTIVE == type)
742 lps_type = BTC_LPS_DISABLE;
743 else
744 lps_type = BTC_LPS_ENABLE;
745
746 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
747 ex_halbtc8723b2ant_lps_notify(btcoexist, lps_type);
748}
749
750void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type)
751{
752 struct rtl_priv *rtlpriv = btcoexist->adapter;
753 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
754 u8 scan_type;
755
756 if (!halbtc_is_bt_coexist_available(btcoexist))
757 return;
758 btcoexist->statistics.cnt_scan_notify++;
759 if (btcoexist->manual_control)
760 return;
761
762 if (type)
763 scan_type = BTC_SCAN_START;
764 else
765 scan_type = BTC_SCAN_FINISH;
766
767 halbtc_leave_low_power();
768
769 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
770 ex_halbtc8723b2ant_scan_notify(btcoexist, scan_type);
771
772 halbtc_nomal_low_power();
773}
774
775void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action)
776{
777 struct rtl_priv *rtlpriv = btcoexist->adapter;
778 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
779 u8 asso_type;
780
781 if (!halbtc_is_bt_coexist_available(btcoexist))
782 return;
783 btcoexist->statistics.cnt_connect_notify++;
784 if (btcoexist->manual_control)
785 return;
786
787 if (action)
788 asso_type = BTC_ASSOCIATE_START;
789 else
790 asso_type = BTC_ASSOCIATE_FINISH;
791
792 halbtc_leave_low_power();
793
794 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
795 ex_halbtc8723b2ant_connect_notify(btcoexist, asso_type);
796}
797
798void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
799 enum _RT_MEDIA_STATUS media_status)
800{
801 struct rtl_priv *rtlpriv = btcoexist->adapter;
802 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
803 u8 status;
804
805 if (!halbtc_is_bt_coexist_available(btcoexist))
806 return;
807 btcoexist->statistics.cnt_media_status_notify++;
808 if (btcoexist->manual_control)
809 return;
810
811 if (RT_MEDIA_CONNECT == media_status)
812 status = BTC_MEDIA_CONNECT;
813 else
814 status = BTC_MEDIA_DISCONNECT;
815
816 halbtc_leave_low_power();
817
818 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
819 btc8723b_med_stat_notify(btcoexist, status);
820
821 halbtc_nomal_low_power();
822}
823
824void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type)
825{
826 struct rtl_priv *rtlpriv = btcoexist->adapter;
827 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
828 u8 packet_type;
829
830 if (!halbtc_is_bt_coexist_available(btcoexist))
831 return;
832 btcoexist->statistics.cnt_special_packet_notify++;
833 if (btcoexist->manual_control)
834 return;
835
836 packet_type = BTC_PACKET_DHCP;
837
838 halbtc_leave_low_power();
839
840 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
841 ex_halbtc8723b2ant_special_packet_notify(btcoexist,
842 packet_type);
843
844 halbtc_nomal_low_power();
845}
846
847void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist,
848 u8 *tmp_buf, u8 length)
849{
850 struct rtl_priv *rtlpriv = btcoexist->adapter;
851 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
852 if (!halbtc_is_bt_coexist_available(btcoexist))
853 return;
854 btcoexist->statistics.cnt_bt_info_notify++;
855
856 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
857 ex_halbtc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length);
858}
859
860void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type)
861{
862 struct rtl_priv *rtlpriv = btcoexist->adapter;
863 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
864 u8 stack_op_type;
865
866 if (!halbtc_is_bt_coexist_available(btcoexist))
867 return;
868 btcoexist->statistics.cnt_stack_operation_notify++;
869 if (btcoexist->manual_control)
870 return;
871
872 stack_op_type = BTC_STACK_OP_NONE;
873
874 halbtc_leave_low_power();
875
876 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
877 ex_halbtc8723b2ant_stack_operation_notify(btcoexist,
878 stack_op_type);
879
880 halbtc_nomal_low_power();
881}
882
883void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
884{
885 struct rtl_priv *rtlpriv = btcoexist->adapter;
886 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
887 if (!halbtc_is_bt_coexist_available(btcoexist))
888 return;
889
890 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
891 ex_halbtc8723b2ant_halt_notify(btcoexist);
892}
893
894void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
895{
896 if (!halbtc_is_bt_coexist_available(btcoexist))
897 return;
898}
899
900void exhalbtc_periodical(struct btc_coexist *btcoexist)
901{
902 struct rtl_priv *rtlpriv = btcoexist->adapter;
903 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
904 if (!halbtc_is_bt_coexist_available(btcoexist))
905 return;
906 btcoexist->statistics.cnt_periodical++;
907
908 halbtc_leave_low_power();
909
910 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
911 ex_halbtc8723b2ant_periodical(btcoexist);
912
913 halbtc_nomal_low_power();
914}
915
916void exhalbtc_dbg_control(struct btc_coexist *btcoexist,
917 u8 code, u8 len, u8 *data)
918{
919 if (!halbtc_is_bt_coexist_available(btcoexist))
920 return;
921 btcoexist->statistics.cnt_dbg_ctrl++;
922}
923
924void exhalbtc_stack_update_profile_info(void)
925{
926}
927
928void exhalbtc_update_min_bt_rssi(char bt_rssi)
929{
930 struct btc_coexist *btcoexist = &gl_bt_coexist;
931
932 if (!halbtc_is_bt_coexist_available(btcoexist))
933 return;
934
935 btcoexist->stack_info.min_bt_rssi = bt_rssi;
936}
937
938void exhalbtc_set_hci_version(u16 hci_version)
939{
940 struct btc_coexist *btcoexist = &gl_bt_coexist;
941
942 if (!halbtc_is_bt_coexist_available(btcoexist))
943 return;
944
945 btcoexist->stack_info.hci_version = hci_version;
946}
947
948void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version)
949{
950 struct btc_coexist *btcoexist = &gl_bt_coexist;
951
952 if (!halbtc_is_bt_coexist_available(btcoexist))
953 return;
954
955 btcoexist->bt_info.bt_real_fw_ver = bt_patch_version;
956 btcoexist->bt_info.bt_hci_ver = bt_hci_version;
957}
958
959void exhalbtc_set_bt_exist(bool bt_exist)
960{
961 gl_bt_coexist.board_info.bt_exist = bt_exist;
962}
963
964void exhalbtc_set_chip_type(u8 chip_type)
965{
966 switch (chip_type) {
967 default:
968 case BT_2WIRE:
969 case BT_ISSC_3WIRE:
970 case BT_ACCEL:
971 case BT_RTL8756:
972 gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_UNDEF;
973 break;
974 case BT_CSR_BC4:
975 gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC4;
976 break;
977 case BT_CSR_BC8:
978 gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC8;
979 break;
980 case BT_RTL8723A:
981 gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723A;
982 break;
983 case BT_RTL8821A:
984 gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8821;
985 break;
986 case BT_RTL8723B:
987 gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723B;
988 break;
989 }
990}
991
992void exhalbtc_set_ant_num(u8 type, u8 ant_num)
993{
994 if (BT_COEX_ANT_TYPE_PG == type) {
995 gl_bt_coexist.board_info.pg_ant_num = ant_num;
996 gl_bt_coexist.board_info.btdm_ant_num = ant_num;
997 } else if (BT_COEX_ANT_TYPE_ANTDIV == type) {
998 gl_bt_coexist.board_info.btdm_ant_num = ant_num;
999 }
1000}
1001
1002void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist)
1003{
1004 struct rtl_priv *rtlpriv = btcoexist->adapter;
1005 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1006 if (!halbtc_is_bt_coexist_available(btcoexist))
1007 return;
1008
1009 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
1010 ex_halbtc8723b2ant_display_coex_info(btcoexist);
1011}
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
new file mode 100644
index 000000000000..871fc3c6d559
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -0,0 +1,559 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25#ifndef __HALBTC_OUT_SRC_H__
26#define __HALBTC_OUT_SRC_H__
27
28#include "../wifi.h"
29
30#define NORMAL_EXEC false
31#define FORCE_EXEC true
32
33#define BTC_RF_A RF90_PATH_A
34#define BTC_RF_B RF90_PATH_B
35#define BTC_RF_C RF90_PATH_C
36#define BTC_RF_D RF90_PATH_D
37
38#define BTC_SMSP SINGLEMAC_SINGLEPHY
39#define BTC_DMDP DUALMAC_DUALPHY
40#define BTC_DMSP DUALMAC_SINGLEPHY
41#define BTC_MP_UNKNOWN 0xff
42
43#define IN
44#define OUT
45
46#define BT_TMP_BUF_SIZE 100
47
48#define BT_COEX_ANT_TYPE_PG 0
49#define BT_COEX_ANT_TYPE_ANTDIV 1
50#define BT_COEX_ANT_TYPE_DETECTED 2
51
52#define BTC_MIMO_PS_STATIC 0
53#define BTC_MIMO_PS_DYNAMIC 1
54
55#define BTC_RATE_DISABLE 0
56#define BTC_RATE_ENABLE 1
57
58#define BTC_ANT_PATH_WIFI 0
59#define BTC_ANT_PATH_BT 1
60#define BTC_ANT_PATH_PTA 2
61
62enum btc_chip_interface {
63 BTC_INTF_UNKNOWN = 0,
64 BTC_INTF_PCI = 1,
65 BTC_INTF_USB = 2,
66 BTC_INTF_SDIO = 3,
67 BTC_INTF_GSPI = 4,
68 BTC_INTF_MAX
69};
70
71enum BTC_CHIP_TYPE {
72 BTC_CHIP_UNDEF = 0,
73 BTC_CHIP_CSR_BC4 = 1,
74 BTC_CHIP_CSR_BC8 = 2,
75 BTC_CHIP_RTL8723A = 3,
76 BTC_CHIP_RTL8821 = 4,
77 BTC_CHIP_RTL8723B = 5,
78 BTC_CHIP_MAX
79};
80
81enum BTC_MSG_TYPE {
82 BTC_MSG_INTERFACE = 0x0,
83 BTC_MSG_ALGORITHM = 0x1,
84 BTC_MSG_MAX
85};
86extern u32 btc_dbg_type[];
87
88/* following is for BTC_MSG_INTERFACE */
89#define INTF_INIT BIT0
90#define INTF_NOTIFY BIT2
91
92/* following is for BTC_ALGORITHM */
93#define ALGO_BT_RSSI_STATE BIT0
94#define ALGO_WIFI_RSSI_STATE BIT1
95#define ALGO_BT_MONITOR BIT2
96#define ALGO_TRACE BIT3
97#define ALGO_TRACE_FW BIT4
98#define ALGO_TRACE_FW_DETAIL BIT5
99#define ALGO_TRACE_FW_EXEC BIT6
100#define ALGO_TRACE_SW BIT7
101#define ALGO_TRACE_SW_DETAIL BIT8
102#define ALGO_TRACE_SW_EXEC BIT9
103
104#define BT_COEX_ANT_TYPE_PG 0
105#define BT_COEX_ANT_TYPE_ANTDIV 1
106#define BT_COEX_ANT_TYPE_DETECTED 2
107#define BTC_MIMO_PS_STATIC 0
108#define BTC_MIMO_PS_DYNAMIC 1
109#define BTC_RATE_DISABLE 0
110#define BTC_RATE_ENABLE 1
111#define BTC_ANT_PATH_WIFI 0
112#define BTC_ANT_PATH_BT 1
113#define BTC_ANT_PATH_PTA 2
114
115
116#define CL_SPRINTF snprintf
117#define CL_PRINTF printk
118
119#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \
120 do { \
121 if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\
122 printk(printstr, ##__VA_ARGS__); \
123 } \
124 } while (0)
125
126#define BTC_PRINT_F(dbgtype, dbgflag, printstr, ...) \
127 do { \
128 if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\
129 pr_info("%s: ", __func__); \
130 printk(printstr, ##__VA_ARGS__); \
131 } \
132 } while (0)
133
134#define BTC_PRINT_ADDR(dbgtype, dbgflag, printstr, _ptr) \
135 do { \
136 if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) { \
137 int __i; \
138 u8 *__ptr = (u8 *)_ptr; \
139 printk printstr; \
140 for (__i = 0; __i < 6; __i++) \
141 printk("%02X%s", __ptr[__i], (__i == 5) ? \
142 "" : "-"); \
143 pr_info("\n"); \
144 } \
145 } while (0)
146
147#define BTC_PRINT_DATA(dbgtype, dbgflag, _titlestring, _hexdata, _hexdatalen) \
148 do { \
149 if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) { \
150 int __i; \
151 u8 *__ptr = (u8 *)_hexdata; \
152 printk(_titlestring); \
153 for (__i = 0; __i < (int)_hexdatalen; __i++) { \
154 printk("%02X%s", __ptr[__i], (((__i + 1) % 4) \
155 == 0) ? " " : " ");\
156 if (((__i + 1) % 16) == 0) \
157 printk("\n"); \
158 } \
159 pr_debug("\n"); \
160 } \
161 } while (0)
162
163#define BTC_ANT_PATH_WIFI 0
164#define BTC_ANT_PATH_BT 1
165#define BTC_ANT_PATH_PTA 2
166
167enum btc_power_save_type {
168 BTC_PS_WIFI_NATIVE = 0,
169 BTC_PS_LPS_ON = 1,
170 BTC_PS_LPS_OFF = 2,
171 BTC_PS_LPS_MAX
172};
173
174struct btc_board_info {
175 /* The following is some board information */
176 u8 bt_chip_type;
177 u8 pg_ant_num; /* pg ant number */
178 u8 btdm_ant_num; /* ant number for btdm */
179 u8 btdm_ant_pos;
180 bool bt_exist;
181};
182
183enum btc_dbg_opcode {
184 BTC_DBG_SET_COEX_NORMAL = 0x0,
185 BTC_DBG_SET_COEX_WIFI_ONLY = 0x1,
186 BTC_DBG_SET_COEX_BT_ONLY = 0x2,
187 BTC_DBG_MAX
188};
189
190enum btc_rssi_state {
191 BTC_RSSI_STATE_HIGH = 0x0,
192 BTC_RSSI_STATE_MEDIUM = 0x1,
193 BTC_RSSI_STATE_LOW = 0x2,
194 BTC_RSSI_STATE_STAY_HIGH = 0x3,
195 BTC_RSSI_STATE_STAY_MEDIUM = 0x4,
196 BTC_RSSI_STATE_STAY_LOW = 0x5,
197 BTC_RSSI_MAX
198};
199
200enum btc_wifi_role {
201 BTC_ROLE_STATION = 0x0,
202 BTC_ROLE_AP = 0x1,
203 BTC_ROLE_IBSS = 0x2,
204 BTC_ROLE_HS_MODE = 0x3,
205 BTC_ROLE_MAX
206};
207
208enum btc_wifi_bw_mode {
209 BTC_WIFI_BW_LEGACY = 0x0,
210 BTC_WIFI_BW_HT20 = 0x1,
211 BTC_WIFI_BW_HT40 = 0x2,
212 BTC_WIFI_BW_MAX
213};
214
215enum btc_wifi_traffic_dir {
216 BTC_WIFI_TRAFFIC_TX = 0x0,
217 BTC_WIFI_TRAFFIC_RX = 0x1,
218 BTC_WIFI_TRAFFIC_MAX
219};
220
221enum btc_wifi_pnp {
222 BTC_WIFI_PNP_WAKE_UP = 0x0,
223 BTC_WIFI_PNP_SLEEP = 0x1,
224 BTC_WIFI_PNP_MAX
225};
226
227
228enum btc_get_type {
229 /* type bool */
230 BTC_GET_BL_HS_OPERATION,
231 BTC_GET_BL_HS_CONNECTING,
232 BTC_GET_BL_WIFI_CONNECTED,
233 BTC_GET_BL_WIFI_BUSY,
234 BTC_GET_BL_WIFI_SCAN,
235 BTC_GET_BL_WIFI_LINK,
236 BTC_GET_BL_WIFI_DHCP,
237 BTC_GET_BL_WIFI_SOFTAP_IDLE,
238 BTC_GET_BL_WIFI_SOFTAP_LINKING,
239 BTC_GET_BL_WIFI_IN_EARLY_SUSPEND,
240 BTC_GET_BL_WIFI_ROAM,
241 BTC_GET_BL_WIFI_4_WAY_PROGRESS,
242 BTC_GET_BL_WIFI_UNDER_5G,
243 BTC_GET_BL_WIFI_AP_MODE_ENABLE,
244 BTC_GET_BL_WIFI_ENABLE_ENCRYPTION,
245 BTC_GET_BL_WIFI_UNDER_B_MODE,
246 BTC_GET_BL_EXT_SWITCH,
247
248 /* type s4Byte */
249 BTC_GET_S4_WIFI_RSSI,
250 BTC_GET_S4_HS_RSSI,
251
252 /* type u32 */
253 BTC_GET_U4_WIFI_BW,
254 BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
255 BTC_GET_U4_WIFI_FW_VER,
256 BTC_GET_U4_BT_PATCH_VER,
257
258 /* type u1Byte */
259 BTC_GET_U1_WIFI_DOT11_CHNL,
260 BTC_GET_U1_WIFI_CENTRAL_CHNL,
261 BTC_GET_U1_WIFI_HS_CHNL,
262 BTC_GET_U1_MAC_PHY_MODE,
263
264 /* for 1Ant */
265 BTC_GET_U1_LPS_MODE,
266 BTC_GET_BL_BT_SCO_BUSY,
267
268 /* for test mode */
269 BTC_GET_DRIVER_TEST_CFG,
270 BTC_GET_MAX
271};
272
273
274enum btc_set_type {
275 /* type bool */
276 BTC_SET_BL_BT_DISABLE,
277 BTC_SET_BL_BT_TRAFFIC_BUSY,
278 BTC_SET_BL_BT_LIMITED_DIG,
279 BTC_SET_BL_FORCE_TO_ROAM,
280 BTC_SET_BL_TO_REJ_AP_AGG_PKT,
281 BTC_SET_BL_BT_CTRL_AGG_SIZE,
282 BTC_SET_BL_INC_SCAN_DEV_NUM,
283
284 /* type u1Byte */
285 BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON,
286 BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE,
287 BTC_SET_UI_SCAN_SIG_COMPENSATION,
288 BTC_SET_U1_AGG_BUF_SIZE,
289
290 /* type trigger some action */
291 BTC_SET_ACT_GET_BT_RSSI,
292 BTC_SET_ACT_AGGREGATE_CTRL,
293
294 /********* for 1Ant **********/
295 /* type bool */
296 BTC_SET_BL_BT_SCO_BUSY,
297 /* type u1Byte */
298 BTC_SET_U1_1ANT_LPS,
299 BTC_SET_U1_1ANT_RPWM,
300 /* type trigger some action */
301 BTC_SET_ACT_LEAVE_LPS,
302 BTC_SET_ACT_ENTER_LPS,
303 BTC_SET_ACT_NORMAL_LPS,
304 BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT,
305 BTC_SET_ACT_DISABLE_LOW_POWER,
306 BTC_SET_ACT_UPDATE_ra_mask,
307 BTC_SET_ACT_SEND_MIMO_PS,
308 /* BT Coex related */
309 BTC_SET_ACT_CTRL_BT_INFO,
310 BTC_SET_ACT_CTRL_BT_COEX,
311 /***************************/
312 BTC_SET_MAX
313};
314
315enum btc_dbg_disp_type {
316 BTC_DBG_DISP_COEX_STATISTICS = 0x0,
317 BTC_DBG_DISP_BT_LINK_INFO = 0x1,
318 BTC_DBG_DISP_BT_FW_VER = 0x2,
319 BTC_DBG_DISP_FW_PWR_MODE_CMD = 0x3,
320 BTC_DBG_DISP_MAX
321};
322
323enum btc_notify_type_ips {
324 BTC_IPS_LEAVE = 0x0,
325 BTC_IPS_ENTER = 0x1,
326 BTC_IPS_MAX
327};
328
329enum btc_notify_type_lps {
330 BTC_LPS_DISABLE = 0x0,
331 BTC_LPS_ENABLE = 0x1,
332 BTC_LPS_MAX
333};
334
335enum btc_notify_type_scan {
336 BTC_SCAN_FINISH = 0x0,
337 BTC_SCAN_START = 0x1,
338 BTC_SCAN_MAX
339};
340
341enum btc_notify_type_associate {
342 BTC_ASSOCIATE_FINISH = 0x0,
343 BTC_ASSOCIATE_START = 0x1,
344 BTC_ASSOCIATE_MAX
345};
346
347enum btc_notify_type_media_status {
348 BTC_MEDIA_DISCONNECT = 0x0,
349 BTC_MEDIA_CONNECT = 0x1,
350 BTC_MEDIA_MAX
351};
352
353enum btc_notify_type_special_packet {
354 BTC_PACKET_UNKNOWN = 0x0,
355 BTC_PACKET_DHCP = 0x1,
356 BTC_PACKET_ARP = 0x2,
357 BTC_PACKET_EAPOL = 0x3,
358 BTC_PACKET_MAX
359};
360
361enum btc_notify_type_stack_operation {
362 BTC_STACK_OP_NONE = 0x0,
363 BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1,
364 BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2,
365 BTC_STACK_OP_MAX
366};
367
368
369typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr);
370
371typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr);
372
373typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr);
374
375typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u8 data);
376
377typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr,
378 u32 bit_mask, u8 data1b);
379
380typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data);
381
382typedef void (*bfp_btc_w4)(void *btc_context, u32 reg_addr, u32 data);
383
384typedef void (*bfp_btc_wr_1byte_bit_mask)(void *btc_context, u32 reg_addr,
385 u8 bit_mask, u8 data);
386
387typedef void (*bfp_btc_set_bb_reg)(void *btc_context, u32 reg_addr,
388 u32 bit_mask, u32 data);
389
390typedef u32 (*bfp_btc_get_bb_reg)(void *btc_context, u32 reg_addr,
391 u32 bit_mask);
392
393typedef void (*bfp_btc_set_rf_reg)(void *btc_context, u8 rf_path, u32 reg_addr,
394 u32 bit_mask, u32 data);
395
396typedef u32 (*bfp_btc_get_rf_reg)(void *btc_context, u8 rf_path,
397 u32 reg_addr, u32 bit_mask);
398
399typedef void (*bfp_btc_fill_h2c)(void *btc_context, u8 element_id,
400 u32 cmd_len, u8 *cmd_buffer);
401
402typedef bool (*bfp_btc_get)(void *btcoexist, u8 get_type, void *out_buf);
403
404typedef bool (*bfp_btc_set)(void *btcoexist, u8 set_type, void *in_buf);
405
406typedef void (*bfp_btc_disp_dbg_msg)(void *btcoexist, u8 disp_type);
407
408struct btc_bt_info {
409 bool bt_disabled;
410 u8 rssi_adjust_for_agc_table_on;
411 u8 rssi_adjust_for_1ant_coex_type;
412 bool bt_busy;
413 u8 agg_buf_size;
414 bool limited_dig;
415 bool reject_agg_pkt;
416 bool b_bt_ctrl_buf_size;
417 bool increase_scan_dev_num;
418 u16 bt_hci_ver;
419 u16 bt_real_fw_ver;
420 u8 bt_fw_ver;
421
422 /* the following is for 1Ant solution */
423 bool bt_ctrl_lps;
424 bool bt_pwr_save_mode;
425 bool bt_lps_on;
426 bool force_to_roam;
427 u8 force_exec_pwr_cmd_cnt;
428 u8 lps_1ant;
429 u8 rpwm_1ant;
430 u32 ra_mask;
431};
432
433struct btc_stack_info {
434 bool profile_notified;
435 u16 hci_version; /* stack hci version */
436 u8 num_of_link;
437 bool bt_link_exist;
438 bool sco_exist;
439 bool acl_exist;
440 bool a2dp_exist;
441 bool hid_exist;
442 u8 num_of_hid;
443 bool pan_exist;
444 bool unknown_acl_exist;
445 char min_bt_rssi;
446};
447
448struct btc_statistics {
449 u32 cnt_bind;
450 u32 cnt_init_hw_config;
451 u32 cnt_init_coex_dm;
452 u32 cnt_ips_notify;
453 u32 cnt_lps_notify;
454 u32 cnt_scan_notify;
455 u32 cnt_connect_notify;
456 u32 cnt_media_status_notify;
457 u32 cnt_special_packet_notify;
458 u32 cnt_bt_info_notify;
459 u32 cnt_periodical;
460 u32 cnt_stack_operation_notify;
461 u32 cnt_dbg_ctrl;
462};
463
464struct btc_bt_link_info {
465 bool bt_link_exist;
466 bool sco_exist;
467 bool sco_only;
468 bool a2dp_exist;
469 bool a2dp_only;
470 bool hid_exist;
471 bool hid_only;
472 bool pan_exist;
473 bool pan_only;
474};
475
476enum btc_antenna_pos {
477 BTC_ANTENNA_AT_MAIN_PORT = 0x1,
478 BTC_ANTENNA_AT_AUX_PORT = 0x2,
479};
480
481struct btc_coexist {
482 /* make sure only one adapter can bind the data context */
483 bool binded;
484 /* default adapter */
485 void *adapter;
486 struct btc_board_info board_info;
487 /* some bt info referenced by non-bt module */
488 struct btc_bt_info bt_info;
489 struct btc_stack_info stack_info;
490 enum btc_chip_interface chip_interface;
491 struct btc_bt_link_info bt_link_info;
492
493 bool initilized;
494 bool stop_coex_dm;
495 bool manual_control;
496 u8 *cli_buf;
497 struct btc_statistics statistics;
498 u8 pwr_mode_val[10];
499
500 /* function pointers - io related */
501 bfp_btc_r1 btc_read_1byte;
502 bfp_btc_w1 btc_write_1byte;
503 bfp_btc_w1_bit_mak btc_write_1byte_bitmask;
504 bfp_btc_r2 btc_read_2byte;
505 bfp_btc_w2 btc_write_2byte;
506 bfp_btc_r4 btc_read_4byte;
507 bfp_btc_w4 btc_write_4byte;
508
509 bfp_btc_set_bb_reg btc_set_bb_reg;
510 bfp_btc_get_bb_reg btc_get_bb_reg;
511
512
513 bfp_btc_set_rf_reg btc_set_rf_reg;
514 bfp_btc_get_rf_reg btc_get_rf_reg;
515
516 bfp_btc_fill_h2c btc_fill_h2c;
517
518 bfp_btc_disp_dbg_msg btc_disp_dbg_msg;
519
520 bfp_btc_get btc_get;
521 bfp_btc_set btc_set;
522};
523
524bool halbtc_is_wifi_uplink(struct rtl_priv *adapter);
525
526extern struct btc_coexist gl_bt_coexist;
527
528bool exhalbtc_initlize_variables(struct rtl_priv *adapter);
529void exhalbtc_init_hw_config(struct btc_coexist *btcoexist);
530void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist);
531void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type);
532void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type);
533void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type);
534void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action);
535void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
536 enum _RT_MEDIA_STATUS media_status);
537void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type);
538void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
539 u8 length);
540void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type);
541void exhalbtc_halt_notify(struct btc_coexist *btcoexist);
542void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
543void exhalbtc_periodical(struct btc_coexist *btcoexist);
544void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len,
545 u8 *data);
546void exhalbtc_stack_update_profile_info(void);
547void exhalbtc_set_hci_version(u16 hci_version);
548void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version);
549void exhalbtc_update_min_bt_rssi(char bt_rssi);
550void exhalbtc_set_bt_exist(bool bt_exist);
551void exhalbtc_set_chip_type(u8 chip_type);
552void exhalbtc_set_ant_num(u8 type, u8 ant_num);
553void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist);
554void exhalbtc_signal_compensation(struct btc_coexist *btcoexist,
555 u8 *rssi_wifi, u8 *rssi_bt);
556void exhalbtc_lps_leave(struct btc_coexist *btcoexist);
557void exhalbtc_low_wifi_traffic_notify(struct btc_coexist *btcoexist);
558
559#endif
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c
new file mode 100644
index 000000000000..0ab94fe4cbbe
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c
@@ -0,0 +1,218 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "rtl_btc.h"
28#include "halbt_precomp.h"
29
30#include <linux/vmalloc.h>
31#include <linux/module.h>
32
33static struct rtl_btc_ops rtl_btc_operation = {
34 .btc_init_variables = rtl_btc_init_variables,
35 .btc_init_hal_vars = rtl_btc_init_hal_vars,
36 .btc_init_hw_config = rtl_btc_init_hw_config,
37 .btc_ips_notify = rtl_btc_ips_notify,
38 .btc_scan_notify = rtl_btc_scan_notify,
39 .btc_connect_notify = rtl_btc_connect_notify,
40 .btc_mediastatus_notify = rtl_btc_mediastatus_notify,
41 .btc_periodical = rtl_btc_periodical,
42 .btc_halt_notify = rtl_btc_halt_notify,
43 .btc_btinfo_notify = rtl_btc_btinfo_notify,
44 .btc_is_limited_dig = rtl_btc_is_limited_dig,
45 .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo,
46 .btc_is_bt_disabled = rtl_btc_is_bt_disabled,
47};
48
49void rtl_btc_init_variables(struct rtl_priv *rtlpriv)
50{
51 exhalbtc_initlize_variables(rtlpriv);
52}
53
54void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv)
55{
56 u8 ant_num;
57 u8 bt_exist;
58 u8 bt_type;
59
60 ant_num = rtl_get_hwpg_ant_num(rtlpriv);
61 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
62 "%s, antNum is %d\n", __func__, ant_num);
63
64 bt_exist = rtl_get_hwpg_bt_exist(rtlpriv);
65 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
66 "%s, bt_exist is %d\n", __func__, bt_exist);
67 exhalbtc_set_bt_exist(bt_exist);
68
69 bt_type = rtl_get_hwpg_bt_type(rtlpriv);
70 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%s, bt_type is %d\n",
71 __func__, bt_type);
72 exhalbtc_set_chip_type(bt_type);
73
74 exhalbtc_set_ant_num(BT_COEX_ANT_TYPE_PG, ant_num);
75}
76
77void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv)
78{
79 exhalbtc_init_hw_config(&gl_bt_coexist);
80 exhalbtc_init_coex_dm(&gl_bt_coexist);
81}
82
83void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type)
84{
85 exhalbtc_ips_notify(&gl_bt_coexist, type);
86}
87
88void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype)
89{
90 exhalbtc_scan_notify(&gl_bt_coexist, scantype);
91}
92
93void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action)
94{
95 exhalbtc_connect_notify(&gl_bt_coexist, action);
96}
97
98void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv,
99 enum _RT_MEDIA_STATUS mstatus)
100{
101 exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus);
102}
103
104void rtl_btc_periodical(struct rtl_priv *rtlpriv)
105{
106 exhalbtc_periodical(&gl_bt_coexist);
107}
108
109void rtl_btc_halt_notify(void)
110{
111 exhalbtc_halt_notify(&gl_bt_coexist);
112}
113
114void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length)
115{
116 exhalbtc_bt_info_notify(&gl_bt_coexist, tmp_buf, length);
117}
118
119bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv)
120{
121 return gl_bt_coexist.bt_info.limited_dig;
122}
123
124bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv)
125{
126 bool bt_change_edca = false;
127 u32 cur_edca_val;
128 u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b;
129 u32 edca_hs;
130 u32 edca_addr = 0x504;
131
132 cur_edca_val = rtl_read_dword(rtlpriv, edca_addr);
133 if (halbtc_is_wifi_uplink(rtlpriv)) {
134 if (cur_edca_val != edca_bt_hs_uplink) {
135 edca_hs = edca_bt_hs_uplink;
136 bt_change_edca = true;
137 }
138 } else {
139 if (cur_edca_val != edca_bt_hs_downlink) {
140 edca_hs = edca_bt_hs_downlink;
141 bt_change_edca = true;
142 }
143 }
144
145 if (bt_change_edca)
146 rtl_write_dword(rtlpriv, edca_addr, edca_hs);
147
148 return true;
149}
150
151bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv)
152{
153 if (gl_bt_coexist.bt_info.bt_disabled)
154 return true;
155 else
156 return false;
157}
158
159struct rtl_btc_ops *rtl_btc_get_ops_pointer(void)
160{
161 return &rtl_btc_operation;
162}
163EXPORT_SYMBOL(rtl_btc_get_ops_pointer);
164
165u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
166{
167 u8 num;
168
169 if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2)
170 num = 2;
171 else
172 num = 1;
173
174 return num;
175}
176
177enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw)
178{
179 struct rtl_priv *rtlpriv = rtl_priv(hw);
180 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
181 enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT;
182
183 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
184
185 if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED)
186 m_status = RT_MEDIA_CONNECT;
187
188 return m_status;
189}
190
191u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv)
192{
193 return rtlpriv->btcoexist.btc_info.btcoexist;
194}
195
196u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
197{
198 return rtlpriv->btcoexist.btc_info.bt_type;
199}
200
201MODULE_AUTHOR("Page He <page_he@realsil.com.cn>");
202MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
203MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
204MODULE_LICENSE("GPL");
205MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
206
207static int __init rtl_btcoexist_module_init(void)
208{
209 return 0;
210}
211
212static void __exit rtl_btcoexist_module_exit(void)
213{
214 return;
215}
216
217module_init(rtl_btcoexist_module_init);
218module_exit(rtl_btcoexist_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h
new file mode 100644
index 000000000000..805b22cc8fc8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h
@@ -0,0 +1,52 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 * Larry Finger <Larry.Finger@lwfinger.net>
22 *
23 *****************************************************************************/
24
25#ifndef __RTL_BTC_H__
26#define __RTL_BTC_H__
27
28#include "halbt_precomp.h"
29
30void rtl_btc_init_variables(struct rtl_priv *rtlpriv);
31void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv);
32void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv);
33void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type);
34void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype);
35void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action);
36void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv,
37 enum _RT_MEDIA_STATUS mstatus);
38void rtl_btc_periodical(struct rtl_priv *rtlpriv);
39void rtl_btc_halt_notify(void);
40void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length);
41bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv);
42bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv);
43bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv);
44
45struct rtl_btc_ops *rtl_btc_get_ops_pointer(void);
46
47u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv);
48u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv);
49u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv);
50enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw);
51
52#endif
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 2d337a0c3df0..ded691f76f2f 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -36,6 +36,66 @@
36 36
37#include <linux/export.h> 37#include <linux/export.h>
38 38
39void rtl_addr_delay(u32 addr)
40{
41 if (addr == 0xfe)
42 mdelay(50);
43 else if (addr == 0xfd)
44 mdelay(5);
45 else if (addr == 0xfc)
46 mdelay(1);
47 else if (addr == 0xfb)
48 udelay(50);
49 else if (addr == 0xfa)
50 udelay(5);
51 else if (addr == 0xf9)
52 udelay(1);
53}
54EXPORT_SYMBOL(rtl_addr_delay);
55
56void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
57 u32 mask, u32 data)
58{
59 if (addr == 0xfe) {
60 mdelay(50);
61 } else if (addr == 0xfd) {
62 mdelay(5);
63 } else if (addr == 0xfc) {
64 mdelay(1);
65 } else if (addr == 0xfb) {
66 udelay(50);
67 } else if (addr == 0xfa) {
68 udelay(5);
69 } else if (addr == 0xf9) {
70 udelay(1);
71 } else {
72 rtl_set_rfreg(hw, rfpath, addr, mask, data);
73 udelay(1);
74 }
75}
76EXPORT_SYMBOL(rtl_rfreg_delay);
77
78void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)
79{
80 if (addr == 0xfe) {
81 mdelay(50);
82 } else if (addr == 0xfd) {
83 mdelay(5);
84 } else if (addr == 0xfc) {
85 mdelay(1);
86 } else if (addr == 0xfb) {
87 udelay(50);
88 } else if (addr == 0xfa) {
89 udelay(5);
90 } else if (addr == 0xf9) {
91 udelay(1);
92 } else {
93 rtl_set_bbreg(hw, addr, MASKDWORD, data);
94 udelay(1);
95 }
96}
97EXPORT_SYMBOL(rtl_bb_delay);
98
39void rtl_fw_cb(const struct firmware *firmware, void *context) 99void rtl_fw_cb(const struct firmware *firmware, void *context)
40{ 100{
41 struct ieee80211_hw *hw = context; 101 struct ieee80211_hw *hw = context;
@@ -475,20 +535,40 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
475{ 535{
476 struct rtl_priv *rtlpriv = rtl_priv(hw); 536 struct rtl_priv *rtlpriv = rtl_priv(hw);
477 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 537 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
538 u32 rx_conf;
478 539
479 *new_flags &= RTL_SUPPORTED_FILTERS; 540 *new_flags &= RTL_SUPPORTED_FILTERS;
480 if (!changed_flags) 541 if (!changed_flags)
481 return; 542 return;
482 543
544 /* if ssid not set to hw don't check bssid
545 * here just used for linked scanning, & linked
546 * and nolink check bssid is set in set network_type */
547 if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
548 (mac->link_state >= MAC80211_LINKED)) {
549 if (mac->opmode != NL80211_IFTYPE_AP &&
550 mac->opmode != NL80211_IFTYPE_MESH_POINT) {
551 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
552 rtlpriv->cfg->ops->set_chk_bssid(hw, false);
553 } else {
554 rtlpriv->cfg->ops->set_chk_bssid(hw, true);
555 }
556 }
557 }
558
559 /* must be called after set_chk_bssid since that function modifies the
560 * RCR register too. */
561 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&rx_conf));
562
483 /*TODO: we disable broadcase now, so enable here */ 563 /*TODO: we disable broadcase now, so enable here */
484 if (changed_flags & FIF_ALLMULTI) { 564 if (changed_flags & FIF_ALLMULTI) {
485 if (*new_flags & FIF_ALLMULTI) { 565 if (*new_flags & FIF_ALLMULTI) {
486 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | 566 rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
487 rtlpriv->cfg->maps[MAC_RCR_AB]; 567 rtlpriv->cfg->maps[MAC_RCR_AB];
488 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 568 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
489 "Enable receive multicast frame\n"); 569 "Enable receive multicast frame\n");
490 } else { 570 } else {
491 mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | 571 rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
492 rtlpriv->cfg->maps[MAC_RCR_AB]); 572 rtlpriv->cfg->maps[MAC_RCR_AB]);
493 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 573 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
494 "Disable receive multicast frame\n"); 574 "Disable receive multicast frame\n");
@@ -497,39 +577,25 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
497 577
498 if (changed_flags & FIF_FCSFAIL) { 578 if (changed_flags & FIF_FCSFAIL) {
499 if (*new_flags & FIF_FCSFAIL) { 579 if (*new_flags & FIF_FCSFAIL) {
500 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; 580 rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
501 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 581 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
502 "Enable receive FCS error frame\n"); 582 "Enable receive FCS error frame\n");
503 } else { 583 } else {
504 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; 584 rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
505 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 585 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
506 "Disable receive FCS error frame\n"); 586 "Disable receive FCS error frame\n");
507 } 587 }
508 } 588 }
509 589
510 /* if ssid not set to hw don't check bssid
511 * here just used for linked scanning, & linked
512 * and nolink check bssid is set in set network_type */
513 if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
514 (mac->link_state >= MAC80211_LINKED)) {
515 if (mac->opmode != NL80211_IFTYPE_AP &&
516 mac->opmode != NL80211_IFTYPE_MESH_POINT) {
517 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
518 rtlpriv->cfg->ops->set_chk_bssid(hw, false);
519 } else {
520 rtlpriv->cfg->ops->set_chk_bssid(hw, true);
521 }
522 }
523 }
524 590
525 if (changed_flags & FIF_CONTROL) { 591 if (changed_flags & FIF_CONTROL) {
526 if (*new_flags & FIF_CONTROL) { 592 if (*new_flags & FIF_CONTROL) {
527 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; 593 rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
528 594
529 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 595 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
530 "Enable receive control frame\n"); 596 "Enable receive control frame\n");
531 } else { 597 } else {
532 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; 598 rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
533 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 599 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
534 "Disable receive control frame\n"); 600 "Disable receive control frame\n");
535 } 601 }
@@ -537,15 +603,17 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
537 603
538 if (changed_flags & FIF_OTHER_BSS) { 604 if (changed_flags & FIF_OTHER_BSS) {
539 if (*new_flags & FIF_OTHER_BSS) { 605 if (*new_flags & FIF_OTHER_BSS) {
540 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; 606 rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
541 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 607 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
542 "Enable receive other BSS's frame\n"); 608 "Enable receive other BSS's frame\n");
543 } else { 609 } else {
544 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; 610 rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
545 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 611 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
546 "Disable receive other BSS's frame\n"); 612 "Disable receive other BSS's frame\n");
547 } 613 }
548 } 614 }
615
616 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&rx_conf));
549} 617}
550static int rtl_op_sta_add(struct ieee80211_hw *hw, 618static int rtl_op_sta_add(struct ieee80211_hw *hw,
551 struct ieee80211_vif *vif, 619 struct ieee80211_vif *vif,
@@ -738,6 +806,11 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
738 rtlpriv->cfg->ops->linked_set_reg(hw); 806 rtlpriv->cfg->ops->linked_set_reg(hw);
739 rcu_read_lock(); 807 rcu_read_lock();
740 sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); 808 sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);
809 if (!sta) {
810 pr_err("ieee80211_find_sta returned NULL\n");
811 rcu_read_unlock();
812 goto out;
813 }
741 814
742 if (vif->type == NL80211_IFTYPE_STATION && sta) 815 if (vif->type == NL80211_IFTYPE_STATION && sta)
743 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); 816 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
@@ -892,7 +965,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
892 965
893 mac->basic_rates = basic_rates; 966 mac->basic_rates = basic_rates;
894 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, 967 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
895 (u8 *) (&basic_rates)); 968 (u8 *)(&basic_rates));
896 } 969 }
897 rcu_read_unlock(); 970 rcu_read_unlock();
898 } 971 }
@@ -906,6 +979,11 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
906 if (bss_conf->assoc) { 979 if (bss_conf->assoc) {
907 if (ppsc->fwctrl_lps) { 980 if (ppsc->fwctrl_lps) {
908 u8 mstatus = RT_MEDIA_CONNECT; 981 u8 mstatus = RT_MEDIA_CONNECT;
982 u8 keep_alive = 10;
983 rtlpriv->cfg->ops->set_hw_reg(hw,
984 HW_VAR_KEEP_ALIVE,
985 (u8 *)(&keep_alive));
986
909 rtlpriv->cfg->ops->set_hw_reg(hw, 987 rtlpriv->cfg->ops->set_hw_reg(hw,
910 HW_VAR_H2C_FW_JOINBSSRPT, 988 HW_VAR_H2C_FW_JOINBSSRPT,
911 &mstatus); 989 &mstatus);
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 2fe46a1b4f1f..027e75374dcc 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -41,5 +41,9 @@
41 41
42extern const struct ieee80211_ops rtl_ops; 42extern const struct ieee80211_ops rtl_ops;
43void rtl_fw_cb(const struct firmware *firmware, void *context); 43void rtl_fw_cb(const struct firmware *firmware, void *context);
44void rtl_addr_delay(u32 addr);
45void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
46 u32 mask, u32 data);
47void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
44 48
45#endif 49#endif
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index d7aa165fe677..f26f4ffc771d 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -811,19 +811,19 @@ done:
811 if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) 811 if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
812 return; 812 return;
813 tmp_one = 1; 813 tmp_one = 1;
814 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, 814 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false,
815 HW_DESC_RXBUFF_ADDR, 815 HW_DESC_RXBUFF_ADDR,
816 (u8 *)&bufferaddress); 816 (u8 *)&bufferaddress);
817 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, 817 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false,
818 HW_DESC_RXPKT_LEN, 818 HW_DESC_RXPKT_LEN,
819 (u8 *)&rtlpci->rxbuffersize); 819 (u8 *)&rtlpci->rxbuffersize);
820 820
821 if (index == rtlpci->rxringcount - 1) 821 if (index == rtlpci->rxringcount - 1)
822 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, 822 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false,
823 HW_DESC_RXERO, 823 HW_DESC_RXERO,
824 &tmp_one); 824 &tmp_one);
825 825
826 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, 826 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false, HW_DESC_RXOWN,
827 &tmp_one); 827 &tmp_one);
828 828
829 index = (index + 1) % rtlpci->rxringcount; 829 index = (index + 1) % rtlpci->rxringcount;
@@ -983,6 +983,8 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
983 struct sk_buff *pskb = NULL; 983 struct sk_buff *pskb = NULL;
984 struct rtl_tx_desc *pdesc = NULL; 984 struct rtl_tx_desc *pdesc = NULL;
985 struct rtl_tcb_desc tcb_desc; 985 struct rtl_tcb_desc tcb_desc;
986 /*This is for new trx flow*/
987 struct rtl_tx_buffer_desc *pbuffer_desc = NULL;
986 u8 temp_one = 1; 988 u8 temp_one = 1;
987 989
988 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); 990 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
@@ -1004,11 +1006,12 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
1004 info = IEEE80211_SKB_CB(pskb); 1006 info = IEEE80211_SKB_CB(pskb);
1005 pdesc = &ring->desc[0]; 1007 pdesc = &ring->desc[0];
1006 rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, 1008 rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
1007 info, NULL, pskb, BEACON_QUEUE, &tcb_desc); 1009 (u8 *)pbuffer_desc, info, NULL, pskb,
1010 BEACON_QUEUE, &tcb_desc);
1008 1011
1009 __skb_queue_tail(&ring->queue, pskb); 1012 __skb_queue_tail(&ring->queue, pskb);
1010 1013
1011 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN, 1014 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN,
1012 &temp_one); 1015 &temp_one);
1013 1016
1014 return; 1017 return;
@@ -1066,7 +1069,7 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
1066 mac->current_ampdu_factor = 3; 1069 mac->current_ampdu_factor = 3;
1067 1070
1068 /*QOS*/ 1071 /*QOS*/
1069 rtlpci->acm_method = eAcmWay2_SW; 1072 rtlpci->acm_method = EACMWAY2_SW;
1070 1073
1071 /*task */ 1074 /*task */
1072 tasklet_init(&rtlpriv->works.irq_tasklet, 1075 tasklet_init(&rtlpriv->works.irq_tasklet,
@@ -1113,7 +1116,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
1113 ((i + 1) % entries) * 1116 ((i + 1) % entries) *
1114 sizeof(*ring); 1117 sizeof(*ring);
1115 1118
1116 rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), 1119 rtlpriv->cfg->ops->set_desc(hw, (u8 *)&(ring[i]),
1117 true, HW_DESC_TX_NEXTDESC_ADDR, 1120 true, HW_DESC_TX_NEXTDESC_ADDR,
1118 (u8 *)&nextdescaddress); 1121 (u8 *)&nextdescaddress);
1119 } 1122 }
@@ -1188,19 +1191,19 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
1188 dev_kfree_skb_any(skb); 1191 dev_kfree_skb_any(skb);
1189 return 1; 1192 return 1;
1190 } 1193 }
1191 rtlpriv->cfg->ops->set_desc((u8 *)entry, false, 1194 rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
1192 HW_DESC_RXBUFF_ADDR, 1195 HW_DESC_RXBUFF_ADDR,
1193 (u8 *)&bufferaddress); 1196 (u8 *)&bufferaddress);
1194 rtlpriv->cfg->ops->set_desc((u8 *)entry, false, 1197 rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
1195 HW_DESC_RXPKT_LEN, 1198 HW_DESC_RXPKT_LEN,
1196 (u8 *)&rtlpci-> 1199 (u8 *)&rtlpci->
1197 rxbuffersize); 1200 rxbuffersize);
1198 rtlpriv->cfg->ops->set_desc((u8 *) entry, false, 1201 rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
1199 HW_DESC_RXOWN, 1202 HW_DESC_RXOWN,
1200 &tmp_one); 1203 &tmp_one);
1201 } 1204 }
1202 1205
1203 rtlpriv->cfg->ops->set_desc((u8 *) entry, false, 1206 rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
1204 HW_DESC_RXERO, &tmp_one); 1207 HW_DESC_RXERO, &tmp_one);
1205 } 1208 }
1206 return 0; 1209 return 0;
@@ -1331,7 +1334,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
1331 1334
1332 for (i = 0; i < rtlpci->rxringcount; i++) { 1335 for (i = 0; i < rtlpci->rxringcount; i++) {
1333 entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; 1336 entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
1334 rtlpriv->cfg->ops->set_desc((u8 *) entry, 1337 rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry,
1335 false, 1338 false,
1336 HW_DESC_RXOWN, 1339 HW_DESC_RXOWN,
1337 &tmp_one); 1340 &tmp_one);
@@ -1424,6 +1427,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
1424 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1427 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1425 struct rtl8192_tx_ring *ring; 1428 struct rtl8192_tx_ring *ring;
1426 struct rtl_tx_desc *pdesc; 1429 struct rtl_tx_desc *pdesc;
1430 struct rtl_tx_buffer_desc *ptx_bd_desc = NULL;
1427 u8 idx; 1431 u8 idx;
1428 u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb); 1432 u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb);
1429 unsigned long flags; 1433 unsigned long flags;
@@ -1464,17 +1468,22 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
1464 idx = 0; 1468 idx = 0;
1465 1469
1466 pdesc = &ring->desc[idx]; 1470 pdesc = &ring->desc[idx];
1467 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, 1471 if (rtlpriv->use_new_trx_flow) {
1468 true, HW_DESC_OWN); 1472 ptx_bd_desc = &ring->buffer_desc[idx];
1473 } else {
1474 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *)pdesc,
1475 true, HW_DESC_OWN);
1469 1476
1470 if ((own == 1) && (hw_queue != BEACON_QUEUE)) { 1477 if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
1471 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 1478 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1472 "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", 1479 "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n",
1473 hw_queue, ring->idx, idx, 1480 hw_queue, ring->idx, idx,
1474 skb_queue_len(&ring->queue)); 1481 skb_queue_len(&ring->queue));
1475 1482
1476 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); 1483 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
1477 return skb->len; 1484 flags);
1485 return skb->len;
1486 }
1478 } 1487 }
1479 1488
1480 if (ieee80211_is_data_qos(fc)) { 1489 if (ieee80211_is_data_qos(fc)) {
@@ -1494,17 +1503,20 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
1494 rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); 1503 rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
1495 1504
1496 rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, 1505 rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc,
1497 info, sta, skb, hw_queue, ptcb_desc); 1506 (u8 *)ptx_bd_desc, info, sta, skb, hw_queue, ptcb_desc);
1498 1507
1499 __skb_queue_tail(&ring->queue, skb); 1508 __skb_queue_tail(&ring->queue, skb);
1500 1509
1501 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true, 1510 if (rtlpriv->use_new_trx_flow) {
1502 HW_DESC_OWN, &temp_one); 1511 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
1503 1512 HW_DESC_OWN, (u8 *)&hw_queue);
1513 } else {
1514 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
1515 HW_DESC_OWN, (u8 *)&temp_one);
1516 }
1504 1517
1505 if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && 1518 if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
1506 hw_queue != BEACON_QUEUE) { 1519 hw_queue != BEACON_QUEUE) {
1507
1508 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 1520 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1509 "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", 1521 "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n",
1510 hw_queue, ring->idx, idx, 1522 hw_queue, ring->idx, idx,
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index d3262ec45d23..90174a814a6d 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -137,12 +137,22 @@ struct rtl_tx_cmd_desc {
137 u32 dword[16]; 137 u32 dword[16];
138} __packed; 138} __packed;
139 139
140/* In new TRX flow, Buffer_desc is new concept
141 * But TX wifi info == TX descriptor in old flow
142 * RX wifi info == RX descriptor in old flow
143 */
144struct rtl_tx_buffer_desc {
145 u32 dword[8]; /*seg = 4*/
146} __packed;
147
140struct rtl8192_tx_ring { 148struct rtl8192_tx_ring {
141 struct rtl_tx_desc *desc; 149 struct rtl_tx_desc *desc;
142 dma_addr_t dma; 150 dma_addr_t dma;
143 unsigned int idx; 151 unsigned int idx;
144 unsigned int entries; 152 unsigned int entries;
145 struct sk_buff_head queue; 153 struct sk_buff_head queue;
154 /*add for new trx flow*/
155 struct rtl_tx_buffer_desc *buffer_desc; /*tx buffer descriptor*/
146}; 156};
147 157
148struct rtl8192_rx_ring { 158struct rtl8192_rx_ring {
@@ -199,6 +209,10 @@ struct rtl_pci {
199 209
200 u16 shortretry_limit; 210 u16 shortretry_limit;
201 u16 longretry_limit; 211 u16 longretry_limit;
212
213 /* MSI support */
214 bool msi_support;
215 bool using_msi;
202}; 216};
203 217
204struct mp_adapter { 218struct mp_adapter {
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index d1c0191a195b..de7f05f848ef 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -32,6 +32,106 @@
32#include "base.h" 32#include "base.h"
33#include "ps.h" 33#include "ps.h"
34 34
35/* Description:
36 * This routine deals with the Power Configuration CMD
37 * parsing for RTL8723/RTL8188E Series IC.
38 * Assumption:
39 * We should follow specific format that was released from HW SD.
40 */
41bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
42 u8 faversion, u8 interface_type,
43 struct wlan_pwr_cfg pwrcfgcmd[])
44{
45 struct wlan_pwr_cfg cfg_cmd = {0};
46 bool polling_bit = false;
47 u32 ary_idx = 0;
48 u8 value = 0;
49 u32 offset = 0;
50 u32 polling_count = 0;
51 u32 max_polling_cnt = 5000;
52
53 do {
54 cfg_cmd = pwrcfgcmd[ary_idx];
55 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
56 "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x),"
57 "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n",
58 GET_PWR_CFG_OFFSET(cfg_cmd),
59 GET_PWR_CFG_CUT_MASK(cfg_cmd),
60 GET_PWR_CFG_FAB_MASK(cfg_cmd),
61 GET_PWR_CFG_INTF_MASK(cfg_cmd),
62 GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd),
63 GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd));
64
65 if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) &&
66 (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) &&
67 (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) {
68 switch (GET_PWR_CFG_CMD(cfg_cmd)) {
69 case PWR_CMD_READ:
70 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
71 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n");
72 break;
73 case PWR_CMD_WRITE:
74 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
75 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n");
76 offset = GET_PWR_CFG_OFFSET(cfg_cmd);
77
78 /*Read the value from system register*/
79 value = rtl_read_byte(rtlpriv, offset);
80 value &= (~(GET_PWR_CFG_MASK(cfg_cmd)));
81 value |= (GET_PWR_CFG_VALUE(cfg_cmd) &
82 GET_PWR_CFG_MASK(cfg_cmd));
83
84 /*Write the value back to sytem register*/
85 rtl_write_byte(rtlpriv, offset, value);
86 break;
87 case PWR_CMD_POLLING:
88 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
89 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n");
90 polling_bit = false;
91 offset = GET_PWR_CFG_OFFSET(cfg_cmd);
92
93 do {
94 value = rtl_read_byte(rtlpriv, offset);
95
96 value &= GET_PWR_CFG_MASK(cfg_cmd);
97 if (value ==
98 (GET_PWR_CFG_VALUE(cfg_cmd)
99 & GET_PWR_CFG_MASK(cfg_cmd)))
100 polling_bit = true;
101 else
102 udelay(10);
103
104 if (polling_count++ > max_polling_cnt)
105 return false;
106 } while (!polling_bit);
107 break;
108 case PWR_CMD_DELAY:
109 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
110 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n");
111 if (GET_PWR_CFG_VALUE(cfg_cmd) ==
112 PWRSEQ_DELAY_US)
113 udelay(GET_PWR_CFG_OFFSET(cfg_cmd));
114 else
115 mdelay(GET_PWR_CFG_OFFSET(cfg_cmd));
116 break;
117 case PWR_CMD_END:
118 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
119 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n");
120 return true;
121 default:
122 RT_ASSERT(false,
123 "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
124 break;
125 }
126
127 }
128 ary_idx++;
129 } while (1);
130
131 return true;
132}
133EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing);
134
35bool rtl_ps_enable_nic(struct ieee80211_hw *hw) 135bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
36{ 136{
37 struct rtl_priv *rtlpriv = rtl_priv(hw); 137 struct rtl_priv *rtlpriv = rtl_priv(hw);
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h
index 88bd76ea88f7..3bd41f958974 100644
--- a/drivers/net/wireless/rtlwifi/ps.h
+++ b/drivers/net/wireless/rtlwifi/ps.h
@@ -32,6 +32,66 @@
32 32
33#define MAX_SW_LPS_SLEEP_INTV 5 33#define MAX_SW_LPS_SLEEP_INTV 5
34 34
35/*---------------------------------------------
36 * 3 The value of cmd: 4 bits
37 *---------------------------------------------
38 */
39#define PWR_CMD_READ 0x00
40#define PWR_CMD_WRITE 0x01
41#define PWR_CMD_POLLING 0x02
42#define PWR_CMD_DELAY 0x03
43#define PWR_CMD_END 0x04
44
45/* define the base address of each block */
46#define PWR_BASEADDR_MAC 0x00
47#define PWR_BASEADDR_USB 0x01
48#define PWR_BASEADDR_PCIE 0x02
49#define PWR_BASEADDR_SDIO 0x03
50
51#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
52#define PWR_CUT_TESTCHIP_MSK BIT(0)
53#define PWR_CUT_A_MSK BIT(1)
54#define PWR_CUT_B_MSK BIT(2)
55#define PWR_CUT_C_MSK BIT(3)
56#define PWR_CUT_D_MSK BIT(4)
57#define PWR_CUT_E_MSK BIT(5)
58#define PWR_CUT_F_MSK BIT(6)
59#define PWR_CUT_G_MSK BIT(7)
60#define PWR_CUT_ALL_MSK 0xFF
61#define PWR_INTF_SDIO_MSK BIT(0)
62#define PWR_INTF_USB_MSK BIT(1)
63#define PWR_INTF_PCI_MSK BIT(2)
64#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
65
66enum pwrseq_delay_unit {
67 PWRSEQ_DELAY_US,
68 PWRSEQ_DELAY_MS,
69};
70
71struct wlan_pwr_cfg {
72 u16 offset;
73 u8 cut_msk;
74 u8 fab_msk:4;
75 u8 interface_msk:4;
76 u8 base:4;
77 u8 cmd:4;
78 u8 msk;
79 u8 value;
80};
81
82#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset)
83#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk)
84#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk)
85#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk)
86#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base)
87#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd)
88#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk)
89#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value)
90
91bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
92 u8 fab_version, u8 interface_type,
93 struct wlan_pwr_cfg pwrcfgcmd[]);
94
35bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, 95bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
36 enum rf_pwrstate state_toset, u32 changesource); 96 enum rf_pwrstate state_toset, u32 changesource);
37bool rtl_ps_enable_nic(struct ieee80211_hw *hw); 97bool rtl_ps_enable_nic(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile b/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile
index 5b194e97f4b3..a85419a37651 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile
@@ -5,7 +5,6 @@ rtl8188ee-objs := \
5 led.o \ 5 led.o \
6 phy.o \ 6 phy.o \
7 pwrseq.o \ 7 pwrseq.o \
8 pwrseqcmd.o \
9 rf.o \ 8 rf.o \
10 sw.o \ 9 sw.o \
11 table.o \ 10 table.o \
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
index a6184b6e1d57..97bc9aa5e1d1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
@@ -235,7 +235,7 @@ void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,
235 u8 pwr_val = 0; 235 u8 pwr_val = 0;
236 u8 cck_base = rtldm->swing_idx_cck_base; 236 u8 cck_base = rtldm->swing_idx_cck_base;
237 u8 cck_val = rtldm->swing_idx_cck; 237 u8 cck_val = rtldm->swing_idx_cck;
238 u8 ofdm_base = rtldm->swing_idx_ofdm_base; 238 u8 ofdm_base = rtldm->swing_idx_ofdm_base[0];
239 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A]; 239 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
240 240
241 if (type == 0) { 241 if (type == 0) {
@@ -726,7 +726,7 @@ static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw)
726 static u64 last_rx; 726 static u64 last_rx;
727 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff; 727 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
728 728
729 if (rtlhal->oem_id == RT_CID_819x_HP) { 729 if (rtlhal->oem_id == RT_CID_819X_HP) {
730 u64 cur_txok_cnt = 0; 730 u64 cur_txok_cnt = 0;
731 u64 cur_rxok_cnt = 0; 731 u64 cur_rxok_cnt = 0;
732 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok; 732 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok;
@@ -912,7 +912,7 @@ static void rtl88e_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
912 for (i = 0; i < OFDM_TABLE_LENGTH; i++) { 912 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
913 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { 913 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
914 ofdm_old[0] = (u8) i; 914 ofdm_old[0] = (u8) i;
915 rtldm->swing_idx_ofdm_base = (u8)i; 915 rtldm->swing_idx_ofdm_base[0] = (u8)i;
916 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 916 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
917 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n", 917 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
918 ROFDM0_XATXIQIMBAL, 918 ROFDM0_XATXIQIMBAL,
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
index e06971be7df7..bd2a26bafb69 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
@@ -41,7 +41,6 @@
41#include "fw.h" 41#include "fw.h"
42#include "led.h" 42#include "led.h"
43#include "hw.h" 43#include "hw.h"
44#include "pwrseqcmd.h"
45#include "pwrseq.h" 44#include "pwrseq.h"
46 45
47#define LLT_CONFIG 5 46#define LLT_CONFIG 5
@@ -509,7 +508,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
509 u8 e_aci = *((u8 *)val); 508 u8 e_aci = *((u8 *)val);
510 rtl88e_dm_init_edca_turbo(hw); 509 rtl88e_dm_init_edca_turbo(hw);
511 510
512 if (rtlpci->acm_method != eAcmWay2_SW) 511 if (rtlpci->acm_method != EACMWAY2_SW)
513 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, 512 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
514 (u8 *)(&e_aci)); 513 (u8 *)(&e_aci));
515 break; } 514 break; }
@@ -815,11 +814,11 @@ static bool _rtl88ee_init_mac(struct ieee80211_hw *hw)
815 814
816 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); 815 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
817 /* HW Power on sequence */ 816 /* HW Power on sequence */
818 if (!rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, 817 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
819 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, 818 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
820 Rtl8188E_NIC_ENABLE_FLOW)) { 819 Rtl8188E_NIC_ENABLE_FLOW)) {
821 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 820 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
822 "init MAC Fail as rtl88_hal_pwrseqcmdparsing\n"); 821 "init MAC Fail as rtl_hal_pwrseqcmdparsing\n");
823 return false; 822 return false;
824 } 823 }
825 824
@@ -1025,9 +1024,20 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
1025 bool rtstatus = true; 1024 bool rtstatus = true;
1026 int err = 0; 1025 int err = 0;
1027 u8 tmp_u1b, u1byte; 1026 u8 tmp_u1b, u1byte;
1027 unsigned long flags;
1028 1028
1029 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Rtl8188EE hw init\n"); 1029 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Rtl8188EE hw init\n");
1030 rtlpriv->rtlhal.being_init_adapter = true; 1030 rtlpriv->rtlhal.being_init_adapter = true;
1031 /* As this function can take a very long time (up to 350 ms)
1032 * and can be called with irqs disabled, reenable the irqs
1033 * to let the other devices continue being serviced.
1034 *
1035 * It is safe doing so since our own interrupts will only be enabled
1036 * in a subsequent step.
1037 */
1038 local_save_flags(flags);
1039 local_irq_enable();
1040
1031 rtlpriv->intf_ops->disable_aspm(hw); 1041 rtlpriv->intf_ops->disable_aspm(hw);
1032 1042
1033 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1); 1043 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1);
@@ -1043,7 +1053,7 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
1043 if (rtstatus != true) { 1053 if (rtstatus != true) {
1044 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); 1054 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
1045 err = 1; 1055 err = 1;
1046 return err; 1056 goto exit;
1047 } 1057 }
1048 1058
1049 err = rtl88e_download_fw(hw, false); 1059 err = rtl88e_download_fw(hw, false);
@@ -1051,8 +1061,7 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
1051 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 1061 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1052 "Failed to download FW. Init HW without FW now..\n"); 1062 "Failed to download FW. Init HW without FW now..\n");
1053 err = 1; 1063 err = 1;
1054 rtlhal->fw_ready = false; 1064 goto exit;
1055 return err;
1056 } else { 1065 } else {
1057 rtlhal->fw_ready = true; 1066 rtlhal->fw_ready = true;
1058 } 1067 }
@@ -1097,7 +1106,7 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
1097 if (ppsc->rfpwr_state == ERFON) { 1106 if (ppsc->rfpwr_state == ERFON) {
1098 if ((rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) || 1107 if ((rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) ||
1099 ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) && 1108 ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) &&
1100 (rtlhal->oem_id == RT_CID_819x_HP))) { 1109 (rtlhal->oem_id == RT_CID_819X_HP))) {
1101 rtl88e_phy_set_rfpath_switch(hw, true); 1110 rtl88e_phy_set_rfpath_switch(hw, true);
1102 rtlpriv->dm.fat_table.rx_idle_ant = MAIN_ANT; 1111 rtlpriv->dm.fat_table.rx_idle_ant = MAIN_ANT;
1103 } else { 1112 } else {
@@ -1135,10 +1144,12 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
1135 } 1144 }
1136 rtl_write_byte(rtlpriv, REG_NAV_CTRL+2, ((30000+127)/128)); 1145 rtl_write_byte(rtlpriv, REG_NAV_CTRL+2, ((30000+127)/128));
1137 rtl88e_dm_init(hw); 1146 rtl88e_dm_init(hw);
1147exit:
1148 local_irq_restore(flags);
1138 rtlpriv->rtlhal.being_init_adapter = false; 1149 rtlpriv->rtlhal.being_init_adapter = false;
1139 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "end of Rtl8188EE hw init %x\n", 1150 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "end of Rtl8188EE hw init %x\n",
1140 err); 1151 err);
1141 return 0; 1152 return err;
1142} 1153}
1143 1154
1144static enum version_8188e _rtl88ee_read_chip_version(struct ieee80211_hw *hw) 1155static enum version_8188e _rtl88ee_read_chip_version(struct ieee80211_hw *hw)
@@ -1235,12 +1246,13 @@ static int _rtl88ee_set_media_status(struct ieee80211_hw *hw,
1235void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 1246void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1236{ 1247{
1237 struct rtl_priv *rtlpriv = rtl_priv(hw); 1248 struct rtl_priv *rtlpriv = rtl_priv(hw);
1238 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 1249 u32 reg_rcr;
1239 u32 reg_rcr = rtlpci->receive_config;
1240 1250
1241 if (rtlpriv->psc.rfpwr_state != ERFON) 1251 if (rtlpriv->psc.rfpwr_state != ERFON)
1242 return; 1252 return;
1243 1253
1254 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
1255
1244 if (check_bssid == true) { 1256 if (check_bssid == true) {
1245 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); 1257 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1246 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, 1258 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
@@ -1345,9 +1357,9 @@ static void _rtl88ee_poweroff_adapter(struct ieee80211_hw *hw)
1345 } 1357 }
1346 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0xFF); 1358 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0xFF);
1347 1359
1348 rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, 1360 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1349 PWR_INTF_PCI_MSK, 1361 PWR_INTF_PCI_MSK,
1350 Rtl8188E_NIC_LPS_ENTER_FLOW); 1362 Rtl8188E_NIC_LPS_ENTER_FLOW);
1351 1363
1352 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); 1364 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1353 1365
@@ -1361,8 +1373,8 @@ static void _rtl88ee_poweroff_adapter(struct ieee80211_hw *hw)
1361 u1b_tmp = rtl_read_byte(rtlpriv, REG_32K_CTRL); 1373 u1b_tmp = rtl_read_byte(rtlpriv, REG_32K_CTRL);
1362 rtl_write_byte(rtlpriv, REG_32K_CTRL, (u1b_tmp & (~BIT(0)))); 1374 rtl_write_byte(rtlpriv, REG_32K_CTRL, (u1b_tmp & (~BIT(0))));
1363 1375
1364 rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, 1376 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1365 PWR_INTF_PCI_MSK, Rtl8188E_NIC_DISABLE_FLOW); 1377 PWR_INTF_PCI_MSK, Rtl8188E_NIC_DISABLE_FLOW);
1366 1378
1367 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1); 1379 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
1368 rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(3)))); 1380 rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(3))));
@@ -1872,15 +1884,15 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
1872 case EEPROM_CID_DEFAULT: 1884 case EEPROM_CID_DEFAULT:
1873 if (rtlefuse->eeprom_did == 0x8179) { 1885 if (rtlefuse->eeprom_did == 0x8179) {
1874 if (rtlefuse->eeprom_svid == 0x1025) { 1886 if (rtlefuse->eeprom_svid == 0x1025) {
1875 rtlhal->oem_id = RT_CID_819x_Acer; 1887 rtlhal->oem_id = RT_CID_819X_ACER;
1876 } else if ((rtlefuse->eeprom_svid == 0x10EC && 1888 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
1877 rtlefuse->eeprom_smid == 0x0179) || 1889 rtlefuse->eeprom_smid == 0x0179) ||
1878 (rtlefuse->eeprom_svid == 0x17AA && 1890 (rtlefuse->eeprom_svid == 0x17AA &&
1879 rtlefuse->eeprom_smid == 0x0179)) { 1891 rtlefuse->eeprom_smid == 0x0179)) {
1880 rtlhal->oem_id = RT_CID_819x_Lenovo; 1892 rtlhal->oem_id = RT_CID_819X_LENOVO;
1881 } else if (rtlefuse->eeprom_svid == 0x103c && 1893 } else if (rtlefuse->eeprom_svid == 0x103c &&
1882 rtlefuse->eeprom_smid == 0x197d) { 1894 rtlefuse->eeprom_smid == 0x197d) {
1883 rtlhal->oem_id = RT_CID_819x_HP; 1895 rtlhal->oem_id = RT_CID_819X_HP;
1884 } else { 1896 } else {
1885 rtlhal->oem_id = RT_CID_DEFAULT; 1897 rtlhal->oem_id = RT_CID_DEFAULT;
1886 } 1898 }
@@ -1892,7 +1904,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
1892 rtlhal->oem_id = RT_CID_TOSHIBA; 1904 rtlhal->oem_id = RT_CID_TOSHIBA;
1893 break; 1905 break;
1894 case EEPROM_CID_QMI: 1906 case EEPROM_CID_QMI:
1895 rtlhal->oem_id = RT_CID_819x_QMI; 1907 rtlhal->oem_id = RT_CID_819X_QMI;
1896 break; 1908 break;
1897 case EEPROM_CID_WHQL: 1909 case EEPROM_CID_WHQL:
1898 default: 1910 default:
@@ -1911,14 +1923,14 @@ static void _rtl88ee_hal_customized_behavior(struct ieee80211_hw *hw)
1911 pcipriv->ledctl.led_opendrain = true; 1923 pcipriv->ledctl.led_opendrain = true;
1912 1924
1913 switch (rtlhal->oem_id) { 1925 switch (rtlhal->oem_id) {
1914 case RT_CID_819x_HP: 1926 case RT_CID_819X_HP:
1915 pcipriv->ledctl.led_opendrain = true; 1927 pcipriv->ledctl.led_opendrain = true;
1916 break; 1928 break;
1917 case RT_CID_819x_Lenovo: 1929 case RT_CID_819X_LENOVO:
1918 case RT_CID_DEFAULT: 1930 case RT_CID_DEFAULT:
1919 case RT_CID_TOSHIBA: 1931 case RT_CID_TOSHIBA:
1920 case RT_CID_CCX: 1932 case RT_CID_CCX:
1921 case RT_CID_819x_Acer: 1933 case RT_CID_819X_ACER:
1922 case RT_CID_WHQL: 1934 case RT_CID_WHQL:
1923 default: 1935 default:
1924 break; 1936 break;
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
index d67f9c731cc4..1cd6c16d597e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
@@ -29,6 +29,7 @@
29 29
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "../core.h"
32#include "../ps.h" 33#include "../ps.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
@@ -151,18 +152,7 @@ static bool config_bb_with_pgheader(struct ieee80211_hw *hw,
151 v2 = table_pg[i + 1]; 152 v2 = table_pg[i + 1];
152 153
153 if (v1 < 0xcdcdcdcd) { 154 if (v1 < 0xcdcdcdcd) {
154 if (table_pg[i] == 0xfe) 155 rtl_addr_delay(table_pg[i]);
155 mdelay(50);
156 else if (table_pg[i] == 0xfd)
157 mdelay(5);
158 else if (table_pg[i] == 0xfc)
159 mdelay(1);
160 else if (table_pg[i] == 0xfb)
161 udelay(50);
162 else if (table_pg[i] == 0xfa)
163 udelay(5);
164 else if (table_pg[i] == 0xf9)
165 udelay(1);
166 156
167 store_pwrindex_offset(hw, table_pg[i], 157 store_pwrindex_offset(hw, table_pg[i],
168 table_pg[i + 1], 158 table_pg[i + 1],
@@ -672,24 +662,9 @@ static void _rtl8188e_config_rf_reg(struct ieee80211_hw *hw,
672 u32 addr, u32 data, enum radio_path rfpath, 662 u32 addr, u32 data, enum radio_path rfpath,
673 u32 regaddr) 663 u32 regaddr)
674{ 664{
675 if (addr == 0xffe) { 665 rtl_rfreg_delay(hw, rfpath, regaddr,
676 mdelay(50); 666 RFREG_OFFSET_MASK,
677 } else if (addr == 0xfd) { 667 data);
678 mdelay(5);
679 } else if (addr == 0xfc) {
680 mdelay(1);
681 } else if (addr == 0xfb) {
682 udelay(50);
683 } else if (addr == 0xfa) {
684 udelay(5);
685 } else if (addr == 0xf9) {
686 udelay(1);
687 } else {
688 rtl_set_rfreg(hw, rfpath, regaddr,
689 RFREG_OFFSET_MASK,
690 data);
691 udelay(1);
692 }
693} 668}
694 669
695static void rtl88_config_s(struct ieee80211_hw *hw, 670static void rtl88_config_s(struct ieee80211_hw *hw,
@@ -702,28 +677,6 @@ static void rtl88_config_s(struct ieee80211_hw *hw,
702 addr | maskforphyset); 677 addr | maskforphyset);
703} 678}
704 679
705static void _rtl8188e_config_bb_reg(struct ieee80211_hw *hw,
706 u32 addr, u32 data)
707{
708 if (addr == 0xfe) {
709 mdelay(50);
710 } else if (addr == 0xfd) {
711 mdelay(5);
712 } else if (addr == 0xfc) {
713 mdelay(1);
714 } else if (addr == 0xfb) {
715 udelay(50);
716 } else if (addr == 0xfa) {
717 udelay(5);
718 } else if (addr == 0xf9) {
719 udelay(1);
720 } else {
721 rtl_set_bbreg(hw, addr, MASKDWORD, data);
722 udelay(1);
723 }
724}
725
726
727#define NEXT_PAIR(v1, v2, i) \ 680#define NEXT_PAIR(v1, v2, i) \
728 do { \ 681 do { \
729 i += 2; v1 = array_table[i]; \ 682 i += 2; v1 = array_table[i]; \
@@ -795,7 +748,7 @@ static void set_baseband_phy_config(struct ieee80211_hw *hw)
795 v1 = array_table[i]; 748 v1 = array_table[i];
796 v2 = array_table[i + 1]; 749 v2 = array_table[i + 1];
797 if (v1 < 0xcdcdcdcd) { 750 if (v1 < 0xcdcdcdcd) {
798 _rtl8188e_config_bb_reg(hw, v1, v2); 751 rtl_bb_delay(hw, v1, v2);
799 } else {/*This line is the start line of branch.*/ 752 } else {/*This line is the start line of branch.*/
800 if (!check_cond(hw, array_table[i])) { 753 if (!check_cond(hw, array_table[i])) {
801 /*Discard the following (offset, data) pairs*/ 754 /*Discard the following (offset, data) pairs*/
@@ -811,7 +764,7 @@ static void set_baseband_phy_config(struct ieee80211_hw *hw)
811 while (v2 != 0xDEAD && 764 while (v2 != 0xDEAD &&
812 v2 != 0xCDEF && 765 v2 != 0xCDEF &&
813 v2 != 0xCDCD && i < arraylen - 2) { 766 v2 != 0xCDCD && i < arraylen - 2) {
814 _rtl8188e_config_bb_reg(hw, v1, v2); 767 rtl_bb_delay(hw, v1, v2);
815 NEXT_PAIR(v1, v2, i); 768 NEXT_PAIR(v1, v2, i);
816 } 769 }
817 770
@@ -1002,7 +955,7 @@ bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
1002 } 955 }
1003 } 956 }
1004 957
1005 if (rtlhal->oem_id == RT_CID_819x_HP) 958 if (rtlhal->oem_id == RT_CID_819X_HP)
1006 rtl88_config_s(hw, 0x52, 0x7E4BD); 959 rtl88_config_s(hw, 0x52, 0x7E4BD);
1007 960
1008 break; 961 break;
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h
index 028ec6dd52b4..32e135ab9a63 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h
@@ -30,7 +30,6 @@
30#ifndef __RTL8723E_PWRSEQ_H__ 30#ifndef __RTL8723E_PWRSEQ_H__
31#define __RTL8723E_PWRSEQ_H__ 31#define __RTL8723E_PWRSEQ_H__
32 32
33#include "pwrseqcmd.h"
34/* 33/*
35 Check document WM-20110607-Paul-RTL8188E_Power_Architecture-R02.vsd 34 Check document WM-20110607-Paul-RTL8188E_Power_Architecture-R02.vsd
36 There are 6 HW Power States: 35 There are 6 HW Power States:
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
index d849abf7d94a..7af85cfa8f87 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
@@ -2215,22 +2215,6 @@
2215#define BWORD1 0xc 2215#define BWORD1 0xc
2216#define BWORD 0xf 2216#define BWORD 0xf
2217 2217
2218#define MASKBYTE0 0xff
2219#define MASKBYTE1 0xff00
2220#define MASKBYTE2 0xff0000
2221#define MASKBYTE3 0xff000000
2222#define MASKHWORD 0xffff0000
2223#define MASKLWORD 0x0000ffff
2224#define MASKDWORD 0xffffffff
2225#define MASK12BITS 0xfff
2226#define MASKH4BITS 0xf0000000
2227#define MASKOFDM_D 0xffc00000
2228#define MASKCCK 0x3f3f3f3f
2229
2230#define MASK4BITS 0x0f
2231#define MASK20BITS 0xfffff
2232#define RFREG_OFFSET_MASK 0xfffff
2233
2234#define BENABLE 0x1 2218#define BENABLE 0x1
2235#define BDISABLE 0x0 2219#define BDISABLE 0x0
2236 2220
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
index 27ace3054d56..2ba6f510d884 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
@@ -489,9 +489,8 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
489 489
490void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw, 490void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,
491 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 491 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
492 struct ieee80211_tx_info *info, 492 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
493 struct ieee80211_sta *sta, 493 struct ieee80211_sta *sta, struct sk_buff *skb,
494 struct sk_buff *skb,
495 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) 494 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
496{ 495{
497 struct rtl_priv *rtlpriv = rtl_priv(hw); 496 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -734,7 +733,8 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
734 pdesc, TX_DESC_SIZE); 733 pdesc, TX_DESC_SIZE);
735} 734}
736 735
737void rtl88ee_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) 736void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
737 u8 desc_name, u8 *val)
738{ 738{
739 if (istx == true) { 739 if (istx == true) {
740 switch (desc_name) { 740 switch (desc_name) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h
index 21ca33a7c770..8c2609412d2c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h
@@ -777,15 +777,15 @@ struct rx_desc_88e {
777 777
778void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw, 778void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,
779 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 779 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
780 struct ieee80211_tx_info *info, 780 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
781 struct ieee80211_sta *sta, 781 struct ieee80211_sta *sta, struct sk_buff *skb,
782 struct sk_buff *skb,
783 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); 782 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
784bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw, 783bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
785 struct rtl_stats *status, 784 struct rtl_stats *status,
786 struct ieee80211_rx_status *rx_status, 785 struct ieee80211_rx_status *rx_status,
787 u8 *pdesc, struct sk_buff *skb); 786 u8 *pdesc, struct sk_buff *skb);
788void rtl88ee_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); 787void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
788 u8 desc_name, u8 *val);
789u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name); 789u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name);
790void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); 790void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
791void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, 791void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index 2eb0b38384dd..4ae51d5b436f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -319,7 +319,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
319 u8 e_aci = *(val); 319 u8 e_aci = *(val);
320 rtl92c_dm_init_edca_turbo(hw); 320 rtl92c_dm_init_edca_turbo(hw);
321 321
322 if (rtlpci->acm_method != eAcmWay2_SW) 322 if (rtlpci->acm_method != EACMWAY2_SW)
323 rtlpriv->cfg->ops->set_hw_reg(hw, 323 rtlpriv->cfg->ops->set_hw_reg(hw,
324 HW_VAR_ACM_CTRL, 324 HW_VAR_ACM_CTRL,
325 (&e_aci)); 325 (&e_aci));
@@ -542,9 +542,11 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
542 (u8 *)(&fw_current_inps)); 542 (u8 *)(&fw_current_inps));
543 } 543 }
544 break; } 544 break; }
545 case HW_VAR_KEEP_ALIVE:
546 break;
545 default: 547 default:
546 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 548 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
547 "switch case not processed\n"); 549 "switch case %d not processed\n", variable);
548 break; 550 break;
549 } 551 }
550} 552}
@@ -1214,11 +1216,13 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
1214void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 1216void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1215{ 1217{
1216 struct rtl_priv *rtlpriv = rtl_priv(hw); 1218 struct rtl_priv *rtlpriv = rtl_priv(hw);
1217 u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); 1219 u32 reg_rcr;
1218 1220
1219 if (rtlpriv->psc.rfpwr_state != ERFON) 1221 if (rtlpriv->psc.rfpwr_state != ERFON)
1220 return; 1222 return;
1221 1223
1224 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
1225
1222 if (check_bssid) { 1226 if (check_bssid) {
1223 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); 1227 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1224 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, 1228 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
@@ -1734,7 +1738,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
1734 if (rtlefuse->eeprom_did == 0x8176) { 1738 if (rtlefuse->eeprom_did == 0x8176) {
1735 if ((rtlefuse->eeprom_svid == 0x103C && 1739 if ((rtlefuse->eeprom_svid == 0x103C &&
1736 rtlefuse->eeprom_smid == 0x1629)) 1740 rtlefuse->eeprom_smid == 0x1629))
1737 rtlhal->oem_id = RT_CID_819x_HP; 1741 rtlhal->oem_id = RT_CID_819X_HP;
1738 else 1742 else
1739 rtlhal->oem_id = RT_CID_DEFAULT; 1743 rtlhal->oem_id = RT_CID_DEFAULT;
1740 } else { 1744 } else {
@@ -1745,7 +1749,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
1745 rtlhal->oem_id = RT_CID_TOSHIBA; 1749 rtlhal->oem_id = RT_CID_TOSHIBA;
1746 break; 1750 break;
1747 case EEPROM_CID_QMI: 1751 case EEPROM_CID_QMI:
1748 rtlhal->oem_id = RT_CID_819x_QMI; 1752 rtlhal->oem_id = RT_CID_819X_QMI;
1749 break; 1753 break;
1750 case EEPROM_CID_WHQL: 1754 case EEPROM_CID_WHQL:
1751 default: 1755 default:
@@ -1764,14 +1768,14 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw)
1764 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1768 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1765 1769
1766 switch (rtlhal->oem_id) { 1770 switch (rtlhal->oem_id) {
1767 case RT_CID_819x_HP: 1771 case RT_CID_819X_HP:
1768 pcipriv->ledctl.led_opendrain = true; 1772 pcipriv->ledctl.led_opendrain = true;
1769 break; 1773 break;
1770 case RT_CID_819x_Lenovo: 1774 case RT_CID_819X_LENOVO:
1771 case RT_CID_DEFAULT: 1775 case RT_CID_DEFAULT:
1772 case RT_CID_TOSHIBA: 1776 case RT_CID_TOSHIBA:
1773 case RT_CID_CCX: 1777 case RT_CID_CCX:
1774 case RT_CID_819x_Acer: 1778 case RT_CID_819X_ACER:
1775 case RT_CID_WHQL: 1779 case RT_CID_WHQL:
1776 default: 1780 default:
1777 break; 1781 break;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
index 73262ca3864b..98b22303c84d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -30,6 +30,7 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "../ps.h" 32#include "../ps.h"
33#include "../core.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "hw.h" 36#include "hw.h"
@@ -198,18 +199,7 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
198 } 199 }
199 if (configtype == BASEBAND_CONFIG_PHY_REG) { 200 if (configtype == BASEBAND_CONFIG_PHY_REG) {
200 for (i = 0; i < phy_reg_arraylen; i = i + 2) { 201 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
201 if (phy_regarray_table[i] == 0xfe) 202 rtl_addr_delay(phy_regarray_table[i]);
202 mdelay(50);
203 else if (phy_regarray_table[i] == 0xfd)
204 mdelay(5);
205 else if (phy_regarray_table[i] == 0xfc)
206 mdelay(1);
207 else if (phy_regarray_table[i] == 0xfb)
208 udelay(50);
209 else if (phy_regarray_table[i] == 0xfa)
210 udelay(5);
211 else if (phy_regarray_table[i] == 0xf9)
212 udelay(1);
213 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, 203 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
214 phy_regarray_table[i + 1]); 204 phy_regarray_table[i + 1]);
215 udelay(1); 205 udelay(1);
@@ -245,18 +235,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
245 235
246 if (configtype == BASEBAND_CONFIG_PHY_REG) { 236 if (configtype == BASEBAND_CONFIG_PHY_REG) {
247 for (i = 0; i < phy_regarray_pg_len; i = i + 3) { 237 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
248 if (phy_regarray_table_pg[i] == 0xfe) 238 rtl_addr_delay(phy_regarray_table_pg[i]);
249 mdelay(50);
250 else if (phy_regarray_table_pg[i] == 0xfd)
251 mdelay(5);
252 else if (phy_regarray_table_pg[i] == 0xfc)
253 mdelay(1);
254 else if (phy_regarray_table_pg[i] == 0xfb)
255 udelay(50);
256 else if (phy_regarray_table_pg[i] == 0xfa)
257 udelay(5);
258 else if (phy_regarray_table_pg[i] == 0xf9)
259 udelay(1);
260 239
261 _rtl92c_store_pwrIndex_diffrate_offset(hw, 240 _rtl92c_store_pwrIndex_diffrate_offset(hw,
262 phy_regarray_table_pg[i], 241 phy_regarray_table_pg[i],
@@ -305,46 +284,16 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
305 switch (rfpath) { 284 switch (rfpath) {
306 case RF90_PATH_A: 285 case RF90_PATH_A:
307 for (i = 0; i < radioa_arraylen; i = i + 2) { 286 for (i = 0; i < radioa_arraylen; i = i + 2) {
308 if (radioa_array_table[i] == 0xfe) 287 rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
309 mdelay(50); 288 RFREG_OFFSET_MASK,
310 else if (radioa_array_table[i] == 0xfd) 289 radioa_array_table[i + 1]);
311 mdelay(5);
312 else if (radioa_array_table[i] == 0xfc)
313 mdelay(1);
314 else if (radioa_array_table[i] == 0xfb)
315 udelay(50);
316 else if (radioa_array_table[i] == 0xfa)
317 udelay(5);
318 else if (radioa_array_table[i] == 0xf9)
319 udelay(1);
320 else {
321 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
322 RFREG_OFFSET_MASK,
323 radioa_array_table[i + 1]);
324 udelay(1);
325 }
326 } 290 }
327 break; 291 break;
328 case RF90_PATH_B: 292 case RF90_PATH_B:
329 for (i = 0; i < radiob_arraylen; i = i + 2) { 293 for (i = 0; i < radiob_arraylen; i = i + 2) {
330 if (radiob_array_table[i] == 0xfe) { 294 rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
331 mdelay(50); 295 RFREG_OFFSET_MASK,
332 } else if (radiob_array_table[i] == 0xfd) 296 radiob_array_table[i + 1]);
333 mdelay(5);
334 else if (radiob_array_table[i] == 0xfc)
335 mdelay(1);
336 else if (radiob_array_table[i] == 0xfb)
337 udelay(50);
338 else if (radiob_array_table[i] == 0xfa)
339 udelay(5);
340 else if (radiob_array_table[i] == 0xf9)
341 udelay(1);
342 else {
343 rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
344 RFREG_OFFSET_MASK,
345 radiob_array_table[i + 1]);
346 udelay(1);
347 }
348 } 297 }
349 break; 298 break;
350 case RF90_PATH_C: 299 case RF90_PATH_C:
@@ -355,6 +304,8 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
355 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 304 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
356 "switch case not processed\n"); 305 "switch case not processed\n");
357 break; 306 break;
307 default:
308 break;
358 } 309 }
359 return true; 310 return true;
360} 311}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
index 8922ecb47ad2..ed703a1b3b7c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
@@ -2044,22 +2044,6 @@
2044#define BWORD1 0xc 2044#define BWORD1 0xc
2045#define BWORD 0xf 2045#define BWORD 0xf
2046 2046
2047#define MASKBYTE0 0xff
2048#define MASKBYTE1 0xff00
2049#define MASKBYTE2 0xff0000
2050#define MASKBYTE3 0xff000000
2051#define MASKHWORD 0xffff0000
2052#define MASKLWORD 0x0000ffff
2053#define MASKDWORD 0xffffffff
2054#define MASK12BITS 0xfff
2055#define MASKH4BITS 0xf0000000
2056#define MASKOFDM_D 0xffc00000
2057#define MASKCCK 0x3f3f3f3f
2058
2059#define MASK4BITS 0x0f
2060#define MASK20BITS 0xfffff
2061#define RFREG_OFFSET_MASK 0xfffff
2062
2063#define BENABLE 0x1 2047#define BENABLE 0x1
2064#define BDISABLE 0x0 2048#define BDISABLE 0x0
2065 2049
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index 114858d46158..8f04817cb7ec 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -426,7 +426,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
426 426
427void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, 427void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
428 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 428 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
429 struct ieee80211_tx_info *info, 429 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
430 struct ieee80211_sta *sta, 430 struct ieee80211_sta *sta,
431 struct sk_buff *skb, 431 struct sk_buff *skb,
432 u8 hw_queue, struct rtl_tcb_desc *tcb_desc) 432 u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
@@ -666,7 +666,8 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
666 "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); 666 "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
667} 667}
668 668
669void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) 669void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
670 u8 desc_name, u8 *val)
670{ 671{
671 if (istx) { 672 if (istx) {
672 switch (desc_name) { 673 switch (desc_name) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
index a7cdd514cb2e..9a39ec4204dd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
@@ -711,8 +711,8 @@ struct rx_desc_92c {
711} __packed; 711} __packed;
712 712
713void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, 713void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
714 struct ieee80211_hdr *hdr, 714 struct ieee80211_hdr *hdr, u8 *pdesc,
715 u8 *pdesc, struct ieee80211_tx_info *info, 715 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
716 struct ieee80211_sta *sta, 716 struct ieee80211_sta *sta,
717 struct sk_buff *skb, u8 hw_queue, 717 struct sk_buff *skb, u8 hw_queue,
718 struct rtl_tcb_desc *ptcb_desc); 718 struct rtl_tcb_desc *ptcb_desc);
@@ -720,7 +720,8 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
720 struct rtl_stats *stats, 720 struct rtl_stats *stats,
721 struct ieee80211_rx_status *rx_status, 721 struct ieee80211_rx_status *rx_status,
722 u8 *pdesc, struct sk_buff *skb); 722 u8 *pdesc, struct sk_buff *skb);
723void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); 723void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
724 u8 desc_name, u8 *val);
724u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name); 725u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);
725void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); 726void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
726void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, 727void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 468bf73cc883..68b5c7e92cfb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -394,7 +394,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
394 if (rtlefuse->eeprom_did == 0x8176) { 394 if (rtlefuse->eeprom_did == 0x8176) {
395 if ((rtlefuse->eeprom_svid == 0x103C && 395 if ((rtlefuse->eeprom_svid == 0x103C &&
396 rtlefuse->eeprom_smid == 0x1629)) 396 rtlefuse->eeprom_smid == 0x1629))
397 rtlhal->oem_id = RT_CID_819x_HP; 397 rtlhal->oem_id = RT_CID_819X_HP;
398 else 398 else
399 rtlhal->oem_id = RT_CID_DEFAULT; 399 rtlhal->oem_id = RT_CID_DEFAULT;
400 } else { 400 } else {
@@ -405,7 +405,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
405 rtlhal->oem_id = RT_CID_TOSHIBA; 405 rtlhal->oem_id = RT_CID_TOSHIBA;
406 break; 406 break;
407 case EEPROM_CID_QMI: 407 case EEPROM_CID_QMI:
408 rtlhal->oem_id = RT_CID_819x_QMI; 408 rtlhal->oem_id = RT_CID_819X_QMI;
409 break; 409 break;
410 case EEPROM_CID_WHQL: 410 case EEPROM_CID_WHQL:
411 default: 411 default:
@@ -423,14 +423,14 @@ static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw)
423 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 423 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
424 424
425 switch (rtlhal->oem_id) { 425 switch (rtlhal->oem_id) {
426 case RT_CID_819x_HP: 426 case RT_CID_819X_HP:
427 usb_priv->ledctl.led_opendrain = true; 427 usb_priv->ledctl.led_opendrain = true;
428 break; 428 break;
429 case RT_CID_819x_Lenovo: 429 case RT_CID_819X_LENOVO:
430 case RT_CID_DEFAULT: 430 case RT_CID_DEFAULT:
431 case RT_CID_TOSHIBA: 431 case RT_CID_TOSHIBA:
432 case RT_CID_CCX: 432 case RT_CID_CCX:
433 case RT_CID_819x_Acer: 433 case RT_CID_819X_ACER:
434 case RT_CID_WHQL: 434 case RT_CID_WHQL:
435 default: 435 default:
436 break; 436 break;
@@ -985,6 +985,17 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
985 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 985 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
986 int err = 0; 986 int err = 0;
987 static bool iqk_initialized; 987 static bool iqk_initialized;
988 unsigned long flags;
989
990 /* As this function can take a very long time (up to 350 ms)
991 * and can be called with irqs disabled, reenable the irqs
992 * to let the other devices continue being serviced.
993 *
994 * It is safe doing so since our own interrupts will only be enabled
995 * in a subsequent step.
996 */
997 local_save_flags(flags);
998 local_irq_enable();
988 999
989 rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; 1000 rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU;
990 err = _rtl92cu_init_mac(hw); 1001 err = _rtl92cu_init_mac(hw);
@@ -997,7 +1008,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
997 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 1008 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
998 "Failed to download FW. Init HW without FW now..\n"); 1009 "Failed to download FW. Init HW without FW now..\n");
999 err = 1; 1010 err = 1;
1000 return err; 1011 goto exit;
1001 } 1012 }
1002 rtlhal->last_hmeboxnum = 0; /* h2c */ 1013 rtlhal->last_hmeboxnum = 0; /* h2c */
1003 _rtl92cu_phy_param_tab_init(hw); 1014 _rtl92cu_phy_param_tab_init(hw);
@@ -1034,6 +1045,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
1034 _InitPABias(hw); 1045 _InitPABias(hw);
1035 _update_mac_setting(hw); 1046 _update_mac_setting(hw);
1036 rtl92c_dm_init(hw); 1047 rtl92c_dm_init(hw);
1048exit:
1049 local_irq_restore(flags);
1037 return err; 1050 return err;
1038} 1051}
1039 1052
@@ -1379,11 +1392,13 @@ void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1379{ 1392{
1380 struct rtl_priv *rtlpriv = rtl_priv(hw); 1393 struct rtl_priv *rtlpriv = rtl_priv(hw);
1381 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 1394 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1382 u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); 1395 u32 reg_rcr;
1383 1396
1384 if (rtlpriv->psc.rfpwr_state != ERFON) 1397 if (rtlpriv->psc.rfpwr_state != ERFON)
1385 return; 1398 return;
1386 1399
1400 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
1401
1387 if (check_bssid) { 1402 if (check_bssid) {
1388 u8 tmp; 1403 u8 tmp;
1389 if (IS_NORMAL_CHIP(rtlhal->version)) { 1404 if (IS_NORMAL_CHIP(rtlhal->version)) {
@@ -1795,7 +1810,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
1795 e_aci); 1810 e_aci);
1796 break; 1811 break;
1797 } 1812 }
1798 if (rtlusb->acm_method != eAcmWay2_SW) 1813 if (rtlusb->acm_method != EACMWAY2_SW)
1799 rtlpriv->cfg->ops->set_hw_reg(hw, 1814 rtlpriv->cfg->ops->set_hw_reg(hw,
1800 HW_VAR_ACM_CTRL, &e_aci); 1815 HW_VAR_ACM_CTRL, &e_aci);
1801 break; 1816 break;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
index 0c09240eadcc..9831ff1128ca 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
@@ -30,6 +30,7 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "../ps.h" 32#include "../ps.h"
33#include "../core.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "phy.h" 36#include "phy.h"
@@ -188,18 +189,7 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
188 } 189 }
189 if (configtype == BASEBAND_CONFIG_PHY_REG) { 190 if (configtype == BASEBAND_CONFIG_PHY_REG) {
190 for (i = 0; i < phy_reg_arraylen; i = i + 2) { 191 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
191 if (phy_regarray_table[i] == 0xfe) 192 rtl_addr_delay(phy_regarray_table[i]);
192 mdelay(50);
193 else if (phy_regarray_table[i] == 0xfd)
194 mdelay(5);
195 else if (phy_regarray_table[i] == 0xfc)
196 mdelay(1);
197 else if (phy_regarray_table[i] == 0xfb)
198 udelay(50);
199 else if (phy_regarray_table[i] == 0xfa)
200 udelay(5);
201 else if (phy_regarray_table[i] == 0xf9)
202 udelay(1);
203 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, 193 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
204 phy_regarray_table[i + 1]); 194 phy_regarray_table[i + 1]);
205 udelay(1); 195 udelay(1);
@@ -236,18 +226,7 @@ bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
236 phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata; 226 phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata;
237 if (configtype == BASEBAND_CONFIG_PHY_REG) { 227 if (configtype == BASEBAND_CONFIG_PHY_REG) {
238 for (i = 0; i < phy_regarray_pg_len; i = i + 3) { 228 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
239 if (phy_regarray_table_pg[i] == 0xfe) 229 rtl_addr_delay(phy_regarray_table_pg[i]);
240 mdelay(50);
241 else if (phy_regarray_table_pg[i] == 0xfd)
242 mdelay(5);
243 else if (phy_regarray_table_pg[i] == 0xfc)
244 mdelay(1);
245 else if (phy_regarray_table_pg[i] == 0xfb)
246 udelay(50);
247 else if (phy_regarray_table_pg[i] == 0xfa)
248 udelay(5);
249 else if (phy_regarray_table_pg[i] == 0xf9)
250 udelay(1);
251 _rtl92c_store_pwrIndex_diffrate_offset(hw, 230 _rtl92c_store_pwrIndex_diffrate_offset(hw,
252 phy_regarray_table_pg[i], 231 phy_regarray_table_pg[i],
253 phy_regarray_table_pg[i + 1], 232 phy_regarray_table_pg[i + 1],
@@ -294,46 +273,16 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
294 switch (rfpath) { 273 switch (rfpath) {
295 case RF90_PATH_A: 274 case RF90_PATH_A:
296 for (i = 0; i < radioa_arraylen; i = i + 2) { 275 for (i = 0; i < radioa_arraylen; i = i + 2) {
297 if (radioa_array_table[i] == 0xfe) 276 rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
298 mdelay(50); 277 RFREG_OFFSET_MASK,
299 else if (radioa_array_table[i] == 0xfd) 278 radioa_array_table[i + 1]);
300 mdelay(5);
301 else if (radioa_array_table[i] == 0xfc)
302 mdelay(1);
303 else if (radioa_array_table[i] == 0xfb)
304 udelay(50);
305 else if (radioa_array_table[i] == 0xfa)
306 udelay(5);
307 else if (radioa_array_table[i] == 0xf9)
308 udelay(1);
309 else {
310 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
311 RFREG_OFFSET_MASK,
312 radioa_array_table[i + 1]);
313 udelay(1);
314 }
315 } 279 }
316 break; 280 break;
317 case RF90_PATH_B: 281 case RF90_PATH_B:
318 for (i = 0; i < radiob_arraylen; i = i + 2) { 282 for (i = 0; i < radiob_arraylen; i = i + 2) {
319 if (radiob_array_table[i] == 0xfe) { 283 rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
320 mdelay(50); 284 RFREG_OFFSET_MASK,
321 } else if (radiob_array_table[i] == 0xfd) 285 radiob_array_table[i + 1]);
322 mdelay(5);
323 else if (radiob_array_table[i] == 0xfc)
324 mdelay(1);
325 else if (radiob_array_table[i] == 0xfb)
326 udelay(50);
327 else if (radiob_array_table[i] == 0xfa)
328 udelay(5);
329 else if (radiob_array_table[i] == 0xf9)
330 udelay(1);
331 else {
332 rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
333 RFREG_OFFSET_MASK,
334 radiob_array_table[i + 1]);
335 udelay(1);
336 }
337 } 286 }
338 break; 287 break;
339 case RF90_PATH_C: 288 case RF90_PATH_C:
@@ -344,6 +293,8 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
344 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 293 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
345 "switch case not processed\n"); 294 "switch case not processed\n");
346 break; 295 break;
296 default:
297 break;
347 } 298 }
348 return true; 299 return true;
349} 300}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index 1bc21ccfa71b..035e0dc3922c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -495,7 +495,7 @@ static void _rtl_tx_desc_checksum(u8 *txdesc)
495 495
496void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, 496void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
497 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 497 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
498 struct ieee80211_tx_info *info, 498 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
499 struct ieee80211_sta *sta, 499 struct ieee80211_sta *sta,
500 struct sk_buff *skb, 500 struct sk_buff *skb,
501 u8 queue_index, 501 u8 queue_index,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
index 725c53accc58..fd8051dcd98a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
@@ -420,7 +420,7 @@ struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *,
420 struct sk_buff_head *); 420 struct sk_buff_head *);
421void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, 421void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
422 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 422 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
423 struct ieee80211_tx_info *info, 423 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
424 struct ieee80211_sta *sta, 424 struct ieee80211_sta *sta,
425 struct sk_buff *skb, 425 struct sk_buff *skb,
426 u8 queue_index, 426 u8 queue_index,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
index 7908e1c85819..304c443b89b2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
@@ -194,15 +194,15 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
194 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); /* hold page C counter */ 194 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); /* hold page C counter */
195 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); /*hold page D counter */ 195 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); /*hold page D counter */
196 196
197 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, BMASKDWORD); 197 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
198 falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff); 198 falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
199 falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16); 199 falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
200 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, BMASKDWORD); 200 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
201 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); 201 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
202 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, BMASKDWORD); 202 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
203 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); 203 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
204 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); 204 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
205 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, BMASKDWORD); 205 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
206 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); 206 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
207 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + 207 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
208 falsealm_cnt->cnt_rate_illegal + 208 falsealm_cnt->cnt_rate_illegal +
@@ -214,9 +214,9 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
214 if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) { 214 if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) {
215 /* hold cck counter */ 215 /* hold cck counter */
216 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); 216 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
217 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, BMASKBYTE0); 217 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
218 falsealm_cnt->cnt_cck_fail = ret_value; 218 falsealm_cnt->cnt_cck_fail = ret_value;
219 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, BMASKBYTE3); 219 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
220 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; 220 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
221 rtl92d_release_cckandrw_pagea_ctl(hw, &flag); 221 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
222 } else { 222 } else {
@@ -331,11 +331,11 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
331 if (de_digtable->pre_cck_pd_state != de_digtable->cur_cck_pd_state) { 331 if (de_digtable->pre_cck_pd_state != de_digtable->cur_cck_pd_state) {
332 if (de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { 332 if (de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
333 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); 333 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
334 rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0x83); 334 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
335 rtl92d_release_cckandrw_pagea_ctl(hw, &flag); 335 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
336 } else { 336 } else {
337 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); 337 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
338 rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0xcd); 338 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
339 rtl92d_release_cckandrw_pagea_ctl(hw, &flag); 339 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
340 } 340 }
341 de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state; 341 de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state;
@@ -722,7 +722,7 @@ static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw)
722 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 722 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
723 "===> Rx Gain %x\n", u4tmp); 723 "===> Rx Gain %x\n", u4tmp);
724 for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++) 724 for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++)
725 rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK, 725 rtl_set_rfreg(hw, i, 0x3C, RFREG_OFFSET_MASK,
726 (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp); 726 (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp);
727} 727}
728 728
@@ -737,7 +737,7 @@ static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg,
737 /* Query CCK default setting From 0xa24 */ 737 /* Query CCK default setting From 0xa24 */
738 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); 738 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
739 temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, 739 temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2,
740 BMASKDWORD) & BMASKCCK; 740 MASKDWORD) & MASKCCK;
741 rtl92d_release_cckandrw_pagea_ctl(hw, &flag); 741 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
742 for (i = 0; i < CCK_TABLE_LENGTH; i++) { 742 for (i = 0; i < CCK_TABLE_LENGTH; i++) {
743 if (rtlpriv->dm.cck_inch14) { 743 if (rtlpriv->dm.cck_inch14) {
@@ -896,9 +896,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
896 rf = 1; 896 rf = 1;
897 if (thermalvalue) { 897 if (thermalvalue) {
898 ele_d = rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 898 ele_d = rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
899 BMASKDWORD) & BMASKOFDM_D; 899 MASKDWORD) & MASKOFDM_D;
900 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { 900 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
901 if (ele_d == (ofdmswing_table[i] & BMASKOFDM_D)) { 901 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
902 ofdm_index_old[0] = (u8) i; 902 ofdm_index_old[0] = (u8) i;
903 903
904 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 904 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
@@ -910,10 +910,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
910 } 910 }
911 if (is2t) { 911 if (is2t) {
912 ele_d = rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 912 ele_d = rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE,
913 BMASKDWORD) & BMASKOFDM_D; 913 MASKDWORD) & MASKOFDM_D;
914 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { 914 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
915 if (ele_d == 915 if (ele_d ==
916 (ofdmswing_table[i] & BMASKOFDM_D)) { 916 (ofdmswing_table[i] & MASKOFDM_D)) {
917 ofdm_index_old[1] = (u8) i; 917 ofdm_index_old[1] = (u8) i;
918 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, 918 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
919 DBG_LOUD, 919 DBG_LOUD,
@@ -1091,10 +1091,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
1091 value32 = (ele_d << 22) | ((ele_c & 0x3F) << 1091 value32 = (ele_d << 22) | ((ele_c & 0x3F) <<
1092 16) | ele_a; 1092 16) | ele_a;
1093 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 1093 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
1094 BMASKDWORD, value32); 1094 MASKDWORD, value32);
1095 1095
1096 value32 = (ele_c & 0x000003C0) >> 6; 1096 value32 = (ele_c & 0x000003C0) >> 6;
1097 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, BMASKH4BITS, 1097 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, MASKH4BITS,
1098 value32); 1098 value32);
1099 1099
1100 value32 = ((val_x * ele_d) >> 7) & 0x01; 1100 value32 = ((val_x * ele_d) >> 7) & 0x01;
@@ -1103,10 +1103,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
1103 1103
1104 } else { 1104 } else {
1105 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 1105 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
1106 BMASKDWORD, 1106 MASKDWORD,
1107 ofdmswing_table 1107 ofdmswing_table
1108 [(u8)ofdm_index[0]]); 1108 [(u8)ofdm_index[0]]);
1109 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, BMASKH4BITS, 1109 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, MASKH4BITS,
1110 0x00); 1110 0x00);
1111 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, 1111 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1112 BIT(24), 0x00); 1112 BIT(24), 0x00);
@@ -1204,21 +1204,21 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
1204 ele_a; 1204 ele_a;
1205 rtl_set_bbreg(hw, 1205 rtl_set_bbreg(hw,
1206 ROFDM0_XBTxIQIMBALANCE, 1206 ROFDM0_XBTxIQIMBALANCE,
1207 BMASKDWORD, value32); 1207 MASKDWORD, value32);
1208 value32 = (ele_c & 0x000003C0) >> 6; 1208 value32 = (ele_c & 0x000003C0) >> 6;
1209 rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 1209 rtl_set_bbreg(hw, ROFDM0_XDTxAFE,
1210 BMASKH4BITS, value32); 1210 MASKH4BITS, value32);
1211 value32 = ((val_x * ele_d) >> 7) & 0x01; 1211 value32 = ((val_x * ele_d) >> 7) & 0x01;
1212 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, 1212 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1213 BIT(28), value32); 1213 BIT(28), value32);
1214 } else { 1214 } else {
1215 rtl_set_bbreg(hw, 1215 rtl_set_bbreg(hw,
1216 ROFDM0_XBTxIQIMBALANCE, 1216 ROFDM0_XBTxIQIMBALANCE,
1217 BMASKDWORD, 1217 MASKDWORD,
1218 ofdmswing_table 1218 ofdmswing_table
1219 [(u8) ofdm_index[1]]); 1219 [(u8) ofdm_index[1]]);
1220 rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 1220 rtl_set_bbreg(hw, ROFDM0_XDTxAFE,
1221 BMASKH4BITS, 0x00); 1221 MASKH4BITS, 0x00);
1222 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, 1222 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1223 BIT(28), 0x00); 1223 BIT(28), 0x00);
1224 } 1224 }
@@ -1229,10 +1229,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
1229 } 1229 }
1230 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1230 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1231 "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n", 1231 "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n",
1232 rtl_get_bbreg(hw, 0xc80, BMASKDWORD), 1232 rtl_get_bbreg(hw, 0xc80, MASKDWORD),
1233 rtl_get_bbreg(hw, 0xc94, BMASKDWORD), 1233 rtl_get_bbreg(hw, 0xc94, MASKDWORD),
1234 rtl_get_rfreg(hw, RF90_PATH_A, 0x24, 1234 rtl_get_rfreg(hw, RF90_PATH_A, 0x24,
1235 BRFREGOFFSETMASK)); 1235 RFREG_OFFSET_MASK));
1236 } 1236 }
1237 if ((delta_iqk > rtlefuse->delta_iqk) && 1237 if ((delta_iqk > rtlefuse->delta_iqk) &&
1238 (rtlefuse->delta_iqk != 0)) { 1238 (rtlefuse->delta_iqk != 0)) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index c4a7db9135d6..2b08671004a0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -318,7 +318,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
318 case HW_VAR_AC_PARAM: { 318 case HW_VAR_AC_PARAM: {
319 u8 e_aci = *val; 319 u8 e_aci = *val;
320 rtl92d_dm_init_edca_turbo(hw); 320 rtl92d_dm_init_edca_turbo(hw);
321 if (rtlpci->acm_method != eAcmWay2_SW) 321 if (rtlpci->acm_method != EACMWAY2_SW)
322 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, 322 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
323 &e_aci); 323 &e_aci);
324 break; 324 break;
@@ -985,9 +985,9 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
985 /* set default value after initialize RF, */ 985 /* set default value after initialize RF, */
986 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0); 986 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);
987 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, 987 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
988 RF_CHNLBW, BRFREGOFFSETMASK); 988 RF_CHNLBW, RFREG_OFFSET_MASK);
989 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, 989 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
990 RF_CHNLBW, BRFREGOFFSETMASK); 990 RF_CHNLBW, RFREG_OFFSET_MASK);
991 991
992 /*---- Set CCK and OFDM Block "ON"----*/ 992 /*---- Set CCK and OFDM Block "ON"----*/
993 if (rtlhal->current_bandtype == BAND_ON_2_4G) 993 if (rtlhal->current_bandtype == BAND_ON_2_4G)
@@ -1035,7 +1035,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
1035 1035
1036 tmp_rega = rtl_get_rfreg(hw, 1036 tmp_rega = rtl_get_rfreg(hw,
1037 (enum radio_path)RF90_PATH_A, 1037 (enum radio_path)RF90_PATH_A,
1038 0x2a, BMASKDWORD); 1038 0x2a, MASKDWORD);
1039 1039
1040 if (((tmp_rega & BIT(11)) == BIT(11))) 1040 if (((tmp_rega & BIT(11)) == BIT(11)))
1041 break; 1041 break;
@@ -1138,11 +1138,13 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
1138void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 1138void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1139{ 1139{
1140 struct rtl_priv *rtlpriv = rtl_priv(hw); 1140 struct rtl_priv *rtlpriv = rtl_priv(hw);
1141 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 1141 u32 reg_rcr;
1142 u32 reg_rcr = rtlpci->receive_config;
1143 1142
1144 if (rtlpriv->psc.rfpwr_state != ERFON) 1143 if (rtlpriv->psc.rfpwr_state != ERFON)
1145 return; 1144 return;
1145
1146 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
1147
1146 if (check_bssid) { 1148 if (check_bssid) {
1147 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); 1149 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1148 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr)); 1150 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
@@ -1332,13 +1334,13 @@ void rtl92de_card_disable(struct ieee80211_hw *hw)
1332 /* c. ========RF OFF sequence========== */ 1334 /* c. ========RF OFF sequence========== */
1333 /* 0x88c[23:20] = 0xf. */ 1335 /* 0x88c[23:20] = 0xf. */
1334 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); 1336 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
1335 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); 1337 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1336 1338
1337 /* APSD_CTRL 0x600[7:0] = 0x40 */ 1339 /* APSD_CTRL 0x600[7:0] = 0x40 */
1338 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 1340 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1339 1341
1340 /* Close antenna 0,0xc04,0xd04 */ 1342 /* Close antenna 0,0xc04,0xd04 */
1341 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0); 1343 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0);
1342 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0); 1344 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0);
1343 1345
1344 /* SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB state machine */ 1346 /* SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB state machine */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
index 13196cc4b1d3..3d1f0dd4e52d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
@@ -30,6 +30,7 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "../ps.h" 32#include "../ps.h"
33#include "../core.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "phy.h" 36#include "phy.h"
@@ -242,7 +243,7 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
242 else if (rtlhal->during_mac0init_radiob) 243 else if (rtlhal->during_mac0init_radiob)
243 /* mac0 use phy1 write radio_b. */ 244 /* mac0 use phy1 write radio_b. */
244 dbi_direct = BIT(3) | BIT(2); 245 dbi_direct = BIT(3) | BIT(2);
245 if (bitmask != BMASKDWORD) { 246 if (bitmask != MASKDWORD) {
246 if (rtlhal->during_mac1init_radioa || 247 if (rtlhal->during_mac1init_radioa ||
247 rtlhal->during_mac0init_radiob) 248 rtlhal->during_mac0init_radiob)
248 originalvalue = rtl92de_read_dword_dbi(hw, 249 originalvalue = rtl92de_read_dword_dbi(hw,
@@ -275,20 +276,20 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,
275 u32 retvalue; 276 u32 retvalue;
276 277
277 newoffset = offset; 278 newoffset = offset;
278 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD); 279 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
279 if (rfpath == RF90_PATH_A) 280 if (rfpath == RF90_PATH_A)
280 tmplong2 = tmplong; 281 tmplong2 = tmplong;
281 else 282 else
282 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD); 283 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
283 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | 284 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
284 (newoffset << 23) | BLSSIREADEDGE; 285 (newoffset << 23) | BLSSIREADEDGE;
285 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD, 286 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
286 tmplong & (~BLSSIREADEDGE)); 287 tmplong & (~BLSSIREADEDGE));
287 udelay(10); 288 udelay(10);
288 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD, tmplong2); 289 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
289 udelay(50); 290 udelay(50);
290 udelay(50); 291 udelay(50);
291 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD, 292 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
292 tmplong | BLSSIREADEDGE); 293 tmplong | BLSSIREADEDGE);
293 udelay(10); 294 udelay(10);
294 if (rfpath == RF90_PATH_A) 295 if (rfpath == RF90_PATH_A)
@@ -321,7 +322,7 @@ static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw,
321 newoffset = offset; 322 newoffset = offset;
322 /* T65 RF */ 323 /* T65 RF */
323 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; 324 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
324 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr); 325 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
325 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", 326 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
326 rfpath, pphyreg->rf3wire_offset, data_and_addr); 327 rfpath, pphyreg->rf3wire_offset, data_and_addr);
327} 328}
@@ -362,7 +363,7 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
362 return; 363 return;
363 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); 364 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
364 if (rtlphy->rf_mode != RF_OP_BY_FW) { 365 if (rtlphy->rf_mode != RF_OP_BY_FW) {
365 if (bitmask != BRFREGOFFSETMASK) { 366 if (bitmask != RFREG_OFFSET_MASK) {
366 original_value = _rtl92d_phy_rf_serial_read(hw, 367 original_value = _rtl92d_phy_rf_serial_read(hw,
367 rfpath, regaddr); 368 rfpath, regaddr);
368 bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); 369 bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
@@ -567,19 +568,8 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
567 " ===> phy:Rtl819XPHY_REG_Array_PG\n"); 568 " ===> phy:Rtl819XPHY_REG_Array_PG\n");
568 if (configtype == BASEBAND_CONFIG_PHY_REG) { 569 if (configtype == BASEBAND_CONFIG_PHY_REG) {
569 for (i = 0; i < phy_reg_arraylen; i = i + 2) { 570 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
570 if (phy_regarray_table[i] == 0xfe) 571 rtl_addr_delay(phy_regarray_table[i]);
571 mdelay(50); 572 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
572 else if (phy_regarray_table[i] == 0xfd)
573 mdelay(5);
574 else if (phy_regarray_table[i] == 0xfc)
575 mdelay(1);
576 else if (phy_regarray_table[i] == 0xfb)
577 udelay(50);
578 else if (phy_regarray_table[i] == 0xfa)
579 udelay(5);
580 else if (phy_regarray_table[i] == 0xf9)
581 udelay(1);
582 rtl_set_bbreg(hw, phy_regarray_table[i], BMASKDWORD,
583 phy_regarray_table[i + 1]); 573 phy_regarray_table[i + 1]);
584 udelay(1); 574 udelay(1);
585 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 575 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
@@ -591,7 +581,7 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
591 if (rtlhal->interfaceindex == 0) { 581 if (rtlhal->interfaceindex == 0) {
592 for (i = 0; i < agctab_arraylen; i = i + 2) { 582 for (i = 0; i < agctab_arraylen; i = i + 2) {
593 rtl_set_bbreg(hw, agctab_array_table[i], 583 rtl_set_bbreg(hw, agctab_array_table[i],
594 BMASKDWORD, 584 MASKDWORD,
595 agctab_array_table[i + 1]); 585 agctab_array_table[i + 1]);
596 /* Add 1us delay between BB/RF register 586 /* Add 1us delay between BB/RF register
597 * setting. */ 587 * setting. */
@@ -607,7 +597,7 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
607 if (rtlhal->current_bandtype == BAND_ON_2_4G) { 597 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
608 for (i = 0; i < agctab_arraylen; i = i + 2) { 598 for (i = 0; i < agctab_arraylen; i = i + 2) {
609 rtl_set_bbreg(hw, agctab_array_table[i], 599 rtl_set_bbreg(hw, agctab_array_table[i],
610 BMASKDWORD, 600 MASKDWORD,
611 agctab_array_table[i + 1]); 601 agctab_array_table[i + 1]);
612 /* Add 1us delay between BB/RF register 602 /* Add 1us delay between BB/RF register
613 * setting. */ 603 * setting. */
@@ -623,7 +613,7 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
623 for (i = 0; i < agctab_5garraylen; i = i + 2) { 613 for (i = 0; i < agctab_5garraylen; i = i + 2) {
624 rtl_set_bbreg(hw, 614 rtl_set_bbreg(hw,
625 agctab_5garray_table[i], 615 agctab_5garray_table[i],
626 BMASKDWORD, 616 MASKDWORD,
627 agctab_5garray_table[i + 1]); 617 agctab_5garray_table[i + 1]);
628 /* Add 1us delay between BB/RF registeri 618 /* Add 1us delay between BB/RF registeri
629 * setting. */ 619 * setting. */
@@ -705,18 +695,7 @@ static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
705 phy_regarray_table_pg = rtl8192de_phy_reg_array_pg; 695 phy_regarray_table_pg = rtl8192de_phy_reg_array_pg;
706 if (configtype == BASEBAND_CONFIG_PHY_REG) { 696 if (configtype == BASEBAND_CONFIG_PHY_REG) {
707 for (i = 0; i < phy_regarray_pg_len; i = i + 3) { 697 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
708 if (phy_regarray_table_pg[i] == 0xfe) 698 rtl_addr_delay(phy_regarray_table_pg[i]);
709 mdelay(50);
710 else if (phy_regarray_table_pg[i] == 0xfd)
711 mdelay(5);
712 else if (phy_regarray_table_pg[i] == 0xfc)
713 mdelay(1);
714 else if (phy_regarray_table_pg[i] == 0xfb)
715 udelay(50);
716 else if (phy_regarray_table_pg[i] == 0xfa)
717 udelay(5);
718 else if (phy_regarray_table_pg[i] == 0xf9)
719 udelay(1);
720 _rtl92d_store_pwrindex_diffrate_offset(hw, 699 _rtl92d_store_pwrindex_diffrate_offset(hw,
721 phy_regarray_table_pg[i], 700 phy_regarray_table_pg[i],
722 phy_regarray_table_pg[i + 1], 701 phy_regarray_table_pg[i + 1],
@@ -843,54 +822,16 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
843 switch (rfpath) { 822 switch (rfpath) {
844 case RF90_PATH_A: 823 case RF90_PATH_A:
845 for (i = 0; i < radioa_arraylen; i = i + 2) { 824 for (i = 0; i < radioa_arraylen; i = i + 2) {
846 if (radioa_array_table[i] == 0xfe) { 825 rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
847 mdelay(50); 826 RFREG_OFFSET_MASK,
848 } else if (radioa_array_table[i] == 0xfd) { 827 radioa_array_table[i + 1]);
849 /* delay_ms(5); */
850 mdelay(5);
851 } else if (radioa_array_table[i] == 0xfc) {
852 /* delay_ms(1); */
853 mdelay(1);
854 } else if (radioa_array_table[i] == 0xfb) {
855 udelay(50);
856 } else if (radioa_array_table[i] == 0xfa) {
857 udelay(5);
858 } else if (radioa_array_table[i] == 0xf9) {
859 udelay(1);
860 } else {
861 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
862 BRFREGOFFSETMASK,
863 radioa_array_table[i + 1]);
864 /* Add 1us delay between BB/RF register set. */
865 udelay(1);
866 }
867 } 828 }
868 break; 829 break;
869 case RF90_PATH_B: 830 case RF90_PATH_B:
870 for (i = 0; i < radiob_arraylen; i = i + 2) { 831 for (i = 0; i < radiob_arraylen; i = i + 2) {
871 if (radiob_array_table[i] == 0xfe) { 832 rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
872 /* Delay specific ms. Only RF configuration 833 RFREG_OFFSET_MASK,
873 * requires delay. */ 834 radiob_array_table[i + 1]);
874 mdelay(50);
875 } else if (radiob_array_table[i] == 0xfd) {
876 /* delay_ms(5); */
877 mdelay(5);
878 } else if (radiob_array_table[i] == 0xfc) {
879 /* delay_ms(1); */
880 mdelay(1);
881 } else if (radiob_array_table[i] == 0xfb) {
882 udelay(50);
883 } else if (radiob_array_table[i] == 0xfa) {
884 udelay(5);
885 } else if (radiob_array_table[i] == 0xf9) {
886 udelay(1);
887 } else {
888 rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
889 BRFREGOFFSETMASK,
890 radiob_array_table[i + 1]);
891 /* Add 1us delay between BB/RF register set. */
892 udelay(1);
893 }
894 } 835 }
895 break; 836 break;
896 case RF90_PATH_C: 837 case RF90_PATH_C:
@@ -911,13 +852,13 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
911 struct rtl_phy *rtlphy = &(rtlpriv->phy); 852 struct rtl_phy *rtlphy = &(rtlpriv->phy);
912 853
913 rtlphy->default_initialgain[0] = 854 rtlphy->default_initialgain[0] =
914 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, BMASKBYTE0); 855 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
915 rtlphy->default_initialgain[1] = 856 rtlphy->default_initialgain[1] =
916 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, BMASKBYTE0); 857 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
917 rtlphy->default_initialgain[2] = 858 rtlphy->default_initialgain[2] =
918 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, BMASKBYTE0); 859 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
919 rtlphy->default_initialgain[3] = 860 rtlphy->default_initialgain[3] =
920 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0); 861 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
921 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 862 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
922 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", 863 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
923 rtlphy->default_initialgain[0], 864 rtlphy->default_initialgain[0],
@@ -925,9 +866,9 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
925 rtlphy->default_initialgain[2], 866 rtlphy->default_initialgain[2],
926 rtlphy->default_initialgain[3]); 867 rtlphy->default_initialgain[3]);
927 rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, 868 rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
928 BMASKBYTE0); 869 MASKBYTE0);
929 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, 870 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
930 BMASKDWORD); 871 MASKDWORD);
931 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 872 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
932 "Default framesync (0x%x) = 0x%x\n", 873 "Default framesync (0x%x) = 0x%x\n",
933 ROFDM0_RXDETECTOR3, rtlphy->framesync); 874 ROFDM0_RXDETECTOR3, rtlphy->framesync);
@@ -1106,7 +1047,7 @@ static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw)
1106{ 1047{
1107 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0); 1048 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0);
1108 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0); 1049 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0);
1109 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x00); 1050 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x00);
1110 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0); 1051 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0);
1111} 1052}
1112 1053
@@ -1168,7 +1109,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
1168{ 1109{
1169 struct rtl_priv *rtlpriv = rtl_priv(hw); 1110 struct rtl_priv *rtlpriv = rtl_priv(hw);
1170 u32 imr_num = MAX_RF_IMR_INDEX; 1111 u32 imr_num = MAX_RF_IMR_INDEX;
1171 u32 rfmask = BRFREGOFFSETMASK; 1112 u32 rfmask = RFREG_OFFSET_MASK;
1172 u8 group, i; 1113 u8 group, i;
1173 unsigned long flag = 0; 1114 unsigned long flag = 0;
1174 1115
@@ -1211,7 +1152,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
1211 for (i = 0; i < imr_num; i++) { 1152 for (i = 0; i < imr_num; i++) {
1212 rtl_set_rfreg(hw, (enum radio_path)rfpath, 1153 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1213 rf_reg_for_5g_swchnl_normal[i], 1154 rf_reg_for_5g_swchnl_normal[i],
1214 BRFREGOFFSETMASK, 1155 RFREG_OFFSET_MASK,
1215 rf_imr_param_normal[0][0][i]); 1156 rf_imr_param_normal[0][0][i]);
1216 } 1157 }
1217 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 1158 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
@@ -1329,7 +1270,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
1329 if (i == 0 && (rtlhal->macphymode == DUALMAC_DUALPHY)) { 1270 if (i == 0 && (rtlhal->macphymode == DUALMAC_DUALPHY)) {
1330 rtl_set_rfreg(hw, (enum radio_path)path, 1271 rtl_set_rfreg(hw, (enum radio_path)path,
1331 rf_reg_for_c_cut_5g[i], 1272 rf_reg_for_c_cut_5g[i],
1332 BRFREGOFFSETMASK, 0xE439D); 1273 RFREG_OFFSET_MASK, 0xE439D);
1333 } else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) { 1274 } else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) {
1334 u4tmp2 = (rf_reg_pram_c_5g[index][i] & 1275 u4tmp2 = (rf_reg_pram_c_5g[index][i] &
1335 0x7FF) | (u4tmp << 11); 1276 0x7FF) | (u4tmp << 11);
@@ -1337,11 +1278,11 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
1337 u4tmp2 &= ~(BIT(7) | BIT(6)); 1278 u4tmp2 &= ~(BIT(7) | BIT(6));
1338 rtl_set_rfreg(hw, (enum radio_path)path, 1279 rtl_set_rfreg(hw, (enum radio_path)path,
1339 rf_reg_for_c_cut_5g[i], 1280 rf_reg_for_c_cut_5g[i],
1340 BRFREGOFFSETMASK, u4tmp2); 1281 RFREG_OFFSET_MASK, u4tmp2);
1341 } else { 1282 } else {
1342 rtl_set_rfreg(hw, (enum radio_path)path, 1283 rtl_set_rfreg(hw, (enum radio_path)path,
1343 rf_reg_for_c_cut_5g[i], 1284 rf_reg_for_c_cut_5g[i],
1344 BRFREGOFFSETMASK, 1285 RFREG_OFFSET_MASK,
1345 rf_reg_pram_c_5g[index][i]); 1286 rf_reg_pram_c_5g[index][i]);
1346 } 1287 }
1347 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 1288 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
@@ -1351,7 +1292,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
1351 path, index, 1292 path, index,
1352 rtl_get_rfreg(hw, (enum radio_path)path, 1293 rtl_get_rfreg(hw, (enum radio_path)path,
1353 rf_reg_for_c_cut_5g[i], 1294 rf_reg_for_c_cut_5g[i],
1354 BRFREGOFFSETMASK)); 1295 RFREG_OFFSET_MASK));
1355 } 1296 }
1356 if (need_pwr_down) 1297 if (need_pwr_down)
1357 _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); 1298 _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
@@ -1381,7 +1322,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
1381 i++) { 1322 i++) {
1382 rtl_set_rfreg(hw, rfpath, 1323 rtl_set_rfreg(hw, rfpath,
1383 rf_for_c_cut_5g_internal_pa[i], 1324 rf_for_c_cut_5g_internal_pa[i],
1384 BRFREGOFFSETMASK, 1325 RFREG_OFFSET_MASK,
1385 rf_pram_c_5g_int_pa[index][i]); 1326 rf_pram_c_5g_int_pa[index][i]);
1386 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, 1327 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
1387 "offset 0x%x value 0x%x path %d index %d\n", 1328 "offset 0x%x value 0x%x path %d index %d\n",
@@ -1422,13 +1363,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
1422 if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7) 1363 if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7)
1423 rtl_set_rfreg(hw, (enum radio_path)path, 1364 rtl_set_rfreg(hw, (enum radio_path)path,
1424 rf_reg_for_c_cut_2g[i], 1365 rf_reg_for_c_cut_2g[i],
1425 BRFREGOFFSETMASK, 1366 RFREG_OFFSET_MASK,
1426 (rf_reg_param_for_c_cut_2g[index][i] | 1367 (rf_reg_param_for_c_cut_2g[index][i] |
1427 BIT(17))); 1368 BIT(17)));
1428 else 1369 else
1429 rtl_set_rfreg(hw, (enum radio_path)path, 1370 rtl_set_rfreg(hw, (enum radio_path)path,
1430 rf_reg_for_c_cut_2g[i], 1371 rf_reg_for_c_cut_2g[i],
1431 BRFREGOFFSETMASK, 1372 RFREG_OFFSET_MASK,
1432 rf_reg_param_for_c_cut_2g 1373 rf_reg_param_for_c_cut_2g
1433 [index][i]); 1374 [index][i]);
1434 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 1375 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
@@ -1438,14 +1379,14 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
1438 rf_reg_mask_for_c_cut_2g[i], path, index, 1379 rf_reg_mask_for_c_cut_2g[i], path, index,
1439 rtl_get_rfreg(hw, (enum radio_path)path, 1380 rtl_get_rfreg(hw, (enum radio_path)path,
1440 rf_reg_for_c_cut_2g[i], 1381 rf_reg_for_c_cut_2g[i],
1441 BRFREGOFFSETMASK)); 1382 RFREG_OFFSET_MASK));
1442 } 1383 }
1443 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1384 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1444 "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", 1385 "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
1445 rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); 1386 rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
1446 1387
1447 rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4, 1388 rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4,
1448 BRFREGOFFSETMASK, 1389 RFREG_OFFSET_MASK,
1449 rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); 1390 rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
1450 if (need_pwr_down) 1391 if (need_pwr_down)
1451 _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); 1392 _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
@@ -1493,41 +1434,41 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
1493 /* path-A IQK setting */ 1434 /* path-A IQK setting */
1494 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); 1435 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
1495 if (rtlhal->interfaceindex == 0) { 1436 if (rtlhal->interfaceindex == 0) {
1496 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f); 1437 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
1497 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f); 1438 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
1498 } else { 1439 } else {
1499 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c22); 1440 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c22);
1500 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c22); 1441 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c22);
1501 } 1442 }
1502 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140102); 1443 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
1503 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x28160206); 1444 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160206);
1504 /* path-B IQK setting */ 1445 /* path-B IQK setting */
1505 if (configpathb) { 1446 if (configpathb) {
1506 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x10008c22); 1447 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
1507 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x10008c22); 1448 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
1508 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140102); 1449 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
1509 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206); 1450 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160206);
1510 } 1451 }
1511 /* LO calibration setting */ 1452 /* LO calibration setting */
1512 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); 1453 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
1513 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); 1454 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1514 /* One shot, path A LOK & IQK */ 1455 /* One shot, path A LOK & IQK */
1515 RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); 1456 RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n");
1516 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); 1457 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1517 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); 1458 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1518 /* delay x ms */ 1459 /* delay x ms */
1519 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1460 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1520 "Delay %d ms for One shot, path A LOK & IQK\n", 1461 "Delay %d ms for One shot, path A LOK & IQK\n",
1521 IQK_DELAY_TIME); 1462 IQK_DELAY_TIME);
1522 mdelay(IQK_DELAY_TIME); 1463 mdelay(IQK_DELAY_TIME);
1523 /* Check failed */ 1464 /* Check failed */
1524 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); 1465 regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1525 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); 1466 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
1526 rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); 1467 rege94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1527 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); 1468 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94);
1528 rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); 1469 rege9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1529 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); 1470 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c);
1530 regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); 1471 regea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1531 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); 1472 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4);
1532 if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) && 1473 if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) &&
1533 (((rege9c & 0x03FF0000) >> 16) != 0x42)) 1474 (((rege9c & 0x03FF0000) >> 16) != 0x42))
@@ -1563,42 +1504,42 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
1563 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); 1504 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n");
1564 /* path-A IQK setting */ 1505 /* path-A IQK setting */
1565 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); 1506 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
1566 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); 1507 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x18008c1f);
1567 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); 1508 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x18008c1f);
1568 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307); 1509 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140307);
1569 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68160960); 1510 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x68160960);
1570 /* path-B IQK setting */ 1511 /* path-B IQK setting */
1571 if (configpathb) { 1512 if (configpathb) {
1572 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f); 1513 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x18008c2f);
1573 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f); 1514 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x18008c2f);
1574 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82110000); 1515 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82110000);
1575 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000); 1516 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x68110000);
1576 } 1517 }
1577 /* LO calibration setting */ 1518 /* LO calibration setting */
1578 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); 1519 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
1579 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); 1520 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1580 /* path-A PA on */ 1521 /* path-A PA on */
1581 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60); 1522 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x07000f60);
1582 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, 0x66e60e30); 1523 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD, 0x66e60e30);
1583 for (i = 0; i < retrycount; i++) { 1524 for (i = 0; i < retrycount; i++) {
1584 /* One shot, path A LOK & IQK */ 1525 /* One shot, path A LOK & IQK */
1585 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1526 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1586 "One shot, path A LOK & IQK!\n"); 1527 "One shot, path A LOK & IQK!\n");
1587 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); 1528 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1588 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); 1529 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1589 /* delay x ms */ 1530 /* delay x ms */
1590 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1531 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1591 "Delay %d ms for One shot, path A LOK & IQK.\n", 1532 "Delay %d ms for One shot, path A LOK & IQK.\n",
1592 IQK_DELAY_TIME); 1533 IQK_DELAY_TIME);
1593 mdelay(IQK_DELAY_TIME * 10); 1534 mdelay(IQK_DELAY_TIME * 10);
1594 /* Check failed */ 1535 /* Check failed */
1595 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); 1536 regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1596 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); 1537 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
1597 rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); 1538 rege94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1598 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); 1539 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94);
1599 rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); 1540 rege9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1600 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); 1541 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c);
1601 regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); 1542 regea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1602 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); 1543 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4);
1603 if (!(regeac & TxOKBit) && 1544 if (!(regeac & TxOKBit) &&
1604 (((rege94 & 0x03FF0000) >> 16) != 0x142)) { 1545 (((rege94 & 0x03FF0000) >> 16) != 0x142)) {
@@ -1620,9 +1561,9 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
1620 } 1561 }
1621 } 1562 }
1622 /* path A PA off */ 1563 /* path A PA off */
1623 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 1564 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD,
1624 rtlphy->iqk_bb_backup[0]); 1565 rtlphy->iqk_bb_backup[0]);
1625 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, 1566 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD,
1626 rtlphy->iqk_bb_backup[1]); 1567 rtlphy->iqk_bb_backup[1]);
1627 return result; 1568 return result;
1628} 1569}
@@ -1637,22 +1578,22 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)
1637 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); 1578 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n");
1638 /* One shot, path B LOK & IQK */ 1579 /* One shot, path B LOK & IQK */
1639 RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); 1580 RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n");
1640 rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002); 1581 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1641 rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000); 1582 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1642 /* delay x ms */ 1583 /* delay x ms */
1643 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1584 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1644 "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME); 1585 "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME);
1645 mdelay(IQK_DELAY_TIME); 1586 mdelay(IQK_DELAY_TIME);
1646 /* Check failed */ 1587 /* Check failed */
1647 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); 1588 regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1648 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); 1589 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
1649 regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); 1590 regeb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1650 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); 1591 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4);
1651 regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); 1592 regebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1652 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); 1593 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc);
1653 regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); 1594 regec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1654 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); 1595 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4);
1655 regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); 1596 regecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1656 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); 1597 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc);
1657 if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) && 1598 if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&
1658 (((regebc & 0x03FF0000) >> 16) != 0x42)) 1599 (((regebc & 0x03FF0000) >> 16) != 0x42))
@@ -1680,31 +1621,31 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
1680 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); 1621 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n");
1681 /* path-A IQK setting */ 1622 /* path-A IQK setting */
1682 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); 1623 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
1683 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); 1624 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x18008c1f);
1684 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); 1625 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x18008c1f);
1685 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000); 1626 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82110000);
1686 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68110000); 1627 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x68110000);
1687 1628
1688 /* path-B IQK setting */ 1629 /* path-B IQK setting */
1689 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f); 1630 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x18008c2f);
1690 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f); 1631 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x18008c2f);
1691 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140307); 1632 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140307);
1692 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960); 1633 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x68160960);
1693 1634
1694 /* LO calibration setting */ 1635 /* LO calibration setting */
1695 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); 1636 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
1696 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); 1637 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1697 1638
1698 /* path-B PA on */ 1639 /* path-B PA on */
1699 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x0f600700); 1640 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x0f600700);
1700 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, 0x061f0d30); 1641 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD, 0x061f0d30);
1701 1642
1702 for (i = 0; i < retrycount; i++) { 1643 for (i = 0; i < retrycount; i++) {
1703 /* One shot, path B LOK & IQK */ 1644 /* One shot, path B LOK & IQK */
1704 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1645 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1705 "One shot, path A LOK & IQK!\n"); 1646 "One shot, path A LOK & IQK!\n");
1706 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000); 1647 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xfa000000);
1707 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); 1648 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1708 1649
1709 /* delay x ms */ 1650 /* delay x ms */
1710 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1651 RTPRINT(rtlpriv, FINIT, INIT_IQK,
@@ -1712,15 +1653,15 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
1712 mdelay(IQK_DELAY_TIME * 10); 1653 mdelay(IQK_DELAY_TIME * 10);
1713 1654
1714 /* Check failed */ 1655 /* Check failed */
1715 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); 1656 regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1716 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); 1657 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
1717 regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); 1658 regeb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1718 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); 1659 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4);
1719 regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); 1660 regebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1720 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); 1661 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc);
1721 regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); 1662 regec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1722 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); 1663 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4);
1723 regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); 1664 regecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1724 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); 1665 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc);
1725 if (!(regeac & BIT(31)) && 1666 if (!(regeac & BIT(31)) &&
1726 (((regeb4 & 0x03FF0000) >> 16) != 0x142)) 1667 (((regeb4 & 0x03FF0000) >> 16) != 0x142))
@@ -1738,9 +1679,9 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
1738 } 1679 }
1739 1680
1740 /* path B PA off */ 1681 /* path B PA off */
1741 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 1682 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD,
1742 rtlphy->iqk_bb_backup[0]); 1683 rtlphy->iqk_bb_backup[0]);
1743 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, 1684 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD,
1744 rtlphy->iqk_bb_backup[2]); 1685 rtlphy->iqk_bb_backup[2]);
1745 return result; 1686 return result;
1746} 1687}
@@ -1754,7 +1695,7 @@ static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw,
1754 1695
1755 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n"); 1696 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n");
1756 for (i = 0; i < regnum; i++) 1697 for (i = 0; i < regnum; i++)
1757 adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD); 1698 adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], MASKDWORD);
1758} 1699}
1759 1700
1760static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw, 1701static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw,
@@ -1779,7 +1720,7 @@ static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw,
1779 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1720 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1780 "Reload ADDA power saving parameters !\n"); 1721 "Reload ADDA power saving parameters !\n");
1781 for (i = 0; i < regnum; i++) 1722 for (i = 0; i < regnum; i++)
1782 rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]); 1723 rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, adda_backup[i]);
1783} 1724}
1784 1725
1785static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw, 1726static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw,
@@ -1807,7 +1748,7 @@ static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,
1807 pathon = rtlpriv->rtlhal.interfaceindex == 0 ? 1748 pathon = rtlpriv->rtlhal.interfaceindex == 0 ?
1808 0x04db25a4 : 0x0b1b25a4; 1749 0x04db25a4 : 0x0b1b25a4;
1809 for (i = 0; i < IQK_ADDA_REG_NUM; i++) 1750 for (i = 0; i < IQK_ADDA_REG_NUM; i++)
1810 rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, pathon); 1751 rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, pathon);
1811} 1752}
1812 1753
1813static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, 1754static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
@@ -1830,9 +1771,9 @@ static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw)
1830 struct rtl_priv *rtlpriv = rtl_priv(hw); 1771 struct rtl_priv *rtlpriv = rtl_priv(hw);
1831 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n"); 1772 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n");
1832 1773
1833 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0); 1774 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1834 rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000); 1775 rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD, 0x00010000);
1835 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); 1776 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1836} 1777}
1837 1778
1838static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode) 1779static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)
@@ -1843,8 +1784,8 @@ static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)
1843 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1784 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1844 "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI"); 1785 "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI");
1845 mode = pi_mode ? 0x01000100 : 0x01000000; 1786 mode = pi_mode ? 0x01000100 : 0x01000000;
1846 rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode); 1787 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1847 rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode); 1788 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1848} 1789}
1849 1790
1850static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], 1791static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
@@ -1875,7 +1816,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
1875 1816
1876 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n"); 1817 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n");
1877 if (t == 0) { 1818 if (t == 0) {
1878 bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); 1819 bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD);
1879 RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); 1820 RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue);
1880 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", 1821 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
1881 is2t ? "2T2R" : "1T1R"); 1822 is2t ? "2T2R" : "1T1R");
@@ -1898,40 +1839,40 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
1898 _rtl92d_phy_pimode_switch(hw, true); 1839 _rtl92d_phy_pimode_switch(hw, true);
1899 1840
1900 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); 1841 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
1901 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600); 1842 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600);
1902 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4); 1843 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4);
1903 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22204000); 1844 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22204000);
1904 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f); 1845 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
1905 if (is2t) { 1846 if (is2t) {
1906 rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 1847 rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD,
1907 0x00010000); 1848 0x00010000);
1908 rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, BMASKDWORD, 1849 rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, MASKDWORD,
1909 0x00010000); 1850 0x00010000);
1910 } 1851 }
1911 /* MAC settings */ 1852 /* MAC settings */
1912 _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg, 1853 _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
1913 rtlphy->iqk_mac_backup); 1854 rtlphy->iqk_mac_backup);
1914 /* Page B init */ 1855 /* Page B init */
1915 rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000); 1856 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1916 if (is2t) 1857 if (is2t)
1917 rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); 1858 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000);
1918 /* IQ calibration setting */ 1859 /* IQ calibration setting */
1919 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); 1860 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n");
1920 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); 1861 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1921 rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00); 1862 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1922 rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); 1863 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1923 for (i = 0; i < retrycount; i++) { 1864 for (i = 0; i < retrycount; i++) {
1924 patha_ok = _rtl92d_phy_patha_iqk(hw, is2t); 1865 patha_ok = _rtl92d_phy_patha_iqk(hw, is2t);
1925 if (patha_ok == 0x03) { 1866 if (patha_ok == 0x03) {
1926 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1867 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1927 "Path A IQK Success!!\n"); 1868 "Path A IQK Success!!\n");
1928 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 1869 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1929 0x3FF0000) >> 16; 1870 0x3FF0000) >> 16;
1930 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & 1871 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1931 0x3FF0000) >> 16; 1872 0x3FF0000) >> 16;
1932 result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) & 1873 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1933 0x3FF0000) >> 16; 1874 0x3FF0000) >> 16;
1934 result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) & 1875 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1935 0x3FF0000) >> 16; 1876 0x3FF0000) >> 16;
1936 break; 1877 break;
1937 } else if (i == (retrycount - 1) && patha_ok == 0x01) { 1878 } else if (i == (retrycount - 1) && patha_ok == 0x01) {
@@ -1939,9 +1880,9 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
1939 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1880 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1940 "Path A IQK Only Tx Success!!\n"); 1881 "Path A IQK Only Tx Success!!\n");
1941 1882
1942 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 1883 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1943 0x3FF0000) >> 16; 1884 0x3FF0000) >> 16;
1944 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & 1885 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1945 0x3FF0000) >> 16; 1886 0x3FF0000) >> 16;
1946 } 1887 }
1947 } 1888 }
@@ -1957,22 +1898,22 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
1957 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1898 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1958 "Path B IQK Success!!\n"); 1899 "Path B IQK Success!!\n");
1959 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, 1900 result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
1960 BMASKDWORD) & 0x3FF0000) >> 16; 1901 MASKDWORD) & 0x3FF0000) >> 16;
1961 result[t][5] = (rtl_get_bbreg(hw, 0xebc, 1902 result[t][5] = (rtl_get_bbreg(hw, 0xebc,
1962 BMASKDWORD) & 0x3FF0000) >> 16; 1903 MASKDWORD) & 0x3FF0000) >> 16;
1963 result[t][6] = (rtl_get_bbreg(hw, 0xec4, 1904 result[t][6] = (rtl_get_bbreg(hw, 0xec4,
1964 BMASKDWORD) & 0x3FF0000) >> 16; 1905 MASKDWORD) & 0x3FF0000) >> 16;
1965 result[t][7] = (rtl_get_bbreg(hw, 0xecc, 1906 result[t][7] = (rtl_get_bbreg(hw, 0xecc,
1966 BMASKDWORD) & 0x3FF0000) >> 16; 1907 MASKDWORD) & 0x3FF0000) >> 16;
1967 break; 1908 break;
1968 } else if (i == (retrycount - 1) && pathb_ok == 0x01) { 1909 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1969 /* Tx IQK OK */ 1910 /* Tx IQK OK */
1970 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1911 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1971 "Path B Only Tx IQK Success!!\n"); 1912 "Path B Only Tx IQK Success!!\n");
1972 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, 1913 result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
1973 BMASKDWORD) & 0x3FF0000) >> 16; 1914 MASKDWORD) & 0x3FF0000) >> 16;
1974 result[t][5] = (rtl_get_bbreg(hw, 0xebc, 1915 result[t][5] = (rtl_get_bbreg(hw, 0xebc,
1975 BMASKDWORD) & 0x3FF0000) >> 16; 1916 MASKDWORD) & 0x3FF0000) >> 16;
1976 } 1917 }
1977 } 1918 }
1978 if (0x00 == pathb_ok) 1919 if (0x00 == pathb_ok)
@@ -1984,7 +1925,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
1984 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1925 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1985 "IQK:Back to BB mode, load original value!\n"); 1926 "IQK:Back to BB mode, load original value!\n");
1986 1927
1987 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); 1928 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1988 if (t != 0) { 1929 if (t != 0) {
1989 /* Switch back BB to SI mode after finish IQ Calibration. */ 1930 /* Switch back BB to SI mode after finish IQ Calibration. */
1990 if (!rtlphy->rfpi_enable) 1931 if (!rtlphy->rfpi_enable)
@@ -2004,8 +1945,8 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
2004 rtlphy->iqk_bb_backup, 1945 rtlphy->iqk_bb_backup,
2005 IQK_BB_REG_NUM - 1); 1946 IQK_BB_REG_NUM - 1);
2006 /* load 0xe30 IQC default value */ 1947 /* load 0xe30 IQC default value */
2007 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00); 1948 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2008 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00); 1949 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2009 } 1950 }
2010 RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); 1951 RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n");
2011} 1952}
@@ -2042,7 +1983,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
2042 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n"); 1983 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n");
2043 mdelay(IQK_DELAY_TIME * 20); 1984 mdelay(IQK_DELAY_TIME * 20);
2044 if (t == 0) { 1985 if (t == 0) {
2045 bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); 1986 bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD);
2046 RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); 1987 RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue);
2047 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", 1988 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
2048 is2t ? "2T2R" : "1T1R"); 1989 is2t ? "2T2R" : "1T1R");
@@ -2072,38 +2013,38 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
2072 if (!rtlphy->rfpi_enable) 2013 if (!rtlphy->rfpi_enable)
2073 _rtl92d_phy_pimode_switch(hw, true); 2014 _rtl92d_phy_pimode_switch(hw, true);
2074 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); 2015 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
2075 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600); 2016 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600);
2076 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4); 2017 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4);
2077 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22208000); 2018 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208000);
2078 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f); 2019 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
2079 2020
2080 /* Page B init */ 2021 /* Page B init */
2081 rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000); 2022 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
2082 if (is2t) 2023 if (is2t)
2083 rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); 2024 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000);
2084 /* IQ calibration setting */ 2025 /* IQ calibration setting */
2085 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); 2026 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n");
2086 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); 2027 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
2087 rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00); 2028 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x10007c00);
2088 rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); 2029 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
2089 patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t); 2030 patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t);
2090 if (patha_ok == 0x03) { 2031 if (patha_ok == 0x03) {
2091 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n"); 2032 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n");
2092 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 2033 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2093 0x3FF0000) >> 16; 2034 0x3FF0000) >> 16;
2094 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & 2035 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2095 0x3FF0000) >> 16; 2036 0x3FF0000) >> 16;
2096 result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) & 2037 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2097 0x3FF0000) >> 16; 2038 0x3FF0000) >> 16;
2098 result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) & 2039 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2099 0x3FF0000) >> 16; 2040 0x3FF0000) >> 16;
2100 } else if (patha_ok == 0x01) { /* Tx IQK OK */ 2041 } else if (patha_ok == 0x01) { /* Tx IQK OK */
2101 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2042 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2102 "Path A IQK Only Tx Success!!\n"); 2043 "Path A IQK Only Tx Success!!\n");
2103 2044
2104 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 2045 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2105 0x3FF0000) >> 16; 2046 0x3FF0000) >> 16;
2106 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & 2047 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2107 0x3FF0000) >> 16; 2048 0x3FF0000) >> 16;
2108 } else { 2049 } else {
2109 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n"); 2050 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n");
@@ -2116,20 +2057,20 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
2116 if (pathb_ok == 0x03) { 2057 if (pathb_ok == 0x03) {
2117 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2058 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2118 "Path B IQK Success!!\n"); 2059 "Path B IQK Success!!\n");
2119 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 2060 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
2120 0x3FF0000) >> 16; 2061 0x3FF0000) >> 16;
2121 result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & 2062 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
2122 0x3FF0000) >> 16; 2063 0x3FF0000) >> 16;
2123 result[t][6] = (rtl_get_bbreg(hw, 0xec4, BMASKDWORD) & 2064 result[t][6] = (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
2124 0x3FF0000) >> 16; 2065 0x3FF0000) >> 16;
2125 result[t][7] = (rtl_get_bbreg(hw, 0xecc, BMASKDWORD) & 2066 result[t][7] = (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
2126 0x3FF0000) >> 16; 2067 0x3FF0000) >> 16;
2127 } else if (pathb_ok == 0x01) { /* Tx IQK OK */ 2068 } else if (pathb_ok == 0x01) { /* Tx IQK OK */
2128 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2069 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2129 "Path B Only Tx IQK Success!!\n"); 2070 "Path B Only Tx IQK Success!!\n");
2130 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 2071 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
2131 0x3FF0000) >> 16; 2072 0x3FF0000) >> 16;
2132 result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & 2073 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
2133 0x3FF0000) >> 16; 2074 0x3FF0000) >> 16;
2134 } else { 2075 } else {
2135 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2076 RTPRINT(rtlpriv, FINIT, INIT_IQK,
@@ -2140,7 +2081,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
2140 /* Back to BB mode, load original value */ 2081 /* Back to BB mode, load original value */
2141 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2082 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2142 "IQK:Back to BB mode, load original value!\n"); 2083 "IQK:Back to BB mode, load original value!\n");
2143 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); 2084 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
2144 if (t != 0) { 2085 if (t != 0) {
2145 if (is2t) 2086 if (is2t)
2146 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, 2087 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
@@ -2240,7 +2181,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
2240 return; 2181 return;
2241 } else if (iqk_ok) { 2182 } else if (iqk_ok) {
2242 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 2183 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
2243 BMASKDWORD) >> 22) & 0x3FF; /* OFDM0_D */ 2184 MASKDWORD) >> 22) & 0x3FF; /* OFDM0_D */
2244 val_x = result[final_candidate][0]; 2185 val_x = result[final_candidate][0];
2245 if ((val_x & 0x00000200) != 0) 2186 if ((val_x & 0x00000200) != 0)
2246 val_x = val_x | 0xFFFFFC00; 2187 val_x = val_x | 0xFFFFFC00;
@@ -2271,7 +2212,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
2271 ((val_y * oldval_0 >> 7) & 0x1)); 2212 ((val_y * oldval_0 >> 7) & 0x1));
2272 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n", 2213 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n",
2273 rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 2214 rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
2274 BMASKDWORD)); 2215 MASKDWORD));
2275 if (txonly) { 2216 if (txonly) {
2276 RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n"); 2217 RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n");
2277 return; 2218 return;
@@ -2299,7 +2240,7 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
2299 return; 2240 return;
2300 } else if (iqk_ok) { 2241 } else if (iqk_ok) {
2301 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 2242 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE,
2302 BMASKDWORD) >> 22) & 0x3FF; 2243 MASKDWORD) >> 22) & 0x3FF;
2303 val_x = result[final_candidate][4]; 2244 val_x = result[final_candidate][4];
2304 if ((val_x & 0x00000200) != 0) 2245 if ((val_x & 0x00000200) != 0)
2305 val_x = val_x | 0xFFFFFC00; 2246 val_x = val_x | 0xFFFFFC00;
@@ -2657,7 +2598,7 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
2657 rf_mode[index] = rtl_read_byte(rtlpriv, offset); 2598 rf_mode[index] = rtl_read_byte(rtlpriv, offset);
2658 /* 2. Set RF mode = standby mode */ 2599 /* 2. Set RF mode = standby mode */
2659 rtl_set_rfreg(hw, (enum radio_path)index, RF_AC, 2600 rtl_set_rfreg(hw, (enum radio_path)index, RF_AC,
2660 BRFREGOFFSETMASK, 0x010000); 2601 RFREG_OFFSET_MASK, 0x010000);
2661 if (rtlpci->init_ready) { 2602 if (rtlpci->init_ready) {
2662 /* switch CV-curve control by LC-calibration */ 2603 /* switch CV-curve control by LC-calibration */
2663 rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7, 2604 rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
@@ -2667,16 +2608,16 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
2667 0x08000, 0x01); 2608 0x08000, 0x01);
2668 } 2609 }
2669 u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6, 2610 u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6,
2670 BRFREGOFFSETMASK); 2611 RFREG_OFFSET_MASK);
2671 while ((!(u4tmp & BIT(11))) && timecount <= timeout) { 2612 while ((!(u4tmp & BIT(11))) && timecount <= timeout) {
2672 mdelay(50); 2613 mdelay(50);
2673 timecount += 50; 2614 timecount += 50;
2674 u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, 2615 u4tmp = rtl_get_rfreg(hw, (enum radio_path)index,
2675 RF_SYN_G6, BRFREGOFFSETMASK); 2616 RF_SYN_G6, RFREG_OFFSET_MASK);
2676 } 2617 }
2677 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2618 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2678 "PHY_LCK finish delay for %d ms=2\n", timecount); 2619 "PHY_LCK finish delay for %d ms=2\n", timecount);
2679 u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK); 2620 u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, RFREG_OFFSET_MASK);
2680 if (index == 0 && rtlhal->interfaceindex == 0) { 2621 if (index == 0 && rtlhal->interfaceindex == 0) {
2681 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2622 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2682 "path-A / 5G LCK\n"); 2623 "path-A / 5G LCK\n");
@@ -2696,9 +2637,9 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
2696 0x7f, i); 2637 0x7f, i);
2697 2638
2698 rtl_set_rfreg(hw, (enum radio_path)index, 0x4D, 2639 rtl_set_rfreg(hw, (enum radio_path)index, 0x4D,
2699 BRFREGOFFSETMASK, 0x0); 2640 RFREG_OFFSET_MASK, 0x0);
2700 readval = rtl_get_rfreg(hw, (enum radio_path)index, 2641 readval = rtl_get_rfreg(hw, (enum radio_path)index,
2701 0x4F, BRFREGOFFSETMASK); 2642 0x4F, RFREG_OFFSET_MASK);
2702 curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5; 2643 curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5;
2703 /* reg 0x4f [4:0] */ 2644 /* reg 0x4f [4:0] */
2704 /* reg 0x50 [19:10] */ 2645 /* reg 0x50 [19:10] */
@@ -2912,7 +2853,7 @@ static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
2912 } 2853 }
2913 rtl_set_rfreg(hw, (enum radio_path)rfpath, 2854 rtl_set_rfreg(hw, (enum radio_path)rfpath,
2914 currentcmd->para1, 2855 currentcmd->para1,
2915 BRFREGOFFSETMASK, 2856 RFREG_OFFSET_MASK,
2916 rtlphy->rfreg_chnlval[rfpath]); 2857 rtlphy->rfreg_chnlval[rfpath]);
2917 _rtl92d_phy_reload_imr_setting(hw, channel, 2858 _rtl92d_phy_reload_imr_setting(hw, channel,
2918 rfpath); 2859 rfpath);
@@ -2960,7 +2901,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
2960 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && 2901 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
2961 rtlhal->bandset == BAND_ON_BOTH) { 2902 rtlhal->bandset == BAND_ON_BOTH) {
2962 ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER, 2903 ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
2963 BMASKDWORD); 2904 MASKDWORD);
2964 if (rtlphy->current_channel > 14 && !(ret_value & BIT(0))) 2905 if (rtlphy->current_channel > 14 && !(ret_value & BIT(0)))
2965 rtl92d_phy_switch_wirelessband(hw, BAND_ON_5G); 2906 rtl92d_phy_switch_wirelessband(hw, BAND_ON_5G);
2966 else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0))) 2907 else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0)))
@@ -3112,7 +3053,7 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)
3112 /* a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */ 3053 /* a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */
3113 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 3054 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
3114 /* b. RF path 0 offset 0x00 = 0x00 disable RF */ 3055 /* b. RF path 0 offset 0x00 = 0x00 disable RF */
3115 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); 3056 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
3116 /* c. APSD_CTRL 0x600[7:0] = 0x40 */ 3057 /* c. APSD_CTRL 0x600[7:0] = 0x40 */
3117 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 3058 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
3118 /* d. APSD_CTRL 0x600[7:0] = 0x00 3059 /* d. APSD_CTRL 0x600[7:0] = 0x00
@@ -3120,12 +3061,12 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)
3120 * RF path 0 offset 0x00 = 0x00 3061 * RF path 0 offset 0x00 = 0x00
3121 * APSD_CTRL 0x600[7:0] = 0x40 3062 * APSD_CTRL 0x600[7:0] = 0x40
3122 * */ 3063 * */
3123 u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK); 3064 u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
3124 while (u4btmp != 0 && delay > 0) { 3065 while (u4btmp != 0 && delay > 0) {
3125 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); 3066 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
3126 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); 3067 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
3127 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 3068 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
3128 u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK); 3069 u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
3129 delay--; 3070 delay--;
3130 } 3071 }
3131 if (delay == 0) { 3072 if (delay == 0) {
@@ -3468,9 +3409,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
3468 /* 5G LAN ON */ 3409 /* 5G LAN ON */
3469 rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa); 3410 rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa);
3470 /* TX BB gain shift*1,Just for testchip,0xc80,0xc88 */ 3411 /* TX BB gain shift*1,Just for testchip,0xc80,0xc88 */
3471 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, 3412 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, MASKDWORD,
3472 0x40000100); 3413 0x40000100);
3473 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, 3414 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, MASKDWORD,
3474 0x40000100); 3415 0x40000100);
3475 if (rtlhal->macphymode == DUALMAC_DUALPHY) { 3416 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
3476 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, 3417 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
@@ -3524,16 +3465,16 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
3524 rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0); 3465 rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0);
3525 /* TX BB gain shift,Just for testchip,0xc80,0xc88 */ 3466 /* TX BB gain shift,Just for testchip,0xc80,0xc88 */
3526 if (rtlefuse->internal_pa_5g[0]) 3467 if (rtlefuse->internal_pa_5g[0])
3527 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, 3468 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, MASKDWORD,
3528 0x2d4000b5); 3469 0x2d4000b5);
3529 else 3470 else
3530 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, 3471 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, MASKDWORD,
3531 0x20000080); 3472 0x20000080);
3532 if (rtlefuse->internal_pa_5g[1]) 3473 if (rtlefuse->internal_pa_5g[1])
3533 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, 3474 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, MASKDWORD,
3534 0x2d4000b5); 3475 0x2d4000b5);
3535 else 3476 else
3536 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, 3477 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, MASKDWORD,
3537 0x20000080); 3478 0x20000080);
3538 if (rtlhal->macphymode == DUALMAC_DUALPHY) { 3479 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
3539 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, 3480 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
@@ -3560,8 +3501,8 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
3560 } 3501 }
3561 } 3502 }
3562 /* update IQK related settings */ 3503 /* update IQK related settings */
3563 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, BMASKDWORD, 0x40000100); 3504 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100);
3564 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, BMASKDWORD, 0x40000100); 3505 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100);
3565 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, 0x00); 3506 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, 0x00);
3566 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) | 3507 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) |
3567 BIT(26) | BIT(24), 0x00); 3508 BIT(26) | BIT(24), 0x00);
@@ -3590,7 +3531,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
3590 /* DMDP */ 3531 /* DMDP */
3591 if (rtlphy->rf_type == RF_1T1R) { 3532 if (rtlphy->rf_type == RF_1T1R) {
3592 /* Use antenna 0,0xc04,0xd04 */ 3533 /* Use antenna 0,0xc04,0xd04 */
3593 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x11); 3534 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x11);
3594 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1); 3535 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1);
3595 3536
3596 /* enable ad/da clock1 for dual-phy reg0x888 */ 3537 /* enable ad/da clock1 for dual-phy reg0x888 */
@@ -3612,7 +3553,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
3612 } else { 3553 } else {
3613 /* Single PHY */ 3554 /* Single PHY */
3614 /* Use antenna 0 & 1,0xc04,0xd04 */ 3555 /* Use antenna 0 & 1,0xc04,0xd04 */
3615 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x33); 3556 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x33);
3616 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3); 3557 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3);
3617 /* disable ad/da clock1,0x888 */ 3558 /* disable ad/da clock1,0x888 */
3618 rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0); 3559 rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0);
@@ -3620,9 +3561,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
3620 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; 3561 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
3621 rfpath++) { 3562 rfpath++) {
3622 rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath, 3563 rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath,
3623 RF_CHNLBW, BRFREGOFFSETMASK); 3564 RF_CHNLBW, RFREG_OFFSET_MASK);
3624 rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C, 3565 rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C,
3625 BRFREGOFFSETMASK); 3566 RFREG_OFFSET_MASK);
3626 } 3567 }
3627 for (i = 0; i < 2; i++) 3568 for (i = 0; i < 2; i++)
3628 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n", 3569 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n",
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
index b7498c5bafc5..7f29b8d765b3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
@@ -1295,18 +1295,4 @@
1295#define BWORD1 0xc 1295#define BWORD1 0xc
1296#define BDWORD 0xf 1296#define BDWORD 0xf
1297 1297
1298#define BMASKBYTE0 0xff
1299#define BMASKBYTE1 0xff00
1300#define BMASKBYTE2 0xff0000
1301#define BMASKBYTE3 0xff000000
1302#define BMASKHWORD 0xffff0000
1303#define BMASKLWORD 0x0000ffff
1304#define BMASKDWORD 0xffffffff
1305#define BMASK12BITS 0xfff
1306#define BMASKH4BITS 0xf0000000
1307#define BMASKOFDM_D 0xffc00000
1308#define BMASKCCK 0x3f3f3f3f
1309
1310#define BRFREGOFFSETMASK 0xfffff
1311
1312#endif 1298#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
index 20144e0b4142..6a6ac540d5b5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
@@ -125,7 +125,7 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
125 } 125 }
126 126
127 tmpval = tx_agc[RF90_PATH_A] & 0xff; 127 tmpval = tx_agc[RF90_PATH_A] & 0xff;
128 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval); 128 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
129 RTPRINT(rtlpriv, FPHY, PHY_TXPWR, 129 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
130 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", 130 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
131 tmpval, RTXAGC_A_CCK1_MCS32); 131 tmpval, RTXAGC_A_CCK1_MCS32);
@@ -135,7 +135,7 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
135 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", 135 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
136 tmpval, RTXAGC_B_CCK11_A_CCK2_11); 136 tmpval, RTXAGC_B_CCK11_A_CCK2_11);
137 tmpval = tx_agc[RF90_PATH_B] >> 24; 137 tmpval = tx_agc[RF90_PATH_B] >> 24;
138 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval); 138 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
139 RTPRINT(rtlpriv, FPHY, PHY_TXPWR, 139 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
140 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", 140 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
141 tmpval, RTXAGC_B_CCK11_A_CCK2_11); 141 tmpval, RTXAGC_B_CCK11_A_CCK2_11);
@@ -360,7 +360,7 @@ static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
360 regoffset = regoffset_a[index]; 360 regoffset = regoffset_a[index];
361 else 361 else
362 regoffset = regoffset_b[index]; 362 regoffset = regoffset_b[index];
363 rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval); 363 rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
364 RTPRINT(rtlpriv, FPHY, PHY_TXPWR, 364 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
365 "Set 0x%x = %08x\n", regoffset, writeval); 365 "Set 0x%x = %08x\n", regoffset, writeval);
366 if (((get_rf_type(rtlphy) == RF_2T2R) && 366 if (((get_rf_type(rtlphy) == RF_2T2R) &&
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
index 0eb0f4ae5920..99c2ab5dfceb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
@@ -545,7 +545,7 @@ static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
545 545
546void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, 546void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
547 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 547 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
548 struct ieee80211_tx_info *info, 548 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
549 struct ieee80211_sta *sta, 549 struct ieee80211_sta *sta,
550 struct sk_buff *skb, 550 struct sk_buff *skb,
551 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) 551 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
@@ -786,7 +786,8 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
786 SET_TX_DESC_OWN(pdesc, 1); 786 SET_TX_DESC_OWN(pdesc, 1);
787} 787}
788 788
789void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) 789void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
790 u8 desc_name, u8 *val)
790{ 791{
791 if (istx) { 792 if (istx) {
792 switch (desc_name) { 793 switch (desc_name) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
index c1b5dfb79d53..fb5cf0634e8d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
@@ -728,8 +728,8 @@ struct rx_desc_92d {
728} __packed; 728} __packed;
729 729
730void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, 730void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
731 struct ieee80211_hdr *hdr, 731 struct ieee80211_hdr *hdr, u8 *pdesc,
732 u8 *pdesc, struct ieee80211_tx_info *info, 732 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
733 struct ieee80211_sta *sta, 733 struct ieee80211_sta *sta,
734 struct sk_buff *skb, u8 hw_queue, 734 struct sk_buff *skb, u8 hw_queue,
735 struct rtl_tcb_desc *ptcb_desc); 735 struct rtl_tcb_desc *ptcb_desc);
@@ -737,7 +737,8 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,
737 struct rtl_stats *stats, 737 struct rtl_stats *stats,
738 struct ieee80211_rx_status *rx_status, 738 struct ieee80211_rx_status *rx_status,
739 u8 *pdesc, struct sk_buff *skb); 739 u8 *pdesc, struct sk_buff *skb);
740void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); 740void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
741 u8 desc_name, u8 *val);
741u32 rtl92de_get_desc(u8 *pdesc, bool istx, u8 desc_name); 742u32 rtl92de_get_desc(u8 *pdesc, bool istx, u8 desc_name);
742void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); 743void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
743void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, 744void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index 4f461786a7eb..3015af167b2b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -251,7 +251,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
251 u8 e_aci = *val; 251 u8 e_aci = *val;
252 rtl92s_dm_init_edca_turbo(hw); 252 rtl92s_dm_init_edca_turbo(hw);
253 253
254 if (rtlpci->acm_method != eAcmWay2_SW) 254 if (rtlpci->acm_method != EACMWAY2_SW)
255 rtlpriv->cfg->ops->set_hw_reg(hw, 255 rtlpriv->cfg->ops->set_hw_reg(hw,
256 HW_VAR_ACM_CTRL, 256 HW_VAR_ACM_CTRL,
257 &e_aci); 257 &e_aci);
@@ -955,7 +955,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
955 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 955 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
956 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 956 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
957 u8 tmp_byte = 0; 957 u8 tmp_byte = 0;
958 958 unsigned long flags;
959 bool rtstatus = true; 959 bool rtstatus = true;
960 u8 tmp_u1b; 960 u8 tmp_u1b;
961 int err = false; 961 int err = false;
@@ -967,6 +967,16 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
967 967
968 rtlpci->being_init_adapter = true; 968 rtlpci->being_init_adapter = true;
969 969
970 /* As this function can take a very long time (up to 350 ms)
971 * and can be called with irqs disabled, reenable the irqs
972 * to let the other devices continue being serviced.
973 *
974 * It is safe doing so since our own interrupts will only be enabled
975 * in a subsequent step.
976 */
977 local_save_flags(flags);
978 local_irq_enable();
979
970 rtlpriv->intf_ops->disable_aspm(hw); 980 rtlpriv->intf_ops->disable_aspm(hw);
971 981
972 /* 1. MAC Initialize */ 982 /* 1. MAC Initialize */
@@ -984,7 +994,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
984 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 994 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
985 "Failed to download FW. Init HW without FW now... " 995 "Failed to download FW. Init HW without FW now... "
986 "Please copy FW into /lib/firmware/rtlwifi\n"); 996 "Please copy FW into /lib/firmware/rtlwifi\n");
987 return 1; 997 err = 1;
998 goto exit;
988 } 999 }
989 1000
990 /* After FW download, we have to reset MAC register */ 1001 /* After FW download, we have to reset MAC register */
@@ -997,7 +1008,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
997 /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */ 1008 /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
998 if (!rtl92s_phy_mac_config(hw)) { 1009 if (!rtl92s_phy_mac_config(hw)) {
999 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n"); 1010 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n");
1000 return rtstatus; 1011 err = rtstatus;
1012 goto exit;
1001 } 1013 }
1002 1014
1003 /* because last function modify RCR, so we update 1015 /* because last function modify RCR, so we update
@@ -1016,7 +1028,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
1016 /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */ 1028 /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
1017 if (!rtl92s_phy_bb_config(hw)) { 1029 if (!rtl92s_phy_bb_config(hw)) {
1018 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n"); 1030 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n");
1019 return rtstatus; 1031 err = rtstatus;
1032 goto exit;
1020 } 1033 }
1021 1034
1022 /* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */ 1035 /* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */
@@ -1033,7 +1046,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
1033 1046
1034 if (!rtl92s_phy_rf_config(hw)) { 1047 if (!rtl92s_phy_rf_config(hw)) {
1035 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); 1048 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n");
1036 return rtstatus; 1049 err = rtstatus;
1050 goto exit;
1037 } 1051 }
1038 1052
1039 /* After read predefined TXT, we must set BB/MAC/RF 1053 /* After read predefined TXT, we must set BB/MAC/RF
@@ -1122,8 +1136,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
1122 1136
1123 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON); 1137 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);
1124 rtl92s_dm_init(hw); 1138 rtl92s_dm_init(hw);
1139exit:
1140 local_irq_restore(flags);
1125 rtlpci->being_init_adapter = false; 1141 rtlpci->being_init_adapter = false;
1126
1127 return err; 1142 return err;
1128} 1143}
1129 1144
@@ -1135,12 +1150,13 @@ void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr)
1135void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 1150void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1136{ 1151{
1137 struct rtl_priv *rtlpriv = rtl_priv(hw); 1152 struct rtl_priv *rtlpriv = rtl_priv(hw);
1138 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 1153 u32 reg_rcr;
1139 u32 reg_rcr = rtlpci->receive_config;
1140 1154
1141 if (rtlpriv->psc.rfpwr_state != ERFON) 1155 if (rtlpriv->psc.rfpwr_state != ERFON)
1142 return; 1156 return;
1143 1157
1158 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
1159
1144 if (check_bssid) { 1160 if (check_bssid) {
1145 reg_rcr |= (RCR_CBSSID); 1161 reg_rcr |= (RCR_CBSSID);
1146 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr)); 1162 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
index 9c092e6eb3fe..77c5b5f35244 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
@@ -30,6 +30,7 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "../ps.h" 32#include "../ps.h"
33#include "../core.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "phy.h" 36#include "phy.h"
@@ -833,18 +834,7 @@ static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
833 834
834 if (configtype == BASEBAND_CONFIG_PHY_REG) { 835 if (configtype == BASEBAND_CONFIG_PHY_REG) {
835 for (i = 0; i < phy_reg_len; i = i + 2) { 836 for (i = 0; i < phy_reg_len; i = i + 2) {
836 if (phy_reg_table[i] == 0xfe) 837 rtl_addr_delay(phy_reg_table[i]);
837 mdelay(50);
838 else if (phy_reg_table[i] == 0xfd)
839 mdelay(5);
840 else if (phy_reg_table[i] == 0xfc)
841 mdelay(1);
842 else if (phy_reg_table[i] == 0xfb)
843 udelay(50);
844 else if (phy_reg_table[i] == 0xfa)
845 udelay(5);
846 else if (phy_reg_table[i] == 0xf9)
847 udelay(1);
848 838
849 /* Add delay for ECS T20 & LG malow platform, */ 839 /* Add delay for ECS T20 & LG malow platform, */
850 udelay(1); 840 udelay(1);
@@ -886,18 +876,7 @@ static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
886 876
887 if (configtype == BASEBAND_CONFIG_PHY_REG) { 877 if (configtype == BASEBAND_CONFIG_PHY_REG) {
888 for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) { 878 for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
889 if (phy_regarray2xtxr_table[i] == 0xfe) 879 rtl_addr_delay(phy_regarray2xtxr_table[i]);
890 mdelay(50);
891 else if (phy_regarray2xtxr_table[i] == 0xfd)
892 mdelay(5);
893 else if (phy_regarray2xtxr_table[i] == 0xfc)
894 mdelay(1);
895 else if (phy_regarray2xtxr_table[i] == 0xfb)
896 udelay(50);
897 else if (phy_regarray2xtxr_table[i] == 0xfa)
898 udelay(5);
899 else if (phy_regarray2xtxr_table[i] == 0xf9)
900 udelay(1);
901 880
902 rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i], 881 rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
903 phy_regarray2xtxr_table[i + 1], 882 phy_regarray2xtxr_table[i + 1],
@@ -920,18 +899,7 @@ static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
920 899
921 if (configtype == BASEBAND_CONFIG_PHY_REG) { 900 if (configtype == BASEBAND_CONFIG_PHY_REG) {
922 for (i = 0; i < phy_pg_len; i = i + 3) { 901 for (i = 0; i < phy_pg_len; i = i + 3) {
923 if (phy_table_pg[i] == 0xfe) 902 rtl_addr_delay(phy_table_pg[i]);
924 mdelay(50);
925 else if (phy_table_pg[i] == 0xfd)
926 mdelay(5);
927 else if (phy_table_pg[i] == 0xfc)
928 mdelay(1);
929 else if (phy_table_pg[i] == 0xfb)
930 udelay(50);
931 else if (phy_table_pg[i] == 0xfa)
932 udelay(5);
933 else if (phy_table_pg[i] == 0xf9)
934 udelay(1);
935 903
936 _rtl92s_store_pwrindex_diffrate_offset(hw, 904 _rtl92s_store_pwrindex_diffrate_offset(hw,
937 phy_table_pg[i], 905 phy_table_pg[i],
@@ -1034,28 +1002,9 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
1034 switch (rfpath) { 1002 switch (rfpath) {
1035 case RF90_PATH_A: 1003 case RF90_PATH_A:
1036 for (i = 0; i < radio_a_tblen; i = i + 2) { 1004 for (i = 0; i < radio_a_tblen; i = i + 2) {
1037 if (radio_a_table[i] == 0xfe) 1005 rtl_rfreg_delay(hw, rfpath, radio_a_table[i],
1038 /* Delay specific ms. Only RF configuration 1006 MASK20BITS, radio_a_table[i + 1]);
1039 * requires delay. */
1040 mdelay(50);
1041 else if (radio_a_table[i] == 0xfd)
1042 mdelay(5);
1043 else if (radio_a_table[i] == 0xfc)
1044 mdelay(1);
1045 else if (radio_a_table[i] == 0xfb)
1046 udelay(50);
1047 else if (radio_a_table[i] == 0xfa)
1048 udelay(5);
1049 else if (radio_a_table[i] == 0xf9)
1050 udelay(1);
1051 else
1052 rtl92s_phy_set_rf_reg(hw, rfpath,
1053 radio_a_table[i],
1054 MASK20BITS,
1055 radio_a_table[i + 1]);
1056 1007
1057 /* Add delay for ECS T20 & LG malow platform */
1058 udelay(1);
1059 } 1008 }
1060 1009
1061 /* PA Bias current for inferiority IC */ 1010 /* PA Bias current for inferiority IC */
@@ -1063,28 +1012,8 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
1063 break; 1012 break;
1064 case RF90_PATH_B: 1013 case RF90_PATH_B:
1065 for (i = 0; i < radio_b_tblen; i = i + 2) { 1014 for (i = 0; i < radio_b_tblen; i = i + 2) {
1066 if (radio_b_table[i] == 0xfe) 1015 rtl_rfreg_delay(hw, rfpath, radio_b_table[i],
1067 /* Delay specific ms. Only RF configuration 1016 MASK20BITS, radio_b_table[i + 1]);
1068 * requires delay.*/
1069 mdelay(50);
1070 else if (radio_b_table[i] == 0xfd)
1071 mdelay(5);
1072 else if (radio_b_table[i] == 0xfc)
1073 mdelay(1);
1074 else if (radio_b_table[i] == 0xfb)
1075 udelay(50);
1076 else if (radio_b_table[i] == 0xfa)
1077 udelay(5);
1078 else if (radio_b_table[i] == 0xf9)
1079 udelay(1);
1080 else
1081 rtl92s_phy_set_rf_reg(hw, rfpath,
1082 radio_b_table[i],
1083 MASK20BITS,
1084 radio_b_table[i + 1]);
1085
1086 /* Add delay for ECS T20 & LG malow platform */
1087 udelay(1);
1088 } 1017 }
1089 break; 1018 break;
1090 case RF90_PATH_C: 1019 case RF90_PATH_C:
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
index c81c83591940..e13043479b71 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
@@ -1165,16 +1165,4 @@
1165 1165
1166#define BTX_AGCRATECCK 0x7f00 1166#define BTX_AGCRATECCK 0x7f00
1167 1167
1168#define MASKBYTE0 0xff
1169#define MASKBYTE1 0xff00
1170#define MASKBYTE2 0xff0000
1171#define MASKBYTE3 0xff000000
1172#define MASKHWORD 0xffff0000
1173#define MASKLWORD 0x0000ffff
1174#define MASKDWORD 0xffffffff
1175
1176#define MAKS12BITS 0xfffff
1177#define MASK20BITS 0xfffff
1178#define RFREG_OFFSET_MASK 0xfffff
1179
1180#endif 1168#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
index 92d38ab3c60e..78a81c1e390b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
@@ -52,7 +52,7 @@ static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,
52 /* We only care about the path A for legacy. */ 52 /* We only care about the path A for legacy. */
53 if (rtlefuse->eeprom_version < 2) { 53 if (rtlefuse->eeprom_version < 2) {
54 pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf); 54 pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf);
55 } else if (rtlefuse->eeprom_version >= 2) { 55 } else {
56 legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff 56 legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff
57 [RF90_PATH_A][chnl - 1]; 57 [RF90_PATH_A][chnl - 1];
58 58
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 163a681962c6..36b48be8329c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -336,7 +336,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
336 336
337void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, 337void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
338 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 338 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
339 struct ieee80211_tx_info *info, 339 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
340 struct ieee80211_sta *sta, 340 struct ieee80211_sta *sta,
341 struct sk_buff *skb, 341 struct sk_buff *skb,
342 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) 342 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
@@ -573,7 +573,8 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
573 } 573 }
574} 574}
575 575
576void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) 576void rtl92se_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
577 u8 desc_name, u8 *val)
577{ 578{
578 if (istx) { 579 if (istx) {
579 switch (desc_name) { 580 switch (desc_name) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
index 64dd66f287c1..5a13f17e3b41 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
@@ -29,8 +29,9 @@
29#ifndef __REALTEK_PCI92SE_TRX_H__ 29#ifndef __REALTEK_PCI92SE_TRX_H__
30#define __REALTEK_PCI92SE_TRX_H__ 30#define __REALTEK_PCI92SE_TRX_H__
31 31
32void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, 32void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
33 u8 *pdesc, struct ieee80211_tx_info *info, 33 struct ieee80211_hdr *hdr, u8 *pdesc,
34 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
34 struct ieee80211_sta *sta, 35 struct ieee80211_sta *sta,
35 struct sk_buff *skb, u8 hw_queue, 36 struct sk_buff *skb, u8 hw_queue,
36 struct rtl_tcb_desc *ptcb_desc); 37 struct rtl_tcb_desc *ptcb_desc);
@@ -39,7 +40,8 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool firstseg,
39bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, 40bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
40 struct ieee80211_rx_status *rx_status, u8 *pdesc, 41 struct ieee80211_rx_status *rx_status, u8 *pdesc,
41 struct sk_buff *skb); 42 struct sk_buff *skb);
42void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); 43void rtl92se_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
44 u8 desc_name, u8 *val);
43u32 rtl92se_get_desc(u8 *pdesc, bool istx, u8 desc_name); 45u32 rtl92se_get_desc(u8 *pdesc, bool istx, u8 desc_name);
44void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); 46void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
45 47
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile
index 4ed731f09b1f..9c34a85fdb89 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile
@@ -10,7 +10,6 @@ rtl8723ae-objs := \
10 led.o \ 10 led.o \
11 phy.o \ 11 phy.o \
12 pwrseq.o \ 12 pwrseq.o \
13 pwrseqcmd.o \
14 rf.o \ 13 rf.o \
15 sw.o \ 14 sw.o \
16 table.o \ 15 table.o \
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
index 8c110356dff9..debe261a7eeb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
@@ -46,11 +46,6 @@
46#define E_CUT_VERSION BIT(14) 46#define E_CUT_VERSION BIT(14)
47#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) 47#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28))
48 48
49enum version_8723e {
50 VERSION_TEST_UMC_CHIP_8723 = 0x0081,
51 VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089,
52 VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089,
53};
54 49
55/* MASK */ 50/* MASK */
56#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) 51#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
index a36eee28f9e7..863ddb3e2888 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
@@ -35,6 +35,7 @@
35#include "def.h" 35#include "def.h"
36#include "phy.h" 36#include "phy.h"
37#include "dm.h" 37#include "dm.h"
38#include "../rtl8723com/dm_common.h"
38#include "fw.h" 39#include "fw.h"
39#include "hal_btc.h" 40#include "hal_btc.h"
40 41
@@ -483,16 +484,6 @@ static void rtl8723ae_dm_dig(struct ieee80211_hw *hw)
483 rtl8723ae_dm_ctrl_initgain_by_twoport(hw); 484 rtl8723ae_dm_ctrl_initgain_by_twoport(hw);
484} 485}
485 486
486static void rtl8723ae_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
487{
488 struct rtl_priv *rtlpriv = rtl_priv(hw);
489
490 rtlpriv->dm.dynamic_txpower_enable = false;
491
492 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
493 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
494}
495
496static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw) 487static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw)
497{ 488{
498 struct rtl_priv *rtlpriv = rtl_priv(hw); 489 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -585,19 +576,6 @@ void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw)
585 } 576 }
586} 577}
587 578
588static void rtl8723ae_dm_pwdmonitor(struct ieee80211_hw *hw)
589{
590}
591
592void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw)
593{
594 struct rtl_priv *rtlpriv = rtl_priv(hw);
595
596 rtlpriv->dm.current_turbo_edca = false;
597 rtlpriv->dm.is_any_nonbepkts = false;
598 rtlpriv->dm.is_cur_rdlstate = false;
599}
600
601static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw) 579static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
602{ 580{
603 struct rtl_priv *rtlpriv = rtl_priv(hw); 581 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -778,17 +756,6 @@ static void rtl8723ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
778 } 756 }
779} 757}
780 758
781static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw)
782{
783 struct rtl_priv *rtlpriv = rtl_priv(hw);
784
785 rtlpriv->dm_pstable.pre_ccastate = CCA_MAX;
786 rtlpriv->dm_pstable.cur_ccasate = CCA_MAX;
787 rtlpriv->dm_pstable.pre_rfstate = RF_MAX;
788 rtlpriv->dm_pstable.cur_rfstate = RF_MAX;
789 rtlpriv->dm_pstable.rssi_val_min = 0;
790}
791
792void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal) 759void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal)
793{ 760{
794 struct rtl_priv *rtlpriv = rtl_priv(hw); 761 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -905,11 +872,11 @@ void rtl8723ae_dm_init(struct ieee80211_hw *hw)
905 872
906 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 873 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
907 rtl8723ae_dm_diginit(hw); 874 rtl8723ae_dm_diginit(hw);
908 rtl8723ae_dm_init_dynamic_txpower(hw); 875 rtl8723_dm_init_dynamic_txpower(hw);
909 rtl8723ae_dm_init_edca_turbo(hw); 876 rtl8723_dm_init_edca_turbo(hw);
910 rtl8723ae_dm_init_rate_adaptive_mask(hw); 877 rtl8723ae_dm_init_rate_adaptive_mask(hw);
911 rtl8723ae_dm_initialize_txpower_tracking(hw); 878 rtl8723ae_dm_initialize_txpower_tracking(hw);
912 rtl8723ae_dm_init_dynamic_bpowersaving(hw); 879 rtl8723_dm_init_dynamic_bb_powersaving(hw);
913} 880}
914 881
915void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw) 882void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw)
@@ -930,7 +897,6 @@ void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw)
930 if ((ppsc->rfpwr_state == ERFON) && 897 if ((ppsc->rfpwr_state == ERFON) &&
931 ((!fw_current_inpsmode) && fw_ps_awake) && 898 ((!fw_current_inpsmode) && fw_ps_awake) &&
932 (!ppsc->rfchange_inprogress)) { 899 (!ppsc->rfchange_inprogress)) {
933 rtl8723ae_dm_pwdmonitor(hw);
934 rtl8723ae_dm_dig(hw); 900 rtl8723ae_dm_dig(hw);
935 rtl8723ae_dm_false_alarm_counter_statistics(hw); 901 rtl8723ae_dm_false_alarm_counter_statistics(hw);
936 rtl8723ae_dm_dynamic_bpowersaving(hw); 902 rtl8723ae_dm_dynamic_bpowersaving(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
index a372b0204456..d253bb53d03e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
@@ -147,7 +147,6 @@ enum dm_dig_connect_e {
147void rtl8723ae_dm_init(struct ieee80211_hw *hw); 147void rtl8723ae_dm_init(struct ieee80211_hw *hw);
148void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw); 148void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw);
149void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw); 149void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw);
150void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw);
151void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); 150void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
152void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); 151void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
153void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw); 152void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
index ba1502b172a6..728b7563ad36 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
@@ -34,199 +34,7 @@
34#include "reg.h" 34#include "reg.h"
35#include "def.h" 35#include "def.h"
36#include "fw.h" 36#include "fw.h"
37 37#include "../rtl8723com/fw_common.h"
38static void _rtl8723ae_enable_fw_download(struct ieee80211_hw *hw, bool enable)
39{
40 struct rtl_priv *rtlpriv = rtl_priv(hw);
41 u8 tmp;
42 if (enable) {
43 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
44 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
45
46 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
47 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
48
49 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
50 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
51 } else {
52 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
53 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
54
55 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
56 }
57}
58
59static void _rtl8723ae_fw_block_write(struct ieee80211_hw *hw,
60 const u8 *buffer, u32 size)
61{
62 struct rtl_priv *rtlpriv = rtl_priv(hw);
63 u32 blockSize = sizeof(u32);
64 u8 *bufferPtr = (u8 *) buffer;
65 u32 *pu4BytePtr = (u32 *) buffer;
66 u32 i, offset, blockCount, remainSize;
67
68 blockCount = size / blockSize;
69 remainSize = size % blockSize;
70
71 for (i = 0; i < blockCount; i++) {
72 offset = i * blockSize;
73 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
74 *(pu4BytePtr + i));
75 }
76
77 if (remainSize) {
78 offset = blockCount * blockSize;
79 bufferPtr += offset;
80 for (i = 0; i < remainSize; i++) {
81 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
82 offset + i), *(bufferPtr + i));
83 }
84 }
85}
86
87static void _rtl8723ae_fw_page_write(struct ieee80211_hw *hw,
88 u32 page, const u8 *buffer, u32 size)
89{
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 u8 value8;
92 u8 u8page = (u8) (page & 0x07);
93
94 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
95
96 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
97 _rtl8723ae_fw_block_write(hw, buffer, size);
98}
99
100static void _rtl8723ae_write_fw(struct ieee80211_hw *hw,
101 enum version_8723e version, u8 *buffer,
102 u32 size)
103{
104 struct rtl_priv *rtlpriv = rtl_priv(hw);
105 u8 *bufferPtr = (u8 *) buffer;
106 u32 page_nums, remain_size;
107 u32 page, offset;
108
109 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
110
111 page_nums = size / FW_8192C_PAGE_SIZE;
112 remain_size = size % FW_8192C_PAGE_SIZE;
113
114 if (page_nums > 6) {
115 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
116 "Page numbers should not be greater then 6\n");
117 }
118
119 for (page = 0; page < page_nums; page++) {
120 offset = page * FW_8192C_PAGE_SIZE;
121 _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset),
122 FW_8192C_PAGE_SIZE);
123 }
124
125 if (remain_size) {
126 offset = page_nums * FW_8192C_PAGE_SIZE;
127 page = page_nums;
128 _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset),
129 remain_size);
130 }
131
132 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n");
133}
134
135static int _rtl8723ae_fw_free_to_go(struct ieee80211_hw *hw)
136{
137 struct rtl_priv *rtlpriv = rtl_priv(hw);
138 int err = -EIO;
139 u32 counter = 0;
140 u32 value32;
141
142 do {
143 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
144 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
145 (!(value32 & FWDL_ChkSum_rpt)));
146
147 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
148 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
149 "chksum report faill ! REG_MCUFWDL:0x%08x .\n",
150 value32);
151 goto exit;
152 }
153
154 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
155 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
156
157 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
158 value32 |= MCUFWDL_RDY;
159 value32 &= ~WINTINI_RDY;
160 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
161
162 counter = 0;
163
164 do {
165 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
166 if (value32 & WINTINI_RDY) {
167 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
168 "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",
169 value32);
170 err = 0;
171 goto exit;
172 }
173
174 mdelay(FW_8192C_POLLING_DELAY);
175
176 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
177
178 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
179 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32);
180
181exit:
182 return err;
183}
184
185int rtl8723ae_download_fw(struct ieee80211_hw *hw)
186{
187 struct rtl_priv *rtlpriv = rtl_priv(hw);
188 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
189 struct rtl8723ae_firmware_header *pfwheader;
190 u8 *pfwdata;
191 u32 fwsize;
192 int err;
193 enum version_8723e version = rtlhal->version;
194
195 if (!rtlhal->pfirmware)
196 return 1;
197
198 pfwheader = (struct rtl8723ae_firmware_header *)rtlhal->pfirmware;
199 pfwdata = (u8 *) rtlhal->pfirmware;
200 fwsize = rtlhal->fwsize;
201
202 if (IS_FW_HEADER_EXIST(pfwheader)) {
203 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
204 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
205 pfwheader->version, pfwheader->signature,
206 (int)sizeof(struct rtl8723ae_firmware_header));
207
208 pfwdata = pfwdata + sizeof(struct rtl8723ae_firmware_header);
209 fwsize = fwsize - sizeof(struct rtl8723ae_firmware_header);
210 }
211
212 if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) {
213 rtl8723ae_firmware_selfreset(hw);
214 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
215 }
216 _rtl8723ae_enable_fw_download(hw, true);
217 _rtl8723ae_write_fw(hw, version, pfwdata, fwsize);
218 _rtl8723ae_enable_fw_download(hw, false);
219
220 err = _rtl8723ae_fw_free_to_go(hw);
221 if (err) {
222 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
223 "Firmware is not ready to run!\n");
224 } else {
225 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
226 "Firmware is ready to run!\n");
227 }
228 return 0;
229}
230 38
231static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) 39static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
232{ 40{
@@ -463,50 +271,6 @@ void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw,
463 return; 271 return;
464} 272}
465 273
466void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw)
467{
468 u8 u1tmp;
469 u8 delay = 100;
470 struct rtl_priv *rtlpriv = rtl_priv(hw);
471
472 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
473 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
474
475 while (u1tmp & BIT(2)) {
476 delay--;
477 if (delay == 0)
478 break;
479 udelay(50);
480 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
481 }
482 if (delay == 0) {
483 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
484 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2)));
485 }
486}
487
488void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
489{
490 struct rtl_priv *rtlpriv = rtl_priv(hw);
491 u8 u1_h2c_set_pwrmode[3] = { 0 };
492 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
493
494 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
495
496 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
497 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
498 (rtlpriv->mac80211.p2p) ?
499 ppsc->smart_ps : 1);
500 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
501 ppsc->reg_max_lps_awakeintvl);
502
503 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
504 "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
505 u1_h2c_set_pwrmode, 3);
506 rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
507
508}
509
510static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw, 274static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw,
511 struct sk_buff *skb) 275 struct sk_buff *skb)
512{ 276{
@@ -812,7 +576,6 @@ void rtl8723ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
812 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); 576 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
813 577
814 p2p_ps_offload->offload_en = 1; 578 p2p_ps_offload->offload_en = 1;
815
816 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { 579 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
817 p2p_ps_offload->role = 1; 580 p2p_ps_offload->role = 1;
818 p2p_ps_offload->allstasleep = 0; 581 p2p_ps_offload->allstasleep = 0;
@@ -836,3 +599,24 @@ void rtl8723ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
836 } 599 }
837 rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); 600 rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
838} 601}
602
603void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
604{
605 struct rtl_priv *rtlpriv = rtl_priv(hw);
606 u8 u1_h2c_set_pwrmode[3] = { 0 };
607 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
608
609 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
610
611 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
612 SET_H2CCMD_PWRMODE_PARM_SMART_PS_23A(u1_h2c_set_pwrmode,
613 (rtlpriv->mac80211.p2p) ?
614 ppsc->smart_ps : 1);
615 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
616 ppsc->reg_max_lps_awakeintvl);
617
618 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
619 "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
620 u1_h2c_set_pwrmode, 3);
621 rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
622}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
index ed3b795e6980..d355b85dd9fe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
@@ -34,7 +34,7 @@
34#define FW_8192C_END_ADDRESS 0x3FFF 34#define FW_8192C_END_ADDRESS 0x3FFF
35#define FW_8192C_PAGE_SIZE 4096 35#define FW_8192C_PAGE_SIZE 4096
36#define FW_8192C_POLLING_DELAY 5 36#define FW_8192C_POLLING_DELAY 5
37#define FW_8192C_POLLING_TIMEOUT_COUNT 1000 37#define FW_8192C_POLLING_TIMEOUT_COUNT 6000
38 38
39#define BEACON_PG 0 39#define BEACON_PG 0
40#define PSPOLL_PG 2 40#define PSPOLL_PG 2
@@ -65,21 +65,9 @@ struct rtl8723ae_firmware_header {
65 u32 rsvd5; 65 u32 rsvd5;
66}; 66};
67 67
68enum rtl8192c_h2c_cmd {
69 H2C_AP_OFFLOAD = 0,
70 H2C_SETPWRMODE = 1,
71 H2C_JOINBSSRPT = 2,
72 H2C_RSVDPAGE = 3,
73 H2C_RSSI_REPORT = 4,
74 H2C_P2P_PS_CTW_CMD = 5,
75 H2C_P2P_PS_OFFLOAD = 6,
76 H2C_RA_MASK = 7,
77 MAX_H2CCMD
78};
79
80#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ 68#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
81 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) 69 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
82#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ 70#define SET_H2CCMD_PWRMODE_PARM_SMART_PS_23A(__ph2ccmd, __val) \
83 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) 71 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
84#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ 72#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
85 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) 73 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
@@ -92,10 +80,8 @@ enum rtl8192c_h2c_cmd {
92#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ 80#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
93 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) 81 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
94 82
95int rtl8723ae_download_fw(struct ieee80211_hw *hw);
96void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, 83void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
97 u32 cmd_len, u8 *p_cmdbuffer); 84 u32 cmd_len, u8 *p_cmdbuffer);
98void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
99void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); 85void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
100void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); 86void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
101void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); 87void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
index 3d092e4b0b7f..48fee1be78c2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
@@ -31,6 +31,8 @@
31#include "../pci.h" 31#include "../pci.h"
32#include "dm.h" 32#include "dm.h"
33#include "fw.h" 33#include "fw.h"
34#include "../rtl8723com/fw_common.h"
35#include "../rtl8723com/fw_common.h"
34#include "phy.h" 36#include "phy.h"
35#include "reg.h" 37#include "reg.h"
36#include "hal_btc.h" 38#include "hal_btc.h"
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
index 68c28340f791..5d534df8d90c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
@@ -30,7 +30,9 @@
30#include "hal_btc.h" 30#include "hal_btc.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "phy.h" 32#include "phy.h"
33#include "../rtl8723com/phy_common.h"
33#include "fw.h" 34#include "fw.h"
35#include "../rtl8723com/fw_common.h"
34#include "reg.h" 36#include "reg.h"
35#include "def.h" 37#include "def.h"
36 38
@@ -391,13 +393,13 @@ static void rtl8723ae_dm_bt_set_sw_full_time_dac_swing(struct ieee80211_hw *hw,
391 if (sw_dac_swing_on) { 393 if (sw_dac_swing_on) {
392 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, 394 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
393 "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl); 395 "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl);
394 rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 396 rtl8723_phy_set_bb_reg(hw, 0x880, 0xff000000,
395 sw_dac_swing_lvl); 397 sw_dac_swing_lvl);
396 rtlpcipriv->bt_coexist.sw_coexist_all_off = false; 398 rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
397 } else { 399 } else {
398 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, 400 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
399 "[BTCoex], SwDacSwing Off!\n"); 401 "[BTCoex], SwDacSwing Off!\n");
400 rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0); 402 rtl8723_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0);
401 } 403 }
402} 404}
403 405
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index c333dfd116b8..f4c9852d1e1e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -38,10 +38,11 @@
38#include "def.h" 38#include "def.h"
39#include "phy.h" 39#include "phy.h"
40#include "dm.h" 40#include "dm.h"
41#include "../rtl8723com/dm_common.h"
41#include "fw.h" 42#include "fw.h"
43#include "../rtl8723com/fw_common.h"
42#include "led.h" 44#include "led.h"
43#include "hw.h" 45#include "hw.h"
44#include "pwrseqcmd.h"
45#include "pwrseq.h" 46#include "pwrseq.h"
46#include "btc.h" 47#include "btc.h"
47 48
@@ -304,9 +305,9 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
304 break; } 305 break; }
305 case HW_VAR_AC_PARAM:{ 306 case HW_VAR_AC_PARAM:{
306 u8 e_aci = *((u8 *) val); 307 u8 e_aci = *((u8 *) val);
307 rtl8723ae_dm_init_edca_turbo(hw); 308 rtl8723_dm_init_edca_turbo(hw);
308 309
309 if (rtlpci->acm_method != eAcmWay2_SW) 310 if (rtlpci->acm_method != EACMWAY2_SW)
310 rtlpriv->cfg->ops->set_hw_reg(hw, 311 rtlpriv->cfg->ops->set_hw_reg(hw,
311 HW_VAR_ACM_CTRL, 312 HW_VAR_ACM_CTRL,
312 (u8 *) (&e_aci)); 313 (u8 *) (&e_aci));
@@ -880,23 +881,33 @@ int rtl8723ae_hw_init(struct ieee80211_hw *hw)
880 bool rtstatus = true; 881 bool rtstatus = true;
881 int err; 882 int err;
882 u8 tmp_u1b; 883 u8 tmp_u1b;
884 unsigned long flags;
883 885
884 rtlpriv->rtlhal.being_init_adapter = true; 886 rtlpriv->rtlhal.being_init_adapter = true;
887 /* As this function can take a very long time (up to 350 ms)
888 * and can be called with irqs disabled, reenable the irqs
889 * to let the other devices continue being serviced.
890 *
891 * It is safe doing so since our own interrupts will only be enabled
892 * in a subsequent step.
893 */
894 local_save_flags(flags);
895 local_irq_enable();
896
885 rtlpriv->intf_ops->disable_aspm(hw); 897 rtlpriv->intf_ops->disable_aspm(hw);
886 rtstatus = _rtl8712e_init_mac(hw); 898 rtstatus = _rtl8712e_init_mac(hw);
887 if (rtstatus != true) { 899 if (rtstatus != true) {
888 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); 900 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
889 err = 1; 901 err = 1;
890 return err; 902 goto exit;
891 } 903 }
892 904
893 err = rtl8723ae_download_fw(hw); 905 err = rtl8723_download_fw(hw, false);
894 if (err) { 906 if (err) {
895 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 907 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
896 "Failed to download FW. Init HW without FW now..\n"); 908 "Failed to download FW. Init HW without FW now..\n");
897 err = 1; 909 err = 1;
898 rtlhal->fw_ready = false; 910 goto exit;
899 return err;
900 } else { 911 } else {
901 rtlhal->fw_ready = true; 912 rtlhal->fw_ready = true;
902 } 913 }
@@ -971,6 +982,8 @@ int rtl8723ae_hw_init(struct ieee80211_hw *hw)
971 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); 982 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
972 } 983 }
973 rtl8723ae_dm_init(hw); 984 rtl8723ae_dm_init(hw);
985exit:
986 local_irq_restore(flags);
974 rtlpriv->rtlhal.being_init_adapter = false; 987 rtlpriv->rtlhal.being_init_adapter = false;
975 return err; 988 return err;
976} 989}
@@ -1112,12 +1125,13 @@ static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw,
1112void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 1125void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1113{ 1126{
1114 struct rtl_priv *rtlpriv = rtl_priv(hw); 1127 struct rtl_priv *rtlpriv = rtl_priv(hw);
1115 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 1128 u32 reg_rcr;
1116 u32 reg_rcr = rtlpci->receive_config;
1117 1129
1118 if (rtlpriv->psc.rfpwr_state != ERFON) 1130 if (rtlpriv->psc.rfpwr_state != ERFON)
1119 return; 1131 return;
1120 1132
1133 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
1134
1121 if (check_bssid == true) { 1135 if (check_bssid == true) {
1122 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); 1136 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1123 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, 1137 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
@@ -1153,7 +1167,7 @@ void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci)
1153{ 1167{
1154 struct rtl_priv *rtlpriv = rtl_priv(hw); 1168 struct rtl_priv *rtlpriv = rtl_priv(hw);
1155 1169
1156 rtl8723ae_dm_init_edca_turbo(hw); 1170 rtl8723_dm_init_edca_turbo(hw);
1157 switch (aci) { 1171 switch (aci) {
1158 case AC1_BK: 1172 case AC1_BK:
1159 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); 1173 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
@@ -1655,7 +1669,7 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
1655 CHK_SVID_SMID(0x10EC, 0x9185)) 1669 CHK_SVID_SMID(0x10EC, 0x9185))
1656 rtlhal->oem_id = RT_CID_TOSHIBA; 1670 rtlhal->oem_id = RT_CID_TOSHIBA;
1657 else if (rtlefuse->eeprom_svid == 0x1025) 1671 else if (rtlefuse->eeprom_svid == 0x1025)
1658 rtlhal->oem_id = RT_CID_819x_Acer; 1672 rtlhal->oem_id = RT_CID_819X_ACER;
1659 else if (CHK_SVID_SMID(0x10EC, 0x6191) || 1673 else if (CHK_SVID_SMID(0x10EC, 0x6191) ||
1660 CHK_SVID_SMID(0x10EC, 0x6192) || 1674 CHK_SVID_SMID(0x10EC, 0x6192) ||
1661 CHK_SVID_SMID(0x10EC, 0x6193) || 1675 CHK_SVID_SMID(0x10EC, 0x6193) ||
@@ -1665,7 +1679,7 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
1665 CHK_SVID_SMID(0x10EC, 0x8191) || 1679 CHK_SVID_SMID(0x10EC, 0x8191) ||
1666 CHK_SVID_SMID(0x10EC, 0x8192) || 1680 CHK_SVID_SMID(0x10EC, 0x8192) ||
1667 CHK_SVID_SMID(0x10EC, 0x8193)) 1681 CHK_SVID_SMID(0x10EC, 0x8193))
1668 rtlhal->oem_id = RT_CID_819x_SAMSUNG; 1682 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
1669 else if (CHK_SVID_SMID(0x10EC, 0x8195) || 1683 else if (CHK_SVID_SMID(0x10EC, 0x8195) ||
1670 CHK_SVID_SMID(0x10EC, 0x9195) || 1684 CHK_SVID_SMID(0x10EC, 0x9195) ||
1671 CHK_SVID_SMID(0x10EC, 0x7194) || 1685 CHK_SVID_SMID(0x10EC, 0x7194) ||
@@ -1673,24 +1687,24 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
1673 CHK_SVID_SMID(0x10EC, 0x8201) || 1687 CHK_SVID_SMID(0x10EC, 0x8201) ||
1674 CHK_SVID_SMID(0x10EC, 0x8202) || 1688 CHK_SVID_SMID(0x10EC, 0x8202) ||
1675 CHK_SVID_SMID(0x10EC, 0x9200)) 1689 CHK_SVID_SMID(0x10EC, 0x9200))
1676 rtlhal->oem_id = RT_CID_819x_Lenovo; 1690 rtlhal->oem_id = RT_CID_819X_LENOVO;
1677 else if (CHK_SVID_SMID(0x10EC, 0x8197) || 1691 else if (CHK_SVID_SMID(0x10EC, 0x8197) ||
1678 CHK_SVID_SMID(0x10EC, 0x9196)) 1692 CHK_SVID_SMID(0x10EC, 0x9196))
1679 rtlhal->oem_id = RT_CID_819x_CLEVO; 1693 rtlhal->oem_id = RT_CID_819X_CLEVO;
1680 else if (CHK_SVID_SMID(0x1028, 0x8194) || 1694 else if (CHK_SVID_SMID(0x1028, 0x8194) ||
1681 CHK_SVID_SMID(0x1028, 0x8198) || 1695 CHK_SVID_SMID(0x1028, 0x8198) ||
1682 CHK_SVID_SMID(0x1028, 0x9197) || 1696 CHK_SVID_SMID(0x1028, 0x9197) ||
1683 CHK_SVID_SMID(0x1028, 0x9198)) 1697 CHK_SVID_SMID(0x1028, 0x9198))
1684 rtlhal->oem_id = RT_CID_819x_DELL; 1698 rtlhal->oem_id = RT_CID_819X_DELL;
1685 else if (CHK_SVID_SMID(0x103C, 0x1629)) 1699 else if (CHK_SVID_SMID(0x103C, 0x1629))
1686 rtlhal->oem_id = RT_CID_819x_HP; 1700 rtlhal->oem_id = RT_CID_819X_HP;
1687 else if (CHK_SVID_SMID(0x1A32, 0x2315)) 1701 else if (CHK_SVID_SMID(0x1A32, 0x2315))
1688 rtlhal->oem_id = RT_CID_819x_QMI; 1702 rtlhal->oem_id = RT_CID_819X_QMI;
1689 else if (CHK_SVID_SMID(0x10EC, 0x8203)) 1703 else if (CHK_SVID_SMID(0x10EC, 0x8203))
1690 rtlhal->oem_id = RT_CID_819x_PRONETS; 1704 rtlhal->oem_id = RT_CID_819X_PRONETS;
1691 else if (CHK_SVID_SMID(0x1043, 0x84B5)) 1705 else if (CHK_SVID_SMID(0x1043, 0x84B5))
1692 rtlhal->oem_id = 1706 rtlhal->oem_id =
1693 RT_CID_819x_Edimax_ASUS; 1707 RT_CID_819X_EDIMAX_ASUS;
1694 else 1708 else
1695 rtlhal->oem_id = RT_CID_DEFAULT; 1709 rtlhal->oem_id = RT_CID_DEFAULT;
1696 } else if (rtlefuse->eeprom_did == 0x8178) { 1710 } else if (rtlefuse->eeprom_did == 0x8178) {
@@ -1712,12 +1726,12 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
1712 CHK_SVID_SMID(0x10EC, 0x9185)) 1726 CHK_SVID_SMID(0x10EC, 0x9185))
1713 rtlhal->oem_id = RT_CID_TOSHIBA; 1727 rtlhal->oem_id = RT_CID_TOSHIBA;
1714 else if (rtlefuse->eeprom_svid == 0x1025) 1728 else if (rtlefuse->eeprom_svid == 0x1025)
1715 rtlhal->oem_id = RT_CID_819x_Acer; 1729 rtlhal->oem_id = RT_CID_819X_ACER;
1716 else if (CHK_SVID_SMID(0x10EC, 0x8186)) 1730 else if (CHK_SVID_SMID(0x10EC, 0x8186))
1717 rtlhal->oem_id = RT_CID_819x_PRONETS; 1731 rtlhal->oem_id = RT_CID_819X_PRONETS;
1718 else if (CHK_SVID_SMID(0x1043, 0x8486)) 1732 else if (CHK_SVID_SMID(0x1043, 0x8486))
1719 rtlhal->oem_id = 1733 rtlhal->oem_id =
1720 RT_CID_819x_Edimax_ASUS; 1734 RT_CID_819X_EDIMAX_ASUS;
1721 else 1735 else
1722 rtlhal->oem_id = RT_CID_DEFAULT; 1736 rtlhal->oem_id = RT_CID_DEFAULT;
1723 } else { 1737 } else {
@@ -1731,7 +1745,7 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
1731 rtlhal->oem_id = RT_CID_CCX; 1745 rtlhal->oem_id = RT_CID_CCX;
1732 break; 1746 break;
1733 case EEPROM_CID_QMI: 1747 case EEPROM_CID_QMI:
1734 rtlhal->oem_id = RT_CID_819x_QMI; 1748 rtlhal->oem_id = RT_CID_819X_QMI;
1735 break; 1749 break;
1736 case EEPROM_CID_WHQL: 1750 case EEPROM_CID_WHQL:
1737 break; 1751 break;
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
index 5d318a85eda4..3ea78afdec73 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
@@ -30,12 +30,14 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../pci.h" 31#include "../pci.h"
32#include "../ps.h" 32#include "../ps.h"
33#include "../core.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "phy.h" 36#include "phy.h"
36#include "rf.h" 37#include "rf.h"
37#include "dm.h" 38#include "dm.h"
38#include "table.h" 39#include "table.h"
40#include "../rtl8723com/phy_common.h"
39 41
40/* static forward definitions */ 42/* static forward definitions */
41static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, 43static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
@@ -43,72 +45,17 @@ static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
43static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw, 45static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
44 enum radio_path rfpath, 46 enum radio_path rfpath,
45 u32 offset, u32 data); 47 u32 offset, u32 data);
46static u32 _phy_rf_serial_read(struct ieee80211_hw *hw,
47 enum radio_path rfpath, u32 offset);
48static void _phy_rf_serial_write(struct ieee80211_hw *hw,
49 enum radio_path rfpath, u32 offset, u32 data);
50static u32 _phy_calculate_bit_shift(u32 bitmask);
51static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw); 48static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
52static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw); 49static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw);
53static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype); 50static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype);
54static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype); 51static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype);
55static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw);
56static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
57 u32 cmdtableidx, u32 cmdtablesz,
58 enum swchnlcmd_id cmdid,
59 u32 para1, u32 para2,
60 u32 msdelay);
61static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, 52static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
62 u8 *stage, u8 *step, u32 *delay); 53 u8 *stage, u8 *step, u32 *delay);
63static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, 54static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
64 enum wireless_mode wirelessmode, 55 enum wireless_mode wirelessmode,
65 long power_indbm); 56 long power_indbm);
66static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
67 enum wireless_mode wirelessmode, u8 txpwridx);
68static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw); 57static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw);
69 58
70u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
71 u32 bitmask)
72{
73 struct rtl_priv *rtlpriv = rtl_priv(hw);
74 u32 returnvalue, originalvalue, bitshift;
75
76 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
77 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
78 originalvalue = rtl_read_dword(rtlpriv, regaddr);
79 bitshift = _phy_calculate_bit_shift(bitmask);
80 returnvalue = (originalvalue & bitmask) >> bitshift;
81
82 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
83 "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask, regaddr,
84 originalvalue);
85
86 return returnvalue;
87}
88
89void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw,
90 u32 regaddr, u32 bitmask, u32 data)
91{
92 struct rtl_priv *rtlpriv = rtl_priv(hw);
93 u32 originalvalue, bitshift;
94
95 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
96 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr,
97 bitmask, data);
98
99 if (bitmask != MASKDWORD) {
100 originalvalue = rtl_read_dword(rtlpriv, regaddr);
101 bitshift = _phy_calculate_bit_shift(bitmask);
102 data = ((originalvalue & (~bitmask)) | (data << bitshift));
103 }
104
105 rtl_write_dword(rtlpriv, regaddr, data);
106
107 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
108 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
109 regaddr, bitmask, data);
110}
111
112u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, 59u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
113 enum radio_path rfpath, u32 regaddr, u32 bitmask) 60 enum radio_path rfpath, u32 regaddr, u32 bitmask)
114{ 61{
@@ -124,11 +71,11 @@ u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
124 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); 71 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
125 72
126 if (rtlphy->rf_mode != RF_OP_BY_FW) 73 if (rtlphy->rf_mode != RF_OP_BY_FW)
127 original_value = _phy_rf_serial_read(hw, rfpath, regaddr); 74 original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
128 else 75 else
129 original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr); 76 original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr);
130 77
131 bitshift = _phy_calculate_bit_shift(bitmask); 78 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
132 readback_value = (original_value & bitmask) >> bitshift; 79 readback_value = (original_value & bitmask) >> bitshift;
133 80
134 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); 81 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
@@ -157,19 +104,19 @@ void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
157 104
158 if (rtlphy->rf_mode != RF_OP_BY_FW) { 105 if (rtlphy->rf_mode != RF_OP_BY_FW) {
159 if (bitmask != RFREG_OFFSET_MASK) { 106 if (bitmask != RFREG_OFFSET_MASK) {
160 original_value = _phy_rf_serial_read(hw, rfpath, 107 original_value = rtl8723_phy_rf_serial_read(hw, rfpath,
161 regaddr); 108 regaddr);
162 bitshift = _phy_calculate_bit_shift(bitmask); 109 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
163 data = ((original_value & (~bitmask)) | 110 data = ((original_value & (~bitmask)) |
164 (data << bitshift)); 111 (data << bitshift));
165 } 112 }
166 113
167 _phy_rf_serial_write(hw, rfpath, regaddr, data); 114 rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data);
168 } else { 115 } else {
169 if (bitmask != RFREG_OFFSET_MASK) { 116 if (bitmask != RFREG_OFFSET_MASK) {
170 original_value = _phy_fw_rf_serial_read(hw, rfpath, 117 original_value = _phy_fw_rf_serial_read(hw, rfpath,
171 regaddr); 118 regaddr);
172 bitshift = _phy_calculate_bit_shift(bitmask); 119 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
173 data = ((original_value & (~bitmask)) | 120 data = ((original_value & (~bitmask)) |
174 (data << bitshift)); 121 (data << bitshift));
175 } 122 }
@@ -197,87 +144,6 @@ static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
197 RT_ASSERT(false, "deprecated!\n"); 144 RT_ASSERT(false, "deprecated!\n");
198} 145}
199 146
200static u32 _phy_rf_serial_read(struct ieee80211_hw *hw,
201 enum radio_path rfpath, u32 offset)
202{
203 struct rtl_priv *rtlpriv = rtl_priv(hw);
204 struct rtl_phy *rtlphy = &(rtlpriv->phy);
205 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
206 u32 newoffset;
207 u32 tmplong, tmplong2;
208 u8 rfpi_enable = 0;
209 u32 retvalue;
210
211 offset &= 0x3f;
212 newoffset = offset;
213 if (RT_CANNOT_IO(hw)) {
214 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
215 return 0xFFFFFFFF;
216 }
217 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
218 if (rfpath == RF90_PATH_A)
219 tmplong2 = tmplong;
220 else
221 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
222 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
223 (newoffset << 23) | BLSSIREADEDGE;
224 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
225 tmplong & (~BLSSIREADEDGE));
226 mdelay(1);
227 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
228 mdelay(1);
229 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
230 tmplong | BLSSIREADEDGE);
231 mdelay(1);
232 if (rfpath == RF90_PATH_A)
233 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
234 BIT(8));
235 else if (rfpath == RF90_PATH_B)
236 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
237 BIT(8));
238 if (rfpi_enable)
239 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
240 BLSSIREADBACKDATA);
241 else
242 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
243 BLSSIREADBACKDATA);
244 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
245 rfpath, pphyreg->rf_rb, retvalue);
246 return retvalue;
247}
248
249static void _phy_rf_serial_write(struct ieee80211_hw *hw,
250 enum radio_path rfpath, u32 offset, u32 data)
251{
252 u32 data_and_addr;
253 u32 newoffset;
254 struct rtl_priv *rtlpriv = rtl_priv(hw);
255 struct rtl_phy *rtlphy = &(rtlpriv->phy);
256 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
257
258 if (RT_CANNOT_IO(hw)) {
259 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
260 return;
261 }
262 offset &= 0x3f;
263 newoffset = offset;
264 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
265 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
266 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
267 rfpath, pphyreg->rf3wire_offset, data_and_addr);
268}
269
270static u32 _phy_calculate_bit_shift(u32 bitmask)
271{
272 u32 i;
273
274 for (i = 0; i <= 31; i++) {
275 if (((bitmask >> i) & 0x1) == 1)
276 break;
277 }
278 return i;
279}
280
281static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw) 147static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw)
282{ 148{
283 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); 149 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
@@ -307,7 +173,7 @@ bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw)
307 u8 tmpu1b; 173 u8 tmpu1b;
308 u8 reg_hwparafile = 1; 174 u8 reg_hwparafile = 1;
309 175
310 _phy_init_bb_rf_reg_def(hw); 176 rtl8723_phy_init_bb_rf_reg_def(hw);
311 177
312 /* 1. 0x28[1] = 1 */ 178 /* 1. 0x28[1] = 1 */
313 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL); 179 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
@@ -412,18 +278,7 @@ static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype)
412 phy_regarray_table = RTL8723EPHY_REG_1TARRAY; 278 phy_regarray_table = RTL8723EPHY_REG_1TARRAY;
413 if (configtype == BASEBAND_CONFIG_PHY_REG) { 279 if (configtype == BASEBAND_CONFIG_PHY_REG) {
414 for (i = 0; i < phy_reg_arraylen; i = i + 2) { 280 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
415 if (phy_regarray_table[i] == 0xfe) 281 rtl_addr_delay(phy_regarray_table[i]);
416 mdelay(50);
417 else if (phy_regarray_table[i] == 0xfd)
418 mdelay(5);
419 else if (phy_regarray_table[i] == 0xfc)
420 mdelay(1);
421 else if (phy_regarray_table[i] == 0xfb)
422 udelay(50);
423 else if (phy_regarray_table[i] == 0xfa)
424 udelay(5);
425 else if (phy_regarray_table[i] == 0xf9)
426 udelay(1);
427 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, 282 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
428 phy_regarray_table[i + 1]); 283 phy_regarray_table[i + 1]);
429 udelay(1); 284 udelay(1);
@@ -585,18 +440,7 @@ static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype)
585 440
586 if (configtype == BASEBAND_CONFIG_PHY_REG) { 441 if (configtype == BASEBAND_CONFIG_PHY_REG) {
587 for (i = 0; i < phy_regarray_pg_len; i = i + 3) { 442 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
588 if (phy_regarray_table_pg[i] == 0xfe) 443 rtl_addr_delay(phy_regarray_table_pg[i]);
589 mdelay(50);
590 else if (phy_regarray_table_pg[i] == 0xfd)
591 mdelay(5);
592 else if (phy_regarray_table_pg[i] == 0xfc)
593 mdelay(1);
594 else if (phy_regarray_table_pg[i] == 0xfb)
595 udelay(50);
596 else if (phy_regarray_table_pg[i] == 0xfa)
597 udelay(5);
598 else if (phy_regarray_table_pg[i] == 0xf9)
599 udelay(1);
600 444
601 _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i], 445 _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i],
602 phy_regarray_table_pg[i + 1], 446 phy_regarray_table_pg[i + 1],
@@ -623,24 +467,9 @@ bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
623 switch (rfpath) { 467 switch (rfpath) {
624 case RF90_PATH_A: 468 case RF90_PATH_A:
625 for (i = 0; i < radioa_arraylen; i = i + 2) { 469 for (i = 0; i < radioa_arraylen; i = i + 2) {
626 if (radioa_array_table[i] == 0xfe) 470 rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
627 mdelay(50); 471 RFREG_OFFSET_MASK,
628 else if (radioa_array_table[i] == 0xfd) 472 radioa_array_table[i + 1]);
629 mdelay(5);
630 else if (radioa_array_table[i] == 0xfc)
631 mdelay(1);
632 else if (radioa_array_table[i] == 0xfb)
633 udelay(50);
634 else if (radioa_array_table[i] == 0xfa)
635 udelay(5);
636 else if (radioa_array_table[i] == 0xf9)
637 udelay(1);
638 else {
639 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
640 RFREG_OFFSET_MASK,
641 radioa_array_table[i + 1]);
642 udelay(1);
643 }
644 } 473 }
645 break; 474 break;
646 case RF90_PATH_B: 475 case RF90_PATH_B:
@@ -690,92 +519,6 @@ void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
690 ROFDM0_RXDETECTOR3, rtlphy->framesync); 519 ROFDM0_RXDETECTOR3, rtlphy->framesync);
691} 520}
692 521
693static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw)
694{
695 struct rtl_priv *rtlpriv = rtl_priv(hw);
696 struct rtl_phy *rtlphy = &(rtlpriv->phy);
697
698 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
699 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
700 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
701 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
702
703 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
704 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
705 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
706 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
707
708 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
709 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
710
711 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
712 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
713
714 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
715 RFPGA0_XA_LSSIPARAMETER;
716 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
717 RFPGA0_XB_LSSIPARAMETER;
718
719 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
720 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
721 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
722 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
723
724 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
725 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
726 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
727 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
728
729 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
730 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
731
732 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
733 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
734
735 rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
736 rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
737 rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
738 rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
739
740 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
741 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
742 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
743 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
744
745 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
746 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
747 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
748 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
749
750 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
751 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
752 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
753 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
754
755 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
756 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
757 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
758 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
759
760 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
761 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
762 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
763 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
764
765 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
766 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
767 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
768 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
769
770 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
771 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
772 rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
773 rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
774
775 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
776 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
777}
778
779void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) 522void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
780{ 523{
781 struct rtl_priv *rtlpriv = rtl_priv(hw); 524 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -785,17 +528,17 @@ void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
785 long txpwr_dbm; 528 long txpwr_dbm;
786 529
787 txpwr_level = rtlphy->cur_cck_txpwridx; 530 txpwr_level = rtlphy->cur_cck_txpwridx;
788 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level); 531 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level);
789 txpwr_level = rtlphy->cur_ofdm24g_txpwridx + 532 txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
790 rtlefuse->legacy_ht_txpowerdiff; 533 rtlefuse->legacy_ht_txpowerdiff;
791 if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm) 534 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm)
792 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, 535 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
793 txpwr_level); 536 txpwr_level);
794 txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 537 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
795 if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) > 538 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) >
796 txpwr_dbm) 539 txpwr_dbm)
797 txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, 540 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
798 txpwr_level); 541 txpwr_level);
799 *powerlevel = txpwr_dbm; 542 *powerlevel = txpwr_dbm;
800} 543}
801 544
@@ -912,28 +655,6 @@ static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
912 return txpwridx; 655 return txpwridx;
913} 656}
914 657
915static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
916 enum wireless_mode wirelessmode, u8 txpwridx)
917{
918 long offset;
919 long pwrout_dbm;
920
921 switch (wirelessmode) {
922 case WIRELESS_MODE_B:
923 offset = -7;
924 break;
925 case WIRELESS_MODE_G:
926 case WIRELESS_MODE_N_24G:
927 offset = -8;
928 break;
929 default:
930 offset = -8;
931 break;
932 }
933 pwrout_dbm = txpwridx / 2 + offset;
934 return pwrout_dbm;
935}
936
937void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw) 658void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
938{ 659{
939 struct rtl_priv *rtlpriv = rtl_priv(hw); 660 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1117,26 +838,26 @@ static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
1117 u8 num_total_rfpath = rtlphy->num_total_rfpath; 838 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1118 839
1119 precommoncmdcnt = 0; 840 precommoncmdcnt = 0;
1120 _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 841 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1121 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 842 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL,
1122 0, 0, 0); 843 0, 0, 0);
1123 _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 844 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1124 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); 845 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1125 postcommoncmdcnt = 0; 846 postcommoncmdcnt = 0;
1126 847
1127 _phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, 848 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1128 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); 849 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1129 rfdependcmdcnt = 0; 850 rfdependcmdcnt = 0;
1130 851
1131 RT_ASSERT((channel >= 1 && channel <= 14), 852 RT_ASSERT((channel >= 1 && channel <= 14),
1132 "illegal channel for Zebra: %d\n", channel); 853 "illegal channel for Zebra: %d\n", channel);
1133 854
1134 _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 855 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1135 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, 856 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
1136 RF_CHNLBW, channel, 10); 857 RF_CHNLBW, channel, 10);
1137 858
1138 _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 859 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1139 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); 860 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
1140 861
1141 do { 862 do {
1142 switch (*stage) { 863 switch (*stage) {
@@ -1204,29 +925,6 @@ static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
1204 return false; 925 return false;
1205} 926}
1206 927
1207static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1208 u32 cmdtableidx, u32 cmdtablesz,
1209 enum swchnlcmd_id cmdid, u32 para1,
1210 u32 para2, u32 msdelay)
1211{
1212 struct swchnlcmd *pcmd;
1213
1214 if (cmdtable == NULL) {
1215 RT_ASSERT(false, "cmdtable cannot be NULL.\n");
1216 return false;
1217 }
1218
1219 if (cmdtableidx >= cmdtablesz)
1220 return false;
1221
1222 pcmd = cmdtable + cmdtableidx;
1223 pcmd->cmdid = cmdid;
1224 pcmd->para1 = para1;
1225 pcmd->para2 = para2;
1226 pcmd->msdelay = msdelay;
1227 return true;
1228}
1229
1230static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) 928static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1231{ 929{
1232 u32 reg_eac, reg_e94, reg_e9c, reg_ea4; 930 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
@@ -1297,136 +995,6 @@ static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw)
1297 return result; 995 return result;
1298} 996}
1299 997
1300static void phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, bool iqk_ok,
1301 long result[][8], u8 final_candidate,
1302 bool btxonly)
1303{
1304 u32 oldval_0, x, tx0_a, reg;
1305 long y, tx0_c;
1306
1307 if (final_candidate == 0xFF) {
1308 return;
1309 } else if (iqk_ok) {
1310 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1311 MASKDWORD) >> 22) & 0x3FF;
1312 x = result[final_candidate][0];
1313 if ((x & 0x00000200) != 0)
1314 x = x | 0xFFFFFC00;
1315 tx0_a = (x * oldval_0) >> 8;
1316 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1317 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1318 ((x * oldval_0 >> 7) & 0x1));
1319 y = result[final_candidate][1];
1320 if ((y & 0x00000200) != 0)
1321 y = y | 0xFFFFFC00;
1322 tx0_c = (y * oldval_0) >> 8;
1323 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1324 ((tx0_c & 0x3C0) >> 6));
1325 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1326 (tx0_c & 0x3F));
1327 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1328 ((y * oldval_0 >> 7) & 0x1));
1329 if (btxonly)
1330 return;
1331 reg = result[final_candidate][2];
1332 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1333 reg = result[final_candidate][3] & 0x3F;
1334 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1335 reg = (result[final_candidate][3] >> 6) & 0xF;
1336 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1337 }
1338}
1339
1340static void phy_save_adda_regs(struct ieee80211_hw *hw,
1341 u32 *addareg, u32 *addabackup,
1342 u32 registernum)
1343{
1344 u32 i;
1345
1346 for (i = 0; i < registernum; i++)
1347 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1348}
1349
1350static void phy_save_mac_regs(struct ieee80211_hw *hw, u32 *macreg,
1351 u32 *macbackup)
1352{
1353 struct rtl_priv *rtlpriv = rtl_priv(hw);
1354 u32 i;
1355
1356 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1357 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1358 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1359}
1360
1361static void phy_reload_adda_regs(struct ieee80211_hw *hw, u32 *addareg,
1362 u32 *addabackup, u32 regiesternum)
1363{
1364 u32 i;
1365
1366 for (i = 0; i < regiesternum; i++)
1367 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1368}
1369
1370static void phy_reload_mac_regs(struct ieee80211_hw *hw, u32 *macreg,
1371 u32 *macbackup)
1372{
1373 struct rtl_priv *rtlpriv = rtl_priv(hw);
1374 u32 i;
1375
1376 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1377 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1378 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1379}
1380
1381static void _rtl8723ae_phy_path_adda_on(struct ieee80211_hw *hw,
1382 u32 *addareg, bool is_patha_on,
1383 bool is2t)
1384{
1385 u32 pathOn;
1386 u32 i;
1387
1388 pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1389 if (false == is2t) {
1390 pathOn = 0x0bdb25a0;
1391 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1392 } else {
1393 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
1394 }
1395
1396 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1397 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
1398}
1399
1400static void _rtl8723ae_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1401 u32 *macreg, u32 *macbackup)
1402{
1403 struct rtl_priv *rtlpriv = rtl_priv(hw);
1404 u32 i = 0;
1405
1406 rtl_write_byte(rtlpriv, macreg[i], 0x3F);
1407
1408 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1409 rtl_write_byte(rtlpriv, macreg[i],
1410 (u8) (macbackup[i] & (~BIT(3))));
1411 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1412}
1413
1414static void _rtl8723ae_phy_path_a_standby(struct ieee80211_hw *hw)
1415{
1416 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1417 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1418 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1419}
1420
1421static void _rtl8723ae_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1422{
1423 u32 mode;
1424
1425 mode = pi_mode ? 0x01000100 : 0x01000000;
1426 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1427 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1428}
1429
1430static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8], 998static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8],
1431 u8 c1, u8 c2) 999 u8 c1, u8 c2)
1432{ 1000{
@@ -1498,10 +1066,12 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1498 const u32 retrycount = 2; 1066 const u32 retrycount = 2;
1499 1067
1500 if (t == 0) { 1068 if (t == 0) {
1501 phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); 1069 rtl8723_save_adda_registers(hw, adda_reg, rtlphy->adda_backup,
1502 phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); 1070 16);
1071 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1072 rtlphy->iqk_mac_backup);
1503 } 1073 }
1504 _rtl8723ae_phy_path_adda_on(hw, adda_reg, true, is2t); 1074 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1505 if (t == 0) { 1075 if (t == 0) {
1506 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, 1076 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1507 RFPGA0_XA_HSSIPARAMETER1, 1077 RFPGA0_XA_HSSIPARAMETER1,
@@ -1509,7 +1079,7 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1509 } 1079 }
1510 1080
1511 if (!rtlphy->rfpi_enable) 1081 if (!rtlphy->rfpi_enable)
1512 _rtl8723ae_phy_pi_mode_switch(hw, true); 1082 rtl8723_phy_pi_mode_switch(hw, true);
1513 if (t == 0) { 1083 if (t == 0) {
1514 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); 1084 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1515 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); 1085 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
@@ -1522,7 +1092,7 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1522 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 1092 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1523 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); 1093 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1524 } 1094 }
1525 _rtl8723ae_phy_mac_setting_calibration(hw, iqk_mac_reg, 1095 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1526 rtlphy->iqk_mac_backup); 1096 rtlphy->iqk_mac_backup);
1527 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); 1097 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1528 if (is2t) 1098 if (is2t)
@@ -1552,8 +1122,8 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1552 } 1122 }
1553 1123
1554 if (is2t) { 1124 if (is2t) {
1555 _rtl8723ae_phy_path_a_standby(hw); 1125 rtl8723_phy_path_a_standby(hw);
1556 _rtl8723ae_phy_path_adda_on(hw, adda_reg, false, is2t); 1126 rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1557 for (i = 0; i < retrycount; i++) { 1127 for (i = 0; i < retrycount; i++) {
1558 pathb_ok = _rtl8723ae_phy_path_b_iqk(hw); 1128 pathb_ok = _rtl8723ae_phy_path_b_iqk(hw);
1559 if (pathb_ok == 0x03) { 1129 if (pathb_ok == 0x03) {
@@ -1588,9 +1158,11 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1588 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); 1158 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1589 if (t != 0) { 1159 if (t != 0) {
1590 if (!rtlphy->rfpi_enable) 1160 if (!rtlphy->rfpi_enable)
1591 _rtl8723ae_phy_pi_mode_switch(hw, false); 1161 rtl8723_phy_pi_mode_switch(hw, false);
1592 phy_reload_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); 1162 rtl8723_phy_reload_adda_registers(hw, adda_reg,
1593 phy_reload_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); 1163 rtlphy->adda_backup, 16);
1164 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1165 rtlphy->iqk_mac_backup);
1594 } 1166 }
1595} 1167}
1596 1168
@@ -1691,7 +1263,8 @@ void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1691 }; 1263 };
1692 1264
1693 if (recovery) { 1265 if (recovery) {
1694 phy_reload_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); 1266 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1267 rtlphy->iqk_bb_backup, 10);
1695 return; 1268 return;
1696 } 1269 }
1697 if (start_conttx || singletone) 1270 if (start_conttx || singletone)
@@ -1756,9 +1329,10 @@ void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1756 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; 1329 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1757 } 1330 }
1758 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ 1331 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1759 phy_path_a_fill_iqk_matrix(hw, patha_ok, result, 1332 rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1760 final_candidate, (reg_ea4 == 0)); 1333 final_candidate,
1761 phy_save_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); 1334 (reg_ea4 == 0));
1335 rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);
1762} 1336}
1763 1337
1764void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw) 1338void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
index 007ebdbbe108..cd43139ed332 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
@@ -76,23 +76,6 @@
76 76
77#define RTL92C_MAX_PATH_NUM 2 77#define RTL92C_MAX_PATH_NUM 2
78 78
79enum swchnlcmd_id {
80 CMDID_END,
81 CMDID_SET_TXPOWEROWER_LEVEL,
82 CMDID_BBREGWRITE10,
83 CMDID_WRITEPORT_ULONG,
84 CMDID_WRITEPORT_USHORT,
85 CMDID_WRITEPORT_UCHAR,
86 CMDID_RF_WRITEREG,
87};
88
89struct swchnlcmd {
90 enum swchnlcmd_id cmdid;
91 u32 para1;
92 u32 para2;
93 u32 msdelay;
94};
95
96enum hw90_block_e { 79enum hw90_block_e {
97 HW90_BLOCK_MAC = 0, 80 HW90_BLOCK_MAC = 0,
98 HW90_BLOCK_PHY0 = 1, 81 HW90_BLOCK_PHY0 = 1,
@@ -183,10 +166,6 @@ struct tx_power_struct {
183 u32 mcs_original_offset[4][16]; 166 u32 mcs_original_offset[4][16];
184}; 167};
185 168
186u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw,
187 u32 regaddr, u32 bitmask);
188void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw,
189 u32 regaddr, u32 bitmask, u32 data);
190u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, 169u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
191 enum radio_path rfpath, u32 regaddr, 170 enum radio_path rfpath, u32 regaddr,
192 u32 bitmask); 171 u32 bitmask);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h
index 7a46f9fdf558..a418acb4d0ca 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h
@@ -30,7 +30,6 @@
30#ifndef __RTL8723E_PWRSEQ_H__ 30#ifndef __RTL8723E_PWRSEQ_H__
31#define __RTL8723E_PWRSEQ_H__ 31#define __RTL8723E_PWRSEQ_H__
32 32
33#include "pwrseqcmd.h"
34/* 33/*
35 Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd 34 Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd
36 There are 6 HW Power States: 35 There are 6 HW Power States:
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
index 199da366c6da..64376b38708b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
@@ -2059,22 +2059,6 @@
2059#define BWORD1 0xc 2059#define BWORD1 0xc
2060#define BWORD 0xf 2060#define BWORD 0xf
2061 2061
2062#define MASKBYTE0 0xff
2063#define MASKBYTE1 0xff00
2064#define MASKBYTE2 0xff0000
2065#define MASKBYTE3 0xff000000
2066#define MASKHWORD 0xffff0000
2067#define MASKLWORD 0x0000ffff
2068#define MASKDWORD 0xffffffff
2069#define MASK12BITS 0xfff
2070#define MASKH4BITS 0xf0000000
2071#define MASKOFDM_D 0xffc00000
2072#define MASKCCK 0x3f3f3f3f
2073
2074#define MASK4BITS 0x0f
2075#define MASK20BITS 0xfffff
2076#define RFREG_OFFSET_MASK 0xfffff
2077
2078#define BENABLE 0x1 2062#define BENABLE 0x1
2079#define BDISABLE 0x0 2063#define BDISABLE 0x0
2080 2064
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
index 62b204faf773..1087a3bd07fa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
@@ -37,8 +37,11 @@
37#include "reg.h" 37#include "reg.h"
38#include "def.h" 38#include "def.h"
39#include "phy.h" 39#include "phy.h"
40#include "../rtl8723com/phy_common.h"
40#include "dm.h" 41#include "dm.h"
41#include "hw.h" 42#include "hw.h"
43#include "fw.h"
44#include "../rtl8723com/fw_common.h"
42#include "sw.h" 45#include "sw.h"
43#include "trx.h" 46#include "trx.h"
44#include "led.h" 47#include "led.h"
@@ -193,6 +196,11 @@ void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw)
193 } 196 }
194} 197}
195 198
199static bool is_fw_header(struct rtl92c_firmware_header *hdr)
200{
201 return (hdr->signature & 0xfff0) == 0x2300;
202}
203
196static struct rtl_hal_ops rtl8723ae_hal_ops = { 204static struct rtl_hal_ops rtl8723ae_hal_ops = {
197 .init_sw_vars = rtl8723ae_init_sw_vars, 205 .init_sw_vars = rtl8723ae_init_sw_vars,
198 .deinit_sw_vars = rtl8723ae_deinit_sw_vars, 206 .deinit_sw_vars = rtl8723ae_deinit_sw_vars,
@@ -231,13 +239,14 @@ static struct rtl_hal_ops rtl8723ae_hal_ops = {
231 .set_key = rtl8723ae_set_key, 239 .set_key = rtl8723ae_set_key,
232 .init_sw_leds = rtl8723ae_init_sw_leds, 240 .init_sw_leds = rtl8723ae_init_sw_leds,
233 .allow_all_destaddr = rtl8723ae_allow_all_destaddr, 241 .allow_all_destaddr = rtl8723ae_allow_all_destaddr,
234 .get_bbreg = rtl8723ae_phy_query_bb_reg, 242 .get_bbreg = rtl8723_phy_query_bb_reg,
235 .set_bbreg = rtl8723ae_phy_set_bb_reg, 243 .set_bbreg = rtl8723_phy_set_bb_reg,
236 .get_rfreg = rtl8723ae_phy_query_rf_reg, 244 .get_rfreg = rtl8723ae_phy_query_rf_reg,
237 .set_rfreg = rtl8723ae_phy_set_rf_reg, 245 .set_rfreg = rtl8723ae_phy_set_rf_reg,
238 .c2h_command_handle = rtl_8723e_c2h_command_handle, 246 .c2h_command_handle = rtl_8723e_c2h_command_handle,
239 .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify, 247 .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify,
240 .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps, 248 .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps,
249 .is_fw_header = is_fw_header,
241}; 250};
242 251
243static struct rtl_mod_params rtl8723ae_mod_params = { 252static struct rtl_mod_params rtl8723ae_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
index 721162cacc3a..29adf55c6fd3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
@@ -365,7 +365,7 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
365 365
366void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, 366void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
367 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 367 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
368 struct ieee80211_tx_info *info, 368 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
369 struct ieee80211_sta *sta, 369 struct ieee80211_sta *sta,
370 struct sk_buff *skb, u8 hw_queue, 370 struct sk_buff *skb, u8 hw_queue,
371 struct rtl_tcb_desc *ptcdesc) 371 struct rtl_tcb_desc *ptcdesc)
@@ -597,7 +597,8 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
597 pdesc, TX_DESC_SIZE); 597 pdesc, TX_DESC_SIZE);
598} 598}
599 599
600void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) 600void rtl8723ae_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
601 u8 desc_name, u8 *val)
601{ 602{
602 if (istx == true) { 603 if (istx == true) {
603 switch (desc_name) { 604 switch (desc_name) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h
index ad05b54bc0f1..4380b7d3a91a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h
@@ -521,12 +521,6 @@ do { \
521 memset(__pdesc, 0, _size); \ 521 memset(__pdesc, 0, _size); \
522} while (0) 522} while (0)
523 523
524#define RTL8723E_RX_HAL_IS_CCK_RATE(rxmcs) \
525 ((rxmcs) == DESC92_RATE1M || \
526 (rxmcs) == DESC92_RATE2M || \
527 (rxmcs) == DESC92_RATE5_5M || \
528 (rxmcs) == DESC92_RATE11M)
529
530struct rx_fwinfo_8723e { 524struct rx_fwinfo_8723e {
531 u8 gain_trsw[4]; 525 u8 gain_trsw[4];
532 u8 pwdb_all; 526 u8 pwdb_all;
@@ -706,8 +700,8 @@ struct rx_desc_8723e {
706} __packed; 700} __packed;
707 701
708void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, 702void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
709 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 703 struct ieee80211_hdr *hdr, u8 *pdesc,
710 struct ieee80211_tx_info *info, 704 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
711 struct ieee80211_sta *sta, 705 struct ieee80211_sta *sta,
712 struct sk_buff *skb, u8 hw_queue, 706 struct sk_buff *skb, u8 hw_queue,
713 struct rtl_tcb_desc *ptcb_desc); 707 struct rtl_tcb_desc *ptcb_desc);
@@ -715,7 +709,8 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
715 struct rtl_stats *status, 709 struct rtl_stats *status,
716 struct ieee80211_rx_status *rx_status, 710 struct ieee80211_rx_status *rx_status,
717 u8 *pdesc, struct sk_buff *skb); 711 u8 *pdesc, struct sk_buff *skb);
718void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); 712void rtl8723ae_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
713 u8 desc_name, u8 *val);
719u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name); 714u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name);
720void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); 715void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
721void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, 716void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/Makefile b/drivers/net/wireless/rtlwifi/rtl8723be/Makefile
new file mode 100644
index 000000000000..59e416abd93a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/Makefile
@@ -0,0 +1,19 @@
1obj-m := rtl8723be.o
2
3
4rtl8723be-objs := \
5 dm.o \
6 fw.o \
7 hw.o \
8 led.o \
9 phy.o \
10 pwrseq.o \
11 rf.o \
12 sw.o \
13 table.o \
14 trx.o \
15
16
17obj-$(CONFIG_RTL8723BE) += rtl8723be.o
18
19ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/def.h b/drivers/net/wireless/rtlwifi/rtl8723be/def.h
new file mode 100644
index 000000000000..3c30b74e983d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/def.h
@@ -0,0 +1,248 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_DEF_H__
27#define __RTL8723BE_DEF_H__
28
29#define HAL_RETRY_LIMIT_INFRA 48
30#define HAL_RETRY_LIMIT_AP_ADHOC 7
31
32#define RESET_DELAY_8185 20
33
34#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
35#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
36
37#define NUM_OF_FIRMWARE_QUEUE 10
38#define NUM_OF_PAGES_IN_FW 0x100
39#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
40#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
41#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
42#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
43#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
44#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
45#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
46#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
47#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
48#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
49
50#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
51#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
52#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
53#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
54#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
55
56#define MAX_LINES_HWCONFIG_TXT 1000
57#define MAX_BYTES_LINE_HWCONFIG_TXT 256
58
59#define SW_THREE_WIRE 0
60#define HW_THREE_WIRE 2
61
62#define BT_DEMO_BOARD 0
63#define BT_QA_BOARD 1
64#define BT_FPGA 2
65
66#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
67#define HAL_PRIME_CHNL_OFFSET_LOWER 1
68#define HAL_PRIME_CHNL_OFFSET_UPPER 2
69
70#define MAX_H2C_QUEUE_NUM 10
71
72#define RX_MPDU_QUEUE 0
73#define RX_CMD_QUEUE 1
74#define RX_MAX_QUEUE 2
75#define AC2QUEUEID(_AC) (_AC)
76
77#define C2H_RX_CMD_HDR_LEN 8
78#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
79 LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
80#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
81 LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
82#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
83 LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
84#define GET_C2H_CMD_CONTINUE(__prxhdr) \
85 LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
86#define GET_C2H_CMD_CONTENT(__prxhdr) \
87 ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
88
89#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
90 LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
91#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
92 LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
93#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
94 LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
95#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
96 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
97#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
98 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
99#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
100 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
101#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
102 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
103#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
104 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
105#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
106 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
107
108#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
109#define CHIP_BONDING_92C_1T2R 0x1
110
111#define CHIP_8723 BIT(0)
112#define CHIP_8723B (BIT(1) | BIT(2))
113#define NORMAL_CHIP BIT(3)
114#define RF_TYPE_1T1R (~(BIT(4) | BIT(5) | BIT(6)))
115#define RF_TYPE_1T2R BIT(4)
116#define RF_TYPE_2T2R BIT(5)
117#define CHIP_VENDOR_UMC BIT(7)
118#define B_CUT_VERSION BIT(12)
119#define C_CUT_VERSION BIT(13)
120#define D_CUT_VERSION ((BIT(12) | BIT(13)))
121#define E_CUT_VERSION BIT(14)
122#define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28))
123
124/* MASK */
125#define IC_TYPE_MASK (BIT(0) | BIT(1) | BIT(2))
126#define CHIP_TYPE_MASK BIT(3)
127#define RF_TYPE_MASK (BIT(4) | BIT(5) | BIT(6))
128#define MANUFACTUER_MASK BIT(7)
129#define ROM_VERSION_MASK (BIT(11) | BIT(10) | BIT(9) | BIT(8))
130#define CUT_VERSION_MASK (BIT(15) | BIT(14) | BIT(13) | BIT(12))
131
132/* Get element */
133#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK)
134#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK)
135#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK)
136#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK)
137#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK)
138#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
139
140#define IS_92C_SERIAL(version) ((IS_81XXC(version) && IS_2T2R(version)) ?\
141 true : false)
142#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0) ?\
143 true : false)
144#define IS_8723_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723) ?\
145 true : false)
146#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version)) ? false : true)
147#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)\
148 ? true : false)
149#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)\
150 ? true : false)
151enum rf_optype {
152 RF_OP_BY_SW_3WIRE = 0,
153 RF_OP_BY_FW,
154 RF_OP_MAX
155};
156
157enum rf_power_state {
158 RF_ON,
159 RF_OFF,
160 RF_SLEEP,
161 RF_SHUT_DOWN,
162};
163
164enum power_save_mode {
165 POWER_SAVE_MODE_ACTIVE,
166 POWER_SAVE_MODE_SAVE,
167};
168
169enum power_polocy_config {
170 POWERCFG_MAX_POWER_SAVINGS,
171 POWERCFG_GLOBAL_POWER_SAVINGS,
172 POWERCFG_LOCAL_POWER_SAVINGS,
173 POWERCFG_LENOVO,
174};
175
176enum interface_select_pci {
177 INTF_SEL1_MINICARD = 0,
178 INTF_SEL0_PCIE = 1,
179 INTF_SEL2_RSV = 2,
180 INTF_SEL3_RSV = 3,
181};
182
183enum rtl_desc_qsel {
184 QSLT_BK = 0x2,
185 QSLT_BE = 0x0,
186 QSLT_VI = 0x5,
187 QSLT_VO = 0x7,
188 QSLT_BEACON = 0x10,
189 QSLT_HIGH = 0x11,
190 QSLT_MGNT = 0x12,
191 QSLT_CMD = 0x13,
192};
193
194enum rtl_desc8723e_rate {
195 DESC92C_RATE1M = 0x00,
196 DESC92C_RATE2M = 0x01,
197 DESC92C_RATE5_5M = 0x02,
198 DESC92C_RATE11M = 0x03,
199
200 DESC92C_RATE6M = 0x04,
201 DESC92C_RATE9M = 0x05,
202 DESC92C_RATE12M = 0x06,
203 DESC92C_RATE18M = 0x07,
204 DESC92C_RATE24M = 0x08,
205 DESC92C_RATE36M = 0x09,
206 DESC92C_RATE48M = 0x0a,
207 DESC92C_RATE54M = 0x0b,
208
209 DESC92C_RATEMCS0 = 0x0c,
210 DESC92C_RATEMCS1 = 0x0d,
211 DESC92C_RATEMCS2 = 0x0e,
212 DESC92C_RATEMCS3 = 0x0f,
213 DESC92C_RATEMCS4 = 0x10,
214 DESC92C_RATEMCS5 = 0x11,
215 DESC92C_RATEMCS6 = 0x12,
216 DESC92C_RATEMCS7 = 0x13,
217 DESC92C_RATEMCS8 = 0x14,
218 DESC92C_RATEMCS9 = 0x15,
219 DESC92C_RATEMCS10 = 0x16,
220 DESC92C_RATEMCS11 = 0x17,
221 DESC92C_RATEMCS12 = 0x18,
222 DESC92C_RATEMCS13 = 0x19,
223 DESC92C_RATEMCS14 = 0x1a,
224 DESC92C_RATEMCS15 = 0x1b,
225 DESC92C_RATEMCS15_SG = 0x1c,
226 DESC92C_RATEMCS32 = 0x20,
227};
228
229enum rx_packet_type {
230 NORMAL_RX,
231 TX_REPORT1,
232 TX_REPORT2,
233 HIS_REPORT,
234};
235
236struct phy_sts_cck_8723e_t {
237 u8 adc_pwdb_X[4];
238 u8 sq_rpt;
239 u8 cck_agc_rpt;
240};
241
242struct h2c_cmd_8723e {
243 u8 element_id;
244 u32 cmd_len;
245 u8 *p_cmdbuffer;
246};
247
248#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
new file mode 100644
index 000000000000..736bfcb7938a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
@@ -0,0 +1,1325 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../base.h"
28#include "../pci.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "dm.h"
33#include "../rtl8723com/dm_common.h"
34#include "fw.h"
35#include "../rtl8723com/fw_common.h"
36#include "trx.h"
37#include "../btcoexist/rtl_btc.h"
38
39static const u32 ofdmswing_table[] = {
40 0x0b40002d, /* 0, -15.0dB */
41 0x0c000030, /* 1, -14.5dB */
42 0x0cc00033, /* 2, -14.0dB */
43 0x0d800036, /* 3, -13.5dB */
44 0x0e400039, /* 4, -13.0dB */
45 0x0f00003c, /* 5, -12.5dB */
46 0x10000040, /* 6, -12.0dB */
47 0x11000044, /* 7, -11.5dB */
48 0x12000048, /* 8, -11.0dB */
49 0x1300004c, /* 9, -10.5dB */
50 0x14400051, /* 10, -10.0dB */
51 0x15800056, /* 11, -9.5dB */
52 0x16c0005b, /* 12, -9.0dB */
53 0x18000060, /* 13, -8.5dB */
54 0x19800066, /* 14, -8.0dB */
55 0x1b00006c, /* 15, -7.5dB */
56 0x1c800072, /* 16, -7.0dB */
57 0x1e400079, /* 17, -6.5dB */
58 0x20000080, /* 18, -6.0dB */
59 0x22000088, /* 19, -5.5dB */
60 0x24000090, /* 20, -5.0dB */
61 0x26000098, /* 21, -4.5dB */
62 0x288000a2, /* 22, -4.0dB */
63 0x2ac000ab, /* 23, -3.5dB */
64 0x2d4000b5, /* 24, -3.0dB */
65 0x300000c0, /* 25, -2.5dB */
66 0x32c000cb, /* 26, -2.0dB */
67 0x35c000d7, /* 27, -1.5dB */
68 0x390000e4, /* 28, -1.0dB */
69 0x3c8000f2, /* 29, -0.5dB */
70 0x40000100, /* 30, +0dB */
71 0x43c0010f, /* 31, +0.5dB */
72 0x47c0011f, /* 32, +1.0dB */
73 0x4c000130, /* 33, +1.5dB */
74 0x50800142, /* 34, +2.0dB */
75 0x55400155, /* 35, +2.5dB */
76 0x5a400169, /* 36, +3.0dB */
77 0x5fc0017f, /* 37, +3.5dB */
78 0x65400195, /* 38, +4.0dB */
79 0x6b8001ae, /* 39, +4.5dB */
80 0x71c001c7, /* 40, +5.0dB */
81 0x788001e2, /* 41, +5.5dB */
82 0x7f8001fe /* 42, +6.0dB */
83};
84
85static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
86 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB */
87 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB */
88 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB */
89 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB */
90 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB */
91 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB */
92 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB */
93 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB */
94 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB */
95 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB */
96 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB */
97 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB */
98 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB */
99 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB */
100 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
101 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB */
102 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
103 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB */
104 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
105 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB */
106 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 20, -6.0dB */
107 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB */
108 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
109 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB */
110 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
111 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB */
112 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB */
113 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB */
114 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
115 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB */
116 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB */
117 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB */
118 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB */
119};
120
121static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
122 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB */
123 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB */
124 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB */
125 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB */
126 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB */
127 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 5, -13.5dB */
128 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB */
129 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB */
130 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB */
131 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB */
132 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB */
133 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 11, -10.5dB */
134 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB */
135 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB */
136 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 14, -9.0dB */
137 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB */
138 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
139 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB */
140 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
141 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
142 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
143 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB */
144 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
145 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 23, -4.5dB */
146 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
147 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
148 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
149 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 27, -2.5dB */
150 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
151 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 29, -1.5dB */
152 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
153 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
154 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */
155};
156
157static const u32 edca_setting_dl[PEER_MAX] = {
158 0xa44f, /* 0 UNKNOWN */
159 0x5ea44f, /* 1 REALTEK_90 */
160 0x5e4322, /* 2 REALTEK_92SE */
161 0x5ea42b, /* 3 BROAD */
162 0xa44f, /* 4 RAL */
163 0xa630, /* 5 ATH */
164 0x5ea630, /* 6 CISCO */
165 0x5ea42b, /* 7 MARVELL */
166};
167
168static const u32 edca_setting_ul[PEER_MAX] = {
169 0x5e4322, /* 0 UNKNOWN */
170 0xa44f, /* 1 REALTEK_90 */
171 0x5ea44f, /* 2 REALTEK_92SE */
172 0x5ea32b, /* 3 BROAD */
173 0x5ea422, /* 4 RAL */
174 0x5ea322, /* 5 ATH */
175 0x3ea430, /* 6 CISCO */
176 0x5ea44f, /* 7 MARV */
177};
178
179void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type,
180 u8 *pdirection, u32 *poutwrite_val)
181{
182 struct rtl_priv *rtlpriv = rtl_priv(hw);
183 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
184 u8 pwr_val = 0;
185 u8 ofdm_base = rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A];
186 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
187 u8 cck_base = rtldm->swing_idx_cck_base;
188 u8 cck_val = rtldm->swing_idx_cck;
189
190 if (type == 0) {
191 if (ofdm_val <= ofdm_base) {
192 *pdirection = 1;
193 pwr_val = ofdm_base - ofdm_val;
194 } else {
195 *pdirection = 2;
196 pwr_val = ofdm_val - ofdm_base;
197 }
198 } else if (type == 1) {
199 if (cck_val <= cck_base) {
200 *pdirection = 1;
201 pwr_val = cck_base - cck_val;
202 } else {
203 *pdirection = 2;
204 pwr_val = cck_val - cck_base;
205 }
206 }
207
208 if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
209 pwr_val = TXPWRTRACK_MAX_IDX;
210
211 *poutwrite_val = pwr_val | (pwr_val << 8) |
212 (pwr_val << 16) | (pwr_val << 24);
213}
214
215static void rtl8723be_dm_diginit(struct ieee80211_hw *hw)
216{
217 struct rtl_priv *rtlpriv = rtl_priv(hw);
218 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
219
220 dm_digtable->dig_enable_flag = true;
221 dm_digtable->cur_igvalue = rtl_get_bbreg(hw,
222 ROFDM0_XAAGCCORE1, 0x7f);
223 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
224 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
225 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
226 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
227 dm_digtable->rx_gain_max = DM_DIG_MAX;
228 dm_digtable->rx_gain_min = DM_DIG_MIN;
229 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
230 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
231 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
232 dm_digtable->pre_cck_cca_thres = 0xff;
233 dm_digtable->cur_cck_cca_thres = 0x83;
234 dm_digtable->forbidden_igi = DM_DIG_MIN;
235 dm_digtable->large_fa_hit = 0;
236 dm_digtable->recover_cnt = 0;
237 dm_digtable->dig_min_0 = DM_DIG_MIN;
238 dm_digtable->dig_min_1 = DM_DIG_MIN;
239 dm_digtable->media_connect_0 = false;
240 dm_digtable->media_connect_1 = false;
241 rtlpriv->dm.dm_initialgain_enable = true;
242 dm_digtable->bt30_cur_igi = 0x32;
243}
244
245void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
246{
247 struct rtl_priv *rtlpriv = rtl_priv(hw);
248 struct rate_adaptive *ra = &(rtlpriv->ra);
249
250 ra->ratr_state = DM_RATR_STA_INIT;
251 ra->pre_ratr_state = DM_RATR_STA_INIT;
252
253 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
254 rtlpriv->dm.useramask = true;
255 else
256 rtlpriv->dm.useramask = false;
257
258 ra->high_rssi_thresh_for_ra = 50;
259 ra->low_rssi_thresh_for_ra40m = 20;
260}
261
262static void rtl8723be_dm_init_txpower_tracking(struct ieee80211_hw *hw)
263{
264 struct rtl_priv *rtlpriv = rtl_priv(hw);
265
266 rtlpriv->dm.txpower_tracking = true;
267 rtlpriv->dm.txpower_track_control = true;
268 rtlpriv->dm.thermalvalue = 0;
269
270 rtlpriv->dm.ofdm_index[0] = 30;
271 rtlpriv->dm.cck_index = 20;
272
273 rtlpriv->dm.swing_idx_cck_base = rtlpriv->dm.cck_index;
274
275 rtlpriv->dm.swing_idx_ofdm_base[0] = rtlpriv->dm.ofdm_index[0];
276 rtlpriv->dm.delta_power_index[RF90_PATH_A] = 0;
277 rtlpriv->dm.delta_power_index_last[RF90_PATH_A] = 0;
278 rtlpriv->dm.power_index_offset[RF90_PATH_A] = 0;
279
280 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
281 " rtlpriv->dm.txpower_tracking = %d\n",
282 rtlpriv->dm.txpower_tracking);
283}
284
285static void rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
286{
287 struct rtl_priv *rtlpriv = rtl_priv(hw);
288
289 rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
290 rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, 0x800);
291 rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
292}
293
294void rtl8723be_dm_init(struct ieee80211_hw *hw)
295{
296 struct rtl_priv *rtlpriv = rtl_priv(hw);
297
298 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
299 rtl8723be_dm_diginit(hw);
300 rtl8723be_dm_init_rate_adaptive_mask(hw);
301 rtl8723_dm_init_edca_turbo(hw);
302 rtl8723_dm_init_dynamic_bb_powersaving(hw);
303 rtl8723_dm_init_dynamic_txpower(hw);
304 rtl8723be_dm_init_txpower_tracking(hw);
305 rtl8723be_dm_init_dynamic_atc_switch(hw);
306}
307
308static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw)
309{
310 struct rtl_priv *rtlpriv = rtl_priv(hw);
311 struct dig_t *rtl_dm_dig = &(rtlpriv->dm_digtable);
312 struct rtl_mac *mac = rtl_mac(rtlpriv);
313
314 /* Determine the minimum RSSI */
315 if ((mac->link_state < MAC80211_LINKED) &&
316 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
317 rtl_dm_dig->min_undec_pwdb_for_dm = 0;
318 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
319 "Not connected to any\n");
320 }
321 if (mac->link_state >= MAC80211_LINKED) {
322 if (mac->opmode == NL80211_IFTYPE_AP ||
323 mac->opmode == NL80211_IFTYPE_ADHOC) {
324 rtl_dm_dig->min_undec_pwdb_for_dm =
325 rtlpriv->dm.entry_min_undec_sm_pwdb;
326 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
327 "AP Client PWDB = 0x%lx\n",
328 rtlpriv->dm.entry_min_undec_sm_pwdb);
329 } else {
330 rtl_dm_dig->min_undec_pwdb_for_dm =
331 rtlpriv->dm.undec_sm_pwdb;
332 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
333 "STA Default Port PWDB = 0x%x\n",
334 rtl_dm_dig->min_undec_pwdb_for_dm);
335 }
336 } else {
337 rtl_dm_dig->min_undec_pwdb_for_dm =
338 rtlpriv->dm.entry_min_undec_sm_pwdb;
339 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
340 "AP Ext Port or disconnet PWDB = 0x%x\n",
341 rtl_dm_dig->min_undec_pwdb_for_dm);
342 }
343 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
344 rtl_dm_dig->min_undec_pwdb_for_dm);
345}
346
347static void rtl8723be_dm_check_rssi_monitor(struct ieee80211_hw *hw)
348{
349 struct rtl_priv *rtlpriv = rtl_priv(hw);
350 struct rtl_sta_info *drv_priv;
351 u8 h2c_parameter[3] = { 0 };
352 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
353
354 /* AP & ADHOC & MESH */
355 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
356 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
357 if (drv_priv->rssi_stat.undec_sm_pwdb <
358 tmp_entry_min_pwdb)
359 tmp_entry_min_pwdb =
360 drv_priv->rssi_stat.undec_sm_pwdb;
361 if (drv_priv->rssi_stat.undec_sm_pwdb >
362 tmp_entry_max_pwdb)
363 tmp_entry_max_pwdb =
364 drv_priv->rssi_stat.undec_sm_pwdb;
365 }
366 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
367
368 /* If associated entry is found */
369 if (tmp_entry_max_pwdb != 0) {
370 rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb;
371 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
372 "EntryMaxPWDB = 0x%lx(%ld)\n",
373 tmp_entry_max_pwdb, tmp_entry_max_pwdb);
374 } else {
375 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
376 }
377 /* If associated entry is found */
378 if (tmp_entry_min_pwdb != 0xff) {
379 rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb;
380 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
381 "EntryMinPWDB = 0x%lx(%ld)\n",
382 tmp_entry_min_pwdb, tmp_entry_min_pwdb);
383 } else {
384 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
385 }
386 /* Indicate Rx signal strength to FW. */
387 if (rtlpriv->dm.useramask) {
388 h2c_parameter[2] = (u8) (rtlpriv->dm.undec_sm_pwdb & 0xFF);
389 h2c_parameter[1] = 0x20;
390 h2c_parameter[0] = 0;
391 rtl8723be_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);
392 } else {
393 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
394 }
395 rtl8723be_dm_find_minimum_rssi(hw);
396 rtlpriv->dm_digtable.rssi_val_min =
397 rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
398}
399
400void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
401{
402 struct rtl_priv *rtlpriv = rtl_priv(hw);
403
404 if (rtlpriv->dm_digtable.cur_igvalue != current_igi) {
405 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
406 if (rtlpriv->phy.rf_type != RF_1T1R)
407 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, current_igi);
408 }
409 rtlpriv->dm_digtable.pre_igvalue = rtlpriv->dm_digtable.cur_igvalue;
410 rtlpriv->dm_digtable.cur_igvalue = current_igi;
411}
412
413static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
414{
415 struct rtl_priv *rtlpriv = rtl_priv(hw);
416 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
417 struct dig_t *dm_digtable = &(rtlpriv->dm_digtable);
418 u8 dig_dynamic_min, dig_maxofmin;
419 bool firstconnect, firstdisconnect;
420 u8 dm_dig_max, dm_dig_min;
421 u8 current_igi = dm_digtable->cur_igvalue;
422 u8 offset;
423
424 /* AP, BT */
425 if (mac->act_scanning)
426 return;
427
428 dig_dynamic_min = dm_digtable->dig_min_0;
429 firstconnect = (mac->link_state >= MAC80211_LINKED) &&
430 !dm_digtable->media_connect_0;
431 firstdisconnect = (mac->link_state < MAC80211_LINKED) &&
432 dm_digtable->media_connect_0;
433
434 dm_dig_max = 0x5a;
435 dm_dig_min = DM_DIG_MIN;
436 dig_maxofmin = DM_DIG_MAX_AP;
437
438 if (mac->link_state >= MAC80211_LINKED) {
439 if ((dm_digtable->rssi_val_min + 10) > dm_dig_max)
440 dm_digtable->rx_gain_max = dm_dig_max;
441 else if ((dm_digtable->rssi_val_min + 10) < dm_dig_min)
442 dm_digtable->rx_gain_max = dm_dig_min;
443 else
444 dm_digtable->rx_gain_max =
445 dm_digtable->rssi_val_min + 10;
446
447 if (rtlpriv->dm.one_entry_only) {
448 offset = 12;
449 if (dm_digtable->rssi_val_min - offset < dm_dig_min)
450 dig_dynamic_min = dm_dig_min;
451 else if (dm_digtable->rssi_val_min - offset >
452 dig_maxofmin)
453 dig_dynamic_min = dig_maxofmin;
454 else
455 dig_dynamic_min =
456 dm_digtable->rssi_val_min - offset;
457 } else {
458 dig_dynamic_min = dm_dig_min;
459 }
460 } else {
461 dm_digtable->rx_gain_max = dm_dig_max;
462 dig_dynamic_min = dm_dig_min;
463 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
464 }
465
466 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
467 if (dm_digtable->large_fa_hit != 3)
468 dm_digtable->large_fa_hit++;
469 if (dm_digtable->forbidden_igi < current_igi) {
470 dm_digtable->forbidden_igi = current_igi;
471 dm_digtable->large_fa_hit = 1;
472 }
473
474 if (dm_digtable->large_fa_hit >= 3) {
475 if ((dm_digtable->forbidden_igi + 1) >
476 dm_digtable->rx_gain_max)
477 dm_digtable->rx_gain_min =
478 dm_digtable->rx_gain_max;
479 else
480 dm_digtable->rx_gain_min =
481 dm_digtable->forbidden_igi + 1;
482 dm_digtable->recover_cnt = 3600;
483 }
484 } else {
485 if (dm_digtable->recover_cnt != 0) {
486 dm_digtable->recover_cnt--;
487 } else {
488 if (dm_digtable->large_fa_hit < 3) {
489 if ((dm_digtable->forbidden_igi - 1) <
490 dig_dynamic_min) {
491 dm_digtable->forbidden_igi =
492 dig_dynamic_min;
493 dm_digtable->rx_gain_min =
494 dig_dynamic_min;
495 } else {
496 dm_digtable->forbidden_igi--;
497 dm_digtable->rx_gain_min =
498 dm_digtable->forbidden_igi + 1;
499 }
500 } else {
501 dm_digtable->large_fa_hit = 0;
502 }
503 }
504 }
505 if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max)
506 dm_digtable->rx_gain_min = dm_digtable->rx_gain_max;
507
508 if (mac->link_state >= MAC80211_LINKED) {
509 if (firstconnect) {
510 if (dm_digtable->rssi_val_min <= dig_maxofmin)
511 current_igi = dm_digtable->rssi_val_min;
512 else
513 current_igi = dig_maxofmin;
514
515 dm_digtable->large_fa_hit = 0;
516 } else {
517 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
518 current_igi += 4;
519 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
520 current_igi += 2;
521 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
522 current_igi -= 2;
523 }
524 } else {
525 if (firstdisconnect) {
526 current_igi = dm_digtable->rx_gain_min;
527 } else {
528 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
529 current_igi += 4;
530 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
531 current_igi += 2;
532 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
533 current_igi -= 2;
534 }
535 }
536
537 if (current_igi > dm_digtable->rx_gain_max)
538 current_igi = dm_digtable->rx_gain_max;
539 else if (current_igi < dm_digtable->rx_gain_min)
540 current_igi = dm_digtable->rx_gain_min;
541
542 rtl8723be_dm_write_dig(hw, current_igi);
543 dm_digtable->media_connect_0 =
544 ((mac->link_state >= MAC80211_LINKED) ? true : false);
545 dm_digtable->dig_min_0 = dig_dynamic_min;
546}
547
548static void rtl8723be_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
549{
550 u32 ret_value;
551 struct rtl_priv *rtlpriv = rtl_priv(hw);
552 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
553
554 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
555 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
556
557 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
558 falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff;
559 falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16;
560
561 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
562 falsealm_cnt->cnt_ofdm_cca = ret_value & 0xffff;
563 falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16;
564
565 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
566 falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff;
567 falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16;
568
569 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
570 falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff;
571
572 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
573 falsealm_cnt->cnt_rate_illegal +
574 falsealm_cnt->cnt_crc8_fail +
575 falsealm_cnt->cnt_mcs_fail +
576 falsealm_cnt->cnt_fast_fsync_fail +
577 falsealm_cnt->cnt_sb_search_fail;
578
579 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
580 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
581
582 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_RST_11N, MASKBYTE0);
583 falsealm_cnt->cnt_cck_fail = ret_value;
584
585 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
586 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
587
588 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
589 falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
590 ((ret_value & 0xff00) >> 8);
591
592 falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
593 falsealm_cnt->cnt_sb_search_fail +
594 falsealm_cnt->cnt_parity_fail +
595 falsealm_cnt->cnt_rate_illegal +
596 falsealm_cnt->cnt_crc8_fail +
597 falsealm_cnt->cnt_mcs_fail +
598 falsealm_cnt->cnt_cck_fail;
599
600 falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
601 falsealm_cnt->cnt_cck_cca;
602
603 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
604 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
605 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
606 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
607
608 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
609 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
610
611 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
612 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
613
614 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
615 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
616
617 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
618 "cnt_parity_fail = %d, cnt_rate_illegal = %d, "
619 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
620 falsealm_cnt->cnt_parity_fail,
621 falsealm_cnt->cnt_rate_illegal,
622 falsealm_cnt->cnt_crc8_fail,
623 falsealm_cnt->cnt_mcs_fail);
624
625 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
626 "cnt_ofdm_fail = %x, cnt_cck_fail = %x,"
627 " cnt_all = %x\n",
628 falsealm_cnt->cnt_ofdm_fail,
629 falsealm_cnt->cnt_cck_fail,
630 falsealm_cnt->cnt_all);
631}
632
633static void rtl8723be_dm_dynamic_txpower(struct ieee80211_hw *hw)
634{
635 /* 8723BE does not support ODM_BB_DYNAMIC_TXPWR*/
636 return;
637}
638
639static void rtl8723be_set_iqk_matrix(struct ieee80211_hw *hw, u8 ofdm_index,
640 u8 rfpath, long iqk_result_x,
641 long iqk_result_y)
642{
643 long ele_a = 0, ele_d, ele_c = 0, value32;
644
645 if (ofdm_index >= 43)
646 ofdm_index = 43 - 1;
647
648 ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000) >> 22;
649
650 if (iqk_result_x != 0) {
651 if ((iqk_result_x & 0x00000200) != 0)
652 iqk_result_x = iqk_result_x | 0xFFFFFC00;
653 ele_a = ((iqk_result_x * ele_d) >> 8) & 0x000003FF;
654
655 if ((iqk_result_y & 0x00000200) != 0)
656 iqk_result_y = iqk_result_y | 0xFFFFFC00;
657 ele_c = ((iqk_result_y * ele_d) >> 8) & 0x000003FF;
658
659 switch (rfpath) {
660 case RF90_PATH_A:
661 value32 = (ele_d << 22) |
662 ((ele_c & 0x3F) << 16) | ele_a;
663 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
664 value32);
665 value32 = (ele_c & 0x000003C0) >> 6;
666 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
667 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
668 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
669 value32);
670 break;
671 default:
672 break;
673 }
674 } else {
675 switch (rfpath) {
676 case RF90_PATH_A:
677 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
678 ofdmswing_table[ofdm_index]);
679 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
680 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00);
681 break;
682 default:
683 break;
684 }
685 }
686}
687
688static void rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw *hw,
689 enum pwr_track_control_method method,
690 u8 rfpath, u8 idx)
691{
692 struct rtl_priv *rtlpriv = rtl_priv(hw);
693 struct rtl_phy *rtlphy = &(rtlpriv->phy);
694 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
695 u8 swing_idx_ofdm_limit = 36;
696
697 if (method == TXAGC) {
698 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
699 } else if (method == BBSWING) {
700 if (rtldm->swing_idx_cck >= CCK_TABLE_SIZE)
701 rtldm->swing_idx_cck = CCK_TABLE_SIZE - 1;
702
703 if (!rtldm->cck_inch14) {
704 rtl_write_byte(rtlpriv, 0xa22,
705 cckswing_table_ch1ch13[rtldm->swing_idx_cck][0]);
706 rtl_write_byte(rtlpriv, 0xa23,
707 cckswing_table_ch1ch13[rtldm->swing_idx_cck][1]);
708 rtl_write_byte(rtlpriv, 0xa24,
709 cckswing_table_ch1ch13[rtldm->swing_idx_cck][2]);
710 rtl_write_byte(rtlpriv, 0xa25,
711 cckswing_table_ch1ch13[rtldm->swing_idx_cck][3]);
712 rtl_write_byte(rtlpriv, 0xa26,
713 cckswing_table_ch1ch13[rtldm->swing_idx_cck][4]);
714 rtl_write_byte(rtlpriv, 0xa27,
715 cckswing_table_ch1ch13[rtldm->swing_idx_cck][5]);
716 rtl_write_byte(rtlpriv, 0xa28,
717 cckswing_table_ch1ch13[rtldm->swing_idx_cck][6]);
718 rtl_write_byte(rtlpriv, 0xa29,
719 cckswing_table_ch1ch13[rtldm->swing_idx_cck][7]);
720 } else {
721 rtl_write_byte(rtlpriv, 0xa22,
722 cckswing_table_ch14[rtldm->swing_idx_cck][0]);
723 rtl_write_byte(rtlpriv, 0xa23,
724 cckswing_table_ch14[rtldm->swing_idx_cck][1]);
725 rtl_write_byte(rtlpriv, 0xa24,
726 cckswing_table_ch14[rtldm->swing_idx_cck][2]);
727 rtl_write_byte(rtlpriv, 0xa25,
728 cckswing_table_ch14[rtldm->swing_idx_cck][3]);
729 rtl_write_byte(rtlpriv, 0xa26,
730 cckswing_table_ch14[rtldm->swing_idx_cck][4]);
731 rtl_write_byte(rtlpriv, 0xa27,
732 cckswing_table_ch14[rtldm->swing_idx_cck][5]);
733 rtl_write_byte(rtlpriv, 0xa28,
734 cckswing_table_ch14[rtldm->swing_idx_cck][6]);
735 rtl_write_byte(rtlpriv, 0xa29,
736 cckswing_table_ch14[rtldm->swing_idx_cck][7]);
737 }
738
739 if (rfpath == RF90_PATH_A) {
740 if (rtldm->swing_idx_ofdm[RF90_PATH_A] <
741 swing_idx_ofdm_limit)
742 swing_idx_ofdm_limit =
743 rtldm->swing_idx_ofdm[RF90_PATH_A];
744
745 rtl8723be_set_iqk_matrix(hw,
746 rtldm->swing_idx_ofdm[rfpath], rfpath,
747 rtlphy->iqk_matrix[idx].value[0][0],
748 rtlphy->iqk_matrix[idx].value[0][1]);
749 } else if (rfpath == RF90_PATH_B) {
750 if (rtldm->swing_idx_ofdm[RF90_PATH_B] <
751 swing_idx_ofdm_limit)
752 swing_idx_ofdm_limit =
753 rtldm->swing_idx_ofdm[RF90_PATH_B];
754
755 rtl8723be_set_iqk_matrix(hw,
756 rtldm->swing_idx_ofdm[rfpath], rfpath,
757 rtlphy->iqk_matrix[idx].value[0][4],
758 rtlphy->iqk_matrix[idx].value[0][5]);
759 }
760 } else {
761 return;
762 }
763}
764
765static void txpwr_track_cb_therm(struct ieee80211_hw *hw)
766{
767 struct rtl_priv *rtlpriv = rtl_priv(hw);
768 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
769 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
770 u8 thermalvalue = 0, delta, delta_lck, delta_iqk;
771 u8 thermalvalue_avg_count = 0;
772 u32 thermalvalue_avg = 0;
773 int i = 0;
774
775 u8 ofdm_min_index = 6;
776 u8 index = 0;
777
778 char delta_swing_table_idx_tup_a[] = {
779 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
780 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10,
781 10, 11, 11, 12, 12, 13, 14, 15};
782 char delta_swing_table_idx_tdown_a[] = {
783 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
784 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9,
785 9, 10, 10, 11, 12, 13, 14, 15};
786
787 /*Initilization ( 7 steps in total)*/
788 rtlpriv->dm.txpower_trackinginit = true;
789 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
790 "rtl8723be_dm_txpower_tracking"
791 "_callback_thermalmeter\n");
792
793 thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xfc00);
794 if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 ||
795 rtlefuse->eeprom_thermalmeter == 0xFF)
796 return;
797 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
798 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
799 "eeprom_thermalmeter 0x%x\n",
800 thermalvalue, rtldm->thermalvalue,
801 rtlefuse->eeprom_thermalmeter);
802 /*3 Initialize ThermalValues of RFCalibrateInfo*/
803 if (!rtldm->thermalvalue) {
804 rtlpriv->dm.thermalvalue_lck = thermalvalue;
805 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
806 }
807
808 /*4 Calculate average thermal meter*/
809 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
810 rtldm->thermalvalue_avg_index++;
811 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8723BE)
812 rtldm->thermalvalue_avg_index = 0;
813
814 for (i = 0; i < AVG_THERMAL_NUM_8723BE; i++) {
815 if (rtldm->thermalvalue_avg[i]) {
816 thermalvalue_avg += rtldm->thermalvalue_avg[i];
817 thermalvalue_avg_count++;
818 }
819 }
820
821 if (thermalvalue_avg_count)
822 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
823
824 /* 5 Calculate delta, delta_LCK, delta_IQK.*/
825 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
826 (thermalvalue - rtlpriv->dm.thermalvalue) :
827 (rtlpriv->dm.thermalvalue - thermalvalue);
828 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
829 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
830 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
831 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
832 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
833 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
834
835 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
836 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
837 "eeprom_thermalmeter 0x%x delta 0x%x "
838 "delta_lck 0x%x delta_iqk 0x%x\n",
839 thermalvalue, rtlpriv->dm.thermalvalue,
840 rtlefuse->eeprom_thermalmeter, delta, delta_lck, delta_iqk);
841 /* 6 If necessary, do LCK.*/
842 if (delta_lck >= IQK_THRESHOLD) {
843 rtlpriv->dm.thermalvalue_lck = thermalvalue;
844 rtl8723be_phy_lc_calibrate(hw);
845 }
846
847 /* 7 If necessary, move the index of
848 * swing table to adjust Tx power.
849 */
850 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
851 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
852 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
853 (rtlefuse->eeprom_thermalmeter - thermalvalue);
854
855 if (delta >= TXSCALE_TABLE_SIZE)
856 delta = TXSCALE_TABLE_SIZE - 1;
857 /* 7.1 Get the final CCK_index and
858 * OFDM_index for each swing table.
859 */
860 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
861 rtldm->delta_power_index_last[RF90_PATH_A] =
862 rtldm->delta_power_index[RF90_PATH_A];
863 rtldm->delta_power_index[RF90_PATH_A] =
864 delta_swing_table_idx_tup_a[delta];
865 } else {
866 rtldm->delta_power_index_last[RF90_PATH_A] =
867 rtldm->delta_power_index[RF90_PATH_A];
868 rtldm->delta_power_index[RF90_PATH_A] =
869 -1 * delta_swing_table_idx_tdown_a[delta];
870 }
871
872 /* 7.2 Handle boundary conditions of index.*/
873 if (rtldm->delta_power_index[RF90_PATH_A] ==
874 rtldm->delta_power_index_last[RF90_PATH_A])
875 rtldm->power_index_offset[RF90_PATH_A] = 0;
876 else
877 rtldm->power_index_offset[RF90_PATH_A] =
878 rtldm->delta_power_index[RF90_PATH_A] -
879 rtldm->delta_power_index_last[RF90_PATH_A];
880
881 rtldm->ofdm_index[0] =
882 rtldm->swing_idx_ofdm_base[RF90_PATH_A] +
883 rtldm->power_index_offset[RF90_PATH_A];
884 rtldm->cck_index = rtldm->swing_idx_cck_base +
885 rtldm->power_index_offset[RF90_PATH_A];
886
887 rtldm->swing_idx_cck = rtldm->cck_index;
888 rtldm->swing_idx_ofdm[0] = rtldm->ofdm_index[0];
889
890 if (rtldm->ofdm_index[0] > OFDM_TABLE_SIZE - 1)
891 rtldm->ofdm_index[0] = OFDM_TABLE_SIZE - 1;
892 else if (rtldm->ofdm_index[0] < ofdm_min_index)
893 rtldm->ofdm_index[0] = ofdm_min_index;
894
895 if (rtldm->cck_index > CCK_TABLE_SIZE - 1)
896 rtldm->cck_index = CCK_TABLE_SIZE - 1;
897 else if (rtldm->cck_index < 0)
898 rtldm->cck_index = 0;
899 } else {
900 rtldm->power_index_offset[RF90_PATH_A] = 0;
901 }
902
903 if ((rtldm->power_index_offset[RF90_PATH_A] != 0) &&
904 (rtldm->txpower_track_control)) {
905 rtldm->done_txpower = true;
906 if (thermalvalue > rtlefuse->eeprom_thermalmeter)
907 rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
908 index);
909 else
910 rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
911 index);
912
913 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
914 rtldm->swing_idx_ofdm_base[RF90_PATH_A] =
915 rtldm->swing_idx_ofdm[0];
916 rtldm->thermalvalue = thermalvalue;
917 }
918
919 if (delta_iqk >= IQK_THRESHOLD) {
920 rtldm->thermalvalue_iqk = thermalvalue;
921 rtl8723be_phy_iq_calibrate(hw, false);
922 }
923
924 rtldm->txpowercount = 0;
925 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
926}
927
928void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw)
929{
930 struct rtl_priv *rtlpriv = rtl_priv(hw);
931 static u8 tm_trigger;
932
933 if (!rtlpriv->dm.txpower_tracking)
934 return;
935
936 if (!tm_trigger) {
937 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16),
938 0x03);
939 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
940 "Trigger 8723be Thermal Meter!!\n");
941 tm_trigger = 1;
942 return;
943 } else {
944 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
945 "Schedule TxPowerTracking !!\n");
946 txpwr_track_cb_therm(hw);
947 tm_trigger = 0;
948 }
949}
950
951static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
952{
953 struct rtl_priv *rtlpriv = rtl_priv(hw);
954 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
955 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
956 struct rate_adaptive *ra = &(rtlpriv->ra);
957 struct ieee80211_sta *sta = NULL;
958 u32 low_rssithresh_for_ra = ra->low2high_rssi_thresh_for_ra40m;
959 u32 high_rssithresh_for_ra = ra->high_rssi_thresh_for_ra;
960 u8 go_up_gap = 5;
961
962 if (is_hal_stop(rtlhal)) {
963 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
964 "driver is going to unload\n");
965 return;
966 }
967
968 if (!rtlpriv->dm.useramask) {
969 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
970 "driver does not control rate adaptive mask\n");
971 return;
972 }
973
974 if (mac->link_state == MAC80211_LINKED &&
975 mac->opmode == NL80211_IFTYPE_STATION) {
976 switch (ra->pre_ratr_state) {
977 case DM_RATR_STA_MIDDLE:
978 high_rssithresh_for_ra += go_up_gap;
979 break;
980 case DM_RATR_STA_LOW:
981 high_rssithresh_for_ra += go_up_gap;
982 low_rssithresh_for_ra += go_up_gap;
983 break;
984 default:
985 break;
986 }
987
988 if (rtlpriv->dm.undec_sm_pwdb >
989 (long)high_rssithresh_for_ra)
990 ra->ratr_state = DM_RATR_STA_HIGH;
991 else if (rtlpriv->dm.undec_sm_pwdb >
992 (long)low_rssithresh_for_ra)
993 ra->ratr_state = DM_RATR_STA_MIDDLE;
994 else
995 ra->ratr_state = DM_RATR_STA_LOW;
996
997 if (ra->pre_ratr_state != ra->ratr_state) {
998 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
999 "RSSI = %ld\n",
1000 rtlpriv->dm.undec_sm_pwdb);
1001 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1002 "RSSI_LEVEL = %d\n", ra->ratr_state);
1003 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1004 "PreState = %d, CurState = %d\n",
1005 ra->pre_ratr_state, ra->ratr_state);
1006
1007 rcu_read_lock();
1008 sta = rtl_find_sta(hw, mac->bssid);
1009 if (sta)
1010 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1011 ra->ratr_state);
1012 rcu_read_unlock();
1013
1014 ra->pre_ratr_state = ra->ratr_state;
1015 }
1016 }
1017}
1018
1019static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
1020{
1021 struct rtl_priv *rtlpriv = rtl_priv(hw);
1022
1023 if (rtlpriv->cfg->ops->get_btc_status()) {
1024 if (rtlpriv->btcoexist.btc_ops->btc_is_disable_edca_turbo(rtlpriv))
1025 return true;
1026 }
1027 if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
1028 return true;
1029
1030 return false;
1031}
1032
1033static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
1034{
1035 struct rtl_priv *rtlpriv = rtl_priv(hw);
1036 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1037 static u64 last_txok_cnt;
1038 static u64 last_rxok_cnt;
1039 u64 cur_txok_cnt = 0;
1040 u64 cur_rxok_cnt = 0;
1041 u32 edca_be_ul = 0x6ea42b;
1042 u32 edca_be_dl = 0x6ea42b;/*not sure*/
1043 u32 edca_be = 0x5ea42b;
1044 u32 iot_peer = 0;
1045 bool is_cur_rdlstate;
1046 bool last_is_cur_rdlstate = false;
1047 bool bias_on_rx = false;
1048 bool edca_turbo_on = false;
1049
1050 last_is_cur_rdlstate = rtlpriv->dm.is_cur_rdlstate;
1051
1052 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
1053 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
1054
1055 iot_peer = rtlpriv->mac80211.vendor;
1056 bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ?
1057 true : false;
1058 edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
1059 (!rtlpriv->dm.disable_framebursting)) ?
1060 true : false;
1061
1062 if ((iot_peer == PEER_CISCO) &&
1063 (mac->mode == WIRELESS_MODE_N_24G)) {
1064 edca_be_dl = edca_setting_dl[iot_peer];
1065 edca_be_ul = edca_setting_ul[iot_peer];
1066 }
1067 if (rtl8723be_dm_is_edca_turbo_disable(hw))
1068 goto exit;
1069
1070 if (edca_turbo_on) {
1071 if (bias_on_rx)
1072 is_cur_rdlstate = (cur_txok_cnt > cur_rxok_cnt * 4) ?
1073 false : true;
1074 else
1075 is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
1076 true : false;
1077
1078 edca_be = (is_cur_rdlstate) ? edca_be_dl : edca_be_ul;
1079 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be);
1080 rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate;
1081 rtlpriv->dm.current_turbo_edca = true;
1082 } else {
1083 if (rtlpriv->dm.current_turbo_edca) {
1084 u8 tmp = AC0_BE;
1085 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
1086 (u8 *)(&tmp));
1087 }
1088 rtlpriv->dm.current_turbo_edca = false;
1089 }
1090
1091exit:
1092 rtlpriv->dm.is_any_nonbepkts = false;
1093 last_txok_cnt = rtlpriv->stats.txbytesunicast;
1094 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
1095}
1096
1097static void rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
1098{
1099 struct rtl_priv *rtlpriv = rtl_priv(hw);
1100 u8 cur_cck_cca_thresh;
1101
1102 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1103 if (rtlpriv->dm_digtable.rssi_val_min > 25) {
1104 cur_cck_cca_thresh = 0xcd;
1105 } else if ((rtlpriv->dm_digtable.rssi_val_min <= 25) &&
1106 (rtlpriv->dm_digtable.rssi_val_min > 10)) {
1107 cur_cck_cca_thresh = 0x83;
1108 } else {
1109 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1110 cur_cck_cca_thresh = 0x83;
1111 else
1112 cur_cck_cca_thresh = 0x40;
1113 }
1114 } else {
1115 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1116 cur_cck_cca_thresh = 0x83;
1117 else
1118 cur_cck_cca_thresh = 0x40;
1119 }
1120
1121 if (rtlpriv->dm_digtable.cur_cck_cca_thres != cur_cck_cca_thresh)
1122 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
1123
1124 rtlpriv->dm_digtable.pre_cck_cca_thres = rtlpriv->dm_digtable.cur_cck_cca_thres;
1125 rtlpriv->dm_digtable.cur_cck_cca_thres = cur_cck_cca_thresh;
1126 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
1127 "CCK cca thresh hold =%x\n",
1128 rtlpriv->dm_digtable.cur_cck_cca_thres);
1129}
1130
1131static void rtl8723be_dm_dynamic_edcca(struct ieee80211_hw *hw)
1132{
1133 struct rtl_priv *rtlpriv = rtl_priv(hw);
1134 u8 reg_c50, reg_c58;
1135 bool fw_current_in_ps_mode = false;
1136
1137 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1138 (u8 *)(&fw_current_in_ps_mode));
1139 if (fw_current_in_ps_mode)
1140 return;
1141
1142 reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1143 reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1144
1145 if (reg_c50 > 0x28 && reg_c58 > 0x28) {
1146 if (!rtlpriv->rtlhal.pre_edcca_enable) {
1147 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
1148 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
1149 }
1150 } else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
1151 if (rtlpriv->rtlhal.pre_edcca_enable) {
1152 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
1153 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
1154 }
1155 }
1156}
1157
1158static void rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
1159{
1160 struct rtl_priv *rtlpriv = rtl_priv(hw);
1161 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1162 u8 crystal_cap;
1163 u32 packet_count;
1164 int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
1165 int cfo_ave_diff;
1166
1167 if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1168 if (rtldm->atc_status == ATC_STATUS_OFF) {
1169 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1170 ATC_STATUS_ON);
1171 rtldm->atc_status = ATC_STATUS_ON;
1172 }
1173 if (rtlpriv->cfg->ops->get_btc_status()) {
1174 if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) {
1175 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1176 "odm_DynamicATCSwitch(): Disable"
1177 " CFO tracking for BT!!\n");
1178 return;
1179 }
1180 }
1181
1182 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
1183 rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
1184 crystal_cap = rtldm->crystal_cap & 0x3f;
1185 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1186 (crystal_cap | (crystal_cap << 6)));
1187 }
1188 } else {
1189 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
1190 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
1191 packet_count = rtldm->packet_count;
1192
1193 if (packet_count == rtldm->packet_count_pre)
1194 return;
1195
1196 rtldm->packet_count_pre = packet_count;
1197
1198 if (rtlpriv->phy.rf_type == RF_1T1R)
1199 cfo_ave = cfo_khz_a;
1200 else
1201 cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
1202
1203 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
1204 (rtldm->cfo_ave_pre - cfo_ave) :
1205 (cfo_ave - rtldm->cfo_ave_pre);
1206
1207 if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) {
1208 rtldm->large_cfo_hit = 1;
1209 return;
1210 } else {
1211 rtldm->large_cfo_hit = 0;
1212 }
1213
1214 rtldm->cfo_ave_pre = cfo_ave;
1215
1216 if (cfo_ave >= -rtldm->cfo_threshold &&
1217 cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
1218 if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
1219 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
1220 rtldm->is_freeze = 1;
1221 } else {
1222 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
1223 }
1224 }
1225
1226 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
1227 adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 1) + 1;
1228 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
1229 rtlpriv->dm.crystal_cap > 0)
1230 adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 1) - 1;
1231
1232 if (adjust_xtal != 0) {
1233 rtldm->is_freeze = 0;
1234 rtldm->crystal_cap += adjust_xtal;
1235
1236 if (rtldm->crystal_cap > 0x3f)
1237 rtldm->crystal_cap = 0x3f;
1238 else if (rtldm->crystal_cap < 0)
1239 rtldm->crystal_cap = 0;
1240
1241 crystal_cap = rtldm->crystal_cap & 0x3f;
1242 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1243 (crystal_cap | (crystal_cap << 6)));
1244 }
1245
1246 if (cfo_ave < CFO_THRESHOLD_ATC &&
1247 cfo_ave > -CFO_THRESHOLD_ATC) {
1248 if (rtldm->atc_status == ATC_STATUS_ON) {
1249 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1250 ATC_STATUS_OFF);
1251 rtldm->atc_status = ATC_STATUS_OFF;
1252 }
1253 } else {
1254 if (rtldm->atc_status == ATC_STATUS_OFF) {
1255 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1256 ATC_STATUS_ON);
1257 rtldm->atc_status = ATC_STATUS_ON;
1258 }
1259 }
1260 }
1261}
1262
1263static void rtl8723be_dm_common_info_self_update(struct ieee80211_hw *hw)
1264{
1265 struct rtl_priv *rtlpriv = rtl_priv(hw);
1266 struct rtl_sta_info *drv_priv;
1267 u8 cnt = 0;
1268
1269 rtlpriv->dm.one_entry_only = false;
1270
1271 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
1272 rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1273 rtlpriv->dm.one_entry_only = true;
1274 return;
1275 }
1276
1277 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1278 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
1279 rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
1280 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1281 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1282 cnt++;
1283 }
1284 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1285
1286 if (cnt == 1)
1287 rtlpriv->dm.one_entry_only = true;
1288 }
1289}
1290
1291void rtl8723be_dm_watchdog(struct ieee80211_hw *hw)
1292{
1293 struct rtl_priv *rtlpriv = rtl_priv(hw);
1294 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1295 bool fw_current_inpsmode = false;
1296 bool fw_ps_awake = true;
1297
1298 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1299 (u8 *)(&fw_current_inpsmode));
1300
1301 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1302 (u8 *)(&fw_ps_awake));
1303
1304 if (ppsc->p2p_ps_info.p2p_ps_mode)
1305 fw_ps_awake = false;
1306
1307 if ((ppsc->rfpwr_state == ERFON) &&
1308 ((!fw_current_inpsmode) && fw_ps_awake) &&
1309 (!ppsc->rfchange_inprogress)) {
1310 rtl8723be_dm_common_info_self_update(hw);
1311 rtl8723be_dm_false_alarm_counter_statistics(hw);
1312 rtl8723be_dm_check_rssi_monitor(hw);
1313 rtl8723be_dm_dig(hw);
1314 rtl8723be_dm_dynamic_edcca(hw);
1315 rtl8723be_dm_cck_packet_detection_thresh(hw);
1316 rtl8723be_dm_refresh_rate_adaptive_mask(hw);
1317 rtl8723be_dm_check_edca_turbo(hw);
1318 rtl8723be_dm_dynamic_atc_switch(hw);
1319 rtl8723be_dm_check_txpower_tracking(hw);
1320 rtl8723be_dm_dynamic_txpower(hw);
1321 if (rtlpriv->cfg->ops->get_btc_status())
1322 rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv);
1323 }
1324 rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
1325}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.h b/drivers/net/wireless/rtlwifi/rtl8723be/dm.h
new file mode 100644
index 000000000000..c6c2f2a78a66
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.h
@@ -0,0 +1,310 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * Contact Information:
15 * wlanfae <wlanfae@realtek.com>
16 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
17 * Hsinchu 300, Taiwan.
18 *
19 * Larry Finger <Larry.Finger@lwfinger.net>
20 *
21 *****************************************************************************/
22
23#ifndef __RTL8723BE_DM_H__
24#define __RTL8723BE_DM_H__
25
26#define MAIN_ANT 0
27#define AUX_ANT 1
28#define MAIN_ANT_CG_TRX 1
29#define AUX_ANT_CG_TRX 0
30#define MAIN_ANT_CGCS_RX 0
31#define AUX_ANT_CGCS_RX 1
32
33#define TXSCALE_TABLE_SIZE 30
34
35/*RF REG LIST*/
36#define DM_REG_RF_MODE_11N 0x00
37#define DM_REG_RF_0B_11N 0x0B
38#define DM_REG_CHNBW_11N 0x18
39#define DM_REG_T_METER_11N 0x24
40#define DM_REG_RF_25_11N 0x25
41#define DM_REG_RF_26_11N 0x26
42#define DM_REG_RF_27_11N 0x27
43#define DM_REG_RF_2B_11N 0x2B
44#define DM_REG_RF_2C_11N 0x2C
45#define DM_REG_RXRF_A3_11N 0x3C
46#define DM_REG_T_METER_92D_11N 0x42
47#define DM_REG_T_METER_88E_11N 0x42
48
49/*BB REG LIST*/
50/*PAGE 8 */
51#define DM_REG_BB_CTRL_11N 0x800
52#define DM_REG_RF_PIN_11N 0x804
53#define DM_REG_PSD_CTRL_11N 0x808
54#define DM_REG_TX_ANT_CTRL_11N 0x80C
55#define DM_REG_BB_PWR_SAV5_11N 0x818
56#define DM_REG_CCK_RPT_FORMAT_11N 0x824
57#define DM_REG_RX_DEFUALT_A_11N 0x858
58#define DM_REG_RX_DEFUALT_B_11N 0x85A
59#define DM_REG_BB_PWR_SAV3_11N 0x85C
60#define DM_REG_ANTSEL_CTRL_11N 0x860
61#define DM_REG_RX_ANT_CTRL_11N 0x864
62#define DM_REG_PIN_CTRL_11N 0x870
63#define DM_REG_BB_PWR_SAV1_11N 0x874
64#define DM_REG_ANTSEL_PATH_11N 0x878
65#define DM_REG_BB_3WIRE_11N 0x88C
66#define DM_REG_SC_CNT_11N 0x8C4
67#define DM_REG_PSD_DATA_11N 0x8B4
68/*PAGE 9*/
69#define DM_REG_ANT_MAPPING1_11N 0x914
70#define DM_REG_ANT_MAPPING2_11N 0x918
71/*PAGE A*/
72#define DM_REG_CCK_ANTDIV_PARA1_11N 0xA00
73#define DM_REG_CCK_CCA_11N 0xA0A
74#define DM_REG_CCK_ANTDIV_PARA2_11N 0xA0C
75#define DM_REG_CCK_ANTDIV_PARA3_11N 0xA10
76#define DM_REG_CCK_ANTDIV_PARA4_11N 0xA14
77#define DM_REG_CCK_FILTER_PARA1_11N 0xA22
78#define DM_REG_CCK_FILTER_PARA2_11N 0xA23
79#define DM_REG_CCK_FILTER_PARA3_11N 0xA24
80#define DM_REG_CCK_FILTER_PARA4_11N 0xA25
81#define DM_REG_CCK_FILTER_PARA5_11N 0xA26
82#define DM_REG_CCK_FILTER_PARA6_11N 0xA27
83#define DM_REG_CCK_FILTER_PARA7_11N 0xA28
84#define DM_REG_CCK_FILTER_PARA8_11N 0xA29
85#define DM_REG_CCK_FA_RST_11N 0xA2C
86#define DM_REG_CCK_FA_MSB_11N 0xA58
87#define DM_REG_CCK_FA_LSB_11N 0xA5C
88#define DM_REG_CCK_CCA_CNT_11N 0xA60
89#define DM_REG_BB_PWR_SAV4_11N 0xA74
90/*PAGE B */
91#define DM_REG_LNA_SWITCH_11N 0xB2C
92#define DM_REG_PATH_SWITCH_11N 0xB30
93#define DM_REG_RSSI_CTRL_11N 0xB38
94#define DM_REG_CONFIG_ANTA_11N 0xB68
95#define DM_REG_RSSI_BT_11N 0xB9C
96/*PAGE C */
97#define DM_REG_OFDM_FA_HOLDC_11N 0xC00
98#define DM_REG_RX_PATH_11N 0xC04
99#define DM_REG_TRMUX_11N 0xC08
100#define DM_REG_OFDM_FA_RSTC_11N 0xC0C
101#define DM_REG_RXIQI_MATRIX_11N 0xC14
102#define DM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C
103#define DM_REG_IGI_A_11N 0xC50
104#define DM_REG_ANTDIV_PARA2_11N 0xC54
105#define DM_REG_IGI_B_11N 0xC58
106#define DM_REG_ANTDIV_PARA3_11N 0xC5C
107#define DM_REG_BB_PWR_SAV2_11N 0xC70
108#define DM_REG_RX_OFF_11N 0xC7C
109#define DM_REG_TXIQK_MATRIXA_11N 0xC80
110#define DM_REG_TXIQK_MATRIXB_11N 0xC88
111#define DM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94
112#define DM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C
113#define DM_REG_RXIQK_MATRIX_LSB_11N 0xCA0
114#define DM_REG_ANTDIV_PARA1_11N 0xCA4
115#define DM_REG_OFDM_FA_TYPE1_11N 0xCF0
116/*PAGE D */
117#define DM_REG_OFDM_FA_RSTD_11N 0xD00
118#define DM_REG_OFDM_FA_TYPE2_11N 0xDA0
119#define DM_REG_OFDM_FA_TYPE3_11N 0xDA4
120#define DM_REG_OFDM_FA_TYPE4_11N 0xDA8
121/*PAGE E */
122#define DM_REG_TXAGC_A_6_18_11N 0xE00
123#define DM_REG_TXAGC_A_24_54_11N 0xE04
124#define DM_REG_TXAGC_A_1_MCS32_11N 0xE08
125#define DM_REG_TXAGC_A_MCS0_3_11N 0xE10
126#define DM_REG_TXAGC_A_MCS4_7_11N 0xE14
127#define DM_REG_TXAGC_A_MCS8_11_11N 0xE18
128#define DM_REG_TXAGC_A_MCS12_15_11N 0xE1C
129#define DM_REG_FPGA0_IQK_11N 0xE28
130#define DM_REG_TXIQK_TONE_A_11N 0xE30
131#define DM_REG_RXIQK_TONE_A_11N 0xE34
132#define DM_REG_TXIQK_PI_A_11N 0xE38
133#define DM_REG_RXIQK_PI_A_11N 0xE3C
134#define DM_REG_TXIQK_11N 0xE40
135#define DM_REG_RXIQK_11N 0xE44
136#define DM_REG_IQK_AGC_PTS_11N 0xE48
137#define DM_REG_IQK_AGC_RSP_11N 0xE4C
138#define DM_REG_BLUETOOTH_11N 0xE6C
139#define DM_REG_RX_WAIT_CCA_11N 0xE70
140#define DM_REG_TX_CCK_RFON_11N 0xE74
141#define DM_REG_TX_CCK_BBON_11N 0xE78
142#define DM_REG_OFDM_RFON_11N 0xE7C
143#define DM_REG_OFDM_BBON_11N 0xE80
144#define DM_REG_TX2RX_11N 0xE84
145#define DM_REG_TX2TX_11N 0xE88
146#define DM_REG_RX_CCK_11N 0xE8C
147#define DM_REG_RX_OFDM_11N 0xED0
148#define DM_REG_RX_WAIT_RIFS_11N 0xED4
149#define DM_REG_RX2RX_11N 0xED8
150#define DM_REG_STANDBY_11N 0xEDC
151#define DM_REG_SLEEP_11N 0xEE0
152#define DM_REG_PMPD_ANAEN_11N 0xEEC
153
154/*MAC REG LIST*/
155#define DM_REG_BB_RST_11N 0x02
156#define DM_REG_ANTSEL_PIN_11N 0x4C
157#define DM_REG_EARLY_MODE_11N 0x4D0
158#define DM_REG_RSSI_MONITOR_11N 0x4FE
159#define DM_REG_EDCA_VO_11N 0x500
160#define DM_REG_EDCA_VI_11N 0x504
161#define DM_REG_EDCA_BE_11N 0x508
162#define DM_REG_EDCA_BK_11N 0x50C
163#define DM_REG_TXPAUSE_11N 0x522
164#define DM_REG_RESP_TX_11N 0x6D8
165#define DM_REG_ANT_TRAIN_PARA1_11N 0x7b0
166#define DM_REG_ANT_TRAIN_PARA2_11N 0x7b4
167
168/*DIG Related*/
169#define DM_BIT_IGI_11N 0x0000007F
170
171#define HAL_DM_DIG_DISABLE BIT(0)
172#define HAL_DM_HIPWR_DISABLE BIT(1)
173
174#define OFDM_TABLE_LENGTH 43
175#define CCK_TABLE_LENGTH 33
176
177#define OFDM_TABLE_SIZE 37
178#define CCK_TABLE_SIZE 33
179
180#define BW_AUTO_SWITCH_HIGH_LOW 25
181#define BW_AUTO_SWITCH_LOW_HIGH 30
182
183#define DM_DIG_THRESH_HIGH 40
184#define DM_DIG_THRESH_LOW 35
185
186#define DM_FALSEALARM_THRESH_LOW 400
187#define DM_FALSEALARM_THRESH_HIGH 1000
188
189#define DM_DIG_MAX 0x3e
190#define DM_DIG_MIN 0x1e
191
192#define DM_DIG_MAX_AP 0x32
193#define DM_DIG_MIN_AP 0x20
194
195#define DM_DIG_FA_UPPER 0x3e
196#define DM_DIG_FA_LOWER 0x1e
197#define DM_DIG_FA_TH0 0x200
198#define DM_DIG_FA_TH1 0x300
199#define DM_DIG_FA_TH2 0x400
200
201#define DM_DIG_BACKOFF_MAX 12
202#define DM_DIG_BACKOFF_MIN -4
203#define DM_DIG_BACKOFF_DEFAULT 10
204
205#define RXPATHSELECTION_DIFF_TH 18
206
207#define DM_RATR_STA_INIT 0
208#define DM_RATR_STA_HIGH 1
209#define DM_RATR_STA_MIDDLE 2
210#define DM_RATR_STA_LOW 3
211
212#define CTS2SELF_THVAL 30
213#define REGC38_TH 20
214
215#define TXHIGHPWRLEVEL_NORMAL 0
216#define TXHIGHPWRLEVEL_LEVEL1 1
217#define TXHIGHPWRLEVEL_LEVEL2 2
218#define TXHIGHPWRLEVEL_BT1 3
219#define TXHIGHPWRLEVEL_BT2 4
220
221#define DM_TYPE_BYFW 0
222#define DM_TYPE_BYDRIVER 1
223
224#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
225#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
226#define TXPWRTRACK_MAX_IDX 6
227
228/* Dynamic ATC switch */
229#define ATC_STATUS_OFF 0x0 /* enable */
230#define ATC_STATUS_ON 0x1 /* disable */
231#define CFO_THRESHOLD_XTAL 10 /* kHz */
232#define CFO_THRESHOLD_ATC 80 /* kHz */
233
234enum FAT_STATE {
235 FAT_NORMAL_STATE = 0,
236 FAT_TRAINING_STATE = 1,
237};
238
239enum tag_dynamic_init_gain_operation_type_definition {
240 DIG_TYPE_THRESH_HIGH = 0,
241 DIG_TYPE_THRESH_LOW = 1,
242 DIG_TYPE_BACKOFF = 2,
243 DIG_TYPE_RX_GAIN_MIN = 3,
244 DIG_TYPE_RX_GAIN_MAX = 4,
245 DIG_TYPE_ENABLE = 5,
246 DIG_TYPE_DISABLE = 6,
247 DIG_OP_TYPE_MAX
248};
249
250enum dm_1r_cca_e {
251 CCA_1R = 0,
252 CCA_2R = 1,
253 CCA_MAX = 2,
254};
255
256enum dm_rf_e {
257 RF_SAVE = 0,
258 RF_NORMAL = 1,
259 RF_MAX = 2,
260};
261
262enum dm_sw_ant_switch_e {
263 ANS_ANTENNA_B = 1,
264 ANS_ANTENNA_A = 2,
265 ANS_ANTENNA_MAX = 3,
266};
267
268enum dm_dig_ext_port_alg_e {
269 DIG_EXT_PORT_STAGE_0 = 0,
270 DIG_EXT_PORT_STAGE_1 = 1,
271 DIG_EXT_PORT_STAGE_2 = 2,
272 DIG_EXT_PORT_STAGE_3 = 3,
273 DIG_EXT_PORT_STAGE_MAX = 4,
274};
275
276enum dm_dig_connect_e {
277 DIG_STA_DISCONNECT = 0,
278 DIG_STA_CONNECT = 1,
279 DIG_STA_BEFORE_CONNECT = 2,
280 DIG_MULTISTA_DISCONNECT = 3,
281 DIG_MULTISTA_CONNECT = 4,
282 DIG_CONNECT_MAX
283};
284
285enum pwr_track_control_method {
286 BBSWING,
287 TXAGC
288};
289
290#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1)
291#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1)
292#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1)
293#define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1)
294#define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1)
295
296void rtl8723be_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, u8 *pdesc,
297 u32 mac_id);
298void rtl8723be_dm_ant_sel_statistics(struct ieee80211_hw *hw, u8 antsel_tr_mux,
299 u32 mac_id, u32 rx_pwdb_all);
300void rtl8723be_dm_fast_antenna_trainning_callback(unsigned long data);
301void rtl8723be_dm_init(struct ieee80211_hw *hw);
302void rtl8723be_dm_watchdog(struct ieee80211_hw *hw);
303void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi);
304void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw);
305void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
306void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type,
307 u8 *pdirection, u32 *poutwrite_val);
308void rtl8723be_dm_init_edca_turbo(struct ieee80211_hw *hw);
309
310#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
new file mode 100644
index 000000000000..f856be6fc138
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
@@ -0,0 +1,620 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
29#include "reg.h"
30#include "def.h"
31#include "fw.h"
32#include "../rtl8723com/fw_common.h"
33
34static bool _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
35 u8 boxnum)
36{
37 struct rtl_priv *rtlpriv = rtl_priv(hw);
38 u8 val_hmetfr;
39 bool result = false;
40
41 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
42 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
43 result = true;
44 return result;
45}
46
47static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
48 u32 cmd_len, u8 *p_cmdbuffer)
49{
50 struct rtl_priv *rtlpriv = rtl_priv(hw);
51 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
52 u8 boxnum;
53 u16 box_reg = 0, box_extreg = 0;
54 u8 u1b_tmp;
55 bool isfw_read = false;
56 u8 buf_index = 0;
57 bool bwrite_sucess = false;
58 u8 wait_h2c_limit = 100;
59 u8 wait_writeh2c_limit = 100;
60 u8 boxcontent[4], boxextcontent[4];
61 u32 h2c_waitcounter = 0;
62 unsigned long flag;
63 u8 idx;
64
65 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
66
67 while (true) {
68 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
69 if (rtlhal->h2c_setinprogress) {
70 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
71 "H2C set in progress! Wait to set.."
72 "element_id(%d).\n", element_id);
73
74 while (rtlhal->h2c_setinprogress) {
75 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
76 flag);
77 h2c_waitcounter++;
78 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
79 "Wait 100 us (%d times)...\n",
80 h2c_waitcounter);
81 udelay(100);
82
83 if (h2c_waitcounter > 1000)
84 return;
85 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
86 flag);
87 }
88 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
89 } else {
90 rtlhal->h2c_setinprogress = true;
91 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
92 break;
93 }
94 }
95 while (!bwrite_sucess) {
96 wait_writeh2c_limit--;
97 if (wait_writeh2c_limit == 0) {
98 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
99 "Write H2C fail because no trigger "
100 "for FW INT!\n");
101 break;
102 }
103 boxnum = rtlhal->last_hmeboxnum;
104 switch (boxnum) {
105 case 0:
106 box_reg = REG_HMEBOX_0;
107 box_extreg = REG_HMEBOX_EXT_0;
108 break;
109 case 1:
110 box_reg = REG_HMEBOX_1;
111 box_extreg = REG_HMEBOX_EXT_1;
112 break;
113 case 2:
114 box_reg = REG_HMEBOX_2;
115 box_extreg = REG_HMEBOX_EXT_2;
116 break;
117 case 3:
118 box_reg = REG_HMEBOX_3;
119 box_extreg = REG_HMEBOX_EXT_3;
120 break;
121 default:
122 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
123 "switch case not processed\n");
124 break;
125 }
126 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum);
127 while (!isfw_read) {
128 wait_h2c_limit--;
129 if (wait_h2c_limit == 0) {
130 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
131 "Wating too long for FW read "
132 "clear HMEBox(%d)!\n", boxnum);
133 break;
134 }
135 udelay(10);
136
137 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw,
138 boxnum);
139 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
140 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
141 "Wating for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
142 boxnum, u1b_tmp);
143 }
144 if (!isfw_read) {
145 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
146 "Write H2C register BOX[%d] fail!!!!! "
147 "Fw do not read.\n", boxnum);
148 break;
149 }
150 memset(boxcontent, 0, sizeof(boxcontent));
151 memset(boxextcontent, 0, sizeof(boxextcontent));
152 boxcontent[0] = element_id;
153 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
154 "Write element_id box_reg(%4x) = %2x\n",
155 box_reg, element_id);
156
157 switch (cmd_len) {
158 case 1:
159 case 2:
160 case 3:
161 /*boxcontent[0] &= ~(BIT(7));*/
162 memcpy((u8 *)(boxcontent) + 1,
163 p_cmdbuffer + buf_index, cmd_len);
164
165 for (idx = 0; idx < 4; idx++) {
166 rtl_write_byte(rtlpriv, box_reg + idx,
167 boxcontent[idx]);
168 }
169 break;
170 case 4:
171 case 5:
172 case 6:
173 case 7:
174 /*boxcontent[0] |= (BIT(7));*/
175 memcpy((u8 *)(boxextcontent),
176 p_cmdbuffer + buf_index+3, cmd_len-3);
177 memcpy((u8 *)(boxcontent) + 1,
178 p_cmdbuffer + buf_index, 3);
179
180 for (idx = 0; idx < 4; idx++) {
181 rtl_write_byte(rtlpriv, box_extreg + idx,
182 boxextcontent[idx]);
183 }
184 for (idx = 0; idx < 4; idx++) {
185 rtl_write_byte(rtlpriv, box_reg + idx,
186 boxcontent[idx]);
187 }
188 break;
189 default:
190 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
191 "switch case not process\n");
192 break;
193 }
194 bwrite_sucess = true;
195
196 rtlhal->last_hmeboxnum = boxnum + 1;
197 if (rtlhal->last_hmeboxnum == 4)
198 rtlhal->last_hmeboxnum = 0;
199
200 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
201 "pHalData->last_hmeboxnum = %d\n",
202 rtlhal->last_hmeboxnum);
203 }
204 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
205 rtlhal->h2c_setinprogress = false;
206 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
207
208 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
209}
210
211void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
212 u32 cmd_len, u8 *p_cmdbuffer)
213{
214 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
215 u32 tmp_cmdbuf[2];
216
217 if (!rtlhal->fw_ready) {
218 RT_ASSERT(false,
219 "return H2C cmd because of Fw download fail!!!\n");
220 return;
221 }
222 memset(tmp_cmdbuf, 0, 8);
223 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
224 _rtl8723be_fill_h2c_command(hw, element_id, cmd_len,
225 (u8 *)&tmp_cmdbuf);
226 return;
227}
228
229void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
230{
231 struct rtl_priv *rtlpriv = rtl_priv(hw);
232 u8 u1_h2c_set_pwrmode[H2C_8723BE_PWEMODE_LENGTH] = { 0 };
233 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
234 u8 rlbm, power_state = 0;
235 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
236
237 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
238 rlbm = 0;/*YJ, temp, 120316. FW now not support RLBM = 2.*/
239 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
240 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
241 (rtlpriv->mac80211.p2p) ?
242 ppsc->smart_ps : 1);
243 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
244 ppsc->reg_max_lps_awakeintvl);
245 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
246 if (mode == FW_PS_ACTIVE_MODE)
247 power_state |= FW_PWR_STATE_ACTIVE;
248 else
249 power_state |= FW_PWR_STATE_RF_OFF;
250 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
251
252 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
253 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
254 u1_h2c_set_pwrmode, H2C_8723BE_PWEMODE_LENGTH);
255 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_SETPWRMODE,
256 H2C_8723BE_PWEMODE_LENGTH,
257 u1_h2c_set_pwrmode);
258}
259
260static bool _rtl8723be_cmd_send_packet(struct ieee80211_hw *hw,
261 struct sk_buff *skb)
262{
263 struct rtl_priv *rtlpriv = rtl_priv(hw);
264 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
265 struct rtl8192_tx_ring *ring;
266 struct rtl_tx_desc *pdesc;
267 struct sk_buff *pskb = NULL;
268 u8 own;
269 unsigned long flags;
270
271 ring = &rtlpci->tx_ring[BEACON_QUEUE];
272
273 pskb = __skb_dequeue(&ring->queue);
274 if (pskb)
275 kfree_skb(pskb);
276
277 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
278
279 pdesc = &ring->desc[0];
280 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
281
282 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
283
284 __skb_queue_tail(&ring->queue, skb);
285
286 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
287
288 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
289
290 return true;
291}
292#define BEACON_PG 0 /* ->1 */
293#define PSPOLL_PG 2
294#define NULL_PG 3
295#define PROBERSP_PG 4 /* ->5 */
296
297#define TOTAL_RESERVED_PKT_LEN 768
298
299static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
300 /* page 0 beacon */
301 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
302 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
303 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
306 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
307 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
308 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
309 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
310 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
314 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
315 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
316 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
317
318 /* page 1 beacon */
319 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335
336 /* page 2 ps-poll */
337 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
338 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353
354 /* page 3 null */
355 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
356 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
357 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371
372 /* page 4 probe_resp */
373 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
374 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
375 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
376 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
377 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
378 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
379 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
380 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
381 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
382 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
383 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
387 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389
390 /* page 5 probe_resp */
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407};
408
409void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
410 bool dl_finished)
411{
412 struct rtl_priv *rtlpriv = rtl_priv(hw);
413 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
414 struct sk_buff *skb = NULL;
415
416 u32 totalpacketlen;
417 bool rtstatus;
418 u8 u1rsvdpageloc[5] = { 0 };
419 bool dlok = false;
420
421 u8 *beacon;
422 u8 *p_pspoll;
423 u8 *nullfunc;
424 u8 *p_probersp;
425 /*---------------------------------------------------------
426 * (1) beacon
427 *---------------------------------------------------------
428 */
429 beacon = &reserved_page_packet[BEACON_PG * 128];
430 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
431 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
432
433 /*-------------------------------------------------------
434 * (2) ps-poll
435 *-------------------------------------------------------
436 */
437 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
438 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
439 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
440 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
441
442 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
443
444 /*--------------------------------------------------------
445 * (3) null data
446 *--------------------------------------------------------
447 */
448 nullfunc = &reserved_page_packet[NULL_PG * 128];
449 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
450 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
451 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
452
453 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
454
455 /*---------------------------------------------------------
456 * (4) probe response
457 *---------------------------------------------------------
458 */
459 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
460 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
461 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
462 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
463
464 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
465
466 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
467
468 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
469 "rtl8723be_set_fw_rsvdpagepkt(): "
470 "HW_VAR_SET_TX_CMD: ALL\n",
471 &reserved_page_packet[0], totalpacketlen);
472 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
473 "rtl8723be_set_fw_rsvdpagepkt(): "
474 "HW_VAR_SET_TX_CMD: ALL\n", u1rsvdpageloc, 3);
475
476
477 skb = dev_alloc_skb(totalpacketlen);
478 memcpy((u8 *)skb_put(skb, totalpacketlen),
479 &reserved_page_packet, totalpacketlen);
480
481 rtstatus = _rtl8723be_cmd_send_packet(hw, skb);
482
483 if (rtstatus)
484 dlok = true;
485
486 if (dlok) {
487 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
488 "Set RSVD page location to Fw.\n");
489 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
490 u1rsvdpageloc, 3);
491 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_RSVDPAGE,
492 sizeof(u1rsvdpageloc), u1rsvdpageloc);
493 } else {
494 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
495 "Set RSVD page location to Fw FAIL!!!!!!.\n");
496 }
497}
498
499/*Should check FW support p2p or not.*/
500static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
501 u8 ctwindow)
502{
503 u8 u1_ctwindow_period[1] = {ctwindow};
504
505 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_P2P_PS_CTW_CMD, 1,
506 u1_ctwindow_period);
507}
508
509void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
510 u8 p2p_ps_state)
511{
512 struct rtl_priv *rtlpriv = rtl_priv(hw);
513 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
514 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
515 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
516 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
517 u8 i;
518 u16 ctwindow;
519 u32 start_time, tsf_low;
520
521 switch (p2p_ps_state) {
522 case P2P_PS_DISABLE:
523 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
524 memset(p2p_ps_offload, 0, sizeof(struct p2p_ps_offload_t));
525 break;
526 case P2P_PS_ENABLE:
527 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
528 /* update CTWindow value. */
529 if (p2pinfo->ctwindow > 0) {
530 p2p_ps_offload->ctwindow_en = 1;
531 ctwindow = p2pinfo->ctwindow;
532 rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow);
533 }
534 /* hw only support 2 set of NoA */
535 for (i = 0; i < p2pinfo->noa_num; i++) {
536 /* To control the register setting
537 * for which NOA
538 */
539 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
540 if (i == 0)
541 p2p_ps_offload->noa0_en = 1;
542 else
543 p2p_ps_offload->noa1_en = 1;
544
545 /* config P2P NoA Descriptor Register */
546 rtl_write_dword(rtlpriv, 0x5E0,
547 p2pinfo->noa_duration[i]);
548 rtl_write_dword(rtlpriv, 0x5E4,
549 p2pinfo->noa_interval[i]);
550
551 /*Get Current TSF value */
552 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
553
554 start_time = p2pinfo->noa_start_time[i];
555 if (p2pinfo->noa_count_type[i] != 1) {
556 while (start_time <= (tsf_low + (50 * 1024))) {
557 start_time += p2pinfo->noa_interval[i];
558 if (p2pinfo->noa_count_type[i] != 255)
559 p2pinfo->noa_count_type[i]--;
560 }
561 }
562 rtl_write_dword(rtlpriv, 0x5E8, start_time);
563 rtl_write_dword(rtlpriv, 0x5EC,
564 p2pinfo->noa_count_type[i]);
565 }
566 if ((p2pinfo->opp_ps == 1) ||
567 (p2pinfo->noa_num > 0)) {
568 /* rst p2p circuit */
569 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
570
571 p2p_ps_offload->offload_en = 1;
572
573 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
574 p2p_ps_offload->role = 1;
575 p2p_ps_offload->allstasleep = 0;
576 } else {
577 p2p_ps_offload->role = 0;
578 }
579 p2p_ps_offload->discovery = 0;
580 }
581 break;
582 case P2P_PS_SCAN:
583 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
584 p2p_ps_offload->discovery = 1;
585 break;
586 case P2P_PS_SCAN_DONE:
587 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
588 p2p_ps_offload->discovery = 0;
589 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
590 break;
591 default:
592 break;
593 }
594 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_P2P_PS_OFFLOAD, 1,
595 (u8 *)p2p_ps_offload);
596}
597
598void rtl8723be_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
599{
600 u8 u1_joinbssrpt_parm[1] = { 0 };
601
602 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
603
604 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_JOINBSSRPT, 1,
605 u1_joinbssrpt_parm);
606}
607
608void rtl8723be_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
609 u8 ap_offload_enable)
610{
611 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
612 u8 u1_apoffload_parm[H2C_8723BE_AP_OFFLOAD_LENGTH] = { 0 };
613
614 SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable);
615 SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->hiddenssid);
616 SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0);
617
618 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_AP_OFFLOAD,
619 H2C_8723BE_AP_OFFLOAD_LENGTH, u1_apoffload_parm);
620}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.h b/drivers/net/wireless/rtlwifi/rtl8723be/fw.h
new file mode 100644
index 000000000000..31eec281e446
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/fw.h
@@ -0,0 +1,248 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 * Larry Finger <Larry.Finger@lwfinger.net>
22 *
23 *****************************************************************************/
24
25#ifndef __RTL8723BE__FW__H__
26#define __RTL8723BE__FW__H__
27
28#define FW_8192C_SIZE 0x8000
29#define FW_8192C_START_ADDRESS 0x1000
30#define FW_8192C_END_ADDRESS 0x5FFF
31#define FW_8192C_PAGE_SIZE 4096
32#define FW_8192C_POLLING_DELAY 5
33#define FW_8192C_POLLING_TIMEOUT_COUNT 6000
34
35#define IS_FW_HEADER_EXIST(_pfwhdr) \
36 ((_pfwhdr->signature&0xFFF0) == 0x5300)
37#define USE_OLD_WOWLAN_DEBUG_FW 0
38
39#define H2C_8723BE_RSVDPAGE_LOC_LEN 5
40#define H2C_8723BE_PWEMODE_LENGTH 5
41#define H2C_8723BE_JOINBSSRPT_LENGTH 1
42#define H2C_8723BE_AP_OFFLOAD_LENGTH 3
43#define H2C_8723BE_WOWLAN_LENGTH 3
44#define H2C_8723BE_KEEP_ALIVE_CTRL_LENGTH 3
45#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
46#define H2C_8723BE_REMOTE_WAKE_CTRL_LEN 1
47#else
48#define H2C_8723BE_REMOTE_WAKE_CTRL_LEN 3
49#endif
50#define H2C_8723BE_AOAC_GLOBAL_INFO_LEN 2
51#define H2C_8723BE_AOAC_RSVDPAGE_LOC_LEN 7
52
53
54/* Fw PS state for RPWM.
55*BIT[2:0] = HW state
56*BIT[3] = Protocol PS state, 1: register active state , 0: register sleep state
57*BIT[4] = sub-state
58*/
59#define FW_PS_GO_ON BIT(0)
60#define FW_PS_TX_NULL BIT(1)
61#define FW_PS_RF_ON BIT(2)
62#define FW_PS_REGISTER_ACTIVE BIT(3)
63
64#define FW_PS_DPS BIT(0)
65#define FW_PS_LCLK (FW_PS_DPS)
66#define FW_PS_RF_OFF BIT(1)
67#define FW_PS_ALL_ON BIT(2)
68#define FW_PS_ST_ACTIVE BIT(3)
69#define FW_PS_ISR_ENABLE BIT(4)
70#define FW_PS_IMR_ENABLE BIT(5)
71
72
73#define FW_PS_ACK BIT(6)
74#define FW_PS_TOGGLE BIT(7)
75
76 /* 88E RPWM value*/
77 /* BIT[0] = 1: 32k, 0: 40M*/
78#define FW_PS_CLOCK_OFF BIT(0) /* 32k*/
79#define FW_PS_CLOCK_ON 0 /*40M*/
80
81#define FW_PS_STATE_MASK (0x0F)
82#define FW_PS_STATE_HW_MASK (0x07)
83/*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/
84#define FW_PS_STATE_INT_MASK (0x3F)
85
86#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x))
87#define FW_PS_STATE_HW(x) (FW_PS_STATE_HW_MASK & (x))
88#define FW_PS_STATE_INT(x) (FW_PS_STATE_INT_MASK & (x))
89#define FW_PS_ISR_VAL(x) ((x) & 0x70)
90#define FW_PS_IMR_MASK(x) ((x) & 0xDF)
91#define FW_PS_KEEP_IMR(x) ((x) & 0x20)
92
93
94#define FW_PS_STATE_S0 (FW_PS_DPS)
95#define FW_PS_STATE_S1 (FW_PS_LCLK)
96#define FW_PS_STATE_S2 (FW_PS_RF_OFF)
97#define FW_PS_STATE_S3 (FW_PS_ALL_ON)
98#define FW_PS_STATE_S4 ((FW_PS_ST_ACTIVE) | (FW_PS_ALL_ON))
99
100/* ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))*/
101#define FW_PS_STATE_ALL_ON_88E (FW_PS_CLOCK_ON)
102/* (FW_PS_RF_ON)*/
103#define FW_PS_STATE_RF_ON_88E (FW_PS_CLOCK_ON)
104/* 0x0*/
105#define FW_PS_STATE_RF_OFF_88E (FW_PS_CLOCK_ON)
106/* (FW_PS_STATE_RF_OFF)*/
107#define FW_PS_STATE_RF_OFF_LOW_PWR_88E (FW_PS_CLOCK_OFF)
108
109#define FW_PS_STATE_ALL_ON_92C (FW_PS_STATE_S4)
110#define FW_PS_STATE_RF_ON_92C (FW_PS_STATE_S3)
111#define FW_PS_STATE_RF_OFF_92C (FW_PS_STATE_S2)
112#define FW_PS_STATE_RF_OFF_LOW_PWR_92C (FW_PS_STATE_S1)
113
114
115/* For 88E H2C PwrMode Cmd ID 5.*/
116#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
117#define FW_PWR_STATE_RF_OFF 0
118
119#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK)
120#define FW_PS_IS_CLK_ON(x) ((x) & (FW_PS_RF_OFF | FW_PS_ALL_ON))
121#define FW_PS_IS_RF_ON(x) ((x) & (FW_PS_ALL_ON))
122#define FW_PS_IS_ACTIVE(x) ((x) & (FW_PS_ST_ACTIVE))
123#define FW_PS_IS_CPWM_INT(x) ((x) & 0x40)
124
125#define FW_CLR_PS_STATE(x) ((x) = ((x) & (0xF0)))
126
127#define IS_IN_LOW_POWER_STATE_88E(fwpsstate) \
128 (FW_PS_STATE(fwpsstate) == FW_PS_CLOCK_OFF)
129
130#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
131#define FW_PWR_STATE_RF_OFF 0
132
133#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0))
134
135#define SET_88E_H2CCMD_WOWLAN_FUNC_ENABLE(__ph2ccmd, __val) \
136 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val)
137#define SET_88E_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__ph2ccmd, __val) \
138 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val)
139#define SET_88E_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__ph2ccmd, __val) \
140 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 2, 1, __val)
141#define SET_88E_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__ph2ccmd, __val) \
142 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 3, 1, __val)
143#define SET_88E_H2CCMD_WOWLAN_ALL_PKT_DROP(__ph2ccmd, __val) \
144 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 4, 1, __val)
145#define SET_88E_H2CCMD_WOWLAN_GPIO_ACTIVE(__ph2ccmd, __val) \
146 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 5, 1, __val)
147#define SET_88E_H2CCMD_WOWLAN_REKEY_WAKE_UP(__ph2ccmd, __val) \
148 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 6, 1, __val)
149#define SET_88E_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__ph2ccmd, __val) \
150 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 7, 1, __val)
151#define SET_88E_H2CCMD_WOWLAN_GPIONUM(__ph2ccmd, __val) \
152 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
153#define SET_88E_H2CCMD_WOWLAN_GPIO_DURATION(__ph2ccmd, __val) \
154 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
155
156
157#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
158 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
159#define SET_H2CCMD_PWRMODE_PARM_RLBM(__ph2ccmd, __val) \
160 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 4, __val)
161#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
162 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 4, 4, __val)
163#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__ph2ccmd, __val) \
164 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
165#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__ph2ccmd, __val) \
166 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val)
167#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__ph2ccmd, __val) \
168 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+4, 0, 8, __val)
169#define GET_88E_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd) \
170 LE_BITS_TO_1BYTE(__ph2ccmd, 0, 8)
171
172#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
173 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
174#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
175 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
176#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
177 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
178#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
179 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
180
181/* AP_OFFLOAD */
182#define SET_H2CCMD_AP_OFFLOAD_ON(__ph2ccmd, __val) \
183 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
184#define SET_H2CCMD_AP_OFFLOAD_HIDDEN(__ph2ccmd, __val) \
185 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
186#define SET_H2CCMD_AP_OFFLOAD_DENYANY(__ph2ccmd, __val) \
187 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
188#define SET_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__ph2ccmd, __val) \
189 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val)
190
191/* Keep Alive Control*/
192#define SET_88E_H2CCMD_KEEP_ALIVE_ENABLE(__ph2ccmd, __val) \
193 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val)
194#define SET_88E_H2CCMD_KEEP_ALIVE_ACCPEPT_USER_DEFINED(__ph2ccmd, __val)\
195 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val)
196#define SET_88E_H2CCMD_KEEP_ALIVE_PERIOD(__ph2ccmd, __val) \
197 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
198
199/*REMOTE_WAKE_CTRL */
200#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_EN(__ph2ccmd, __val) \
201 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val)
202#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
203#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__ph2ccmd, __val)\
204 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val)
205#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__ph2ccmd, __val)\
206 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 2, 1, __val)
207#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__ph2ccmd, __val)\
208 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 3, 1, __val)
209#else
210#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_PAIRWISE_ENC_ALG(__ph2ccmd, __val)\
211 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
212#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GROUP_ENC_ALG(__ph2ccmd, __val) \
213 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
214#endif
215
216/* GTK_OFFLOAD */
217#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__ph2ccmd, __val)\
218 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
219#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__ph2ccmd, __val) \
220 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
221
222/* AOAC_RSVDPAGE_LOC */
223#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_REM_WAKE_CTRL_INFO(__ph2ccmd, __val)\
224 SET_BITS_TO_LE_1BYTE((__ph2ccmd), 0, 8, __val)
225#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__ph2ccmd, __val) \
226 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
227#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__ph2ccmd, __val) \
228 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
229#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__ph2ccmd, __val) \
230 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val)
231#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__ph2ccmd, __val) \
232 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+4, 0, 8, __val)
233
234void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
235void rtl8723be_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
236 u8 ap_offload_enable);
237void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
238 u32 cmd_len, u8 *p_cmdbuffer);
239void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw);
240void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
241 bool dl_finished);
242void rtl8723be_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
243int rtl8723be_download_fw(struct ieee80211_hw *hw,
244 bool buse_wake_on_wlan_fw);
245void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
246 u8 p2p_ps_state);
247
248#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
new file mode 100644
index 000000000000..7e70c7108d91
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
@@ -0,0 +1,2527 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../efuse.h"
28#include "../base.h"
29#include "../regd.h"
30#include "../cam.h"
31#include "../ps.h"
32#include "../pci.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "dm.h"
37#include "../rtl8723com/dm_common.h"
38#include "fw.h"
39#include "../rtl8723com/fw_common.h"
40#include "led.h"
41#include "hw.h"
42#include "pwrseq.h"
43#include "../btcoexist/rtl_btc.h"
44
45#define LLT_CONFIG 5
46
47static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
48{
49 struct rtl_priv *rtlpriv = rtl_priv(hw);
50 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
51 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
52
53 while (skb_queue_len(&ring->queue)) {
54 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
55 struct sk_buff *skb = __skb_dequeue(&ring->queue);
56
57 pci_unmap_single(rtlpci->pdev,
58 rtlpriv->cfg->ops->get_desc(
59 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
60 skb->len, PCI_DMA_TODEVICE);
61 kfree_skb(skb);
62 ring->idx = (ring->idx + 1) % ring->entries;
63 }
64}
65
66static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
67 u8 set_bits, u8 clear_bits)
68{
69 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
70 struct rtl_priv *rtlpriv = rtl_priv(hw);
71
72 rtlpci->reg_bcn_ctrl_val |= set_bits;
73 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
74
75 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
76}
77
78static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
79{
80 struct rtl_priv *rtlpriv = rtl_priv(hw);
81 u8 tmp1byte;
82
83 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
84 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
85 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
86 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
87 tmp1byte &= ~(BIT(0));
88 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
89}
90
91static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
92{
93 struct rtl_priv *rtlpriv = rtl_priv(hw);
94 u8 tmp1byte;
95
96 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
97 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
98 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
99 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
100 tmp1byte |= BIT(1);
101 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
102}
103
104static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
105{
106 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
107}
108
109static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
110{
111 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
112}
113
114static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
115 bool need_turn_off_ckk)
116{
117 struct rtl_priv *rtlpriv = rtl_priv(hw);
118 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
119 bool support_remote_wake_up;
120 u32 count = 0, isr_regaddr, content;
121 bool schedule_timer = need_turn_off_ckk;
122 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
123 (u8 *)(&support_remote_wake_up));
124
125 if (!rtlhal->fw_ready)
126 return;
127 if (!rtlpriv->psc.fw_current_inpsmode)
128 return;
129
130 while (1) {
131 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
132 if (rtlhal->fw_clk_change_in_progress) {
133 while (rtlhal->fw_clk_change_in_progress) {
134 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
135 count++;
136 udelay(100);
137 if (count > 1000)
138 return;
139 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
140 }
141 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
142 } else {
143 rtlhal->fw_clk_change_in_progress = false;
144 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
145 break;
146 }
147 }
148 if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
149 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
150 (u8 *)(&rpwm_val));
151 if (FW_PS_IS_ACK(rpwm_val)) {
152 isr_regaddr = REG_HISR;
153 content = rtl_read_dword(rtlpriv, isr_regaddr);
154 while (!(content & IMR_CPWM) && (count < 500)) {
155 udelay(50);
156 count++;
157 content = rtl_read_dword(rtlpriv, isr_regaddr);
158 }
159
160 if (content & IMR_CPWM) {
161 rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
162 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_88E;
163 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
164 "Receive CPWM INT!!! Set "
165 "pHalData->FwPSState = %X\n",
166 rtlhal->fw_ps_state);
167 }
168 }
169 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
170 rtlhal->fw_clk_change_in_progress = false;
171 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
172 if (schedule_timer) {
173 mod_timer(&rtlpriv->works.fw_clockoff_timer,
174 jiffies + MSECS(10));
175 }
176 } else {
177 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
178 rtlhal->fw_clk_change_in_progress = false;
179 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
180 }
181}
182
183static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
184{
185 struct rtl_priv *rtlpriv = rtl_priv(hw);
186 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
187 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
188 struct rtl8192_tx_ring *ring;
189 enum rf_pwrstate rtstate;
190 bool schedule_timer = false;
191 u8 queue;
192
193 if (!rtlhal->fw_ready)
194 return;
195 if (!rtlpriv->psc.fw_current_inpsmode)
196 return;
197 if (!rtlhal->allow_sw_to_change_hwclc)
198 return;
199 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
200 if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
201 return;
202
203 for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
204 ring = &rtlpci->tx_ring[queue];
205 if (skb_queue_len(&ring->queue)) {
206 schedule_timer = true;
207 break;
208 }
209 }
210 if (schedule_timer) {
211 mod_timer(&rtlpriv->works.fw_clockoff_timer,
212 jiffies + MSECS(10));
213 return;
214 }
215 if (FW_PS_STATE(rtlhal->fw_ps_state) !=
216 FW_PS_STATE_RF_OFF_LOW_PWR_88E) {
217 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
218 if (!rtlhal->fw_clk_change_in_progress) {
219 rtlhal->fw_clk_change_in_progress = true;
220 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
221 rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
222 rtl_write_word(rtlpriv, REG_HISR, 0x0100);
223 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
224 (u8 *)(&rpwm_val));
225 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
226 rtlhal->fw_clk_change_in_progress = false;
227 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
228 } else {
229 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
230 mod_timer(&rtlpriv->works.fw_clockoff_timer,
231 jiffies + MSECS(10));
232 }
233 }
234}
235
236static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
237{
238 u8 rpwm_val = 0;
239 rpwm_val |= (FW_PS_STATE_RF_OFF_88E | FW_PS_ACK);
240 _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
241}
242
243static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
244{
245 struct rtl_priv *rtlpriv = rtl_priv(hw);
246 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
247 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
248 bool fw_current_inps = false;
249 u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
250
251 if (ppsc->low_power_enable) {
252 rpwm_val = (FW_PS_STATE_ALL_ON_88E | FW_PS_ACK);/* RF on */
253 _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
254 rtlhal->allow_sw_to_change_hwclc = false;
255 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
256 (u8 *)(&fw_pwrmode));
257 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
258 (u8 *)(&fw_current_inps));
259 } else {
260 rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
261 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
262 (u8 *)(&rpwm_val));
263 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
264 (u8 *)(&fw_pwrmode));
265 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
266 (u8 *)(&fw_current_inps));
267 }
268}
269
270static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
271{
272 struct rtl_priv *rtlpriv = rtl_priv(hw);
273 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
274 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
275 bool fw_current_inps = true;
276 u8 rpwm_val;
277
278 if (ppsc->low_power_enable) {
279 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_88E; /* RF off */
280 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
281 (u8 *)(&fw_current_inps));
282 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
283 (u8 *)(&ppsc->fwctrl_psmode));
284 rtlhal->allow_sw_to_change_hwclc = true;
285 _rtl8723be_set_fw_clock_off(hw, rpwm_val);
286
287 } else {
288 rpwm_val = FW_PS_STATE_RF_OFF_88E; /* RF off */
289 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
290 (u8 *)(&fw_current_inps));
291 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
292 (u8 *)(&ppsc->fwctrl_psmode));
293 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
294 (u8 *)(&rpwm_val));
295 }
296}
297
298void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
299{
300 struct rtl_priv *rtlpriv = rtl_priv(hw);
301 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
302 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
303
304 switch (variable) {
305 case HW_VAR_RCR:
306 *((u32 *)(val)) = rtlpci->receive_config;
307 break;
308 case HW_VAR_RF_STATE:
309 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
310 break;
311 case HW_VAR_FWLPS_RF_ON: {
312 enum rf_pwrstate rfstate;
313 u32 val_rcr;
314
315 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
316 (u8 *)(&rfstate));
317 if (rfstate == ERFOFF) {
318 *((bool *)(val)) = true;
319 } else {
320 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
321 val_rcr &= 0x00070000;
322 if (val_rcr)
323 *((bool *)(val)) = false;
324 else
325 *((bool *)(val)) = true;
326 }
327 break; }
328 case HW_VAR_FW_PSMODE_STATUS:
329 *((bool *)(val)) = ppsc->fw_current_inpsmode;
330 break;
331 case HW_VAR_CORRECT_TSF: {
332 u64 tsf;
333 u32 *ptsf_low = (u32 *)&tsf;
334 u32 *ptsf_high = ((u32 *)&tsf) + 1;
335
336 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
337 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
338
339 *((u64 *)(val)) = tsf;
340
341 break; }
342 default:
343 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
344 "switch case not process %x\n", variable);
345 break;
346 }
347}
348
349void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
350{
351 struct rtl_priv *rtlpriv = rtl_priv(hw);
352 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
353 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
354 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
355 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
356 u8 idx;
357
358 switch (variable) {
359 case HW_VAR_ETHER_ADDR:
360 for (idx = 0; idx < ETH_ALEN; idx++)
361 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
362 break;
363 case HW_VAR_BASIC_RATE: {
364 u16 rate_cfg = ((u16 *)val)[0];
365 u8 rate_index = 0;
366 rate_cfg = rate_cfg & 0x15f;
367 rate_cfg |= 0x01;
368 rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
369 rtl_write_byte(rtlpriv, REG_RRSR + 1, (rate_cfg >> 8) & 0xff);
370 while (rate_cfg > 0x1) {
371 rate_cfg = (rate_cfg >> 1);
372 rate_index++;
373 }
374 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
375 break; }
376 case HW_VAR_BSSID:
377 for (idx = 0; idx < ETH_ALEN; idx++)
378 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
379 break;
380 case HW_VAR_SIFS:
381 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
382 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
383
384 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
385 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
386
387 if (!mac->ht_enable)
388 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
389 else
390 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
391 *((u16 *)val));
392 break;
393 case HW_VAR_SLOT_TIME: {
394 u8 e_aci;
395
396 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
397 "HW_VAR_SLOT_TIME %x\n", val[0]);
398
399 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
400
401 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
402 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
403 (u8 *)(&e_aci));
404 }
405 break; }
406 case HW_VAR_ACK_PREAMBLE: {
407 u8 reg_tmp;
408 u8 short_preamble = (bool) (*(u8 *)val);
409 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
410 if (short_preamble) {
411 reg_tmp |= 0x02;
412 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
413 } else {
414 reg_tmp &= 0xFD;
415 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
416 }
417 break; }
418 case HW_VAR_WPA_CONFIG:
419 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
420 break;
421 case HW_VAR_AMPDU_MIN_SPACE: {
422 u8 min_spacing_to_set;
423 u8 sec_min_space;
424
425 min_spacing_to_set = *((u8 *)val);
426 if (min_spacing_to_set <= 7) {
427 sec_min_space = 0;
428
429 if (min_spacing_to_set < sec_min_space)
430 min_spacing_to_set = sec_min_space;
431
432 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
433 min_spacing_to_set);
434
435 *val = min_spacing_to_set;
436
437 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
438 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
439 mac->min_space_cfg);
440
441 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
442 mac->min_space_cfg);
443 }
444 break; }
445 case HW_VAR_SHORTGI_DENSITY: {
446 u8 density_to_set;
447
448 density_to_set = *((u8 *)val);
449 mac->min_space_cfg |= (density_to_set << 3);
450
451 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
452 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
453 mac->min_space_cfg);
454
455 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
456 mac->min_space_cfg);
457 break; }
458 case HW_VAR_AMPDU_FACTOR: {
459 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
460 u8 factor_toset;
461 u8 *p_regtoset = NULL;
462 u8 index = 0;
463
464 p_regtoset = regtoset_normal;
465
466 factor_toset = *((u8 *)val);
467 if (factor_toset <= 3) {
468 factor_toset = (1 << (factor_toset + 2));
469 if (factor_toset > 0xf)
470 factor_toset = 0xf;
471
472 for (index = 0; index < 4; index++) {
473 if ((p_regtoset[index] & 0xf0) >
474 (factor_toset << 4))
475 p_regtoset[index] =
476 (p_regtoset[index] & 0x0f) |
477 (factor_toset << 4);
478
479 if ((p_regtoset[index] & 0x0f) > factor_toset)
480 p_regtoset[index] =
481 (p_regtoset[index] & 0xf0) |
482 (factor_toset);
483
484 rtl_write_byte(rtlpriv,
485 (REG_AGGLEN_LMT + index),
486 p_regtoset[index]);
487 }
488 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
489 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
490 factor_toset);
491 }
492 break; }
493 case HW_VAR_AC_PARAM: {
494 u8 e_aci = *((u8 *)val);
495 rtl8723_dm_init_edca_turbo(hw);
496
497 if (rtlpci->acm_method != EACMWAY2_SW)
498 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
499 (u8 *)(&e_aci));
500 break; }
501 case HW_VAR_ACM_CTRL: {
502 u8 e_aci = *((u8 *)val);
503 union aci_aifsn *p_aci_aifsn =
504 (union aci_aifsn *)(&(mac->ac[0].aifs));
505 u8 acm = p_aci_aifsn->f.acm;
506 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
507
508 acm_ctrl =
509 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
510
511 if (acm) {
512 switch (e_aci) {
513 case AC0_BE:
514 acm_ctrl |= ACMHW_BEQEN;
515 break;
516 case AC2_VI:
517 acm_ctrl |= ACMHW_VIQEN;
518 break;
519 case AC3_VO:
520 acm_ctrl |= ACMHW_VOQEN;
521 break;
522 default:
523 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
524 "HW_VAR_ACM_CTRL acm set "
525 "failed: eACI is %d\n", acm);
526 break;
527 }
528 } else {
529 switch (e_aci) {
530 case AC0_BE:
531 acm_ctrl &= (~ACMHW_BEQEN);
532 break;
533 case AC2_VI:
534 acm_ctrl &= (~ACMHW_VIQEN);
535 break;
536 case AC3_VO:
537 acm_ctrl &= (~ACMHW_BEQEN);
538 break;
539 default:
540 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
541 "switch case not process\n");
542 break;
543 }
544 }
545 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
546 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
547 "Write 0x%X\n", acm_ctrl);
548 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
549 break; }
550 case HW_VAR_RCR:
551 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
552 rtlpci->receive_config = ((u32 *)(val))[0];
553 break;
554 case HW_VAR_RETRY_LIMIT: {
555 u8 retry_limit = ((u8 *)(val))[0];
556
557 rtl_write_word(rtlpriv, REG_RL,
558 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
559 retry_limit << RETRY_LIMIT_LONG_SHIFT);
560 break; }
561 case HW_VAR_DUAL_TSF_RST:
562 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
563 break;
564 case HW_VAR_EFUSE_BYTES:
565 rtlefuse->efuse_usedbytes = *((u16 *)val);
566 break;
567 case HW_VAR_EFUSE_USAGE:
568 rtlefuse->efuse_usedpercentage = *((u8 *)val);
569 break;
570 case HW_VAR_IO_CMD:
571 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
572 break;
573 case HW_VAR_SET_RPWM: {
574 u8 rpwm_val;
575
576 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
577 udelay(1);
578
579 if (rpwm_val & BIT(7)) {
580 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
581 } else {
582 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
583 ((*(u8 *)val) | BIT(7)));
584 }
585 break; }
586 case HW_VAR_H2C_FW_PWRMODE:
587 rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
588 break;
589 case HW_VAR_FW_PSMODE_STATUS:
590 ppsc->fw_current_inpsmode = *((bool *)val);
591 break;
592 case HW_VAR_RESUME_CLK_ON:
593 _rtl8723be_set_fw_ps_rf_on(hw);
594 break;
595 case HW_VAR_FW_LPS_ACTION: {
596 bool enter_fwlps = *((bool *)val);
597
598 if (enter_fwlps)
599 _rtl8723be_fwlps_enter(hw);
600 else
601 _rtl8723be_fwlps_leave(hw);
602
603 break; }
604 case HW_VAR_H2C_FW_JOINBSSRPT: {
605 u8 mstatus = (*(u8 *)val);
606 u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
607 u8 count = 0, dlbcn_count = 0;
608 bool recover = false;
609
610 if (mstatus == RT_MEDIA_CONNECT) {
611 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
612
613 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
614 rtl_write_byte(rtlpriv, REG_CR + 1,
615 (tmp_regcr | BIT(0)));
616
617 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
618 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
619
620 tmp_reg422 = rtl_read_byte(rtlpriv,
621 REG_FWHW_TXQ_CTRL + 2);
622 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
623 tmp_reg422 & (~BIT(6)));
624 if (tmp_reg422 & BIT(6))
625 recover = true;
626
627 do {
628 bcnvalid_reg = rtl_read_byte(rtlpriv,
629 REG_TDECTRL + 2);
630 rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
631 (bcnvalid_reg | BIT(0)));
632 _rtl8723be_return_beacon_queue_skb(hw);
633
634 rtl8723be_set_fw_rsvdpagepkt(hw, 0);
635 bcnvalid_reg = rtl_read_byte(rtlpriv,
636 REG_TDECTRL + 2);
637 count = 0;
638 while (!(bcnvalid_reg & BIT(0)) && count < 20) {
639 count++;
640 udelay(10);
641 bcnvalid_reg = rtl_read_byte(rtlpriv,
642 REG_TDECTRL + 2);
643 }
644 dlbcn_count++;
645 } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
646
647 if (bcnvalid_reg & BIT(0))
648 rtl_write_byte(rtlpriv, REG_TDECTRL+2, BIT(0));
649
650 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
651 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
652
653 if (recover) {
654 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
655 tmp_reg422);
656 }
657 rtl_write_byte(rtlpriv, REG_CR + 1,
658 (tmp_regcr & ~(BIT(0))));
659 }
660 rtl8723be_set_fw_joinbss_report_cmd(hw, (*(u8 *)val));
661 break; }
662 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
663 rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
664 break;
665 case HW_VAR_AID: {
666 u16 u2btmp;
667 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
668 u2btmp &= 0xC000;
669 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
670 (u2btmp | mac->assoc_id));
671 break; }
672 case HW_VAR_CORRECT_TSF: {
673 u8 btype_ibss = ((u8 *)(val))[0];
674
675 if (btype_ibss)
676 _rtl8723be_stop_tx_beacon(hw);
677
678 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
679
680 rtl_write_dword(rtlpriv, REG_TSFTR,
681 (u32) (mac->tsf & 0xffffffff));
682 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
683 (u32) ((mac->tsf >> 32) & 0xffffffff));
684
685 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
686
687 if (btype_ibss)
688 _rtl8723be_resume_tx_beacon(hw);
689 break; }
690 case HW_VAR_KEEP_ALIVE: {
691 u8 array[2];
692 array[0] = 0xff;
693 array[1] = *((u8 *)val);
694 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL,
695 2, array);
696 break; }
697 default:
698 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
699 "switch case not process %x\n",
700 variable);
701 break;
702 }
703}
704
705static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
706{
707 struct rtl_priv *rtlpriv = rtl_priv(hw);
708 bool status = true;
709 int count = 0;
710 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
711 _LLT_OP(_LLT_WRITE_ACCESS);
712
713 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
714
715 do {
716 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
717 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
718 break;
719
720 if (count > POLLING_LLT_THRESHOLD) {
721 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
722 "Failed to polling write LLT done at "
723 "address %d!\n", address);
724 status = false;
725 break;
726 }
727 } while (++count);
728
729 return status;
730}
731
732static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
733{
734 struct rtl_priv *rtlpriv = rtl_priv(hw);
735 unsigned short i;
736 u8 txpktbuf_bndy;
737 u8 maxpage;
738 bool status;
739
740 maxpage = 255;
741 txpktbuf_bndy = 245;
742
743 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
744 (0x27FF0000 | txpktbuf_bndy));
745 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
746
747 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
748 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
749
750 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
751 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
752 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
753
754 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
755 status = _rtl8723be_llt_write(hw, i, i + 1);
756 if (!status)
757 return status;
758 }
759 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
760
761 if (!status)
762 return status;
763
764 for (i = txpktbuf_bndy; i < maxpage; i++) {
765 status = _rtl8723be_llt_write(hw, i, (i + 1));
766 if (!status)
767 return status;
768 }
769 status = _rtl8723be_llt_write(hw, maxpage, txpktbuf_bndy);
770 if (!status)
771 return status;
772
773 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
774 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
775
776 return true;
777}
778
779static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
780{
781 struct rtl_priv *rtlpriv = rtl_priv(hw);
782 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
783 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
784 struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0);
785
786 if (rtlpriv->rtlhal.up_first_time)
787 return;
788
789 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
790 rtl8723be_sw_led_on(hw, pled0);
791 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
792 rtl8723be_sw_led_on(hw, pled0);
793 else
794 rtl8723be_sw_led_off(hw, pled0);
795}
796
797static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
798{
799 struct rtl_priv *rtlpriv = rtl_priv(hw);
800 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
801
802 unsigned char bytetmp;
803 unsigned short wordtmp;
804 u16 retry = 0;
805 bool mac_func_enable;
806
807 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
808
809 /*Auto Power Down to CHIP-off State*/
810 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
811 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
812
813 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
814 if (bytetmp == 0xFF)
815 mac_func_enable = true;
816 else
817 mac_func_enable = false;
818
819 /* HW Power on sequence */
820 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
821 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
822 RTL8723_NIC_ENABLE_FLOW)) {
823 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
824 "init MAC Fail as power on failure\n");
825 return false;
826 }
827 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
828 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
829
830 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
831 bytetmp = 0xff;
832 rtl_write_byte(rtlpriv, REG_CR, bytetmp);
833 mdelay(2);
834
835 bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
836 bytetmp |= 0x7f;
837 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
838 mdelay(2);
839
840 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
841 if (bytetmp & BIT(0)) {
842 bytetmp = rtl_read_byte(rtlpriv, 0x7c);
843 bytetmp |= BIT(6);
844 rtl_write_byte(rtlpriv, 0x7c, bytetmp);
845 }
846 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
847 bytetmp |= BIT(3);
848 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp);
849 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
850 bytetmp &= ~BIT(4);
851 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp);
852
853 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+3);
854 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+3, bytetmp | 0x77);
855
856 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
857
858 if (!mac_func_enable) {
859 if (!_rtl8723be_llt_table_init(hw))
860 return false;
861 }
862 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
863 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
864
865 /* Enable FW Beamformer Interrupt */
866 bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
867 rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
868
869 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
870 wordtmp &= 0xf;
871 wordtmp |= 0xF5B1;
872 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
873
874 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
875 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
876 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
877 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
878
879 rtl_write_byte(rtlpriv, 0x4d0, 0x0);
880
881 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
882 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
883 DMA_BIT_MASK(32));
884 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
885 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
886 DMA_BIT_MASK(32));
887 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
888 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
889 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
890 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
891 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
892 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
893 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
894 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
895 rtl_write_dword(rtlpriv, REG_HQ_DESA,
896 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
897 DMA_BIT_MASK(32));
898 rtl_write_dword(rtlpriv, REG_RX_DESA,
899 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
900 DMA_BIT_MASK(32));
901
902 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
903 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
904
905 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
906
907 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
908 rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6));
909
910 rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
911
912 do {
913 retry++;
914 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
915 } while ((retry < 200) && (bytetmp & BIT(7)));
916
917 _rtl8723be_gen_refresh_led_state(hw);
918
919 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
920
921 bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
922 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & ~BIT(2));
923
924 return true;
925}
926
927static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
928{
929 struct rtl_priv *rtlpriv = rtl_priv(hw);
930 u8 reg_bw_opmode;
931 u32 reg_ratr, reg_prsr;
932
933 reg_bw_opmode = BW_OPMODE_20MHZ;
934 reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
935 RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
936 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
937
938 rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
939 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
940}
941
942static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
943{
944 struct rtl_priv *rtlpriv = rtl_priv(hw);
945 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
946
947 rtl_write_byte(rtlpriv, 0x34b, 0x93);
948 rtl_write_word(rtlpriv, 0x350, 0x870c);
949 rtl_write_byte(rtlpriv, 0x352, 0x1);
950
951 if (ppsc->support_backdoor)
952 rtl_write_byte(rtlpriv, 0x349, 0x1b);
953 else
954 rtl_write_byte(rtlpriv, 0x349, 0x03);
955
956 rtl_write_word(rtlpriv, 0x350, 0x2718);
957 rtl_write_byte(rtlpriv, 0x352, 0x1);
958}
959
960void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
961{
962 struct rtl_priv *rtlpriv = rtl_priv(hw);
963 u8 sec_reg_value;
964
965 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
966 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
967 rtlpriv->sec.pairwise_enc_algorithm,
968 rtlpriv->sec.group_enc_algorithm);
969
970 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
971 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
972 "not open hw encryption\n");
973 return;
974 }
975 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
976
977 if (rtlpriv->sec.use_defaultkey) {
978 sec_reg_value |= SCR_TXUSEDK;
979 sec_reg_value |= SCR_RXUSEDK;
980 }
981 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
982
983 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
984
985 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "The SECR-value %x\n",
986 sec_reg_value);
987
988 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
989}
990
991int rtl8723be_hw_init(struct ieee80211_hw *hw)
992{
993 struct rtl_priv *rtlpriv = rtl_priv(hw);
994 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
995 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
996 struct rtl_phy *rtlphy = &(rtlpriv->phy);
997 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
998 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
999 bool rtstatus = true;
1000 int err;
1001 u8 tmp_u1b;
1002 unsigned long flags;
1003
1004 /* reenable interrupts to not interfere with other devices */
1005 local_save_flags(flags);
1006 local_irq_enable();
1007
1008 rtlpriv->rtlhal.being_init_adapter = true;
1009 rtlpriv->intf_ops->disable_aspm(hw);
1010 rtstatus = _rtl8723be_init_mac(hw);
1011 if (!rtstatus) {
1012 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
1013 err = 1;
1014 goto exit;
1015 }
1016 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
1017 tmp_u1b &= 0x7F;
1018 rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b);
1019
1020 err = rtl8723_download_fw(hw, true);
1021 if (err) {
1022 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1023 "Failed to download FW. Init HW without FW now..\n");
1024 err = 1;
1025 rtlhal->fw_ready = false;
1026 goto exit;
1027 } else {
1028 rtlhal->fw_ready = true;
1029 }
1030 rtlhal->last_hmeboxnum = 0;
1031 rtl8723be_phy_mac_config(hw);
1032 /* because last function modify RCR, so we update
1033 * rcr var here, or TP will unstable for receive_config
1034 * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
1035 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1036 */
1037 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1038 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1039 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1040
1041 rtl8723be_phy_bb_config(hw);
1042 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
1043 rtl8723be_phy_rf_config(hw);
1044
1045 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1046 RF_CHNLBW, RFREG_OFFSET_MASK);
1047 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1048 RF_CHNLBW, RFREG_OFFSET_MASK);
1049 rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1050 rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1051
1052 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
1053 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
1054 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
1055 _rtl8723be_hw_configure(hw);
1056 rtl_cam_reset_all_entry(hw);
1057 rtl8723be_enable_hw_security_config(hw);
1058
1059 ppsc->rfpwr_state = ERFON;
1060
1061 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1062 _rtl8723be_enable_aspm_back_door(hw);
1063 rtlpriv->intf_ops->enable_aspm(hw);
1064
1065 rtl8723be_bt_hw_init(hw);
1066
1067 rtl_set_bbreg(hw, 0x64, BIT(20), 0);
1068 rtl_set_bbreg(hw, 0x64, BIT(24), 0);
1069
1070 rtl_set_bbreg(hw, 0x40, BIT(4), 0);
1071 rtl_set_bbreg(hw, 0x40, BIT(3), 1);
1072
1073 rtl_set_bbreg(hw, 0x944, BIT(0)|BIT(1), 0x3);
1074 rtl_set_bbreg(hw, 0x930, 0xff, 0x77);
1075
1076 rtl_set_bbreg(hw, 0x38, BIT(11), 0x1);
1077
1078 rtl_set_bbreg(hw, 0xb2c, 0xffffffff, 0x80000000);
1079
1080 if (ppsc->rfpwr_state == ERFON) {
1081 rtl8723be_dm_check_txpower_tracking(hw);
1082 rtl8723be_phy_lc_calibrate(hw);
1083 }
1084 tmp_u1b = efuse_read_1byte(hw, 0x1FA);
1085 if (!(tmp_u1b & BIT(0))) {
1086 rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
1087 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n");
1088 }
1089 if (!(tmp_u1b & BIT(4))) {
1090 tmp_u1b = rtl_read_byte(rtlpriv, 0x16);
1091 tmp_u1b &= 0x0F;
1092 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
1093 udelay(10);
1094 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
1095 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
1096 }
1097 rtl8723be_dm_init(hw);
1098exit:
1099 local_irq_restore(flags);
1100 rtlpriv->rtlhal.being_init_adapter = false;
1101 return err;
1102}
1103
1104static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1105{
1106 struct rtl_priv *rtlpriv = rtl_priv(hw);
1107 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1108 enum version_8723e version = VERSION_UNKNOWN;
1109 u8 count = 0;
1110 u8 value8;
1111 u32 value32;
1112
1113 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0);
1114
1115 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 2);
1116 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 2, value8 | BIT(0));
1117
1118 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1119 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, value8 | BIT(0));
1120
1121 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1122 while (((value8 & BIT(0))) && (count++ < 100)) {
1123 udelay(10);
1124 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1125 }
1126 count = 0;
1127 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1128 while ((value8 == 0) && (count++ < 50)) {
1129 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1130 mdelay(1);
1131 }
1132 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1133 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
1134 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unkown chip version\n");
1135 else
1136 version = (enum version_8723e) VERSION_TEST_CHIP_1T1R_8723B;
1137
1138 rtlphy->rf_type = RF_1T1R;
1139
1140 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1141 if (value8 >= 0x02)
1142 version |= BIT(3);
1143 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1144 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
1145 "RF_2T2R" : "RF_1T1R");
1146
1147 return version;
1148}
1149
1150static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1151 enum nl80211_iftype type)
1152{
1153 struct rtl_priv *rtlpriv = rtl_priv(hw);
1154 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1155 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1156
1157 rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0);
1158 RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
1159 "clear 0x550 when set HW_VAR_MEDIA_STATUS\n");
1160
1161 if (type == NL80211_IFTYPE_UNSPECIFIED ||
1162 type == NL80211_IFTYPE_STATION) {
1163 _rtl8723be_stop_tx_beacon(hw);
1164 _rtl8723be_enable_bcn_sub_func(hw);
1165 } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) {
1166 _rtl8723be_resume_tx_beacon(hw);
1167 _rtl8723be_disable_bcn_sub_func(hw);
1168 } else {
1169 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1170 "Set HW_VAR_MEDIA_STATUS: "
1171 "No such media status(%x).\n", type);
1172 }
1173 switch (type) {
1174 case NL80211_IFTYPE_UNSPECIFIED:
1175 bt_msr |= MSR_NOLINK;
1176 ledaction = LED_CTL_LINK;
1177 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1178 "Set Network type to NO LINK!\n");
1179 break;
1180 case NL80211_IFTYPE_ADHOC:
1181 bt_msr |= MSR_ADHOC;
1182 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1183 "Set Network type to Ad Hoc!\n");
1184 break;
1185 case NL80211_IFTYPE_STATION:
1186 bt_msr |= MSR_INFRA;
1187 ledaction = LED_CTL_LINK;
1188 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1189 "Set Network type to STA!\n");
1190 break;
1191 case NL80211_IFTYPE_AP:
1192 bt_msr |= MSR_AP;
1193 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1194 "Set Network type to AP!\n");
1195 break;
1196 default:
1197 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1198 "Network type %d not support!\n", type);
1199 return 1;
1200 }
1201 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1202 rtlpriv->cfg->ops->led_control(hw, ledaction);
1203 if ((bt_msr & 0x03) == MSR_AP)
1204 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1205 else
1206 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1207 return 0;
1208}
1209
1210void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1211{
1212 struct rtl_priv *rtlpriv = rtl_priv(hw);
1213 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1214 u32 reg_rcr = rtlpci->receive_config;
1215
1216 if (rtlpriv->psc.rfpwr_state != ERFON)
1217 return;
1218
1219 if (check_bssid) {
1220 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1221 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1222 (u8 *)(&reg_rcr));
1223 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1224 } else if (!check_bssid) {
1225 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1226 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1227 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1228 (u8 *)(&reg_rcr));
1229 }
1230}
1231
1232int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1233 enum nl80211_iftype type)
1234{
1235 struct rtl_priv *rtlpriv = rtl_priv(hw);
1236
1237 if (_rtl8723be_set_media_status(hw, type))
1238 return -EOPNOTSUPP;
1239
1240 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1241 if (type != NL80211_IFTYPE_AP)
1242 rtl8723be_set_check_bssid(hw, true);
1243 } else {
1244 rtl8723be_set_check_bssid(hw, false);
1245 }
1246 return 0;
1247}
1248
1249/* don't set REG_EDCA_BE_PARAM here
1250 * because mac80211 will send pkt when scan
1251 */
1252void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1253{
1254 struct rtl_priv *rtlpriv = rtl_priv(hw);
1255 rtl8723_dm_init_edca_turbo(hw);
1256 switch (aci) {
1257 case AC1_BK:
1258 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1259 break;
1260 case AC0_BE:
1261 break;
1262 case AC2_VI:
1263 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1264 break;
1265 case AC3_VO:
1266 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1267 break;
1268 default:
1269 RT_ASSERT(false, "invalid aci: %d !\n", aci);
1270 break;
1271 }
1272}
1273
1274void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1275{
1276 struct rtl_priv *rtlpriv = rtl_priv(hw);
1277 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1278
1279 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1280 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1281 rtlpci->irq_enabled = true;
1282 /* there are some C2H CMDs have been sent
1283 * before system interrupt is enabled, e.g., C2H, CPWM.
1284 * So we need to clear all C2H events that FW has notified,
1285 * otherwise FW won't schedule any commands anymore.
1286 */
1287 rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0);
1288 /*enable system interrupt*/
1289 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1290}
1291
1292void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1293{
1294 struct rtl_priv *rtlpriv = rtl_priv(hw);
1295 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1296
1297 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1298 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1299 rtlpci->irq_enabled = false;
1300 synchronize_irq(rtlpci->pdev->irq);
1301}
1302
1303static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1304{
1305 struct rtl_priv *rtlpriv = rtl_priv(hw);
1306 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1307 u8 u1b_tmp;
1308
1309 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1310 /* 1. Run LPS WL RFOFF flow */
1311 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1312 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1313
1314 /* 2. 0x1F[7:0] = 0 */
1315 /* turn off RF */
1316 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1317 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1318 rtlhal->fw_ready)
1319 rtl8723be_firmware_selfreset(hw);
1320
1321 /* Reset MCU. Suggested by Filen. */
1322 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1323 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1324
1325 /* g. MCUFWDL 0x80[1:0]= 0 */
1326 /* reset MCU ready status */
1327 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1328
1329 /* HW card disable configuration. */
1330 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1331 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1332
1333 /* Reset MCU IO Wrapper */
1334 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1335 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
1336 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1337 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1338
1339 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1340 /* lock ISO/CLK/Power control register */
1341 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1342}
1343
1344void rtl8723be_card_disable(struct ieee80211_hw *hw)
1345{
1346 struct rtl_priv *rtlpriv = rtl_priv(hw);
1347 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1348 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1349 enum nl80211_iftype opmode;
1350
1351 mac->link_state = MAC80211_NOLINK;
1352 opmode = NL80211_IFTYPE_UNSPECIFIED;
1353 _rtl8723be_set_media_status(hw, opmode);
1354 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1355 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1356 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1357 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1358 _rtl8723be_poweroff_adapter(hw);
1359
1360 /* after power off we should do iqk again */
1361 rtlpriv->phy.iqk_initialized = false;
1362}
1363
1364void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1365 u32 *p_inta, u32 *p_intb)
1366{
1367 struct rtl_priv *rtlpriv = rtl_priv(hw);
1368 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1369
1370 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1371 rtl_write_dword(rtlpriv, ISR, *p_inta);
1372
1373 *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1374 rtlpci->irq_mask[1];
1375 rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1376}
1377
1378void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1379{
1380 struct rtl_priv *rtlpriv = rtl_priv(hw);
1381 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1382 u16 bcn_interval, atim_window;
1383
1384 bcn_interval = mac->beacon_interval;
1385 atim_window = 2; /*FIX MERGE */
1386 rtl8723be_disable_interrupt(hw);
1387 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1388 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1389 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1390 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1391 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1392 rtl_write_byte(rtlpriv, 0x606, 0x30);
1393 rtl8723be_enable_interrupt(hw);
1394}
1395
1396void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1397{
1398 struct rtl_priv *rtlpriv = rtl_priv(hw);
1399 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1400 u16 bcn_interval = mac->beacon_interval;
1401
1402 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1403 "beacon_interval:%d\n", bcn_interval);
1404 rtl8723be_disable_interrupt(hw);
1405 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1406 rtl8723be_enable_interrupt(hw);
1407}
1408
1409void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1410 u32 add_msr, u32 rm_msr)
1411{
1412 struct rtl_priv *rtlpriv = rtl_priv(hw);
1413 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1414
1415 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1416 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1417
1418 if (add_msr)
1419 rtlpci->irq_mask[0] |= add_msr;
1420 if (rm_msr)
1421 rtlpci->irq_mask[0] &= (~rm_msr);
1422 rtl8723be_disable_interrupt(hw);
1423 rtl8723be_enable_interrupt(hw);
1424}
1425
1426static u8 _rtl8723be_get_chnl_group(u8 chnl)
1427{
1428 u8 group;
1429
1430 if (chnl < 3)
1431 group = 0;
1432 else if (chnl < 9)
1433 group = 1;
1434 else
1435 group = 2;
1436 return group;
1437}
1438
1439static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1440 struct txpower_info_2g *pw2g,
1441 struct txpower_info_5g *pw5g,
1442 bool autoload_fail, u8 *hwinfo)
1443{
1444 struct rtl_priv *rtlpriv = rtl_priv(hw);
1445 u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1446
1447 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1448 "hal_ReadPowerValueFromPROM8723BE(): "
1449 "PROMContent[0x%x]= 0x%x\n",
1450 (addr + 1), hwinfo[addr + 1]);
1451 if (0xFF == hwinfo[addr + 1]) /*YJ, add, 120316*/
1452 autoload_fail = true;
1453
1454 if (autoload_fail) {
1455 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1456 "auto load fail : Use Default value!\n");
1457 for (path = 0; path < MAX_RF_PATH; path++) {
1458 /* 2.4G default value */
1459 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1460 pw2g->index_cck_base[path][group] = 0x2D;
1461 pw2g->index_bw40_base[path][group] = 0x2D;
1462 }
1463 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1464 if (cnt == 0) {
1465 pw2g->bw20_diff[path][0] = 0x02;
1466 pw2g->ofdm_diff[path][0] = 0x04;
1467 } else {
1468 pw2g->bw20_diff[path][cnt] = 0xFE;
1469 pw2g->bw40_diff[path][cnt] = 0xFE;
1470 pw2g->cck_diff[path][cnt] = 0xFE;
1471 pw2g->ofdm_diff[path][cnt] = 0xFE;
1472 }
1473 }
1474 }
1475 return;
1476 }
1477 for (path = 0; path < MAX_RF_PATH; path++) {
1478 /*2.4G default value*/
1479 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1480 pw2g->index_cck_base[path][group] = hwinfo[addr++];
1481 if (pw2g->index_cck_base[path][group] == 0xFF)
1482 pw2g->index_cck_base[path][group] = 0x2D;
1483 }
1484 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1485 pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1486 if (pw2g->index_bw40_base[path][group] == 0xFF)
1487 pw2g->index_bw40_base[path][group] = 0x2D;
1488 }
1489 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1490 if (cnt == 0) {
1491 pw2g->bw40_diff[path][cnt] = 0;
1492 if (hwinfo[addr] == 0xFF) {
1493 pw2g->bw20_diff[path][cnt] = 0x02;
1494 } else {
1495 pw2g->bw20_diff[path][cnt] =
1496 (hwinfo[addr] & 0xf0) >> 4;
1497 /*bit sign number to 8 bit sign number*/
1498 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1499 pw2g->bw20_diff[path][cnt] |= 0xF0;
1500 }
1501 if (hwinfo[addr] == 0xFF) {
1502 pw2g->ofdm_diff[path][cnt] = 0x04;
1503 } else {
1504 pw2g->ofdm_diff[path][cnt] =
1505 (hwinfo[addr] & 0x0f);
1506 /*bit sign number to 8 bit sign number*/
1507 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1508 pw2g->ofdm_diff[path][cnt] |=
1509 0xF0;
1510 }
1511 pw2g->cck_diff[path][cnt] = 0;
1512 addr++;
1513 } else {
1514 if (hwinfo[addr] == 0xFF) {
1515 pw2g->bw40_diff[path][cnt] = 0xFE;
1516 } else {
1517 pw2g->bw40_diff[path][cnt] =
1518 (hwinfo[addr] & 0xf0) >> 4;
1519 if (pw2g->bw40_diff[path][cnt] & BIT(3))
1520 pw2g->bw40_diff[path][cnt] |=
1521 0xF0;
1522 }
1523 if (hwinfo[addr] == 0xFF) {
1524 pw2g->bw20_diff[path][cnt] = 0xFE;
1525 } else {
1526 pw2g->bw20_diff[path][cnt] =
1527 (hwinfo[addr] & 0x0f);
1528 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1529 pw2g->bw20_diff[path][cnt] |=
1530 0xF0;
1531 }
1532 addr++;
1533
1534 if (hwinfo[addr] == 0xFF) {
1535 pw2g->ofdm_diff[path][cnt] = 0xFE;
1536 } else {
1537 pw2g->ofdm_diff[path][cnt] =
1538 (hwinfo[addr] & 0xf0) >> 4;
1539 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1540 pw2g->ofdm_diff[path][cnt] |=
1541 0xF0;
1542 }
1543 if (hwinfo[addr] == 0xFF) {
1544 pw2g->cck_diff[path][cnt] = 0xFE;
1545 } else {
1546 pw2g->cck_diff[path][cnt] =
1547 (hwinfo[addr] & 0x0f);
1548 if (pw2g->cck_diff[path][cnt] & BIT(3))
1549 pw2g->cck_diff[path][cnt] |=
1550 0xF0;
1551 }
1552 addr++;
1553 }
1554 }
1555 /*5G default value*/
1556 for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1557 pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1558 if (pw5g->index_bw40_base[path][group] == 0xFF)
1559 pw5g->index_bw40_base[path][group] = 0xFE;
1560 }
1561 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1562 if (cnt == 0) {
1563 pw5g->bw40_diff[path][cnt] = 0;
1564
1565 if (hwinfo[addr] == 0xFF) {
1566 pw5g->bw20_diff[path][cnt] = 0;
1567 } else {
1568 pw5g->bw20_diff[path][0] =
1569 (hwinfo[addr] & 0xf0) >> 4;
1570 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1571 pw5g->bw20_diff[path][cnt] |=
1572 0xF0;
1573 }
1574 if (hwinfo[addr] == 0xFF) {
1575 pw5g->ofdm_diff[path][cnt] = 0x04;
1576 } else {
1577 pw5g->ofdm_diff[path][0] =
1578 (hwinfo[addr] & 0x0f);
1579 if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1580 pw5g->ofdm_diff[path][cnt] |=
1581 0xF0;
1582 }
1583 addr++;
1584 } else {
1585 if (hwinfo[addr] == 0xFF) {
1586 pw5g->bw40_diff[path][cnt] = 0xFE;
1587 } else {
1588 pw5g->bw40_diff[path][cnt] =
1589 (hwinfo[addr] & 0xf0) >> 4;
1590 if (pw5g->bw40_diff[path][cnt] & BIT(3))
1591 pw5g->bw40_diff[path][cnt] |= 0xF0;
1592 }
1593 if (hwinfo[addr] == 0xFF) {
1594 pw5g->bw20_diff[path][cnt] = 0xFE;
1595 } else {
1596 pw5g->bw20_diff[path][cnt] =
1597 (hwinfo[addr] & 0x0f);
1598 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1599 pw5g->bw20_diff[path][cnt] |= 0xF0;
1600 }
1601 addr++;
1602 }
1603 }
1604 if (hwinfo[addr] == 0xFF) {
1605 pw5g->ofdm_diff[path][1] = 0xFE;
1606 pw5g->ofdm_diff[path][2] = 0xFE;
1607 } else {
1608 pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1609 pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1610 }
1611 addr++;
1612
1613 if (hwinfo[addr] == 0xFF)
1614 pw5g->ofdm_diff[path][3] = 0xFE;
1615 else
1616 pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1617 addr++;
1618
1619 for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1620 if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1621 pw5g->ofdm_diff[path][cnt] = 0xFE;
1622 else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1623 pw5g->ofdm_diff[path][cnt] |= 0xF0;
1624 }
1625 }
1626}
1627
1628static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1629 bool autoload_fail,
1630 u8 *hwinfo)
1631{
1632 struct rtl_priv *rtlpriv = rtl_priv(hw);
1633 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1634 struct txpower_info_2g pw2g;
1635 struct txpower_info_5g pw5g;
1636 u8 rf_path, index;
1637 u8 i;
1638
1639 _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1640 hwinfo);
1641
1642 for (rf_path = 0; rf_path < 2; rf_path++) {
1643 for (i = 0; i < 14; i++) {
1644 index = _rtl8723be_get_chnl_group(i+1);
1645
1646 rtlefuse->txpwrlevel_cck[rf_path][i] =
1647 pw2g.index_cck_base[rf_path][index];
1648 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1649 pw2g.index_bw40_base[rf_path][index];
1650 }
1651 for (i = 0; i < MAX_TX_COUNT; i++) {
1652 rtlefuse->txpwr_ht20diff[rf_path][i] =
1653 pw2g.bw20_diff[rf_path][i];
1654 rtlefuse->txpwr_ht40diff[rf_path][i] =
1655 pw2g.bw40_diff[rf_path][i];
1656 rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1657 pw2g.ofdm_diff[rf_path][i];
1658 }
1659 for (i = 0; i < 14; i++) {
1660 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1661 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = "
1662 "[0x%x / 0x%x ]\n", rf_path, i,
1663 rtlefuse->txpwrlevel_cck[rf_path][i],
1664 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1665 }
1666 }
1667 if (!autoload_fail)
1668 rtlefuse->eeprom_thermalmeter =
1669 hwinfo[EEPROM_THERMAL_METER_88E];
1670 else
1671 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1672
1673 if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
1674 rtlefuse->apk_thermalmeterignore = true;
1675 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1676 }
1677 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1678 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1679 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1680
1681 if (!autoload_fail) {
1682 rtlefuse->eeprom_regulatory =
1683 hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
1684 if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
1685 rtlefuse->eeprom_regulatory = 0;
1686 } else {
1687 rtlefuse->eeprom_regulatory = 0;
1688 }
1689 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1690 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1691}
1692
1693static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
1694 bool pseudo_test)
1695{
1696 struct rtl_priv *rtlpriv = rtl_priv(hw);
1697 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1698 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1699 u16 i, usvalue;
1700 u8 hwinfo[HWSET_MAX_SIZE];
1701 u16 eeprom_id;
1702 bool is_toshiba_smid1 = false;
1703 bool is_toshiba_smid2 = false;
1704 bool is_samsung_smid = false;
1705 bool is_lenovo_smid = false;
1706 u16 toshiba_smid1[] = {
1707 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
1708 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
1709 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
1710 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
1711 };
1712 u16 toshiba_smid2[] = {
1713 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
1714 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
1715 };
1716 u16 samsung_smid[] = {
1717 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
1718 0x8193, 0x9191, 0x9192, 0x9193
1719 };
1720 u16 lenovo_smid[] = {
1721 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
1722 };
1723
1724 if (pseudo_test) {
1725 /* needs to be added */
1726 return;
1727 }
1728 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
1729 rtl_efuse_shadow_map_update(hw);
1730
1731 memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
1732 HWSET_MAX_SIZE);
1733 } else if (rtlefuse->epromtype == EEPROM_93C46) {
1734 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1735 "RTL819X Not boot from eeprom, check it !!");
1736 }
1737 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
1738 hwinfo, HWSET_MAX_SIZE);
1739
1740 eeprom_id = *((u16 *)&hwinfo[0]);
1741 if (eeprom_id != RTL8723BE_EEPROM_ID) {
1742 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1743 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
1744 rtlefuse->autoload_failflag = true;
1745 } else {
1746 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1747 rtlefuse->autoload_failflag = false;
1748 }
1749 if (rtlefuse->autoload_failflag)
1750 return;
1751
1752 rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
1753 rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
1754 rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
1755 rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
1756 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1757 "EEPROMId = 0x%4x\n", eeprom_id);
1758 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1759 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1760 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1761 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1762 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1763 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1764 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1765 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1766
1767 for (i = 0; i < 6; i += 2) {
1768 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1769 *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
1770 }
1771 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "dev_addr: %pM\n",
1772 rtlefuse->dev_addr);
1773
1774 /*parse xtal*/
1775 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
1776 if (rtlefuse->crystalcap == 0xFF)
1777 rtlefuse->crystalcap = 0x20;
1778
1779 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
1780 hwinfo);
1781
1782 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
1783 rtlefuse->autoload_failflag,
1784 hwinfo);
1785
1786 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
1787 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1788 rtlefuse->txpwr_fromeprom = true;
1789 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
1790
1791 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1792 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
1793
1794 /* set channel plan to world wide 13 */
1795 rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
1796
1797 if (rtlhal->oem_id == RT_CID_DEFAULT) {
1798 /* Does this one have a Toshiba SMID from group 1? */
1799 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
1800 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
1801 is_toshiba_smid1 = true;
1802 break;
1803 }
1804 }
1805 /* Does this one have a Toshiba SMID from group 2? */
1806 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
1807 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
1808 is_toshiba_smid2 = true;
1809 break;
1810 }
1811 }
1812 /* Does this one have a Samsung SMID? */
1813 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
1814 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
1815 is_samsung_smid = true;
1816 break;
1817 }
1818 }
1819 /* Does this one have a Lenovo SMID? */
1820 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
1821 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
1822 is_lenovo_smid = true;
1823 break;
1824 }
1825 }
1826 switch (rtlefuse->eeprom_oemid) {
1827 case EEPROM_CID_DEFAULT:
1828 if (rtlefuse->eeprom_did == 0x8176) {
1829 if (rtlefuse->eeprom_svid == 0x10EC &&
1830 is_toshiba_smid1) {
1831 rtlhal->oem_id = RT_CID_TOSHIBA;
1832 } else if (rtlefuse->eeprom_svid == 0x1025) {
1833 rtlhal->oem_id = RT_CID_819X_ACER;
1834 } else if (rtlefuse->eeprom_svid == 0x10EC &&
1835 is_samsung_smid) {
1836 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
1837 } else if (rtlefuse->eeprom_svid == 0x10EC &&
1838 is_lenovo_smid) {
1839 rtlhal->oem_id = RT_CID_819X_LENOVO;
1840 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
1841 rtlefuse->eeprom_smid == 0x8197) ||
1842 (rtlefuse->eeprom_svid == 0x10EC &&
1843 rtlefuse->eeprom_smid == 0x9196)) {
1844 rtlhal->oem_id = RT_CID_819X_CLEVO;
1845 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
1846 rtlefuse->eeprom_smid == 0x8194) ||
1847 (rtlefuse->eeprom_svid == 0x1028 &&
1848 rtlefuse->eeprom_smid == 0x8198) ||
1849 (rtlefuse->eeprom_svid == 0x1028 &&
1850 rtlefuse->eeprom_smid == 0x9197) ||
1851 (rtlefuse->eeprom_svid == 0x1028 &&
1852 rtlefuse->eeprom_smid == 0x9198)) {
1853 rtlhal->oem_id = RT_CID_819X_DELL;
1854 } else if ((rtlefuse->eeprom_svid == 0x103C &&
1855 rtlefuse->eeprom_smid == 0x1629)) {
1856 rtlhal->oem_id = RT_CID_819X_HP;
1857 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
1858 rtlefuse->eeprom_smid == 0x2315)) {
1859 rtlhal->oem_id = RT_CID_819X_QMI;
1860 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
1861 rtlefuse->eeprom_smid == 0x8203)) {
1862 rtlhal->oem_id = RT_CID_819X_PRONETS;
1863 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
1864 rtlefuse->eeprom_smid == 0x84B5)) {
1865 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
1866 } else {
1867 rtlhal->oem_id = RT_CID_DEFAULT;
1868 }
1869 } else if (rtlefuse->eeprom_did == 0x8178) {
1870 if (rtlefuse->eeprom_svid == 0x10EC &&
1871 is_toshiba_smid2)
1872 rtlhal->oem_id = RT_CID_TOSHIBA;
1873 else if (rtlefuse->eeprom_svid == 0x1025)
1874 rtlhal->oem_id = RT_CID_819X_ACER;
1875 else if ((rtlefuse->eeprom_svid == 0x10EC &&
1876 rtlefuse->eeprom_smid == 0x8186))
1877 rtlhal->oem_id = RT_CID_819X_PRONETS;
1878 else if ((rtlefuse->eeprom_svid == 0x1043 &&
1879 rtlefuse->eeprom_smid == 0x84B6))
1880 rtlhal->oem_id =
1881 RT_CID_819X_EDIMAX_ASUS;
1882 else
1883 rtlhal->oem_id = RT_CID_DEFAULT;
1884 } else {
1885 rtlhal->oem_id = RT_CID_DEFAULT;
1886 }
1887 break;
1888 case EEPROM_CID_TOSHIBA:
1889 rtlhal->oem_id = RT_CID_TOSHIBA;
1890 break;
1891 case EEPROM_CID_CCX:
1892 rtlhal->oem_id = RT_CID_CCX;
1893 break;
1894 case EEPROM_CID_QMI:
1895 rtlhal->oem_id = RT_CID_819X_QMI;
1896 break;
1897 case EEPROM_CID_WHQL:
1898 break;
1899 default:
1900 rtlhal->oem_id = RT_CID_DEFAULT;
1901 break;
1902 }
1903 }
1904}
1905
1906static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
1907{
1908 struct rtl_priv *rtlpriv = rtl_priv(hw);
1909 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1910 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1911
1912 pcipriv->ledctl.led_opendrain = true;
1913 switch (rtlhal->oem_id) {
1914 case RT_CID_819X_HP:
1915 pcipriv->ledctl.led_opendrain = true;
1916 break;
1917 case RT_CID_819X_LENOVO:
1918 case RT_CID_DEFAULT:
1919 case RT_CID_TOSHIBA:
1920 case RT_CID_CCX:
1921 case RT_CID_819X_ACER:
1922 case RT_CID_WHQL:
1923 default:
1924 break;
1925 }
1926 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1927 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
1928}
1929
1930void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
1931{
1932 struct rtl_priv *rtlpriv = rtl_priv(hw);
1933 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1934 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1935 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1936 u8 tmp_u1b;
1937
1938 rtlhal->version = _rtl8723be_read_chip_version(hw);
1939 if (get_rf_type(rtlphy) == RF_1T1R)
1940 rtlpriv->dm.rfpath_rxenable[0] = true;
1941 else
1942 rtlpriv->dm.rfpath_rxenable[0] =
1943 rtlpriv->dm.rfpath_rxenable[1] = true;
1944 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
1945 rtlhal->version);
1946 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
1947 if (tmp_u1b & BIT(4)) {
1948 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
1949 rtlefuse->epromtype = EEPROM_93C46;
1950 } else {
1951 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
1952 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1953 }
1954 if (tmp_u1b & BIT(5)) {
1955 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1956 rtlefuse->autoload_failflag = false;
1957 _rtl8723be_read_adapter_info(hw, false);
1958 } else {
1959 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
1960 }
1961 _rtl8723be_hal_customized_behavior(hw);
1962}
1963
1964static void rtl8723be_update_hal_rate_table(struct ieee80211_hw *hw,
1965 struct ieee80211_sta *sta)
1966{
1967 struct rtl_priv *rtlpriv = rtl_priv(hw);
1968 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1969 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1970 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1971 u32 ratr_value;
1972 u8 ratr_index = 0;
1973 u8 nmode = mac->ht_enable;
1974 u8 mimo_ps = IEEE80211_SMPS_OFF;
1975 u16 shortgi_rate;
1976 u32 tmp_ratr_value;
1977 u8 curtxbw_40mhz = mac->bw_40;
1978 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1979 1 : 0;
1980 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1981 1 : 0;
1982 enum wireless_mode wirelessmode = mac->mode;
1983
1984 if (rtlhal->current_bandtype == BAND_ON_5G)
1985 ratr_value = sta->supp_rates[1] << 4;
1986 else
1987 ratr_value = sta->supp_rates[0];
1988 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1989 ratr_value = 0xfff;
1990 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1991 sta->ht_cap.mcs.rx_mask[0] << 12);
1992 switch (wirelessmode) {
1993 case WIRELESS_MODE_B:
1994 if (ratr_value & 0x0000000c)
1995 ratr_value &= 0x0000000d;
1996 else
1997 ratr_value &= 0x0000000f;
1998 break;
1999 case WIRELESS_MODE_G:
2000 ratr_value &= 0x00000FF5;
2001 break;
2002 case WIRELESS_MODE_N_24G:
2003 case WIRELESS_MODE_N_5G:
2004 nmode = 1;
2005 if (mimo_ps == IEEE80211_SMPS_STATIC) {
2006 ratr_value &= 0x0007F005;
2007 } else {
2008 u32 ratr_mask;
2009
2010 if (get_rf_type(rtlphy) == RF_1T2R ||
2011 get_rf_type(rtlphy) == RF_1T1R)
2012 ratr_mask = 0x000ff005;
2013 else
2014 ratr_mask = 0x0f0ff005;
2015 ratr_value &= ratr_mask;
2016 }
2017 break;
2018 default:
2019 if (rtlphy->rf_type == RF_1T2R)
2020 ratr_value &= 0x000ff0ff;
2021 else
2022 ratr_value &= 0x0f0ff0ff;
2023 break;
2024 }
2025 if ((rtlpriv->btcoexist.bt_coexistence) &&
2026 (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) &&
2027 (rtlpriv->btcoexist.bt_cur_state) &&
2028 (rtlpriv->btcoexist.bt_ant_isolation) &&
2029 ((rtlpriv->btcoexist.bt_service == BT_SCO) ||
2030 (rtlpriv->btcoexist.bt_service == BT_BUSY)))
2031 ratr_value &= 0x0fffcfc0;
2032 else
2033 ratr_value &= 0x0FFFFFFF;
2034
2035 if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
2036 (!curtxbw_40mhz && curshortgi_20mhz))) {
2037 ratr_value |= 0x10000000;
2038 tmp_ratr_value = (ratr_value >> 12);
2039
2040 for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2041 if ((1 << shortgi_rate) & tmp_ratr_value)
2042 break;
2043 }
2044 shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2045 (shortgi_rate << 4) | (shortgi_rate);
2046 }
2047 rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
2048
2049 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2050 "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0));
2051}
2052
2053static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2054 u8 rate_index)
2055{
2056 u8 ret = 0;
2057
2058 switch (rate_index) {
2059 case RATR_INX_WIRELESS_NGB:
2060 ret = 1;
2061 break;
2062 case RATR_INX_WIRELESS_N:
2063 case RATR_INX_WIRELESS_NG:
2064 ret = 5;
2065 break;
2066 case RATR_INX_WIRELESS_NB:
2067 ret = 3;
2068 break;
2069 case RATR_INX_WIRELESS_GB:
2070 ret = 6;
2071 break;
2072 case RATR_INX_WIRELESS_G:
2073 ret = 7;
2074 break;
2075 case RATR_INX_WIRELESS_B:
2076 ret = 8;
2077 break;
2078 default:
2079 ret = 0;
2080 break;
2081 }
2082 return ret;
2083}
2084
2085static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2086 struct ieee80211_sta *sta,
2087 u8 rssi_level)
2088{
2089 struct rtl_priv *rtlpriv = rtl_priv(hw);
2090 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2091 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2092 struct rtl_sta_info *sta_entry = NULL;
2093 u32 ratr_bitmap;
2094 u8 ratr_index;
2095 u8 curtxbw_40mhz = (sta->ht_cap.cap &
2096 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
2097 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2098 1 : 0;
2099 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2100 1 : 0;
2101 enum wireless_mode wirelessmode = 0;
2102 bool shortgi = false;
2103 u8 rate_mask[7];
2104 u8 macid = 0;
2105 u8 mimo_ps = IEEE80211_SMPS_OFF;
2106
2107 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2108 wirelessmode = sta_entry->wireless_mode;
2109 if (mac->opmode == NL80211_IFTYPE_STATION ||
2110 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2111 curtxbw_40mhz = mac->bw_40;
2112 else if (mac->opmode == NL80211_IFTYPE_AP ||
2113 mac->opmode == NL80211_IFTYPE_ADHOC)
2114 macid = sta->aid + 1;
2115
2116 ratr_bitmap = sta->supp_rates[0];
2117
2118 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2119 ratr_bitmap = 0xfff;
2120
2121 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2122 sta->ht_cap.mcs.rx_mask[0] << 12);
2123 switch (wirelessmode) {
2124 case WIRELESS_MODE_B:
2125 ratr_index = RATR_INX_WIRELESS_B;
2126 if (ratr_bitmap & 0x0000000c)
2127 ratr_bitmap &= 0x0000000d;
2128 else
2129 ratr_bitmap &= 0x0000000f;
2130 break;
2131 case WIRELESS_MODE_G:
2132 ratr_index = RATR_INX_WIRELESS_GB;
2133
2134 if (rssi_level == 1)
2135 ratr_bitmap &= 0x00000f00;
2136 else if (rssi_level == 2)
2137 ratr_bitmap &= 0x00000ff0;
2138 else
2139 ratr_bitmap &= 0x00000ff5;
2140 break;
2141 case WIRELESS_MODE_A:
2142 ratr_index = RATR_INX_WIRELESS_A;
2143 ratr_bitmap &= 0x00000ff0;
2144 break;
2145 case WIRELESS_MODE_N_24G:
2146 case WIRELESS_MODE_N_5G:
2147 ratr_index = RATR_INX_WIRELESS_NGB;
2148
2149 if (mimo_ps == IEEE80211_SMPS_STATIC ||
2150 mimo_ps == IEEE80211_SMPS_DYNAMIC) {
2151 if (rssi_level == 1)
2152 ratr_bitmap &= 0x00070000;
2153 else if (rssi_level == 2)
2154 ratr_bitmap &= 0x0007f000;
2155 else
2156 ratr_bitmap &= 0x0007f005;
2157 } else {
2158 if (rtlphy->rf_type == RF_1T1R) {
2159 if (curtxbw_40mhz) {
2160 if (rssi_level == 1)
2161 ratr_bitmap &= 0x000f0000;
2162 else if (rssi_level == 2)
2163 ratr_bitmap &= 0x000ff000;
2164 else
2165 ratr_bitmap &= 0x000ff015;
2166 } else {
2167 if (rssi_level == 1)
2168 ratr_bitmap &= 0x000f0000;
2169 else if (rssi_level == 2)
2170 ratr_bitmap &= 0x000ff000;
2171 else
2172 ratr_bitmap &= 0x000ff005;
2173 }
2174 } else {
2175 if (curtxbw_40mhz) {
2176 if (rssi_level == 1)
2177 ratr_bitmap &= 0x0f8f0000;
2178 else if (rssi_level == 2)
2179 ratr_bitmap &= 0x0f8ff000;
2180 else
2181 ratr_bitmap &= 0x0f8ff015;
2182 } else {
2183 if (rssi_level == 1)
2184 ratr_bitmap &= 0x0f8f0000;
2185 else if (rssi_level == 2)
2186 ratr_bitmap &= 0x0f8ff000;
2187 else
2188 ratr_bitmap &= 0x0f8ff005;
2189 }
2190 }
2191 }
2192 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2193 (!curtxbw_40mhz && curshortgi_20mhz)) {
2194 if (macid == 0)
2195 shortgi = true;
2196 else if (macid == 1)
2197 shortgi = false;
2198 }
2199 break;
2200 default:
2201 ratr_index = RATR_INX_WIRELESS_NGB;
2202
2203 if (rtlphy->rf_type == RF_1T2R)
2204 ratr_bitmap &= 0x000ff0ff;
2205 else
2206 ratr_bitmap &= 0x0f0ff0ff;
2207 break;
2208 }
2209 sta_entry->ratr_index = ratr_index;
2210
2211 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2212 "ratr_bitmap :%x\n", ratr_bitmap);
2213 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28);
2214 rate_mask[0] = macid;
2215 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
2216 (shortgi ? 0x80 : 0x00);
2217 rate_mask[2] = curtxbw_40mhz;
2218 /* if (prox_priv->proxim_modeinfo->power_output > 0)
2219 * rate_mask[2] |= BIT(6);
2220 */
2221
2222 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2223 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2224 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2225 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2226
2227 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2228 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2229 ratr_index, ratr_bitmap,
2230 rate_mask[0], rate_mask[1],
2231 rate_mask[2], rate_mask[3],
2232 rate_mask[4], rate_mask[5],
2233 rate_mask[6]);
2234 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_RA_MASK, 7, rate_mask);
2235 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2236}
2237
2238void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2239 struct ieee80211_sta *sta,
2240 u8 rssi_level)
2241{
2242 struct rtl_priv *rtlpriv = rtl_priv(hw);
2243 if (rtlpriv->dm.useramask)
2244 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
2245 else
2246 rtl8723be_update_hal_rate_table(hw, sta);
2247}
2248
2249void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2250{
2251 struct rtl_priv *rtlpriv = rtl_priv(hw);
2252 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2253 u16 sifs_timer;
2254
2255 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
2256 (u8 *)&mac->slot_time);
2257 if (!mac->ht_enable)
2258 sifs_timer = 0x0a0a;
2259 else
2260 sifs_timer = 0x0e0e;
2261 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2262}
2263
2264bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2265{
2266 struct rtl_priv *rtlpriv = rtl_priv(hw);
2267 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2268 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2269 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2270 u8 u1tmp;
2271 bool actuallyset = false;
2272
2273 if (rtlpriv->rtlhal.being_init_adapter)
2274 return false;
2275
2276 if (ppsc->swrf_processing)
2277 return false;
2278
2279 spin_lock(&rtlpriv->locks.rf_ps_lock);
2280 if (ppsc->rfchange_inprogress) {
2281 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2282 return false;
2283 } else {
2284 ppsc->rfchange_inprogress = true;
2285 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2286 }
2287 cur_rfstate = ppsc->rfpwr_state;
2288
2289 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2290 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2291
2292 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2293
2294 if (rtlphy->polarity_ctl)
2295 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2296 else
2297 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2298
2299 if (ppsc->hwradiooff &&
2300 (e_rfpowerstate_toset == ERFON)) {
2301 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2302 "GPIOChangeRF - HW Radio ON, RF ON\n");
2303
2304 e_rfpowerstate_toset = ERFON;
2305 ppsc->hwradiooff = false;
2306 actuallyset = true;
2307 } else if (!ppsc->hwradiooff &&
2308 (e_rfpowerstate_toset == ERFOFF)) {
2309 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2310 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2311
2312 e_rfpowerstate_toset = ERFOFF;
2313 ppsc->hwradiooff = true;
2314 actuallyset = true;
2315 }
2316 if (actuallyset) {
2317 spin_lock(&rtlpriv->locks.rf_ps_lock);
2318 ppsc->rfchange_inprogress = false;
2319 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2320 } else {
2321 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2322 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2323
2324 spin_lock(&rtlpriv->locks.rf_ps_lock);
2325 ppsc->rfchange_inprogress = false;
2326 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2327 }
2328 *valid = 1;
2329 return !ppsc->hwradiooff;
2330}
2331
2332void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2333 u8 *p_macaddr, bool is_group, u8 enc_algo,
2334 bool is_wepkey, bool clear_all)
2335{
2336 struct rtl_priv *rtlpriv = rtl_priv(hw);
2337 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2338 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2339 u8 *macaddr = p_macaddr;
2340 u32 entry_id = 0;
2341 bool is_pairwise = false;
2342
2343 static u8 cam_const_addr[4][6] = {
2344 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2345 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2346 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2347 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2348 };
2349 static u8 cam_const_broad[] = {
2350 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2351 };
2352
2353 if (clear_all) {
2354 u8 idx = 0;
2355 u8 cam_offset = 0;
2356 u8 clear_number = 5;
2357
2358 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2359
2360 for (idx = 0; idx < clear_number; idx++) {
2361 rtl_cam_mark_invalid(hw, cam_offset + idx);
2362 rtl_cam_empty_entry(hw, cam_offset + idx);
2363
2364 if (idx < 5) {
2365 memset(rtlpriv->sec.key_buf[idx], 0,
2366 MAX_KEY_LEN);
2367 rtlpriv->sec.key_len[idx] = 0;
2368 }
2369 }
2370 } else {
2371 switch (enc_algo) {
2372 case WEP40_ENCRYPTION:
2373 enc_algo = CAM_WEP40;
2374 break;
2375 case WEP104_ENCRYPTION:
2376 enc_algo = CAM_WEP104;
2377 break;
2378 case TKIP_ENCRYPTION:
2379 enc_algo = CAM_TKIP;
2380 break;
2381 case AESCCMP_ENCRYPTION:
2382 enc_algo = CAM_AES;
2383 break;
2384 default:
2385 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2386 "switch case not process\n");
2387 enc_algo = CAM_TKIP;
2388 break;
2389 }
2390
2391 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2392 macaddr = cam_const_addr[key_index];
2393 entry_id = key_index;
2394 } else {
2395 if (is_group) {
2396 macaddr = cam_const_broad;
2397 entry_id = key_index;
2398 } else {
2399 if (mac->opmode == NL80211_IFTYPE_AP) {
2400 entry_id = rtl_cam_get_free_entry(hw,
2401 p_macaddr);
2402 if (entry_id >= TOTAL_CAM_ENTRY) {
2403 RT_TRACE(rtlpriv, COMP_SEC,
2404 DBG_EMERG,
2405 "Can not find free"
2406 " hw security cam "
2407 "entry\n");
2408 return;
2409 }
2410 } else {
2411 entry_id = CAM_PAIRWISE_KEY_POSITION;
2412 }
2413 key_index = PAIRWISE_KEYIDX;
2414 is_pairwise = true;
2415 }
2416 }
2417 if (rtlpriv->sec.key_len[key_index] == 0) {
2418 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2419 "delete one entry, entry_id is %d\n",
2420 entry_id);
2421 if (mac->opmode == NL80211_IFTYPE_AP)
2422 rtl_cam_del_entry(hw, p_macaddr);
2423 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2424 } else {
2425 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2426 "add one entry\n");
2427 if (is_pairwise) {
2428 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2429 "set Pairwise key\n");
2430
2431 rtl_cam_add_one_entry(hw, macaddr, key_index,
2432 entry_id, enc_algo,
2433 CAM_CONFIG_NO_USEDK,
2434 rtlpriv->sec.key_buf[key_index]);
2435 } else {
2436 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2437 "set group key\n");
2438
2439 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2440 rtl_cam_add_one_entry(hw,
2441 rtlefuse->dev_addr,
2442 PAIRWISE_KEYIDX,
2443 CAM_PAIRWISE_KEY_POSITION,
2444 enc_algo,
2445 CAM_CONFIG_NO_USEDK,
2446 rtlpriv->sec.key_buf
2447 [entry_id]);
2448 }
2449 rtl_cam_add_one_entry(hw, macaddr, key_index,
2450 entry_id, enc_algo,
2451 CAM_CONFIG_NO_USEDK,
2452 rtlpriv->sec.key_buf[entry_id]);
2453 }
2454 }
2455 }
2456}
2457
2458void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2459 bool auto_load_fail, u8 *hwinfo)
2460{
2461 struct rtl_priv *rtlpriv = rtl_priv(hw);
2462 u8 value;
2463 u32 tmpu_32;
2464
2465 if (!auto_load_fail) {
2466 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2467 if (tmpu_32 & BIT(18))
2468 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2469 else
2470 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2471 value = hwinfo[RF_OPTION4];
2472 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2473 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
2474 } else {
2475 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2476 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2477 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
2478 }
2479}
2480
2481void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2482{
2483 struct rtl_priv *rtlpriv = rtl_priv(hw);
2484
2485 /* 0:Low, 1:High, 2:From Efuse. */
2486 rtlpriv->btcoexist.reg_bt_iso = 2;
2487 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2488 rtlpriv->btcoexist.reg_bt_sco = 3;
2489 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2490 rtlpriv->btcoexist.reg_bt_sco = 0;
2491}
2492
2493void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2494{
2495 struct rtl_priv *rtlpriv = rtl_priv(hw);
2496
2497 if (rtlpriv->cfg->ops->get_btc_status())
2498 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
2499}
2500
2501void rtl8723be_suspend(struct ieee80211_hw *hw)
2502{
2503}
2504
2505void rtl8723be_resume(struct ieee80211_hw *hw)
2506{
2507}
2508
2509/* Turn on AAP (RCR:bit 0) for promicuous mode. */
2510void rtl8723be_allow_all_destaddr(struct ieee80211_hw *hw, bool allow_all_da,
2511 bool write_into_reg)
2512{
2513 struct rtl_priv *rtlpriv = rtl_priv(hw);
2514 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2515
2516 if (allow_all_da) /* Set BIT0 */
2517 rtlpci->receive_config |= RCR_AAP;
2518 else /* Clear BIT0 */
2519 rtlpci->receive_config &= ~RCR_AAP;
2520
2521 if (write_into_reg)
2522 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
2523
2524 RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
2525 "receive_config = 0x%08X, write_into_reg =%d\n",
2526 rtlpci->receive_config, write_into_reg);
2527}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.h b/drivers/net/wireless/rtlwifi/rtl8723be/hw.h
new file mode 100644
index 000000000000..b7449a9b57e4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.h
@@ -0,0 +1,64 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_HW_H__
27#define __RTL8723BE_HW_H__
28
29void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
30void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw);
31
32void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
33 u32 *p_inta, u32 *p_intb);
34int rtl8723be_hw_init(struct ieee80211_hw *hw);
35void rtl8723be_card_disable(struct ieee80211_hw *hw);
36void rtl8723be_enable_interrupt(struct ieee80211_hw *hw);
37void rtl8723be_disable_interrupt(struct ieee80211_hw *hw);
38int rtl8723be_set_network_type(struct ieee80211_hw *hw,
39 enum nl80211_iftype type);
40void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
41void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci);
42void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw);
43void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw);
44void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
45 u32 add_msr, u32 rm_msr);
46void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
47void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
48 struct ieee80211_sta *sta,
49 u8 rssi_level);
50void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw);
51bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
52void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw);
53void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
54 u8 *p_macaddr, bool is_group, u8 enc_algo,
55 bool is_wepkey, bool clear_all);
56void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
57 bool autoload_fail, u8 *hwinfo);
58void rtl8723be_bt_reg_init(struct ieee80211_hw *hw);
59void rtl8723be_bt_hw_init(struct ieee80211_hw *hw);
60void rtl8723be_suspend(struct ieee80211_hw *hw);
61void rtl8723be_resume(struct ieee80211_hw *hw);
62void rtl8723be_allow_all_destaddr(struct ieee80211_hw *hw, bool allow_all_da,
63 bool write_into_reg);
64#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/led.c b/drivers/net/wireless/rtlwifi/rtl8723be/led.c
new file mode 100644
index 000000000000..cb931a38dc48
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/led.c
@@ -0,0 +1,153 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "reg.h"
29#include "led.h"
30
31static void _rtl8723be_init_led(struct ieee80211_hw *hw, struct rtl_led *pled,
32 enum rtl_led_pin ledpin)
33{
34 pled->hw = hw;
35 pled->ledpin = ledpin;
36 pled->ledon = false;
37}
38
39void rtl8723be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
40{
41 u8 ledcfg;
42 struct rtl_priv *rtlpriv = rtl_priv(hw);
43
44 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
45 "LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin);
46
47 switch (pled->ledpin) {
48 case LED_PIN_GPIO0:
49 break;
50 case LED_PIN_LED0:
51 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
52 ledcfg &= ~BIT(6);
53 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5));
54 break;
55 case LED_PIN_LED1:
56 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
57 rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
58 break;
59 default:
60 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
61 "switch case not process\n");
62 break;
63 }
64 pled->ledon = true;
65}
66
67void rtl8723be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
68{
69 struct rtl_priv *rtlpriv = rtl_priv(hw);
70 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
71 u8 ledcfg;
72
73 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
74 "LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin);
75
76 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
77
78 switch (pled->ledpin) {
79 case LED_PIN_GPIO0:
80 break;
81 case LED_PIN_LED0:
82 ledcfg &= 0xf0;
83 if (pcipriv->ledctl.led_opendrain) {
84 ledcfg &= 0x90; /* Set to software control. */
85 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
86 ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
87 ledcfg &= 0xFE;
88 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
89 } else {
90 ledcfg &= ~BIT(6);
91 rtl_write_byte(rtlpriv, REG_LEDCFG2,
92 (ledcfg | BIT(3) | BIT(5)));
93 }
94 break;
95 case LED_PIN_LED1:
96 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
97 ledcfg &= 0x10; /* Set to software control. */
98 rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3));
99
100 break;
101 default:
102 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
103 "switch case not processed\n");
104 break;
105 }
106 pled->ledon = false;
107}
108
109void rtl8723be_init_sw_leds(struct ieee80211_hw *hw)
110{
111 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
112 _rtl8723be_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
113 _rtl8723be_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
114}
115
116static void _rtl8723be_sw_led_control(struct ieee80211_hw *hw,
117 enum led_ctl_mode ledaction)
118{
119 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
120 struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0);
121 switch (ledaction) {
122 case LED_CTL_POWER_ON:
123 case LED_CTL_LINK:
124 case LED_CTL_NO_LINK:
125 rtl8723be_sw_led_on(hw, pled0);
126 break;
127 case LED_CTL_POWER_OFF:
128 rtl8723be_sw_led_off(hw, pled0);
129 break;
130 default:
131 break;
132 }
133}
134
135void rtl8723be_led_control(struct ieee80211_hw *hw,
136 enum led_ctl_mode ledaction)
137{
138 struct rtl_priv *rtlpriv = rtl_priv(hw);
139 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
140
141 if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
142 (ledaction == LED_CTL_TX ||
143 ledaction == LED_CTL_RX ||
144 ledaction == LED_CTL_SITE_SURVEY ||
145 ledaction == LED_CTL_LINK ||
146 ledaction == LED_CTL_NO_LINK ||
147 ledaction == LED_CTL_START_TO_LINK ||
148 ledaction == LED_CTL_POWER_ON)) {
149 return;
150 }
151 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction);
152 _rtl8723be_sw_led_control(hw, ledaction);
153}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/led.h b/drivers/net/wireless/rtlwifi/rtl8723be/led.h
new file mode 100644
index 000000000000..c57de379ee8d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/led.h
@@ -0,0 +1,35 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_LED_H__
27#define __RTL8723BE_LED_H__
28
29void rtl8723be_init_sw_leds(struct ieee80211_hw *hw);
30void rtl8723be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
31void rtl8723be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
32void rtl8723be_led_control(struct ieee80211_hw *hw,
33 enum led_ctl_mode ledaction);
34
35#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
new file mode 100644
index 000000000000..1575ef9ece9f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
@@ -0,0 +1,2156 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../ps.h"
29#include "../core.h"
30#include "reg.h"
31#include "def.h"
32#include "phy.h"
33#include "../rtl8723com/phy_common.h"
34#include "rf.h"
35#include "dm.h"
36#include "table.h"
37#include "trx.h"
38
39static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
40static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
41 u8 configtype);
42static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
43 u8 channel, u8 *stage,
44 u8 *step, u32 *delay);
45static bool _rtl8723be_check_condition(struct ieee80211_hw *hw,
46 const u32 condition)
47{
48 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
49 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
50 u32 _board = rtlefuse->board_type; /*need efuse define*/
51 u32 _interface = rtlhal->interface;
52 u32 _platform = 0x08;/*SupportPlatform */
53 u32 cond = condition;
54
55 if (condition == 0xCDCDCDCD)
56 return true;
57
58 cond = condition & 0xFF;
59 if ((_board & cond) == 0 && cond != 0x1F)
60 return false;
61
62 cond = condition & 0xFF00;
63 cond = cond >> 8;
64 if ((_interface & cond) == 0 && cond != 0x07)
65 return false;
66
67 cond = condition & 0xFF0000;
68 cond = cond >> 16;
69 if ((_platform & cond) == 0 && cond != 0x0F)
70 return false;
71 return true;
72}
73
74static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
75{
76 struct rtl_priv *rtlpriv = rtl_priv(hw);
77 u32 i;
78 u32 arraylength;
79 u32 *ptrarray;
80
81 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
82 arraylength = RTL8723BEMAC_1T_ARRAYLEN;
83 ptrarray = RTL8723BEMAC_1T_ARRAY;
84 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
85 "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength);
86 for (i = 0; i < arraylength; i = i + 2)
87 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
88 return true;
89}
90
91static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
92 u8 configtype)
93{
94 #define READ_NEXT_PAIR(v1, v2, i) \
95 do { \
96 i += 2; \
97 v1 = array_table[i];\
98 v2 = array_table[i+1]; \
99 } while (0)
100
101 int i;
102 u32 *array_table;
103 u16 arraylen;
104 struct rtl_priv *rtlpriv = rtl_priv(hw);
105 u32 v1 = 0, v2 = 0;
106
107 if (configtype == BASEBAND_CONFIG_PHY_REG) {
108 arraylen = RTL8723BEPHY_REG_1TARRAYLEN;
109 array_table = RTL8723BEPHY_REG_1TARRAY;
110
111 for (i = 0; i < arraylen; i = i + 2) {
112 v1 = array_table[i];
113 v2 = array_table[i+1];
114 if (v1 < 0xcdcdcdcd) {
115 rtl_bb_delay(hw, v1, v2);
116 } else {/*This line is the start line of branch.*/
117 if (!_rtl8723be_check_condition(hw, array_table[i])) {
118 /*Discard the following (offset, data) pairs*/
119 READ_NEXT_PAIR(v1, v2, i);
120 while (v2 != 0xDEAD &&
121 v2 != 0xCDEF &&
122 v2 != 0xCDCD &&
123 i < arraylen - 2) {
124 READ_NEXT_PAIR(v1, v2, i);
125 }
126 i -= 2; /* prevent from for-loop += 2*/
127 /* Configure matched pairs and
128 * skip to end of if-else.
129 */
130 } else {
131 READ_NEXT_PAIR(v1, v2, i);
132 while (v2 != 0xDEAD &&
133 v2 != 0xCDEF &&
134 v2 != 0xCDCD &&
135 i < arraylen - 2) {
136 rtl_bb_delay(hw,
137 v1, v2);
138 READ_NEXT_PAIR(v1, v2, i);
139 }
140
141 while (v2 != 0xDEAD && i < arraylen - 2)
142 READ_NEXT_PAIR(v1, v2, i);
143 }
144 }
145 }
146 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
147 arraylen = RTL8723BEAGCTAB_1TARRAYLEN;
148 array_table = RTL8723BEAGCTAB_1TARRAY;
149
150 for (i = 0; i < arraylen; i = i + 2) {
151 v1 = array_table[i];
152 v2 = array_table[i+1];
153 if (v1 < 0xCDCDCDCD) {
154 rtl_set_bbreg(hw, array_table[i],
155 MASKDWORD,
156 array_table[i + 1]);
157 udelay(1);
158 continue;
159 } else {/*This line is the start line of branch.*/
160 if (!_rtl8723be_check_condition(hw, array_table[i])) {
161 /* Discard the following
162 * (offset, data) pairs
163 */
164 READ_NEXT_PAIR(v1, v2, i);
165 while (v2 != 0xDEAD &&
166 v2 != 0xCDEF &&
167 v2 != 0xCDCD &&
168 i < arraylen - 2) {
169 READ_NEXT_PAIR(v1, v2, i);
170 }
171 i -= 2; /* prevent from for-loop += 2*/
172 /*Configure matched pairs and
173 *skip to end of if-else.
174 */
175 } else {
176 READ_NEXT_PAIR(v1, v2, i);
177 while (v2 != 0xDEAD &&
178 v2 != 0xCDEF &&
179 v2 != 0xCDCD &&
180 i < arraylen - 2) {
181 rtl_set_bbreg(hw, array_table[i],
182 MASKDWORD,
183 array_table[i + 1]);
184 udelay(1);
185 READ_NEXT_PAIR(v1, v2, i);
186 }
187
188 while (v2 != 0xDEAD && i < arraylen - 2)
189 READ_NEXT_PAIR(v1, v2, i);
190 }
191 }
192 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
193 "The agctab_array_table[0] is "
194 "%x Rtl818EEPHY_REGArray[1] is %x\n",
195 array_table[i], array_table[i + 1]);
196 }
197 }
198 return true;
199}
200
201static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
202{
203 u8 index = 0;
204
205 switch (regaddr) {
206 case RTXAGC_A_RATE18_06:
207 case RTXAGC_B_RATE18_06:
208 index = 0;
209 break;
210 case RTXAGC_A_RATE54_24:
211 case RTXAGC_B_RATE54_24:
212 index = 1;
213 break;
214 case RTXAGC_A_CCK1_MCS32:
215 case RTXAGC_B_CCK1_55_MCS32:
216 index = 2;
217 break;
218 case RTXAGC_B_CCK11_A_CCK2_11:
219 index = 3;
220 break;
221 case RTXAGC_A_MCS03_MCS00:
222 case RTXAGC_B_MCS03_MCS00:
223 index = 4;
224 break;
225 case RTXAGC_A_MCS07_MCS04:
226 case RTXAGC_B_MCS07_MCS04:
227 index = 5;
228 break;
229 case RTXAGC_A_MCS11_MCS08:
230 case RTXAGC_B_MCS11_MCS08:
231 index = 6;
232 break;
233 case RTXAGC_A_MCS15_MCS12:
234 case RTXAGC_B_MCS15_MCS12:
235 index = 7;
236 break;
237 default:
238 regaddr &= 0xFFF;
239 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
240 index = (u8) ((regaddr - 0xC20) / 4);
241 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
242 index = (u8) ((regaddr - 0xE20) / 4);
243 break;
244 };
245 return index;
246}
247
248u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
249 u32 regaddr, u32 bitmask)
250{
251 struct rtl_priv *rtlpriv = rtl_priv(hw);
252 u32 original_value, readback_value, bitshift;
253 unsigned long flags;
254
255 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
256 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
257 regaddr, rfpath, bitmask);
258
259 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
260
261 original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
262 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
263 readback_value = (original_value & bitmask) >> bitshift;
264
265 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
266
267 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
268 "regaddr(%#x), rfpath(%#x), "
269 "bitmask(%#x), original_value(%#x)\n",
270 regaddr, rfpath, bitmask, original_value);
271
272 return readback_value;
273}
274
275void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
276 u32 regaddr, u32 bitmask, u32 data)
277{
278 struct rtl_priv *rtlpriv = rtl_priv(hw);
279 u32 original_value, bitshift;
280 unsigned long flags;
281
282 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
283 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
284 regaddr, bitmask, data, path);
285
286 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
287
288 if (bitmask != RFREG_OFFSET_MASK) {
289 original_value = rtl8723_phy_rf_serial_read(hw, path,
290 regaddr);
291 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
292 data = ((original_value & (~bitmask)) |
293 (data << bitshift));
294 }
295
296 rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
297
298 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
299
300 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
301 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
302 regaddr, bitmask, data, path);
303}
304
305bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
306{
307 struct rtl_priv *rtlpriv = rtl_priv(hw);
308 bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
309
310 rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
311 return rtstatus;
312}
313
314bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
315{
316 bool rtstatus = true;
317 struct rtl_priv *rtlpriv = rtl_priv(hw);
318 u16 regval;
319 u8 reg_hwparafile = 1;
320 u32 tmp;
321 u8 crystalcap = rtlpriv->efuse.crystalcap;
322 rtl8723_phy_init_bb_rf_reg_def(hw);
323 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
324 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
325 regval | BIT(13) | BIT(0) | BIT(1));
326
327 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
328 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
329 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
330 FEN_BB_GLB_RSTN | FEN_BBRSTB);
331 tmp = rtl_read_dword(rtlpriv, 0x4c);
332 rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
333
334 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
335
336 if (reg_hwparafile == 1)
337 rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
338
339 crystalcap = crystalcap & 0x3F;
340 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
341 (crystalcap | crystalcap << 6));
342
343 return rtstatus;
344}
345
346bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
347{
348 return rtl8723be_phy_rf6052_config(hw);
349}
350
351static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
352 u32 data, enum radio_path rfpath,
353 u32 regaddr)
354{
355 if (addr == 0xfe || addr == 0xffe) {
356 mdelay(50);
357 } else {
358 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
359 udelay(1);
360 }
361}
362
363static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
364 u32 addr, u32 data)
365{
366 u32 content = 0x1000; /*RF Content: radio_a_txt*/
367 u32 maskforphyset = (u32)(content & 0xE000);
368
369 _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
370 addr | maskforphyset);
371}
372
373static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
374{
375 struct rtl_priv *rtlpriv = rtl_priv(hw);
376 struct rtl_phy *rtlphy = &(rtlpriv->phy);
377
378 u8 band, path, txnum, section;
379
380 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
381 for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
382 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
383 for (section = 0;
384 section < TX_PWR_BY_RATE_NUM_SECTION;
385 ++section)
386 rtlphy->tx_power_by_rate_offset[band]
387 [path][txnum][section] = 0;
388}
389
390static void phy_set_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band,
391 u8 path, u8 rate_section,
392 u8 txnum, u8 value)
393{
394 struct rtl_priv *rtlpriv = rtl_priv(hw);
395 struct rtl_phy *rtlphy = &(rtlpriv->phy);
396
397 if (path > RF90_PATH_D) {
398 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
399 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
400 path);
401 return;
402 }
403
404 if (band == BAND_ON_2_4G) {
405 switch (rate_section) {
406 case CCK:
407 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
408 break;
409 case OFDM:
410 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
411 break;
412 case HT_MCS0_MCS7:
413 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
414 break;
415 case HT_MCS8_MCS15:
416 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
417 break;
418 default:
419 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
420 "Invalid RateSection %d in Band 2.4G, Rf Path"
421 " %d, %dTx in PHY_SetTxPowerByRateBase()\n",
422 rate_section, path, txnum);
423 break;
424 };
425 } else {
426 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
427 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
428 band);
429 }
430}
431
432static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path,
433 u8 txnum, u8 rate_section)
434{
435 struct rtl_priv *rtlpriv = rtl_priv(hw);
436 struct rtl_phy *rtlphy = &(rtlpriv->phy);
437 u8 value = 0;
438 if (path > RF90_PATH_D) {
439 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
440 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
441 path);
442 return 0;
443 }
444
445 if (band == BAND_ON_2_4G) {
446 switch (rate_section) {
447 case CCK:
448 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
449 break;
450 case OFDM:
451 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
452 break;
453 case HT_MCS0_MCS7:
454 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
455 break;
456 case HT_MCS8_MCS15:
457 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
458 break;
459 default:
460 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
461 "Invalid RateSection %d in Band 2.4G, Rf Path"
462 " %d, %dTx in PHY_GetTxPowerByRateBase()\n",
463 rate_section, path, txnum);
464 break;
465 };
466 } else {
467 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
468 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
469 band);
470 }
471
472 return value;
473}
474
475static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
476{
477 struct rtl_priv *rtlpriv = rtl_priv(hw);
478 struct rtl_phy *rtlphy = &(rtlpriv->phy);
479 u16 raw_value = 0;
480 u8 base = 0, path = 0;
481
482 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
483 if (path == RF90_PATH_A) {
484 raw_value = (u16) (rtlphy->tx_power_by_rate_offset
485 [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
486 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
487 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, CCK,
488 RF_1TX, base);
489 } else if (path == RF90_PATH_B) {
490 raw_value = (u16) (rtlphy->tx_power_by_rate_offset
491 [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
492 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
493 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
494 CCK, RF_1TX, base);
495 }
496 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
497 [path][RF_1TX][1] >> 24) & 0xFF;
498 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
499 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX,
500 base);
501
502 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
503 [path][RF_1TX][5] >> 24) & 0xFF;
504 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
505 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7,
506 RF_1TX, base);
507
508 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
509 [path][RF_2TX][7] >> 24) & 0xFF;
510 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
511 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
512 HT_MCS8_MCS15, RF_2TX, base);
513 }
514}
515
516static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val)
517{
518 char i = 0;
519 u8 temp_value = 0;
520 u32 temp_data = 0;
521
522 for (i = 3; i >= 0; --i) {
523 if (i >= start && i <= end) {
524 /* Get the exact value */
525 temp_value = (u8) (*data >> (i * 8)) & 0xF;
526 temp_value += ((u8) ((*data >> (i*8 + 4)) & 0xF)) * 10;
527
528 /* Change the value to a relative value */
529 temp_value = (temp_value > base_val) ?
530 temp_value - base_val :
531 base_val - temp_value;
532 } else {
533 temp_value = (u8) (*data >> (i * 8)) & 0xFF;
534 }
535 temp_data <<= 8;
536 temp_data |= temp_value;
537 }
538 *data = temp_data;
539}
540
541static void conv_dbm_to_rel(struct ieee80211_hw *hw)
542{
543 struct rtl_priv *rtlpriv = rtl_priv(hw);
544 struct rtl_phy *rtlphy = &(rtlpriv->phy);
545 u8 base = 0, rfpath = RF90_PATH_A;
546
547 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
548 RF_1TX, CCK);
549 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
550 [rfpath][RF_1TX][2]), 1, 1, base);
551 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
552 [rfpath][RF_1TX][3]), 1, 3, base);
553
554 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
555 RF_1TX, OFDM);
556 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
557 [rfpath][RF_1TX][0]), 0, 3, base);
558 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
559 [rfpath][RF_1TX][1]), 0, 3, base);
560
561 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
562 RF_1TX, HT_MCS0_MCS7);
563 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
564 [rfpath][RF_1TX][4]), 0, 3, base);
565 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
566 [rfpath][RF_1TX][5]), 0, 3, base);
567
568 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
569 RF_2TX, HT_MCS8_MCS15);
570 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
571 [rfpath][RF_2TX][6]), 0, 3, base);
572
573 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
574 [rfpath][RF_2TX][7]), 0, 3, base);
575
576 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
577 "<=== conv_dbm_to_rel()\n");
578}
579
580static void _rtl8723be_phy_txpower_by_rate_configuration(
581 struct ieee80211_hw *hw)
582{
583 _rtl8723be_phy_store_txpower_by_rate_base(hw);
584 conv_dbm_to_rel(hw);
585}
586
587static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
588{
589 struct rtl_priv *rtlpriv = rtl_priv(hw);
590 struct rtl_phy *rtlphy = &(rtlpriv->phy);
591 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
592 bool rtstatus;
593
594 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
595 BASEBAND_CONFIG_PHY_REG);
596 if (!rtstatus) {
597 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
598 return false;
599 }
600 _rtl8723be_phy_init_tx_power_by_rate(hw);
601 if (!rtlefuse->autoload_failflag) {
602 rtlphy->pwrgroup_cnt = 0;
603 rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
604 BASEBAND_CONFIG_PHY_REG);
605 }
606 _rtl8723be_phy_txpower_by_rate_configuration(hw);
607 if (!rtstatus) {
608 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
609 return false;
610 }
611 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
612 BASEBAND_CONFIG_AGC_TAB);
613 if (!rtstatus) {
614 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
615 return false;
616 }
617 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
618 RFPGA0_XA_HSSIPARAMETER2,
619 0x200));
620 return true;
621}
622
623static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
624 u32 band, u32 rfpath,
625 u32 txnum, u32 regaddr,
626 u32 bitmask, u32 data)
627{
628 struct rtl_priv *rtlpriv = rtl_priv(hw);
629 struct rtl_phy *rtlphy = &(rtlpriv->phy);
630 u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
631
632 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
633 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
634 "Invalid Band %d\n", band);
635 return;
636 }
637
638 if (rfpath > TX_PWR_BY_RATE_NUM_RF) {
639 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
640 "Invalid RfPath %d\n", rfpath);
641 return;
642 }
643 if (txnum > TX_PWR_BY_RATE_NUM_RF) {
644 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
645 "Invalid TxNum %d\n", txnum);
646 return;
647 }
648 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
649 data;
650}
651
652static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
653 u8 configtype)
654{
655 struct rtl_priv *rtlpriv = rtl_priv(hw);
656 int i;
657 u32 *phy_regarray_table_pg;
658 u16 phy_regarray_pg_len;
659 u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
660
661 phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
662 phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
663
664 if (configtype == BASEBAND_CONFIG_PHY_REG) {
665 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
666 v1 = phy_regarray_table_pg[i];
667 v2 = phy_regarray_table_pg[i+1];
668 v3 = phy_regarray_table_pg[i+2];
669 v4 = phy_regarray_table_pg[i+3];
670 v5 = phy_regarray_table_pg[i+4];
671 v6 = phy_regarray_table_pg[i+5];
672
673 if (v1 < 0xcdcdcdcd) {
674 if (phy_regarray_table_pg[i] == 0xfe ||
675 phy_regarray_table_pg[i] == 0xffe)
676 mdelay(50);
677 else
678 _rtl8723be_store_tx_power_by_rate(hw,
679 v1, v2, v3, v4, v5, v6);
680 continue;
681 } else {
682 /*don't need the hw_body*/
683 if (!_rtl8723be_check_condition(hw,
684 phy_regarray_table_pg[i])) {
685 i += 2; /* skip the pair of expression*/
686 v1 = phy_regarray_table_pg[i];
687 v2 = phy_regarray_table_pg[i+1];
688 v3 = phy_regarray_table_pg[i+2];
689 while (v2 != 0xDEAD) {
690 i += 3;
691 v1 = phy_regarray_table_pg[i];
692 v2 = phy_regarray_table_pg[i+1];
693 v3 = phy_regarray_table_pg[i+2];
694 }
695 }
696 }
697 }
698 } else {
699 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
700 "configtype != BaseBand_Config_PHY_REG\n");
701 }
702 return true;
703}
704
705bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
706 enum radio_path rfpath)
707{
708 #define READ_NEXT_RF_PAIR(v1, v2, i) \
709 do { \
710 i += 2; \
711 v1 = radioa_array_table[i]; \
712 v2 = radioa_array_table[i+1]; \
713 } while (0)
714
715 int i;
716 bool rtstatus = true;
717 u32 *radioa_array_table;
718 u16 radioa_arraylen;
719 struct rtl_priv *rtlpriv = rtl_priv(hw);
720 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
721 u32 v1 = 0, v2 = 0;
722
723 radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
724 radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
725 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
726 "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
727 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
728 rtstatus = true;
729 switch (rfpath) {
730 case RF90_PATH_A:
731 for (i = 0; i < radioa_arraylen; i = i + 2) {
732 v1 = radioa_array_table[i];
733 v2 = radioa_array_table[i+1];
734 if (v1 < 0xcdcdcdcd) {
735 _rtl8723be_config_rf_radio_a(hw, v1, v2);
736 } else { /*This line is the start line of branch.*/
737 if (!_rtl8723be_check_condition(hw,
738 radioa_array_table[i])) {
739 /* Discard the following
740 * (offset, data) pairs
741 */
742 READ_NEXT_RF_PAIR(v1, v2, i);
743 while (v2 != 0xDEAD &&
744 v2 != 0xCDEF &&
745 v2 != 0xCDCD &&
746 i < radioa_arraylen - 2)
747 READ_NEXT_RF_PAIR(v1, v2, i);
748 i -= 2; /* prevent from for-loop += 2*/
749 } else {
750 /* Configure matched pairs
751 * and skip to end of if-else.
752 */
753 READ_NEXT_RF_PAIR(v1, v2, i);
754 while (v2 != 0xDEAD &&
755 v2 != 0xCDEF &&
756 v2 != 0xCDCD &&
757 i < radioa_arraylen - 2) {
758 _rtl8723be_config_rf_radio_a(hw,
759 v1, v2);
760 READ_NEXT_RF_PAIR(v1, v2, i);
761 }
762
763 while (v2 != 0xDEAD &&
764 i < radioa_arraylen - 2) {
765 READ_NEXT_RF_PAIR(v1, v2, i);
766 }
767 }
768 }
769 }
770
771 if (rtlhal->oem_id == RT_CID_819X_HP)
772 _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
773
774 break;
775 case RF90_PATH_B:
776 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
777 "switch case not process\n");
778 break;
779 case RF90_PATH_C:
780 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
781 "switch case not process\n");
782 break;
783 case RF90_PATH_D:
784 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
785 "switch case not process\n");
786 break;
787 }
788 return true;
789}
790
791void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
792{
793 struct rtl_priv *rtlpriv = rtl_priv(hw);
794 struct rtl_phy *rtlphy = &(rtlpriv->phy);
795
796 rtlphy->default_initialgain[0] =
797 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
798 rtlphy->default_initialgain[1] =
799 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
800 rtlphy->default_initialgain[2] =
801 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
802 rtlphy->default_initialgain[3] =
803 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
804
805 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
806 "Default initial gain (c50 = 0x%x, "
807 "c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n",
808 rtlphy->default_initialgain[0],
809 rtlphy->default_initialgain[1],
810 rtlphy->default_initialgain[2],
811 rtlphy->default_initialgain[3]);
812
813 rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
814 MASKBYTE0);
815 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
816 MASKDWORD);
817
818 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
819 "Default framesync (0x%x) = 0x%x\n",
820 ROFDM0_RXDETECTOR3, rtlphy->framesync);
821}
822
823void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
824{
825 struct rtl_priv *rtlpriv = rtl_priv(hw);
826 struct rtl_phy *rtlphy = &(rtlpriv->phy);
827 u8 txpwr_level;
828 long txpwr_dbm;
829
830 txpwr_level = rtlphy->cur_cck_txpwridx;
831 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
832 txpwr_level);
833 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
834 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
835 txpwr_dbm)
836 txpwr_dbm =
837 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
838 txpwr_level);
839 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
840 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
841 txpwr_level) > txpwr_dbm)
842 txpwr_dbm =
843 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
844 txpwr_level);
845 *powerlevel = txpwr_dbm;
846}
847
848static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
849 u8 rate)
850{
851 u8 rate_section = 0;
852
853 switch (rate) {
854 case DESC92C_RATE1M:
855 rate_section = 2;
856 break;
857 case DESC92C_RATE2M:
858 case DESC92C_RATE5_5M:
859 if (path == RF90_PATH_A)
860 rate_section = 3;
861 else if (path == RF90_PATH_B)
862 rate_section = 2;
863 break;
864 case DESC92C_RATE11M:
865 rate_section = 3;
866 break;
867 case DESC92C_RATE6M:
868 case DESC92C_RATE9M:
869 case DESC92C_RATE12M:
870 case DESC92C_RATE18M:
871 rate_section = 0;
872 break;
873 case DESC92C_RATE24M:
874 case DESC92C_RATE36M:
875 case DESC92C_RATE48M:
876 case DESC92C_RATE54M:
877 rate_section = 1;
878 break;
879 case DESC92C_RATEMCS0:
880 case DESC92C_RATEMCS1:
881 case DESC92C_RATEMCS2:
882 case DESC92C_RATEMCS3:
883 rate_section = 4;
884 break;
885 case DESC92C_RATEMCS4:
886 case DESC92C_RATEMCS5:
887 case DESC92C_RATEMCS6:
888 case DESC92C_RATEMCS7:
889 rate_section = 5;
890 break;
891 case DESC92C_RATEMCS8:
892 case DESC92C_RATEMCS9:
893 case DESC92C_RATEMCS10:
894 case DESC92C_RATEMCS11:
895 rate_section = 6;
896 break;
897 case DESC92C_RATEMCS12:
898 case DESC92C_RATEMCS13:
899 case DESC92C_RATEMCS14:
900 case DESC92C_RATEMCS15:
901 rate_section = 7;
902 break;
903 default:
904 RT_ASSERT(true, "Rate_Section is Illegal\n");
905 break;
906 }
907 return rate_section;
908}
909
910static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
911 enum band_type band,
912 enum radio_path rfpath, u8 rate)
913{
914 struct rtl_priv *rtlpriv = rtl_priv(hw);
915 struct rtl_phy *rtlphy = &(rtlpriv->phy);
916 u8 shift = 0, rate_section, tx_num;
917 char tx_pwr_diff = 0;
918
919 rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
920 rate);
921 tx_num = RF_TX_NUM_NONIMPLEMENT;
922
923 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
924 if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
925 tx_num = RF_2TX;
926 else
927 tx_num = RF_1TX;
928 }
929
930 switch (rate) {
931 case DESC92C_RATE6M:
932 case DESC92C_RATE24M:
933 case DESC92C_RATEMCS0:
934 case DESC92C_RATEMCS4:
935 case DESC92C_RATEMCS8:
936 case DESC92C_RATEMCS12:
937 shift = 0;
938 break;
939 case DESC92C_RATE1M:
940 case DESC92C_RATE2M:
941 case DESC92C_RATE9M:
942 case DESC92C_RATE36M:
943 case DESC92C_RATEMCS1:
944 case DESC92C_RATEMCS5:
945 case DESC92C_RATEMCS9:
946 case DESC92C_RATEMCS13:
947 shift = 8;
948 break;
949 case DESC92C_RATE5_5M:
950 case DESC92C_RATE12M:
951 case DESC92C_RATE48M:
952 case DESC92C_RATEMCS2:
953 case DESC92C_RATEMCS6:
954 case DESC92C_RATEMCS10:
955 case DESC92C_RATEMCS14:
956 shift = 16;
957 break;
958 case DESC92C_RATE11M:
959 case DESC92C_RATE18M:
960 case DESC92C_RATE54M:
961 case DESC92C_RATEMCS3:
962 case DESC92C_RATEMCS7:
963 case DESC92C_RATEMCS11:
964 case DESC92C_RATEMCS15:
965 shift = 24;
966 break;
967 default:
968 RT_ASSERT(true, "Rate_Section is Illegal\n");
969 break;
970 }
971 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
972 [rate_section] >> shift) & 0xff;
973
974 return tx_pwr_diff;
975}
976
977static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
978 u8 rate, u8 bandwidth, u8 channel)
979{
980 struct rtl_priv *rtlpriv = rtl_priv(hw);
981 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
982 u8 index = (channel - 1);
983 u8 txpower;
984 u8 power_diff_byrate = 0;
985
986 if (channel > 14 || channel < 1) {
987 index = 0;
988 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
989 "Illegal channel!\n");
990 }
991 if (RTL8723E_RX_HAL_IS_CCK_RATE(rate))
992 txpower = rtlefuse->txpwrlevel_cck[path][index];
993 else if (DESC92C_RATE6M <= rate)
994 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
995 else
996 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
997 "invalid rate\n");
998
999 if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1000 !RTL8723E_RX_HAL_IS_CCK_RATE(rate))
1001 txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1002
1003 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1004 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1005 txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1006 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1007 txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1008 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1009 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1010 txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1011 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1012 txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1013 }
1014 if (rtlefuse->eeprom_regulatory != 2)
1015 power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1016 BAND_ON_2_4G,
1017 path, rate);
1018
1019 txpower += power_diff_byrate;
1020
1021 if (txpower > MAX_POWER_INDEX)
1022 txpower = MAX_POWER_INDEX;
1023
1024 return txpower;
1025}
1026
1027static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1028 u8 power_index, u8 path, u8 rate)
1029{
1030 struct rtl_priv *rtlpriv = rtl_priv(hw);
1031 if (path == RF90_PATH_A) {
1032 switch (rate) {
1033 case DESC92C_RATE1M:
1034 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1035 MASKBYTE1, power_index);
1036 break;
1037 case DESC92C_RATE2M:
1038 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1039 MASKBYTE1, power_index);
1040 break;
1041 case DESC92C_RATE5_5M:
1042 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1043 MASKBYTE2, power_index);
1044 break;
1045 case DESC92C_RATE11M:
1046 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1047 MASKBYTE3, power_index);
1048 break;
1049 case DESC92C_RATE6M:
1050 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1051 MASKBYTE0, power_index);
1052 break;
1053 case DESC92C_RATE9M:
1054 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1055 MASKBYTE1, power_index);
1056 break;
1057 case DESC92C_RATE12M:
1058 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1059 MASKBYTE2, power_index);
1060 break;
1061 case DESC92C_RATE18M:
1062 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1063 MASKBYTE3, power_index);
1064 break;
1065 case DESC92C_RATE24M:
1066 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1067 MASKBYTE0, power_index);
1068 break;
1069 case DESC92C_RATE36M:
1070 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1071 MASKBYTE1, power_index);
1072 break;
1073 case DESC92C_RATE48M:
1074 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1075 MASKBYTE2, power_index);
1076 break;
1077 case DESC92C_RATE54M:
1078 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1079 MASKBYTE3, power_index);
1080 break;
1081 case DESC92C_RATEMCS0:
1082 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1083 MASKBYTE0, power_index);
1084 break;
1085 case DESC92C_RATEMCS1:
1086 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1087 MASKBYTE1, power_index);
1088 break;
1089 case DESC92C_RATEMCS2:
1090 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1091 MASKBYTE2, power_index);
1092 break;
1093 case DESC92C_RATEMCS3:
1094 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1095 MASKBYTE3, power_index);
1096 break;
1097 case DESC92C_RATEMCS4:
1098 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1099 MASKBYTE0, power_index);
1100 break;
1101 case DESC92C_RATEMCS5:
1102 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1103 MASKBYTE1, power_index);
1104 break;
1105 case DESC92C_RATEMCS6:
1106 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1107 MASKBYTE2, power_index);
1108 break;
1109 case DESC92C_RATEMCS7:
1110 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1111 MASKBYTE3, power_index);
1112 break;
1113 case DESC92C_RATEMCS8:
1114 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1115 MASKBYTE0, power_index);
1116 break;
1117 case DESC92C_RATEMCS9:
1118 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1119 MASKBYTE1, power_index);
1120 break;
1121 case DESC92C_RATEMCS10:
1122 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1123 MASKBYTE2, power_index);
1124 break;
1125 case DESC92C_RATEMCS11:
1126 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1127 MASKBYTE3, power_index);
1128 break;
1129 default:
1130 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1131 "Invalid Rate!!\n");
1132 break;
1133 }
1134 } else {
1135 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1136 }
1137}
1138
1139void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1140{
1141 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1142 u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1143 DESC92C_RATE5_5M, DESC92C_RATE11M};
1144 u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1145 DESC92C_RATE12M, DESC92C_RATE18M,
1146 DESC92C_RATE24M, DESC92C_RATE36M,
1147 DESC92C_RATE48M, DESC92C_RATE54M};
1148 u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1149 DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1150 DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1151 DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1152 u8 i, size;
1153 u8 power_index;
1154
1155 if (!rtlefuse->txpwr_fromeprom)
1156 return;
1157
1158 size = sizeof(cck_rates) / sizeof(u8);
1159 for (i = 0; i < size; i++) {
1160 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1161 cck_rates[i],
1162 rtl_priv(hw)->phy.current_chan_bw,
1163 channel);
1164 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1165 cck_rates[i]);
1166 }
1167 size = sizeof(ofdm_rates) / sizeof(u8);
1168 for (i = 0; i < size; i++) {
1169 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1170 ofdm_rates[i],
1171 rtl_priv(hw)->phy.current_chan_bw,
1172 channel);
1173 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1174 ofdm_rates[i]);
1175 }
1176 size = sizeof(ht_rates_1t) / sizeof(u8);
1177 for (i = 0; i < size; i++) {
1178 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1179 ht_rates_1t[i],
1180 rtl_priv(hw)->phy.current_chan_bw,
1181 channel);
1182 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1183 ht_rates_1t[i]);
1184 }
1185}
1186
1187void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1188{
1189 struct rtl_priv *rtlpriv = rtl_priv(hw);
1190 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1191 enum io_type iotype;
1192
1193 if (!is_hal_stop(rtlhal)) {
1194 switch (operation) {
1195 case SCAN_OPT_BACKUP:
1196 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1197 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1198 (u8 *)&iotype);
1199 break;
1200 case SCAN_OPT_RESTORE:
1201 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1202 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1203 (u8 *)&iotype);
1204 break;
1205 default:
1206 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1207 "Unknown Scan Backup operation.\n");
1208 break;
1209 }
1210 }
1211}
1212
1213void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1214{
1215 struct rtl_priv *rtlpriv = rtl_priv(hw);
1216 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1217 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1218 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1219 u8 reg_bw_opmode;
1220 u8 reg_prsr_rsc;
1221
1222 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1223 "Switch to %s bandwidth\n",
1224 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1225 "20MHz" : "40MHz");
1226
1227 if (is_hal_stop(rtlhal)) {
1228 rtlphy->set_bwmode_inprogress = false;
1229 return;
1230 }
1231
1232 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1233 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1234
1235 switch (rtlphy->current_chan_bw) {
1236 case HT_CHANNEL_WIDTH_20:
1237 reg_bw_opmode |= BW_OPMODE_20MHZ;
1238 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1239 break;
1240 case HT_CHANNEL_WIDTH_20_40:
1241 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1242 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1243 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1244 (mac->cur_40_prime_sc << 5);
1245 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1246 break;
1247 default:
1248 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1249 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1250 break;
1251 }
1252
1253 switch (rtlphy->current_chan_bw) {
1254 case HT_CHANNEL_WIDTH_20:
1255 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1256 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1257 break;
1258 case HT_CHANNEL_WIDTH_20_40:
1259 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1260 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1261 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1262 (mac->cur_40_prime_sc >> 1));
1263 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1264 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1265 (mac->cur_40_prime_sc ==
1266 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1267 break;
1268 default:
1269 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1270 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1271 break;
1272 }
1273 rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1274 rtlphy->set_bwmode_inprogress = false;
1275 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1276}
1277
1278void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1279 enum nl80211_channel_type ch_type)
1280{
1281 struct rtl_priv *rtlpriv = rtl_priv(hw);
1282 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1283 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1284 u8 tmp_bw = rtlphy->current_chan_bw;
1285
1286 if (rtlphy->set_bwmode_inprogress)
1287 return;
1288 rtlphy->set_bwmode_inprogress = true;
1289 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1290 rtl8723be_phy_set_bw_mode_callback(hw);
1291 } else {
1292 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1293 "false driver sleep or unload\n");
1294 rtlphy->set_bwmode_inprogress = false;
1295 rtlphy->current_chan_bw = tmp_bw;
1296 }
1297}
1298
1299void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1300{
1301 struct rtl_priv *rtlpriv = rtl_priv(hw);
1302 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1303 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1304 u32 delay;
1305
1306 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1307 "switch to channel%d\n", rtlphy->current_channel);
1308 if (is_hal_stop(rtlhal))
1309 return;
1310 do {
1311 if (!rtlphy->sw_chnl_inprogress)
1312 break;
1313 if (!rtl8723be_phy_sw_chn_step_by_step(hw,
1314 rtlphy->current_channel,
1315 &rtlphy->sw_chnl_stage,
1316 &rtlphy->sw_chnl_step,
1317 &delay)) {
1318 if (delay > 0)
1319 mdelay(delay);
1320 else
1321 continue;
1322 } else {
1323 rtlphy->sw_chnl_inprogress = false;
1324 }
1325 break;
1326 } while (true);
1327 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1328}
1329
1330u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1331{
1332 struct rtl_priv *rtlpriv = rtl_priv(hw);
1333 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1334 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1335
1336 if (rtlphy->sw_chnl_inprogress)
1337 return 0;
1338 if (rtlphy->set_bwmode_inprogress)
1339 return 0;
1340 RT_ASSERT((rtlphy->current_channel <= 14),
1341 "WIRELESS_MODE_G but channel>14");
1342 rtlphy->sw_chnl_inprogress = true;
1343 rtlphy->sw_chnl_stage = 0;
1344 rtlphy->sw_chnl_step = 0;
1345 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1346 rtl8723be_phy_sw_chnl_callback(hw);
1347 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1348 "sw_chnl_inprogress false schdule "
1349 "workitem current channel %d\n",
1350 rtlphy->current_channel);
1351 rtlphy->sw_chnl_inprogress = false;
1352 } else {
1353 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1354 "sw_chnl_inprogress false driver sleep or"
1355 " unload\n");
1356 rtlphy->sw_chnl_inprogress = false;
1357 }
1358 return 1;
1359}
1360
1361static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
1362 u8 channel, u8 *stage,
1363 u8 *step, u32 *delay)
1364{
1365 struct rtl_priv *rtlpriv = rtl_priv(hw);
1366 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1367 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1368 u32 precommoncmdcnt;
1369 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1370 u32 postcommoncmdcnt;
1371 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1372 u32 rfdependcmdcnt;
1373 struct swchnlcmd *currentcmd = NULL;
1374 u8 rfpath;
1375 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1376
1377 precommoncmdcnt = 0;
1378 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1379 MAX_PRECMD_CNT,
1380 CMDID_SET_TXPOWEROWER_LEVEL,
1381 0, 0, 0);
1382 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1383 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1384 postcommoncmdcnt = 0;
1385 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1386 MAX_POSTCMD_CNT, CMDID_END,
1387 0, 0, 0);
1388 rfdependcmdcnt = 0;
1389
1390 RT_ASSERT((channel >= 1 && channel <= 14),
1391 "illegal channel for Zebra: %d\n", channel);
1392
1393 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1394 MAX_RFDEPENDCMD_CNT,
1395 CMDID_RF_WRITEREG,
1396 RF_CHNLBW, channel, 10);
1397
1398 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1399 MAX_RFDEPENDCMD_CNT,
1400 CMDID_END, 0, 0, 0);
1401
1402 do {
1403 switch (*stage) {
1404 case 0:
1405 currentcmd = &precommoncmd[*step];
1406 break;
1407 case 1:
1408 currentcmd = &rfdependcmd[*step];
1409 break;
1410 case 2:
1411 currentcmd = &postcommoncmd[*step];
1412 break;
1413 }
1414
1415 if (currentcmd->cmdid == CMDID_END) {
1416 if ((*stage) == 2) {
1417 return true;
1418 } else {
1419 (*stage)++;
1420 (*step) = 0;
1421 continue;
1422 }
1423 }
1424
1425 switch (currentcmd->cmdid) {
1426 case CMDID_SET_TXPOWEROWER_LEVEL:
1427 rtl8723be_phy_set_txpower_level(hw, channel);
1428 break;
1429 case CMDID_WRITEPORT_ULONG:
1430 rtl_write_dword(rtlpriv, currentcmd->para1,
1431 currentcmd->para2);
1432 break;
1433 case CMDID_WRITEPORT_USHORT:
1434 rtl_write_word(rtlpriv, currentcmd->para1,
1435 (u16) currentcmd->para2);
1436 break;
1437 case CMDID_WRITEPORT_UCHAR:
1438 rtl_write_byte(rtlpriv, currentcmd->para1,
1439 (u8) currentcmd->para2);
1440 break;
1441 case CMDID_RF_WRITEREG:
1442 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1443 rtlphy->rfreg_chnlval[rfpath] =
1444 ((rtlphy->rfreg_chnlval[rfpath] &
1445 0xfffffc00) | currentcmd->para2);
1446
1447 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1448 currentcmd->para1,
1449 RFREG_OFFSET_MASK,
1450 rtlphy->rfreg_chnlval[rfpath]);
1451 }
1452 break;
1453 default:
1454 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1455 "switch case not process\n");
1456 break;
1457 }
1458
1459 break;
1460 } while (true);
1461
1462 (*delay) = currentcmd->msdelay;
1463 (*step)++;
1464 return false;
1465}
1466
1467static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1468{
1469 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1470 u8 result = 0x00;
1471
1472 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
1473 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
1474 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
1475 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
1476
1477 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1478 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1479 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1480
1481 mdelay(IQK_DELAY_TIME);
1482
1483 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1484 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1485 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1486 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1487
1488 if (!(reg_eac & BIT(28)) &&
1489 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1490 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1491 result |= 0x01;
1492 return result;
1493}
1494
1495static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8],
1496 u8 c1, u8 c2)
1497{
1498 u32 i, j, diff, simularity_bitmap, bound;
1499 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1500
1501 u8 final_candidate[2] = { 0xFF, 0xFF };
1502 bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1503
1504 if (is2t)
1505 bound = 8;
1506 else
1507 bound = 4;
1508
1509 simularity_bitmap = 0;
1510
1511 for (i = 0; i < bound; i++) {
1512 diff = (result[c1][i] > result[c2][i]) ?
1513 (result[c1][i] - result[c2][i]) :
1514 (result[c2][i] - result[c1][i]);
1515
1516 if (diff > MAX_TOLERANCE) {
1517 if ((i == 2 || i == 6) && !simularity_bitmap) {
1518 if (result[c1][i] + result[c1][i + 1] == 0)
1519 final_candidate[(i / 4)] = c2;
1520 else if (result[c2][i] + result[c2][i + 1] == 0)
1521 final_candidate[(i / 4)] = c1;
1522 else
1523 simularity_bitmap |= (1 << i);
1524 } else {
1525 simularity_bitmap |= (1 << i);
1526 }
1527 }
1528 }
1529
1530 if (simularity_bitmap == 0) {
1531 for (i = 0; i < (bound / 4); i++) {
1532 if (final_candidate[i] != 0xFF) {
1533 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1534 result[3][j] =
1535 result[final_candidate[i]][j];
1536 bresult = false;
1537 }
1538 }
1539 return bresult;
1540 } else if (!(simularity_bitmap & 0x0F)) {
1541 for (i = 0; i < 4; i++)
1542 result[3][i] = result[c1][i];
1543 return false;
1544 } else if (!(simularity_bitmap & 0xF0) && is2t) {
1545 for (i = 4; i < 8; i++)
1546 result[3][i] = result[c1][i];
1547 return false;
1548 } else {
1549 return false;
1550 }
1551}
1552
1553static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
1554 long result[][8], u8 t, bool is2t)
1555{
1556 struct rtl_priv *rtlpriv = rtl_priv(hw);
1557 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1558 u32 i;
1559 u8 patha_ok;
1560 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1561 0x85c, 0xe6c, 0xe70, 0xe74,
1562 0xe78, 0xe7c, 0xe80, 0xe84,
1563 0xe88, 0xe8c, 0xed0, 0xed4,
1564 0xed8, 0xedc, 0xee0, 0xeec
1565 };
1566
1567 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1568 0x522, 0x550, 0x551, 0x040
1569 };
1570 u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1571 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
1572 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
1573 0x870, 0x860,
1574 0x864, 0x800
1575 };
1576 const u32 retrycount = 2;
1577 u32 path_sel_bb, path_sel_rf;
1578 u8 tmp_reg_c50, tmp_reg_c58;
1579
1580 tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
1581 tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
1582
1583 if (t == 0) {
1584 rtl8723_save_adda_registers(hw, adda_reg,
1585 rtlphy->adda_backup, 16);
1586 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1587 rtlphy->iqk_mac_backup);
1588 rtl8723_save_adda_registers(hw, iqk_bb_reg,
1589 rtlphy->iqk_bb_backup,
1590 IQK_BB_REG_NUM);
1591 }
1592 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1593 if (t == 0) {
1594 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1595 RFPGA0_XA_HSSIPARAMETER1,
1596 BIT(8));
1597 }
1598 if (!rtlphy->rfpi_enable)
1599 rtl8723_phy_pi_mode_switch(hw, true);
1600
1601 path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
1602 path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff);
1603
1604 /*BB Setting*/
1605 rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
1606 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1607 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1608 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1609
1610 rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
1611 rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
1612 rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
1613 rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
1614
1615 if (is2t)
1616 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASKDWORD, 0x10000);
1617 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1618 rtlphy->iqk_mac_backup);
1619 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1620
1621 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1622 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1623 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
1624 for (i = 0; i < retrycount; i++) {
1625 patha_ok = _rtl8723be_phy_path_a_iqk(hw, is2t);
1626 if (patha_ok == 0x01) {
1627 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1628 "Path A Tx IQK Success!!\n");
1629 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1630 0x3FF0000) >> 16;
1631 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1632 0x3FF0000) >> 16;
1633 break;
1634 }
1635 }
1636
1637 if (0 == patha_ok)
1638 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1639 "Path A IQK Success!!\n");
1640 if (is2t) {
1641 rtl8723_phy_path_a_standby(hw);
1642 rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1643 }
1644
1645 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1646
1647 if (t != 0) {
1648 if (!rtlphy->rfpi_enable)
1649 rtl8723_phy_pi_mode_switch(hw, false);
1650 rtl8723_phy_reload_adda_registers(hw, adda_reg,
1651 rtlphy->adda_backup, 16);
1652 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1653 rtlphy->iqk_mac_backup);
1654 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1655 rtlphy->iqk_bb_backup,
1656 IQK_BB_REG_NUM);
1657
1658 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
1659 rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);
1660
1661 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
1662 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
1663 if (is2t) {
1664 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
1665 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
1666 }
1667 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1668 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1669 }
1670 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
1671}
1672
1673static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1674{
1675 struct rtl_priv *rtlpriv = rtl_priv(hw);
1676 u8 tmpreg;
1677 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1678
1679 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1680
1681 if ((tmpreg & 0x70) != 0)
1682 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1683 else
1684 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1685
1686 if ((tmpreg & 0x70) != 0) {
1687 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1688
1689 if (is2t)
1690 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1691 MASK12BITS);
1692
1693 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1694 (rf_a_mode & 0x8FFFF) | 0x10000);
1695
1696 if (is2t)
1697 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1698 (rf_b_mode & 0x8FFFF) | 0x10000);
1699 }
1700 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1701
1702 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
1703 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
1704
1705 mdelay(100);
1706
1707 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
1708
1709 if ((tmpreg & 0x70) != 0) {
1710 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1711 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1712
1713 if (is2t)
1714 rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
1715 MASK12BITS, rf_b_mode);
1716 } else {
1717 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1718 }
1719 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1720}
1721
1722static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1723 bool bmain, bool is2t)
1724{
1725 struct rtl_priv *rtlpriv = rtl_priv(hw);
1726 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1727 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1728 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1729
1730 if (is_hal_stop(rtlhal)) {
1731 u8 u1btmp;
1732 u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
1733 rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
1734 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1735 }
1736 if (is2t) {
1737 if (bmain)
1738 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1739 BIT(5) | BIT(6), 0x1);
1740 else
1741 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1742 BIT(5) | BIT(6), 0x2);
1743 } else {
1744 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
1745 rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
1746
1747 /* We use the RF definition of MAIN and AUX,
1748 * left antenna and right antenna repectively.
1749 * Default output at AUX.
1750 */
1751 if (bmain) {
1752 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1753 BIT(14) | BIT(13) | BIT(12), 0);
1754 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1755 BIT(5) | BIT(4) | BIT(3), 0);
1756 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1757 rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 0);
1758 } else {
1759 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1760 BIT(14) | BIT(13) | BIT(12), 1);
1761 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1762 BIT(5) | BIT(4) | BIT(3), 1);
1763 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1764 rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 1);
1765 }
1766 }
1767}
1768
1769#undef IQK_ADDA_REG_NUM
1770#undef IQK_DELAY_TIME
1771
1772void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1773{
1774 struct rtl_priv *rtlpriv = rtl_priv(hw);
1775 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1776 long result[4][8];
1777 u8 i, final_candidate;
1778 bool patha_ok, pathb_ok;
1779 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1780 reg_ecc, reg_tmp = 0;
1781 bool is12simular, is13simular, is23simular;
1782 u32 iqk_bb_reg[9] = {
1783 ROFDM0_XARXIQIMBALANCE,
1784 ROFDM0_XBRXIQIMBALANCE,
1785 ROFDM0_ECCATHRESHOLD,
1786 ROFDM0_AGCRSSITABLE,
1787 ROFDM0_XATXIQIMBALANCE,
1788 ROFDM0_XBTXIQIMBALANCE,
1789 ROFDM0_XCTXAFE,
1790 ROFDM0_XDTXAFE,
1791 ROFDM0_RXIQEXTANTA
1792 };
1793
1794 if (recovery) {
1795 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1796 rtlphy->iqk_bb_backup, 9);
1797 return;
1798 }
1799
1800 for (i = 0; i < 8; i++) {
1801 result[0][i] = 0;
1802 result[1][i] = 0;
1803 result[2][i] = 0;
1804 result[3][i] = 0;
1805 }
1806 final_candidate = 0xff;
1807 patha_ok = false;
1808 pathb_ok = false;
1809 is12simular = false;
1810 is23simular = false;
1811 is13simular = false;
1812 for (i = 0; i < 3; i++) {
1813 if (get_rf_type(rtlphy) == RF_2T2R)
1814 _rtl8723be_phy_iq_calibrate(hw, result, i, true);
1815 else
1816 _rtl8723be_phy_iq_calibrate(hw, result, i, false);
1817 if (i == 1) {
1818 is12simular = phy_similarity_cmp(hw, result, 0, 1);
1819 if (is12simular) {
1820 final_candidate = 0;
1821 break;
1822 }
1823 }
1824 if (i == 2) {
1825 is13simular = phy_similarity_cmp(hw, result, 0, 2);
1826 if (is13simular) {
1827 final_candidate = 0;
1828 break;
1829 }
1830 is23simular = phy_similarity_cmp(hw, result, 1, 2);
1831 if (is23simular) {
1832 final_candidate = 1;
1833 } else {
1834 for (i = 0; i < 8; i++)
1835 reg_tmp += result[3][i];
1836
1837 if (reg_tmp != 0)
1838 final_candidate = 3;
1839 else
1840 final_candidate = 0xFF;
1841 }
1842 }
1843 }
1844 for (i = 0; i < 4; i++) {
1845 reg_e94 = result[i][0];
1846 reg_e9c = result[i][1];
1847 reg_ea4 = result[i][2];
1848 reg_eac = result[i][3];
1849 reg_eb4 = result[i][4];
1850 reg_ebc = result[i][5];
1851 reg_ec4 = result[i][6];
1852 reg_ecc = result[i][7];
1853 }
1854 if (final_candidate != 0xff) {
1855 reg_e94 = result[final_candidate][0];
1856 rtlphy->reg_e94 = reg_e94;
1857 reg_e9c = result[final_candidate][1];
1858 rtlphy->reg_e9c = reg_e9c;
1859 reg_ea4 = result[final_candidate][2];
1860 reg_eac = result[final_candidate][3];
1861 reg_eb4 = result[final_candidate][4];
1862 rtlphy->reg_eb4 = reg_eb4;
1863 reg_ebc = result[final_candidate][5];
1864 rtlphy->reg_ebc = reg_ebc;
1865 reg_ec4 = result[final_candidate][6];
1866 reg_ecc = result[final_candidate][7];
1867 patha_ok = true;
1868 pathb_ok = true;
1869 } else {
1870 rtlphy->reg_e94 = 0x100;
1871 rtlphy->reg_eb4 = 0x100;
1872 rtlphy->reg_e9c = 0x0;
1873 rtlphy->reg_ebc = 0x0;
1874 }
1875 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1876 rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1877 final_candidate,
1878 (reg_ea4 == 0));
1879 if (final_candidate != 0xFF) {
1880 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
1881 rtlphy->iqk_matrix[0].value[0][i] =
1882 result[final_candidate][i];
1883 rtlphy->iqk_matrix[0].iqk_done = true;
1884 }
1885 rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1886}
1887
1888void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
1889{
1890 struct rtl_priv *rtlpriv = rtl_priv(hw);
1891 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1892 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1893 u32 timeout = 2000, timecount = 0;
1894
1895 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
1896 udelay(50);
1897 timecount += 50;
1898 }
1899
1900 rtlphy->lck_inprogress = true;
1901 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1902 "LCK:Start!!! currentband %x delay %d ms\n",
1903 rtlhal->current_bandtype, timecount);
1904
1905 _rtl8723be_phy_lc_calibrate(hw, false);
1906
1907 rtlphy->lck_inprogress = false;
1908}
1909
1910void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
1911{
1912 struct rtl_priv *rtlpriv = rtl_priv(hw);
1913 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1914
1915 if (rtlphy->apk_done)
1916 return;
1917
1918 return;
1919}
1920
1921void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1922{
1923 _rtl8723be_phy_set_rfpath_switch(hw, bmain, false);
1924}
1925
1926static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
1927{
1928 struct rtl_priv *rtlpriv = rtl_priv(hw);
1929 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1930
1931 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1932 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1933 rtlphy->current_io_type, rtlphy->set_io_inprogress);
1934 switch (rtlphy->current_io_type) {
1935 case IO_CMD_RESUME_DM_BY_SCAN:
1936 rtlpriv->dm_digtable.cur_igvalue =
1937 rtlphy->initgain_backup.xaagccore1;
1938 /*rtl92c_dm_write_dig(hw);*/
1939 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
1940 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
1941 break;
1942 case IO_CMD_PAUSE_DM_BY_SCAN:
1943 rtlphy->initgain_backup.xaagccore1 =
1944 rtlpriv->dm_digtable.cur_igvalue;
1945 rtlpriv->dm_digtable.cur_igvalue = 0x17;
1946 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
1947 break;
1948 default:
1949 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1950 "switch case not process\n");
1951 break;
1952 }
1953 rtlphy->set_io_inprogress = false;
1954 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1955 "(%#x)\n", rtlphy->current_io_type);
1956}
1957
1958bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1959{
1960 struct rtl_priv *rtlpriv = rtl_priv(hw);
1961 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1962 bool postprocessing = false;
1963
1964 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1965 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1966 iotype, rtlphy->set_io_inprogress);
1967 do {
1968 switch (iotype) {
1969 case IO_CMD_RESUME_DM_BY_SCAN:
1970 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1971 "[IO CMD] Resume DM after scan.\n");
1972 postprocessing = true;
1973 break;
1974 case IO_CMD_PAUSE_DM_BY_SCAN:
1975 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1976 "[IO CMD] Pause DM before scan.\n");
1977 postprocessing = true;
1978 break;
1979 default:
1980 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1981 "switch case not process\n");
1982 break;
1983 }
1984 } while (false);
1985 if (postprocessing && !rtlphy->set_io_inprogress) {
1986 rtlphy->set_io_inprogress = true;
1987 rtlphy->current_io_type = iotype;
1988 } else {
1989 return false;
1990 }
1991 rtl8723be_phy_set_io(hw);
1992 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
1993 return true;
1994}
1995
1996static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
1997{
1998 struct rtl_priv *rtlpriv = rtl_priv(hw);
1999
2000 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2001 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2002 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2003 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2004 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2005}
2006
2007static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2008{
2009 struct rtl_priv *rtlpriv = rtl_priv(hw);
2010
2011 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2012 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2013 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2014 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2015}
2016
2017static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2018 enum rf_pwrstate rfpwr_state)
2019{
2020 struct rtl_priv *rtlpriv = rtl_priv(hw);
2021 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2022 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2023 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2024 bool bresult = true;
2025 u8 i, queue_id;
2026 struct rtl8192_tx_ring *ring = NULL;
2027
2028 switch (rfpwr_state) {
2029 case ERFON:
2030 if ((ppsc->rfpwr_state == ERFOFF) &&
2031 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2032 bool rtstatus;
2033 u32 initialize_count = 0;
2034 do {
2035 initialize_count++;
2036 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2037 "IPS Set eRf nic enable\n");
2038 rtstatus = rtl_ps_enable_nic(hw);
2039 } while (!rtstatus && (initialize_count < 10));
2040 RT_CLEAR_PS_LEVEL(ppsc,
2041 RT_RF_OFF_LEVL_HALT_NIC);
2042 } else {
2043 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2044 "Set ERFON sleeped:%d ms\n",
2045 jiffies_to_msecs(jiffies -
2046 ppsc->last_sleep_jiffies));
2047 ppsc->last_awake_jiffies = jiffies;
2048 rtl8723be_phy_set_rf_on(hw);
2049 }
2050 if (mac->link_state == MAC80211_LINKED)
2051 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2052 else
2053 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2054 break;
2055 case ERFOFF:
2056 for (queue_id = 0, i = 0;
2057 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2058 ring = &pcipriv->dev.tx_ring[queue_id];
2059 if (skb_queue_len(&ring->queue) == 0) {
2060 queue_id++;
2061 continue;
2062 } else {
2063 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2064 "eRf Off/Sleep: %d times "
2065 "TcbBusyQueue[%d] =%d before "
2066 "doze!\n", (i + 1), queue_id,
2067 skb_queue_len(&ring->queue));
2068
2069 udelay(10);
2070 i++;
2071 }
2072 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2073 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2074 "\n ERFSLEEP: %d times "
2075 "TcbBusyQueue[%d] = %d !\n",
2076 MAX_DOZE_WAITING_TIMES_9x,
2077 queue_id,
2078 skb_queue_len(&ring->queue));
2079 break;
2080 }
2081 }
2082
2083 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2084 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2085 "IPS Set eRf nic disable\n");
2086 rtl_ps_disable_nic(hw);
2087 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2088 } else {
2089 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2090 rtlpriv->cfg->ops->led_control(hw,
2091 LED_CTL_NO_LINK);
2092 } else {
2093 rtlpriv->cfg->ops->led_control(hw,
2094 LED_CTL_POWER_OFF);
2095 }
2096 }
2097 break;
2098 case ERFSLEEP:
2099 if (ppsc->rfpwr_state == ERFOFF)
2100 break;
2101 for (queue_id = 0, i = 0;
2102 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2103 ring = &pcipriv->dev.tx_ring[queue_id];
2104 if (skb_queue_len(&ring->queue) == 0) {
2105 queue_id++;
2106 continue;
2107 } else {
2108 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2109 "eRf Off/Sleep: %d times "
2110 "TcbBusyQueue[%d] =%d before "
2111 "doze!\n", (i + 1), queue_id,
2112 skb_queue_len(&ring->queue));
2113
2114 udelay(10);
2115 i++;
2116 }
2117 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2118 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2119 "\n ERFSLEEP: %d times "
2120 "TcbBusyQueue[%d] = %d !\n",
2121 MAX_DOZE_WAITING_TIMES_9x,
2122 queue_id,
2123 skb_queue_len(&ring->queue));
2124 break;
2125 }
2126 }
2127 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2128 "Set ERFSLEEP awaked:%d ms\n",
2129 jiffies_to_msecs(jiffies -
2130 ppsc->last_awake_jiffies));
2131 ppsc->last_sleep_jiffies = jiffies;
2132 _rtl8723be_phy_set_rf_sleep(hw);
2133 break;
2134 default:
2135 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2136 "switch case not process\n");
2137 bresult = false;
2138 break;
2139 }
2140 if (bresult)
2141 ppsc->rfpwr_state = rfpwr_state;
2142 return bresult;
2143}
2144
2145bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2146 enum rf_pwrstate rfpwr_state)
2147{
2148 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2149
2150 bool bresult = false;
2151
2152 if (rfpwr_state == ppsc->rfpwr_state)
2153 return bresult;
2154 bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2155 return bresult;
2156}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.h b/drivers/net/wireless/rtlwifi/rtl8723be/phy.h
new file mode 100644
index 000000000000..444ef95bb6af
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.h
@@ -0,0 +1,217 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_PHY_H__
27#define __RTL8723BE_PHY_H__
28
29/*It must always set to 4, otherwise read efuse table secquence will be wrong.*/
30#define MAX_TX_COUNT 4
31#define TX_1S 0
32#define TX_2S 1
33
34#define MAX_POWER_INDEX 0x3F
35
36#define MAX_PRECMD_CNT 16
37#define MAX_RFDEPENDCMD_CNT 16
38#define MAX_POSTCMD_CNT 16
39
40#define MAX_DOZE_WAITING_TIMES_9x 64
41
42#define RT_CANNOT_IO(hw) false
43#define HIGHPOWER_RADIOA_ARRAYLEN 22
44
45#define IQK_ADDA_REG_NUM 16
46#define IQK_BB_REG_NUM 9
47#define MAX_TOLERANCE 5
48#define IQK_DELAY_TIME 10
49#define index_mapping_NUM 15
50
51#define APK_BB_REG_NUM 5
52#define APK_AFE_REG_NUM 16
53#define APK_CURVE_REG_NUM 4
54#define PATH_NUM 1
55
56#define LOOP_LIMIT 5
57#define MAX_STALL_TIME 50
58#define ANTENNADIVERSITYVALUE 0x80
59#define MAX_TXPWR_IDX_NMODE_92S 63
60#define RESET_CNT_LIMIT 3
61
62#define IQK_ADDA_REG_NUM 16
63#define IQK_MAC_REG_NUM 4
64
65#define RF6052_MAX_PATH 2
66
67#define CT_OFFSET_MAC_ADDR 0X16
68
69#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
70#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
71#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
72#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
73#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
74
75#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
76#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
77
78#define CT_OFFSET_CHANNEL_PLAH 0x75
79#define CT_OFFSET_THERMAL_METER 0x78
80#define CT_OFFSET_RF_OPTION 0x79
81#define CT_OFFSET_VERSION 0x7E
82#define CT_OFFSET_CUSTOMER_ID 0x7F
83
84#define RTL92C_MAX_PATH_NUM 2
85
86enum hw90_block_e {
87 HW90_BLOCK_MAC = 0,
88 HW90_BLOCK_PHY0 = 1,
89 HW90_BLOCK_PHY1 = 2,
90 HW90_BLOCK_RF = 3,
91 HW90_BLOCK_MAXIMUM = 4,
92};
93
94enum baseband_config_type {
95 BASEBAND_CONFIG_PHY_REG = 0,
96 BASEBAND_CONFIG_AGC_TAB = 1,
97};
98
99enum ra_offset_area {
100 RA_OFFSET_LEGACY_OFDM1,
101 RA_OFFSET_LEGACY_OFDM2,
102 RA_OFFSET_HT_OFDM1,
103 RA_OFFSET_HT_OFDM2,
104 RA_OFFSET_HT_OFDM3,
105 RA_OFFSET_HT_OFDM4,
106 RA_OFFSET_HT_CCK,
107};
108
109enum antenna_path {
110 ANTENNA_NONE,
111 ANTENNA_D,
112 ANTENNA_C,
113 ANTENNA_CD,
114 ANTENNA_B,
115 ANTENNA_BD,
116 ANTENNA_BC,
117 ANTENNA_BCD,
118 ANTENNA_A,
119 ANTENNA_AD,
120 ANTENNA_AC,
121 ANTENNA_ACD,
122 ANTENNA_AB,
123 ANTENNA_ABD,
124 ANTENNA_ABC,
125 ANTENNA_ABCD
126};
127
128struct r_antenna_select_ofdm {
129 u32 r_tx_antenna:4;
130 u32 r_ant_l:4;
131 u32 r_ant_non_ht:4;
132 u32 r_ant_ht1:4;
133 u32 r_ant_ht2:4;
134 u32 r_ant_ht_s1:4;
135 u32 r_ant_non_ht_s1:4;
136 u32 ofdm_txsc:2;
137 u32 reserved:2;
138};
139
140struct r_antenna_select_cck {
141 u8 r_cckrx_enable_2:2;
142 u8 r_cckrx_enable:2;
143 u8 r_ccktx_enable:4;
144};
145
146
147struct efuse_contents {
148 u8 mac_addr[ETH_ALEN];
149 u8 cck_tx_power_idx[6];
150 u8 ht40_1s_tx_power_idx[6];
151 u8 ht40_2s_tx_power_idx_diff[3];
152 u8 ht20_tx_power_idx_diff[3];
153 u8 ofdm_tx_power_idx_diff[3];
154 u8 ht40_max_power_offset[3];
155 u8 ht20_max_power_offset[3];
156 u8 channel_plan;
157 u8 thermal_meter;
158 u8 rf_option[5];
159 u8 version;
160 u8 oem_id;
161 u8 regulatory;
162};
163
164struct tx_power_struct {
165 u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
166 u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
167 u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
168 u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
169 u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
170 u8 legacy_ht_txpowerdiff;
171 u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
172 u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
173 u8 pwrgroup_cnt;
174 u32 mcs_original_offset[4][16];
175};
176
177enum _ANT_DIV_TYPE {
178 NO_ANTDIV = 0xFF,
179 CG_TRX_HW_ANTDIV = 0x01,
180 CGCS_RX_HW_ANTDIV = 0x02,
181 FIXED_HW_ANTDIV = 0x03,
182 CG_TRX_SMART_ANTDIV = 0x04,
183 CGCS_RX_SW_ANTDIV = 0x05,
184};
185
186u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw,
187 enum radio_path rfpath,
188 u32 regaddr, u32 bitmask);
189void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw,
190 enum radio_path rfpath,
191 u32 regaddr, u32 bitmask, u32 data);
192bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw);
193bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw);
194bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw);
195void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
196void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw,
197 long *powerlevel);
198void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw,
199 u8 channel);
200void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw,
201 u8 operation);
202void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
203void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
204 enum nl80211_channel_type ch_type);
205void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw);
206u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw);
207void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
208 bool b_recovery);
209void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
210void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw);
211void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
212bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
213 enum radio_path rfpath);
214bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
215bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
216 enum rf_pwrstate rfpwr_state);
217#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c
new file mode 100644
index 000000000000..b5167e73fecf
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c
@@ -0,0 +1,106 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "pwrseqcmd.h"
27#include "pwrseq.h"
28
29
30/* drivers should parse below arrays and do the corresponding actions */
31/*3 Power on Array*/
32struct wlan_pwr_cfg rtl8723B_power_on_flow[RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS +
33 RTL8723B_TRANS_END_STEPS] = {
34 RTL8723B_TRANS_CARDEMU_TO_ACT
35 RTL8723B_TRANS_END
36};
37
38/*3Radio off GPIO Array */
39struct wlan_pwr_cfg rtl8723B_radio_off_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS
40 + RTL8723B_TRANS_END_STEPS] = {
41 RTL8723B_TRANS_ACT_TO_CARDEMU
42 RTL8723B_TRANS_END
43};
44
45/*3Card Disable Array*/
46struct wlan_pwr_cfg rtl8723B_card_disable_flow
47 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
48 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
49 RTL8723B_TRANS_END_STEPS] = {
50 RTL8723B_TRANS_ACT_TO_CARDEMU
51 RTL8723B_TRANS_CARDEMU_TO_CARDDIS
52 RTL8723B_TRANS_END
53};
54
55/*3 Card Enable Array*/
56struct wlan_pwr_cfg rtl8723B_card_enable_flow
57 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
58 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
59 RTL8723B_TRANS_END_STEPS] = {
60 RTL8723B_TRANS_CARDDIS_TO_CARDEMU
61 RTL8723B_TRANS_CARDEMU_TO_ACT
62 RTL8723B_TRANS_END
63};
64
65/*3Suspend Array*/
66struct wlan_pwr_cfg rtl8723B_suspend_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
67 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS +
68 RTL8723B_TRANS_END_STEPS] = {
69 RTL8723B_TRANS_ACT_TO_CARDEMU
70 RTL8723B_TRANS_CARDEMU_TO_SUS
71 RTL8723B_TRANS_END
72};
73
74/*3 Resume Array*/
75struct wlan_pwr_cfg rtl8723B_resume_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
76 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS +
77 RTL8723B_TRANS_END_STEPS] = {
78 RTL8723B_TRANS_SUS_TO_CARDEMU
79 RTL8723B_TRANS_CARDEMU_TO_ACT
80 RTL8723B_TRANS_END
81};
82
83/*3HWPDN Array*/
84struct wlan_pwr_cfg rtl8723B_hwpdn_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
85 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
86 RTL8723B_TRANS_END_STEPS] = {
87 RTL8723B_TRANS_ACT_TO_CARDEMU
88 RTL8723B_TRANS_CARDEMU_TO_PDN
89 RTL8723B_TRANS_END
90};
91
92/*3 Enter LPS */
93struct wlan_pwr_cfg rtl8723B_enter_lps_flow[RTL8723B_TRANS_ACT_TO_LPS_STEPS +
94 RTL8723B_TRANS_END_STEPS] = {
95 /*FW behavior*/
96 RTL8723B_TRANS_ACT_TO_LPS
97 RTL8723B_TRANS_END
98};
99
100/*3 Leave LPS */
101struct wlan_pwr_cfg rtl8723B_leave_lps_flow[RTL8723B_TRANS_LPS_TO_ACT_STEPS +
102 RTL8723B_TRANS_END_STEPS] = {
103 /*FW behavior*/
104 RTL8723B_TRANS_LPS_TO_ACT
105 RTL8723B_TRANS_END
106};
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h
new file mode 100644
index 000000000000..a62f43ed8d32
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h
@@ -0,0 +1,304 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_PWRSEQ_H__
27#define __RTL8723BE_PWRSEQ_H__
28
29/* Check document WM-20130425-JackieLau-RTL8723B_Power_Architecture v05.vsd
30 * There are 6 HW Power States:
31 * 0: POFF--Power Off
32 * 1: PDN--Power Down
33 * 2: CARDEMU--Card Emulation
34 * 3: ACT--Active Mode
35 * 4: LPS--Low Power State
36 * 5: SUS--Suspend
37 *
38 * The transition from different states are defined below
39 * TRANS_CARDEMU_TO_ACT
40 * TRANS_ACT_TO_CARDEMU
41 * TRANS_CARDEMU_TO_SUS
42 * TRANS_SUS_TO_CARDEMU
43 * TRANS_CARDEMU_TO_PDN
44 * TRANS_ACT_TO_LPS
45 * TRANS_LPS_TO_ACT
46 *
47 * TRANS_END
48 */
49#define RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS 23
50#define RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS 15
51#define RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS 15
52#define RTL8723B_TRANS_SUS_TO_CARDEMU_STEPS 15
53#define RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS 15
54#define RTL8723B_TRANS_PDN_TO_CARDEMU_STEPS 15
55#define RTL8723B_TRANS_ACT_TO_LPS_STEPS 15
56#define RTL8723B_TRANS_LPS_TO_ACT_STEPS 15
57#define RTL8723B_TRANS_END_STEPS 1
58
59#define RTL8723B_TRANS_CARDEMU_TO_ACT \
60 {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
61 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
62 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
63 {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
64 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
65 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
66 {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
67 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
68 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS}, \
69 {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
70 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
71 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0}, \
72 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
73 PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)|BIT(2)), 0}, \
74 {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
75 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0) , 0}, \
76 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
77 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
78 {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
79 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0) , BIT(0)}, \
80 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
81 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
82 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
83 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \
84 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
85 PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \
86 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
87 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
88 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
89 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}, \
90 {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
91 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), BIT(6)}, \
92 {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
93 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
94 {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
95 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
96 {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
97 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
98 {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
99 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
100 {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
101 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
102 {0x0068, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\
103 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3), BIT(3)}, \
104 {0x0069, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
105 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), BIT(6)},
106
107#define RTL8723B_TRANS_ACT_TO_CARDEMU \
108 {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
109 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \
110 {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
111 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
112 {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
113 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
114 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
115 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
116 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
117 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, \
118 {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
119 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), 0}, \
120 {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
121 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \
122 PWR_CMD_WRITE, BIT(5), BIT(5)}, \
123 {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
124 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \
125 PWR_CMD_WRITE, BIT(0), 0},
126
127#define RTL8723B_TRANS_CARDEMU_TO_SUS \
128 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
129 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4) | BIT(3), (BIT(4) | BIT(3))}, \
130 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
131 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \
132 PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, \
133 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
134 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \
135 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
136 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, \
137 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
138 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)},\
139 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
140 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
141 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
142 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0},
143
144#define RTL8723B_TRANS_SUS_TO_CARDEMU \
145 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
146 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, \
147 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
148 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
149 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
150 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
151 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
152 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
153 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
154 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0},
155
156#define RTL8723B_TRANS_CARDEMU_TO_CARDDIS \
157 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
158 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, \
159 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
160 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
161 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, \
162 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
163 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, \
164 {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
165 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 1}, \
166 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
167 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \
168 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
169 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
170 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
171 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0},
172
173#define RTL8723B_TRANS_CARDDIS_TO_CARDEMU \
174 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
175 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, \
176 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
177 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
178 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
179 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
180 {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
181 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
182 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
183 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \
184 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
185 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
186 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
187 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},
188
189#define RTL8723B_TRANS_CARDEMU_TO_PDN \
190 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
191 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \
192 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
193 PWR_INTF_SDIO_MSK | PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, \
194 PWR_CMD_WRITE, 0xFF, 0x20}, \
195 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
196 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
197 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
198 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},
199
200#define RTL8723B_TRANS_PDN_TO_CARDEMU \
201 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
202 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},
203
204#define RTL8723B_TRANS_ACT_TO_LPS \
205 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
206 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
207 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
208 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
209 {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
210 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
211 {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
212 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
213 {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
214 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
215 {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
216 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
217 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
218 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
219 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
220 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \
221 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
222 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
223 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
224 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03}, \
225 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
226 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
227 {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
228 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00}, \
229 {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
230 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)},
231
232#define RTL8723B_TRANS_LPS_TO_ACT \
233 {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
234 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, \
235 {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
236 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \
237 {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
238 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \
239 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
240 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \
241 {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
242 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
243 {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
244 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \
245 {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
246 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \
247 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
248 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
249 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
250 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
251 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
252 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1) | BIT(0), BIT(1) | BIT(0)}, \
253 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
254 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},
255
256#define RTL8723B_TRANS_END \
257 {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, 0, \
258 PWR_CMD_END, 0, 0},
259
260extern struct wlan_pwr_cfg rtl8723B_power_on_flow
261 [RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS +
262 RTL8723B_TRANS_END_STEPS];
263extern struct wlan_pwr_cfg rtl8723B_radio_off_flow
264 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
265 RTL8723B_TRANS_END_STEPS];
266extern struct wlan_pwr_cfg rtl8723B_card_disable_flow
267 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
268 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
269 RTL8723B_TRANS_END_STEPS];
270extern struct wlan_pwr_cfg rtl8723B_card_enable_flow
271 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
272 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
273 RTL8723B_TRANS_END_STEPS];
274extern struct wlan_pwr_cfg rtl8723B_suspend_flow
275 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
276 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS +
277 RTL8723B_TRANS_END_STEPS];
278extern struct wlan_pwr_cfg rtl8723B_resume_flow
279 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
280 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS +
281 RTL8723B_TRANS_END_STEPS];
282extern struct wlan_pwr_cfg rtl8723B_hwpdn_flow
283 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
284 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
285 RTL8723B_TRANS_END_STEPS];
286extern struct wlan_pwr_cfg rtl8723B_enter_lps_flow
287 [RTL8723B_TRANS_ACT_TO_LPS_STEPS +
288 RTL8723B_TRANS_END_STEPS];
289extern struct wlan_pwr_cfg rtl8723B_leave_lps_flow
290 [RTL8723B_TRANS_LPS_TO_ACT_STEPS +
291 RTL8723B_TRANS_END_STEPS];
292
293/* RTL8723 Power Configuration CMDs for PCIe interface */
294#define RTL8723_NIC_PWR_ON_FLOW rtl8723B_power_on_flow
295#define RTL8723_NIC_RF_OFF_FLOW rtl8723B_radio_off_flow
296#define RTL8723_NIC_DISABLE_FLOW rtl8723B_card_disable_flow
297#define RTL8723_NIC_ENABLE_FLOW rtl8723B_card_enable_flow
298#define RTL8723_NIC_SUSPEND_FLOW rtl8723B_suspend_flow
299#define RTL8723_NIC_RESUME_FLOW rtl8723B_resume_flow
300#define RTL8723_NIC_PDN_FLOW rtl8723B_hwpdn_flow
301#define RTL8723_NIC_LPS_ENTER_FLOW rtl8723B_enter_lps_flow
302#define RTL8723_NIC_LPS_LEAVE_FLOW rtl8723B_leave_lps_flow
303
304#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c
new file mode 100644
index 000000000000..e4a507a756fb
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c
@@ -0,0 +1,140 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "pwrseq.h"
27
28/* Description:
29 * This routine deal with the Power Configuration CMDs
30 * parsing for RTL8723/RTL8188E Series IC.
31 * Assumption:
32 * We should follow specific format which was released from HW SD.
33 *
34 * 2011.07.07, added by Roger.
35 */
36bool rtlbe_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
37 u8 fab_version, u8 interface_type,
38 struct wlan_pwr_cfg pwrcfgcmd[])
39
40{
41 struct wlan_pwr_cfg pwr_cfg_cmd = {0};
42 bool b_polling_bit = false;
43 u32 ary_idx = 0;
44 u8 value = 0;
45 u32 offset = 0;
46 u32 polling_count = 0;
47 u32 max_polling_cnt = 5000;
48
49 do {
50 pwr_cfg_cmd = pwrcfgcmd[ary_idx];
51 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
52 "rtlbe_hal_pwrseqcmdparsing(): "
53 "offset(%#x),cut_msk(%#x), fab_msk(%#x),"
54 "interface_msk(%#x), base(%#x), "
55 "cmd(%#x), msk(%#x), value(%#x)\n",
56 GET_PWR_CFG_OFFSET(pwr_cfg_cmd),
57 GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd),
58 GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd),
59 GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd),
60 GET_PWR_CFG_BASE(pwr_cfg_cmd),
61 GET_PWR_CFG_CMD(pwr_cfg_cmd),
62 GET_PWR_CFG_MASK(pwr_cfg_cmd),
63 GET_PWR_CFG_VALUE(pwr_cfg_cmd));
64
65 if ((GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd)&fab_version) &&
66 (GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd)&cut_version) &&
67 (GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd)&interface_type)) {
68 switch (GET_PWR_CFG_CMD(pwr_cfg_cmd)) {
69 case PWR_CMD_READ:
70 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
71 "rtlbe_hal_pwrseqcmdparsing(): "
72 "PWR_CMD_READ\n");
73 break;
74 case PWR_CMD_WRITE:
75 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
76 "rtlbe_hal_pwrseqcmdparsing(): "
77 "PWR_CMD_WRITE\n");
78 offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd);
79
80 /*Read the value from system register*/
81 value = rtl_read_byte(rtlpriv, offset);
82 value &= (~(GET_PWR_CFG_MASK(pwr_cfg_cmd)));
83 value = value | (GET_PWR_CFG_VALUE(pwr_cfg_cmd)
84 & GET_PWR_CFG_MASK(pwr_cfg_cmd));
85
86 /*Write the value back to sytem register*/
87 rtl_write_byte(rtlpriv, offset, value);
88 break;
89 case PWR_CMD_POLLING:
90 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
91 "rtlbe_hal_pwrseqcmdparsing(): "
92 "PWR_CMD_POLLING\n");
93 b_polling_bit = false;
94 offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd);
95
96 do {
97 value = rtl_read_byte(rtlpriv, offset);
98
99 value &= GET_PWR_CFG_MASK(pwr_cfg_cmd);
100 if (value ==
101 (GET_PWR_CFG_VALUE(pwr_cfg_cmd) &
102 GET_PWR_CFG_MASK(pwr_cfg_cmd)))
103 b_polling_bit = true;
104 else
105 udelay(10);
106
107 if (polling_count++ > max_polling_cnt)
108 return false;
109
110 } while (!b_polling_bit);
111 break;
112 case PWR_CMD_DELAY:
113 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
114 "rtlbe_hal_pwrseqcmdparsing(): "
115 "PWR_CMD_DELAY\n");
116 if (GET_PWR_CFG_VALUE(pwr_cfg_cmd) ==
117 PWRSEQ_DELAY_US)
118 udelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd));
119 else
120 mdelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd));
121 break;
122 case PWR_CMD_END:
123 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
124 "rtlbe_hal_pwrseqcmdparsing(): "
125 "PWR_CMD_END\n");
126 return true;
127 break;
128 default:
129 RT_ASSERT(false,
130 "rtlbe_hal_pwrseqcmdparsing(): "
131 "Unknown CMD!!\n");
132 break;
133 }
134 }
135
136 ary_idx++;
137 } while (1);
138
139 return true;
140}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h
new file mode 100644
index 000000000000..ce14a3b5cb71
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h
@@ -0,0 +1,95 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_PWRSEQCMD_H__
27#define __RTL8723BE_PWRSEQCMD_H__
28
29#include "../wifi.h"
30/*---------------------------------------------*/
31/*The value of cmd: 4 bits */
32/*---------------------------------------------*/
33#define PWR_CMD_READ 0x00
34#define PWR_CMD_WRITE 0x01
35#define PWR_CMD_POLLING 0x02
36#define PWR_CMD_DELAY 0x03
37#define PWR_CMD_END 0x04
38
39/* define the base address of each block */
40#define PWR_BASEADDR_MAC 0x00
41#define PWR_BASEADDR_USB 0x01
42#define PWR_BASEADDR_PCIE 0x02
43#define PWR_BASEADDR_SDIO 0x03
44
45#define PWR_INTF_SDIO_MSK BIT(0)
46#define PWR_INTF_USB_MSK BIT(1)
47#define PWR_INTF_PCI_MSK BIT(2)
48#define PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
49
50#define PWR_FAB_TSMC_MSK BIT(0)
51#define PWR_FAB_UMC_MSK BIT(1)
52#define PWR_FAB_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
53
54#define PWR_CUT_TESTCHIP_MSK BIT(0)
55#define PWR_CUT_A_MSK BIT(1)
56#define PWR_CUT_B_MSK BIT(2)
57#define PWR_CUT_C_MSK BIT(3)
58#define PWR_CUT_D_MSK BIT(4)
59#define PWR_CUT_E_MSK BIT(5)
60#define PWR_CUT_F_MSK BIT(6)
61#define PWR_CUT_G_MSK BIT(7)
62#define PWR_CUT_ALL_MSK 0xFF
63
64
65enum pwrseq_delay_unit {
66 PWRSEQ_DELAY_US,
67 PWRSEQ_DELAY_MS,
68};
69
70struct wlan_pwr_cfg {
71 u16 offset;
72 u8 cut_msk;
73 u8 fab_msk:4;
74 u8 interface_msk:4;
75 u8 base:4;
76 u8 cmd:4;
77 u8 msk;
78 u8 value;
79
80};
81
82#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset
83#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk
84#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk
85#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) __PWR_CMD.interface_msk
86#define GET_PWR_CFG_BASE(__PWR_CMD) __PWR_CMD.base
87#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd
88#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk
89#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value
90
91bool rtlbe_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
92 u8 fab_version, u8 interface_type,
93 struct wlan_pwr_cfg pwrcfgcmd[]);
94
95#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
new file mode 100644
index 000000000000..4c653fab8795
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
@@ -0,0 +1,2277 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_REG_H__
27#define __RTL8723BE_REG_H__
28
29#define TXPKT_BUF_SELECT 0x69
30#define RXPKT_BUF_SELECT 0xA5
31#define DISABLE_TRXPKT_BUF_ACCESS 0x0
32
33#define REG_SYS_ISO_CTRL 0x0000
34#define REG_SYS_FUNC_EN 0x0002
35#define REG_APS_FSMCO 0x0004
36#define REG_SYS_CLKR 0x0008
37#define REG_9346CR 0x000A
38#define REG_EE_VPD 0x000C
39#define REG_AFE_MISC 0x0010
40#define REG_SPS0_CTRL 0x0011
41#define REG_SPS_OCP_CFG 0x0018
42#define REG_RSV_CTRL 0x001C
43#define REG_RF_CTRL 0x001F
44#define REG_LDOA15_CTRL 0x0020
45#define REG_LDOV12D_CTRL 0x0021
46#define REG_LDOHCI12_CTRL 0x0022
47#define REG_LPLDO_CTRL 0x0023
48#define REG_AFE_XTAL_CTRL 0x0024
49/* 1.5v for 8188EE test chip, 1.4v for MP chip */
50#define REG_AFE_LDO_CTRL 0x0027
51#define REG_AFE_PLL_CTRL 0x0028
52#define REG_MAC_PHY_CTRL 0x002c
53#define REG_EFUSE_CTRL 0x0030
54#define REG_EFUSE_TEST 0x0034
55#define REG_PWR_DATA 0x0038
56#define REG_CAL_TIMER 0x003C
57#define REG_ACLK_MON 0x003E
58#define REG_GPIO_MUXCFG 0x0040
59#define REG_GPIO_IO_SEL 0x0042
60#define REG_MAC_PINMUX_CFG 0x0043
61#define REG_GPIO_PIN_CTRL 0x0044
62#define REG_GPIO_INTM 0x0048
63#define REG_LEDCFG0 0x004C
64#define REG_LEDCFG1 0x004D
65#define REG_LEDCFG2 0x004E
66#define REG_LEDCFG3 0x004F
67#define REG_FSIMR 0x0050
68#define REG_FSISR 0x0054
69#define REG_HSIMR 0x0058
70#define REG_HSISR 0x005c
71#define REG_GPIO_PIN_CTRL_2 0x0060
72#define REG_GPIO_IO_SEL_2 0x0062
73#define REG_MULTI_FUNC_CTRL 0x0068
74#define REG_GPIO_OUTPUT 0x006c
75#define REG_AFE_XTAL_CTRL_EXT 0x0078
76#define REG_XCK_OUT_CTRL 0x007c
77#define REG_MCUFWDL 0x0080
78#define REG_WOL_EVENT 0x0081
79#define REG_MCUTSTCFG 0x0084
80
81
82#define REG_HIMR 0x00B0
83#define REG_HISR 0x00B4
84#define REG_HIMRE 0x00B8
85#define REG_HISRE 0x00BC
86
87#define REG_EFUSE_ACCESS 0x00CF
88
89#define REG_BIST_SCAN 0x00D0
90#define REG_BIST_RPT 0x00D4
91#define REG_BIST_ROM_RPT 0x00D8
92#define REG_USB_SIE_INTF 0x00E0
93#define REG_PCIE_MIO_INTF 0x00E4
94#define REG_PCIE_MIO_INTD 0x00E8
95#define REG_HPON_FSM 0x00EC
96#define REG_SYS_CFG 0x00F0
97#define REG_GPIO_OUTSTS 0x00F4
98#define REG_SYS_CFG1 0x00F0
99#define REG_ROM_VERSION 0x00FD
100
101#define REG_CR 0x0100
102#define REG_PBP 0x0104
103#define REG_PKT_BUFF_ACCESS_CTRL 0x0106
104#define REG_TRXDMA_CTRL 0x010C
105#define REG_TRXFF_BNDY 0x0114
106#define REG_TRXFF_STATUS 0x0118
107#define REG_RXFF_PTR 0x011C
108
109#define REG_CPWM 0x012F
110#define REG_FWIMR 0x0130
111#define REG_FWISR 0x0134
112#define REG_PKTBUF_DBG_CTRL 0x0140
113#define REG_PKTBUF_DBG_DATA_L 0x0144
114#define REG_PKTBUF_DBG_DATA_H 0x0148
115#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL + 2)
116
117#define REG_TC0_CTRL 0x0150
118#define REG_TC1_CTRL 0x0154
119#define REG_TC2_CTRL 0x0158
120#define REG_TC3_CTRL 0x015C
121#define REG_TC4_CTRL 0x0160
122#define REG_TCUNIT_BASE 0x0164
123#define REG_MBIST_START 0x0174
124#define REG_MBIST_DONE 0x0178
125#define REG_MBIST_FAIL 0x017C
126#define REG_32K_CTRL 0x0194
127#define REG_C2HEVT_MSG_NORMAL 0x01A0
128#define REG_C2HEVT_CLEAR 0x01AF
129#define REG_C2HEVT_MSG_TEST 0x01B8
130#define REG_MCUTST_1 0x01c0
131#define REG_FMETHR 0x01C8
132#define REG_HMETFR 0x01CC
133#define REG_HMEBOX_0 0x01D0
134#define REG_HMEBOX_1 0x01D4
135#define REG_HMEBOX_2 0x01D8
136#define REG_HMEBOX_3 0x01DC
137
138#define REG_LLT_INIT 0x01E0
139#define REG_BB_ACCEESS_CTRL 0x01E8
140#define REG_BB_ACCESS_DATA 0x01EC
141
142#define REG_HMEBOX_EXT_0 0x01F0
143#define REG_HMEBOX_EXT_1 0x01F4
144#define REG_HMEBOX_EXT_2 0x01F8
145#define REG_HMEBOX_EXT_3 0x01FC
146
147#define REG_RQPN 0x0200
148#define REG_FIFOPAGE 0x0204
149#define REG_TDECTRL 0x0208
150#define REG_TXDMA_OFFSET_CHK 0x020C
151#define REG_TXDMA_STATUS 0x0210
152#define REG_RQPN_NPQ 0x0214
153
154#define REG_RXDMA_AGG_PG_TH 0x0280
155/* FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 */
156#define REG_FW_UPD_RDPTR 0x0284
157/* Control the RX DMA.*/
158#define REG_RXDMA_CONTROL 0x0286
159/* The number of packets in RXPKTBUF. */
160#define REG_RXPKT_NUM 0x0287
161
162#define REG_PCIE_CTRL_REG 0x0300
163#define REG_INT_MIG 0x0304
164#define REG_BCNQ_DESA 0x0308
165#define REG_HQ_DESA 0x0310
166#define REG_MGQ_DESA 0x0318
167#define REG_VOQ_DESA 0x0320
168#define REG_VIQ_DESA 0x0328
169#define REG_BEQ_DESA 0x0330
170#define REG_BKQ_DESA 0x0338
171#define REG_RX_DESA 0x0340
172
173#define REG_DBI 0x0348
174#define REG_MDIO 0x0354
175#define REG_DBG_SEL 0x0360
176#define REG_PCIE_HRPWM 0x0361
177#define REG_PCIE_HCPWM 0x0363
178#define REG_UART_CTRL 0x0364
179#define REG_WATCH_DOG 0x0368
180#define REG_UART_TX_DESA 0x0370
181#define REG_UART_RX_DESA 0x0378
182
183
184#define REG_HDAQ_DESA_NODEF 0x0000
185#define REG_CMDQ_DESA_NODEF 0x0000
186
187#define REG_VOQ_INFORMATION 0x0400
188#define REG_VIQ_INFORMATION 0x0404
189#define REG_BEQ_INFORMATION 0x0408
190#define REG_BKQ_INFORMATION 0x040C
191#define REG_MGQ_INFORMATION 0x0410
192#define REG_HGQ_INFORMATION 0x0414
193#define REG_BCNQ_INFORMATION 0x0418
194#define REG_TXPKT_EMPTY 0x041A
195
196
197#define REG_CPU_MGQ_INFORMATION 0x041C
198#define REG_FWHW_TXQ_CTRL 0x0420
199#define REG_HWSEQ_CTRL 0x0423
200#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
201#define REG_TXPKTBUF_MGQ_BDNY 0x0425
202#define REG_MULTI_BCNQ_EN 0x0426
203#define REG_MULTI_BCNQ_OFFSET 0x0427
204#define REG_SPEC_SIFS 0x0428
205#define REG_RL 0x042A
206#define REG_DARFRC 0x0430
207#define REG_RARFRC 0x0438
208#define REG_RRSR 0x0440
209#define REG_ARFR0 0x0444
210#define REG_ARFR1 0x0448
211#define REG_ARFR2 0x044C
212#define REG_ARFR3 0x0450
213#define REG_AMPDU_MAX_TIME 0x0456
214#define REG_AGGLEN_LMT 0x0458
215#define REG_AMPDU_MIN_SPACE 0x045C
216#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D
217#define REG_FAST_EDCA_CTRL 0x0460
218#define REG_RD_RESP_PKT_TH 0x0463
219#define REG_INIRTS_RATE_SEL 0x0480
220#define REG_INIDATA_RATE_SEL 0x0484
221#define REG_POWER_STATUS 0x04A4
222#define REG_POWER_STAGE1 0x04B4
223#define REG_POWER_STAGE2 0x04B8
224#define REG_PKT_LIFE_TIME 0x04C0
225#define REG_STBC_SETTING 0x04C4
226#define REG_PROT_MODE_CTRL 0x04C8
227#define REG_BAR_MODE_CTRL 0x04CC
228#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
229#define REG_EARLY_MODE_CONTROL 0x04D0
230#define REG_NQOS_SEQ 0x04DC
231#define REG_QOS_SEQ 0x04DE
232#define REG_NEED_CPU_HANDLE 0x04E0
233#define REG_PKT_LOSE_RPT 0x04E1
234#define REG_PTCL_ERR_STATUS 0x04E2
235#define REG_TX_RPT_CTRL 0x04EC
236#define REG_TX_RPT_TIME 0x04F0
237#define REG_DUMMY 0x04FC
238
239#define REG_EDCA_VO_PARAM 0x0500
240#define REG_EDCA_VI_PARAM 0x0504
241#define REG_EDCA_BE_PARAM 0x0508
242#define REG_EDCA_BK_PARAM 0x050C
243#define REG_BCNTCFG 0x0510
244#define REG_PIFS 0x0512
245#define REG_RDG_PIFS 0x0513
246#define REG_SIFS_CTX 0x0514
247#define REG_SIFS_TRX 0x0516
248#define REG_AGGR_BREAK_TIME 0x051A
249#define REG_SLOT 0x051B
250#define REG_TX_PTCL_CTRL 0x0520
251#define REG_TXPAUSE 0x0522
252#define REG_DIS_TXREQ_CLR 0x0523
253#define REG_RD_CTRL 0x0524
254#define REG_TBTT_PROHIBIT 0x0540
255#define REG_RD_NAV_NXT 0x0544
256#define REG_NAV_PROT_LEN 0x0546
257#define REG_BCN_CTRL 0x0550
258#define REG_USTIME_TSF 0x0551
259#define REG_MBID_NUM 0x0552
260#define REG_DUAL_TSF_RST 0x0553
261#define REG_BCN_INTERVAL 0x0554
262#define REG_MBSSID_BCN_SPACE 0x0554
263#define REG_DRVERLYINT 0x0558
264#define REG_BCNDMATIM 0x0559
265#define REG_ATIMWND 0x055A
266#define REG_BCN_MAX_ERR 0x055D
267#define REG_RXTSF_OFFSET_CCK 0x055E
268#define REG_RXTSF_OFFSET_OFDM 0x055F
269#define REG_TSFTR 0x0560
270#define REG_INIT_TSFTR 0x0564
271#define REG_SECONDARY_CCA_CTRL 0x0577
272#define REG_PSTIMER 0x0580
273#define REG_TIMER0 0x0584
274#define REG_TIMER1 0x0588
275#define REG_ACMHWCTRL 0x05C0
276#define REG_ACMRSTCTRL 0x05C1
277#define REG_ACMAVG 0x05C2
278#define REG_VO_ADMTIME 0x05C4
279#define REG_VI_ADMTIME 0x05C6
280#define REG_BE_ADMTIME 0x05C8
281#define REG_EDCA_RANDOM_GEN 0x05CC
282#define REG_SCH_TXCMD 0x05D0
283
284#define REG_APSD_CTRL 0x0600
285#define REG_BWOPMODE 0x0603
286#define REG_TCR 0x0604
287#define REG_RCR 0x0608
288#define REG_RX_PKT_LIMIT 0x060C
289#define REG_RX_DLK_TIME 0x060D
290#define REG_RX_DRVINFO_SZ 0x060F
291
292#define REG_MACID 0x0610
293#define REG_BSSID 0x0618
294#define REG_MAR 0x0620
295#define REG_MBIDCAMCFG 0x0628
296
297#define REG_USTIME_EDCA 0x0638
298#define REG_MAC_SPEC_SIFS 0x063A
299#define REG_RESP_SIFS_CCK 0x063C
300#define REG_RESP_SIFS_OFDM 0x063E
301#define REG_ACKTO 0x0640
302#define REG_CTS2TO 0x0641
303#define REG_EIFS 0x0642
304
305#define REG_NAV_CTRL 0x0650
306#define REG_BACAMCMD 0x0654
307#define REG_BACAMCONTENT 0x0658
308#define REG_LBDLY 0x0660
309#define REG_FWDLY 0x0661
310#define REG_RXERR_RPT 0x0664
311#define REG_TRXPTCL_CTL 0x0668
312
313#define REG_CAMCMD 0x0670
314#define REG_CAMWRITE 0x0674
315#define REG_CAMREAD 0x0678
316#define REG_CAMDBG 0x067C
317#define REG_SECCFG 0x0680
318
319#define REG_WOW_CTRL 0x0690
320#define REG_PSSTATUS 0x0691
321#define REG_PS_RX_INFO 0x0692
322#define REG_UAPSD_TID 0x0693
323#define REG_LPNAV_CTRL 0x0694
324#define REG_WKFMCAM_NUM 0x0698
325#define REG_WKFMCAM_RWD 0x069C
326#define REG_RXFLTMAP0 0x06A0
327#define REG_RXFLTMAP1 0x06A2
328#define REG_RXFLTMAP2 0x06A4
329#define REG_BCN_PSR_RPT 0x06A8
330#define REG_CALB32K_CTRL 0x06AC
331#define REG_PKT_MON_CTRL 0x06B4
332#define REG_BT_COEX_TABLE 0x06C0
333#define REG_WMAC_RESP_TXINFO 0x06D8
334
335#define REG_USB_INFO 0xFE17
336#define REG_USB_SPECIAL_OPTION 0xFE55
337#define REG_USB_DMA_AGG_TO 0xFE5B
338#define REG_USB_AGG_TO 0xFE5C
339#define REG_USB_AGG_TH 0xFE5D
340
341#define REG_TEST_USB_TXQS 0xFE48
342#define REG_TEST_SIE_VID 0xFE60
343#define REG_TEST_SIE_PID 0xFE62
344#define REG_TEST_SIE_OPTIONAL 0xFE64
345#define REG_TEST_SIE_CHIRP_K 0xFE65
346#define REG_TEST_SIE_PHY 0xFE66
347#define REG_TEST_SIE_MAC_ADDR 0xFE70
348#define REG_TEST_SIE_STRING 0xFE80
349
350#define REG_NORMAL_SIE_VID 0xFE60
351#define REG_NORMAL_SIE_PID 0xFE62
352#define REG_NORMAL_SIE_OPTIONAL 0xFE64
353#define REG_NORMAL_SIE_EP 0xFE65
354#define REG_NORMAL_SIE_PHY 0xFE68
355#define REG_NORMAL_SIE_MAC_ADDR 0xFE70
356#define REG_NORMAL_SIE_STRING 0xFE80
357
358#define CR9346 REG_9346CR
359#define MSR (REG_CR + 2)
360#define ISR REG_HISR
361#define TSFR REG_TSFTR
362
363#define MACIDR0 REG_MACID
364#define MACIDR4 (REG_MACID + 4)
365
366#define PBP REG_PBP
367
368#define IDR0 MACIDR0
369#define IDR4 MACIDR4
370
371#define UNUSED_REGISTER 0x1BF
372#define DCAM UNUSED_REGISTER
373#define PSR UNUSED_REGISTER
374#define BBADDR UNUSED_REGISTER
375#define PHYDATAR UNUSED_REGISTER
376
377#define INVALID_BBRF_VALUE 0x12345678
378
379#define MAX_MSS_DENSITY_2T 0x13
380#define MAX_MSS_DENSITY_1T 0x0A
381
382#define CMDEEPROM_EN BIT(5)
383#define CMDEEPROM_SEL BIT(4)
384#define CMD9346CR_9356SEL BIT(4)
385#define AUTOLOAD_EEPROM (CMDEEPROM_EN | CMDEEPROM_SEL)
386#define AUTOLOAD_EFUSE CMDEEPROM_EN
387
388#define GPIOSEL_GPIO 0
389#define GPIOSEL_ENBT BIT(5)
390
391#define GPIO_IN REG_GPIO_PIN_CTRL
392#define GPIO_OUT (REG_GPIO_PIN_CTRL + 1)
393#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL + 2)
394#define GPIO_MOD (REG_GPIO_PIN_CTRL + 3)
395
396/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */
397#define HSIMR_GPIO12_0_INT_EN BIT(0)
398#define HSIMR_SPS_OCP_INT_EN BIT(5)
399#define HSIMR_RON_INT_EN BIT(6)
400#define HSIMR_PDN_INT_EN BIT(7)
401#define HSIMR_GPIO9_INT_EN BIT(25)
402
403/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */
404
405#define HSISR_GPIO12_0_INT BIT(0)
406#define HSISR_SPS_OCP_INT BIT(5)
407#define HSISR_RON_INT_EN BIT(6)
408#define HSISR_PDNINT BIT(7)
409#define HSISR_GPIO9_INT BIT(25)
410
411#define MSR_NOLINK 0x00
412#define MSR_ADHOC 0x01
413#define MSR_INFRA 0x02
414#define MSR_AP 0x03
415
416#define RRSR_RSC_OFFSET 21
417#define RRSR_SHORT_OFFSET 23
418#define RRSR_RSC_BW_40M 0x600000
419#define RRSR_RSC_UPSUBCHNL 0x400000
420#define RRSR_RSC_LOWSUBCHNL 0x200000
421#define RRSR_SHORT 0x800000
422#define RRSR_1M BIT(0)
423#define RRSR_2M BIT(1)
424#define RRSR_5_5M BIT(2)
425#define RRSR_11M BIT(3)
426#define RRSR_6M BIT(4)
427#define RRSR_9M BIT(5)
428#define RRSR_12M BIT(6)
429#define RRSR_18M BIT(7)
430#define RRSR_24M BIT(8)
431#define RRSR_36M BIT(9)
432#define RRSR_48M BIT(10)
433#define RRSR_54M BIT(11)
434#define RRSR_MCS0 BIT(12)
435#define RRSR_MCS1 BIT(13)
436#define RRSR_MCS2 BIT(14)
437#define RRSR_MCS3 BIT(15)
438#define RRSR_MCS4 BIT(16)
439#define RRSR_MCS5 BIT(17)
440#define RRSR_MCS6 BIT(18)
441#define RRSR_MCS7 BIT(19)
442#define BRSR_ACKSHORTPMB BIT(23)
443
444#define RATR_1M 0x00000001
445#define RATR_2M 0x00000002
446#define RATR_55M 0x00000004
447#define RATR_11M 0x00000008
448#define RATR_6M 0x00000010
449#define RATR_9M 0x00000020
450#define RATR_12M 0x00000040
451#define RATR_18M 0x00000080
452#define RATR_24M 0x00000100
453#define RATR_36M 0x00000200
454#define RATR_48M 0x00000400
455#define RATR_54M 0x00000800
456#define RATR_MCS0 0x00001000
457#define RATR_MCS1 0x00002000
458#define RATR_MCS2 0x00004000
459#define RATR_MCS3 0x00008000
460#define RATR_MCS4 0x00010000
461#define RATR_MCS5 0x00020000
462#define RATR_MCS6 0x00040000
463#define RATR_MCS7 0x00080000
464#define RATR_MCS8 0x00100000
465#define RATR_MCS9 0x00200000
466#define RATR_MCS10 0x00400000
467#define RATR_MCS11 0x00800000
468#define RATR_MCS12 0x01000000
469#define RATR_MCS13 0x02000000
470#define RATR_MCS14 0x04000000
471#define RATR_MCS15 0x08000000
472
473#define RATE_1M BIT(0)
474#define RATE_2M BIT(1)
475#define RATE_5_5M BIT(2)
476#define RATE_11M BIT(3)
477#define RATE_6M BIT(4)
478#define RATE_9M BIT(5)
479#define RATE_12M BIT(6)
480#define RATE_18M BIT(7)
481#define RATE_24M BIT(8)
482#define RATE_36M BIT(9)
483#define RATE_48M BIT(10)
484#define RATE_54M BIT(11)
485#define RATE_MCS0 BIT(12)
486#define RATE_MCS1 BIT(13)
487#define RATE_MCS2 BIT(14)
488#define RATE_MCS3 BIT(15)
489#define RATE_MCS4 BIT(16)
490#define RATE_MCS5 BIT(17)
491#define RATE_MCS6 BIT(18)
492#define RATE_MCS7 BIT(19)
493#define RATE_MCS8 BIT(20)
494#define RATE_MCS9 BIT(21)
495#define RATE_MCS10 BIT(22)
496#define RATE_MCS11 BIT(23)
497#define RATE_MCS12 BIT(24)
498#define RATE_MCS13 BIT(25)
499#define RATE_MCS14 BIT(26)
500#define RATE_MCS15 BIT(27)
501
502#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
503#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\
504 RATR_24M | RATR_36M | RATR_48M | RATR_54M)
505#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\
506 RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\
507 RATR_MCS6 | RATR_MCS7)
508#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\
509 RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\
510 RATR_MCS14 | RATR_MCS15)
511
512#define BW_OPMODE_20MHZ BIT(2)
513#define BW_OPMODE_5G BIT(1)
514#define BW_OPMODE_11J BIT(0)
515
516#define CAM_VALID BIT(15)
517#define CAM_NOTVALID 0x0000
518#define CAM_USEDK BIT(5)
519
520#define CAM_NONE 0x0
521#define CAM_WEP40 0x01
522#define CAM_TKIP 0x02
523#define CAM_AES 0x04
524#define CAM_WEP104 0x05
525
526#define TOTAL_CAM_ENTRY 32
527#define HALF_CAM_ENTRY 16
528
529#define CAM_WRITE BIT(16)
530#define CAM_READ 0x00000000
531#define CAM_POLLINIG BIT(31)
532
533#define SCR_USEDK 0x01
534#define SCR_TXSEC_ENABLE 0x02
535#define SCR_RXSEC_ENABLE 0x04
536
537#define WOW_PMEN BIT(0)
538#define WOW_WOMEN BIT(1)
539#define WOW_MAGIC BIT(2)
540#define WOW_UWF BIT(3)
541
542/*********************************************
543* 8723BE IMR/ISR bits
544**********************************************/
545#define IMR_DISABLED 0x0
546/* IMR DW0(0x0060-0063) Bit 0-31 */
547#define IMR_TXCCK BIT(30) /* TXRPT interrupt when
548 * CCX bit of the packet is set
549 */
550#define IMR_PSTIMEOUT BIT(29) /* Power Save Time Out Interrupt */
551#define IMR_GTINT4 BIT(28) /* When GTIMER4 expires,
552 * this bit is set to 1
553 */
554#define IMR_GTINT3 BIT(27) /* When GTIMER3 expires,
555 * this bit is set to 1
556 */
557#define IMR_TBDER BIT(26) /* Transmit Beacon0 Error */
558#define IMR_TBDOK BIT(25) /* Transmit Beacon0 OK */
559#define IMR_TSF_BIT32_TOGGLE BIT(24) /* TSF Timer BIT32 toggle
560 * indication interrupt
561 */
562#define IMR_BCNDMAINT0 BIT(20) /* Beacon DMA Interrupt 0 */
563#define IMR_BCNDOK0 BIT(16) /* Beacon Queue DMA OK0 */
564#define IMR_HSISR_IND_ON_INT BIT(15) /* HSISR Indicator (HSIMR & HSISR is
565 * true, this bit is set to 1)
566 */
567#define IMR_BCNDMAINT_E BIT(14) /* Beacon DMA Interrupt
568 * Extension for Win7
569 */
570#define IMR_ATIMEND BIT(12) /* CTWidnow End or ATIM Window End */
571#define IMR_HISR1_IND_INT BIT(11) /* HISR1 Indicator (HISR1 & HIMR1 is
572 * true, this bit is set to 1)
573 */
574#define IMR_C2HCMD BIT(10) /* CPU to Host Command INT Status,
575 * Write 1 clear
576 */
577#define IMR_CPWM2 BIT(9) /* CPU power Mode exchange INT Status,
578 * Write 1 clear
579 */
580#define IMR_CPWM BIT(8) /* CPU power Mode exchange INT Status,
581 * Write 1 clear
582 */
583#define IMR_HIGHDOK BIT(7) /* High Queue DMA OK */
584#define IMR_MGNTDOK BIT(6) /* Management Queue DMA OK */
585#define IMR_BKDOK BIT(5) /* AC_BK DMA OK */
586#define IMR_BEDOK BIT(4) /* AC_BE DMA OK */
587#define IMR_VIDOK BIT(3) /* AC_VI DMA OK */
588#define IMR_VODOK BIT(2) /* AC_VO DMA OK */
589#define IMR_RDU BIT(1) /* Rx Descriptor Unavailable */
590#define IMR_ROK BIT(0) /* Receive DMA OK */
591
592/* IMR DW1(0x00B4-00B7) Bit 0-31 */
593#define IMR_BCNDMAINT7 BIT(27) /* Beacon DMA Interrupt 7 */
594#define IMR_BCNDMAINT6 BIT(26) /* Beacon DMA Interrupt 6 */
595#define IMR_BCNDMAINT5 BIT(25) /* Beacon DMA Interrupt 5 */
596#define IMR_BCNDMAINT4 BIT(24) /* Beacon DMA Interrupt 4 */
597#define IMR_BCNDMAINT3 BIT(23) /* Beacon DMA Interrupt 3 */
598#define IMR_BCNDMAINT2 BIT(22) /* Beacon DMA Interrupt 2 */
599#define IMR_BCNDMAINT1 BIT(21) /* Beacon DMA Interrupt 1 */
600#define IMR_BCNDOK7 BIT(20) /* Beacon Queue DMA OK Interrup 7 */
601#define IMR_BCNDOK6 BIT(19) /* Beacon Queue DMA OK Interrup 6 */
602#define IMR_BCNDOK5 BIT(18) /* Beacon Queue DMA OK Interrup 5 */
603#define IMR_BCNDOK4 BIT(17) /* Beacon Queue DMA OK Interrup 4 */
604#define IMR_BCNDOK3 BIT(16) /* Beacon Queue DMA OK Interrup 3 */
605#define IMR_BCNDOK2 BIT(15) /* Beacon Queue DMA OK Interrup 2 */
606#define IMR_BCNDOK1 BIT(14) /* Beacon Queue DMA OK Interrup 1 */
607#define IMR_ATIMEND_E BIT(13) /* ATIM Window End Extension for Win7 */
608#define IMR_TXERR BIT(11) /* Tx Error Flag Interrupt Status,
609 * write 1 clear.
610 */
611#define IMR_RXERR BIT(10) /* Rx Error Flag INT Status,
612 * Write 1 clear
613 */
614#define IMR_TXFOVW BIT(9) /* Transmit FIFO Overflow */
615#define IMR_RXFOVW BIT(8) /* Receive FIFO Overflow */
616
617#define HWSET_MAX_SIZE 512
618#define EFUSE_MAX_SECTION 64
619#define EFUSE_REAL_CONTENT_LEN 256
620#define EFUSE_OOB_PROTECT_BYTES 18 /* PG data exclude header,
621 * dummy 7 bytes frome CP test
622 * and reserved 1byte.
623 */
624
625#define EEPROM_DEFAULT_TSSI 0x0
626#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
627#define EEPROM_DEFAULT_CRYSTALCAP 0x5
628#define EEPROM_DEFAULT_BOARDTYPE 0x02
629#define EEPROM_DEFAULT_TXPOWER 0x1010
630#define EEPROM_DEFAULT_HT2T_TXPWR 0x10
631
632#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
633#define EEPROM_DEFAULT_THERMALMETER 0x18
634#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0
635#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5
636#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22
637#define EEPROM_DEFAULT_HT40_2SDIFF 0x0
638#define EEPROM_DEFAULT_HT20_DIFF 2
639#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
640#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0
641#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0
642
643#define RF_OPTION1 0x79
644#define RF_OPTION2 0x7A
645#define RF_OPTION3 0x7B
646#define RF_OPTION4 0xC3
647
648#define EEPROM_DEFAULT_PID 0x1234
649#define EEPROM_DEFAULT_VID 0x5678
650#define EEPROM_DEFAULT_CUSTOMERID 0xAB
651#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD
652#define EEPROM_DEFAULT_VERSION 0
653
654#define EEPROM_CHANNEL_PLAN_FCC 0x0
655#define EEPROM_CHANNEL_PLAN_IC 0x1
656#define EEPROM_CHANNEL_PLAN_ETSI 0x2
657#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
658#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
659#define EEPROM_CHANNEL_PLAN_MKK 0x5
660#define EEPROM_CHANNEL_PLAN_MKK1 0x6
661#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
662#define EEPROM_CHANNEL_PLAN_TELEC 0x8
663#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
664#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
665#define EEPROM_CHANNEL_PLAN_NCC 0xB
666#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
667
668#define EEPROM_CID_DEFAULT 0x0
669#define EEPROM_CID_TOSHIBA 0x4
670#define EEPROM_CID_CCX 0x10
671#define EEPROM_CID_QMI 0x0D
672#define EEPROM_CID_WHQL 0xFE
673
674#define RTL8723BE_EEPROM_ID 0x8129
675
676#define EEPROM_HPON 0x02
677#define EEPROM_CLK 0x06
678#define EEPROM_TESTR 0x08
679
680
681#define EEPROM_TXPOWERCCK 0x10
682#define EEPROM_TXPOWERHT40_1S 0x16
683#define EEPROM_TXPOWERHT20DIFF 0x1B
684#define EEPROM_TXPOWER_OFDMDIFF 0x1B
685
686
687
688#define EEPROM_TX_PWR_INX 0x10
689
690#define EEPROM_CHANNELPLAN 0xB8
691#define EEPROM_XTAL_8723BE 0xB9
692#define EEPROM_THERMAL_METER_88E 0xBA
693#define EEPROM_IQK_LCK_88E 0xBB
694
695#define EEPROM_RF_BOARD_OPTION_88E 0xC1
696#define EEPROM_RF_FEATURE_OPTION_88E 0xC2
697#define EEPROM_RF_BT_SETTING_88E 0xC3
698#define EEPROM_VERSION 0xC4
699#define EEPROM_CUSTOMER_ID 0xC5
700#define EEPROM_RF_ANTENNA_OPT_88E 0xC9
701
702#define EEPROM_MAC_ADDR 0xD0
703#define EEPROM_VID 0xD6
704#define EEPROM_DID 0xD8
705#define EEPROM_SVID 0xDA
706#define EEPROM_SMID 0xDC
707
708#define STOPBECON BIT(6)
709#define STOPHIGHT BIT(5)
710#define STOPMGT BIT(4)
711#define STOPVO BIT(3)
712#define STOPVI BIT(2)
713#define STOPBE BIT(1)
714#define STOPBK BIT(0)
715
716#define RCR_APPFCS BIT(31)
717#define RCR_APP_MIC BIT(30)
718#define RCR_APP_ICV BIT(29)
719#define RCR_APP_PHYST_RXFF BIT(28)
720#define RCR_APP_BA_SSN BIT(27)
721#define RCR_ENMBID BIT(24)
722#define RCR_LSIGEN BIT(23)
723#define RCR_MFBEN BIT(22)
724#define RCR_HTC_LOC_CTRL BIT(14)
725#define RCR_AMF BIT(13)
726#define RCR_ACF BIT(12)
727#define RCR_ADF BIT(11)
728#define RCR_AICV BIT(9)
729#define RCR_ACRC32 BIT(8)
730#define RCR_CBSSID_BCN BIT(7)
731#define RCR_CBSSID_DATA BIT(6)
732#define RCR_CBSSID RCR_CBSSID_DATA
733#define RCR_APWRMGT BIT(5)
734#define RCR_ADD3 BIT(4)
735#define RCR_AB BIT(3)
736#define RCR_AM BIT(2)
737#define RCR_APM BIT(1)
738#define RCR_AAP BIT(0)
739#define RCR_MXDMA_OFFSET 8
740#define RCR_FIFO_OFFSET 13
741
742#define RSV_CTRL 0x001C
743#define RD_CTRL 0x0524
744
745#define REG_USB_INFO 0xFE17
746#define REG_USB_SPECIAL_OPTION 0xFE55
747#define REG_USB_DMA_AGG_TO 0xFE5B
748#define REG_USB_AGG_TO 0xFE5C
749#define REG_USB_AGG_TH 0xFE5D
750
751#define REG_USB_VID 0xFE60
752#define REG_USB_PID 0xFE62
753#define REG_USB_OPTIONAL 0xFE64
754#define REG_USB_CHIRP_K 0xFE65
755#define REG_USB_PHY 0xFE66
756#define REG_USB_MAC_ADDR 0xFE70
757#define REG_USB_HRPWM 0xFE58
758#define REG_USB_HCPWM 0xFE57
759
760#define SW18_FPWM BIT(3)
761
762#define ISO_MD2PP BIT(0)
763#define ISO_UA2USB BIT(1)
764#define ISO_UD2CORE BIT(2)
765#define ISO_PA2PCIE BIT(3)
766#define ISO_PD2CORE BIT(4)
767#define ISO_IP2MAC BIT(5)
768#define ISO_DIOP BIT(6)
769#define ISO_DIOE BIT(7)
770#define ISO_EB2CORE BIT(8)
771#define ISO_DIOR BIT(9)
772
773#define PWC_EV25V BIT(14)
774#define PWC_EV12V BIT(15)
775
776#define FEN_BBRSTB BIT(0)
777#define FEN_BB_GLB_RSTN BIT(1)
778#define FEN_USBA BIT(2)
779#define FEN_UPLL BIT(3)
780#define FEN_USBD BIT(4)
781#define FEN_DIO_PCIE BIT(5)
782#define FEN_PCIEA BIT(6)
783#define FEN_PPLL BIT(7)
784#define FEN_PCIED BIT(8)
785#define FEN_DIOE BIT(9)
786#define FEN_CPUEN BIT(10)
787#define FEN_DCORE BIT(11)
788#define FEN_ELDR BIT(12)
789#define FEN_DIO_RF BIT(13)
790#define FEN_HWPDN BIT(14)
791#define FEN_MREGEN BIT(15)
792
793#define PFM_LDALL BIT(0)
794#define PFM_ALDN BIT(1)
795#define PFM_LDKP BIT(2)
796#define PFM_WOWL BIT(3)
797#define ENPDN BIT(4)
798#define PDN_PL BIT(5)
799#define APFM_ONMAC BIT(8)
800#define APFM_OFF BIT(9)
801#define APFM_RSM BIT(10)
802#define AFSM_HSUS BIT(11)
803#define AFSM_PCIE BIT(12)
804#define APDM_MAC BIT(13)
805#define APDM_HOST BIT(14)
806#define APDM_HPDN BIT(15)
807#define RDY_MACON BIT(16)
808#define SUS_HOST BIT(17)
809#define ROP_ALD BIT(20)
810#define ROP_PWR BIT(21)
811#define ROP_SPS BIT(22)
812#define SOP_MRST BIT(25)
813#define SOP_FUSE BIT(26)
814#define SOP_ABG BIT(27)
815#define SOP_AMB BIT(28)
816#define SOP_RCK BIT(29)
817#define SOP_A8M BIT(30)
818#define XOP_BTCK BIT(31)
819
820#define ANAD16V_EN BIT(0)
821#define ANA8M BIT(1)
822#define MACSLP BIT(4)
823#define LOADER_CLK_EN BIT(5)
824#define _80M_SSC_DIS BIT(7)
825#define _80M_SSC_EN_HO BIT(8)
826#define PHY_SSC_RSTB BIT(9)
827#define SEC_CLK_EN BIT(10)
828#define MAC_CLK_EN BIT(11)
829#define SYS_CLK_EN BIT(12)
830#define RING_CLK_EN BIT(13)
831
832#define BOOT_FROM_EEPROM BIT(4)
833#define EEPROM_EN BIT(5)
834
835#define AFE_BGEN BIT(0)
836#define AFE_MBEN BIT(1)
837#define MAC_ID_EN BIT(7)
838
839#define WLOCK_ALL BIT(0)
840#define WLOCK_00 BIT(1)
841#define WLOCK_04 BIT(2)
842#define WLOCK_08 BIT(3)
843#define WLOCK_40 BIT(4)
844#define R_DIS_PRST_0 BIT(5)
845#define R_DIS_PRST_1 BIT(6)
846#define LOCK_ALL_EN BIT(7)
847
848#define RF_EN BIT(0)
849#define RF_RSTB BIT(1)
850#define RF_SDMRSTB BIT(2)
851
852#define LDA15_EN BIT(0)
853#define LDA15_STBY BIT(1)
854#define LDA15_OBUF BIT(2)
855#define LDA15_REG_VOS BIT(3)
856#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
857
858#define LDV12_EN BIT(0)
859#define LDV12_SDBY BIT(1)
860#define LPLDO_HSM BIT(2)
861#define LPLDO_LSM_DIS BIT(3)
862#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
863
864#define XTAL_EN BIT(0)
865#define XTAL_BSEL BIT(1)
866#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
867#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
868#define XTAL_GATE_USB BIT(8)
869#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
870#define XTAL_GATE_AFE BIT(11)
871#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
872#define XTAL_RF_GATE BIT(14)
873#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
874#define XTAL_GATE_DIG BIT(17)
875#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
876#define XTAL_BT_GATE BIT(20)
877#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
878#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
879
880#define CKDLY_AFE BIT(26)
881#define CKDLY_USB BIT(27)
882#define CKDLY_DIG BIT(28)
883#define CKDLY_BT BIT(29)
884
885#define APLL_EN BIT(0)
886#define APLL_320_EN BIT(1)
887#define APLL_FREF_SEL BIT(2)
888#define APLL_EDGE_SEL BIT(3)
889#define APLL_WDOGB BIT(4)
890#define APLL_LPFEN BIT(5)
891
892#define APLL_REF_CLK_13MHZ 0x1
893#define APLL_REF_CLK_19_2MHZ 0x2
894#define APLL_REF_CLK_20MHZ 0x3
895#define APLL_REF_CLK_25MHZ 0x4
896#define APLL_REF_CLK_26MHZ 0x5
897#define APLL_REF_CLK_38_4MHZ 0x6
898#define APLL_REF_CLK_40MHZ 0x7
899
900#define APLL_320EN BIT(14)
901#define APLL_80EN BIT(15)
902#define APLL_1MEN BIT(24)
903
904#define ALD_EN BIT(18)
905#define EF_PD BIT(19)
906#define EF_FLAG BIT(31)
907
908#define EF_TRPT BIT(7)
909#define LDOE25_EN BIT(31)
910
911#define RSM_EN BIT(0)
912#define TIMER_EN BIT(4)
913
914#define TRSW0EN BIT(2)
915#define TRSW1EN BIT(3)
916#define EROM_EN BIT(4)
917#define ENBT BIT(5)
918#define ENUART BIT(8)
919#define UART_910 BIT(9)
920#define ENPMAC BIT(10)
921#define SIC_SWRST BIT(11)
922#define ENSIC BIT(12)
923#define SIC_23 BIT(13)
924#define ENHDP BIT(14)
925#define SIC_LBK BIT(15)
926
927#define LED0PL BIT(4)
928#define LED1PL BIT(12)
929#define LED0DIS BIT(7)
930
931#define MCUFWDL_EN BIT(0)
932#define MCUFWDL_RDY BIT(1)
933#define FWDL_CHKSUM_RPT BIT(2)
934#define MACINI_RDY BIT(3)
935#define BBINI_RDY BIT(4)
936#define RFINI_RDY BIT(5)
937#define WINTINI_RDY BIT(6)
938#define CPRST BIT(23)
939
940#define XCLK_VLD BIT(0)
941#define ACLK_VLD BIT(1)
942#define UCLK_VLD BIT(2)
943#define PCLK_VLD BIT(3)
944#define PCIRSTB BIT(4)
945#define V15_VLD BIT(5)
946#define TRP_B15V_EN BIT(7)
947#define SIC_IDLE BIT(8)
948#define BD_MAC2 BIT(9)
949#define BD_MAC1 BIT(10)
950#define IC_MACPHY_MODE BIT(11)
951#define VENDOR_ID BIT(19)
952#define PAD_HWPD_IDN BIT(22)
953#define TRP_VAUX_EN BIT(23)
954#define TRP_BT_EN BIT(24)
955#define BD_PKG_SEL BIT(25)
956#define BD_HCI_SEL BIT(26)
957#define TYPE_ID BIT(27)
958
959#define CHIP_VER_RTL_MASK 0xF000
960#define CHIP_VER_RTL_SHIFT 12
961
962#define REG_LBMODE (REG_CR + 3)
963
964#define HCI_TXDMA_EN BIT(0)
965#define HCI_RXDMA_EN BIT(1)
966#define TXDMA_EN BIT(2)
967#define RXDMA_EN BIT(3)
968#define PROTOCOL_EN BIT(4)
969#define SCHEDULE_EN BIT(5)
970#define MACTXEN BIT(6)
971#define MACRXEN BIT(7)
972#define ENSWBCN BIT(8)
973#define ENSEC BIT(9)
974
975#define _NETTYPE(x) (((x) & 0x3) << 16)
976#define MASK_NETTYPE 0x30000
977#define NT_NO_LINK 0x0
978#define NT_LINK_AD_HOC 0x1
979#define NT_LINK_AP 0x2
980#define NT_AS_AP 0x3
981
982#define _LBMODE(x) (((x) & 0xF) << 24)
983#define MASK_LBMODE 0xF000000
984#define LOOPBACK_NORMAL 0x0
985#define LOOPBACK_IMMEDIATELY 0xB
986#define LOOPBACK_MAC_DELAY 0x3
987#define LOOPBACK_PHY 0x1
988#define LOOPBACK_DMA 0x7
989
990#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
991#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
992#define _PSRX_MASK 0xF
993#define _PSTX_MASK 0xF0
994#define _PSRX(x) (x)
995#define _PSTX(x) ((x) << 4)
996
997#define PBP_64 0x0
998#define PBP_128 0x1
999#define PBP_256 0x2
1000#define PBP_512 0x3
1001#define PBP_1024 0x4
1002
1003#define RXDMA_ARBBW_EN BIT(0)
1004#define RXSHFT_EN BIT(1)
1005#define RXDMA_AGG_EN BIT(2)
1006#define QS_VO_QUEUE BIT(8)
1007#define QS_VI_QUEUE BIT(9)
1008#define QS_BE_QUEUE BIT(10)
1009#define QS_BK_QUEUE BIT(11)
1010#define QS_MANAGER_QUEUE BIT(12)
1011#define QS_HIGH_QUEUE BIT(13)
1012
1013#define HQSEL_VOQ BIT(0)
1014#define HQSEL_VIQ BIT(1)
1015#define HQSEL_BEQ BIT(2)
1016#define HQSEL_BKQ BIT(3)
1017#define HQSEL_MGTQ BIT(4)
1018#define HQSEL_HIQ BIT(5)
1019
1020#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14)
1021#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12)
1022#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10)
1023#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8)
1024#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6)
1025#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4)
1026
1027#define QUEUE_LOW 1
1028#define QUEUE_NORMAL 2
1029#define QUEUE_HIGH 3
1030
1031#define _LLT_NO_ACTIVE 0x0
1032#define _LLT_WRITE_ACCESS 0x1
1033#define _LLT_READ_ACCESS 0x2
1034
1035#define _LLT_INIT_DATA(x) ((x) & 0xFF)
1036#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
1037#define _LLT_OP(x) (((x) & 0x3) << 30)
1038#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
1039
1040#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
1041#define BB_WRITE_EN BIT(30)
1042#define BB_READ_EN BIT(31)
1043
1044#define _HPQ(x) ((x) & 0xFF)
1045#define _LPQ(x) (((x) & 0xFF) << 8)
1046#define _PUBQ(x) (((x) & 0xFF) << 16)
1047#define _NPQ(x) ((x) & 0xFF)
1048
1049#define HPQ_PUBLIC_DIS BIT(24)
1050#define LPQ_PUBLIC_DIS BIT(25)
1051#define LD_RQPN BIT(31)
1052
1053#define BCN_VALID BIT(16)
1054#define BCN_HEAD(x) (((x) & 0xFF) << 8)
1055#define BCN_HEAD_MASK 0xFF00
1056
1057#define BLK_DESC_NUM_SHIFT 4
1058#define BLK_DESC_NUM_MASK 0xF
1059
1060#define DROP_DATA_EN BIT(9)
1061
1062#define EN_AMPDU_RTY_NEW BIT(7)
1063
1064#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
1065
1066#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
1067#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
1068
1069#define RATE_REG_BITMAP_ALL 0xFFFFF
1070
1071#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
1072
1073#define _RRSR_RSC(x) (((x) & 0x3) << 21)
1074#define RRSR_RSC_RESERVED 0x0
1075#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
1076#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
1077#define RRSR_RSC_DUPLICATE_MODE 0x3
1078
1079#define USE_SHORT_G1 BIT(20)
1080
1081#define _AGGLMT_MCS0(x) ((x) & 0xF)
1082#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
1083#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
1084#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
1085#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
1086#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
1087#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
1088#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
1089
1090#define RETRY_LIMIT_SHORT_SHIFT 8
1091#define RETRY_LIMIT_LONG_SHIFT 0
1092
1093#define _DARF_RC1(x) ((x) & 0x1F)
1094#define _DARF_RC2(x) (((x) & 0x1F) << 8)
1095#define _DARF_RC3(x) (((x) & 0x1F) << 16)
1096#define _DARF_RC4(x) (((x) & 0x1F) << 24)
1097#define _DARF_RC5(x) ((x) & 0x1F)
1098#define _DARF_RC6(x) (((x) & 0x1F) << 8)
1099#define _DARF_RC7(x) (((x) & 0x1F) << 16)
1100#define _DARF_RC8(x) (((x) & 0x1F) << 24)
1101
1102#define _RARF_RC1(x) ((x) & 0x1F)
1103#define _RARF_RC2(x) (((x) & 0x1F) << 8)
1104#define _RARF_RC3(x) (((x) & 0x1F) << 16)
1105#define _RARF_RC4(x) (((x) & 0x1F) << 24)
1106#define _RARF_RC5(x) ((x) & 0x1F)
1107#define _RARF_RC6(x) (((x) & 0x1F) << 8)
1108#define _RARF_RC7(x) (((x) & 0x1F) << 16)
1109#define _RARF_RC8(x) (((x) & 0x1F) << 24)
1110
1111#define AC_PARAM_TXOP_LIMIT_OFFSET 16
1112#define AC_PARAM_ECW_MAX_OFFSET 12
1113#define AC_PARAM_ECW_MIN_OFFSET 8
1114#define AC_PARAM_AIFS_OFFSET 0
1115
1116#define _AIFS(x) (x)
1117#define _ECW_MAX_MIN(x) ((x) << 8)
1118#define _TXOP_LIMIT(x) ((x) << 16)
1119
1120#define _BCNIFS(x) ((x) & 0xFF)
1121#define _BCNECW(x) ((((x) & 0xF)) << 8)
1122
1123#define _LRL(x) ((x) & 0x3F)
1124#define _SRL(x) (((x) & 0x3F) << 8)
1125
1126#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
1127#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8)
1128
1129#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
1130#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8)
1131
1132#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
1133
1134#define DIS_EDCA_CNT_DWN BIT(11)
1135
1136#define EN_MBSSID BIT(1)
1137#define EN_TXBCN_RPT BIT(2)
1138#define EN_BCN_FUNCTION BIT(3)
1139
1140#define TSFTR_RST BIT(0)
1141#define TSFTR1_RST BIT(1)
1142
1143#define STOP_BCNQ BIT(6)
1144
1145#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
1146#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
1147
1148#define ACMHW_HWEN BIT(0)
1149#define ACMHW_BEQEN BIT(1)
1150#define ACMHW_VIQEN BIT(2)
1151#define ACMHW_VOQEN BIT(3)
1152#define ACMHW_BEQSTATUS BIT(4)
1153#define ACMHW_VIQSTATUS BIT(5)
1154#define ACMHW_VOQSTATUS BIT(6)
1155
1156#define APSDOFF BIT(6)
1157#define APSDOFF_STATUS BIT(7)
1158
1159#define BW_20MHZ BIT(2)
1160
1161#define RATE_BITMAP_ALL 0xFFFFF
1162
1163#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
1164
1165#define TSFRST BIT(0)
1166#define DIS_GCLK BIT(1)
1167#define PAD_SEL BIT(2)
1168#define PWR_ST BIT(6)
1169#define PWRBIT_OW_EN BIT(7)
1170#define ACRC BIT(8)
1171#define CFENDFORM BIT(9)
1172#define ICV BIT(10)
1173
1174#define AAP BIT(0)
1175#define APM BIT(1)
1176#define AM BIT(2)
1177#define AB BIT(3)
1178#define ADD3 BIT(4)
1179#define APWRMGT BIT(5)
1180#define CBSSID BIT(6)
1181#define CBSSID_DATA BIT(6)
1182#define CBSSID_BCN BIT(7)
1183#define ACRC32 BIT(8)
1184#define AICV BIT(9)
1185#define ADF BIT(11)
1186#define ACF BIT(12)
1187#define AMF BIT(13)
1188#define HTC_LOC_CTRL BIT(14)
1189#define UC_DATA_EN BIT(16)
1190#define BM_DATA_EN BIT(17)
1191#define MFBEN BIT(22)
1192#define LSIGEN BIT(23)
1193#define ENMBID BIT(24)
1194#define APP_BASSN BIT(27)
1195#define APP_PHYSTS BIT(28)
1196#define APP_ICV BIT(29)
1197#define APP_MIC BIT(30)
1198#define APP_FCS BIT(31)
1199
1200#define _MIN_SPACE(x) ((x) & 0x7)
1201#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
1202
1203#define RXERR_TYPE_OFDM_PPDU 0
1204#define RXERR_TYPE_OFDM_FALSE_ALARM 1
1205#define RXERR_TYPE_OFDM_MPDU_OK 2
1206#define RXERR_TYPE_OFDM_MPDU_FAIL 3
1207#define RXERR_TYPE_CCK_PPDU 4
1208#define RXERR_TYPE_CCK_FALSE_ALARM 5
1209#define RXERR_TYPE_CCK_MPDU_OK 6
1210#define RXERR_TYPE_CCK_MPDU_FAIL 7
1211#define RXERR_TYPE_HT_PPDU 8
1212#define RXERR_TYPE_HT_FALSE_ALARM 9
1213#define RXERR_TYPE_HT_MPDU_TOTAL 10
1214#define RXERR_TYPE_HT_MPDU_OK 11
1215#define RXERR_TYPE_HT_MPDU_FAIL 12
1216#define RXERR_TYPE_RX_FULL_DROP 15
1217
1218#define RXERR_COUNTER_MASK 0xFFFFF
1219#define RXERR_RPT_RST BIT(27)
1220#define _RXERR_RPT_SEL(type) ((type) << 28)
1221
1222#define SCR_TXUSEDK BIT(0)
1223#define SCR_RXUSEDK BIT(1)
1224#define SCR_TXENCENABLE BIT(2)
1225#define SCR_RXDECENABLE BIT(3)
1226#define SCR_SKBYA2 BIT(4)
1227#define SCR_NOSKMC BIT(5)
1228#define SCR_TXBCUSEDK BIT(6)
1229#define SCR_RXBCUSEDK BIT(7)
1230
1231#define XCLK_VLD BIT(0)
1232#define ACLK_VLD BIT(1)
1233#define UCLK_VLD BIT(2)
1234#define PCLK_VLD BIT(3)
1235#define PCIRSTB BIT(4)
1236#define V15_VLD BIT(5)
1237#define TRP_B15V_EN BIT(7)
1238#define SIC_IDLE BIT(8)
1239#define BD_MAC2 BIT(9)
1240#define BD_MAC1 BIT(10)
1241#define IC_MACPHY_MODE BIT(11)
1242#define BT_FUNC BIT(16)
1243#define VENDOR_ID BIT(19)
1244#define PAD_HWPD_IDN BIT(22)
1245#define TRP_VAUX_EN BIT(23)
1246#define TRP_BT_EN BIT(24)
1247#define BD_PKG_SEL BIT(25)
1248#define BD_HCI_SEL BIT(26)
1249#define TYPE_ID BIT(27)
1250
1251#define USB_IS_HIGH_SPEED 0
1252#define USB_IS_FULL_SPEED 1
1253#define USB_SPEED_MASK BIT(5)
1254
1255#define USB_NORMAL_SIE_EP_MASK 0xF
1256#define USB_NORMAL_SIE_EP_SHIFT 4
1257
1258#define USB_TEST_EP_MASK 0x30
1259#define USB_TEST_EP_SHIFT 4
1260
1261#define USB_AGG_EN BIT(3)
1262
1263#define MAC_ADDR_LEN 6
1264#define LAST_ENTRY_OF_TX_PKT_BUFFER 175/*255 88e*/
1265
1266#define POLLING_LLT_THRESHOLD 20
1267#define POLLING_READY_TIMEOUT_COUNT 3000
1268
1269#define MAX_MSS_DENSITY_2T 0x13
1270#define MAX_MSS_DENSITY_1T 0x0A
1271
1272#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
1273#define EPROM_CMD_CONFIG 0x3
1274#define EPROM_CMD_LOAD 1
1275
1276#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
1277
1278#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
1279
1280#define RPMAC_RESET 0x100
1281#define RPMAC_TXSTART 0x104
1282#define RPMAC_TXLEGACYSIG 0x108
1283#define RPMAC_TXHTSIG1 0x10c
1284#define RPMAC_TXHTSIG2 0x110
1285#define RPMAC_PHYDEBUG 0x114
1286#define RPMAC_TXPACKETNUM 0x118
1287#define RPMAC_TXIDLE 0x11c
1288#define RPMAC_TXMACHEADER0 0x120
1289#define RPMAC_TXMACHEADER1 0x124
1290#define RPMAC_TXMACHEADER2 0x128
1291#define RPMAC_TXMACHEADER3 0x12c
1292#define RPMAC_TXMACHEADER4 0x130
1293#define RPMAC_TXMACHEADER5 0x134
1294#define RPMAC_TXDADATYPE 0x138
1295#define RPMAC_TXRANDOMSEED 0x13c
1296#define RPMAC_CCKPLCPPREAMBLE 0x140
1297#define RPMAC_CCKPLCPHEADER 0x144
1298#define RPMAC_CCKCRC16 0x148
1299#define RPMAC_OFDMRXCRC32OK 0x170
1300#define RPMAC_OFDMRXCRC32ER 0x174
1301#define RPMAC_OFDMRXPARITYER 0x178
1302#define RPMAC_OFDMRXCRC8ER 0x17c
1303#define RPMAC_CCKCRXRC16ER 0x180
1304#define RPMAC_CCKCRXRC32ER 0x184
1305#define RPMAC_CCKCRXRC32OK 0x188
1306#define RPMAC_TXSTATUS 0x18c
1307
1308#define RFPGA0_RFMOD 0x800
1309
1310#define RFPGA0_TXINFO 0x804
1311#define RFPGA0_PSDFUNCTION 0x808
1312
1313#define RFPGA0_TXGAINSTAGE 0x80c
1314
1315#define RFPGA0_RFTIMING1 0x810
1316#define RFPGA0_RFTIMING2 0x814
1317
1318#define RFPGA0_XA_HSSIPARAMETER1 0x820
1319#define RFPGA0_XA_HSSIPARAMETER2 0x824
1320#define RFPGA0_XB_HSSIPARAMETER1 0x828
1321#define RFPGA0_XB_HSSIPARAMETER2 0x82c
1322
1323#define RFPGA0_XA_LSSIPARAMETER 0x840
1324#define RFPGA0_XB_LSSIPARAMETER 0x844
1325
1326#define RFPGA0_RFWAKEUPPARAMETER 0x850
1327#define RFPGA0_RFSLEEPUPPARAMETER 0x854
1328
1329#define RFPGA0_XAB_SWITCHCONTROL 0x858
1330#define RFPGA0_XCD_SWITCHCONTROL 0x85c
1331
1332#define RFPGA0_XA_RFINTERFACEOE 0x860
1333#define RFPGA0_XB_RFINTERFACEOE 0x864
1334
1335#define RFPGA0_XAB_RFINTERFACESW 0x870
1336#define RFPGA0_XCD_RFINTERFACESW 0x874
1337
1338#define RFPGA0_XAB_RFPARAMETER 0x878
1339#define RFPGA0_XCD_RFPARAMETER 0x87c
1340
1341#define RFPGA0_ANALOGPARAMETER1 0x880
1342#define RFPGA0_ANALOGPARAMETER2 0x884
1343#define RFPGA0_ANALOGPARAMETER3 0x888
1344#define RFPGA0_ANALOGPARAMETER4 0x88c
1345
1346#define RFPGA0_XA_LSSIREADBACK 0x8a0
1347#define RFPGA0_XB_LSSIREADBACK 0x8a4
1348#define RFPGA0_XC_LSSIREADBACK 0x8a8
1349#define RFPGA0_XD_LSSIREADBACK 0x8ac
1350
1351#define RFPGA0_PSDREPORT 0x8b4
1352#define TRANSCEIVEA_HSPI_READBACK 0x8b8
1353#define TRANSCEIVEB_HSPI_READBACK 0x8bc
1354#define REG_SC_CNT 0x8c4
1355#define RFPGA0_XAB_RFINTERFACERB 0x8e0
1356#define RFPGA0_XCD_RFINTERFACERB 0x8e4
1357
1358#define RFPGA1_RFMOD 0x900
1359
1360#define RFPGA1_TXBLOCK 0x904
1361#define RFPGA1_DEBUGSELECT 0x908
1362#define RFPGA1_TXINFO 0x90c
1363
1364#define RCCK0_SYSTEM 0xa00
1365
1366#define RCCK0_AFESETTING 0xa04
1367#define RCCK0_CCA 0xa08
1368
1369#define RCCK0_RXAGC1 0xa0c
1370#define RCCK0_RXAGC2 0xa10
1371
1372#define RCCK0_RXHP 0xa14
1373
1374#define RCCK0_DSPPARAMETER1 0xa18
1375#define RCCK0_DSPPARAMETER2 0xa1c
1376
1377#define RCCK0_TXFILTER1 0xa20
1378#define RCCK0_TXFILTER2 0xa24
1379#define RCCK0_DEBUGPORT 0xa28
1380#define RCCK0_FALSEALARMREPORT 0xa2c
1381#define RCCK0_TRSSIREPORT 0xa50
1382#define RCCK0_RXREPORT 0xa54
1383#define RCCK0_FACOUNTERLOWER 0xa5c
1384#define RCCK0_FACOUNTERUPPER 0xa58
1385#define RCCK0_CCA_CNT 0xa60
1386
1387
1388/* PageB(0xB00) */
1389#define RPDP_ANTA 0xb00
1390#define RPDP_ANTA_4 0xb04
1391#define RPDP_ANTA_8 0xb08
1392#define RPDP_ANTA_C 0xb0c
1393#define RPDP_ANTA_10 0xb10
1394#define RPDP_ANTA_14 0xb14
1395#define RPDP_ANTA_18 0xb18
1396#define RPDP_ANTA_1C 0xb1c
1397#define RPDP_ANTA_20 0xb20
1398#define RPDP_ANTA_24 0xb24
1399
1400#define RCONFIG_PMPD_ANTA 0xb28
1401#define CONFIG_RAM64X16 0xb2c
1402
1403#define RBNDA 0xb30
1404#define RHSSIPAR 0xb34
1405
1406#define RCONFIG_ANTA 0xb68
1407#define RCONFIG_ANTB 0xb6c
1408
1409#define RPDP_ANTB 0xb70
1410#define RPDP_ANTB_4 0xb74
1411#define RPDP_ANTB_8 0xb78
1412#define RPDP_ANTB_C 0xb7c
1413#define RPDP_ANTB_10 0xb80
1414#define RPDP_ANTB_14 0xb84
1415#define RPDP_ANTB_18 0xb88
1416#define RPDP_ANTB_1C 0xb8c
1417#define RPDP_ANTB_20 0xb90
1418#define RPDP_ANTB_24 0xb94
1419
1420#define RCONFIG_PMPD_ANTB 0xb98
1421
1422#define RBNDB 0xba0
1423
1424#define RAPK 0xbd8
1425#define RPM_RX0_ANTA 0xbdc
1426#define RPM_RX1_ANTA 0xbe0
1427#define RPM_RX2_ANTA 0xbe4
1428#define RPM_RX3_ANTA 0xbe8
1429#define RPM_RX0_ANTB 0xbec
1430#define RPM_RX1_ANTB 0xbf0
1431#define RPM_RX2_ANTB 0xbf4
1432#define RPM_RX3_ANTB 0xbf8
1433
1434/*Page C*/
1435#define ROFDM0_LSTF 0xc00
1436
1437#define ROFDM0_TRXPATHENABLE 0xc04
1438#define ROFDM0_TRMUXPAR 0xc08
1439#define ROFDM0_TRSWISOLATION 0xc0c
1440
1441#define ROFDM0_XARXAFE 0xc10
1442#define ROFDM0_XARXIQIMBALANCE 0xc14
1443#define ROFDM0_XBRXAFE 0xc18
1444#define ROFDM0_XBRXIQIMBALANCE 0xc1c
1445#define ROFDM0_XCRXAFE 0xc20
1446#define ROFDM0_XCRXIQIMBANLANCE 0xc24
1447#define ROFDM0_XDRXAFE 0xc28
1448#define ROFDM0_XDRXIQIMBALANCE 0xc2c
1449
1450#define ROFDM0_RXDETECTOR1 0xc30
1451#define ROFDM0_RXDETECTOR2 0xc34
1452#define ROFDM0_RXDETECTOR3 0xc38
1453#define ROFDM0_RXDETECTOR4 0xc3c
1454
1455#define ROFDM0_RXDSP 0xc40
1456#define ROFDM0_CFOANDDAGC 0xc44
1457#define ROFDM0_CCADROPTHRESHOLD 0xc48
1458#define ROFDM0_ECCATHRESHOLD 0xc4c
1459
1460#define ROFDM0_XAAGCCORE1 0xc50
1461#define ROFDM0_XAAGCCORE2 0xc54
1462#define ROFDM0_XBAGCCORE1 0xc58
1463#define ROFDM0_XBAGCCORE2 0xc5c
1464#define ROFDM0_XCAGCCORE1 0xc60
1465#define ROFDM0_XCAGCCORE2 0xc64
1466#define ROFDM0_XDAGCCORE1 0xc68
1467#define ROFDM0_XDAGCCORE2 0xc6c
1468
1469#define ROFDM0_AGCPARAMETER1 0xc70
1470#define ROFDM0_AGCPARAMETER2 0xc74
1471#define ROFDM0_AGCRSSITABLE 0xc78
1472#define ROFDM0_HTSTFAGC 0xc7c
1473
1474#define ROFDM0_XATXIQIMBALANCE 0xc80
1475#define ROFDM0_XATXAFE 0xc84
1476#define ROFDM0_XBTXIQIMBALANCE 0xc88
1477#define ROFDM0_XBTXAFE 0xc8c
1478#define ROFDM0_XCTXIQIMBALANCE 0xc90
1479#define ROFDM0_XCTXAFE 0xc94
1480#define ROFDM0_XDTXIQIMBALANCE 0xc98
1481#define ROFDM0_XDTXAFE 0xc9c
1482
1483#define ROFDM0_RXIQEXTANTA 0xca0
1484#define ROFDM0_TXCOEFF1 0xca4
1485#define ROFDM0_TXCOEFF2 0xca8
1486#define ROFDM0_TXCOEFF3 0xcac
1487#define ROFDM0_TXCOEFF4 0xcb0
1488#define ROFDM0_TXCOEFF5 0xcb4
1489#define ROFDM0_TXCOEFF6 0xcb8
1490
1491#define ROFDM0_RXHPPARAMETER 0xce0
1492#define ROFDM0_TXPSEUDONOISEWGT 0xce4
1493#define ROFDM0_FRAMESYNC 0xcf0
1494#define ROFDM0_DFSREPORT 0xcf4
1495
1496
1497#define ROFDM1_LSTF 0xd00
1498#define ROFDM1_TRXPATHENABLE 0xd04
1499
1500#define ROFDM1_CF0 0xd08
1501#define ROFDM1_CSI1 0xd10
1502#define ROFDM1_SBD 0xd14
1503#define ROFDM1_CSI2 0xd18
1504#define ROFDM1_CFOTRACKING 0xd2c
1505#define ROFDM1_TRXMESAURE1 0xd34
1506#define ROFDM1_INTFDET 0xd3c
1507#define ROFDM1_PSEUDONOISESTATEAB 0xd50
1508#define ROFDM1_PSEUDONOISESTATECD 0xd54
1509#define ROFDM1_RXPSEUDONOISEWGT 0xd58
1510
1511#define ROFDM_PHYCOUNTER1 0xda0
1512#define ROFDM_PHYCOUNTER2 0xda4
1513#define ROFDM_PHYCOUNTER3 0xda8
1514
1515#define ROFDM_SHORTCFOAB 0xdac
1516#define ROFDM_SHORTCFOCD 0xdb0
1517#define ROFDM_LONGCFOAB 0xdb4
1518#define ROFDM_LONGCFOCD 0xdb8
1519#define ROFDM_TAILCF0AB 0xdbc
1520#define ROFDM_TAILCF0CD 0xdc0
1521#define ROFDM_PWMEASURE1 0xdc4
1522#define ROFDM_PWMEASURE2 0xdc8
1523#define ROFDM_BWREPORT 0xdcc
1524#define ROFDM_AGCREPORT 0xdd0
1525#define ROFDM_RXSNR 0xdd4
1526#define ROFDM_RXEVMCSI 0xdd8
1527#define ROFDM_SIGREPORT 0xddc
1528
1529#define RTXAGC_A_RATE18_06 0xe00
1530#define RTXAGC_A_RATE54_24 0xe04
1531#define RTXAGC_A_CCK1_MCS32 0xe08
1532#define RTXAGC_A_MCS03_MCS00 0xe10
1533#define RTXAGC_A_MCS07_MCS04 0xe14
1534#define RTXAGC_A_MCS11_MCS08 0xe18
1535#define RTXAGC_A_MCS15_MCS12 0xe1c
1536
1537#define RTXAGC_B_RATE18_06 0x830
1538#define RTXAGC_B_RATE54_24 0x834
1539#define RTXAGC_B_CCK1_55_MCS32 0x838
1540#define RTXAGC_B_MCS03_MCS00 0x83c
1541#define RTXAGC_B_MCS07_MCS04 0x848
1542#define RTXAGC_B_MCS11_MCS08 0x84c
1543#define RTXAGC_B_MCS15_MCS12 0x868
1544#define RTXAGC_B_CCK11_A_CCK2_11 0x86c
1545
1546#define RFPGA0_IQK 0xe28
1547#define RTX_IQK_TONE_A 0xe30
1548#define RRX_IQK_TONE_A 0xe34
1549#define RTX_IQK_PI_A 0xe38
1550#define RRX_IQK_PI_A 0xe3c
1551
1552#define RTX_IQK 0xe40
1553#define RRX_IQK 0xe44
1554#define RIQK_AGC_PTS 0xe48
1555#define RIQK_AGC_RSP 0xe4c
1556#define RTX_IQK_TONE_B 0xe50
1557#define RRX_IQK_TONE_B 0xe54
1558#define RTX_IQK_PI_B 0xe58
1559#define RRX_IQK_PI_B 0xe5c
1560#define RIQK_AGC_CONT 0xe60
1561
1562#define RBLUE_TOOTH 0xe6c
1563#define RRX_WAIT_CCA 0xe70
1564#define RTX_CCK_RFON 0xe74
1565#define RTX_CCK_BBON 0xe78
1566#define RTX_OFDM_RFON 0xe7c
1567#define RTX_OFDM_BBON 0xe80
1568#define RTX_TO_RX 0xe84
1569#define RTX_TO_TX 0xe88
1570#define RRX_CCK 0xe8c
1571
1572#define RTX_POWER_BEFORE_IQK_A 0xe94
1573#define RTX_POWER_AFTER_IQK_A 0xe9c
1574
1575#define RRX_POWER_BEFORE_IQK_A 0xea0
1576#define RRX_POWER_BEFORE_IQK_A_2 0xea4
1577#define RRX_POWER_AFTER_IQK_A 0xea8
1578#define RRX_POWER_AFTER_IQK_A_2 0xeac
1579
1580#define RTX_POWER_BEFORE_IQK_B 0xeb4
1581#define RTX_POWER_AFTER_IQK_B 0xebc
1582
1583#define RRX_POWER_BEFORE_IQK_B 0xec0
1584#define RRX_POWER_BEFORE_IQK_B_2 0xec4
1585#define RRX_POWER_AFTER_IQK_B 0xec8
1586#define RRX_POWER_AFTER_IQK_B_2 0xecc
1587
1588#define RRX_OFDM 0xed0
1589#define RRX_WAIT_RIFS 0xed4
1590#define RRX_TO_RX 0xed8
1591#define RSTANDBY 0xedc
1592#define RSLEEP 0xee0
1593#define RPMPD_ANAEN 0xeec
1594
1595#define RZEBRA1_HSSIENABLE 0x0
1596#define RZEBRA1_TRXENABLE1 0x1
1597#define RZEBRA1_TRXENABLE2 0x2
1598#define RZEBRA1_AGC 0x4
1599#define RZEBRA1_CHARGEPUMP 0x5
1600#define RZEBRA1_CHANNEL 0x7
1601
1602#define RZEBRA1_TXGAIN 0x8
1603#define RZEBRA1_TXLPF 0x9
1604#define RZEBRA1_RXLPF 0xb
1605#define RZEBRA1_RXHPFCORNER 0xc
1606
1607#define RGLOBALCTRL 0
1608#define RRTL8256_TXLPF 19
1609#define RRTL8256_RXLPF 11
1610#define RRTL8258_TXLPF 0x11
1611#define RRTL8258_RXLPF 0x13
1612#define RRTL8258_RSSILPF 0xa
1613
1614#define RF_AC 0x00
1615
1616#define RF_IQADJ_G1 0x01
1617#define RF_IQADJ_G2 0x02
1618#define RF_POW_TRSW 0x05
1619
1620#define RF_GAIN_RX 0x06
1621#define RF_GAIN_TX 0x07
1622
1623#define RF_TXM_IDAC 0x08
1624#define RF_BS_IQGEN 0x0F
1625
1626#define RF_MODE1 0x10
1627#define RF_MODE2 0x11
1628
1629#define RF_RX_AGC_HP 0x12
1630#define RF_TX_AGC 0x13
1631#define RF_BIAS 0x14
1632#define RF_IPA 0x15
1633#define RF_POW_ABILITY 0x17
1634#define RF_MODE_AG 0x18
1635#define RRFCHANNEL 0x18
1636#define RF_CHNLBW 0x18
1637#define RF_TOP 0x19
1638
1639#define RF_RX_G1 0x1A
1640#define RF_RX_G2 0x1B
1641
1642#define RF_RX_BB2 0x1C
1643#define RF_RX_BB1 0x1D
1644
1645#define RF_RCK1 0x1E
1646#define RF_RCK2 0x1F
1647
1648#define RF_TX_G1 0x20
1649#define RF_TX_G2 0x21
1650#define RF_TX_G3 0x22
1651
1652#define RF_TX_BB1 0x23
1653#define RF_T_METER 0x42
1654
1655#define RF_SYN_G1 0x25
1656#define RF_SYN_G2 0x26
1657#define RF_SYN_G3 0x27
1658#define RF_SYN_G4 0x28
1659#define RF_SYN_G5 0x29
1660#define RF_SYN_G6 0x2A
1661#define RF_SYN_G7 0x2B
1662#define RF_SYN_G8 0x2C
1663
1664#define RF_RCK_OS 0x30
1665#define RF_TXPA_G1 0x31
1666#define RF_TXPA_G2 0x32
1667#define RF_TXPA_G3 0x33
1668
1669#define RF_TX_BIAS_A 0x35
1670#define RF_TX_BIAS_D 0x36
1671#define RF_LOBF_9 0x38
1672#define RF_RXRF_A3 0x3C
1673#define RF_TRSW 0x3F
1674
1675#define RF_TXRF_A2 0x41
1676#define RF_TXPA_G4 0x46
1677#define RF_TXPA_A4 0x4B
1678
1679#define RF_WE_LUT 0xEF
1680
1681#define BBBRESETB 0x100
1682#define BGLOBALRESETB 0x200
1683#define BOFDMTXSTART 0x4
1684#define BCCKTXSTART 0x8
1685#define BCRC32DEBUG 0x100
1686#define BPMACLOOPBACK 0x10
1687#define BTXLSIG 0xffffff
1688#define BOFDMTXRATE 0xf
1689#define BOFDMTXRESERVED 0x10
1690#define BOFDMTXLENGTH 0x1ffe0
1691#define BOFDMTXPARITY 0x20000
1692#define BTXHTSIG1 0xffffff
1693#define BTXHTMCSRATE 0x7f
1694#define BTXHTBW 0x80
1695#define BTXHTLENGTH 0xffff00
1696#define BTXHTSIG2 0xffffff
1697#define BTXHTSMOOTHING 0x1
1698#define BTXHTSOUNDING 0x2
1699#define BTXHTRESERVED 0x4
1700#define BTXHTAGGREATION 0x8
1701#define BTXHTSTBC 0x30
1702#define BTXHTADVANCECODING 0x40
1703#define BTXHTSHORTGI 0x80
1704#define BTXHTNUMBERHT_LTF 0x300
1705#define BTXHTCRC8 0x3fc00
1706#define BCOUNTERRESET 0x10000
1707#define BNUMOFOFDMTX 0xffff
1708#define BNUMOFCCKTX 0xffff0000
1709#define BTXIDLEINTERVAL 0xffff
1710#define BOFDMSERVICE 0xffff0000
1711#define BTXMACHEADER 0xffffffff
1712#define BTXDATAINIT 0xff
1713#define BTXHTMODE 0x100
1714#define BTXDATATYPE 0x30000
1715#define BTXRANDOMSEED 0xffffffff
1716#define BCCKTXPREAMBLE 0x1
1717#define BCCKTXSFD 0xffff0000
1718#define BCCKTXSIG 0xff
1719#define BCCKTXSERVICE 0xff00
1720#define BCCKLENGTHEXT 0x8000
1721#define BCCKTXLENGHT 0xffff0000
1722#define BCCKTXCRC16 0xffff
1723#define BCCKTXSTATUS 0x1
1724#define BOFDMTXSTATUS 0x2
1725#define IS_BB_REG_OFFSET_92S(_offset) \
1726 ((_offset >= 0x800) && (_offset <= 0xfff))
1727
1728#define BRFMOD 0x1
1729#define BJAPANMODE 0x2
1730#define BCCKTXSC 0x30
1731#define BCCKEN 0x1000000
1732#define BOFDMEN 0x2000000
1733
1734#define BOFDMRXADCPHASE 0x10000
1735#define BOFDMTXDACPHASE 0x40000
1736#define BXATXAGC 0x3f
1737
1738#define BXBTXAGC 0xf00
1739#define BXCTXAGC 0xf000
1740#define BXDTXAGC 0xf0000
1741
1742#define BPASTART 0xf0000000
1743#define BTRSTART 0x00f00000
1744#define BRFSTART 0x0000f000
1745#define BBBSTART 0x000000f0
1746#define BBBCCKSTART 0x0000000f
1747#define BPAEND 0xf
1748#define BTREND 0x0f000000
1749#define BRFEND 0x000f0000
1750#define BCCAMASK 0x000000f0
1751#define BR2RCCAMASK 0x00000f00
1752#define BHSSI_R2TDELAY 0xf8000000
1753#define BHSSI_T2RDELAY 0xf80000
1754#define BCONTXHSSI 0x400
1755#define BIGFROMCCK 0x200
1756#define BAGCADDRESS 0x3f
1757#define BRXHPTX 0x7000
1758#define BRXHP2RX 0x38000
1759#define BRXHPCCKINI 0xc0000
1760#define BAGCTXCODE 0xc00000
1761#define BAGCRXCODE 0x300000
1762
1763#define B3WIREDATALENGTH 0x800
1764#define B3WIREADDREAALENGTH 0x400
1765
1766#define B3WIRERFPOWERDOWN 0x1
1767#define B5GPAPEPOLARITY 0x40000000
1768#define B2GPAPEPOLARITY 0x80000000
1769#define BRFSW_TXDEFAULTANT 0x3
1770#define BRFSW_TXOPTIONANT 0x30
1771#define BRFSW_RXDEFAULTANT 0x300
1772#define BRFSW_RXOPTIONANT 0x3000
1773#define BRFSI_3WIREDATA 0x1
1774#define BRFSI_3WIRECLOCK 0x2
1775#define BRFSI_3WIRELOAD 0x4
1776#define BRFSI_3WIRERW 0x8
1777#define BRFSI_3WIRE 0xf
1778
1779#define BRFSI_RFENV 0x10
1780
1781#define BRFSI_TRSW 0x20
1782#define BRFSI_TRSWB 0x40
1783#define BRFSI_ANTSW 0x100
1784#define BRFSI_ANTSWB 0x200
1785#define BRFSI_PAPE 0x400
1786#define BRFSI_PAPE5G 0x800
1787#define BBANDSELECT 0x1
1788#define BHTSIG2_GI 0x80
1789#define BHTSIG2_SMOOTHING 0x01
1790#define BHTSIG2_SOUNDING 0x02
1791#define BHTSIG2_AGGREATON 0x08
1792#define BHTSIG2_STBC 0x30
1793#define BHTSIG2_ADVCODING 0x40
1794#define BHTSIG2_NUMOFHTLTF 0x300
1795#define BHTSIG2_CRC8 0x3fc
1796#define BHTSIG1_MCS 0x7f
1797#define BHTSIG1_BANDWIDTH 0x80
1798#define BHTSIG1_HTLENGTH 0xffff
1799#define BLSIG_RATE 0xf
1800#define BLSIG_RESERVED 0x10
1801#define BLSIG_LENGTH 0x1fffe
1802#define BLSIG_PARITY 0x20
1803#define BCCKRXPHASE 0x4
1804
1805#define BLSSIREADADDRESS 0x7f800000
1806#define BLSSIREADEDGE 0x80000000
1807
1808#define BLSSIREADBACKDATA 0xfffff
1809
1810#define BLSSIREADOKFLAG 0x1000
1811#define BCCKSAMPLERATE 0x8
1812#define BREGULATOR0STANDBY 0x1
1813#define BREGULATORPLLSTANDBY 0x2
1814#define BREGULATOR1STANDBY 0x4
1815#define BPLLPOWERUP 0x8
1816#define BDPLLPOWERUP 0x10
1817#define BDA10POWERUP 0x20
1818#define BAD7POWERUP 0x200
1819#define BDA6POWERUP 0x2000
1820#define BXTALPOWERUP 0x4000
1821#define B40MDCLKPOWERUP 0x8000
1822#define BDA6DEBUGMODE 0x20000
1823#define BDA6SWING 0x380000
1824
1825#define BADCLKPHASE 0x4000000
1826#define B80MCLKDELAY 0x18000000
1827#define BAFEWATCHDOGENABLE 0x20000000
1828
1829#define BXTALCAP01 0xc0000000
1830#define BXTALCAP23 0x3
1831#define BXTALCAP92X 0x0f000000
1832#define BXTALCAP 0x0f000000
1833
1834#define BINTDIFCLKENABLE 0x400
1835#define BEXTSIGCLKENABLE 0x800
1836#define BBANDGAP_MBIAS_POWERUP 0x10000
1837#define BAD11SH_GAIN 0xc0000
1838#define BAD11NPUT_RANGE 0x700000
1839#define BAD110P_CURRENT 0x3800000
1840#define BLPATH_LOOPBACK 0x4000000
1841#define BQPATH_LOOPBACK 0x8000000
1842#define BAFE_LOOPBACK 0x10000000
1843#define BDA10_SWING 0x7e0
1844#define BDA10_REVERSE 0x800
1845#define BDA_CLK_SOURCE 0x1000
1846#define BDA7INPUT_RANGE 0x6000
1847#define BDA7_GAIN 0x38000
1848#define BDA7OUTPUT_CM_MODE 0x40000
1849#define BDA7INPUT_CM_MODE 0x380000
1850#define BDA7CURRENT 0xc00000
1851#define BREGULATOR_ADJUST 0x7000000
1852#define BAD11POWERUP_ATTX 0x1
1853#define BDA10PS_ATTX 0x10
1854#define BAD11POWERUP_ATRX 0x100
1855#define BDA10PS_ATRX 0x1000
1856#define BCCKRX_AGC_FORMAT 0x200
1857#define BPSDFFT_SAMPLE_POINT 0xc000
1858#define BPSD_AVERAGE_NUM 0x3000
1859#define BIQPATH_CONTROL 0xc00
1860#define BPSD_FREQ 0x3ff
1861#define BPSD_ANTENNA_PATH 0x30
1862#define BPSD_IQ_SWITCH 0x40
1863#define BPSD_RX_TRIGGER 0x400000
1864#define BPSD_TX_TRIGGER 0x80000000
1865#define BPSD_SINE_TONE_SCALE 0x7f000000
1866#define BPSD_REPORT 0xffff
1867
1868#define BOFDM_TXSC 0x30000000
1869#define BCCK_TXON 0x1
1870#define BOFDM_TXON 0x2
1871#define BDEBUG_PAGE 0xfff
1872#define BDEBUG_ITEM 0xff
1873#define BANTL 0x10
1874#define BANT_NONHT 0x100
1875#define BANT_HT1 0x1000
1876#define BANT_HT2 0x10000
1877#define BANT_HT1S1 0x100000
1878#define BANT_NONHTS1 0x1000000
1879
1880#define BCCK_BBMODE 0x3
1881#define BCCK_TXPOWERSAVING 0x80
1882#define BCCK_RXPOWERSAVING 0x40
1883
1884#define BCCK_SIDEBAND 0x10
1885
1886#define BCCK_SCRAMBLE 0x8
1887#define BCCK_ANTDIVERSITY 0x8000
1888#define BCCK_CARRIER_RECOVERY 0x4000
1889#define BCCK_TXRATE 0x3000
1890#define BCCK_DCCANCEL 0x0800
1891#define BCCK_ISICANCEL 0x0400
1892#define BCCK_MATCH_FILTER 0x0200
1893#define BCCK_EQUALIZER 0x0100
1894#define BCCK_PREAMBLE_DETECT 0x800000
1895#define BCCK_FAST_FALSECCA 0x400000
1896#define BCCK_CH_ESTSTART 0x300000
1897#define BCCK_CCA_COUNT 0x080000
1898#define BCCK_CS_LIM 0x070000
1899#define BCCK_BIST_MODE 0x80000000
1900#define BCCK_CCAMASK 0x40000000
1901#define BCCK_TX_DAC_PHASE 0x4
1902#define BCCK_RX_ADC_PHASE 0x20000000
1903#define BCCKR_CP_MODE 0x0100
1904#define BCCK_TXDC_OFFSET 0xf0
1905#define BCCK_RXDC_OFFSET 0xf
1906#define BCCK_CCA_MODE 0xc000
1907#define BCCK_FALSECS_LIM 0x3f00
1908#define BCCK_CS_RATIO 0xc00000
1909#define BCCK_CORGBIT_SEL 0x300000
1910#define BCCK_PD_LIM 0x0f0000
1911#define BCCK_NEWCCA 0x80000000
1912#define BCCK_RXHP_OF_IG 0x8000
1913#define BCCK_RXIG 0x7f00
1914#define BCCK_LNA_POLARITY 0x800000
1915#define BCCK_RX1ST_BAIN 0x7f0000
1916#define BCCK_RF_EXTEND 0x20000000
1917#define BCCK_RXAGC_SATLEVEL 0x1f000000
1918#define BCCK_RXAGC_SATCOUNT 0xe0
1919#define BCCKRXRFSETTLE 0x1f
1920#define BCCK_FIXED_RXAGC 0x8000
1921#define BCCK_ANTENNA_POLARITY 0x2000
1922#define BCCK_TXFILTER_TYPE 0x0c00
1923#define BCCK_RXAGC_REPORTTYPE 0x0300
1924#define BCCK_RXDAGC_EN 0x80000000
1925#define BCCK_RXDAGC_PERIOD 0x20000000
1926#define BCCK_RXDAGC_SATLEVEL 0x1f000000
1927#define BCCK_TIMING_RECOVERY 0x800000
1928#define BCCK_TXC0 0x3f0000
1929#define BCCK_TXC1 0x3f000000
1930#define BCCK_TXC2 0x3f
1931#define BCCK_TXC3 0x3f00
1932#define BCCK_TXC4 0x3f0000
1933#define BCCK_TXC5 0x3f000000
1934#define BCCK_TXC6 0x3f
1935#define BCCK_TXC7 0x3f00
1936#define BCCK_DEBUGPORT 0xff0000
1937#define BCCK_DAC_DEBUG 0x0f000000
1938#define BCCK_FALSEALARM_ENABLE 0x8000
1939#define BCCK_FALSEALARM_READ 0x4000
1940#define BCCK_TRSSI 0x7f
1941#define BCCK_RXAGC_REPORT 0xfe
1942#define BCCK_RXREPORT_ANTSEL 0x80000000
1943#define BCCK_RXREPORT_MFOFF 0x40000000
1944#define BCCK_RXREPORT_SQLOSS 0x20000000
1945#define BCCK_RXREPORT_PKTLOSS 0x10000000
1946#define BCCK_RXREPORT_LOCKEDBIT 0x08000000
1947#define BCCK_RXREPORT_RATEERROR 0x04000000
1948#define BCCK_RXREPORT_RXRATE 0x03000000
1949#define BCCK_RXFA_COUNTER_LOWER 0xff
1950#define BCCK_RXFA_COUNTER_UPPER 0xff000000
1951#define BCCK_RXHPAGC_START 0xe000
1952#define BCCK_RXHPAGC_FINAL 0x1c00
1953#define BCCK_RXFALSEALARM_ENABLE 0x8000
1954#define BCCK_FACOUNTER_FREEZE 0x4000
1955#define BCCK_TXPATH_SEL 0x10000000
1956#define BCCK_DEFAULT_RXPATH 0xc000000
1957#define BCCK_OPTION_RXPATH 0x3000000
1958
1959#define BNUM_OFSTF 0x3
1960#define BSHIFT_L 0xc0
1961#define BGI_TH 0xc
1962#define BRXPATH_A 0x1
1963#define BRXPATH_B 0x2
1964#define BRXPATH_C 0x4
1965#define BRXPATH_D 0x8
1966#define BTXPATH_A 0x1
1967#define BTXPATH_B 0x2
1968#define BTXPATH_C 0x4
1969#define BTXPATH_D 0x8
1970#define BTRSSI_FREQ 0x200
1971#define BADC_BACKOFF 0x3000
1972#define BDFIR_BACKOFF 0xc000
1973#define BTRSSI_LATCH_PHASE 0x10000
1974#define BRX_LDC_OFFSET 0xff
1975#define BRX_QDC_OFFSET 0xff00
1976#define BRX_DFIR_MODE 0x1800000
1977#define BRX_DCNF_TYPE 0xe000000
1978#define BRXIQIMB_A 0x3ff
1979#define BRXIQIMB_B 0xfc00
1980#define BRXIQIMB_C 0x3f0000
1981#define BRXIQIMB_D 0xffc00000
1982#define BDC_DC_NOTCH 0x60000
1983#define BRXNB_NOTCH 0x1f000000
1984#define BPD_TH 0xf
1985#define BPD_TH_OPT2 0xc000
1986#define BPWED_TH 0x700
1987#define BIFMF_WIN_L 0x800
1988#define BPD_OPTION 0x1000
1989#define BMF_WIN_L 0xe000
1990#define BBW_SEARCH_L 0x30000
1991#define BWIN_ENH_L 0xc0000
1992#define BBW_TH 0x700000
1993#define BED_TH2 0x3800000
1994#define BBW_OPTION 0x4000000
1995#define BRADIO_TH 0x18000000
1996#define BWINDOW_L 0xe0000000
1997#define BSBD_OPTION 0x1
1998#define BFRAME_TH 0x1c
1999#define BFS_OPTION 0x60
2000#define BDC_SLOPE_CHECK 0x80
2001#define BFGUARD_COUNTER_DC_L 0xe00
2002#define BFRAME_WEIGHT_SHORT 0x7000
2003#define BSUB_TUNE 0xe00000
2004#define BFRAME_DC_LENGTH 0xe000000
2005#define BSBD_START_OFFSET 0x30000000
2006#define BFRAME_TH_2 0x7
2007#define BFRAME_GI2_TH 0x38
2008#define BGI2_SYNC_EN 0x40
2009#define BSARCH_SHORT_EARLY 0x300
2010#define BSARCH_SHORT_LATE 0xc00
2011#define BSARCH_GI2_LATE 0x70000
2012#define BCFOANTSUM 0x1
2013#define BCFOACC 0x2
2014#define BCFOSTARTOFFSET 0xc
2015#define BCFOLOOPBACK 0x70
2016#define BCFOSUMWEIGHT 0x80
2017#define BDAGCENABLE 0x10000
2018#define BTXIQIMB_A 0x3ff
2019#define BTXIQIMB_b 0xfc00
2020#define BTXIQIMB_C 0x3f0000
2021#define BTXIQIMB_D 0xffc00000
2022#define BTXIDCOFFSET 0xff
2023#define BTXIQDCOFFSET 0xff00
2024#define BTXDFIRMODE 0x10000
2025#define BTXPESUDO_NOISEON 0x4000000
2026#define BTXPESUDO_NOISE_A 0xff
2027#define BTXPESUDO_NOISE_B 0xff00
2028#define BTXPESUDO_NOISE_C 0xff0000
2029#define BTXPESUDO_NOISE_D 0xff000000
2030#define BCCA_DROPOPTION 0x20000
2031#define BCCA_DROPTHRES 0xfff00000
2032#define BEDCCA_H 0xf
2033#define BEDCCA_L 0xf0
2034#define BLAMBDA_ED 0x300
2035#define BRX_INITIALGAIN 0x7f
2036#define BRX_ANTDIV_EN 0x80
2037#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00
2038#define BRX_HIGHPOWER_FLOW 0x8000
2039#define BRX_AGC_FREEZE_THRES 0xc0000
2040#define BRX_FREEZESTEP_AGC1 0x300000
2041#define BRX_FREEZESTEP_AGC2 0xc00000
2042#define BRX_FREEZESTEP_AGC3 0x3000000
2043#define BRX_FREEZESTEP_AGC0 0xc000000
2044#define BRXRSSI_CMP_EN 0x10000000
2045#define BRXQUICK_AGCEN 0x20000000
2046#define BRXAGC_FREEZE_THRES_MODE 0x40000000
2047#define BRX_OVERFLOW_CHECKTYPE 0x80000000
2048#define BRX_AGCSHIFT 0x7f
2049#define BTRSW_TRI_ONLY 0x80
2050#define BPOWER_THRES 0x300
2051#define BRXAGC_EN 0x1
2052#define BRXAGC_TOGETHER_EN 0x2
2053#define BRXAGC_MIN 0x4
2054#define BRXHP_INI 0x7
2055#define BRXHP_TRLNA 0x70
2056#define BRXHP_RSSI 0x700
2057#define BRXHP_BBP1 0x7000
2058#define BRXHP_BBP2 0x70000
2059#define BRXHP_BBP3 0x700000
2060#define BRSSI_H 0x7f0000
2061#define BRSSI_GEN 0x7f000000
2062#define BRXSETTLE_TRSW 0x7
2063#define BRXSETTLE_LNA 0x38
2064#define BRXSETTLE_RSSI 0x1c0
2065#define BRXSETTLE_BBP 0xe00
2066#define BRXSETTLE_RXHP 0x7000
2067#define BRXSETTLE_ANTSW_RSSI 0x38000
2068#define BRXSETTLE_ANTSW 0xc0000
2069#define BRXPROCESS_TIME_DAGC 0x300000
2070#define BRXSETTLE_HSSI 0x400000
2071#define BRXPROCESS_TIME_BBPPW 0x800000
2072#define BRXANTENNA_POWER_SHIFT 0x3000000
2073#define BRSSI_TABLE_SELECT 0xc000000
2074#define BRXHP_FINAL 0x7000000
2075#define BRXHPSETTLE_BBP 0x7
2076#define BRXHTSETTLE_HSSI 0x8
2077#define BRXHTSETTLE_RXHP 0x70
2078#define BRXHTSETTLE_BBPPW 0x80
2079#define BRXHTSETTLE_IDLE 0x300
2080#define BRXHTSETTLE_RESERVED 0x1c00
2081#define BRXHT_RXHP_EN 0x8000
2082#define BRXAGC_FREEZE_THRES 0x30000
2083#define BRXAGC_TOGETHEREN 0x40000
2084#define BRXHTAGC_MIN 0x80000
2085#define BRXHTAGC_EN 0x100000
2086#define BRXHTDAGC_EN 0x200000
2087#define BRXHT_RXHP_BBP 0x1c00000
2088#define BRXHT_RXHP_FINAL 0xe0000000
2089#define BRXPW_RADIO_TH 0x3
2090#define BRXPW_RADIO_EN 0x4
2091#define BRXMF_HOLD 0x3800
2092#define BRXPD_DELAY_TH1 0x38
2093#define BRXPD_DELAY_TH2 0x1c0
2094#define BRXPD_DC_COUNT_MAX 0x600
2095#define BRXPD_DELAY_TH 0x8000
2096#define BRXPROCESS_DELAY 0xf0000
2097#define BRXSEARCHRANGE_GI2_EARLY 0x700000
2098#define BRXFRAME_FUARD_COUNTER_L 0x3800000
2099#define BRXSGI_GUARD_L 0xc000000
2100#define BRXSGI_SEARCH_L 0x30000000
2101#define BRXSGI_TH 0xc0000000
2102#define BDFSCNT0 0xff
2103#define BDFSCNT1 0xff00
2104#define BDFSFLAG 0xf0000
2105#define BMF_WEIGHT_SUM 0x300000
2106#define BMINIDX_TH 0x7f000000
2107#define BDAFORMAT 0x40000
2108#define BTXCH_EMU_ENABLE 0x01000000
2109#define BTRSW_ISOLATION_A 0x7f
2110#define BTRSW_ISOLATION_B 0x7f00
2111#define BTRSW_ISOLATION_C 0x7f0000
2112#define BTRSW_ISOLATION_D 0x7f000000
2113#define BEXT_LNA_GAIN 0x7c00
2114
2115#define BSTBC_EN 0x4
2116#define BANTENNA_MAPPING 0x10
2117#define BNSS 0x20
2118#define BCFO_ANTSUM_ID 0x200
2119#define BPHY_COUNTER_RESET 0x8000000
2120#define BCFO_REPORT_GET 0x4000000
2121#define BOFDM_CONTINUE_TX 0x10000000
2122#define BOFDM_SINGLE_CARRIER 0x20000000
2123#define BOFDM_SINGLE_TONE 0x40000000
2124#define BHT_DETECT 0x100
2125#define BCFOEN 0x10000
2126#define BCFOVALUE 0xfff00000
2127#define BSIGTONE_RE 0x3f
2128#define BSIGTONE_IM 0x7f00
2129#define BCOUNTER_CCA 0xffff
2130#define BCOUNTER_PARITYFAIL 0xffff0000
2131#define BCOUNTER_RATEILLEGAL 0xffff
2132#define BCOUNTER_CRC8FAIL 0xffff0000
2133#define BCOUNTER_MCSNOSUPPORT 0xffff
2134#define BCOUNTER_FASTSYNC 0xffff
2135#define BSHORTCFO 0xfff
2136#define BSHORTCFOT_LENGTH 12
2137#define BSHORTCFOF_LENGTH 11
2138#define BLONGCFO 0x7ff
2139#define BLONGCFOT_LENGTH 11
2140#define BLONGCFOF_LENGTH 11
2141#define BTAILCFO 0x1fff
2142#define BTAILCFOT_LENGTH 13
2143#define BTAILCFOF_LENGTH 12
2144#define BNOISE_EN_PWDB 0xffff
2145#define BCC_POWER_DB 0xffff0000
2146#define BMOISE_PWDB 0xffff
2147#define BPOWERMEAST_LENGTH 10
2148#define BPOWERMEASF_LENGTH 3
2149#define BRX_HT_BW 0x1
2150#define BRXSC 0x6
2151#define BRX_HT 0x8
2152#define BNB_INTF_DET_ON 0x1
2153#define BINTF_WIN_LEN_CFG 0x30
2154#define BNB_INTF_TH_CFG 0x1c0
2155#define BRFGAIN 0x3f
2156#define BTABLESEL 0x40
2157#define BTRSW 0x80
2158#define BRXSNR_A 0xff
2159#define BRXSNR_B 0xff00
2160#define BRXSNR_C 0xff0000
2161#define BRXSNR_D 0xff000000
2162#define BSNR_EVMT_LENGTH 8
2163#define BSNR_EVMF_LENGTH 1
2164#define BCSI1ST 0xff
2165#define BCSI2ND 0xff00
2166#define BRXEVM1ST 0xff0000
2167#define BRXEVM2ND 0xff000000
2168#define BSIGEVM 0xff
2169#define BPWDB 0xff00
2170#define BSGIEN 0x10000
2171
2172#define BSFACTOR_QMA1 0xf
2173#define BSFACTOR_QMA2 0xf0
2174#define BSFACTOR_QMA3 0xf00
2175#define BSFACTOR_QMA4 0xf000
2176#define BSFACTOR_QMA5 0xf0000
2177#define BSFACTOR_QMA6 0xf0000
2178#define BSFACTOR_QMA7 0xf00000
2179#define BSFACTOR_QMA8 0xf000000
2180#define BSFACTOR_QMA9 0xf0000000
2181#define BCSI_SCHEME 0x100000
2182
2183#define BNOISE_LVL_TOP_SET 0x3
2184#define BCHSMOOTH 0x4
2185#define BCHSMOOTH_CFG1 0x38
2186#define BCHSMOOTH_CFG2 0x1c0
2187#define BCHSMOOTH_CFG3 0xe00
2188#define BCHSMOOTH_CFG4 0x7000
2189#define BMRCMODE 0x800000
2190#define BTHEVMCFG 0x7000000
2191
2192#define BLOOP_FIT_TYPE 0x1
2193#define BUPD_CFO 0x40
2194#define BUPD_CFO_OFFDATA 0x80
2195#define BADV_UPD_CFO 0x100
2196#define BADV_TIME_CTRL 0x800
2197#define BUPD_CLKO 0x1000
2198#define BFC 0x6000
2199#define BTRACKING_MODE 0x8000
2200#define BPHCMP_ENABLE 0x10000
2201#define BUPD_CLKO_LTF 0x20000
2202#define BCOM_CH_CFO 0x40000
2203#define BCSI_ESTI_MODE 0x80000
2204#define BADV_UPD_EQZ 0x100000
2205#define BUCHCFG 0x7000000
2206#define BUPDEQZ 0x8000000
2207
2208#define BRX_PESUDO_NOISE_ON 0x20000000
2209#define BRX_PESUDO_NOISE_A 0xff
2210#define BRX_PESUDO_NOISE_B 0xff00
2211#define BRX_PESUDO_NOISE_C 0xff0000
2212#define BRX_PESUDO_NOISE_D 0xff000000
2213#define BRX_PESUDO_NOISESTATE_A 0xffff
2214#define BRX_PESUDO_NOISESTATE_B 0xffff0000
2215#define BRX_PESUDO_NOISESTATE_C 0xffff
2216#define BRX_PESUDO_NOISESTATE_D 0xffff0000
2217
2218#define BZEBRA1_HSSIENABLE 0x8
2219#define BZEBRA1_TRXCONTROL 0xc00
2220#define BZEBRA1_TRXGAINSETTING 0x07f
2221#define BZEBRA1_RXCOUNTER 0xc00
2222#define BZEBRA1_TXCHANGEPUMP 0x38
2223#define BZEBRA1_RXCHANGEPUMP 0x7
2224#define BZEBRA1_CHANNEL_NUM 0xf80
2225#define BZEBRA1_TXLPFBW 0x400
2226#define BZEBRA1_RXLPFBW 0x600
2227
2228#define BRTL8256REG_MODE_CTRL1 0x100
2229#define BRTL8256REG_MODE_CTRL0 0x40
2230#define BRTL8256REG_TXLPFBW 0x18
2231#define BRTL8256REG_RXLPFBW 0x600
2232
2233#define BRTL8258_TXLPFBW 0xc
2234#define BRTL8258_RXLPFBW 0xc00
2235#define BRTL8258_RSSILPFBW 0xc0
2236
2237#define BBYTE0 0x1
2238#define BBYTE1 0x2
2239#define BBYTE2 0x4
2240#define BBYTE3 0x8
2241#define BWORD0 0x3
2242#define BWORD1 0xc
2243#define BWORD 0xf
2244
2245#define BENABLE 0x1
2246#define BDISABLE 0x0
2247
2248#define LEFT_ANTENNA 0x0
2249#define RIGHT_ANTENNA 0x1
2250
2251#define TCHECK_TXSTATUS 500
2252#define TUPDATE_RXCOUNTER 100
2253
2254#define REG_UN_used_register 0x01bf
2255
2256/* WOL bit information */
2257#define HAL92C_WOL_PTK_UPDATE_EVENT BIT(0)
2258#define HAL92C_WOL_GTK_UPDATE_EVENT BIT(1)
2259#define HAL92C_WOL_DISASSOC_EVENT BIT(2)
2260#define HAL92C_WOL_DEAUTH_EVENT BIT(3)
2261#define HAL92C_WOL_FW_DISCONNECT_EVENT BIT(4)
2262
2263#define WOL_REASON_PTK_UPDATE BIT(0)
2264#define WOL_REASON_GTK_UPDATE BIT(1)
2265#define WOL_REASON_DISASSOC BIT(2)
2266#define WOL_REASON_DEAUTH BIT(3)
2267#define WOL_REASON_FW_DISCONNECT BIT(4)
2268
2269/* 2 EFUSE_TEST (For RTL8723 partially) */
2270#define EFUSE_SEL(x) (((x) & 0x3) << 8)
2271#define EFUSE_SEL_MASK 0x300
2272#define EFUSE_WIFI_SEL_0 0x0
2273
2274#define WL_HWPDN_EN BIT(0) /* Enable GPIO[9] as WiFi HW PDn source*/
2275#define WL_HWPDN_SL BIT(1) /* WiFi HW PDn polarity control*/
2276
2277#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.c b/drivers/net/wireless/rtlwifi/rtl8723be/rf.c
new file mode 100644
index 000000000000..486294930a7b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/rf.c
@@ -0,0 +1,504 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "reg.h"
28#include "def.h"
29#include "phy.h"
30#include "rf.h"
31#include "dm.h"
32
33static bool _rtl8723be_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
34
35void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
36{
37 struct rtl_priv *rtlpriv = rtl_priv(hw);
38 struct rtl_phy *rtlphy = &(rtlpriv->phy);
39
40 switch (bandwidth) {
41 case HT_CHANNEL_WIDTH_20:
42 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
43 0xfffff3ff) | BIT(10) | BIT(11));
44 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
45 rtlphy->rfreg_chnlval[0]);
46 break;
47 case HT_CHANNEL_WIDTH_20_40:
48 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
49 0xfffff3ff) | BIT(10));
50 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
51 rtlphy->rfreg_chnlval[0]);
52 break;
53 default:
54 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
55 "unknown bandwidth: %#X\n", bandwidth);
56 break;
57 }
58}
59
60void rtl8723be_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
61 u8 *ppowerlevel)
62{
63 struct rtl_priv *rtlpriv = rtl_priv(hw);
64 struct rtl_phy *rtlphy = &(rtlpriv->phy);
65 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
66 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
67 u32 tx_agc[2] = {0, 0}, tmpval;
68 bool turbo_scanoff = false;
69 u8 idx1, idx2;
70 u8 *ptr;
71 u8 direction;
72 u32 pwrtrac_value;
73
74 if (rtlefuse->eeprom_regulatory != 0)
75 turbo_scanoff = true;
76
77 if (mac->act_scanning) {
78 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
79 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
80
81 if (turbo_scanoff) {
82 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
83 tx_agc[idx1] = ppowerlevel[idx1] |
84 (ppowerlevel[idx1] << 8) |
85 (ppowerlevel[idx1] << 16) |
86 (ppowerlevel[idx1] << 24);
87 }
88 }
89 } else {
90 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
91 tx_agc[idx1] = ppowerlevel[idx1] |
92 (ppowerlevel[idx1] << 8) |
93 (ppowerlevel[idx1] << 16) |
94 (ppowerlevel[idx1] << 24);
95 }
96 if (rtlefuse->eeprom_regulatory == 0) {
97 tmpval =
98 (rtlphy->mcs_offset[0][6]) +
99 (rtlphy->mcs_offset[0][7] << 8);
100 tx_agc[RF90_PATH_A] += tmpval;
101
102 tmpval = (rtlphy->mcs_offset[0][14]) +
103 (rtlphy->mcs_offset[0][15] <<
104 24);
105 tx_agc[RF90_PATH_B] += tmpval;
106 }
107 }
108 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
109 ptr = (u8 *)(&(tx_agc[idx1]));
110 for (idx2 = 0; idx2 < 4; idx2++) {
111 if (*ptr > RF6052_MAX_TX_PWR)
112 *ptr = RF6052_MAX_TX_PWR;
113 ptr++;
114 }
115 }
116 rtl8723be_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value);
117 if (direction == 1) {
118 tx_agc[0] += pwrtrac_value;
119 tx_agc[1] += pwrtrac_value;
120 } else if (direction == 2) {
121 tx_agc[0] -= pwrtrac_value;
122 tx_agc[1] -= pwrtrac_value;
123 }
124 tmpval = tx_agc[RF90_PATH_A] & 0xff;
125 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
126
127 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
128 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
129 RTXAGC_A_CCK1_MCS32);
130
131 tmpval = tx_agc[RF90_PATH_A] >> 8;
132
133 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
134
135 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
136 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
137 RTXAGC_B_CCK11_A_CCK2_11);
138
139 tmpval = tx_agc[RF90_PATH_B] >> 24;
140 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
141
142 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
143 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
144 RTXAGC_B_CCK11_A_CCK2_11);
145
146 tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
147 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
148
149 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
150 "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
151 RTXAGC_B_CCK1_55_MCS32);
152}
153
154static void rtl8723be_phy_get_power_base(struct ieee80211_hw *hw,
155 u8 *ppowerlevel_ofdm,
156 u8 *ppowerlevel_bw20,
157 u8 *ppowerlevel_bw40,
158 u8 channel, u32 *ofdmbase,
159 u32 *mcsbase)
160{
161 struct rtl_priv *rtlpriv = rtl_priv(hw);
162 struct rtl_phy *rtlphy = &(rtlpriv->phy);
163 u32 powerbase0, powerbase1;
164 u8 i, powerlevel[2];
165
166 for (i = 0; i < 2; i++) {
167 powerbase0 = ppowerlevel_ofdm[i];
168
169 powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
170 (powerbase0 << 8) | powerbase0;
171 *(ofdmbase + i) = powerbase0;
172 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
173 " [OFDM power base index rf(%c) = 0x%x]\n",
174 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i));
175 }
176
177 for (i = 0; i < 2; i++) {
178 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20)
179 powerlevel[i] = ppowerlevel_bw20[i];
180 else
181 powerlevel[i] = ppowerlevel_bw40[i];
182 powerbase1 = powerlevel[i];
183 powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) |
184 (powerbase1 << 8) | powerbase1;
185
186 *(mcsbase + i) = powerbase1;
187
188 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
189 " [MCS power base index rf(%c) = 0x%x]\n",
190 ((i == 0) ? 'A' : 'B'), *(mcsbase + i));
191 }
192}
193
194static void txpwr_by_regulatory(struct ieee80211_hw *hw, u8 channel, u8 index,
195 u32 *powerbase0, u32 *powerbase1,
196 u32 *p_outwriteval)
197{
198 struct rtl_priv *rtlpriv = rtl_priv(hw);
199 struct rtl_phy *rtlphy = &(rtlpriv->phy);
200 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
201 u8 i, chnlgroup = 0, pwr_diff_limit[4];
202 u8 pwr_diff = 0, customer_pwr_diff;
203 u32 writeval, customer_limit, rf;
204
205 for (rf = 0; rf < 2; rf++) {
206 switch (rtlefuse->eeprom_regulatory) {
207 case 0:
208 chnlgroup = 0;
209
210 writeval =
211 rtlphy->mcs_offset[chnlgroup][index + (rf ? 8 : 0)]
212 + ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
213
214 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
215 "RTK better performance, "
216 "writeval(%c) = 0x%x\n",
217 ((rf == 0) ? 'A' : 'B'), writeval);
218 break;
219 case 1:
220 if (rtlphy->pwrgroup_cnt == 1) {
221 chnlgroup = 0;
222 } else {
223 if (channel < 3)
224 chnlgroup = 0;
225 else if (channel < 6)
226 chnlgroup = 1;
227 else if (channel < 9)
228 chnlgroup = 2;
229 else if (channel < 12)
230 chnlgroup = 3;
231 else if (channel < 14)
232 chnlgroup = 4;
233 else if (channel == 14)
234 chnlgroup = 5;
235 }
236 writeval = rtlphy->mcs_offset[chnlgroup]
237 [index + (rf ? 8 : 0)] + ((index < 2) ?
238 powerbase0[rf] :
239 powerbase1[rf]);
240
241 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
242 "Realtek regulatory, 20MHz, "
243 "writeval(%c) = 0x%x\n",
244 ((rf == 0) ? 'A' : 'B'), writeval);
245
246 break;
247 case 2:
248 writeval =
249 ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
250
251 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
252 "Better regulatory, "
253 "writeval(%c) = 0x%x\n",
254 ((rf == 0) ? 'A' : 'B'), writeval);
255 break;
256 case 3:
257 chnlgroup = 0;
258
259 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
260 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
261 "customer's limit, 40MHz "
262 "rf(%c) = 0x%x\n",
263 ((rf == 0) ? 'A' : 'B'),
264 rtlefuse->pwrgroup_ht40[rf]
265 [channel-1]);
266 } else {
267 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
268 "customer's limit, 20MHz "
269 "rf(%c) = 0x%x\n",
270 ((rf == 0) ? 'A' : 'B'),
271 rtlefuse->pwrgroup_ht20[rf]
272 [channel-1]);
273 }
274
275 if (index < 2)
276 pwr_diff =
277 rtlefuse->txpwr_legacyhtdiff[rf][channel-1];
278 else if (rtlphy->current_chan_bw ==
279 HT_CHANNEL_WIDTH_20)
280 pwr_diff =
281 rtlefuse->txpwr_ht20diff[rf][channel-1];
282
283 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
284 customer_pwr_diff =
285 rtlefuse->pwrgroup_ht40[rf][channel-1];
286 else
287 customer_pwr_diff =
288 rtlefuse->pwrgroup_ht20[rf][channel-1];
289
290 if (pwr_diff > customer_pwr_diff)
291 pwr_diff = 0;
292 else
293 pwr_diff = customer_pwr_diff - pwr_diff;
294
295 for (i = 0; i < 4; i++) {
296 pwr_diff_limit[i] =
297 (u8)((rtlphy->mcs_offset
298 [chnlgroup][index + (rf ? 8 : 0)] &
299 (0x7f << (i * 8))) >> (i * 8));
300
301 if (pwr_diff_limit[i] > pwr_diff)
302 pwr_diff_limit[i] = pwr_diff;
303 }
304
305 customer_limit = (pwr_diff_limit[3] << 24) |
306 (pwr_diff_limit[2] << 16) |
307 (pwr_diff_limit[1] << 8) |
308 (pwr_diff_limit[0]);
309
310 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
311 "Customer's limit rf(%c) = 0x%x\n",
312 ((rf == 0) ? 'A' : 'B'), customer_limit);
313
314 writeval = customer_limit + ((index < 2) ?
315 powerbase0[rf] :
316 powerbase1[rf]);
317
318 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
319 "Customer, writeval rf(%c)= 0x%x\n",
320 ((rf == 0) ? 'A' : 'B'), writeval);
321 break;
322 default:
323 chnlgroup = 0;
324 writeval =
325 rtlphy->mcs_offset[chnlgroup]
326 [index + (rf ? 8 : 0)]
327 + ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
328
329 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
330 "RTK better performance, writeval "
331 "rf(%c) = 0x%x\n",
332 ((rf == 0) ? 'A' : 'B'), writeval);
333 break;
334 }
335
336 if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
337 writeval = writeval - 0x06060606;
338 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
339 TXHIGHPWRLEVEL_BT2)
340 writeval = writeval - 0x0c0c0c0c;
341 *(p_outwriteval + rf) = writeval;
342 }
343}
344
345static void _rtl8723be_write_ofdm_power_reg(struct ieee80211_hw *hw,
346 u8 index, u32 *value)
347{
348 struct rtl_priv *rtlpriv = rtl_priv(hw);
349 u16 regoffset_a[6] = {
350 RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
351 RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
352 RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
353 };
354 u16 regoffset_b[6] = {
355 RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
356 RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
357 RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
358 };
359 u8 i, rf, pwr_val[4];
360 u32 writeval;
361 u16 regoffset;
362
363 for (rf = 0; rf < 2; rf++) {
364 writeval = value[rf];
365 for (i = 0; i < 4; i++) {
366 pwr_val[i] = (u8) ((writeval & (0x7f <<
367 (i * 8))) >> (i * 8));
368
369 if (pwr_val[i] > RF6052_MAX_TX_PWR)
370 pwr_val[i] = RF6052_MAX_TX_PWR;
371 }
372 writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
373 (pwr_val[1] << 8) | pwr_val[0];
374
375 if (rf == 0)
376 regoffset = regoffset_a[index];
377 else
378 regoffset = regoffset_b[index];
379 rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
380
381 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
382 "Set 0x%x = %08x\n", regoffset, writeval);
383 }
384}
385
386void rtl8723be_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
387 u8 *ppowerlevel_ofdm,
388 u8 *ppowerlevel_bw20,
389 u8 *ppowerlevel_bw40, u8 channel)
390{
391 u32 writeval[2], powerbase0[2], powerbase1[2];
392 u8 index;
393 u8 direction;
394 u32 pwrtrac_value;
395
396 rtl8723be_phy_get_power_base(hw, ppowerlevel_ofdm, ppowerlevel_bw20,
397 ppowerlevel_bw40, channel,
398 &powerbase0[0], &powerbase1[0]);
399
400 rtl8723be_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value);
401
402 for (index = 0; index < 6; index++) {
403 txpwr_by_regulatory(hw, channel, index, &powerbase0[0],
404 &powerbase1[0], &writeval[0]);
405 if (direction == 1) {
406 writeval[0] += pwrtrac_value;
407 writeval[1] += pwrtrac_value;
408 } else if (direction == 2) {
409 writeval[0] -= pwrtrac_value;
410 writeval[1] -= pwrtrac_value;
411 }
412 _rtl8723be_write_ofdm_power_reg(hw, index, &writeval[0]);
413 }
414}
415
416bool rtl8723be_phy_rf6052_config(struct ieee80211_hw *hw)
417{
418 struct rtl_priv *rtlpriv = rtl_priv(hw);
419 struct rtl_phy *rtlphy = &(rtlpriv->phy);
420
421 if (rtlphy->rf_type == RF_1T1R)
422 rtlphy->num_total_rfpath = 1;
423 else
424 rtlphy->num_total_rfpath = 2;
425
426 return _rtl8723be_phy_rf6052_config_parafile(hw);
427}
428
429static bool _rtl8723be_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
430{
431 struct rtl_priv *rtlpriv = rtl_priv(hw);
432 struct rtl_phy *rtlphy = &(rtlpriv->phy);
433 struct bb_reg_def *pphyreg;
434 u32 u4_regvalue = 0;
435 u8 rfpath;
436 bool rtstatus = true;
437
438 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
439 pphyreg = &rtlphy->phyreg_def[rfpath];
440
441 switch (rfpath) {
442 case RF90_PATH_A:
443 case RF90_PATH_C:
444 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
445 BRFSI_RFENV);
446 break;
447 case RF90_PATH_B:
448 case RF90_PATH_D:
449 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
450 BRFSI_RFENV << 16);
451 break;
452 }
453
454 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
455 udelay(1);
456
457 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
458 udelay(1);
459
460 rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
461 B3WIREADDREAALENGTH, 0x0);
462 udelay(1);
463
464 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
465 udelay(1);
466
467 switch (rfpath) {
468 case RF90_PATH_A:
469 rtstatus = rtl8723be_phy_config_rf_with_headerfile(hw,
470 (enum radio_path)rfpath);
471 break;
472 case RF90_PATH_B:
473 rtstatus = rtl8723be_phy_config_rf_with_headerfile(hw,
474 (enum radio_path)rfpath);
475 break;
476 case RF90_PATH_C:
477 break;
478 case RF90_PATH_D:
479 break;
480 }
481
482 switch (rfpath) {
483 case RF90_PATH_A:
484 case RF90_PATH_C:
485 rtl_set_bbreg(hw, pphyreg->rfintfs,
486 BRFSI_RFENV, u4_regvalue);
487 break;
488 case RF90_PATH_B:
489 case RF90_PATH_D:
490 rtl_set_bbreg(hw, pphyreg->rfintfs,
491 BRFSI_RFENV << 16, u4_regvalue);
492 break;
493 }
494
495 if (!rtstatus) {
496 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
497 "Radio[%d] Fail!!", rfpath);
498 return false;
499 }
500 }
501
502 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "\n");
503 return rtstatus;
504}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
new file mode 100644
index 000000000000..a6fea106ced4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
@@ -0,0 +1,43 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_RF_H__
27#define __RTL8723BE_RF_H__
28
29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31
32void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth);
34void rtl8723be_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
35 u8 *ppowerlevel);
36void rtl8723be_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
37 u8 *ppowerlevel_ofdm,
38 u8 *ppowerlevel_bw20,
39 u8 *ppowerlevel_bw40,
40 u8 channel);
41bool rtl8723be_phy_rf6052_config(struct ieee80211_hw *hw);
42
43#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
new file mode 100644
index 000000000000..b4577ebc4bb0
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
@@ -0,0 +1,384 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../core.h"
28#include "../pci.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "../rtl8723com/phy_common.h"
33#include "dm.h"
34#include "hw.h"
35#include "fw.h"
36#include "../rtl8723com/fw_common.h"
37#include "sw.h"
38#include "trx.h"
39#include "led.h"
40#include "table.h"
41#include "../btcoexist/rtl_btc.h"
42
43#include <linux/vmalloc.h>
44#include <linux/module.h>
45
46static void rtl8723be_init_aspm_vars(struct ieee80211_hw *hw)
47{
48 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
49
50 /*close ASPM for AMD defaultly */
51 rtlpci->const_amdpci_aspm = 0;
52
53 /* ASPM PS mode.
54 * 0 - Disable ASPM,
55 * 1 - Enable ASPM without Clock Req,
56 * 2 - Enable ASPM with Clock Req,
57 * 3 - Alwyas Enable ASPM with Clock Req,
58 * 4 - Always Enable ASPM without Clock Req.
59 * set defult to RTL8192CE:3 RTL8192E:2
60 */
61 rtlpci->const_pci_aspm = 3;
62
63 /*Setting for PCI-E device */
64 rtlpci->const_devicepci_aspm_setting = 0x03;
65
66 /*Setting for PCI-E bridge */
67 rtlpci->const_hostpci_aspm_setting = 0x02;
68
69 /* In Hw/Sw Radio Off situation.
70 * 0 - Default,
71 * 1 - From ASPM setting without low Mac Pwr,
72 * 2 - From ASPM setting with low Mac Pwr,
73 * 3 - Bus D3
74 * set default to RTL8192CE:0 RTL8192SE:2
75 */
76 rtlpci->const_hwsw_rfoff_d3 = 0;
77
78 /* This setting works for those device with
79 * backdoor ASPM setting such as EPHY setting.
80 * 0 - Not support ASPM,
81 * 1 - Support ASPM,
82 * 2 - According to chipset.
83 */
84 rtlpci->const_support_pciaspm = 1;
85}
86
87int rtl8723be_init_sw_vars(struct ieee80211_hw *hw)
88{
89 int err = 0;
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
92 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
93
94 rtl8723be_bt_reg_init(hw);
95 rtlpci->msi_support = true;
96 rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
97
98 rtlpriv->dm.dm_initialgain_enable = 1;
99 rtlpriv->dm.dm_flag = 0;
100 rtlpriv->dm.disable_framebursting = 0;
101 rtlpriv->dm.thermalvalue = 0;
102 rtlpci->transmit_config = CFENDFORM | BIT(15) | BIT(24) | BIT(25);
103
104 mac->ht_enable = true;
105
106 /* compatible 5G band 88ce just 2.4G band & smsp */
107 rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
108 rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
109 rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
110
111 rtlpci->receive_config = (RCR_APPFCS |
112 RCR_APP_MIC |
113 RCR_APP_ICV |
114 RCR_APP_PHYST_RXFF |
115 RCR_HTC_LOC_CTRL |
116 RCR_AMF |
117 RCR_ACF |
118 RCR_ADF |
119 RCR_AICV |
120 RCR_AB |
121 RCR_AM |
122 RCR_APM |
123 0);
124
125 rtlpci->irq_mask[0] = (u32) (IMR_PSTIMEOUT |
126 IMR_HSISR_IND_ON_INT |
127 IMR_C2HCMD |
128 IMR_HIGHDOK |
129 IMR_MGNTDOK |
130 IMR_BKDOK |
131 IMR_BEDOK |
132 IMR_VIDOK |
133 IMR_VODOK |
134 IMR_RDU |
135 IMR_ROK |
136 0);
137
138 rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | 0);
139
140 /* for debug level */
141 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
142 /* for LPS & IPS */
143 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
144 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
145 rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
146 rtlpriv->psc.reg_fwctrl_lps = 3;
147 rtlpriv->psc.reg_max_lps_awakeintvl = 5;
148 /* for ASPM, you can close aspm through
149 * set const_support_pciaspm = 0
150 */
151 rtl8723be_init_aspm_vars(hw);
152
153 if (rtlpriv->psc.reg_fwctrl_lps == 1)
154 rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
155 else if (rtlpriv->psc.reg_fwctrl_lps == 2)
156 rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
157 else if (rtlpriv->psc.reg_fwctrl_lps == 3)
158 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
159
160 /* for firmware buf */
161 rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
162 if (!rtlpriv->rtlhal.pfirmware) {
163 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
164 "Can't alloc buffer for fw.\n");
165 return 1;
166 }
167
168 rtlpriv->max_fw_size = 0x8000;
169 pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
170 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
171 rtlpriv->io.dev, GFP_KERNEL, hw,
172 rtl_fw_cb);
173 if (err) {
174 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
175 "Failed to request firmware!\n");
176 return 1;
177 }
178 return 0;
179}
180
181void rtl8723be_deinit_sw_vars(struct ieee80211_hw *hw)
182{
183 struct rtl_priv *rtlpriv = rtl_priv(hw);
184
185 if (rtlpriv->cfg->ops->get_btc_status())
186 rtlpriv->btcoexist.btc_ops->btc_halt_notify();
187 if (rtlpriv->rtlhal.pfirmware) {
188 vfree(rtlpriv->rtlhal.pfirmware);
189 rtlpriv->rtlhal.pfirmware = NULL;
190 }
191}
192
193/* get bt coexist status */
194bool rtl8723be_get_btc_status(void)
195{
196 return true;
197}
198
199static bool is_fw_header(struct rtl92c_firmware_header *hdr)
200{
201 return (hdr->signature & 0xfff0) == 0x5300;
202}
203
204static struct rtl_hal_ops rtl8723be_hal_ops = {
205 .init_sw_vars = rtl8723be_init_sw_vars,
206 .deinit_sw_vars = rtl8723be_deinit_sw_vars,
207 .read_eeprom_info = rtl8723be_read_eeprom_info,
208 .interrupt_recognized = rtl8723be_interrupt_recognized,
209 .hw_init = rtl8723be_hw_init,
210 .hw_disable = rtl8723be_card_disable,
211 .hw_suspend = rtl8723be_suspend,
212 .hw_resume = rtl8723be_resume,
213 .enable_interrupt = rtl8723be_enable_interrupt,
214 .disable_interrupt = rtl8723be_disable_interrupt,
215 .set_network_type = rtl8723be_set_network_type,
216 .set_chk_bssid = rtl8723be_set_check_bssid,
217 .set_qos = rtl8723be_set_qos,
218 .set_bcn_reg = rtl8723be_set_beacon_related_registers,
219 .set_bcn_intv = rtl8723be_set_beacon_interval,
220 .update_interrupt_mask = rtl8723be_update_interrupt_mask,
221 .get_hw_reg = rtl8723be_get_hw_reg,
222 .set_hw_reg = rtl8723be_set_hw_reg,
223 .update_rate_tbl = rtl8723be_update_hal_rate_tbl,
224 .fill_tx_desc = rtl8723be_tx_fill_desc,
225 .fill_tx_cmddesc = rtl8723be_tx_fill_cmddesc,
226 .query_rx_desc = rtl8723be_rx_query_desc,
227 .set_channel_access = rtl8723be_update_channel_access_setting,
228 .radio_onoff_checking = rtl8723be_gpio_radio_on_off_checking,
229 .set_bw_mode = rtl8723be_phy_set_bw_mode,
230 .switch_channel = rtl8723be_phy_sw_chnl,
231 .dm_watchdog = rtl8723be_dm_watchdog,
232 .scan_operation_backup = rtl8723be_phy_scan_operation_backup,
233 .set_rf_power_state = rtl8723be_phy_set_rf_power_state,
234 .led_control = rtl8723be_led_control,
235 .set_desc = rtl8723be_set_desc,
236 .get_desc = rtl8723be_get_desc,
237 .is_tx_desc_closed = rtl8723be_is_tx_desc_closed,
238 .tx_polling = rtl8723be_tx_polling,
239 .enable_hw_sec = rtl8723be_enable_hw_security_config,
240 .set_key = rtl8723be_set_key,
241 .init_sw_leds = rtl8723be_init_sw_leds,
242 .get_bbreg = rtl8723_phy_query_bb_reg,
243 .set_bbreg = rtl8723_phy_set_bb_reg,
244 .get_rfreg = rtl8723be_phy_query_rf_reg,
245 .set_rfreg = rtl8723be_phy_set_rf_reg,
246 .fill_h2c_cmd = rtl8723be_fill_h2c_cmd,
247 .get_btc_status = rtl8723be_get_btc_status,
248 .is_fw_header = is_fw_header,
249};
250
251static struct rtl_mod_params rtl8723be_mod_params = {
252 .sw_crypto = false,
253 .inactiveps = true,
254 .swctrl_lps = false,
255 .fwctrl_lps = true,
256 .debug = DBG_EMERG,
257};
258
259static struct rtl_hal_cfg rtl8723be_hal_cfg = {
260 .bar_id = 2,
261 .write_readback = true,
262 .name = "rtl8723be_pci",
263 .fw_name = "rtlwifi/rtl8723befw.bin",
264 .ops = &rtl8723be_hal_ops,
265 .mod_params = &rtl8723be_mod_params,
266 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
267 .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
268 .maps[SYS_CLK] = REG_SYS_CLKR,
269 .maps[MAC_RCR_AM] = AM,
270 .maps[MAC_RCR_AB] = AB,
271 .maps[MAC_RCR_ACRC32] = ACRC32,
272 .maps[MAC_RCR_ACF] = ACF,
273 .maps[MAC_RCR_AAP] = AAP,
274
275 .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS,
276
277 .maps[EFUSE_TEST] = REG_EFUSE_TEST,
278 .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
279 .maps[EFUSE_CLK] = 0,
280 .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
281 .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
282 .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
283 .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
284 .maps[EFUSE_ANA8M] = ANA8M,
285 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
286 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
287 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
288 .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
289
290 .maps[RWCAM] = REG_CAMCMD,
291 .maps[WCAMI] = REG_CAMWRITE,
292 .maps[RCAMO] = REG_CAMREAD,
293 .maps[CAMDBG] = REG_CAMDBG,
294 .maps[SECR] = REG_SECCFG,
295 .maps[SEC_CAM_NONE] = CAM_NONE,
296 .maps[SEC_CAM_WEP40] = CAM_WEP40,
297 .maps[SEC_CAM_TKIP] = CAM_TKIP,
298 .maps[SEC_CAM_AES] = CAM_AES,
299 .maps[SEC_CAM_WEP104] = CAM_WEP104,
300
301 .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
302 .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
303 .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
304 .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
305 .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
306 .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
307 .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
308 .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
309 .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
310 .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
311 .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
312 .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
313 .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
314
315 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
316 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
317 .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0,
318 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
319 .maps[RTL_IMR_RDU] = IMR_RDU,
320 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
321 .maps[RTL_IMR_BDOK] = IMR_BCNDOK0,
322 .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
323 .maps[RTL_IMR_TBDER] = IMR_TBDER,
324 .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
325 .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
326 .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
327 .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
328 .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
329 .maps[RTL_IMR_VODOK] = IMR_VODOK,
330 .maps[RTL_IMR_ROK] = IMR_ROK,
331 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER),
332
333 .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
334 .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
335 .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
336 .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
337 .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
338 .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
339 .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
340 .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
341 .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
342 .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
343 .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
344 .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
345
346 .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
347 .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
348};
349
350static DEFINE_PCI_DEVICE_TABLE(rtl8723be_pci_id) = {
351 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb723, rtl8723be_hal_cfg)},
352 {},
353};
354
355MODULE_DEVICE_TABLE(pci, rtl8723be_pci_id);
356
357MODULE_AUTHOR("PageHe <page_he@realsil.com.cn>");
358MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
359MODULE_LICENSE("GPL");
360MODULE_DESCRIPTION("Realtek 8723BE 802.11n PCI wireless");
361MODULE_FIRMWARE("rtlwifi/rtl8723befw.bin");
362
363module_param_named(swenc, rtl8723be_mod_params.sw_crypto, bool, 0444);
364module_param_named(debug, rtl8723be_mod_params.debug, int, 0444);
365module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444);
366module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444);
367module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444);
368MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
369MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
370MODULE_PARM_DESC(fwlps, "using linked fw control power save (default 1 is open)\n");
371MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
372
373static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
374
375static struct pci_driver rtl8723be_driver = {
376 .name = KBUILD_MODNAME,
377 .id_table = rtl8723be_pci_id,
378 .probe = rtl_pci_probe,
379 .remove = rtl_pci_disconnect,
380
381 .driver.pm = &rtlwifi_pm_ops,
382};
383
384module_pci_driver(rtl8723be_driver);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.h b/drivers/net/wireless/rtlwifi/rtl8723be/sw.h
new file mode 100644
index 000000000000..a7b25e769950
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.h
@@ -0,0 +1,35 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_SW_H__
27#define __RTL8723BE_SW_H__
28
29int rtl8723be_init_sw_vars(struct ieee80211_hw *hw);
30void rtl8723be_deinit_sw_vars(struct ieee80211_hw *hw);
31void rtl8723be_init_var_map(struct ieee80211_hw *hw);
32bool rtl8723be_get_btc_status(void);
33
34
35#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/table.c b/drivers/net/wireless/rtlwifi/rtl8723be/table.c
new file mode 100644
index 000000000000..4b283cde042e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/table.c
@@ -0,0 +1,572 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Created on 2010/ 5/18, 1:41
23 *
24 * Larry Finger <Larry.Finger@lwfinger.net>
25 *
26 *****************************************************************************/
27
28#include "table.h"
29u32 RTL8723BEPHY_REG_1TARRAY[] = {
30 0x800, 0x80040000,
31 0x804, 0x00000003,
32 0x808, 0x0000FC00,
33 0x80C, 0x0000000A,
34 0x810, 0x10001331,
35 0x814, 0x020C3D10,
36 0x818, 0x02200385,
37 0x81C, 0x00000000,
38 0x820, 0x01000100,
39 0x824, 0x00390204,
40 0x828, 0x00000000,
41 0x82C, 0x00000000,
42 0x830, 0x00000000,
43 0x834, 0x00000000,
44 0x838, 0x00000000,
45 0x83C, 0x00000000,
46 0x840, 0x00010000,
47 0x844, 0x00000000,
48 0x848, 0x00000000,
49 0x84C, 0x00000000,
50 0x850, 0x00000000,
51 0x854, 0x00000000,
52 0x858, 0x569A11A9,
53 0x85C, 0x01000014,
54 0x860, 0x66F60110,
55 0x864, 0x061F0649,
56 0x868, 0x00000000,
57 0x86C, 0x27272700,
58 0x870, 0x07000760,
59 0x874, 0x25004000,
60 0x878, 0x00000808,
61 0x87C, 0x00000000,
62 0x880, 0xB0000C1C,
63 0x884, 0x00000001,
64 0x888, 0x00000000,
65 0x88C, 0xCCC000C0,
66 0x890, 0x00000800,
67 0x894, 0xFFFFFFFE,
68 0x898, 0x40302010,
69 0x89C, 0x00706050,
70 0x900, 0x00000000,
71 0x904, 0x00000023,
72 0x908, 0x00000000,
73 0x90C, 0x81121111,
74 0x910, 0x00000002,
75 0x914, 0x00000201,
76 0x948, 0x00000000,
77 0xA00, 0x00D047C8,
78 0xA04, 0x80FF000C,
79 0xA08, 0x8C838300,
80 0xA0C, 0x2E7F120F,
81 0xA10, 0x9500BB78,
82 0xA14, 0x1114D028,
83 0xA18, 0x00881117,
84 0xA1C, 0x89140F00,
85 0xA20, 0x1A1B0000,
86 0xA24, 0x090E1317,
87 0xA28, 0x00000204,
88 0xA2C, 0x00D30000,
89 0xA70, 0x101FBF00,
90 0xA74, 0x00000007,
91 0xA78, 0x00000900,
92 0xA7C, 0x225B0606,
93 0xA80, 0x21806490,
94 0xB2C, 0x00000000,
95 0xC00, 0x48071D40,
96 0xC04, 0x03A05611,
97 0xC08, 0x000000E4,
98 0xC0C, 0x6C6C6C6C,
99 0xC10, 0x08800000,
100 0xC14, 0x40000100,
101 0xC18, 0x08800000,
102 0xC1C, 0x40000100,
103 0xC20, 0x00000000,
104 0xC24, 0x00000000,
105 0xC28, 0x00000000,
106 0xC2C, 0x00000000,
107 0xC30, 0x69E9AC44,
108 0xC34, 0x469652AF,
109 0xC38, 0x49795994,
110 0xC3C, 0x0A97971C,
111 0xC40, 0x1F7C403F,
112 0xC44, 0x000100B7,
113 0xC48, 0xEC020107,
114 0xC4C, 0x007F037F,
115 0xC50, 0x69553420,
116 0xC54, 0x43BC0094,
117 0xC58, 0x00023169,
118 0xC5C, 0x00250492,
119 0xC60, 0x00000000,
120 0xC64, 0x7112848B,
121 0xC68, 0x47C00BFF,
122 0xC6C, 0x00000036,
123 0xC70, 0x2C7F000D,
124 0xC74, 0x020610DB,
125 0xC78, 0x0000001F,
126 0xC7C, 0x00B91612,
127 0xC80, 0x390000E4,
128 0xC84, 0x20F60000,
129 0xC88, 0x40000100,
130 0xC8C, 0x20200000,
131 0xC90, 0x00020E1A,
132 0xC94, 0x00000000,
133 0xC98, 0x00020E1A,
134 0xC9C, 0x00007F7F,
135 0xCA0, 0x00000000,
136 0xCA4, 0x000300A0,
137 0xCA8, 0x00000000,
138 0xCAC, 0x00000000,
139 0xCB0, 0x00000000,
140 0xCB4, 0x00000000,
141 0xCB8, 0x00000000,
142 0xCBC, 0x28000000,
143 0xCC0, 0x00000000,
144 0xCC4, 0x00000000,
145 0xCC8, 0x00000000,
146 0xCCC, 0x00000000,
147 0xCD0, 0x00000000,
148 0xCD4, 0x00000000,
149 0xCD8, 0x64B22427,
150 0xCDC, 0x00766932,
151 0xCE0, 0x00222222,
152 0xCE4, 0x00000000,
153 0xCE8, 0x37644302,
154 0xCEC, 0x2F97D40C,
155 0xD00, 0x00000740,
156 0xD04, 0x40020401,
157 0xD08, 0x0000907F,
158 0xD0C, 0x20010201,
159 0xD10, 0xA0633333,
160 0xD14, 0x3333BC53,
161 0xD18, 0x7A8F5B6F,
162 0xD2C, 0xCC979975,
163 0xD30, 0x00000000,
164 0xD34, 0x80608000,
165 0xD38, 0x00000000,
166 0xD3C, 0x00127353,
167 0xD40, 0x00000000,
168 0xD44, 0x00000000,
169 0xD48, 0x00000000,
170 0xD4C, 0x00000000,
171 0xD50, 0x6437140A,
172 0xD54, 0x00000000,
173 0xD58, 0x00000282,
174 0xD5C, 0x30032064,
175 0xD60, 0x4653DE68,
176 0xD64, 0x04518A3C,
177 0xD68, 0x00002101,
178 0xD6C, 0x2A201C16,
179 0xD70, 0x1812362E,
180 0xD74, 0x322C2220,
181 0xD78, 0x000E3C24,
182 0xE00, 0x2D2D2D2D,
183 0xE04, 0x2D2D2D2D,
184 0xE08, 0x0390272D,
185 0xE10, 0x2D2D2D2D,
186 0xE14, 0x2D2D2D2D,
187 0xE18, 0x2D2D2D2D,
188 0xE1C, 0x2D2D2D2D,
189 0xE28, 0x00000000,
190 0xE30, 0x1000DC1F,
191 0xE34, 0x10008C1F,
192 0xE38, 0x02140102,
193 0xE3C, 0x681604C2,
194 0xE40, 0x01007C00,
195 0xE44, 0x01004800,
196 0xE48, 0xFB000000,
197 0xE4C, 0x000028D1,
198 0xE50, 0x1000DC1F,
199 0xE54, 0x10008C1F,
200 0xE58, 0x02140102,
201 0xE5C, 0x28160D05,
202 0xE60, 0x00000008,
203 0xE68, 0x001B2556,
204 0xE6C, 0x00C00096,
205 0xE70, 0x00C00096,
206 0xE74, 0x01000056,
207 0xE78, 0x01000014,
208 0xE7C, 0x01000056,
209 0xE80, 0x01000014,
210 0xE84, 0x00C00096,
211 0xE88, 0x01000056,
212 0xE8C, 0x00C00096,
213 0xED0, 0x00C00096,
214 0xED4, 0x00C00096,
215 0xED8, 0x00C00096,
216 0xEDC, 0x000000D6,
217 0xEE0, 0x000000D6,
218 0xEEC, 0x01C00016,
219 0xF14, 0x00000003,
220 0xF4C, 0x00000000,
221 0xF00, 0x00000300,
222 0x820, 0x01000100,
223 0x800, 0x83040000,
224};
225
226u32 RTL8723BEPHY_REG_ARRAY_PG[] = {
227 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00004000,
228 0, 0, 0, 0x0000086c, 0xffffff00, 0x34363800,
229 0, 0, 0, 0x00000e00, 0xffffffff, 0x42444646,
230 0, 0, 0, 0x00000e04, 0xffffffff, 0x30343840,
231 0, 0, 0, 0x00000e10, 0xffffffff, 0x38404244,
232 0, 0, 0, 0x00000e14, 0xffffffff, 0x26303436
233};
234
235u32 RTL8723BE_RADIOA_1TARRAY[] = {
236 0x000, 0x00010000,
237 0x0B0, 0x000DFFE0,
238 0x0FE, 0x00000000,
239 0x0FE, 0x00000000,
240 0x0FE, 0x00000000,
241 0x0B1, 0x00000018,
242 0x0FE, 0x00000000,
243 0x0FE, 0x00000000,
244 0x0FE, 0x00000000,
245 0x0B2, 0x00084C00,
246 0x0B5, 0x0000D2CC,
247 0x0B6, 0x000925AA,
248 0x0B7, 0x00000010,
249 0x0B8, 0x0000907F,
250 0x05C, 0x00000002,
251 0x07C, 0x00000002,
252 0x07E, 0x00000005,
253 0x08B, 0x0006FC00,
254 0x0B0, 0x000FF9F0,
255 0x01C, 0x000739D2,
256 0x01E, 0x00000000,
257 0x0DF, 0x00000780,
258 0x050, 0x00067435,
259 0x051, 0x0006B04E,
260 0x052, 0x000007D2,
261 0x053, 0x00000000,
262 0x054, 0x00050400,
263 0x055, 0x0004026E,
264 0x0DD, 0x0000004C,
265 0x070, 0x00067435,
266 0x071, 0x0006B04E,
267 0x072, 0x000007D2,
268 0x073, 0x00000000,
269 0x074, 0x00050400,
270 0x075, 0x0004026E,
271 0x0EF, 0x00000100,
272 0x034, 0x0000ADD7,
273 0x035, 0x00005C00,
274 0x034, 0x00009DD4,
275 0x035, 0x00005000,
276 0x034, 0x00008DD1,
277 0x035, 0x00004400,
278 0x034, 0x00007DCE,
279 0x035, 0x00003800,
280 0x034, 0x00006CD1,
281 0x035, 0x00004400,
282 0x034, 0x00005CCE,
283 0x035, 0x00003800,
284 0x034, 0x000048CE,
285 0x035, 0x00004400,
286 0x034, 0x000034CE,
287 0x035, 0x00003800,
288 0x034, 0x00002451,
289 0x035, 0x00004400,
290 0x034, 0x0000144E,
291 0x035, 0x00003800,
292 0x034, 0x00000051,
293 0x035, 0x00004400,
294 0x0EF, 0x00000000,
295 0x0EF, 0x00000100,
296 0x0ED, 0x00000010,
297 0x044, 0x0000ADD7,
298 0x044, 0x00009DD4,
299 0x044, 0x00008DD1,
300 0x044, 0x00007DCE,
301 0x044, 0x00006CC1,
302 0x044, 0x00005CCE,
303 0x044, 0x000044D1,
304 0x044, 0x000034CE,
305 0x044, 0x00002451,
306 0x044, 0x0000144E,
307 0x044, 0x00000051,
308 0x0EF, 0x00000000,
309 0x0ED, 0x00000000,
310 0x0EF, 0x00002000,
311 0x03B, 0x000380EF,
312 0x03B, 0x000302FE,
313 0x03B, 0x00028CE6,
314 0x03B, 0x000200BC,
315 0x03B, 0x000188A5,
316 0x03B, 0x00010FBC,
317 0x03B, 0x00008F71,
318 0x03B, 0x00000900,
319 0x0EF, 0x00000000,
320 0x0ED, 0x00000001,
321 0x040, 0x000380EF,
322 0x040, 0x000302FE,
323 0x040, 0x00028CE6,
324 0x040, 0x000200BC,
325 0x040, 0x000188A5,
326 0x040, 0x00010FBC,
327 0x040, 0x00008F71,
328 0x040, 0x00000900,
329 0x0ED, 0x00000000,
330 0x082, 0x00080000,
331 0x083, 0x00008000,
332 0x084, 0x00048D80,
333 0x085, 0x00068000,
334 0x0A2, 0x00080000,
335 0x0A3, 0x00008000,
336 0x0A4, 0x00048D80,
337 0x0A5, 0x00068000,
338 0x000, 0x00033D80,
339};
340
341u32 RTL8723BEMAC_1T_ARRAY[] = {
342 0x02F, 0x00000030,
343 0x035, 0x00000000,
344 0x428, 0x0000000A,
345 0x429, 0x00000010,
346 0x430, 0x00000000,
347 0x431, 0x00000000,
348 0x432, 0x00000000,
349 0x433, 0x00000001,
350 0x434, 0x00000004,
351 0x435, 0x00000005,
352 0x436, 0x00000007,
353 0x437, 0x00000008,
354 0x43C, 0x00000004,
355 0x43D, 0x00000005,
356 0x43E, 0x00000007,
357 0x43F, 0x00000008,
358 0x440, 0x0000005D,
359 0x441, 0x00000001,
360 0x442, 0x00000000,
361 0x444, 0x00000010,
362 0x445, 0x00000000,
363 0x446, 0x00000000,
364 0x447, 0x00000000,
365 0x448, 0x00000000,
366 0x449, 0x000000F0,
367 0x44A, 0x0000000F,
368 0x44B, 0x0000003E,
369 0x44C, 0x00000010,
370 0x44D, 0x00000000,
371 0x44E, 0x00000000,
372 0x44F, 0x00000000,
373 0x450, 0x00000000,
374 0x451, 0x000000F0,
375 0x452, 0x0000000F,
376 0x453, 0x00000000,
377 0x456, 0x0000005E,
378 0x460, 0x00000066,
379 0x461, 0x00000066,
380 0x4C8, 0x000000FF,
381 0x4C9, 0x00000008,
382 0x4CC, 0x000000FF,
383 0x4CD, 0x000000FF,
384 0x4CE, 0x00000001,
385 0x500, 0x00000026,
386 0x501, 0x000000A2,
387 0x502, 0x0000002F,
388 0x503, 0x00000000,
389 0x504, 0x00000028,
390 0x505, 0x000000A3,
391 0x506, 0x0000005E,
392 0x507, 0x00000000,
393 0x508, 0x0000002B,
394 0x509, 0x000000A4,
395 0x50A, 0x0000005E,
396 0x50B, 0x00000000,
397 0x50C, 0x0000004F,
398 0x50D, 0x000000A4,
399 0x50E, 0x00000000,
400 0x50F, 0x00000000,
401 0x512, 0x0000001C,
402 0x514, 0x0000000A,
403 0x516, 0x0000000A,
404 0x525, 0x0000004F,
405 0x550, 0x00000010,
406 0x551, 0x00000010,
407 0x559, 0x00000002,
408 0x55C, 0x00000050,
409 0x55D, 0x000000FF,
410 0x605, 0x00000030,
411 0x608, 0x0000000E,
412 0x609, 0x0000002A,
413 0x620, 0x000000FF,
414 0x621, 0x000000FF,
415 0x622, 0x000000FF,
416 0x623, 0x000000FF,
417 0x624, 0x000000FF,
418 0x625, 0x000000FF,
419 0x626, 0x000000FF,
420 0x627, 0x000000FF,
421 0x638, 0x00000050,
422 0x63C, 0x0000000A,
423 0x63D, 0x0000000A,
424 0x63E, 0x0000000E,
425 0x63F, 0x0000000E,
426 0x640, 0x00000040,
427 0x642, 0x00000040,
428 0x643, 0x00000000,
429 0x652, 0x000000C8,
430 0x66E, 0x00000005,
431 0x700, 0x00000021,
432 0x701, 0x00000043,
433 0x702, 0x00000065,
434 0x703, 0x00000087,
435 0x708, 0x00000021,
436 0x709, 0x00000043,
437 0x70A, 0x00000065,
438 0x70B, 0x00000087,
439};
440
441u32 RTL8723BEAGCTAB_1TARRAY[] = {
442 0xC78, 0xFD000001,
443 0xC78, 0xFC010001,
444 0xC78, 0xFB020001,
445 0xC78, 0xFA030001,
446 0xC78, 0xF9040001,
447 0xC78, 0xF8050001,
448 0xC78, 0xF7060001,
449 0xC78, 0xF6070001,
450 0xC78, 0xF5080001,
451 0xC78, 0xF4090001,
452 0xC78, 0xF30A0001,
453 0xC78, 0xF20B0001,
454 0xC78, 0xF10C0001,
455 0xC78, 0xF00D0001,
456 0xC78, 0xEF0E0001,
457 0xC78, 0xEE0F0001,
458 0xC78, 0xED100001,
459 0xC78, 0xEC110001,
460 0xC78, 0xEB120001,
461 0xC78, 0xEA130001,
462 0xC78, 0xE9140001,
463 0xC78, 0xE8150001,
464 0xC78, 0xE7160001,
465 0xC78, 0xAA170001,
466 0xC78, 0xA9180001,
467 0xC78, 0xA8190001,
468 0xC78, 0xA71A0001,
469 0xC78, 0xA61B0001,
470 0xC78, 0xA51C0001,
471 0xC78, 0xA41D0001,
472 0xC78, 0xA31E0001,
473 0xC78, 0x671F0001,
474 0xC78, 0x66200001,
475 0xC78, 0x65210001,
476 0xC78, 0x64220001,
477 0xC78, 0x63230001,
478 0xC78, 0x62240001,
479 0xC78, 0x61250001,
480 0xC78, 0x47260001,
481 0xC78, 0x46270001,
482 0xC78, 0x45280001,
483 0xC78, 0x44290001,
484 0xC78, 0x432A0001,
485 0xC78, 0x422B0001,
486 0xC78, 0x292C0001,
487 0xC78, 0x282D0001,
488 0xC78, 0x272E0001,
489 0xC78, 0x262F0001,
490 0xC78, 0x25300001,
491 0xC78, 0x24310001,
492 0xC78, 0x09320001,
493 0xC78, 0x08330001,
494 0xC78, 0x07340001,
495 0xC78, 0x06350001,
496 0xC78, 0x05360001,
497 0xC78, 0x04370001,
498 0xC78, 0x03380001,
499 0xC78, 0x02390001,
500 0xC78, 0x013A0001,
501 0xC78, 0x003B0001,
502 0xC78, 0x003C0001,
503 0xC78, 0x003D0001,
504 0xC78, 0x003E0001,
505 0xC78, 0x003F0001,
506 0xC78, 0xFC400001,
507 0xC78, 0xFB410001,
508 0xC78, 0xFA420001,
509 0xC78, 0xF9430001,
510 0xC78, 0xF8440001,
511 0xC78, 0xF7450001,
512 0xC78, 0xF6460001,
513 0xC78, 0xF5470001,
514 0xC78, 0xF4480001,
515 0xC78, 0xF3490001,
516 0xC78, 0xF24A0001,
517 0xC78, 0xF14B0001,
518 0xC78, 0xF04C0001,
519 0xC78, 0xEF4D0001,
520 0xC78, 0xEE4E0001,
521 0xC78, 0xED4F0001,
522 0xC78, 0xEC500001,
523 0xC78, 0xEB510001,
524 0xC78, 0xEA520001,
525 0xC78, 0xE9530001,
526 0xC78, 0xE8540001,
527 0xC78, 0xE7550001,
528 0xC78, 0xE6560001,
529 0xC78, 0xE5570001,
530 0xC78, 0xAA580001,
531 0xC78, 0xA9590001,
532 0xC78, 0xA85A0001,
533 0xC78, 0xA75B0001,
534 0xC78, 0xA65C0001,
535 0xC78, 0xA55D0001,
536 0xC78, 0xA45E0001,
537 0xC78, 0x675F0001,
538 0xC78, 0x66600001,
539 0xC78, 0x65610001,
540 0xC78, 0x64620001,
541 0xC78, 0x63630001,
542 0xC78, 0x62640001,
543 0xC78, 0x61650001,
544 0xC78, 0x47660001,
545 0xC78, 0x46670001,
546 0xC78, 0x45680001,
547 0xC78, 0x44690001,
548 0xC78, 0x436A0001,
549 0xC78, 0x426B0001,
550 0xC78, 0x296C0001,
551 0xC78, 0x286D0001,
552 0xC78, 0x276E0001,
553 0xC78, 0x266F0001,
554 0xC78, 0x25700001,
555 0xC78, 0x24710001,
556 0xC78, 0x09720001,
557 0xC78, 0x08730001,
558 0xC78, 0x07740001,
559 0xC78, 0x06750001,
560 0xC78, 0x05760001,
561 0xC78, 0x04770001,
562 0xC78, 0x03780001,
563 0xC78, 0x02790001,
564 0xC78, 0x017A0001,
565 0xC78, 0x007B0001,
566 0xC78, 0x007C0001,
567 0xC78, 0x007D0001,
568 0xC78, 0x007E0001,
569 0xC78, 0x007F0001,
570 0xC50, 0x69553422,
571 0xC50, 0x69553420,
572};
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/table.h b/drivers/net/wireless/rtlwifi/rtl8723be/table.h
new file mode 100644
index 000000000000..932760a84827
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/table.h
@@ -0,0 +1,43 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Created on 2010/ 5/18, 1:41
23 *
24 * Larry Finger <Larry.Finger@lwfinger.net>
25 *
26 *****************************************************************************/
27
28#ifndef __RTL8723BE_TABLE__H_
29#define __RTL8723BE_TABLE__H_
30
31#include <linux/types.h>
32#define RTL8723BEPHY_REG_1TARRAYLEN 388
33extern u32 RTL8723BEPHY_REG_1TARRAY[];
34#define RTL8723BEPHY_REG_ARRAY_PGLEN 36
35extern u32 RTL8723BEPHY_REG_ARRAY_PG[];
36#define RTL8723BE_RADIOA_1TARRAYLEN 206
37extern u32 RTL8723BE_RADIOA_1TARRAY[];
38#define RTL8723BEMAC_1T_ARRAYLEN 194
39extern u32 RTL8723BEMAC_1T_ARRAY[];
40#define RTL8723BEAGCTAB_1TARRAYLEN 260
41extern u32 RTL8723BEAGCTAB_1TARRAY[];
42
43#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
new file mode 100644
index 000000000000..74a75dceab08
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
@@ -0,0 +1,960 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
29#include "../stats.h"
30#include "reg.h"
31#include "def.h"
32#include "phy.h"
33#include "trx.h"
34#include "led.h"
35#include "dm.h"
36#include "phy.h"
37
38static u8 _rtl8723be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
39{
40 __le16 fc = rtl_get_fc(skb);
41
42 if (unlikely(ieee80211_is_beacon(fc)))
43 return QSLT_BEACON;
44 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
45 return QSLT_MGNT;
46
47 return skb->priority;
48}
49
50/* mac80211's rate_idx is like this:
51 *
52 * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
53 *
54 * B/G rate:
55 * (rx_status->flag & RX_FLAG_HT) = 0,
56 * DESC92C_RATE1M-->DESC92C_RATE54M ==> idx is 0-->11,
57 *
58 * N rate:
59 * (rx_status->flag & RX_FLAG_HT) = 1,
60 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
61 *
62 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
63 * A rate:
64 * (rx_status->flag & RX_FLAG_HT) = 0,
65 * DESC92C_RATE6M-->DESC92C_RATE54M ==> idx is 0-->7,
66 *
67 * N rate:
68 * (rx_status->flag & RX_FLAG_HT) = 1,
69 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
70 */
71static int _rtl8723be_rate_mapping(struct ieee80211_hw *hw,
72 bool isht, u8 desc_rate)
73{
74 int rate_idx;
75
76 if (!isht) {
77 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
78 switch (desc_rate) {
79 case DESC92C_RATE1M:
80 rate_idx = 0;
81 break;
82 case DESC92C_RATE2M:
83 rate_idx = 1;
84 break;
85 case DESC92C_RATE5_5M:
86 rate_idx = 2;
87 break;
88 case DESC92C_RATE11M:
89 rate_idx = 3;
90 break;
91 case DESC92C_RATE6M:
92 rate_idx = 4;
93 break;
94 case DESC92C_RATE9M:
95 rate_idx = 5;
96 break;
97 case DESC92C_RATE12M:
98 rate_idx = 6;
99 break;
100 case DESC92C_RATE18M:
101 rate_idx = 7;
102 break;
103 case DESC92C_RATE24M:
104 rate_idx = 8;
105 break;
106 case DESC92C_RATE36M:
107 rate_idx = 9;
108 break;
109 case DESC92C_RATE48M:
110 rate_idx = 10;
111 break;
112 case DESC92C_RATE54M:
113 rate_idx = 11;
114 break;
115 default:
116 rate_idx = 0;
117 break;
118 }
119 } else {
120 switch (desc_rate) {
121 case DESC92C_RATE6M:
122 rate_idx = 0;
123 break;
124 case DESC92C_RATE9M:
125 rate_idx = 1;
126 break;
127 case DESC92C_RATE12M:
128 rate_idx = 2;
129 break;
130 case DESC92C_RATE18M:
131 rate_idx = 3;
132 break;
133 case DESC92C_RATE24M:
134 rate_idx = 4;
135 break;
136 case DESC92C_RATE36M:
137 rate_idx = 5;
138 break;
139 case DESC92C_RATE48M:
140 rate_idx = 6;
141 break;
142 case DESC92C_RATE54M:
143 rate_idx = 7;
144 break;
145 default:
146 rate_idx = 0;
147 break;
148 }
149 }
150 } else {
151 switch (desc_rate) {
152 case DESC92C_RATEMCS0:
153 rate_idx = 0;
154 break;
155 case DESC92C_RATEMCS1:
156 rate_idx = 1;
157 break;
158 case DESC92C_RATEMCS2:
159 rate_idx = 2;
160 break;
161 case DESC92C_RATEMCS3:
162 rate_idx = 3;
163 break;
164 case DESC92C_RATEMCS4:
165 rate_idx = 4;
166 break;
167 case DESC92C_RATEMCS5:
168 rate_idx = 5;
169 break;
170 case DESC92C_RATEMCS6:
171 rate_idx = 6;
172 break;
173 case DESC92C_RATEMCS7:
174 rate_idx = 7;
175 break;
176 case DESC92C_RATEMCS8:
177 rate_idx = 8;
178 break;
179 case DESC92C_RATEMCS9:
180 rate_idx = 9;
181 break;
182 case DESC92C_RATEMCS10:
183 rate_idx = 10;
184 break;
185 case DESC92C_RATEMCS11:
186 rate_idx = 11;
187 break;
188 case DESC92C_RATEMCS12:
189 rate_idx = 12;
190 break;
191 case DESC92C_RATEMCS13:
192 rate_idx = 13;
193 break;
194 case DESC92C_RATEMCS14:
195 rate_idx = 14;
196 break;
197 case DESC92C_RATEMCS15:
198 rate_idx = 15;
199 break;
200 default:
201 rate_idx = 0;
202 break;
203 }
204 }
205 return rate_idx;
206}
207
208static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw,
209 struct rtl_stats *pstatus, u8 *pdesc,
210 struct rx_fwinfo_8723be *p_drvinfo,
211 bool packet_match_bssid,
212 bool packet_toself,
213 bool packet_beacon)
214{
215 struct rtl_priv *rtlpriv = rtl_priv(hw);
216 struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
217 struct phy_sts_cck_8723e_t *cck_buf;
218 struct phy_status_rpt *p_phystrpt = (struct phy_status_rpt *)p_drvinfo;
219 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
220 char rx_pwr_all = 0, rx_pwr[4];
221 u8 rf_rx_num = 0, evm, pwdb_all;
222 u8 i, max_spatial_stream;
223 u32 rssi, total_rssi = 0;
224 bool is_cck = pstatus->is_cck;
225 u8 lan_idx, vga_idx;
226
227 /* Record it for next packet processing */
228 pstatus->packet_matchbssid = packet_match_bssid;
229 pstatus->packet_toself = packet_toself;
230 pstatus->packet_beacon = packet_beacon;
231 pstatus->rx_mimo_sig_qual[0] = -1;
232 pstatus->rx_mimo_sig_qual[1] = -1;
233
234 if (is_cck) {
235 u8 cck_highpwr;
236 u8 cck_agc_rpt;
237 /* CCK Driver info Structure is not the same as OFDM packet. */
238 cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo;
239 cck_agc_rpt = cck_buf->cck_agc_rpt;
240
241 /* (1)Hardware does not provide RSSI for CCK
242 * (2)PWDB, Average PWDB cacluated by
243 * hardware (for rate adaptive)
244 */
245 if (ppsc->rfpwr_state == ERFON)
246 cck_highpwr = (u8) rtl_get_bbreg(hw,
247 RFPGA0_XA_HSSIPARAMETER2,
248 BIT(9));
249 else
250 cck_highpwr = false;
251
252 lan_idx = ((cck_agc_rpt & 0xE0) >> 5);
253 vga_idx = (cck_agc_rpt & 0x1f);
254 switch (lan_idx) {
255 case 7:
256 if (vga_idx <= 27)/*VGA_idx = 27~2*/
257 rx_pwr_all = -100 + 2 * (27 - vga_idx);
258 else
259 rx_pwr_all = -100;
260 break;
261 case 6:/*VGA_idx = 2~0*/
262 rx_pwr_all = -48 + 2 * (2 - vga_idx);
263 break;
264 case 5:/*VGA_idx = 7~5*/
265 rx_pwr_all = -42 + 2 * (7 - vga_idx);
266 break;
267 case 4:/*VGA_idx = 7~4*/
268 rx_pwr_all = -36 + 2 * (7 - vga_idx);
269 break;
270 case 3:/*VGA_idx = 7~0*/
271 rx_pwr_all = -24 + 2 * (7 - vga_idx);
272 break;
273 case 2:
274 if (cck_highpwr)/*VGA_idx = 5~0*/
275 rx_pwr_all = -12 + 2 * (5 - vga_idx);
276 else
277 rx_pwr_all = -6 + 2 * (5 - vga_idx);
278 break;
279 case 1:
280 rx_pwr_all = 8 - 2 * vga_idx;
281 break;
282 case 0:
283 rx_pwr_all = 14 - 2 * vga_idx;
284 break;
285 default:
286 break;
287 }
288 rx_pwr_all += 6;
289 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
290 /* CCK gain is smaller than OFDM/MCS gain, */
291 /* so we add gain diff by experiences,
292 * the val is 6
293 */
294 pwdb_all += 6;
295 if (pwdb_all > 100)
296 pwdb_all = 100;
297 /* modify the offset to make the same gain index with OFDM. */
298 if (pwdb_all > 34 && pwdb_all <= 42)
299 pwdb_all -= 2;
300 else if (pwdb_all > 26 && pwdb_all <= 34)
301 pwdb_all -= 6;
302 else if (pwdb_all > 14 && pwdb_all <= 26)
303 pwdb_all -= 8;
304 else if (pwdb_all > 4 && pwdb_all <= 14)
305 pwdb_all -= 4;
306 if (!cck_highpwr) {
307 if (pwdb_all >= 80)
308 pwdb_all = ((pwdb_all - 80) << 1) +
309 ((pwdb_all - 80) >> 1) + 80;
310 else if ((pwdb_all <= 78) && (pwdb_all >= 20))
311 pwdb_all += 3;
312 if (pwdb_all > 100)
313 pwdb_all = 100;
314 }
315
316 pstatus->rx_pwdb_all = pwdb_all;
317 pstatus->recvsignalpower = rx_pwr_all;
318
319 /* (3) Get Signal Quality (EVM) */
320 if (packet_match_bssid) {
321 u8 sq;
322
323 if (pstatus->rx_pwdb_all > 40) {
324 sq = 100;
325 } else {
326 sq = cck_buf->sq_rpt;
327 if (sq > 64)
328 sq = 0;
329 else if (sq < 20)
330 sq = 100;
331 else
332 sq = ((64 - sq) * 100) / 44;
333 }
334
335 pstatus->signalquality = sq;
336 pstatus->rx_mimo_sig_qual[0] = sq;
337 pstatus->rx_mimo_sig_qual[1] = -1;
338 }
339 } else {
340 rtlpriv->dm.rfpath_rxenable[0] = true;
341 rtlpriv->dm.rfpath_rxenable[1] = true;
342
343 /* (1)Get RSSI for HT rate */
344 for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
345 /* we will judge RF RX path now. */
346 if (rtlpriv->dm.rfpath_rxenable[i])
347 rf_rx_num++;
348
349 rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f)*2) - 110;
350
351 /* Translate DBM to percentage. */
352 rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
353 total_rssi += rssi;
354
355 /* Get Rx snr value in DB */
356 rtlpriv->stats.rx_snr_db[i] =
357 (long)(p_drvinfo->rxsnr[i] / 2);
358
359 /* Record Signal Strength for next packet */
360 if (packet_match_bssid)
361 pstatus->rx_mimo_signalstrength[i] = (u8) rssi;
362 }
363
364 /* (2)PWDB, Avg cacluated by hardware (for rate adaptive) */
365 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
366
367 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
368 pstatus->rx_pwdb_all = pwdb_all;
369 pstatus->rxpower = rx_pwr_all;
370 pstatus->recvsignalpower = rx_pwr_all;
371
372 /* (3)EVM of HT rate */
373 if (pstatus->is_ht && pstatus->rate >= DESC92C_RATEMCS8 &&
374 pstatus->rate <= DESC92C_RATEMCS15)
375 max_spatial_stream = 2;
376 else
377 max_spatial_stream = 1;
378
379 for (i = 0; i < max_spatial_stream; i++) {
380 evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
381
382 if (packet_match_bssid) {
383 /* Fill value in RFD, Get the first
384 * spatial stream only
385 */
386 if (i == 0)
387 pstatus->signalquality =
388 (u8) (evm & 0xff);
389 pstatus->rx_mimo_sig_qual[i] =
390 (u8) (evm & 0xff);
391 }
392 }
393 if (packet_match_bssid) {
394 for (i = RF90_PATH_A; i <= RF90_PATH_B; i++)
395 rtl_priv(hw)->dm.cfo_tail[i] =
396 (char)p_phystrpt->path_cfotail[i];
397
398 rtl_priv(hw)->dm.packet_count++;
399 if (rtl_priv(hw)->dm.packet_count == 0xffffffff)
400 rtl_priv(hw)->dm.packet_count = 0;
401 }
402 }
403
404 /* UI BSS List signal strength(in percentage),
405 * make it good looking, from 0~100.
406 */
407 if (is_cck)
408 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
409 pwdb_all));
410 else if (rf_rx_num != 0)
411 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
412 total_rssi /= rf_rx_num));
413 /*HW antenna diversity*/
414 rtldm->fat_table.antsel_rx_keep_0 = p_phystrpt->ant_sel;
415 rtldm->fat_table.antsel_rx_keep_1 = p_phystrpt->ant_sel_b;
416 rtldm->fat_table.antsel_rx_keep_2 = p_phystrpt->antsel_rx_keep_2;
417}
418
419static void _rtl8723be_translate_rx_signal_stuff(struct ieee80211_hw *hw,
420 struct sk_buff *skb,
421 struct rtl_stats *pstatus,
422 u8 *pdesc,
423 struct rx_fwinfo_8723be *p_drvinfo)
424{
425 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
426 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
427 struct ieee80211_hdr *hdr;
428 u8 *tmp_buf;
429 u8 *praddr;
430 u8 *psaddr;
431 u16 fc, type;
432 bool packet_matchbssid, packet_toself, packet_beacon;
433
434 tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
435
436 hdr = (struct ieee80211_hdr *)tmp_buf;
437 fc = le16_to_cpu(hdr->frame_control);
438 type = WLAN_FC_GET_TYPE(hdr->frame_control);
439 praddr = hdr->addr1;
440 psaddr = ieee80211_get_SA(hdr);
441 memcpy(pstatus->psaddr, psaddr, ETH_ALEN);
442
443 packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
444 (!ether_addr_equal(mac->bssid, (fc & IEEE80211_FCTL_TODS) ?
445 hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
446 hdr->addr2 : hdr->addr3)) &&
447 (!pstatus->hwerror) &&
448 (!pstatus->crc) && (!pstatus->icv));
449
450 packet_toself = packet_matchbssid &&
451 (!ether_addr_equal(praddr, rtlefuse->dev_addr));
452
453 /* YP: packet_beacon is not initialized,
454 * this assignment is neccesary,
455 * otherwise it counld be true in this case
456 * the situation is much worse in Kernel 3.10
457 */
458 if (ieee80211_is_beacon(hdr->frame_control))
459 packet_beacon = true;
460 else
461 packet_beacon = false;
462
463 if (packet_beacon && packet_matchbssid)
464 rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++;
465
466 _rtl8723be_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo,
467 packet_matchbssid,
468 packet_toself,
469 packet_beacon);
470
471 rtl_process_phyinfo(hw, tmp_buf, pstatus);
472}
473
474static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
475 u8 *virtualaddress)
476{
477 u32 dwtmp = 0;
478 memset(virtualaddress, 0, 8);
479
480 SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
481 if (ptcb_desc->empkt_num == 1) {
482 dwtmp = ptcb_desc->empkt_len[0];
483 } else {
484 dwtmp = ptcb_desc->empkt_len[0];
485 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
486 dwtmp += ptcb_desc->empkt_len[1];
487 }
488 SET_EARLYMODE_LEN0(virtualaddress, dwtmp);
489
490 if (ptcb_desc->empkt_num <= 3) {
491 dwtmp = ptcb_desc->empkt_len[2];
492 } else {
493 dwtmp = ptcb_desc->empkt_len[2];
494 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
495 dwtmp += ptcb_desc->empkt_len[3];
496 }
497 SET_EARLYMODE_LEN1(virtualaddress, dwtmp);
498 if (ptcb_desc->empkt_num <= 5) {
499 dwtmp = ptcb_desc->empkt_len[4];
500 } else {
501 dwtmp = ptcb_desc->empkt_len[4];
502 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
503 dwtmp += ptcb_desc->empkt_len[5];
504 }
505 SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF);
506 SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4);
507 if (ptcb_desc->empkt_num <= 7) {
508 dwtmp = ptcb_desc->empkt_len[6];
509 } else {
510 dwtmp = ptcb_desc->empkt_len[6];
511 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
512 dwtmp += ptcb_desc->empkt_len[7];
513 }
514 SET_EARLYMODE_LEN3(virtualaddress, dwtmp);
515 if (ptcb_desc->empkt_num <= 9) {
516 dwtmp = ptcb_desc->empkt_len[8];
517 } else {
518 dwtmp = ptcb_desc->empkt_len[8];
519 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
520 dwtmp += ptcb_desc->empkt_len[9];
521 }
522 SET_EARLYMODE_LEN4(virtualaddress, dwtmp);
523}
524
525bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw,
526 struct rtl_stats *status,
527 struct ieee80211_rx_status *rx_status,
528 u8 *pdesc, struct sk_buff *skb)
529{
530 struct rtl_priv *rtlpriv = rtl_priv(hw);
531 struct rx_fwinfo_8723be *p_drvinfo;
532 struct ieee80211_hdr *hdr;
533
534 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
535 status->packet_report_type = (u8)GET_RX_STATUS_DESC_RPT_SEL(pdesc);
536 if (status->packet_report_type == TX_REPORT2)
537 status->length = (u16) GET_RX_RPT2_DESC_PKT_LEN(pdesc);
538 else
539 status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
540 status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
541 RX_DRV_INFO_SIZE_UNIT;
542 status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
543 status->icv = (u16) GET_RX_DESC_ICV(pdesc);
544 status->crc = (u16) GET_RX_DESC_CRC32(pdesc);
545 status->hwerror = (status->crc | status->icv);
546 status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
547 status->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
548 status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
549 status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
550 status->isfirst_ampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
551 if (status->packet_report_type == NORMAL_RX)
552 status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
553 status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
554 status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
555
556 status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate);
557
558 status->macid = GET_RX_DESC_MACID(pdesc);
559 if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
560 status->wake_match = BIT(2);
561 else if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
562 status->wake_match = BIT(1);
563 else if (GET_RX_STATUS_DESC_UNICAST_MATCH(pdesc))
564 status->wake_match = BIT(0);
565 else
566 status->wake_match = 0;
567 if (status->wake_match)
568 RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD,
569 "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n",
570 status->wake_match);
571 rx_status->freq = hw->conf.chandef.chan->center_freq;
572 rx_status->band = hw->conf.chandef.chan->band;
573
574
575 hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size +
576 status->rx_bufshift);
577
578 if (status->crc)
579 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
580
581 if (status->rx_is40Mhzpacket)
582 rx_status->flag |= RX_FLAG_40MHZ;
583
584 if (status->is_ht)
585 rx_status->flag |= RX_FLAG_HT;
586
587 rx_status->flag |= RX_FLAG_MACTIME_START;
588
589 /* hw will set status->decrypted true, if it finds the
590 * frame is open data frame or mgmt frame.
591 * So hw will not decryption robust managment frame
592 * for IEEE80211w but still set status->decrypted
593 * true, so here we should set it back to undecrypted
594 * for IEEE80211w frame, and mac80211 sw will help
595 * to decrypt it
596 */
597 if (status->decrypted) {
598 if (!hdr) {
599 WARN_ON_ONCE(true);
600 pr_err("decrypted is true but hdr NULL in skb %p\n",
601 rtl_get_hdr(skb));
602 return false;
603 }
604
605 if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
606 (ieee80211_has_protected(hdr->frame_control)))
607 rx_status->flag &= ~RX_FLAG_DECRYPTED;
608 else
609 rx_status->flag |= RX_FLAG_DECRYPTED;
610 }
611
612 /* rate_idx: index of data rate into band's
613 * supported rates or MCS index if HT rates
614 * are use (RX_FLAG_HT)
615 * Notice: this is diff with windows define
616 */
617 rx_status->rate_idx = _rtl8723be_rate_mapping(hw, status->is_ht,
618 status->rate);
619
620 rx_status->mactime = status->timestamp_low;
621 if (phystatus) {
622 p_drvinfo = (struct rx_fwinfo_8723be *)(skb->data +
623 status->rx_bufshift);
624
625 _rtl8723be_translate_rx_signal_stuff(hw, skb, status,
626 pdesc, p_drvinfo);
627 }
628
629 /*rx_status->qual = status->signal; */
630 rx_status->signal = status->recvsignalpower + 10;
631 if (status->packet_report_type == TX_REPORT2) {
632 status->macid_valid_entry[0] =
633 GET_RX_RPT2_DESC_MACID_VALID_1(pdesc);
634 status->macid_valid_entry[1] =
635 GET_RX_RPT2_DESC_MACID_VALID_2(pdesc);
636 }
637 return true;
638}
639
640void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
641 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
642 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
643 struct ieee80211_sta *sta, struct sk_buff *skb,
644 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
645{
646 struct rtl_priv *rtlpriv = rtl_priv(hw);
647 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
648 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
649 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
650 u8 *pdesc = (u8 *)pdesc_tx;
651 u16 seq_number;
652 __le16 fc = hdr->frame_control;
653 unsigned int buf_len = 0;
654 unsigned int skb_len = skb->len;
655 u8 fw_qsel = _rtl8723be_map_hwqueue_to_fwqueue(skb, hw_queue);
656 bool firstseg = ((hdr->seq_ctrl &
657 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
658 bool lastseg = ((hdr->frame_control &
659 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
660 dma_addr_t mapping;
661 u8 bw_40 = 0;
662 u8 short_gi = 0;
663
664 if (mac->opmode == NL80211_IFTYPE_STATION) {
665 bw_40 = mac->bw_40;
666 } else if (mac->opmode == NL80211_IFTYPE_AP ||
667 mac->opmode == NL80211_IFTYPE_ADHOC) {
668 if (sta)
669 bw_40 = sta->ht_cap.cap &
670 IEEE80211_HT_CAP_SUP_WIDTH_20_40;
671 }
672 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
673 rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
674 /* reserve 8 byte for AMPDU early mode */
675 if (rtlhal->earlymode_enable) {
676 skb_push(skb, EM_HDR_LEN);
677 memset(skb->data, 0, EM_HDR_LEN);
678 }
679 buf_len = skb->len;
680 mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
681 PCI_DMA_TODEVICE);
682 if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
683 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "DMA mapping error");
684 return;
685 }
686 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723be));
687 if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
688 firstseg = true;
689 lastseg = true;
690 }
691 if (firstseg) {
692 if (rtlhal->earlymode_enable) {
693 SET_TX_DESC_PKT_OFFSET(pdesc, 1);
694 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
695 EM_HDR_LEN);
696 if (ptcb_desc->empkt_num) {
697 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
698 "Insert 8 byte.pTcb->EMPktNum:%d\n",
699 ptcb_desc->empkt_num);
700 _rtl8723be_insert_emcontent(ptcb_desc,
701 (u8 *)(skb->data));
702 }
703 } else {
704 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
705 }
706
707 /* ptcb_desc->use_driver_rate = true; */
708 SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
709 if (ptcb_desc->hw_rate > DESC92C_RATEMCS0)
710 short_gi = (ptcb_desc->use_shortgi) ? 1 : 0;
711 else
712 short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0;
713
714 SET_TX_DESC_DATA_SHORTGI(pdesc, short_gi);
715
716 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
717 SET_TX_DESC_AGG_ENABLE(pdesc, 1);
718 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
719 }
720 SET_TX_DESC_SEQ(pdesc, seq_number);
721 SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
722 !ptcb_desc->cts_enable) ?
723 1 : 0));
724 SET_TX_DESC_HW_RTS_ENABLE(pdesc, 0);
725 SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ?
726 1 : 0));
727
728 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
729
730 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
731 SET_TX_DESC_RTS_SHORT(pdesc,
732 ((ptcb_desc->rts_rate <= DESC92C_RATE54M) ?
733 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
734 (ptcb_desc->rts_use_shortgi ? 1 : 0)));
735
736 if (ptcb_desc->btx_enable_sw_calc_duration)
737 SET_TX_DESC_NAV_USE_HDR(pdesc, 1);
738
739 if (bw_40) {
740 if (ptcb_desc->packet_bw) {
741 SET_TX_DESC_DATA_BW(pdesc, 1);
742 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
743 } else {
744 SET_TX_DESC_DATA_BW(pdesc, 0);
745 SET_TX_DESC_TX_SUB_CARRIER(pdesc, mac->cur_40_prime_sc);
746 }
747 } else {
748 SET_TX_DESC_DATA_BW(pdesc, 0);
749 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
750 }
751
752 SET_TX_DESC_LINIP(pdesc, 0);
753 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
754 if (sta) {
755 u8 ampdu_density = sta->ht_cap.ampdu_density;
756 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
757 }
758 if (info->control.hw_key) {
759 struct ieee80211_key_conf *keyconf =
760 info->control.hw_key;
761 switch (keyconf->cipher) {
762 case WLAN_CIPHER_SUITE_WEP40:
763 case WLAN_CIPHER_SUITE_WEP104:
764 case WLAN_CIPHER_SUITE_TKIP:
765 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
766 break;
767 case WLAN_CIPHER_SUITE_CCMP:
768 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
769 break;
770 default:
771 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
772 break;
773 }
774 }
775
776 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
777 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
778 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
779 SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
780 1 : 0);
781 SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
782
783 if (ieee80211_is_data_qos(fc)) {
784 if (mac->rdg_en) {
785 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
786 "Enable RDG function.\n");
787 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
788 SET_TX_DESC_HTC(pdesc, 1);
789 }
790 }
791 }
792
793 SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
794 SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
795 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
796 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
797 SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
798 SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
799
800 if (!ieee80211_is_data_qos(fc)) {
801 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
802 SET_TX_DESC_HWSEQ_SEL(pdesc, 0);
803 }
804 SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
805 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
806 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
807 SET_TX_DESC_BMC(pdesc, 1);
808 }
809 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
810}
811
812void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
813 bool b_firstseg, bool b_lastseg,
814 struct sk_buff *skb)
815{
816 struct rtl_priv *rtlpriv = rtl_priv(hw);
817 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
818 u8 fw_queue = QSLT_BEACON;
819
820 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
821 skb->data, skb->len,
822 PCI_DMA_TODEVICE);
823
824 if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
825 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
826 "DMA mapping error");
827 return;
828 }
829 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
830
831 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
832
833 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
834
835 SET_TX_DESC_SEQ(pdesc, 0);
836
837 SET_TX_DESC_LINIP(pdesc, 0);
838
839 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
840
841 SET_TX_DESC_FIRST_SEG(pdesc, 1);
842 SET_TX_DESC_LAST_SEG(pdesc, 1);
843
844 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
845
846 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
847
848 SET_TX_DESC_RATE_ID(pdesc, 0);
849 SET_TX_DESC_MACID(pdesc, 0);
850
851 SET_TX_DESC_OWN(pdesc, 1);
852
853 SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
854
855 SET_TX_DESC_FIRST_SEG(pdesc, 1);
856 SET_TX_DESC_LAST_SEG(pdesc, 1);
857
858 SET_TX_DESC_USE_RATE(pdesc, 1);
859}
860
861void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
862 u8 desc_name, u8 *val)
863{
864 if (istx) {
865 switch (desc_name) {
866 case HW_DESC_OWN:
867 SET_TX_DESC_OWN(pdesc, 1);
868 break;
869 case HW_DESC_TX_NEXTDESC_ADDR:
870 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *)val);
871 break;
872 default:
873 RT_ASSERT(false, "ERR txdesc :%d not process\n",
874 desc_name);
875 break;
876 }
877 } else {
878 switch (desc_name) {
879 case HW_DESC_RXOWN:
880 SET_RX_DESC_OWN(pdesc, 1);
881 break;
882 case HW_DESC_RXBUFF_ADDR:
883 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *)val);
884 break;
885 case HW_DESC_RXPKT_LEN:
886 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *)val);
887 break;
888 case HW_DESC_RXERO:
889 SET_RX_DESC_EOR(pdesc, 1);
890 break;
891 default:
892 RT_ASSERT(false, "ERR rxdesc :%d not process\n",
893 desc_name);
894 break;
895 }
896 }
897}
898
899u32 rtl8723be_get_desc(u8 *pdesc, bool istx, u8 desc_name)
900{
901 u32 ret = 0;
902
903 if (istx) {
904 switch (desc_name) {
905 case HW_DESC_OWN:
906 ret = GET_TX_DESC_OWN(pdesc);
907 break;
908 case HW_DESC_TXBUFF_ADDR:
909 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
910 break;
911 default:
912 RT_ASSERT(false, "ERR txdesc :%d not process\n",
913 desc_name);
914 break;
915 }
916 } else {
917 switch (desc_name) {
918 case HW_DESC_OWN:
919 ret = GET_RX_DESC_OWN(pdesc);
920 break;
921 case HW_DESC_RXPKT_LEN:
922 ret = GET_RX_DESC_PKT_LEN(pdesc);
923 break;
924 default:
925 RT_ASSERT(false, "ERR rxdesc :%d not process\n",
926 desc_name);
927 break;
928 }
929 }
930 return ret;
931}
932
933bool rtl8723be_is_tx_desc_closed(struct ieee80211_hw *hw,
934 u8 hw_queue, u16 index)
935{
936 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
937 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
938 u8 *entry = (u8 *)(&ring->desc[ring->idx]);
939 u8 own = (u8) rtl8723be_get_desc(entry, true, HW_DESC_OWN);
940
941 /*beacon packet will only use the first
942 *descriptor by default, and the own may not
943 *be cleared by the hardware
944 */
945 if (own)
946 return false;
947 else
948 return true;
949}
950
951void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
952{
953 struct rtl_priv *rtlpriv = rtl_priv(hw);
954 if (hw_queue == BEACON_QUEUE) {
955 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
956 } else {
957 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
958 BIT(0) << (hw_queue));
959 }
960}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.h b/drivers/net/wireless/rtlwifi/rtl8723be/trx.h
new file mode 100644
index 000000000000..102f33dcc988
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.h
@@ -0,0 +1,617 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_TRX_H__
27#define __RTL8723BE_TRX_H__
28
29#define TX_DESC_SIZE 40
30#define TX_DESC_AGGR_SUBFRAME_SIZE 32
31
32#define RX_DESC_SIZE 32
33#define RX_DRV_INFO_SIZE_UNIT 8
34
35#define TX_DESC_NEXT_DESC_OFFSET 40
36#define USB_HWDESC_HEADER_LEN 40
37#define CRCLENGTH 4
38
39#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
40 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
41#define SET_TX_DESC_OFFSET(__pdesc, __val) \
42 SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
43#define SET_TX_DESC_BMC(__pdesc, __val) \
44 SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
45#define SET_TX_DESC_HTC(__pdesc, __val) \
46 SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
47#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
48 SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
49#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
50 SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
51#define SET_TX_DESC_LINIP(__pdesc, __val) \
52 SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
53#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
54 SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
55#define SET_TX_DESC_GF(__pdesc, __val) \
56 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
57#define SET_TX_DESC_OWN(__pdesc, __val) \
58 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
59
60#define GET_TX_DESC_PKT_SIZE(__pdesc) \
61 LE_BITS_TO_4BYTE(__pdesc, 0, 16)
62#define GET_TX_DESC_OFFSET(__pdesc) \
63 LE_BITS_TO_4BYTE(__pdesc, 16, 8)
64#define GET_TX_DESC_BMC(__pdesc) \
65 LE_BITS_TO_4BYTE(__pdesc, 24, 1)
66#define GET_TX_DESC_HTC(__pdesc) \
67 LE_BITS_TO_4BYTE(__pdesc, 25, 1)
68#define GET_TX_DESC_LAST_SEG(__pdesc) \
69 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
70#define GET_TX_DESC_FIRST_SEG(__pdesc) \
71 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
72#define GET_TX_DESC_LINIP(__pdesc) \
73 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
74#define GET_TX_DESC_NO_ACM(__pdesc) \
75 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
76#define GET_TX_DESC_GF(__pdesc) \
77 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
78#define GET_TX_DESC_OWN(__pdesc) \
79 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
80
81#define SET_TX_DESC_MACID(__pdesc, __val) \
82 SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 7, __val)
83#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
84 SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
85#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
86 SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
87#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
88 SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
89#define SET_TX_DESC_PIFS(__pdesc, __val) \
90 SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
91#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
92 SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 5, __val)
93#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
94 SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
95#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
96 SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
97#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
98 SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 5, __val)
99
100
101#define SET_TX_DESC_PAID(__pdesc, __val) \
102 SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 9, __val)
103#define SET_TX_DESC_CCA_RTS(__pdesc, __val) \
104 SET_BITS_TO_LE_4BYTE(__pdesc+8, 10, 2, __val)
105#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
106 SET_BITS_TO_LE_4BYTE(__pdesc+8, 12, 1, __val)
107#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
108 SET_BITS_TO_LE_4BYTE(__pdesc+8, 13, 1, __val)
109#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
110 SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
111#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
112 SET_BITS_TO_LE_4BYTE(__pdesc+8, 16, 1, __val)
113#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
114 SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
115#define SET_TX_DESC_RAW(__pdesc, __val) \
116 SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
117#define SET_TX_DESC_SPE_RPT(__pdesc, __val) \
118 SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
119#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
120 SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
121#define SET_TX_DESC_BT_INT(__pdesc, __val) \
122 SET_BITS_TO_LE_4BYTE(__pdesc+8, 23, 1, __val)
123#define SET_TX_DESC_GID(__pdesc, __val) \
124 SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 6, __val)
125
126
127#define SET_TX_DESC_WHEADER_LEN(__pdesc, __val) \
128 SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 4, __val)
129#define SET_TX_DESC_CHK_EN(__pdesc, __val) \
130 SET_BITS_TO_LE_4BYTE(__pdesc+12, 4, 1, __val)
131#define SET_TX_DESC_EARLY_MODE(__pdesc, __val) \
132 SET_BITS_TO_LE_4BYTE(__pdesc+12, 5, 1, __val)
133#define SET_TX_DESC_HWSEQ_SEL(__pdesc, __val) \
134 SET_BITS_TO_LE_4BYTE(__pdesc+12, 6, 2, __val)
135#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
136 SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 1, __val)
137#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
138 SET_BITS_TO_LE_4BYTE(__pdesc+12, 9, 1, __val)
139#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
140 SET_BITS_TO_LE_4BYTE(__pdesc+12, 10, 1, __val)
141#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
142 SET_BITS_TO_LE_4BYTE(__pdesc+12, 11, 1, __val)
143#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
144 SET_BITS_TO_LE_4BYTE(__pdesc+12, 12, 1, __val)
145#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
146 SET_BITS_TO_LE_4BYTE(__pdesc+12, 13, 1, __val)
147#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
148 SET_BITS_TO_LE_4BYTE(__pdesc+12, 15, 1, __val)
149#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
150 SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 1, __val)
151#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
152 SET_BITS_TO_LE_4BYTE(__pdesc+12, 17, 5, __val)
153#define SET_TX_DESC_NDPA(__pdesc, __val) \
154 SET_BITS_TO_LE_4BYTE(__pdesc+12, 22, 2, __val)
155#define SET_TX_DESC_AMPDU_MAX_TIME(__pdesc, __val) \
156 SET_BITS_TO_LE_4BYTE(__pdesc+12, 24, 8, __val)
157
158
159#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
160 SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 7, __val)
161#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
162 SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 5, __val)
163#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
164 SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 4, __val)
165#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
166 SET_BITS_TO_LE_4BYTE(__pdesc+16, 17, 1, __val)
167#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
168 SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 6, __val)
169#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
170 SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 5, __val)
171
172
173#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
174 SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 4, __val)
175#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
176 SET_BITS_TO_LE_4BYTE(__pdesc+20, 4, 1, __val)
177#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
178 SET_BITS_TO_LE_4BYTE(__pdesc+20, 5, 2, __val)
179#define SET_TX_DESC_DATA_LDPC(__pdesc, __val) \
180 SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
181#define SET_TX_DESC_DATA_STBC(__pdesc, __val) \
182 SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 2, __val)
183#define SET_TX_DESC_CTROL_STBC(__pdesc, __val) \
184 SET_BITS_TO_LE_4BYTE(__pdesc+20, 10, 2, __val)
185#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
186 SET_BITS_TO_LE_4BYTE(__pdesc+20, 12, 1, __val)
187#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
188 SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
189
190
191#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
192 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
193
194#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
195 LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
196
197#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
198 SET_BITS_TO_LE_4BYTE(__pdesc+32, 15, 1, __val)
199
200#define SET_TX_DESC_SEQ(__pdesc, __val) \
201 SET_BITS_TO_LE_4BYTE(__pdesc+36, 12, 12, __val)
202
203#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
204 SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
205
206#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
207 LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
208
209
210#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
211 SET_BITS_TO_LE_4BYTE(__pdesc+48, 0, 32, __val)
212
213#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
214 LE_BITS_TO_4BYTE(__pdesc+48, 0, 32)
215
216#define GET_RX_DESC_PKT_LEN(__pdesc) \
217 LE_BITS_TO_4BYTE(__pdesc, 0, 14)
218#define GET_RX_DESC_CRC32(__pdesc) \
219 LE_BITS_TO_4BYTE(__pdesc, 14, 1)
220#define GET_RX_DESC_ICV(__pdesc) \
221 LE_BITS_TO_4BYTE(__pdesc, 15, 1)
222#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
223 LE_BITS_TO_4BYTE(__pdesc, 16, 4)
224#define GET_RX_DESC_SECURITY(__pdesc) \
225 LE_BITS_TO_4BYTE(__pdesc, 20, 3)
226#define GET_RX_DESC_QOS(__pdesc) \
227 LE_BITS_TO_4BYTE(__pdesc, 23, 1)
228#define GET_RX_DESC_SHIFT(__pdesc) \
229 LE_BITS_TO_4BYTE(__pdesc, 24, 2)
230#define GET_RX_DESC_PHYST(__pdesc) \
231 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
232#define GET_RX_DESC_SWDEC(__pdesc) \
233 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
234#define GET_RX_DESC_LS(__pdesc) \
235 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
236#define GET_RX_DESC_FS(__pdesc) \
237 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
238#define GET_RX_DESC_EOR(__pdesc) \
239 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
240#define GET_RX_DESC_OWN(__pdesc) \
241 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
242
243#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
244 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
245#define SET_RX_DESC_EOR(__pdesc, __val) \
246 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
247#define SET_RX_DESC_OWN(__pdesc, __val) \
248 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
249
250#define GET_RX_DESC_MACID(__pdesc) \
251 LE_BITS_TO_4BYTE(__pdesc+4, 0, 7)
252#define GET_RX_DESC_TID(__pdesc) \
253 LE_BITS_TO_4BYTE(__pdesc+4, 8, 4)
254#define GET_RX_DESC_AMSDU(__pdesc) \
255 LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
256#define GET_RX_STATUS_DESC_RXID_MATCH(__pdesc) \
257 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
258#define GET_RX_DESC_PAGGR(__pdesc) \
259 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
260#define GET_RX_DESC_A1_FIT(__pdesc) \
261 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
262#define GET_RX_DESC_CHKERR(__pdesc) \
263 LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
264#define GET_RX_DESC_IPVER(__pdesc) \
265 LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
266#define GET_RX_STATUS_DESC_IS_TCPUDP(__pdesc) \
267 LE_BITS_TO_4BYTE(__pdesc+4, 22, 1)
268#define GET_RX_STATUS_DESC_CHK_VLD(__pdesc) \
269 LE_BITS_TO_4BYTE(__pdesc+4, 23, 1)
270#define GET_RX_DESC_PAM(__pdesc) \
271 LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
272#define GET_RX_DESC_PWR(__pdesc) \
273 LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
274#define GET_RX_DESC_MD(__pdesc) \
275 LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
276#define GET_RX_DESC_MF(__pdesc) \
277 LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
278#define GET_RX_DESC_TYPE(__pdesc) \
279 LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
280#define GET_RX_DESC_MC(__pdesc) \
281 LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
282#define GET_RX_DESC_BC(__pdesc) \
283 LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
284
285
286#define GET_RX_DESC_SEQ(__pdesc) \
287 LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
288#define GET_RX_DESC_FRAG(__pdesc) \
289 LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
290#define GET_RX_STATUS_DESC_RX_IS_QOS(__pdesc) \
291 LE_BITS_TO_4BYTE(__pdesc+8, 16, 1)
292#define GET_RX_STATUS_DESC_WLANHD_IV_LEN(__pdesc) \
293 LE_BITS_TO_4BYTE(__pdesc+8, 18, 6)
294#define GET_RX_STATUS_DESC_RPT_SEL(__pdesc) \
295 LE_BITS_TO_4BYTE(__pdesc+8, 28, 1)
296
297
298#define GET_RX_DESC_RXMCS(__pdesc) \
299 LE_BITS_TO_4BYTE(__pdesc+12, 0, 7)
300#define GET_RX_DESC_RXHT(__pdesc) \
301 LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
302#define GET_RX_STATUS_DESC_RX_GF(__pdesc) \
303 LE_BITS_TO_4BYTE(__pdesc+12, 7, 1)
304#define GET_RX_DESC_HTC(__pdesc) \
305 LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
306#define GET_RX_STATUS_DESC_EOSP(__pdesc) \
307 LE_BITS_TO_4BYTE(__pdesc+12, 11, 1)
308#define GET_RX_STATUS_DESC_BSSID_FIT(__pdesc) \
309 LE_BITS_TO_4BYTE(__pdesc+12, 12, 2)
310
311#define GET_RX_STATUS_DESC_PATTERN_MATCH(__pdesc) \
312 LE_BITS_TO_4BYTE(__pdesc+12, 29, 1)
313#define GET_RX_STATUS_DESC_UNICAST_MATCH(__pdesc) \
314 LE_BITS_TO_4BYTE(__pdesc+12, 30, 1)
315#define GET_RX_STATUS_DESC_MAGIC_MATCH(__pdesc) \
316 LE_BITS_TO_4BYTE(__pdesc+12, 31, 1)
317
318#define GET_RX_DESC_SPLCP(__pdesc) \
319 LE_BITS_TO_4BYTE(__pdesc+16, 0, 1)
320#define GET_RX_STATUS_DESC_LDPC(__pdesc) \
321 LE_BITS_TO_4BYTE(__pdesc+16, 1, 1)
322#define GET_RX_STATUS_DESC_STBC(__pdesc) \
323 LE_BITS_TO_4BYTE(__pdesc+16, 2, 1)
324#define GET_RX_DESC_BW(__pdesc) \
325 LE_BITS_TO_4BYTE(__pdesc+16, 4, 2)
326
327#define GET_RX_DESC_TSFL(__pdesc) \
328 LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
329
330#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
331 LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
332#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
333 LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
334
335#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
336 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
337#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
338 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
339
340
341/* TX report 2 format in Rx desc*/
342
343#define GET_RX_RPT2_DESC_PKT_LEN(__rxstatusdesc) \
344 LE_BITS_TO_4BYTE(__rxstatusdesc, 0, 9)
345#define GET_RX_RPT2_DESC_MACID_VALID_1(__rxstatusdesc) \
346 LE_BITS_TO_4BYTE(__rxstatusdesc+16, 0, 32)
347#define GET_RX_RPT2_DESC_MACID_VALID_2(__rxstatusdesc) \
348 LE_BITS_TO_4BYTE(__rxstatusdesc+20, 0, 32)
349
350#define SET_EARLYMODE_PKTNUM(__paddr, __value) \
351 SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __value)
352#define SET_EARLYMODE_LEN0(__paddr, __value) \
353 SET_BITS_TO_LE_4BYTE(__paddr, 4, 12, __value)
354#define SET_EARLYMODE_LEN1(__paddr, __value) \
355 SET_BITS_TO_LE_4BYTE(__paddr, 16, 12, __value)
356#define SET_EARLYMODE_LEN2_1(__paddr, __value) \
357 SET_BITS_TO_LE_4BYTE(__paddr, 28, 4, __value)
358#define SET_EARLYMODE_LEN2_2(__paddr, __value) \
359 SET_BITS_TO_LE_4BYTE(__paddr+4, 0, 8, __value)
360#define SET_EARLYMODE_LEN3(__paddr, __value) \
361 SET_BITS_TO_LE_4BYTE(__paddr+4, 8, 12, __value)
362#define SET_EARLYMODE_LEN4(__paddr, __value) \
363 SET_BITS_TO_LE_4BYTE(__paddr+4, 20, 12, __value)
364
365#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
366do { \
367 if (_size > TX_DESC_NEXT_DESC_OFFSET) \
368 memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
369 else \
370 memset(__pdesc, 0, _size); \
371} while (0)
372
373struct phy_rx_agc_info_t {
374 #ifdef __LITTLE_ENDIAN
375 u8 gain:7, trsw:1;
376 #else
377 u8 trsw:1, gain:7;
378 #endif
379};
380struct phy_status_rpt {
381 struct phy_rx_agc_info_t path_agc[2];
382 u8 ch_corr[2];
383 u8 cck_sig_qual_ofdm_pwdb_all;
384 u8 cck_agc_rpt_ofdm_cfosho_a;
385 u8 cck_rpt_b_ofdm_cfosho_b;
386 u8 rsvd_1;/* ch_corr_msb; */
387 u8 noise_power_db_msb;
388 char path_cfotail[2];
389 u8 pcts_mask[2];
390 char stream_rxevm[2];
391 u8 path_rxsnr[2];
392 u8 noise_power_db_lsb;
393 u8 rsvd_2[3];
394 u8 stream_csi[2];
395 u8 stream_target_csi[2];
396 u8 sig_evm;
397 u8 rsvd_3;
398#ifdef __LITTLE_ENDIAN
399 u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
400 u8 sgi_en:1;
401 u8 rxsc:2;
402 u8 idle_long:1;
403 u8 r_ant_train_en:1;
404 u8 ant_sel_b:1;
405 u8 ant_sel:1;
406#else /* _BIG_ENDIAN_ */
407 u8 ant_sel:1;
408 u8 ant_sel_b:1;
409 u8 r_ant_train_en:1;
410 u8 idle_long:1;
411 u8 rxsc:2;
412 u8 sgi_en:1;
413 u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
414#endif
415} __packed;
416
417struct rx_fwinfo_8723be {
418 u8 gain_trsw[4];
419 u8 pwdb_all;
420 u8 cfosho[4];
421 u8 cfotail[4];
422 char rxevm[2];
423 char rxsnr[4];
424 u8 pdsnr[2];
425 u8 csi_current[2];
426 u8 csi_target[2];
427 u8 sigevm;
428 u8 max_ex_pwr;
429 u8 ex_intf_flag:1;
430 u8 sgi_en:1;
431 u8 rxsc:2;
432 u8 reserve:4;
433} __packed;
434
435struct tx_desc_8723be {
436 u32 pktsize:16;
437 u32 offset:8;
438 u32 bmc:1;
439 u32 htc:1;
440 u32 lastseg:1;
441 u32 firstseg:1;
442 u32 linip:1;
443 u32 noacm:1;
444 u32 gf:1;
445 u32 own:1;
446
447 u32 macid:6;
448 u32 rsvd0:2;
449 u32 queuesel:5;
450 u32 rd_nav_ext:1;
451 u32 lsig_txop_en:1;
452 u32 pifs:1;
453 u32 rateid:4;
454 u32 nav_usehdr:1;
455 u32 en_descid:1;
456 u32 sectype:2;
457 u32 pktoffset:8;
458
459 u32 rts_rc:6;
460 u32 data_rc:6;
461 u32 agg_en:1;
462 u32 rdg_en:1;
463 u32 bar_retryht:2;
464 u32 agg_break:1;
465 u32 morefrag:1;
466 u32 raw:1;
467 u32 ccx:1;
468 u32 ampdudensity:3;
469 u32 bt_int:1;
470 u32 ant_sela:1;
471 u32 ant_selb:1;
472 u32 txant_cck:2;
473 u32 txant_l:2;
474 u32 txant_ht:2;
475
476 u32 nextheadpage:8;
477 u32 tailpage:8;
478 u32 seq:12;
479 u32 cpu_handle:1;
480 u32 tag1:1;
481 u32 trigger_int:1;
482 u32 hwseq_en:1;
483
484 u32 rtsrate:5;
485 u32 apdcfe:1;
486 u32 qos:1;
487 u32 hwseq_ssn:1;
488 u32 userrate:1;
489 u32 dis_rtsfb:1;
490 u32 dis_datafb:1;
491 u32 cts2self:1;
492 u32 rts_en:1;
493 u32 hwrts_en:1;
494 u32 portid:1;
495 u32 pwr_status:3;
496 u32 waitdcts:1;
497 u32 cts2ap_en:1;
498 u32 txsc:2;
499 u32 stbc:2;
500 u32 txshort:1;
501 u32 txbw:1;
502 u32 rtsshort:1;
503 u32 rtsbw:1;
504 u32 rtssc:2;
505 u32 rtsstbc:2;
506
507 u32 txrate:6;
508 u32 shortgi:1;
509 u32 ccxt:1;
510 u32 txrate_fb_lmt:5;
511 u32 rtsrate_fb_lmt:4;
512 u32 retrylmt_en:1;
513 u32 txretrylmt:6;
514 u32 usb_txaggnum:8;
515
516 u32 txagca:5;
517 u32 txagcb:5;
518 u32 usemaxlen:1;
519 u32 maxaggnum:5;
520 u32 mcsg1maxlen:4;
521 u32 mcsg2maxlen:4;
522 u32 mcsg3maxlen:4;
523 u32 mcs7sgimaxlen:4;
524
525 u32 txbuffersize:16;
526 u32 sw_offset30:8;
527 u32 sw_offset31:4;
528 u32 rsvd1:1;
529 u32 antsel_c:1;
530 u32 null_0:1;
531 u32 null_1:1;
532
533 u32 txbuffaddr;
534 u32 txbufferaddr64;
535 u32 nextdescaddress;
536 u32 nextdescaddress64;
537
538 u32 reserve_pass_pcie_mm_limit[4];
539} __packed;
540
541struct rx_desc_8723be {
542 u32 length:14;
543 u32 crc32:1;
544 u32 icverror:1;
545 u32 drv_infosize:4;
546 u32 security:3;
547 u32 qos:1;
548 u32 shift:2;
549 u32 phystatus:1;
550 u32 swdec:1;
551 u32 lastseg:1;
552 u32 firstseg:1;
553 u32 eor:1;
554 u32 own:1;
555
556 u32 macid:6;
557 u32 tid:4;
558 u32 hwrsvd:5;
559 u32 paggr:1;
560 u32 faggr:1;
561 u32 a1_fit:4;
562 u32 a2_fit:4;
563 u32 pam:1;
564 u32 pwr:1;
565 u32 moredata:1;
566 u32 morefrag:1;
567 u32 type:2;
568 u32 mc:1;
569 u32 bc:1;
570
571 u32 seq:12;
572 u32 frag:4;
573 u32 nextpktlen:14;
574 u32 nextind:1;
575 u32 rsvd:1;
576
577 u32 rxmcs:6;
578 u32 rxht:1;
579 u32 amsdu:1;
580 u32 splcp:1;
581 u32 bandwidth:1;
582 u32 htc:1;
583 u32 tcpchk_rpt:1;
584 u32 ipcchk_rpt:1;
585 u32 tcpchk_valid:1;
586 u32 hwpcerr:1;
587 u32 hwpcind:1;
588 u32 iv0:16;
589
590 u32 iv1;
591
592 u32 tsfl;
593
594 u32 bufferaddress;
595 u32 bufferaddress64;
596
597} __packed;
598
599void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
600 struct ieee80211_hdr *hdr, u8 *pdesc,
601 u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
602 struct ieee80211_sta *sta, struct sk_buff *skb,
603 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
604bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw,
605 struct rtl_stats *status,
606 struct ieee80211_rx_status *rx_status,
607 u8 *pdesc, struct sk_buff *skb);
608void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
609 u8 desc_name, u8 *val);
610u32 rtl8723be_get_desc(u8 *pdesc, bool istx, u8 desc_name);
611bool rtl8723be_is_tx_desc_closed(struct ieee80211_hw *hw,
612 u8 hw_queue, u16 index);
613void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
614void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
615 bool b_firstseg, bool b_lastseg,
616 struct sk_buff *skb);
617#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/Makefile b/drivers/net/wireless/rtlwifi/rtl8723com/Makefile
new file mode 100644
index 000000000000..345a68adcf38
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/Makefile
@@ -0,0 +1,9 @@
1rtl8723-common-objs := \
2 main.o \
3 dm_common.o \
4 fw_common.o \
5 phy_common.o
6
7obj-$(CONFIG_RTL8723_COMMON) += rtl8723-common.o
8
9ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c
new file mode 100644
index 000000000000..4e254b72bf45
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c
@@ -0,0 +1,65 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "dm_common.h"
28#include "../rtl8723ae/dm.h"
29#include <linux/module.h>
30
31/* These routines are common to RTL8723AE and RTL8723bE */
32
33void rtl8723_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
34{
35 struct rtl_priv *rtlpriv = rtl_priv(hw);
36
37 rtlpriv->dm.dynamic_txpower_enable = false;
38
39 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
40 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
41}
42EXPORT_SYMBOL_GPL(rtl8723_dm_init_dynamic_txpower);
43
44void rtl8723_dm_init_edca_turbo(struct ieee80211_hw *hw)
45{
46 struct rtl_priv *rtlpriv = rtl_priv(hw);
47
48 rtlpriv->dm.current_turbo_edca = false;
49 rtlpriv->dm.is_any_nonbepkts = false;
50 rtlpriv->dm.is_cur_rdlstate = false;
51}
52EXPORT_SYMBOL_GPL(rtl8723_dm_init_edca_turbo);
53
54void rtl8723_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
55{
56 struct rtl_priv *rtlpriv = rtl_priv(hw);
57
58 rtlpriv->dm_pstable.pre_ccastate = CCA_MAX;
59 rtlpriv->dm_pstable.cur_ccasate = CCA_MAX;
60 rtlpriv->dm_pstable.pre_rfstate = RF_MAX;
61 rtlpriv->dm_pstable.cur_rfstate = RF_MAX;
62 rtlpriv->dm_pstable.rssi_val_min = 0;
63 rtlpriv->dm_pstable.initialize = 0;
64}
65EXPORT_SYMBOL_GPL(rtl8723_dm_init_dynamic_bb_powersaving);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h
new file mode 100644
index 000000000000..5c1b94ce2f86
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h
@@ -0,0 +1,33 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __DM_COMMON_H__
27#define __DM_COMMON_H__
28
29void rtl8723_dm_init_dynamic_txpower(struct ieee80211_hw *hw);
30void rtl8723_dm_init_edca_turbo(struct ieee80211_hw *hw);
31void rtl8723_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw);
32
33#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c
new file mode 100644
index 000000000000..c12da552b7f7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c
@@ -0,0 +1,329 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
29#include "fw_common.h"
30#include <linux/module.h>
31
32void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable)
33{
34 struct rtl_priv *rtlpriv = rtl_priv(hw);
35 u8 tmp;
36
37 if (enable) {
38 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
39 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
40
41 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
42 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
43
44 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
45 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
46 } else {
47 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
48 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
49
50 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
51 }
52}
53EXPORT_SYMBOL_GPL(rtl8723_enable_fw_download);
54
55void rtl8723_fw_block_write(struct ieee80211_hw *hw,
56 const u8 *buffer, u32 size)
57{
58 struct rtl_priv *rtlpriv = rtl_priv(hw);
59 u32 blocksize = sizeof(u32);
60 u8 *bufferptr = (u8 *)buffer;
61 u32 *pu4byteptr = (u32 *)buffer;
62 u32 i, offset, blockcount, remainsize;
63
64 blockcount = size / blocksize;
65 remainsize = size % blocksize;
66
67 for (i = 0; i < blockcount; i++) {
68 offset = i * blocksize;
69 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
70 *(pu4byteptr + i));
71 }
72 if (remainsize) {
73 offset = blockcount * blocksize;
74 bufferptr += offset;
75 for (i = 0; i < remainsize; i++) {
76 rtl_write_byte(rtlpriv,
77 (FW_8192C_START_ADDRESS + offset + i),
78 *(bufferptr + i));
79 }
80 }
81}
82EXPORT_SYMBOL_GPL(rtl8723_fw_block_write);
83
84void rtl8723_fw_page_write(struct ieee80211_hw *hw,
85 u32 page, const u8 *buffer, u32 size)
86{
87 struct rtl_priv *rtlpriv = rtl_priv(hw);
88 u8 value8;
89 u8 u8page = (u8) (page & 0x07);
90
91 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
92
93 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
94 rtl8723_fw_block_write(hw, buffer, size);
95}
96EXPORT_SYMBOL_GPL(rtl8723_fw_page_write);
97
98static void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
99{
100 u32 fwlen = *pfwlen;
101 u8 remain = (u8) (fwlen % 4);
102
103 remain = (remain == 0) ? 0 : (4 - remain);
104
105 while (remain > 0) {
106 pfwbuf[fwlen] = 0;
107 fwlen++;
108 remain--;
109 }
110 *pfwlen = fwlen;
111}
112
113void rtl8723_write_fw(struct ieee80211_hw *hw,
114 enum version_8723e version,
115 u8 *buffer, u32 size)
116{
117 struct rtl_priv *rtlpriv = rtl_priv(hw);
118 u8 *bufferptr = (u8 *)buffer;
119 u32 pagenums, remainsize;
120 u32 page, offset;
121
122 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
123
124 rtl8723_fill_dummy(bufferptr, &size);
125
126 pagenums = size / FW_8192C_PAGE_SIZE;
127 remainsize = size % FW_8192C_PAGE_SIZE;
128
129 if (pagenums > 8) {
130 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
131 "Page numbers should not greater then 8\n");
132 }
133 for (page = 0; page < pagenums; page++) {
134 offset = page * FW_8192C_PAGE_SIZE;
135 rtl8723_fw_page_write(hw, page, (bufferptr + offset),
136 FW_8192C_PAGE_SIZE);
137 }
138 if (remainsize) {
139 offset = pagenums * FW_8192C_PAGE_SIZE;
140 page = pagenums;
141 rtl8723_fw_page_write(hw, page, (bufferptr + offset),
142 remainsize);
143 }
144}
145EXPORT_SYMBOL_GPL(rtl8723_write_fw);
146
147void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw)
148{
149 u8 u1tmp;
150 u8 delay = 100;
151 struct rtl_priv *rtlpriv = rtl_priv(hw);
152
153 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
154 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
155
156 while (u1tmp & BIT(2)) {
157 delay--;
158 if (delay == 0)
159 break;
160 udelay(50);
161 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
162 }
163 if (delay == 0) {
164 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
165 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2)));
166 }
167}
168EXPORT_SYMBOL_GPL(rtl8723ae_firmware_selfreset);
169
170void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw)
171{
172 u8 u1b_tmp;
173 struct rtl_priv *rtlpriv = rtl_priv(hw);
174
175 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
176 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
177
178 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
179 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
180 udelay(50);
181
182 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
183 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0)));
184
185 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
186 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2)));
187
188 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
189 " _8051Reset8723be(): 8051 reset success .\n");
190}
191EXPORT_SYMBOL_GPL(rtl8723be_firmware_selfreset);
192
193int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be)
194{
195 struct rtl_priv *rtlpriv = rtl_priv(hw);
196 int err = -EIO;
197 u32 counter = 0;
198 u32 value32;
199
200 do {
201 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
202 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
203 (!(value32 & FWDL_CHKSUM_RPT)));
204
205 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
206 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
207 "chksum report fail ! REG_MCUFWDL:0x%08x .\n",
208 value32);
209 goto exit;
210 }
211 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
212 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
213
214 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL) | MCUFWDL_RDY;
215 value32 &= ~WINTINI_RDY;
216 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
217
218 if (is_8723be)
219 rtl8723be_firmware_selfreset(hw);
220 counter = 0;
221
222 do {
223 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
224 if (value32 & WINTINI_RDY) {
225 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
226 "Polling FW ready success!! "
227 "REG_MCUFWDL:0x%08x .\n",
228 value32);
229 err = 0;
230 goto exit;
231 }
232 udelay(FW_8192C_POLLING_DELAY);
233
234 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
235
236 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
237 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n",
238 value32);
239
240exit:
241 return err;
242}
243EXPORT_SYMBOL_GPL(rtl8723_fw_free_to_go);
244
245int rtl8723_download_fw(struct ieee80211_hw *hw,
246 bool is_8723be)
247{
248 struct rtl_priv *rtlpriv = rtl_priv(hw);
249 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
250 struct rtl92c_firmware_header *pfwheader;
251 u8 *pfwdata;
252 u32 fwsize;
253 int err;
254 enum version_8723e version = rtlhal->version;
255
256 if (!rtlhal->pfirmware)
257 return 1;
258
259 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
260 pfwdata = (u8 *)rtlhal->pfirmware;
261 fwsize = rtlhal->fwsize;
262 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
263 "normal Firmware SIZE %d\n", fwsize);
264
265 if (rtlpriv->cfg->ops->is_fw_header(pfwheader)) {
266 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
267 "Firmware Version(%d), Signature(%#x), Size(%d)\n",
268 pfwheader->version, pfwheader->signature,
269 (int)sizeof(struct rtl92c_firmware_header));
270
271 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
272 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
273 }
274 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
275 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
276 if (is_8723be)
277 rtl8723be_firmware_selfreset(hw);
278 else
279 rtl8723ae_firmware_selfreset(hw);
280 }
281 rtl8723_enable_fw_download(hw, true);
282 rtl8723_write_fw(hw, version, pfwdata, fwsize);
283 rtl8723_enable_fw_download(hw, false);
284
285 err = rtl8723_fw_free_to_go(hw, is_8723be);
286 if (err) {
287 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
288 "Firmware is not ready to run!\n");
289 } else {
290 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
291 "Firmware is ready to run!\n");
292 }
293 return 0;
294}
295EXPORT_SYMBOL_GPL(rtl8723_download_fw);
296
297bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw,
298 struct sk_buff *skb)
299{
300 struct rtl_priv *rtlpriv = rtl_priv(hw);
301 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
302 struct rtl8192_tx_ring *ring;
303 struct rtl_tx_desc *pdesc;
304 struct sk_buff *pskb = NULL;
305 u8 own;
306 unsigned long flags;
307
308 ring = &rtlpci->tx_ring[BEACON_QUEUE];
309
310 pskb = __skb_dequeue(&ring->queue);
311 if (pskb)
312 kfree_skb(pskb);
313
314 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
315
316 pdesc = &ring->desc[0];
317 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
318
319 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
320
321 __skb_queue_tail(&ring->queue, skb);
322
323 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
324
325 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
326
327 return true;
328}
329EXPORT_SYMBOL_GPL(rtl8723_cmd_send_packet);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h
new file mode 100644
index 000000000000..cf1cc5804d06
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h
@@ -0,0 +1,126 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __FW_COMMON_H__
27#define __FW_COMMON_H__
28
29#define REG_SYS_FUNC_EN 0x0002
30#define REG_MCUFWDL 0x0080
31#define FW_8192C_START_ADDRESS 0x1000
32#define FW_8192C_PAGE_SIZE 4096
33#define FW_8192C_POLLING_TIMEOUT_COUNT 6000
34#define FW_8192C_POLLING_DELAY 5
35
36#define MCUFWDL_RDY BIT(1)
37#define FWDL_CHKSUM_RPT BIT(2)
38#define WINTINI_RDY BIT(6)
39
40#define REG_RSV_CTRL 0x001C
41#define REG_HMETFR 0x01CC
42
43enum version_8723e {
44 VERSION_TEST_UMC_CHIP_8723 = 0x0081,
45 VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089,
46 VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089,
47 VERSION_TEST_CHIP_1T1R_8723B = 0x0106,
48 VERSION_NORMAL_SMIC_CHIP_1T1R_8723B = 0x010E,
49 VERSION_UNKNOWN = 0xFF,
50};
51
52enum rtl8723ae_h2c_cmd {
53 H2C_AP_OFFLOAD = 0,
54 H2C_SETPWRMODE = 1,
55 H2C_JOINBSSRPT = 2,
56 H2C_RSVDPAGE = 3,
57 H2C_RSSI_REPORT = 4,
58 H2C_P2P_PS_CTW_CMD = 5,
59 H2C_P2P_PS_OFFLOAD = 6,
60 H2C_RA_MASK = 7,
61 MAX_H2CCMD
62};
63
64enum rtl8723be_cmd {
65 H2C_8723BE_RSVDPAGE = 0,
66 H2C_8723BE_JOINBSSRPT = 1,
67 H2C_8723BE_SCAN = 2,
68 H2C_8723BE_KEEP_ALIVE_CTRL = 3,
69 H2C_8723BE_DISCONNECT_DECISION = 4,
70 H2C_8723BE_INIT_OFFLOAD = 6,
71 H2C_8723BE_AP_OFFLOAD = 8,
72 H2C_8723BE_BCN_RSVDPAGE = 9,
73 H2C_8723BE_PROBERSP_RSVDPAGE = 10,
74
75 H2C_8723BE_SETPWRMODE = 0x20,
76 H2C_8723BE_PS_TUNING_PARA = 0x21,
77 H2C_8723BE_PS_TUNING_PARA2 = 0x22,
78 H2C_8723BE_PS_LPS_PARA = 0x23,
79 H2C_8723BE_P2P_PS_OFFLOAD = 0x24,
80
81 H2C_8723BE_WO_WLAN = 0x80,
82 H2C_8723BE_REMOTE_WAKE_CTRL = 0x81,
83 H2C_8723BE_AOAC_GLOBAL_INFO = 0x82,
84 H2C_8723BE_AOAC_RSVDPAGE = 0x83,
85 H2C_8723BE_RSSI_REPORT = 0x42,
86 H2C_8723BE_RA_MASK = 0x40,
87 H2C_8723BE_SELECTIVE_SUSPEND_ROF_CMD,
88 H2C_8723BE_P2P_PS_MODE,
89 H2C_8723BE_PSD_RESULT,
90 /*Not defined CTW CMD for P2P yet*/
91 H2C_8723BE_P2P_PS_CTW_CMD,
92 MAX_8723BE_H2CCMD
93};
94
95struct rtl92c_firmware_header {
96 u16 signature;
97 u8 category;
98 u8 function;
99 u16 version;
100 u8 subversion;
101 u8 rsvd1;
102 u8 month;
103 u8 date;
104 u8 hour;
105 u8 minute;
106 u16 ramcodesize;
107 u16 rsvd2;
108 u32 svnindex;
109 u32 rsvd3;
110 u32 rsvd4;
111 u32 rsvd5;
112};
113
114void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
115void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw);
116void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable);
117void rtl8723_fw_block_write(struct ieee80211_hw *hw,
118 const u8 *buffer, u32 size);
119void rtl8723_fw_page_write(struct ieee80211_hw *hw,
120 u32 page, const u8 *buffer, u32 size);
121void rtl8723_write_fw(struct ieee80211_hw *hw,
122 enum version_8723e version,
123 u8 *buffer, u32 size);
124int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be);
125int rtl8723_download_fw(struct ieee80211_hw *hw, bool is_8723be);
126#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/main.c b/drivers/net/wireless/rtlwifi/rtl8723com/main.c
new file mode 100644
index 000000000000..9014a94fac6a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/main.c
@@ -0,0 +1,33 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include <linux/module.h>
28
29
30MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
31MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
32MODULE_LICENSE("GPL");
33MODULE_DESCRIPTION("Realtek RTL8723AE/RTL8723BE 802.11n PCI wireless common routines");
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c
new file mode 100644
index 000000000000..d73b659bd2b5
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c
@@ -0,0 +1,434 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "phy_common.h"
28#include "../rtl8723ae/reg.h"
29#include <linux/module.h>
30
31/* These routines are common to RTL8723AE and RTL8723bE */
32
33u32 rtl8723_phy_query_bb_reg(struct ieee80211_hw *hw,
34 u32 regaddr, u32 bitmask)
35{
36 struct rtl_priv *rtlpriv = rtl_priv(hw);
37 u32 returnvalue, originalvalue, bitshift;
38
39 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
40 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
41 originalvalue = rtl_read_dword(rtlpriv, regaddr);
42 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
43 returnvalue = (originalvalue & bitmask) >> bitshift;
44
45 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
46 "BBR MASK = 0x%x Addr[0x%x]= 0x%x\n",
47 bitmask, regaddr, originalvalue);
48
49 return returnvalue;
50}
51EXPORT_SYMBOL_GPL(rtl8723_phy_query_bb_reg);
52
53void rtl8723_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
54 u32 bitmask, u32 data)
55{
56 struct rtl_priv *rtlpriv = rtl_priv(hw);
57 u32 originalvalue, bitshift;
58
59 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
60 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
61 regaddr, bitmask, data);
62
63 if (bitmask != MASKDWORD) {
64 originalvalue = rtl_read_dword(rtlpriv, regaddr);
65 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
66 data = ((originalvalue & (~bitmask)) | (data << bitshift));
67 }
68
69 rtl_write_dword(rtlpriv, regaddr, data);
70
71 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
72 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
73 regaddr, bitmask, data);
74}
75EXPORT_SYMBOL_GPL(rtl8723_phy_set_bb_reg);
76
77u32 rtl8723_phy_calculate_bit_shift(u32 bitmask)
78{
79 u32 i;
80
81 for (i = 0; i <= 31; i++) {
82 if (((bitmask >> i) & 0x1) == 1)
83 break;
84 }
85 return i;
86}
87EXPORT_SYMBOL_GPL(rtl8723_phy_calculate_bit_shift);
88
89u32 rtl8723_phy_rf_serial_read(struct ieee80211_hw *hw,
90 enum radio_path rfpath, u32 offset)
91{
92 struct rtl_priv *rtlpriv = rtl_priv(hw);
93 struct rtl_phy *rtlphy = &(rtlpriv->phy);
94 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
95 u32 newoffset;
96 u32 tmplong, tmplong2;
97 u8 rfpi_enable = 0;
98 u32 retvalue;
99
100 offset &= 0xff;
101 newoffset = offset;
102 if (RT_CANNOT_IO(hw)) {
103 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
104 return 0xFFFFFFFF;
105 }
106 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
107 if (rfpath == RF90_PATH_A)
108 tmplong2 = tmplong;
109 else
110 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
111 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
112 (newoffset << 23) | BLSSIREADEDGE;
113 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
114 tmplong & (~BLSSIREADEDGE));
115 mdelay(1);
116 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
117 mdelay(2);
118 if (rfpath == RF90_PATH_A)
119 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
120 BIT(8));
121 else if (rfpath == RF90_PATH_B)
122 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
123 BIT(8));
124 if (rfpi_enable)
125 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
126 BLSSIREADBACKDATA);
127 else
128 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
129 BLSSIREADBACKDATA);
130 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
131 "RFR-%d Addr[0x%x]= 0x%x\n",
132 rfpath, pphyreg->rf_rb, retvalue);
133 return retvalue;
134}
135EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_read);
136
137void rtl8723_phy_rf_serial_write(struct ieee80211_hw *hw,
138 enum radio_path rfpath,
139 u32 offset, u32 data)
140{
141 u32 data_and_addr;
142 u32 newoffset;
143 struct rtl_priv *rtlpriv = rtl_priv(hw);
144 struct rtl_phy *rtlphy = &(rtlpriv->phy);
145 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
146
147 if (RT_CANNOT_IO(hw)) {
148 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
149 return;
150 }
151 offset &= 0xff;
152 newoffset = offset;
153 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
154 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
155 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
156 "RFW-%d Addr[0x%x]= 0x%x\n", rfpath,
157 pphyreg->rf3wire_offset, data_and_addr);
158}
159EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_write);
160
161long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
162 enum wireless_mode wirelessmode,
163 u8 txpwridx)
164{
165 long offset;
166 long pwrout_dbm;
167
168 switch (wirelessmode) {
169 case WIRELESS_MODE_B:
170 offset = -7;
171 break;
172 case WIRELESS_MODE_G:
173 case WIRELESS_MODE_N_24G:
174 default:
175 offset = -8;
176 break;
177 }
178 pwrout_dbm = txpwridx / 2 + offset;
179 return pwrout_dbm;
180}
181EXPORT_SYMBOL_GPL(rtl8723_phy_txpwr_idx_to_dbm);
182
183void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw *hw)
184{
185 struct rtl_priv *rtlpriv = rtl_priv(hw);
186 struct rtl_phy *rtlphy = &(rtlpriv->phy);
187
188 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
189 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
190 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
191 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
192
193 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
194 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
195 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
196 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
197
198 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
199 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
200
201 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
202 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
203
204 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
205 RFPGA0_XA_LSSIPARAMETER;
206 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
207 RFPGA0_XB_LSSIPARAMETER;
208
209 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
210 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
211 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
212 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
213
214 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
215 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
216 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
217 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
218
219 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
220 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
221
222 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
223 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
224
225 rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
226 rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
227 rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
228 rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
229
230 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
231 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
232 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
233 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
234
235 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
236 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
237 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
238 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
239
240 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
241 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
242 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
243 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
244
245 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
246 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
247 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
248 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
249
250 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
251 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
252 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
253 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
254
255 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
256 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
257 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
258 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
259
260 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
261 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
262 rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
263 rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
264
265 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
266 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
267}
268EXPORT_SYMBOL_GPL(rtl8723_phy_init_bb_rf_reg_def);
269
270bool rtl8723_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
271 u32 cmdtableidx,
272 u32 cmdtablesz,
273 enum swchnlcmd_id cmdid,
274 u32 para1, u32 para2,
275 u32 msdelay)
276{
277 struct swchnlcmd *pcmd;
278
279 if (cmdtable == NULL) {
280 RT_ASSERT(false, "cmdtable cannot be NULL.\n");
281 return false;
282 }
283
284 if (cmdtableidx >= cmdtablesz)
285 return false;
286
287 pcmd = cmdtable + cmdtableidx;
288 pcmd->cmdid = cmdid;
289 pcmd->para1 = para1;
290 pcmd->para2 = para2;
291 pcmd->msdelay = msdelay;
292 return true;
293}
294EXPORT_SYMBOL_GPL(rtl8723_phy_set_sw_chnl_cmdarray);
295
296void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
297 bool iqk_ok,
298 long result[][8],
299 u8 final_candidate,
300 bool btxonly)
301{
302 u32 oldval_0, x, tx0_a, reg;
303 long y, tx0_c;
304
305 if (final_candidate == 0xFF) {
306 return;
307 } else if (iqk_ok) {
308 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
309 MASKDWORD) >> 22) & 0x3FF;
310 x = result[final_candidate][0];
311 if ((x & 0x00000200) != 0)
312 x = x | 0xFFFFFC00;
313 tx0_a = (x * oldval_0) >> 8;
314 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
315 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
316 ((x * oldval_0 >> 7) & 0x1));
317 y = result[final_candidate][1];
318 if ((y & 0x00000200) != 0)
319 y = y | 0xFFFFFC00;
320 tx0_c = (y * oldval_0) >> 8;
321 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
322 ((tx0_c & 0x3C0) >> 6));
323 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
324 (tx0_c & 0x3F));
325 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
326 ((y * oldval_0 >> 7) & 0x1));
327 if (btxonly)
328 return;
329 reg = result[final_candidate][2];
330 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
331 reg = result[final_candidate][3] & 0x3F;
332 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
333 reg = (result[final_candidate][3] >> 6) & 0xF;
334 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
335 }
336}
337EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_fill_iqk_matrix);
338
339void rtl8723_save_adda_registers(struct ieee80211_hw *hw, u32 *addareg,
340 u32 *addabackup, u32 registernum)
341{
342 u32 i;
343
344 for (i = 0; i < registernum; i++)
345 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
346}
347EXPORT_SYMBOL_GPL(rtl8723_save_adda_registers);
348
349void rtl8723_phy_save_mac_registers(struct ieee80211_hw *hw,
350 u32 *macreg, u32 *macbackup)
351{
352 struct rtl_priv *rtlpriv = rtl_priv(hw);
353 u32 i;
354
355 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
356 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
357 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
358}
359EXPORT_SYMBOL_GPL(rtl8723_phy_save_mac_registers);
360
361void rtl8723_phy_reload_adda_registers(struct ieee80211_hw *hw,
362 u32 *addareg, u32 *addabackup,
363 u32 regiesternum)
364{
365 u32 i;
366
367 for (i = 0; i < regiesternum; i++)
368 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
369}
370EXPORT_SYMBOL_GPL(rtl8723_phy_reload_adda_registers);
371
372void rtl8723_phy_reload_mac_registers(struct ieee80211_hw *hw,
373 u32 *macreg, u32 *macbackup)
374{
375 struct rtl_priv *rtlpriv = rtl_priv(hw);
376 u32 i;
377
378 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
379 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
380 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
381}
382EXPORT_SYMBOL_GPL(rtl8723_phy_reload_mac_registers);
383
384void rtl8723_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
385 bool is_patha_on, bool is2t)
386{
387 u32 pathon;
388 u32 i;
389
390 pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
391 if (!is2t) {
392 pathon = 0x0bdb25a0;
393 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
394 } else {
395 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
396 }
397
398 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
399 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
400}
401EXPORT_SYMBOL_GPL(rtl8723_phy_path_adda_on);
402
403void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw *hw,
404 u32 *macreg, u32 *macbackup)
405{
406 struct rtl_priv *rtlpriv = rtl_priv(hw);
407 u32 i = 0;
408
409 rtl_write_byte(rtlpriv, macreg[i], 0x3F);
410
411 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
412 rtl_write_byte(rtlpriv, macreg[i],
413 (u8) (macbackup[i] & (~BIT(3))));
414 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
415}
416EXPORT_SYMBOL_GPL(rtl8723_phy_mac_setting_calibration);
417
418void rtl8723_phy_path_a_standby(struct ieee80211_hw *hw)
419{
420 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
421 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
422 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
423}
424EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_standby);
425
426void rtl8723_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
427{
428 u32 mode;
429
430 mode = pi_mode ? 0x01000100 : 0x01000000;
431 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
432 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
433}
434EXPORT_SYMBOL_GPL(rtl8723_phy_pi_mode_switch);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h
new file mode 100644
index 000000000000..83b891a9adb8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h
@@ -0,0 +1,89 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __PHY_COMMON__
27#define __PHY_COMMON__
28
29#define RT_CANNOT_IO(hw) false
30
31enum swchnlcmd_id {
32 CMDID_END,
33 CMDID_SET_TXPOWEROWER_LEVEL,
34 CMDID_BBREGWRITE10,
35 CMDID_WRITEPORT_ULONG,
36 CMDID_WRITEPORT_USHORT,
37 CMDID_WRITEPORT_UCHAR,
38 CMDID_RF_WRITEREG,
39};
40
41struct swchnlcmd {
42 enum swchnlcmd_id cmdid;
43 u32 para1;
44 u32 para2;
45 u32 msdelay;
46};
47
48u32 rtl8723_phy_query_bb_reg(struct ieee80211_hw *hw,
49 u32 regaddr, u32 bitmask);
50void rtl8723_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
51 u32 bitmask, u32 data);
52u32 rtl8723_phy_calculate_bit_shift(u32 bitmask);
53u32 rtl8723_phy_rf_serial_read(struct ieee80211_hw *hw,
54 enum radio_path rfpath, u32 offset);
55void rtl8723_phy_rf_serial_write(struct ieee80211_hw *hw,
56 enum radio_path rfpath,
57 u32 offset, u32 data);
58long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
59 enum wireless_mode wirelessmode,
60 u8 txpwridx);
61void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw *hw);
62bool rtl8723_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
63 u32 cmdtableidx,
64 u32 cmdtablesz,
65 enum swchnlcmd_id cmdid,
66 u32 para1, u32 para2,
67 u32 msdelay);
68void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
69 bool iqk_ok,
70 long result[][8],
71 u8 final_candidate,
72 bool btxonly);
73void rtl8723_save_adda_registers(struct ieee80211_hw *hw, u32 *addareg,
74 u32 *addabackup, u32 registernum);
75void rtl8723_phy_save_mac_registers(struct ieee80211_hw *hw,
76 u32 *macreg, u32 *macbackup);
77void rtl8723_phy_reload_adda_registers(struct ieee80211_hw *hw,
78 u32 *addareg, u32 *addabackup,
79 u32 regiesternum);
80void rtl8723_phy_reload_mac_registers(struct ieee80211_hw *hw,
81 u32 *macreg, u32 *macbackup);
82void rtl8723_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
83 bool is_patha_on, bool is2t);
84void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw *hw,
85 u32 *macreg, u32 *macbackup);
86void rtl8723_phy_path_a_standby(struct ieee80211_hw *hw);
87void rtl8723_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode);
88
89#endif
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 4933f02ce1d5..0398d3ea15b0 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -410,7 +410,7 @@ static void rtl_usb_init_sw(struct ieee80211_hw *hw)
410 mac->current_ampdu_factor = 3; 410 mac->current_ampdu_factor = 3;
411 411
412 /* QOS */ 412 /* QOS */
413 rtlusb->acm_method = eAcmWay2_SW; 413 rtlusb->acm_method = EACMWAY2_SW;
414 414
415 /* IRQ */ 415 /* IRQ */
416 /* HIMR - turn all on */ 416 /* HIMR - turn all on */
@@ -994,7 +994,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw,
994 seq_number += 1; 994 seq_number += 1;
995 seq_number <<= 4; 995 seq_number <<= 4;
996 } 996 }
997 rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, sta, skb, 997 rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, NULL, info, sta, skb,
998 hw_queue, &tcb_desc); 998 hw_queue, &tcb_desc);
999 if (!ieee80211_has_morefrags(hdr->frame_control)) { 999 if (!ieee80211_has_morefrags(hdr->frame_control)) {
1000 if (qc) 1000 if (qc)
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 8c647391bedf..6965afdf572a 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -41,6 +41,38 @@
41#include <linux/completion.h> 41#include <linux/completion.h>
42#include "debug.h" 42#include "debug.h"
43 43
44#define MASKBYTE0 0xff
45#define MASKBYTE1 0xff00
46#define MASKBYTE2 0xff0000
47#define MASKBYTE3 0xff000000
48#define MASKHWORD 0xffff0000
49#define MASKLWORD 0x0000ffff
50#define MASKDWORD 0xffffffff
51#define MASK12BITS 0xfff
52#define MASKH4BITS 0xf0000000
53#define MASKOFDM_D 0xffc00000
54#define MASKCCK 0x3f3f3f3f
55
56#define MASK4BITS 0x0f
57#define MASK20BITS 0xfffff
58#define RFREG_OFFSET_MASK 0xfffff
59
60#define MASKBYTE0 0xff
61#define MASKBYTE1 0xff00
62#define MASKBYTE2 0xff0000
63#define MASKBYTE3 0xff000000
64#define MASKHWORD 0xffff0000
65#define MASKLWORD 0x0000ffff
66#define MASKDWORD 0xffffffff
67#define MASK12BITS 0xfff
68#define MASKH4BITS 0xf0000000
69#define MASKOFDM_D 0xffc00000
70#define MASKCCK 0x3f3f3f3f
71
72#define MASK4BITS 0x0f
73#define MASK20BITS 0xfffff
74#define RFREG_OFFSET_MASK 0xfffff
75
44#define RF_CHANGE_BY_INIT 0 76#define RF_CHANGE_BY_INIT 0
45#define RF_CHANGE_BY_IPS BIT(28) 77#define RF_CHANGE_BY_IPS BIT(28)
46#define RF_CHANGE_BY_PS BIT(29) 78#define RF_CHANGE_BY_PS BIT(29)
@@ -49,6 +81,7 @@
49 81
50#define IQK_ADDA_REG_NUM 16 82#define IQK_ADDA_REG_NUM 16
51#define IQK_MAC_REG_NUM 4 83#define IQK_MAC_REG_NUM 4
84#define IQK_THRESHOLD 8
52 85
53#define MAX_KEY_LEN 61 86#define MAX_KEY_LEN 61
54#define KEY_BUF_SIZE 5 87#define KEY_BUF_SIZE 5
@@ -86,7 +119,18 @@
86#define MAC80211_4ADDR_LEN 30 119#define MAC80211_4ADDR_LEN 30
87 120
88#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */ 121#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */
122#define CHANNEL_MAX_NUMBER_2G 14
123#define CHANNEL_MAX_NUMBER_5G 54 /* Please refer to
124 *"phy_GetChnlGroup8812A" and
125 * "Hal_ReadTxPowerInfo8812A"
126 */
127#define CHANNEL_MAX_NUMBER_5G_80M 7
89#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */ 128#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */
129#define CHANNEL_MAX_NUMBER_5G 54 /* Please refer to
130 *"phy_GetChnlGroup8812A" and
131 * "Hal_ReadTxPowerInfo8812A"
132 */
133#define CHANNEL_MAX_NUMBER_5G_80M 7
90#define MAX_PG_GROUP 13 134#define MAX_PG_GROUP 13
91#define CHANNEL_GROUP_MAX_2G 3 135#define CHANNEL_GROUP_MAX_2G 3
92#define CHANNEL_GROUP_IDX_5GL 3 136#define CHANNEL_GROUP_IDX_5GL 3
@@ -96,6 +140,7 @@
96#define CHANNEL_MAX_NUMBER_2G 14 140#define CHANNEL_MAX_NUMBER_2G 14
97#define AVG_THERMAL_NUM 8 141#define AVG_THERMAL_NUM 8
98#define AVG_THERMAL_NUM_88E 4 142#define AVG_THERMAL_NUM_88E 4
143#define AVG_THERMAL_NUM_8723BE 4
99#define MAX_TID_COUNT 9 144#define MAX_TID_COUNT 9
100 145
101/* for early mode */ 146/* for early mode */
@@ -107,6 +152,24 @@
107#define MAX_CHNL_GROUP_24G 6 152#define MAX_CHNL_GROUP_24G 6
108#define MAX_CHNL_GROUP_5G 14 153#define MAX_CHNL_GROUP_5G 14
109 154
155#define TX_PWR_BY_RATE_NUM_BAND 2
156#define TX_PWR_BY_RATE_NUM_RF 4
157#define TX_PWR_BY_RATE_NUM_SECTION 12
158#define MAX_BASE_NUM_IN_PHY_REG_PG_24G 6
159#define MAX_BASE_NUM_IN_PHY_REG_PG_5G 5
160
161#define RTL8192EE_SEG_NUM 1 /* 0:2 seg, 1: 4 seg, 2: 8 seg */
162
163#define DEL_SW_IDX_SZ 30
164#define BAND_NUM 3
165
166enum rf_tx_num {
167 RF_1TX = 0,
168 RF_2TX,
169 RF_MAX_TX_NUM,
170 RF_TX_NUM_NONIMPLEMENT,
171};
172
110struct txpower_info_2g { 173struct txpower_info_2g {
111 u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; 174 u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
112 u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; 175 u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
@@ -115,6 +178,8 @@ struct txpower_info_2g {
115 u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT]; 178 u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];
116 u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT]; 179 u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];
117 u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; 180 u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT];
181 u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT];
182 u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT];
118}; 183};
119 184
120struct txpower_info_5g { 185struct txpower_info_5g {
@@ -123,6 +188,17 @@ struct txpower_info_5g {
123 u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT]; 188 u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];
124 u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT]; 189 u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];
125 u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; 190 u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT];
191 u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT];
192 u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT];
193};
194
195enum rate_section {
196 CCK = 0,
197 OFDM,
198 HT_MCS0_MCS7,
199 HT_MCS8_MCS15,
200 VHT_1SSMCS0_1SSMCS9,
201 VHT_2SSMCS0_2SSMCS9,
126}; 202};
127 203
128enum intf_type { 204enum intf_type {
@@ -158,7 +234,10 @@ enum hardware_type {
158 HARDWARE_TYPE_RTL8192DU, 234 HARDWARE_TYPE_RTL8192DU,
159 HARDWARE_TYPE_RTL8723AE, 235 HARDWARE_TYPE_RTL8723AE,
160 HARDWARE_TYPE_RTL8723U, 236 HARDWARE_TYPE_RTL8723U,
237 HARDWARE_TYPE_RTL8723BE,
161 HARDWARE_TYPE_RTL8188EE, 238 HARDWARE_TYPE_RTL8188EE,
239 HARDWARE_TYPE_RTL8821AE,
240 HARDWARE_TYPE_RTL8812AE,
162 241
163 /* keep it last */ 242 /* keep it last */
164 HARDWARE_TYPE_NUM 243 HARDWARE_TYPE_NUM
@@ -195,8 +274,16 @@ enum hardware_type {
195 _pdesc->rxmcs == DESC92_RATE5_5M || \ 274 _pdesc->rxmcs == DESC92_RATE5_5M || \
196 _pdesc->rxmcs == DESC92_RATE11M) 275 _pdesc->rxmcs == DESC92_RATE11M)
197 276
277#define RTL8723E_RX_HAL_IS_CCK_RATE(rxmcs) \
278 ((rxmcs) == DESC92_RATE1M || \
279 (rxmcs) == DESC92_RATE2M || \
280 (rxmcs) == DESC92_RATE5_5M || \
281 (rxmcs) == DESC92_RATE11M)
282
198enum scan_operation_backup_opt { 283enum scan_operation_backup_opt {
199 SCAN_OPT_BACKUP = 0, 284 SCAN_OPT_BACKUP = 0,
285 SCAN_OPT_BACKUP_BAND0 = 0,
286 SCAN_OPT_BACKUP_BAND1,
200 SCAN_OPT_RESTORE, 287 SCAN_OPT_RESTORE,
201 SCAN_OPT_MAX 288 SCAN_OPT_MAX
202}; 289};
@@ -231,7 +318,9 @@ struct bb_reg_def {
231 318
232enum io_type { 319enum io_type {
233 IO_CMD_PAUSE_DM_BY_SCAN = 0, 320 IO_CMD_PAUSE_DM_BY_SCAN = 0,
234 IO_CMD_RESUME_DM_BY_SCAN = 1, 321 IO_CMD_PAUSE_BAND0_DM_BY_SCAN = 0,
322 IO_CMD_PAUSE_BAND1_DM_BY_SCAN = 1,
323 IO_CMD_RESUME_DM_BY_SCAN = 2,
235}; 324};
236 325
237enum hw_variables { 326enum hw_variables {
@@ -298,6 +387,7 @@ enum hw_variables {
298 HW_VAR_SET_RPWM, 387 HW_VAR_SET_RPWM,
299 HW_VAR_H2C_FW_PWRMODE, 388 HW_VAR_H2C_FW_PWRMODE,
300 HW_VAR_H2C_FW_JOINBSSRPT, 389 HW_VAR_H2C_FW_JOINBSSRPT,
390 HW_VAR_H2C_FW_MEDIASTATUSRPT,
301 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, 391 HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
302 HW_VAR_FW_PSMODE_STATUS, 392 HW_VAR_FW_PSMODE_STATUS,
303 HW_VAR_RESUME_CLK_ON, 393 HW_VAR_RESUME_CLK_ON,
@@ -330,6 +420,8 @@ enum hw_variables {
330 420
331 HAL_DEF_WOWLAN, 421 HAL_DEF_WOWLAN,
332 HW_VAR_MRC, 422 HW_VAR_MRC,
423 HW_VAR_KEEP_ALIVE,
424 HW_VAR_NAV_UPPER,
333 425
334 HW_VAR_MGT_FILTER, 426 HW_VAR_MGT_FILTER,
335 HW_VAR_CTRL_FILTER, 427 HW_VAR_CTRL_FILTER,
@@ -348,34 +440,34 @@ enum rt_oem_id {
348 RT_CID_8187_HW_LED = 3, 440 RT_CID_8187_HW_LED = 3,
349 RT_CID_8187_NETGEAR = 4, 441 RT_CID_8187_NETGEAR = 4,
350 RT_CID_WHQL = 5, 442 RT_CID_WHQL = 5,
351 RT_CID_819x_CAMEO = 6, 443 RT_CID_819X_CAMEO = 6,
352 RT_CID_819x_RUNTOP = 7, 444 RT_CID_819X_RUNTOP = 7,
353 RT_CID_819x_Senao = 8, 445 RT_CID_819X_SENAO = 8,
354 RT_CID_TOSHIBA = 9, 446 RT_CID_TOSHIBA = 9,
355 RT_CID_819x_Netcore = 10, 447 RT_CID_819X_NETCORE = 10,
356 RT_CID_Nettronix = 11, 448 RT_CID_NETTRONIX = 11,
357 RT_CID_DLINK = 12, 449 RT_CID_DLINK = 12,
358 RT_CID_PRONET = 13, 450 RT_CID_PRONET = 13,
359 RT_CID_COREGA = 14, 451 RT_CID_COREGA = 14,
360 RT_CID_819x_ALPHA = 15, 452 RT_CID_819X_ALPHA = 15,
361 RT_CID_819x_Sitecom = 16, 453 RT_CID_819X_SITECOM = 16,
362 RT_CID_CCX = 17, 454 RT_CID_CCX = 17,
363 RT_CID_819x_Lenovo = 18, 455 RT_CID_819X_LENOVO = 18,
364 RT_CID_819x_QMI = 19, 456 RT_CID_819X_QMI = 19,
365 RT_CID_819x_Edimax_Belkin = 20, 457 RT_CID_819X_EDIMAX_BELKIN = 20,
366 RT_CID_819x_Sercomm_Belkin = 21, 458 RT_CID_819X_SERCOMM_BELKIN = 21,
367 RT_CID_819x_CAMEO1 = 22, 459 RT_CID_819X_CAMEO1 = 22,
368 RT_CID_819x_MSI = 23, 460 RT_CID_819X_MSI = 23,
369 RT_CID_819x_Acer = 24, 461 RT_CID_819X_ACER = 24,
370 RT_CID_819x_HP = 27, 462 RT_CID_819X_HP = 27,
371 RT_CID_819x_CLEVO = 28, 463 RT_CID_819X_CLEVO = 28,
372 RT_CID_819x_Arcadyan_Belkin = 29, 464 RT_CID_819X_ARCADYAN_BELKIN = 29,
373 RT_CID_819x_SAMSUNG = 30, 465 RT_CID_819X_SAMSUNG = 30,
374 RT_CID_819x_WNC_COREGA = 31, 466 RT_CID_819X_WNC_COREGA = 31,
375 RT_CID_819x_Foxcoon = 32, 467 RT_CID_819X_FOXCOON = 32,
376 RT_CID_819x_DELL = 33, 468 RT_CID_819X_DELL = 33,
377 RT_CID_819x_PRONETS = 34, 469 RT_CID_819X_PRONETS = 34,
378 RT_CID_819x_Edimax_ASUS = 35, 470 RT_CID_819X_EDIMAX_ASUS = 35,
379 RT_CID_NETGEAR = 36, 471 RT_CID_NETGEAR = 36,
380 RT_CID_PLANEX = 37, 472 RT_CID_PLANEX = 37,
381 RT_CID_CC_C = 38, 473 RT_CID_CC_C = 38,
@@ -389,6 +481,7 @@ enum hw_descs {
389 HW_DESC_RXBUFF_ADDR, 481 HW_DESC_RXBUFF_ADDR,
390 HW_DESC_RXPKT_LEN, 482 HW_DESC_RXPKT_LEN,
391 HW_DESC_RXERO, 483 HW_DESC_RXERO,
484 HW_DESC_RX_PREPARE,
392}; 485};
393 486
394enum prime_sc { 487enum prime_sc {
@@ -407,6 +500,7 @@ enum rf_type {
407enum ht_channel_width { 500enum ht_channel_width {
408 HT_CHANNEL_WIDTH_20 = 0, 501 HT_CHANNEL_WIDTH_20 = 0,
409 HT_CHANNEL_WIDTH_20_40 = 1, 502 HT_CHANNEL_WIDTH_20_40 = 1,
503 HT_CHANNEL_WIDTH_80 = 2,
410}; 504};
411 505
412/* Ref: 802.11i sepc D10.0 7.3.2.25.1 506/* Ref: 802.11i sepc D10.0 7.3.2.25.1
@@ -471,6 +565,9 @@ enum rtl_var_map {
471 MAC_RCR_ACRC32, 565 MAC_RCR_ACRC32,
472 MAC_RCR_ACF, 566 MAC_RCR_ACF,
473 MAC_RCR_AAP, 567 MAC_RCR_AAP,
568 MAC_HIMR,
569 MAC_HIMRE,
570 MAC_HSISR,
474 571
475 /*efuse map */ 572 /*efuse map */
476 EFUSE_TEST, 573 EFUSE_TEST,
@@ -608,7 +705,7 @@ enum rtl_led_pin {
608enum acm_method { 705enum acm_method {
609 eAcmWay0_SwAndHw = 0, 706 eAcmWay0_SwAndHw = 0,
610 eAcmWay1_HW = 1, 707 eAcmWay1_HW = 1,
611 eAcmWay2_SW = 2, 708 EACMWAY2_SW = 2,
612}; 709};
613 710
614enum macphy_mode { 711enum macphy_mode {
@@ -645,7 +742,9 @@ enum wireless_mode {
645 WIRELESS_MODE_G = 0x04, 742 WIRELESS_MODE_G = 0x04,
646 WIRELESS_MODE_AUTO = 0x08, 743 WIRELESS_MODE_AUTO = 0x08,
647 WIRELESS_MODE_N_24G = 0x10, 744 WIRELESS_MODE_N_24G = 0x10,
648 WIRELESS_MODE_N_5G = 0x20 745 WIRELESS_MODE_N_5G = 0x20,
746 WIRELESS_MODE_AC_5G = 0x40,
747 WIRELESS_MODE_AC_24G = 0x80
649}; 748};
650 749
651#define IS_WIRELESS_MODE_A(wirelessmode) \ 750#define IS_WIRELESS_MODE_A(wirelessmode) \
@@ -669,6 +768,8 @@ enum ratr_table_mode {
669 RATR_INX_WIRELESS_B = 6, 768 RATR_INX_WIRELESS_B = 6,
670 RATR_INX_WIRELESS_MC = 7, 769 RATR_INX_WIRELESS_MC = 7,
671 RATR_INX_WIRELESS_A = 8, 770 RATR_INX_WIRELESS_A = 8,
771 RATR_INX_WIRELESS_AC_5N = 8,
772 RATR_INX_WIRELESS_AC_24N = 9,
672}; 773};
673 774
674enum rtl_link_state { 775enum rtl_link_state {
@@ -803,8 +904,12 @@ struct wireless_stats {
803 long signal_strength; 904 long signal_strength;
804 905
805 u8 rx_rssi_percentage[4]; 906 u8 rx_rssi_percentage[4];
907 u8 rx_evm_dbm[4];
806 u8 rx_evm_percentage[2]; 908 u8 rx_evm_percentage[2];
807 909
910 u16 rx_cfo_short[4];
911 u16 rx_cfo_tail[4];
912
808 struct rt_smooth_data ui_rssi; 913 struct rt_smooth_data ui_rssi;
809 struct rt_smooth_data ui_link_quality; 914 struct rt_smooth_data ui_link_quality;
810}; 915};
@@ -817,9 +922,9 @@ struct rate_adaptive {
817 u32 high_rssi_thresh_for_ra; 922 u32 high_rssi_thresh_for_ra;
818 u32 high2low_rssi_thresh_for_ra; 923 u32 high2low_rssi_thresh_for_ra;
819 u8 low2high_rssi_thresh_for_ra40m; 924 u8 low2high_rssi_thresh_for_ra40m;
820 u32 low_rssi_thresh_for_ra40M; 925 u32 low_rssi_thresh_for_ra40m;
821 u8 low2high_rssi_thresh_for_ra20m; 926 u8 low2high_rssi_thresh_for_ra20m;
822 u32 low_rssi_thresh_for_ra20M; 927 u32 low_rssi_thresh_for_ra20m;
823 u32 upper_rssi_threshold_ratr; 928 u32 upper_rssi_threshold_ratr;
824 u32 middleupper_rssi_threshold_ratr; 929 u32 middleupper_rssi_threshold_ratr;
825 u32 middle_rssi_threshold_ratr; 930 u32 middle_rssi_threshold_ratr;
@@ -833,6 +938,10 @@ struct rate_adaptive {
833 u32 ping_rssi_thresh_for_ra; 938 u32 ping_rssi_thresh_for_ra;
834 u32 last_ratr; 939 u32 last_ratr;
835 u8 pre_ratr_state; 940 u8 pre_ratr_state;
941 u8 ldpc_thres;
942 bool use_ldpc;
943 bool lower_rts_rate;
944 bool is_special_data;
836}; 945};
837 946
838struct regd_pair_mapping { 947struct regd_pair_mapping {
@@ -841,6 +950,16 @@ struct regd_pair_mapping {
841 u16 reg_2ghz_ctl; 950 u16 reg_2ghz_ctl;
842}; 951};
843 952
953struct dynamic_primary_cca {
954 u8 pricca_flag;
955 u8 intf_flag;
956 u8 intf_type;
957 u8 dup_rts_flag;
958 u8 monitor_flag;
959 u8 ch_offset;
960 u8 mf_state;
961};
962
844struct rtl_regulatory { 963struct rtl_regulatory {
845 char alpha2[2]; 964 char alpha2[2];
846 u16 country_code; 965 u16 country_code;
@@ -976,16 +1095,29 @@ struct rtl_phy {
976 u32 iqk_bb_backup[10]; 1095 u32 iqk_bb_backup[10];
977 bool iqk_initialized; 1096 bool iqk_initialized;
978 1097
1098 bool rfpath_rx_enable[MAX_RF_PATH];
1099 u8 reg_837;
979 /* Dual mac */ 1100 /* Dual mac */
980 bool need_iqk; 1101 bool need_iqk;
981 struct iqk_matrix_regs iqk_matrix[IQK_MATRIX_SETTINGS_NUM]; 1102 struct iqk_matrix_regs iqk_matrix[IQK_MATRIX_SETTINGS_NUM];
982 1103
983 bool rfpi_enable; 1104 bool rfpi_enable;
1105 bool iqk_in_progress;
984 1106
985 u8 pwrgroup_cnt; 1107 u8 pwrgroup_cnt;
986 u8 cck_high_power; 1108 u8 cck_high_power;
987 /* MAX_PG_GROUP groups of pwr diff by rates */ 1109 /* MAX_PG_GROUP groups of pwr diff by rates */
988 u32 mcs_offset[MAX_PG_GROUP][16]; 1110 u32 mcs_offset[MAX_PG_GROUP][16];
1111 u32 tx_power_by_rate_offset[TX_PWR_BY_RATE_NUM_BAND]
1112 [TX_PWR_BY_RATE_NUM_RF]
1113 [TX_PWR_BY_RATE_NUM_RF]
1114 [TX_PWR_BY_RATE_NUM_SECTION];
1115 u8 txpwr_by_rate_base_24g[TX_PWR_BY_RATE_NUM_RF]
1116 [TX_PWR_BY_RATE_NUM_RF]
1117 [MAX_BASE_NUM_IN_PHY_REG_PG_24G];
1118 u8 txpwr_by_rate_base_5g[TX_PWR_BY_RATE_NUM_RF]
1119 [TX_PWR_BY_RATE_NUM_RF]
1120 [MAX_BASE_NUM_IN_PHY_REG_PG_5G];
989 u8 default_initialgain[4]; 1121 u8 default_initialgain[4];
990 1122
991 /* the current Tx power level */ 1123 /* the current Tx power level */
@@ -998,6 +1130,7 @@ struct rtl_phy {
998 bool apk_done; 1130 bool apk_done;
999 u32 reg_rf3c[2]; /* pathA / pathB */ 1131 u32 reg_rf3c[2]; /* pathA / pathB */
1000 1132
1133 u32 backup_rf_0x1a;/*92ee*/
1001 /* bfsync */ 1134 /* bfsync */
1002 u8 framesync; 1135 u8 framesync;
1003 u32 framesync_c34; 1136 u32 framesync_c34;
@@ -1006,6 +1139,7 @@ struct rtl_phy {
1006 struct phy_parameters hwparam_tables[MAX_TAB]; 1139 struct phy_parameters hwparam_tables[MAX_TAB];
1007 u16 rf_pathmap; 1140 u16 rf_pathmap;
1008 1141
1142 u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/
1009 enum rt_polarity_ctl polarity_ctl; 1143 enum rt_polarity_ctl polarity_ctl;
1010}; 1144};
1011 1145
@@ -1133,6 +1267,7 @@ struct rtl_mac {
1133 u8 use_cts_protect; 1267 u8 use_cts_protect;
1134 u8 cur_40_prime_sc; 1268 u8 cur_40_prime_sc;
1135 u8 cur_40_prime_sc_bk; 1269 u8 cur_40_prime_sc_bk;
1270 u8 cur_80_prime_sc;
1136 u64 tsf; 1271 u64 tsf;
1137 u8 retry_short; 1272 u8 retry_short;
1138 u8 retry_long; 1273 u8 retry_long;
@@ -1213,6 +1348,7 @@ struct rtl_hal {
1213 bool being_init_adapter; 1348 bool being_init_adapter;
1214 bool bbrf_ready; 1349 bool bbrf_ready;
1215 bool mac_func_enable; 1350 bool mac_func_enable;
1351 bool pre_edcca_enable;
1216 struct bt_coexist_8723 hal_coex_8723; 1352 struct bt_coexist_8723 hal_coex_8723;
1217 1353
1218 enum intf_type interface; 1354 enum intf_type interface;
@@ -1234,6 +1370,7 @@ struct rtl_hal {
1234 /*Reserve page start offset except beacon in TxQ. */ 1370 /*Reserve page start offset except beacon in TxQ. */
1235 u8 fw_rsvdpage_startoffset; 1371 u8 fw_rsvdpage_startoffset;
1236 u8 h2c_txcmd_seq; 1372 u8 h2c_txcmd_seq;
1373 u8 current_ra_rate;
1237 1374
1238 /* FW Cmd IO related */ 1375 /* FW Cmd IO related */
1239 u16 fwcmd_iomap; 1376 u16 fwcmd_iomap;
@@ -1273,6 +1410,9 @@ struct rtl_hal {
1273 bool disable_amsdu_8k; 1410 bool disable_amsdu_8k;
1274 bool master_of_dmsp; 1411 bool master_of_dmsp;
1275 bool slave_of_dmsp; 1412 bool slave_of_dmsp;
1413
1414 u16 rx_tag;/*for 92ee*/
1415 u8 rts_en;
1276}; 1416};
1277 1417
1278struct rtl_security { 1418struct rtl_security {
@@ -1321,6 +1461,16 @@ struct fast_ant_training {
1321 bool becomelinked; 1461 bool becomelinked;
1322}; 1462};
1323 1463
1464struct dm_phy_dbg_info {
1465 char rx_snrdb[4];
1466 u64 num_qry_phy_status;
1467 u64 num_qry_phy_status_cck;
1468 u64 num_qry_phy_status_ofdm;
1469 u16 num_qry_beacon_pkt;
1470 u16 num_non_be_pkt;
1471 s32 rx_evm[4];
1472};
1473
1324struct rtl_dm { 1474struct rtl_dm {
1325 /*PHY status for Dynamic Management */ 1475 /*PHY status for Dynamic Management */
1326 long entry_min_undec_sm_pwdb; 1476 long entry_min_undec_sm_pwdb;
@@ -1360,29 +1510,84 @@ struct rtl_dm {
1360 u8 txpower_track_control; 1510 u8 txpower_track_control;
1361 bool interrupt_migration; 1511 bool interrupt_migration;
1362 bool disable_tx_int; 1512 bool disable_tx_int;
1363 char ofdm_index[2]; 1513 char ofdm_index[MAX_RF_PATH];
1514 u8 default_ofdm_index;
1515 u8 default_cck_index;
1364 char cck_index; 1516 char cck_index;
1365 char delta_power_index; 1517 char delta_power_index[MAX_RF_PATH];
1366 char delta_power_index_last; 1518 char delta_power_index_last[MAX_RF_PATH];
1367 char power_index_offset; 1519 char power_index_offset[MAX_RF_PATH];
1520 char absolute_ofdm_swing_idx[MAX_RF_PATH];
1521 char remnant_ofdm_swing_idx[MAX_RF_PATH];
1522 char remnant_cck_idx;
1523 bool modify_txagc_flag_path_a;
1524 bool modify_txagc_flag_path_b;
1525
1526 bool one_entry_only;
1527 struct dm_phy_dbg_info dbginfo;
1528
1529 /* Dynamic ATC switch */
1530 bool atc_status;
1531 bool large_cfo_hit;
1532 bool is_freeze;
1533 int cfo_tail[2];
1534 int cfo_ave_pre;
1535 int crystal_cap;
1536 u8 cfo_threshold;
1537 u32 packet_count;
1538 u32 packet_count_pre;
1539 u8 tx_rate;
1368 1540
1369 /*88e tx power tracking*/ 1541 /*88e tx power tracking*/
1370 u8 swing_idx_ofdm[2]; 1542 u8 swing_idx_ofdm[MAX_RF_PATH];
1371 u8 swing_idx_ofdm_cur; 1543 u8 swing_idx_ofdm_cur;
1372 u8 swing_idx_ofdm_base; 1544 u8 swing_idx_ofdm_base[MAX_RF_PATH];
1373 bool swing_flag_ofdm; 1545 bool swing_flag_ofdm;
1374 u8 swing_idx_cck; 1546 u8 swing_idx_cck;
1375 u8 swing_idx_cck_cur; 1547 u8 swing_idx_cck_cur;
1376 u8 swing_idx_cck_base; 1548 u8 swing_idx_cck_base;
1377 bool swing_flag_cck; 1549 bool swing_flag_cck;
1378 1550
1551 char swing_diff_2g;
1552 char swing_diff_5g;
1553
1554 u8 delta_swing_table_idx_24gccka_p[DEL_SW_IDX_SZ];
1555 u8 delta_swing_table_idx_24gccka_n[DEL_SW_IDX_SZ];
1556 u8 delta_swing_table_idx_24gcckb_p[DEL_SW_IDX_SZ];
1557 u8 delta_swing_table_idx_24gcckb_n[DEL_SW_IDX_SZ];
1558 u8 delta_swing_table_idx_24ga_p[DEL_SW_IDX_SZ];
1559 u8 delta_swing_table_idx_24ga_n[DEL_SW_IDX_SZ];
1560 u8 delta_swing_table_idx_24gb_p[DEL_SW_IDX_SZ];
1561 u8 delta_swing_table_idx_24gb_n[DEL_SW_IDX_SZ];
1562 u8 delta_swing_table_idx_5ga_p[BAND_NUM][DEL_SW_IDX_SZ];
1563 u8 delta_swing_table_idx_5ga_n[BAND_NUM][DEL_SW_IDX_SZ];
1564 u8 delta_swing_table_idx_5gb_p[BAND_NUM][DEL_SW_IDX_SZ];
1565 u8 delta_swing_table_idx_5gb_n[BAND_NUM][DEL_SW_IDX_SZ];
1566 u8 delta_swing_table_idx_24ga_p_8188e[DEL_SW_IDX_SZ];
1567 u8 delta_swing_table_idx_24ga_n_8188e[DEL_SW_IDX_SZ];
1568
1379 /* DMSP */ 1569 /* DMSP */
1380 bool supp_phymode_switch; 1570 bool supp_phymode_switch;
1381 1571
1572 /* DulMac */
1382 struct fast_ant_training fat_table; 1573 struct fast_ant_training fat_table;
1574
1575 u8 resp_tx_path;
1576 u8 path_sel;
1577 u32 patha_sum;
1578 u32 pathb_sum;
1579 u32 patha_cnt;
1580 u32 pathb_cnt;
1581
1582 u8 pre_channel;
1583 u8 *p_channel;
1584 u8 linked_interval;
1585
1586 u64 last_tx_ok_cnt;
1587 u64 last_rx_ok_cnt;
1383}; 1588};
1384 1589
1385#define EFUSE_MAX_LOGICAL_SIZE 256 1590#define EFUSE_MAX_LOGICAL_SIZE 512
1386 1591
1387struct rtl_efuse { 1592struct rtl_efuse {
1388 bool autoLoad_ok; 1593 bool autoLoad_ok;
@@ -1422,12 +1627,9 @@ struct rtl_efuse {
1422 u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */ 1627 u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */
1423 u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX]; 1628 u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX];
1424 u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; 1629 u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX];
1425 u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G]; 1630 u8 eeprom_chnlarea_txpwr_cck[MAX_RF_PATH][CHANNEL_GROUP_MAX_2G];
1426 u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX]; 1631 u8 eeprom_chnlarea_txpwr_ht40_1s[MAX_RF_PATH][CHANNEL_GROUP_MAX];
1427 u8 eprom_chnl_txpwr_ht40_2sdf[2][CHANNEL_GROUP_MAX]; 1632 u8 eprom_chnl_txpwr_ht40_2sdf[MAX_RF_PATH][CHANNEL_GROUP_MAX];
1428 u8 txpwrlevel_cck[2][CHANNEL_MAX_NUMBER_2G];
1429 u8 txpwrlevel_ht40_1s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */
1430 u8 txpwrlevel_ht40_2s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */
1431 1633
1432 u8 internal_pa_5g[2]; /* pathA / pathB */ 1634 u8 internal_pa_5g[2]; /* pathA / pathB */
1433 u8 eeprom_c9; 1635 u8 eeprom_c9;
@@ -1438,9 +1640,38 @@ struct rtl_efuse {
1438 u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER]; 1640 u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER];
1439 u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER]; 1641 u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER];
1440 1642
1441 char txpwr_ht20diff[2][CHANNEL_MAX_NUMBER]; /*HT 20<->40 Pwr diff */ 1643 u8 txpwrlevel_cck[MAX_RF_PATH][CHANNEL_MAX_NUMBER_2G];
1442 /*For HT<->legacy pwr diff*/ 1644 /*For HT 40MHZ pwr */
1443 u8 txpwr_legacyhtdiff[2][CHANNEL_MAX_NUMBER]; 1645 u8 txpwrlevel_ht40_1s[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
1646 /*For HT 40MHZ pwr */
1647 u8 txpwrlevel_ht40_2s[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
1648
1649 /*--------------------------------------------------------*
1650 * 8192CE\8192SE\8192DE\8723AE use the following 4 arrays,
1651 * other ICs (8188EE\8723BE\8192EE\8812AE...)
1652 * define new arrays in Windows code.
1653 * BUT, in linux code, we use the same array for all ICs.
1654 *
1655 * The Correspondance relation between two arrays is:
1656 * txpwr_cckdiff[][] == CCK_24G_Diff[][]
1657 * txpwr_ht20diff[][] == BW20_24G_Diff[][]
1658 * txpwr_ht40diff[][] == BW40_24G_Diff[][]
1659 * txpwr_legacyhtdiff[][] == OFDM_24G_Diff[][]
1660 *
1661 * Sizes of these arrays are decided by the larger ones.
1662 */
1663 char txpwr_cckdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
1664 char txpwr_ht20diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
1665 char txpwr_ht40diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
1666 char txpwr_legacyhtdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
1667
1668 u8 txpwr_5g_bw40base[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
1669 u8 txpwr_5g_bw80base[MAX_RF_PATH][CHANNEL_MAX_NUMBER_5G_80M];
1670 char txpwr_5g_ofdmdiff[MAX_RF_PATH][MAX_TX_COUNT];
1671 char txpwr_5g_bw20diff[MAX_RF_PATH][MAX_TX_COUNT];
1672 char txpwr_5g_bw40diff[MAX_RF_PATH][MAX_TX_COUNT];
1673 char txpwr_5g_bw80diff[MAX_RF_PATH][MAX_TX_COUNT];
1674
1444 u8 txpwr_safetyflag; /* Band edge enable flag */ 1675 u8 txpwr_safetyflag; /* Band edge enable flag */
1445 u16 eeprom_txpowerdiff; 1676 u16 eeprom_txpowerdiff;
1446 u8 legacy_httxpowerdiff; /* Legacy to HT rate power diff */ 1677 u8 legacy_httxpowerdiff; /* Legacy to HT rate power diff */
@@ -1571,7 +1802,9 @@ struct rtl_stats {
1571 bool rx_is40Mhzpacket; 1802 bool rx_is40Mhzpacket;
1572 u32 rx_pwdb_all; 1803 u32 rx_pwdb_all;
1573 u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ 1804 u8 rx_mimo_signalstrength[4]; /*in 0~100 index */
1574 s8 rx_mimo_sig_qual[2]; 1805 s8 rx_mimo_sig_qual[4];
1806 u8 rx_pwr[4]; /* per-path's pwdb */
1807 u8 rx_snr[4]; /* per-path's SNR */
1575 bool packet_matchbssid; 1808 bool packet_matchbssid;
1576 bool is_cck; 1809 bool is_cck;
1577 bool is_ht; 1810 bool is_ht;
@@ -1644,6 +1877,8 @@ struct rtl_tcb_desc {
1644 bool btx_enable_sw_calc_duration; 1877 bool btx_enable_sw_calc_duration;
1645}; 1878};
1646 1879
1880struct rtl92c_firmware_header;
1881
1647struct rtl_hal_ops { 1882struct rtl_hal_ops {
1648 int (*init_sw_vars) (struct ieee80211_hw *hw); 1883 int (*init_sw_vars) (struct ieee80211_hw *hw);
1649 void (*deinit_sw_vars) (struct ieee80211_hw *hw); 1884 void (*deinit_sw_vars) (struct ieee80211_hw *hw);
@@ -1673,9 +1908,17 @@ struct rtl_hal_ops {
1673 void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); 1908 void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
1674 void (*update_rate_tbl) (struct ieee80211_hw *hw, 1909 void (*update_rate_tbl) (struct ieee80211_hw *hw,
1675 struct ieee80211_sta *sta, u8 rssi_level); 1910 struct ieee80211_sta *sta, u8 rssi_level);
1911 void (*pre_fill_tx_bd_desc)(struct ieee80211_hw *hw, u8 *tx_bd_desc,
1912 u8 *desc, u8 queue_index,
1913 struct sk_buff *skb, dma_addr_t addr);
1676 void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level); 1914 void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level);
1915 u16 (*rx_desc_buff_remained_cnt)(struct ieee80211_hw *hw,
1916 u8 queue_index);
1917 void (*rx_check_dma_ok)(struct ieee80211_hw *hw, u8 *header_desc,
1918 u8 queue_index);
1677 void (*fill_tx_desc) (struct ieee80211_hw *hw, 1919 void (*fill_tx_desc) (struct ieee80211_hw *hw,
1678 struct ieee80211_hdr *hdr, u8 *pdesc_tx, 1920 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
1921 u8 *pbd_desc_tx,
1679 struct ieee80211_tx_info *info, 1922 struct ieee80211_tx_info *info,
1680 struct ieee80211_sta *sta, 1923 struct ieee80211_sta *sta,
1681 struct sk_buff *skb, u8 hw_queue, 1924 struct sk_buff *skb, u8 hw_queue,
@@ -1698,8 +1941,11 @@ struct rtl_hal_ops {
1698 enum rf_pwrstate rfpwr_state); 1941 enum rf_pwrstate rfpwr_state);
1699 void (*led_control) (struct ieee80211_hw *hw, 1942 void (*led_control) (struct ieee80211_hw *hw,
1700 enum led_ctl_mode ledaction); 1943 enum led_ctl_mode ledaction);
1701 void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val); 1944 void (*set_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
1945 u8 desc_name, u8 *val);
1702 u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name); 1946 u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name);
1947 bool (*is_tx_desc_closed) (struct ieee80211_hw *hw,
1948 u8 hw_queue, u16 index);
1703 void (*tx_polling) (struct ieee80211_hw *hw, u8 hw_queue); 1949 void (*tx_polling) (struct ieee80211_hw *hw, u8 hw_queue);
1704 void (*enable_hw_sec) (struct ieee80211_hw *hw); 1950 void (*enable_hw_sec) (struct ieee80211_hw *hw);
1705 void (*set_key) (struct ieee80211_hw *hw, u32 key_index, 1951 void (*set_key) (struct ieee80211_hw *hw, u32 key_index,
@@ -1738,6 +1984,10 @@ struct rtl_hal_ops {
1738 void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); 1984 void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
1739 void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id, 1985 void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,
1740 u32 cmd_len, u8 *p_cmdbuffer); 1986 u32 cmd_len, u8 *p_cmdbuffer);
1987 bool (*get_btc_status) (void);
1988 bool (*is_fw_header) (struct rtl92c_firmware_header *hdr);
1989 u32 (*rx_command_packet)(struct ieee80211_hw *hw,
1990 struct rtl_stats status, struct sk_buff *skb);
1741}; 1991};
1742 1992
1743struct rtl_intf_ops { 1993struct rtl_intf_ops {
@@ -1847,6 +2097,8 @@ struct rtl_locks {
1847 2097
1848 /*Easy concurrent*/ 2098 /*Easy concurrent*/
1849 spinlock_t check_sendpkt_lock; 2099 spinlock_t check_sendpkt_lock;
2100
2101 spinlock_t iqk_lock;
1850}; 2102};
1851 2103
1852struct rtl_works { 2104struct rtl_works {
@@ -1915,6 +2167,7 @@ struct ps_t {
1915 u8 cur_ccasate; 2167 u8 cur_ccasate;
1916 u8 pre_rfstate; 2168 u8 pre_rfstate;
1917 u8 cur_rfstate; 2169 u8 cur_rfstate;
2170 u8 initialize;
1918 long rssi_val_min; 2171 long rssi_val_min;
1919}; 2172};
1920 2173
@@ -1939,6 +2192,7 @@ struct dig_t {
1939 u8 cursta_cstate; 2192 u8 cursta_cstate;
1940 u8 presta_cstate; 2193 u8 presta_cstate;
1941 u8 curmultista_cstate; 2194 u8 curmultista_cstate;
2195 u8 stop_dig;
1942 char back_val; 2196 char back_val;
1943 char back_range_max; 2197 char back_range_max;
1944 char back_range_min; 2198 char back_range_min;
@@ -1956,6 +2210,7 @@ struct dig_t {
1956 u8 cur_ccasate; 2210 u8 cur_ccasate;
1957 u8 large_fa_hit; 2211 u8 large_fa_hit;
1958 u8 dig_dynamic_min; 2212 u8 dig_dynamic_min;
2213 u8 dig_dynamic_min_1;
1959 u8 forbidden_igi; 2214 u8 forbidden_igi;
1960 u8 dig_state; 2215 u8 dig_state;
1961 u8 dig_highpwrstate; 2216 u8 dig_highpwrstate;
@@ -1972,6 +2227,7 @@ struct dig_t {
1972 char backoffval_range_min; 2227 char backoffval_range_min;
1973 u8 dig_min_0; 2228 u8 dig_min_0;
1974 u8 dig_min_1; 2229 u8 dig_min_1;
2230 u8 bt30_cur_igi;
1975 bool media_connect_0; 2231 bool media_connect_0;
1976 bool media_connect_1; 2232 bool media_connect_1;
1977 2233
@@ -1986,6 +2242,96 @@ struct rtl_global_var {
1986 spinlock_t glb_list_lock; 2242 spinlock_t glb_list_lock;
1987}; 2243};
1988 2244
2245struct rtl_btc_info {
2246 u8 bt_type;
2247 u8 btcoexist;
2248 u8 ant_num;
2249};
2250
2251struct bt_coexist_info {
2252 struct rtl_btc_ops *btc_ops;
2253 struct rtl_btc_info btc_info;
2254 /* EEPROM BT info. */
2255 u8 eeprom_bt_coexist;
2256 u8 eeprom_bt_type;
2257 u8 eeprom_bt_ant_num;
2258 u8 eeprom_bt_ant_isol;
2259 u8 eeprom_bt_radio_shared;
2260
2261 u8 bt_coexistence;
2262 u8 bt_ant_num;
2263 u8 bt_coexist_type;
2264 u8 bt_state;
2265 u8 bt_cur_state; /* 0:on, 1:off */
2266 u8 bt_ant_isolation; /* 0:good, 1:bad */
2267 u8 bt_pape_ctrl; /* 0:SW, 1:SW/HW dynamic */
2268 u8 bt_service;
2269 u8 bt_radio_shared_type;
2270 u8 bt_rfreg_origin_1e;
2271 u8 bt_rfreg_origin_1f;
2272 u8 bt_rssi_state;
2273 u32 ratio_tx;
2274 u32 ratio_pri;
2275 u32 bt_edca_ul;
2276 u32 bt_edca_dl;
2277
2278 bool init_set;
2279 bool bt_busy_traffic;
2280 bool bt_traffic_mode_set;
2281 bool bt_non_traffic_mode_set;
2282
2283 bool fw_coexist_all_off;
2284 bool sw_coexist_all_off;
2285 bool hw_coexist_all_off;
2286 u32 cstate;
2287 u32 previous_state;
2288 u32 cstate_h;
2289 u32 previous_state_h;
2290
2291 u8 bt_pre_rssi_state;
2292 u8 bt_pre_rssi_state1;
2293
2294 u8 reg_bt_iso;
2295 u8 reg_bt_sco;
2296 bool balance_on;
2297 u8 bt_active_zero_cnt;
2298 bool cur_bt_disabled;
2299 bool pre_bt_disabled;
2300
2301 u8 bt_profile_case;
2302 u8 bt_profile_action;
2303 bool bt_busy;
2304 bool hold_for_bt_operation;
2305 u8 lps_counter;
2306};
2307
2308struct rtl_btc_ops {
2309 void (*btc_init_variables) (struct rtl_priv *rtlpriv);
2310 void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv);
2311 void (*btc_init_hw_config) (struct rtl_priv *rtlpriv);
2312 void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type);
2313 void (*btc_scan_notify) (struct rtl_priv *rtlpriv, u8 scantype);
2314 void (*btc_connect_notify) (struct rtl_priv *rtlpriv, u8 action);
2315 void (*btc_mediastatus_notify) (struct rtl_priv *rtlpriv,
2316 enum _RT_MEDIA_STATUS mstatus);
2317 void (*btc_periodical) (struct rtl_priv *rtlpriv);
2318 void (*btc_halt_notify) (void);
2319 void (*btc_btinfo_notify) (struct rtl_priv *rtlpriv,
2320 u8 *tmp_buf, u8 length);
2321 bool (*btc_is_limited_dig) (struct rtl_priv *rtlpriv);
2322 bool (*btc_is_disable_edca_turbo) (struct rtl_priv *rtlpriv);
2323 bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv);
2324};
2325
2326struct proxim {
2327 bool proxim_on;
2328
2329 void *proximity_priv;
2330 int (*proxim_rx)(struct ieee80211_hw *hw, struct rtl_stats *status,
2331 struct sk_buff *skb);
2332 u8 (*proxim_get_var)(struct ieee80211_hw *hw, u8 type);
2333};
2334
1989struct rtl_priv { 2335struct rtl_priv {
1990 struct ieee80211_hw *hw; 2336 struct ieee80211_hw *hw;
1991 struct completion firmware_loading_complete; 2337 struct completion firmware_loading_complete;
@@ -2008,6 +2354,7 @@ struct rtl_priv {
2008 2354
2009 struct rtl_ps_ctl psc; 2355 struct rtl_ps_ctl psc;
2010 struct rate_adaptive ra; 2356 struct rate_adaptive ra;
2357 struct dynamic_primary_cca primarycca;
2011 struct wireless_stats stats; 2358 struct wireless_stats stats;
2012 struct rt_link_detect link_info; 2359 struct rt_link_detect link_info;
2013 struct false_alarm_statistics falsealm_cnt; 2360 struct false_alarm_statistics falsealm_cnt;
@@ -2048,6 +2395,20 @@ struct rtl_priv {
2048 bool enter_ps; /* true when entering PS */ 2395 bool enter_ps; /* true when entering PS */
2049 u8 rate_mask[5]; 2396 u8 rate_mask[5];
2050 2397
2398 /* intel Proximity, should be alloc mem
2399 * in intel Proximity module and can only
2400 * be used in intel Proximity mode
2401 */
2402 struct proxim proximity;
2403
2404 /*for bt coexist use*/
2405 struct bt_coexist_info btcoexist;
2406
2407 /* separate 92ee from other ICs,
2408 * 92ee use new trx flow.
2409 */
2410 bool use_new_trx_flow;
2411
2051 /*This must be the last item so 2412 /*This must be the last item so
2052 that it points to the data allocated 2413 that it points to the data allocated
2053 beyond this structure like: 2414 beyond this structure like:
@@ -2079,6 +2440,15 @@ enum bt_co_type {
2079 BT_CSR_BC8 = 4, 2440 BT_CSR_BC8 = 4,
2080 BT_RTL8756 = 5, 2441 BT_RTL8756 = 5,
2081 BT_RTL8723A = 6, 2442 BT_RTL8723A = 6,
2443 BT_RTL8821A = 7,
2444 BT_RTL8723B = 8,
2445 BT_RTL8192E = 9,
2446 BT_RTL8812A = 11,
2447};
2448
2449enum bt_total_ant_num {
2450 ANT_TOTAL_X2 = 0,
2451 ANT_TOTAL_X1 = 1
2082}; 2452};
2083 2453
2084enum bt_cur_state { 2454enum bt_cur_state {
@@ -2104,62 +2474,6 @@ enum bt_radio_shared {
2104 BT_RADIO_INDIVIDUAL = 1, 2474 BT_RADIO_INDIVIDUAL = 1,
2105}; 2475};
2106 2476
2107struct bt_coexist_info {
2108
2109 /* EEPROM BT info. */
2110 u8 eeprom_bt_coexist;
2111 u8 eeprom_bt_type;
2112 u8 eeprom_bt_ant_num;
2113 u8 eeprom_bt_ant_isol;
2114 u8 eeprom_bt_radio_shared;
2115
2116 u8 bt_coexistence;
2117 u8 bt_ant_num;
2118 u8 bt_coexist_type;
2119 u8 bt_state;
2120 u8 bt_cur_state; /* 0:on, 1:off */
2121 u8 bt_ant_isolation; /* 0:good, 1:bad */
2122 u8 bt_pape_ctrl; /* 0:SW, 1:SW/HW dynamic */
2123 u8 bt_service;
2124 u8 bt_radio_shared_type;
2125 u8 bt_rfreg_origin_1e;
2126 u8 bt_rfreg_origin_1f;
2127 u8 bt_rssi_state;
2128 u32 ratio_tx;
2129 u32 ratio_pri;
2130 u32 bt_edca_ul;
2131 u32 bt_edca_dl;
2132
2133 bool init_set;
2134 bool bt_busy_traffic;
2135 bool bt_traffic_mode_set;
2136 bool bt_non_traffic_mode_set;
2137
2138 bool fw_coexist_all_off;
2139 bool sw_coexist_all_off;
2140 bool hw_coexist_all_off;
2141 u32 cstate;
2142 u32 previous_state;
2143 u32 cstate_h;
2144 u32 previous_state_h;
2145
2146 u8 bt_pre_rssi_state;
2147 u8 bt_pre_rssi_state1;
2148
2149 u8 reg_bt_iso;
2150 u8 reg_bt_sco;
2151 bool balance_on;
2152 u8 bt_active_zero_cnt;
2153 bool cur_bt_disabled;
2154 bool pre_bt_disabled;
2155
2156 u8 bt_profile_case;
2157 u8 bt_profile_action;
2158 bool bt_busy;
2159 bool hold_for_bt_operation;
2160 u8 lps_counter;
2161};
2162
2163 2477
2164/**************************************** 2478/****************************************
2165 mem access macro define start 2479 mem access macro define start
diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index 998e95895f9d..a92bd3e89796 100644
--- a/drivers/net/wireless/ti/wilink_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
@@ -23,17 +23,17 @@
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/wl12xx.h> 24#include <linux/wl12xx.h>
25 25
26static struct wl12xx_platform_data *platform_data; 26static struct wl12xx_platform_data *wl12xx_platform_data;
27 27
28int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) 28int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
29{ 29{
30 if (platform_data) 30 if (wl12xx_platform_data)
31 return -EBUSY; 31 return -EBUSY;
32 if (!data) 32 if (!data)
33 return -EINVAL; 33 return -EINVAL;
34 34
35 platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); 35 wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
36 if (!platform_data) 36 if (!wl12xx_platform_data)
37 return -ENOMEM; 37 return -ENOMEM;
38 38
39 return 0; 39 return 0;
@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
41 41
42struct wl12xx_platform_data *wl12xx_get_platform_data(void) 42struct wl12xx_platform_data *wl12xx_get_platform_data(void)
43{ 43{
44 if (!platform_data) 44 if (!wl12xx_platform_data)
45 return ERR_PTR(-ENODEV); 45 return ERR_PTR(-ENODEV);
46 46
47 return platform_data; 47 return wl12xx_platform_data;
48} 48}
49EXPORT_SYMBOL(wl12xx_get_platform_data); 49EXPORT_SYMBOL(wl12xx_get_platform_data);
50
51static struct wl1251_platform_data *wl1251_platform_data;
52
53int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
54{
55 if (wl1251_platform_data)
56 return -EBUSY;
57 if (!data)
58 return -EINVAL;
59
60 wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
61 if (!wl1251_platform_data)
62 return -ENOMEM;
63
64 return 0;
65}
66
67struct wl1251_platform_data *wl1251_get_platform_data(void)
68{
69 if (!wl1251_platform_data)
70 return ERR_PTR(-ENODEV);
71
72 return wl1251_platform_data;
73}
74EXPORT_SYMBOL(wl1251_get_platform_data);
diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c
index 223649bcaa5a..bf1fa18b9786 100644
--- a/drivers/net/wireless/ti/wl1251/cmd.c
+++ b/drivers/net/wireless/ti/wl1251/cmd.c
@@ -448,7 +448,7 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
448 * Note: This bug may be caused by the fw's DTIM handling. 448 * Note: This bug may be caused by the fw's DTIM handling.
449 */ 449 */
450 if (is_zero_ether_addr(wl->bssid)) 450 if (is_zero_ether_addr(wl->bssid))
451 cmd->params.scan_options |= WL1251_SCAN_OPT_PRIORITY_HIGH; 451 cmd->params.scan_options |= cpu_to_le16(WL1251_SCAN_OPT_PRIORITY_HIGH);
452 cmd->params.num_channels = n_channels; 452 cmd->params.num_channels = n_channels;
453 cmd->params.num_probe_requests = n_probes; 453 cmd->params.num_probe_requests = n_probes;
454 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ 454 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c
index 123c4bb50e0a..cde0eaf99714 100644
--- a/drivers/net/wireless/ti/wl1251/rx.c
+++ b/drivers/net/wireless/ti/wl1251/rx.c
@@ -180,7 +180,7 @@ static void wl1251_rx_body(struct wl1251 *wl,
180 wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); 180 wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
181 181
182 /* The actual length doesn't include the target's alignment */ 182 /* The actual length doesn't include the target's alignment */
183 skb->len = desc->length - PLCP_HEADER_LENGTH; 183 skb_trim(skb, desc->length - PLCP_HEADER_LENGTH);
184 184
185 fc = (u16 *)skb->data; 185 fc = (u16 *)skb->data;
186 186
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e2b3d9c541e8..b661f896e9fe 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -28,6 +28,7 @@
28#include <linux/wl12xx.h> 28#include <linux/wl12xx.h>
29#include <linux/irq.h> 29#include <linux/irq.h>
30#include <linux/pm_runtime.h> 30#include <linux/pm_runtime.h>
31#include <linux/gpio.h>
31 32
32#include "wl1251.h" 33#include "wl1251.h"
33 34
@@ -182,8 +183,9 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
182 * callback in case it wants to do any additional setup, 183 * callback in case it wants to do any additional setup,
183 * for example enabling clock buffer for the module. 184 * for example enabling clock buffer for the module.
184 */ 185 */
185 if (wl->set_power) 186 if (gpio_is_valid(wl->power_gpio))
186 wl->set_power(true); 187 gpio_set_value(wl->power_gpio, true);
188
187 189
188 ret = pm_runtime_get_sync(&func->dev); 190 ret = pm_runtime_get_sync(&func->dev);
189 if (ret < 0) { 191 if (ret < 0) {
@@ -203,8 +205,8 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
203 if (ret < 0) 205 if (ret < 0)
204 goto out; 206 goto out;
205 207
206 if (wl->set_power) 208 if (gpio_is_valid(wl->power_gpio))
207 wl->set_power(false); 209 gpio_set_value(wl->power_gpio, false);
208 } 210 }
209 211
210out: 212out:
@@ -227,7 +229,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
227 struct wl1251 *wl; 229 struct wl1251 *wl;
228 struct ieee80211_hw *hw; 230 struct ieee80211_hw *hw;
229 struct wl1251_sdio *wl_sdio; 231 struct wl1251_sdio *wl_sdio;
230 const struct wl12xx_platform_data *wl12xx_board_data; 232 const struct wl1251_platform_data *wl1251_board_data;
231 233
232 hw = wl1251_alloc_hw(); 234 hw = wl1251_alloc_hw();
233 if (IS_ERR(hw)) 235 if (IS_ERR(hw))
@@ -254,11 +256,20 @@ static int wl1251_sdio_probe(struct sdio_func *func,
254 wl->if_priv = wl_sdio; 256 wl->if_priv = wl_sdio;
255 wl->if_ops = &wl1251_sdio_ops; 257 wl->if_ops = &wl1251_sdio_ops;
256 258
257 wl12xx_board_data = wl12xx_get_platform_data(); 259 wl1251_board_data = wl1251_get_platform_data();
258 if (!IS_ERR(wl12xx_board_data)) { 260 if (!IS_ERR(wl1251_board_data)) {
259 wl->set_power = wl12xx_board_data->set_power; 261 wl->power_gpio = wl1251_board_data->power_gpio;
260 wl->irq = wl12xx_board_data->irq; 262 wl->irq = wl1251_board_data->irq;
261 wl->use_eeprom = wl12xx_board_data->use_eeprom; 263 wl->use_eeprom = wl1251_board_data->use_eeprom;
264 }
265
266 if (gpio_is_valid(wl->power_gpio)) {
267 ret = devm_gpio_request(&func->dev, wl->power_gpio,
268 "wl1251 power");
269 if (ret) {
270 wl1251_error("Failed to request gpio: %d\n", ret);
271 goto disable;
272 }
262 } 273 }
263 274
264 if (wl->irq) { 275 if (wl->irq) {
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 1342f81e683d..b06d36d99362 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -26,6 +26,10 @@
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/wl12xx.h> 28#include <linux/wl12xx.h>
29#include <linux/gpio.h>
30#include <linux/of.h>
31#include <linux/of_gpio.h>
32#include <linux/regulator/consumer.h>
29 33
30#include "wl1251.h" 34#include "wl1251.h"
31#include "reg.h" 35#include "reg.h"
@@ -221,8 +225,8 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl)
221 225
222static int wl1251_spi_set_power(struct wl1251 *wl, bool enable) 226static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
223{ 227{
224 if (wl->set_power) 228 if (gpio_is_valid(wl->power_gpio))
225 wl->set_power(enable); 229 gpio_set_value(wl->power_gpio, enable);
226 230
227 return 0; 231 return 0;
228} 232}
@@ -238,13 +242,13 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
238 242
239static int wl1251_spi_probe(struct spi_device *spi) 243static int wl1251_spi_probe(struct spi_device *spi)
240{ 244{
241 struct wl12xx_platform_data *pdata; 245 struct wl1251_platform_data *pdata = dev_get_platdata(&spi->dev);
246 struct device_node *np = spi->dev.of_node;
242 struct ieee80211_hw *hw; 247 struct ieee80211_hw *hw;
243 struct wl1251 *wl; 248 struct wl1251 *wl;
244 int ret; 249 int ret;
245 250
246 pdata = dev_get_platdata(&spi->dev); 251 if (!np && !pdata) {
247 if (!pdata) {
248 wl1251_error("no platform data"); 252 wl1251_error("no platform data");
249 return -ENODEV; 253 return -ENODEV;
250 } 254 }
@@ -271,22 +275,42 @@ static int wl1251_spi_probe(struct spi_device *spi)
271 goto out_free; 275 goto out_free;
272 } 276 }
273 277
274 wl->set_power = pdata->set_power; 278 if (np) {
275 if (!wl->set_power) { 279 wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom");
276 wl1251_error("set power function missing in platform data"); 280 wl->power_gpio = of_get_named_gpio(np, "ti,power-gpio", 0);
277 return -ENODEV; 281 } else if (pdata) {
282 wl->power_gpio = pdata->power_gpio;
283 wl->use_eeprom = pdata->use_eeprom;
284 }
285
286 if (wl->power_gpio == -EPROBE_DEFER) {
287 ret = -EPROBE_DEFER;
288 goto out_free;
289 }
290
291 if (gpio_is_valid(wl->power_gpio)) {
292 ret = devm_gpio_request_one(&spi->dev, wl->power_gpio,
293 GPIOF_OUT_INIT_LOW, "wl1251 power");
294 if (ret) {
295 wl1251_error("Failed to request gpio: %d\n", ret);
296 goto out_free;
297 }
298 } else {
299 wl1251_error("set power gpio missing in platform data");
300 ret = -ENODEV;
301 goto out_free;
278 } 302 }
279 303
280 wl->irq = spi->irq; 304 wl->irq = spi->irq;
281 if (wl->irq < 0) { 305 if (wl->irq < 0) {
282 wl1251_error("irq missing in platform data"); 306 wl1251_error("irq missing in platform data");
283 return -ENODEV; 307 ret = -ENODEV;
308 goto out_free;
284 } 309 }
285 310
286 wl->use_eeprom = pdata->use_eeprom;
287
288 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); 311 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
289 ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); 312 ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0,
313 DRIVER_NAME, wl);
290 if (ret < 0) { 314 if (ret < 0) {
291 wl1251_error("request_irq() failed: %d", ret); 315 wl1251_error("request_irq() failed: %d", ret);
292 goto out_free; 316 goto out_free;
@@ -294,16 +318,26 @@ static int wl1251_spi_probe(struct spi_device *spi)
294 318
295 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); 319 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
296 320
321 wl->vio = devm_regulator_get(&spi->dev, "vio");
322 if (IS_ERR(wl->vio)) {
323 ret = PTR_ERR(wl->vio);
324 wl1251_error("vio regulator missing: %d", ret);
325 goto out_free;
326 }
327
328 ret = regulator_enable(wl->vio);
329 if (ret)
330 goto out_free;
331
297 ret = wl1251_init_ieee80211(wl); 332 ret = wl1251_init_ieee80211(wl);
298 if (ret) 333 if (ret)
299 goto out_irq; 334 goto disable_regulator;
300 335
301 return 0; 336 return 0;
302 337
303 out_irq: 338disable_regulator:
304 free_irq(wl->irq, wl); 339 regulator_disable(wl->vio);
305 340out_free:
306 out_free:
307 ieee80211_free_hw(hw); 341 ieee80211_free_hw(hw);
308 342
309 return ret; 343 return ret;
@@ -315,6 +349,7 @@ static int wl1251_spi_remove(struct spi_device *spi)
315 349
316 free_irq(wl->irq, wl); 350 free_irq(wl->irq, wl);
317 wl1251_free_hw(wl); 351 wl1251_free_hw(wl);
352 regulator_disable(wl->vio);
318 353
319 return 0; 354 return 0;
320} 355}
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 235617a7716d..16dae5269175 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -276,10 +276,12 @@ struct wl1251 {
276 void *if_priv; 276 void *if_priv;
277 const struct wl1251_if_operations *if_ops; 277 const struct wl1251_if_operations *if_ops;
278 278
279 void (*set_power)(bool enable); 279 int power_gpio;
280 int irq; 280 int irq;
281 bool use_eeprom; 281 bool use_eeprom;
282 282
283 struct regulator *vio;
284
283 spinlock_t wl_lock; 285 spinlock_t wl_lock;
284 286
285 enum wl1251_state state; 287 enum wl1251_state state;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 7aae5b3a0c2c..ed88d3913483 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -800,7 +800,7 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
800 size_t len; 800 size_t len;
801 801
802 /* Make sure we have enough room */ 802 /* Make sure we have enough room */
803 len = min(maxlen, (size_t)(PAGE_SIZE - wl->fwlog_size)); 803 len = min_t(size_t, maxlen, PAGE_SIZE - wl->fwlog_size);
804 804
805 /* Fill the FW log file, consumed by the sysfs fwlog entry */ 805 /* Fill the FW log file, consumed by the sysfs fwlog entry */
806 memcpy(wl->fwlog + wl->fwlog_size, memblock, len); 806 memcpy(wl->fwlog + wl->fwlog_size, memblock, len);
@@ -3668,8 +3668,8 @@ out:
3668 return ret; 3668 return ret;
3669} 3669}
3670 3670
3671static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, 3671static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
3672 struct ieee80211_vif *vif) 3672 struct ieee80211_vif *vif)
3673{ 3673{
3674 struct wl1271 *wl = hw->priv; 3674 struct wl1271 *wl = hw->priv;
3675 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 3675 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
@@ -3691,6 +3691,8 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
3691 wl1271_ps_elp_sleep(wl); 3691 wl1271_ps_elp_sleep(wl);
3692out: 3692out:
3693 mutex_unlock(&wl->mutex); 3693 mutex_unlock(&wl->mutex);
3694
3695 return 0;
3694} 3696}
3695 3697
3696static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) 3698static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index b2c018dccf18..dbe826dd7c23 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -211,7 +211,7 @@ static int __must_check wl12xx_spi_raw_read(struct device *child, int addr,
211 u32 chunk_len; 211 u32 chunk_len;
212 212
213 while (len > 0) { 213 while (len > 0) {
214 chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); 214 chunk_len = min_t(size_t, WSPI_MAX_CHUNK_SIZE, len);
215 215
216 cmd = &wl->buffer_cmd; 216 cmd = &wl->buffer_cmd;
217 busy_buf = wl->buffer_busyword; 217 busy_buf = wl->buffer_busyword;
@@ -285,7 +285,7 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
285 cmd = &commands[0]; 285 cmd = &commands[0];
286 i = 0; 286 i = 0;
287 while (len > 0) { 287 while (len > 0) {
288 chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); 288 chunk_len = min_t(size_t, WSPI_MAX_CHUNK_SIZE, len);
289 289
290 *cmd = 0; 290 *cmd = 0;
291 *cmd |= WSPI_CMD_WRITE; 291 *cmd |= WSPI_CMD_WRITE;
diff --git a/drivers/net/wireless/ti/wlcore/sysfs.c b/drivers/net/wireless/ti/wlcore/sysfs.c
index 8e583497940d..24dd288d6809 100644
--- a/drivers/net/wireless/ti/wlcore/sysfs.c
+++ b/drivers/net/wireless/ti/wlcore/sysfs.c
@@ -152,7 +152,7 @@ static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj,
152 } 152 }
153 153
154 /* Seeking is not supported - old logs are not kept. Disregard pos. */ 154 /* Seeking is not supported - old logs are not kept. Disregard pos. */
155 len = min(count, (size_t)wl->fwlog_size); 155 len = min_t(size_t, count, wl->fwlog_size);
156 wl->fwlog_size -= len; 156 wl->fwlog_size -= len;
157 memcpy(buffer, wl->fwlog, len); 157 memcpy(buffer, wl->fwlog, len);
158 158
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index d24d4a958c67..d5c371d77ddf 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -42,8 +42,7 @@
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/string.h> 43#include <linux/string.h>
44#include <linux/wireless.h> 44#include <linux/wireless.h>
45#include <linux/ieee80211.h> 45#include <net/cfg80211.h>
46#include <linux/etherdevice.h>
47 46
48#include <net/iw_handler.h> 47#include <net/iw_handler.h>
49 48
@@ -1454,7 +1453,8 @@ static int wl3501_get_freq(struct net_device *dev, struct iw_request_info *info,
1454{ 1453{
1455 struct wl3501_card *this = netdev_priv(dev); 1454 struct wl3501_card *this = netdev_priv(dev);
1456 1455
1457 wrqu->freq.m = ieee80211_dsss_chan_to_freq(this->chan) * 100000; 1456 wrqu->freq.m = 100000 *
1457 ieee80211_channel_to_frequency(this->chan, IEEE80211_BAND_2GHZ);
1458 wrqu->freq.e = 1; 1458 wrqu->freq.e = 1;
1459 return 0; 1459 return 0;
1460} 1460}
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index d39c4178c33a..6f5c793a7855 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -18,7 +18,7 @@
18#include <linux/netdevice.h> 18#include <linux/netdevice.h>
19#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
20#include <linux/wireless.h> 20#include <linux/wireless.h>
21#include <linux/ieee80211.h> 21#include <net/cfg80211.h>
22#include <net/iw_handler.h> 22#include <net/iw_handler.h>
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/if_arp.h> 24#include <linux/if_arp.h>
@@ -914,11 +914,8 @@ static int zd1201_set_freq(struct net_device *dev,
914 914
915 if (freq->e == 0) 915 if (freq->e == 0)
916 channel = freq->m; 916 channel = freq->m;
917 else { 917 else
918 channel = ieee80211_freq_to_dsss_chan(freq->m); 918 channel = ieee80211_frequency_to_channel(freq->m);
919 if (channel < 0)
920 channel = 0;
921 }
922 919
923 err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel); 920 err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel);
924 if (err) 921 if (err)
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/trx.c b/drivers/staging/rtl8821ae/rtl8821ae/trx.c
index 75ae4387fe19..963b55f661c8 100644
--- a/drivers/staging/rtl8821ae/rtl8821ae/trx.c
+++ b/drivers/staging/rtl8821ae/rtl8821ae/trx.c
@@ -616,7 +616,7 @@ bool rtl8821ae_rx_query_desc(struct ieee80211_hw *hw,
616 return false; 616 return false;
617 } 617 }
618 618
619 if ((ieee80211_is_robust_mgmt_frame(hdr)) && 619 if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
620 (ieee80211_has_protected(hdr->frame_control))) 620 (ieee80211_has_protected(hdr->frame_control)))
621 rx_status->flag &= ~RX_FLAG_DECRYPTED; 621 rx_status->flag &= ~RX_FLAG_DECRYPTED;
622 else 622 else
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c
index a7d24c95191d..7dd2b95416e8 100644
--- a/drivers/staging/wlan-ng/cfg80211.c
+++ b/drivers/staging/wlan-ng/cfg80211.c
@@ -416,7 +416,7 @@ static int prism2_scan(struct wiphy *wiphy,
416 memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len); 416 memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len);
417 bss = cfg80211_inform_bss(wiphy, 417 bss = cfg80211_inform_bss(wiphy,
418 ieee80211_get_channel(wiphy, 418 ieee80211_get_channel(wiphy,
419 ieee80211_dsss_chan_to_freq(msg2.dschannel.data)), 419 ieee80211_channel_to_frequency(msg2.dschannel.data, IEEE80211_BAND_2GHZ)),
420 (const u8 *) &(msg2.bssid.data.data), 420 (const u8 *) &(msg2.bssid.data.data),
421 msg2.timestamp.data, msg2.capinfo.data, 421 msg2.timestamp.data, msg2.capinfo.data,
422 msg2.beaconperiod.data, 422 msg2.beaconperiod.data,
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 5f349355ee54..06299048c4f4 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2308,42 +2308,6 @@ static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr,
2308} 2308}
2309 2309
2310/** 2310/**
2311 * ieee80211_dsss_chan_to_freq - get channel center frequency
2312 * @channel: the DSSS channel
2313 *
2314 * Convert IEEE802.11 DSSS channel to the center frequency (MHz).
2315 * Ref IEEE 802.11-2007 section 15.6
2316 */
2317static inline int ieee80211_dsss_chan_to_freq(int channel)
2318{
2319 if ((channel > 0) && (channel < 14))
2320 return 2407 + (channel * 5);
2321 else if (channel == 14)
2322 return 2484;
2323 else
2324 return -1;
2325}
2326
2327/**
2328 * ieee80211_freq_to_dsss_chan - get channel
2329 * @freq: the frequency
2330 *
2331 * Convert frequency (MHz) to IEEE802.11 DSSS channel
2332 * Ref IEEE 802.11-2007 section 15.6
2333 *
2334 * This routine selects the channel with the closest center frequency.
2335 */
2336static inline int ieee80211_freq_to_dsss_chan(int freq)
2337{
2338 if ((freq >= 2410) && (freq < 2475))
2339 return (freq - 2405) / 5;
2340 else if ((freq >= 2482) && (freq < 2487))
2341 return 14;
2342 else
2343 return -1;
2344}
2345
2346/**
2347 * ieee80211_tu_to_usec - convert time units (TU) to microseconds 2311 * ieee80211_tu_to_usec - convert time units (TU) to microseconds
2348 * @tu: the TUs 2312 * @tu: the TUs
2349 */ 2313 */
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 3737f7218f51..7bb6148d990f 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -23,6 +23,7 @@
23#define TEMP_MINOR 131 /* Temperature Sensor */ 23#define TEMP_MINOR 131 /* Temperature Sensor */
24#define RTC_MINOR 135 24#define RTC_MINOR 135
25#define EFI_RTC_MINOR 136 /* EFI Time services */ 25#define EFI_RTC_MINOR 136 /* EFI Time services */
26#define VHCI_MINOR 137
26#define SUN_OPENPROM_MINOR 139 27#define SUN_OPENPROM_MINOR 139
27#define DMAPI_MINOR 140 /* DMAPI */ 28#define DMAPI_MINOR 140 /* DMAPI */
28#define NVRAM_MINOR 144 29#define NVRAM_MINOR 144
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 90b4fdc8a61f..4781d7b27dd3 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -518,9 +518,9 @@ extern void tty_port_put(struct tty_port *port);
518 518
519static inline struct tty_port *tty_port_get(struct tty_port *port) 519static inline struct tty_port *tty_port_get(struct tty_port *port)
520{ 520{
521 if (port) 521 if (port && kref_get_unless_zero(&port->kref))
522 kref_get(&port->kref); 522 return port;
523 return port; 523 return NULL;
524} 524}
525 525
526/* If the cts flow control is enabled, return true. */ 526/* If the cts flow control is enabled, return true. */
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index a54fe82e704b..a9c723be1acf 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -48,11 +48,15 @@ enum {
48 WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */ 48 WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */
49}; 49};
50 50
51struct wl12xx_platform_data { 51struct wl1251_platform_data {
52 void (*set_power)(bool enable); 52 int power_gpio;
53 /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ 53 /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
54 int irq; 54 int irq;
55 bool use_eeprom; 55 bool use_eeprom;
56};
57
58struct wl12xx_platform_data {
59 int irq;
56 int board_ref_clock; 60 int board_ref_clock;
57 int board_tcxo_clock; 61 int board_tcxo_clock;
58 unsigned long platform_quirks; 62 unsigned long platform_quirks;
@@ -68,6 +72,10 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
68 72
69struct wl12xx_platform_data *wl12xx_get_platform_data(void); 73struct wl12xx_platform_data *wl12xx_get_platform_data(void);
70 74
75int wl1251_set_platform_data(const struct wl1251_platform_data *data);
76
77struct wl1251_platform_data *wl1251_get_platform_data(void);
78
71#else 79#else
72 80
73static inline 81static inline
@@ -82,6 +90,18 @@ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
82 return ERR_PTR(-ENODATA); 90 return ERR_PTR(-ENODATA);
83} 91}
84 92
93static inline
94int wl1251_set_platform_data(const struct wl1251_platform_data *data)
95{
96 return -ENOSYS;
97}
98
99static inline
100struct wl1251_platform_data *wl1251_get_platform_data(void)
101{
102 return ERR_PTR(-ENODATA);
103}
104
85#endif 105#endif
86 106
87#endif 107#endif
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index f4f9ee466791..904777c1cd24 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -65,6 +65,7 @@ struct bt_security {
65#define BT_SECURITY_LOW 1 65#define BT_SECURITY_LOW 1
66#define BT_SECURITY_MEDIUM 2 66#define BT_SECURITY_MEDIUM 2
67#define BT_SECURITY_HIGH 3 67#define BT_SECURITY_HIGH 3
68#define BT_SECURITY_FIPS 4
68 69
69#define BT_DEFER_SETUP 7 70#define BT_DEFER_SETUP 7
70 71
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 66c1cd87bfe7..be150cf8cd43 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -117,11 +117,18 @@ enum {
117 HCI_SERVICE_CACHE, 117 HCI_SERVICE_CACHE,
118 HCI_DEBUG_KEYS, 118 HCI_DEBUG_KEYS,
119 HCI_DUT_MODE, 119 HCI_DUT_MODE,
120 HCI_FORCE_SC,
121 HCI_FORCE_STATIC_ADDR,
120 HCI_UNREGISTER, 122 HCI_UNREGISTER,
121 HCI_USER_CHANNEL, 123 HCI_USER_CHANNEL,
122 124
123 HCI_LE_SCAN, 125 HCI_LE_SCAN,
124 HCI_SSP_ENABLED, 126 HCI_SSP_ENABLED,
127 HCI_SC_ENABLED,
128 HCI_SC_ONLY,
129 HCI_PRIVACY,
130 HCI_RPA_EXPIRED,
131 HCI_RPA_RESOLVING,
125 HCI_HS_ENABLED, 132 HCI_HS_ENABLED,
126 HCI_LE_ENABLED, 133 HCI_LE_ENABLED,
127 HCI_ADVERTISING, 134 HCI_ADVERTISING,
@@ -133,6 +140,7 @@ enum {
133 HCI_FAST_CONNECTABLE, 140 HCI_FAST_CONNECTABLE,
134 HCI_BREDR_ENABLED, 141 HCI_BREDR_ENABLED,
135 HCI_6LOWPAN_ENABLED, 142 HCI_6LOWPAN_ENABLED,
143 HCI_LE_SCAN_INTERRUPTED,
136}; 144};
137 145
138/* A mask for the flags that are supposed to remain when a reset happens 146/* A mask for the flags that are supposed to remain when a reset happens
@@ -175,6 +183,8 @@ enum {
175#define HCI_CMD_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ 183#define HCI_CMD_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
176#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ 184#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */
177#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ 185#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
186#define HCI_POWER_OFF_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */
187#define HCI_LE_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */
178 188
179/* HCI data types */ 189/* HCI data types */
180#define HCI_COMMAND_PKT 0x01 190#define HCI_COMMAND_PKT 0x01
@@ -282,10 +292,14 @@ enum {
282#define LMP_SYNC_TRAIN 0x04 292#define LMP_SYNC_TRAIN 0x04
283#define LMP_SYNC_SCAN 0x08 293#define LMP_SYNC_SCAN 0x08
284 294
295#define LMP_SC 0x01
296#define LMP_PING 0x02
297
285/* Host features */ 298/* Host features */
286#define LMP_HOST_SSP 0x01 299#define LMP_HOST_SSP 0x01
287#define LMP_HOST_LE 0x02 300#define LMP_HOST_LE 0x02
288#define LMP_HOST_LE_BREDR 0x04 301#define LMP_HOST_LE_BREDR 0x04
302#define LMP_HOST_SC 0x08
289 303
290/* Connection modes */ 304/* Connection modes */
291#define HCI_CM_ACTIVE 0x0000 305#define HCI_CM_ACTIVE 0x0000
@@ -307,6 +321,7 @@ enum {
307#define HCI_LM_TRUSTED 0x0008 321#define HCI_LM_TRUSTED 0x0008
308#define HCI_LM_RELIABLE 0x0010 322#define HCI_LM_RELIABLE 0x0010
309#define HCI_LM_SECURE 0x0020 323#define HCI_LM_SECURE 0x0020
324#define HCI_LM_FIPS 0x0040
310 325
311/* Authentication types */ 326/* Authentication types */
312#define HCI_AT_NO_BONDING 0x00 327#define HCI_AT_NO_BONDING 0x00
@@ -327,17 +342,24 @@ enum {
327#define HCI_LK_LOCAL_UNIT 0x01 342#define HCI_LK_LOCAL_UNIT 0x01
328#define HCI_LK_REMOTE_UNIT 0x02 343#define HCI_LK_REMOTE_UNIT 0x02
329#define HCI_LK_DEBUG_COMBINATION 0x03 344#define HCI_LK_DEBUG_COMBINATION 0x03
330#define HCI_LK_UNAUTH_COMBINATION 0x04 345#define HCI_LK_UNAUTH_COMBINATION_P192 0x04
331#define HCI_LK_AUTH_COMBINATION 0x05 346#define HCI_LK_AUTH_COMBINATION_P192 0x05
332#define HCI_LK_CHANGED_COMBINATION 0x06 347#define HCI_LK_CHANGED_COMBINATION 0x06
348#define HCI_LK_UNAUTH_COMBINATION_P256 0x07
349#define HCI_LK_AUTH_COMBINATION_P256 0x08
333/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */ 350/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
334#define HCI_SMP_STK 0x80 351#define HCI_SMP_STK 0x80
335#define HCI_SMP_STK_SLAVE 0x81 352#define HCI_SMP_STK_SLAVE 0x81
336#define HCI_SMP_LTK 0x82 353#define HCI_SMP_LTK 0x82
337#define HCI_SMP_LTK_SLAVE 0x83 354#define HCI_SMP_LTK_SLAVE 0x83
338 355
356/* Long Term Key types */
357#define HCI_LTK_UNAUTH 0x00
358#define HCI_LTK_AUTH 0x01
359
339/* ---- HCI Error Codes ---- */ 360/* ---- HCI Error Codes ---- */
340#define HCI_ERROR_AUTH_FAILURE 0x05 361#define HCI_ERROR_AUTH_FAILURE 0x05
362#define HCI_ERROR_MEMORY_EXCEEDED 0x07
341#define HCI_ERROR_CONNECTION_TIMEOUT 0x08 363#define HCI_ERROR_CONNECTION_TIMEOUT 0x08
342#define HCI_ERROR_REJ_BAD_ADDR 0x0f 364#define HCI_ERROR_REJ_BAD_ADDR 0x0f
343#define HCI_ERROR_REMOTE_USER_TERM 0x13 365#define HCI_ERROR_REMOTE_USER_TERM 0x13
@@ -660,6 +682,15 @@ struct hci_rp_set_csb {
660 682
661#define HCI_OP_START_SYNC_TRAIN 0x0443 683#define HCI_OP_START_SYNC_TRAIN 0x0443
662 684
685#define HCI_OP_REMOTE_OOB_EXT_DATA_REPLY 0x0445
686struct hci_cp_remote_oob_ext_data_reply {
687 bdaddr_t bdaddr;
688 __u8 hash192[16];
689 __u8 randomizer192[16];
690 __u8 hash256[16];
691 __u8 randomizer256[16];
692} __packed;
693
663#define HCI_OP_SNIFF_MODE 0x0803 694#define HCI_OP_SNIFF_MODE 0x0803
664struct hci_cp_sniff_mode { 695struct hci_cp_sniff_mode {
665 __le16 handle; 696 __le16 handle;
@@ -933,6 +964,26 @@ struct hci_rp_write_sync_train_params {
933 __le16 sync_train_int; 964 __le16 sync_train_int;
934} __packed; 965} __packed;
935 966
967#define HCI_OP_READ_SC_SUPPORT 0x0c79
968struct hci_rp_read_sc_support {
969 __u8 status;
970 __u8 support;
971} __packed;
972
973#define HCI_OP_WRITE_SC_SUPPORT 0x0c7a
974struct hci_cp_write_sc_support {
975 __u8 support;
976} __packed;
977
978#define HCI_OP_READ_LOCAL_OOB_EXT_DATA 0x0c7d
979struct hci_rp_read_local_oob_ext_data {
980 __u8 status;
981 __u8 hash192[16];
982 __u8 randomizer192[16];
983 __u8 hash256[16];
984 __u8 randomizer256[16];
985} __packed;
986
936#define HCI_OP_READ_LOCAL_VERSION 0x1001 987#define HCI_OP_READ_LOCAL_VERSION 0x1001
937struct hci_rp_read_local_version { 988struct hci_rp_read_local_version {
938 __u8 status; 989 __u8 status;
@@ -1133,6 +1184,9 @@ struct hci_cp_le_set_scan_enable {
1133 __u8 filter_dup; 1184 __u8 filter_dup;
1134} __packed; 1185} __packed;
1135 1186
1187#define HCI_LE_USE_PEER_ADDR 0x00
1188#define HCI_LE_USE_WHITELIST 0x01
1189
1136#define HCI_OP_LE_CREATE_CONN 0x200d 1190#define HCI_OP_LE_CREATE_CONN 0x200d
1137struct hci_cp_le_create_conn { 1191struct hci_cp_le_create_conn {
1138 __le16 scan_interval; 1192 __le16 scan_interval;
@@ -1157,6 +1211,20 @@ struct hci_rp_le_read_white_list_size {
1157 __u8 size; 1211 __u8 size;
1158} __packed; 1212} __packed;
1159 1213
1214#define HCI_OP_LE_CLEAR_WHITE_LIST 0x2010
1215
1216#define HCI_OP_LE_ADD_TO_WHITE_LIST 0x2011
1217struct hci_cp_le_add_to_white_list {
1218 __u8 bdaddr_type;
1219 bdaddr_t bdaddr;
1220} __packed;
1221
1222#define HCI_OP_LE_DEL_FROM_WHITE_LIST 0x2012
1223struct hci_cp_le_del_from_white_list {
1224 __u8 bdaddr_type;
1225 bdaddr_t bdaddr;
1226} __packed;
1227
1160#define HCI_OP_LE_CONN_UPDATE 0x2013 1228#define HCI_OP_LE_CONN_UPDATE 0x2013
1161struct hci_cp_le_conn_update { 1229struct hci_cp_le_conn_update {
1162 __le16 handle; 1230 __le16 handle;
@@ -1171,7 +1239,7 @@ struct hci_cp_le_conn_update {
1171#define HCI_OP_LE_START_ENC 0x2019 1239#define HCI_OP_LE_START_ENC 0x2019
1172struct hci_cp_le_start_enc { 1240struct hci_cp_le_start_enc {
1173 __le16 handle; 1241 __le16 handle;
1174 __u8 rand[8]; 1242 __le64 rand;
1175 __le16 ediv; 1243 __le16 ediv;
1176 __u8 ltk[16]; 1244 __u8 ltk[16];
1177} __packed; 1245} __packed;
@@ -1583,7 +1651,7 @@ struct hci_ev_le_conn_complete {
1583#define HCI_EV_LE_LTK_REQ 0x05 1651#define HCI_EV_LE_LTK_REQ 0x05
1584struct hci_ev_le_ltk_req { 1652struct hci_ev_le_ltk_req {
1585 __le16 handle; 1653 __le16 handle;
1586 __u8 random[8]; 1654 __le64 rand;
1587 __le16 ediv; 1655 __le16 ediv;
1588} __packed; 1656} __packed;
1589 1657
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f2f0cf5865c4..dbb788e4f265 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -99,9 +99,17 @@ struct smp_ltk {
99 u8 type; 99 u8 type;
100 u8 enc_size; 100 u8 enc_size;
101 __le16 ediv; 101 __le16 ediv;
102 u8 rand[8]; 102 __le64 rand;
103 u8 val[16]; 103 u8 val[16];
104} __packed; 104};
105
106struct smp_irk {
107 struct list_head list;
108 bdaddr_t rpa;
109 bdaddr_t bdaddr;
110 u8 addr_type;
111 u8 val[16];
112};
105 113
106struct link_key { 114struct link_key {
107 struct list_head list; 115 struct list_head list;
@@ -114,12 +122,17 @@ struct link_key {
114struct oob_data { 122struct oob_data {
115 struct list_head list; 123 struct list_head list;
116 bdaddr_t bdaddr; 124 bdaddr_t bdaddr;
117 u8 hash[16]; 125 u8 hash192[16];
118 u8 randomizer[16]; 126 u8 randomizer192[16];
127 u8 hash256[16];
128 u8 randomizer256[16];
119}; 129};
120 130
121#define HCI_MAX_SHORT_NAME_LENGTH 10 131#define HCI_MAX_SHORT_NAME_LENGTH 10
122 132
133/* Default LE RPA expiry time, 15 minutes */
134#define HCI_DEFAULT_RPA_TIMEOUT (15 * 60)
135
123struct amp_assoc { 136struct amp_assoc {
124 __u16 len; 137 __u16 len;
125 __u16 offset; 138 __u16 offset;
@@ -141,8 +154,9 @@ struct hci_dev {
141 __u8 bus; 154 __u8 bus;
142 __u8 dev_type; 155 __u8 dev_type;
143 bdaddr_t bdaddr; 156 bdaddr_t bdaddr;
157 bdaddr_t random_addr;
144 bdaddr_t static_addr; 158 bdaddr_t static_addr;
145 __u8 own_addr_type; 159 __u8 adv_addr_type;
146 __u8 dev_name[HCI_MAX_NAME_LENGTH]; 160 __u8 dev_name[HCI_MAX_NAME_LENGTH];
147 __u8 short_name[HCI_MAX_SHORT_NAME_LENGTH]; 161 __u8 short_name[HCI_MAX_SHORT_NAME_LENGTH];
148 __u8 eir[HCI_MAX_EIR_LENGTH]; 162 __u8 eir[HCI_MAX_EIR_LENGTH];
@@ -167,6 +181,7 @@ struct hci_dev {
167 __u16 page_scan_interval; 181 __u16 page_scan_interval;
168 __u16 page_scan_window; 182 __u16 page_scan_window;
169 __u8 page_scan_type; 183 __u8 page_scan_type;
184 __u8 le_adv_channel_map;
170 __u16 le_scan_interval; 185 __u16 le_scan_interval;
171 __u16 le_scan_window; 186 __u16 le_scan_window;
172 __u16 le_conn_min_interval; 187 __u16 le_conn_min_interval;
@@ -257,19 +272,21 @@ struct hci_dev {
257 __u32 req_status; 272 __u32 req_status;
258 __u32 req_result; 273 __u32 req_result;
259 274
260 struct list_head mgmt_pending; 275 struct crypto_blkcipher *tfm_aes;
261 276
262 struct discovery_state discovery; 277 struct discovery_state discovery;
263 struct hci_conn_hash conn_hash; 278 struct hci_conn_hash conn_hash;
264 struct list_head blacklist;
265 279
280 struct list_head mgmt_pending;
281 struct list_head blacklist;
266 struct list_head uuids; 282 struct list_head uuids;
267
268 struct list_head link_keys; 283 struct list_head link_keys;
269
270 struct list_head long_term_keys; 284 struct list_head long_term_keys;
271 285 struct list_head identity_resolving_keys;
272 struct list_head remote_oob_data; 286 struct list_head remote_oob_data;
287 struct list_head le_white_list;
288 struct list_head le_conn_params;
289 struct list_head pend_le_conns;
273 290
274 struct hci_dev_stats stat; 291 struct hci_dev_stats stat;
275 292
@@ -291,6 +308,11 @@ struct hci_dev {
291 __u8 scan_rsp_data[HCI_MAX_AD_LENGTH]; 308 __u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
292 __u8 scan_rsp_data_len; 309 __u8 scan_rsp_data_len;
293 310
311 __u8 irk[16];
312 __u32 rpa_timeout;
313 struct delayed_work rpa_expired;
314 bdaddr_t rpa;
315
294 int (*open)(struct hci_dev *hdev); 316 int (*open)(struct hci_dev *hdev);
295 int (*close)(struct hci_dev *hdev); 317 int (*close)(struct hci_dev *hdev);
296 int (*flush)(struct hci_dev *hdev); 318 int (*flush)(struct hci_dev *hdev);
@@ -310,6 +332,10 @@ struct hci_conn {
310 __u8 dst_type; 332 __u8 dst_type;
311 bdaddr_t src; 333 bdaddr_t src;
312 __u8 src_type; 334 __u8 src_type;
335 bdaddr_t init_addr;
336 __u8 init_addr_type;
337 bdaddr_t resp_addr;
338 __u8 resp_addr_type;
313 __u16 handle; 339 __u16 handle;
314 __u16 state; 340 __u16 state;
315 __u8 mode; 341 __u8 mode;
@@ -332,6 +358,8 @@ struct hci_conn {
332 __u8 passkey_entered; 358 __u8 passkey_entered;
333 __u16 disc_timeout; 359 __u16 disc_timeout;
334 __u16 setting; 360 __u16 setting;
361 __u16 le_conn_min_interval;
362 __u16 le_conn_max_interval;
335 unsigned long flags; 363 unsigned long flags;
336 364
337 __u8 remote_cap; 365 __u8 remote_cap;
@@ -347,6 +375,7 @@ struct hci_conn {
347 struct delayed_work disc_work; 375 struct delayed_work disc_work;
348 struct delayed_work auto_accept_work; 376 struct delayed_work auto_accept_work;
349 struct delayed_work idle_work; 377 struct delayed_work idle_work;
378 struct delayed_work le_conn_timeout;
350 379
351 struct device dev; 380 struct device dev;
352 381
@@ -372,6 +401,22 @@ struct hci_chan {
372 __u8 state; 401 __u8 state;
373}; 402};
374 403
404struct hci_conn_params {
405 struct list_head list;
406
407 bdaddr_t addr;
408 u8 addr_type;
409
410 u16 conn_min_interval;
411 u16 conn_max_interval;
412
413 enum {
414 HCI_AUTO_CONN_DISABLED,
415 HCI_AUTO_CONN_ALWAYS,
416 HCI_AUTO_CONN_LINK_LOSS,
417 } auto_connect;
418};
419
375extern struct list_head hci_dev_list; 420extern struct list_head hci_dev_list;
376extern struct list_head hci_cb_list; 421extern struct list_head hci_cb_list;
377extern rwlock_t hci_dev_list_lock; 422extern rwlock_t hci_dev_list_lock;
@@ -446,6 +491,8 @@ enum {
446 HCI_CONN_LE_SMP_PEND, 491 HCI_CONN_LE_SMP_PEND,
447 HCI_CONN_MGMT_CONNECTED, 492 HCI_CONN_MGMT_CONNECTED,
448 HCI_CONN_SSP_ENABLED, 493 HCI_CONN_SSP_ENABLED,
494 HCI_CONN_SC_ENABLED,
495 HCI_CONN_AES_CCM,
449 HCI_CONN_POWER_SAVE, 496 HCI_CONN_POWER_SAVE,
450 HCI_CONN_REMOTE_OOB, 497 HCI_CONN_REMOTE_OOB,
451 HCI_CONN_6LOWPAN, 498 HCI_CONN_6LOWPAN,
@@ -458,6 +505,13 @@ static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
458 test_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 505 test_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
459} 506}
460 507
508static inline bool hci_conn_sc_enabled(struct hci_conn *conn)
509{
510 struct hci_dev *hdev = conn->hdev;
511 return test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
512 test_bit(HCI_CONN_SC_ENABLED, &conn->flags);
513}
514
461static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) 515static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
462{ 516{
463 struct hci_conn_hash *h = &hdev->conn_hash; 517 struct hci_conn_hash *h = &hdev->conn_hash;
@@ -521,6 +575,13 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
521 } 575 }
522} 576}
523 577
578static inline unsigned int hci_conn_count(struct hci_dev *hdev)
579{
580 struct hci_conn_hash *c = &hdev->conn_hash;
581
582 return c->acl_num + c->amp_num + c->sco_num + c->le_num;
583}
584
524static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, 585static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
525 __u16 handle) 586 __u16 handle)
526{ 587{
@@ -594,8 +655,10 @@ void hci_chan_del(struct hci_chan *chan);
594void hci_chan_list_flush(struct hci_conn *conn); 655void hci_chan_list_flush(struct hci_conn *conn);
595struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle); 656struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
596 657
597struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, 658struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
598 __u8 dst_type, __u8 sec_level, __u8 auth_type); 659 u8 dst_type, u8 sec_level, u8 auth_type);
660struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
661 u8 sec_level, u8 auth_type);
599struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, 662struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
600 __u16 setting); 663 __u16 setting);
601int hci_conn_check_link_mode(struct hci_conn *conn); 664int hci_conn_check_link_mode(struct hci_conn *conn);
@@ -606,6 +669,8 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
606 669
607void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); 670void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
608 671
672void hci_le_conn_failed(struct hci_conn *conn, u8 status);
673
609/* 674/*
610 * hci_conn_get() and hci_conn_put() are used to control the life-time of an 675 * hci_conn_get() and hci_conn_put() are used to control the life-time of an
611 * "hci_conn" object. They do not guarantee that the hci_conn object is running, 676 * "hci_conn" object. They do not guarantee that the hci_conn object is running,
@@ -737,31 +802,64 @@ int hci_inquiry(void __user *arg);
737 802
738struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 803struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
739 bdaddr_t *bdaddr, u8 type); 804 bdaddr_t *bdaddr, u8 type);
740int hci_blacklist_clear(struct hci_dev *hdev);
741int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 805int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
742int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 806int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
743 807
744int hci_uuids_clear(struct hci_dev *hdev); 808struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev,
809 bdaddr_t *bdaddr, u8 type);
810void hci_white_list_clear(struct hci_dev *hdev);
811int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
812int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
813
814struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
815 bdaddr_t *addr, u8 addr_type);
816int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
817 u8 auto_connect, u16 conn_min_interval,
818 u16 conn_max_interval);
819void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
820void hci_conn_params_clear(struct hci_dev *hdev);
745 821
746int hci_link_keys_clear(struct hci_dev *hdev); 822struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
823 bdaddr_t *addr, u8 addr_type);
824void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
825void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
826void hci_pend_le_conns_clear(struct hci_dev *hdev);
827
828void hci_update_background_scan(struct hci_dev *hdev);
829
830void hci_uuids_clear(struct hci_dev *hdev);
831
832void hci_link_keys_clear(struct hci_dev *hdev);
747struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 833struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
748int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 834int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
749 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len); 835 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
750struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]); 836struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
751int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 837 bool master);
752 int new_key, u8 authenticated, u8 tk[16], u8 enc_size, 838struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
753 __le16 ediv, u8 rand[8]); 839 u8 addr_type, u8 type, u8 authenticated,
840 u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand);
754struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 841struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
755 u8 addr_type); 842 u8 addr_type, bool master);
756int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr); 843int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type);
757int hci_smp_ltks_clear(struct hci_dev *hdev); 844void hci_smp_ltks_clear(struct hci_dev *hdev);
758int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 845int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
759 846
760int hci_remote_oob_data_clear(struct hci_dev *hdev); 847struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa);
848struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
849 u8 addr_type);
850struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
851 u8 addr_type, u8 val[16], bdaddr_t *rpa);
852void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type);
853void hci_smp_irks_clear(struct hci_dev *hdev);
854
855void hci_remote_oob_data_clear(struct hci_dev *hdev);
761struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 856struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
762 bdaddr_t *bdaddr); 857 bdaddr_t *bdaddr);
763int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 858int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
764 u8 *randomizer); 859 u8 *hash, u8 *randomizer);
860int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
861 u8 *hash192, u8 *randomizer192,
862 u8 *hash256, u8 *randomizer256);
765int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); 863int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
766 864
767void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); 865void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
@@ -803,9 +901,12 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
803#define lmp_csb_slave_capable(dev) ((dev)->features[2][0] & LMP_CSB_SLAVE) 901#define lmp_csb_slave_capable(dev) ((dev)->features[2][0] & LMP_CSB_SLAVE)
804#define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN) 902#define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN)
805#define lmp_sync_scan_capable(dev) ((dev)->features[2][0] & LMP_SYNC_SCAN) 903#define lmp_sync_scan_capable(dev) ((dev)->features[2][0] & LMP_SYNC_SCAN)
904#define lmp_sc_capable(dev) ((dev)->features[2][1] & LMP_SC)
905#define lmp_ping_capable(dev) ((dev)->features[2][1] & LMP_PING)
806 906
807/* ----- Host capabilities ----- */ 907/* ----- Host capabilities ----- */
808#define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP) 908#define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP)
909#define lmp_host_sc_capable(dev) ((dev)->features[1][0] & LMP_HOST_SC)
809#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) 910#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE))
810#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) 911#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
811 912
@@ -1019,6 +1120,26 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
1019 return false; 1120 return false;
1020} 1121}
1021 1122
1123static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
1124{
1125 if (addr_type != 0x01)
1126 return false;
1127
1128 if ((bdaddr->b[5] & 0xc0) == 0x40)
1129 return true;
1130
1131 return false;
1132}
1133
1134static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
1135 bdaddr_t *bdaddr, u8 addr_type)
1136{
1137 if (!hci_bdaddr_is_rpa(bdaddr, addr_type))
1138 return NULL;
1139
1140 return hci_find_irk_by_rpa(hdev, bdaddr);
1141}
1142
1022int hci_register_cb(struct hci_cb *hcb); 1143int hci_register_cb(struct hci_cb *hcb);
1023int hci_unregister_cb(struct hci_cb *hcb); 1144int hci_unregister_cb(struct hci_cb *hcb);
1024 1145
@@ -1040,6 +1161,9 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
1040 const void *param, u8 event); 1161 const void *param, u8 event);
1041void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); 1162void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
1042 1163
1164void hci_req_add_le_scan_disable(struct hci_request *req);
1165void hci_req_add_le_passive_scan(struct hci_request *req);
1166
1043struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 1167struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
1044 const void *param, u32 timeout); 1168 const void *param, u32 timeout);
1045struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 1169struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
@@ -1085,6 +1209,7 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered);
1085void mgmt_discoverable_timeout(struct hci_dev *hdev); 1209void mgmt_discoverable_timeout(struct hci_dev *hdev);
1086void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); 1210void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
1087void mgmt_connectable(struct hci_dev *hdev, u8 connectable); 1211void mgmt_connectable(struct hci_dev *hdev, u8 connectable);
1212void mgmt_advertising(struct hci_dev *hdev, u8 advertising);
1088void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); 1213void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
1089void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, 1214void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
1090 bool persistent); 1215 bool persistent);
@@ -1092,7 +1217,8 @@ void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
1092 u8 addr_type, u32 flags, u8 *name, u8 name_len, 1217 u8 addr_type, u32 flags, u8 *name, u8 name_len,
1093 u8 *dev_class); 1218 u8 *dev_class);
1094void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, 1219void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
1095 u8 link_type, u8 addr_type, u8 reason); 1220 u8 link_type, u8 addr_type, u8 reason,
1221 bool mgmt_connected);
1096void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, 1222void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
1097 u8 link_type, u8 addr_type, u8 status); 1223 u8 link_type, u8 addr_type, u8 status);
1098void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1224void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
@@ -1122,11 +1248,13 @@ void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
1122 u8 addr_type, u8 status); 1248 u8 addr_type, u8 status);
1123void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); 1249void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
1124void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); 1250void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
1251void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
1125void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, 1252void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
1126 u8 status); 1253 u8 status);
1127void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); 1254void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
1128void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, 1255void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
1129 u8 *randomizer, u8 status); 1256 u8 *randomizer192, u8 *hash256,
1257 u8 *randomizer256, u8 status);
1130void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1258void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
1131 u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, 1259 u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
1132 u8 ssp, u8 *eir, u16 eir_len); 1260 u8 ssp, u8 *eir, u16 eir_len);
@@ -1135,8 +1263,10 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
1135void mgmt_discovering(struct hci_dev *hdev, u8 discovering); 1263void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
1136int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 1264int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
1137int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 1265int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
1138void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent); 1266void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key);
1267void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
1139void mgmt_reenable_advertising(struct hci_dev *hdev); 1268void mgmt_reenable_advertising(struct hci_dev *hdev);
1269void mgmt_smp_complete(struct hci_conn *conn, bool complete);
1140 1270
1141/* HCI info for socket */ 1271/* HCI info for socket */
1142#define hci_pi(sk) ((struct hci_pinfo *) sk) 1272#define hci_pi(sk) ((struct hci_pinfo *) sk)
@@ -1168,9 +1298,14 @@ struct hci_sec_filter {
1168 1298
1169void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, 1299void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
1170 u16 latency, u16 to_multiplier); 1300 u16 latency, u16 to_multiplier);
1171void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], 1301void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
1172 __u8 ltk[16]); 1302 __u8 ltk[16]);
1173 1303
1304int hci_update_random_address(struct hci_request *req, bool require_privacy,
1305 u8 *own_addr_type);
1306void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
1307 u8 *bdaddr_type);
1308
1174#define SCO_AIRMODE_MASK 0x0003 1309#define SCO_AIRMODE_MASK 0x0003
1175#define SCO_AIRMODE_CVSD 0x0000 1310#define SCO_AIRMODE_CVSD 0x0000
1176#define SCO_AIRMODE_TRANSP 0x0003 1311#define SCO_AIRMODE_TRANSP 0x0003
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index dbc4a89984ca..4abdcb220e3a 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -91,6 +91,7 @@ struct l2cap_conninfo {
91#define L2CAP_LM_TRUSTED 0x0008 91#define L2CAP_LM_TRUSTED 0x0008
92#define L2CAP_LM_RELIABLE 0x0010 92#define L2CAP_LM_RELIABLE 0x0010
93#define L2CAP_LM_SECURE 0x0020 93#define L2CAP_LM_SECURE 0x0020
94#define L2CAP_LM_FIPS 0x0040
94 95
95/* L2CAP command codes */ 96/* L2CAP command codes */
96#define L2CAP_COMMAND_REJ 0x01 97#define L2CAP_COMMAND_REJ 0x01
@@ -623,6 +624,9 @@ struct l2cap_conn {
623 __u32 rx_len; 624 __u32 rx_len;
624 __u8 tx_ident; 625 __u8 tx_ident;
625 626
627 struct sk_buff_head pending_rx;
628 struct work_struct pending_rx_work;
629
626 __u8 disc_reason; 630 __u8 disc_reason;
627 631
628 struct delayed_work security_timer; 632 struct delayed_work security_timer;
@@ -647,7 +651,7 @@ struct l2cap_user {
647#define L2CAP_CHAN_RAW 1 651#define L2CAP_CHAN_RAW 1
648#define L2CAP_CHAN_CONN_LESS 2 652#define L2CAP_CHAN_CONN_LESS 2
649#define L2CAP_CHAN_CONN_ORIENTED 3 653#define L2CAP_CHAN_CONN_ORIENTED 3
650#define L2CAP_CHAN_CONN_FIX_A2MP 4 654#define L2CAP_CHAN_FIXED 4
651 655
652/* ----- L2CAP socket info ----- */ 656/* ----- L2CAP socket info ----- */
653#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) 657#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
@@ -853,7 +857,6 @@ static inline long l2cap_chan_no_get_sndtimeo(struct l2cap_chan *chan)
853} 857}
854 858
855extern bool disable_ertm; 859extern bool disable_ertm;
856extern bool enable_lecoc;
857 860
858int l2cap_init_sockets(void); 861int l2cap_init_sockets(void);
859void l2cap_cleanup_sockets(void); 862void l2cap_cleanup_sockets(void);
@@ -878,6 +881,7 @@ int l2cap_ertm_init(struct l2cap_chan *chan);
878void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); 881void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
879void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); 882void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
880void l2cap_chan_del(struct l2cap_chan *chan, int err); 883void l2cap_chan_del(struct l2cap_chan *chan, int err);
884void l2cap_conn_update_id_addr(struct hci_conn *hcon);
881void l2cap_send_conn_req(struct l2cap_chan *chan); 885void l2cap_send_conn_req(struct l2cap_chan *chan);
882void l2cap_move_start(struct l2cap_chan *chan); 886void l2cap_move_start(struct l2cap_chan *chan);
883void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, 887void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 518c5c84e39a..0326648fd799 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -94,6 +94,9 @@ struct mgmt_rp_read_index_list {
94#define MGMT_SETTING_HS 0x00000100 94#define MGMT_SETTING_HS 0x00000100
95#define MGMT_SETTING_LE 0x00000200 95#define MGMT_SETTING_LE 0x00000200
96#define MGMT_SETTING_ADVERTISING 0x00000400 96#define MGMT_SETTING_ADVERTISING 0x00000400
97#define MGMT_SETTING_SECURE_CONN 0x00000800
98#define MGMT_SETTING_DEBUG_KEYS 0x00001000
99#define MGMT_SETTING_PRIVACY 0x00002000
97 100
98#define MGMT_OP_READ_INFO 0x0004 101#define MGMT_OP_READ_INFO 0x0004
99#define MGMT_READ_INFO_SIZE 0 102#define MGMT_READ_INFO_SIZE 0
@@ -180,11 +183,11 @@ struct mgmt_cp_load_link_keys {
180 183
181struct mgmt_ltk_info { 184struct mgmt_ltk_info {
182 struct mgmt_addr_info addr; 185 struct mgmt_addr_info addr;
183 __u8 authenticated; 186 __u8 type;
184 __u8 master; 187 __u8 master;
185 __u8 enc_size; 188 __u8 enc_size;
186 __le16 ediv; 189 __le16 ediv;
187 __u8 rand[8]; 190 __le64 rand;
188 __u8 val[16]; 191 __u8 val[16];
189} __packed; 192} __packed;
190 193
@@ -294,6 +297,12 @@ struct mgmt_rp_read_local_oob_data {
294 __u8 hash[16]; 297 __u8 hash[16];
295 __u8 randomizer[16]; 298 __u8 randomizer[16];
296} __packed; 299} __packed;
300struct mgmt_rp_read_local_oob_ext_data {
301 __u8 hash192[16];
302 __u8 randomizer192[16];
303 __u8 hash256[16];
304 __u8 randomizer256[16];
305} __packed;
297 306
298#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0021 307#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0021
299struct mgmt_cp_add_remote_oob_data { 308struct mgmt_cp_add_remote_oob_data {
@@ -302,6 +311,14 @@ struct mgmt_cp_add_remote_oob_data {
302 __u8 randomizer[16]; 311 __u8 randomizer[16];
303} __packed; 312} __packed;
304#define MGMT_ADD_REMOTE_OOB_DATA_SIZE (MGMT_ADDR_INFO_SIZE + 32) 313#define MGMT_ADD_REMOTE_OOB_DATA_SIZE (MGMT_ADDR_INFO_SIZE + 32)
314struct mgmt_cp_add_remote_oob_ext_data {
315 struct mgmt_addr_info addr;
316 __u8 hash192[16];
317 __u8 randomizer192[16];
318 __u8 hash256[16];
319 __u8 randomizer256[16];
320} __packed;
321#define MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE (MGMT_ADDR_INFO_SIZE + 64)
305 322
306#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x0022 323#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x0022
307struct mgmt_cp_remove_remote_oob_data { 324struct mgmt_cp_remove_remote_oob_data {
@@ -369,6 +386,29 @@ struct mgmt_cp_set_scan_params {
369} __packed; 386} __packed;
370#define MGMT_SET_SCAN_PARAMS_SIZE 4 387#define MGMT_SET_SCAN_PARAMS_SIZE 4
371 388
389#define MGMT_OP_SET_SECURE_CONN 0x002D
390
391#define MGMT_OP_SET_DEBUG_KEYS 0x002E
392
393#define MGMT_OP_SET_PRIVACY 0x002F
394struct mgmt_cp_set_privacy {
395 __u8 privacy;
396 __u8 irk[16];
397} __packed;
398#define MGMT_SET_PRIVACY_SIZE 17
399
400struct mgmt_irk_info {
401 struct mgmt_addr_info addr;
402 __u8 val[16];
403} __packed;
404
405#define MGMT_OP_LOAD_IRKS 0x0030
406struct mgmt_cp_load_irks {
407 __le16 irk_count;
408 struct mgmt_irk_info irks[0];
409} __packed;
410#define MGMT_LOAD_IRKS_SIZE 2
411
372#define MGMT_EV_CMD_COMPLETE 0x0001 412#define MGMT_EV_CMD_COMPLETE 0x0001
373struct mgmt_ev_cmd_complete { 413struct mgmt_ev_cmd_complete {
374 __le16 opcode; 414 __le16 opcode;
@@ -504,3 +544,10 @@ struct mgmt_ev_passkey_notify {
504 __le32 passkey; 544 __le32 passkey;
505 __u8 entered; 545 __u8 entered;
506} __packed; 546} __packed;
547
548#define MGMT_EV_NEW_IRK 0x0018
549struct mgmt_ev_new_irk {
550 __u8 store_hint;
551 bdaddr_t rpa;
552 struct mgmt_irk_info irk;
553} __packed;
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 486213a1aed8..2611cc389d7d 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -238,9 +238,11 @@ int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
238 u8 channel); 238 u8 channel);
239int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason); 239int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
240int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb); 240int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
241void rfcomm_dlc_send_noerror(struct rfcomm_dlc *d, struct sk_buff *skb);
241int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig); 242int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
242int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig); 243int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
243void rfcomm_dlc_accept(struct rfcomm_dlc *d); 244void rfcomm_dlc_accept(struct rfcomm_dlc *d);
245struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel);
244 246
245#define rfcomm_dlc_lock(d) spin_lock(&d->lock) 247#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
246#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock) 248#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
@@ -295,6 +297,7 @@ struct rfcomm_conninfo {
295#define RFCOMM_LM_TRUSTED 0x0008 297#define RFCOMM_LM_TRUSTED 0x0008
296#define RFCOMM_LM_RELIABLE 0x0010 298#define RFCOMM_LM_RELIABLE 0x0010
297#define RFCOMM_LM_SECURE 0x0020 299#define RFCOMM_LM_SECURE 0x0020
300#define RFCOMM_LM_FIPS 0x0040
298 301
299#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) sk) 302#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) sk)
300 303
@@ -323,11 +326,16 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel,
323#define RFCOMMGETDEVINFO _IOR('R', 211, int) 326#define RFCOMMGETDEVINFO _IOR('R', 211, int)
324#define RFCOMMSTEALDLC _IOW('R', 220, int) 327#define RFCOMMSTEALDLC _IOW('R', 220, int)
325 328
329/* rfcomm_dev.flags bit definitions */
326#define RFCOMM_REUSE_DLC 0 330#define RFCOMM_REUSE_DLC 0
327#define RFCOMM_RELEASE_ONHUP 1 331#define RFCOMM_RELEASE_ONHUP 1
328#define RFCOMM_HANGUP_NOW 2 332#define RFCOMM_HANGUP_NOW 2
329#define RFCOMM_TTY_ATTACHED 3 333#define RFCOMM_TTY_ATTACHED 3
330#define RFCOMM_TTY_RELEASED 4 334#define RFCOMM_DEFUNCT_BIT4 4 /* don't reuse this bit - userspace visible */
335
336/* rfcomm_dev.status bit definitions */
337#define RFCOMM_DEV_RELEASED 0
338#define RFCOMM_TTY_OWNED 1
331 339
332struct rfcomm_dev_req { 340struct rfcomm_dev_req {
333 s16 dev_id; 341 s16 dev_id;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9f90554e88c4..8c9ba44fb7cf 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2206,7 +2206,12 @@ struct cfg80211_qos_map {
2206 * @set_cqm_txe_config: Configure connection quality monitor TX error 2206 * @set_cqm_txe_config: Configure connection quality monitor TX error
2207 * thresholds. 2207 * thresholds.
2208 * @sched_scan_start: Tell the driver to start a scheduled scan. 2208 * @sched_scan_start: Tell the driver to start a scheduled scan.
2209 * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. 2209 * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. This
2210 * call must stop the scheduled scan and be ready for starting a new one
2211 * before it returns, i.e. @sched_scan_start may be called immediately
2212 * after that again and should not fail in that case. The driver should
2213 * not call cfg80211_sched_scan_stopped() for a requested stop (when this
2214 * method returns 0.)
2210 * 2215 *
2211 * @mgmt_frame_register: Notify driver that a management frame type was 2216 * @mgmt_frame_register: Notify driver that a management frame type was
2212 * registered. Note that this callback may not sleep, and cannot run 2217 * registered. Note that this callback may not sleep, and cannot run
@@ -2465,7 +2470,8 @@ struct cfg80211_ops {
2465 2470
2466 int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, 2471 int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev,
2467 u8 *peer, u8 action_code, u8 dialog_token, 2472 u8 *peer, u8 action_code, u8 dialog_token,
2468 u16 status_code, const u8 *buf, size_t len); 2473 u16 status_code, u32 peer_capability,
2474 const u8 *buf, size_t len);
2469 int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, 2475 int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
2470 u8 *peer, enum nl80211_tdls_operation oper); 2476 u8 *peer, enum nl80211_tdls_operation oper);
2471 2477
@@ -2610,9 +2616,12 @@ struct ieee80211_iface_limit {
2610 * only in special cases. 2616 * only in special cases.
2611 * @radar_detect_widths: bitmap of channel widths supported for radar detection 2617 * @radar_detect_widths: bitmap of channel widths supported for radar detection
2612 * 2618 *
2613 * These examples can be expressed as follows: 2619 * With this structure the driver can describe which interface
2620 * combinations it supports concurrently.
2614 * 2621 *
2615 * Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total: 2622 * Examples:
2623 *
2624 * 1. Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total:
2616 * 2625 *
2617 * struct ieee80211_iface_limit limits1[] = { 2626 * struct ieee80211_iface_limit limits1[] = {
2618 * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, 2627 * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), },
@@ -2626,7 +2635,7 @@ struct ieee80211_iface_limit {
2626 * }; 2635 * };
2627 * 2636 *
2628 * 2637 *
2629 * Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total: 2638 * 2. Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total:
2630 * 2639 *
2631 * struct ieee80211_iface_limit limits2[] = { 2640 * struct ieee80211_iface_limit limits2[] = {
2632 * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) | 2641 * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) |
@@ -2640,7 +2649,8 @@ struct ieee80211_iface_limit {
2640 * }; 2649 * };
2641 * 2650 *
2642 * 2651 *
2643 * Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total. 2652 * 3. Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total.
2653 *
2644 * This allows for an infrastructure connection and three P2P connections. 2654 * This allows for an infrastructure connection and three P2P connections.
2645 * 2655 *
2646 * struct ieee80211_iface_limit limits3[] = { 2656 * struct ieee80211_iface_limit limits3[] = {
@@ -2790,7 +2800,7 @@ struct wiphy_vendor_command {
2790 * @perm_addr: permanent MAC address of this device 2800 * @perm_addr: permanent MAC address of this device
2791 * @addr_mask: If the device supports multiple MAC addresses by masking, 2801 * @addr_mask: If the device supports multiple MAC addresses by masking,
2792 * set this to a mask with variable bits set to 1, e.g. if the last 2802 * set this to a mask with variable bits set to 1, e.g. if the last
2793 * four bits are variable then set it to 00:...:00:0f. The actual 2803 * four bits are variable then set it to 00-00-00-00-00-0f. The actual
2794 * variable bits shall be determined by the interfaces added, with 2804 * variable bits shall be determined by the interfaces added, with
2795 * interfaces not matching the mask being rejected to be brought up. 2805 * interfaces not matching the mask being rejected to be brought up.
2796 * @n_addresses: number of addresses in @addresses. 2806 * @n_addresses: number of addresses in @addresses.
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 4f0f29dce0aa..86faa413b37d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -66,10 +66,6 @@
66 * 66 *
67 * Secondly, when the hardware handles fragmentation, the frame handed to 67 * Secondly, when the hardware handles fragmentation, the frame handed to
68 * the driver from mac80211 is the MSDU, not the MPDU. 68 * the driver from mac80211 is the MSDU, not the MPDU.
69 *
70 * Finally, for received frames, the driver is able to indicate that it has
71 * filled a radiotap header and put that in front of the frame; if it does
72 * not do so then mac80211 may add this under certain circumstances.
73 */ 69 */
74 70
75/** 71/**
@@ -1507,8 +1503,6 @@ struct ieee80211_tx_control {
1507 * @IEEE80211_HW_CONNECTION_MONITOR: 1503 * @IEEE80211_HW_CONNECTION_MONITOR:
1508 * The hardware performs its own connection monitoring, including 1504 * The hardware performs its own connection monitoring, including
1509 * periodic keep-alives to the AP and probing the AP on beacon loss. 1505 * periodic keep-alives to the AP and probing the AP on beacon loss.
1510 * When this flag is set, signaling beacon-loss will cause an immediate
1511 * change to disassociated state.
1512 * 1506 *
1513 * @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC: 1507 * @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC:
1514 * This device needs to get data from beacon before association (i.e. 1508 * This device needs to get data from beacon before association (i.e.
@@ -1644,10 +1638,6 @@ enum ieee80211_hw_flags {
1644 * the hw can report back. 1638 * the hw can report back.
1645 * @max_rate_tries: maximum number of tries for each stage 1639 * @max_rate_tries: maximum number of tries for each stage
1646 * 1640 *
1647 * @napi_weight: weight used for NAPI polling. You must specify an
1648 * appropriate value here if a napi_poll operation is provided
1649 * by your driver.
1650 *
1651 * @max_rx_aggregation_subframes: maximum buffer size (number of 1641 * @max_rx_aggregation_subframes: maximum buffer size (number of
1652 * sub-frames) to be used for A-MPDU block ack receiver 1642 * sub-frames) to be used for A-MPDU block ack receiver
1653 * aggregation. 1643 * aggregation.
@@ -1701,7 +1691,6 @@ struct ieee80211_hw {
1701 int vif_data_size; 1691 int vif_data_size;
1702 int sta_data_size; 1692 int sta_data_size;
1703 int chanctx_data_size; 1693 int chanctx_data_size;
1704 int napi_weight;
1705 u16 queues; 1694 u16 queues;
1706 u16 max_listen_interval; 1695 u16 max_listen_interval;
1707 s8 max_signal; 1696 s8 max_signal;
@@ -2471,6 +2460,7 @@ enum ieee80211_roc_type {
2471 * This process will continue until sched_scan_stop is called. 2460 * This process will continue until sched_scan_stop is called.
2472 * 2461 *
2473 * @sched_scan_stop: Tell the hardware to stop an ongoing scheduled scan. 2462 * @sched_scan_stop: Tell the hardware to stop an ongoing scheduled scan.
2463 * In this case, ieee80211_sched_scan_stopped() must not be called.
2474 * 2464 *
2475 * @sw_scan_start: Notifier function that is called just before a software scan 2465 * @sw_scan_start: Notifier function that is called just before a software scan
2476 * is started. Can be NULL, if the driver doesn't need this notification. 2466 * is started. Can be NULL, if the driver doesn't need this notification.
@@ -2624,8 +2614,6 @@ enum ieee80211_roc_type {
2624 * callback. They must then call ieee80211_chswitch_done() to indicate 2614 * callback. They must then call ieee80211_chswitch_done() to indicate
2625 * completion of the channel switch. 2615 * completion of the channel switch.
2626 * 2616 *
2627 * @napi_poll: Poll Rx queue for incoming data frames.
2628 *
2629 * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device. 2617 * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device.
2630 * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may 2618 * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may
2631 * reject TX/RX mask combinations they cannot support by returning -EINVAL 2619 * reject TX/RX mask combinations they cannot support by returning -EINVAL
@@ -2820,7 +2808,7 @@ struct ieee80211_ops {
2820 struct ieee80211_vif *vif, 2808 struct ieee80211_vif *vif,
2821 struct cfg80211_sched_scan_request *req, 2809 struct cfg80211_sched_scan_request *req,
2822 struct ieee80211_sched_scan_ies *ies); 2810 struct ieee80211_sched_scan_ies *ies);
2823 void (*sched_scan_stop)(struct ieee80211_hw *hw, 2811 int (*sched_scan_stop)(struct ieee80211_hw *hw,
2824 struct ieee80211_vif *vif); 2812 struct ieee80211_vif *vif);
2825 void (*sw_scan_start)(struct ieee80211_hw *hw); 2813 void (*sw_scan_start)(struct ieee80211_hw *hw);
2826 void (*sw_scan_complete)(struct ieee80211_hw *hw); 2814 void (*sw_scan_complete)(struct ieee80211_hw *hw);
@@ -2884,7 +2872,6 @@ struct ieee80211_ops {
2884 void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); 2872 void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
2885 void (*channel_switch)(struct ieee80211_hw *hw, 2873 void (*channel_switch)(struct ieee80211_hw *hw,
2886 struct ieee80211_channel_switch *ch_switch); 2874 struct ieee80211_channel_switch *ch_switch);
2887 int (*napi_poll)(struct ieee80211_hw *hw, int budget);
2888 int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); 2875 int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
2889 int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 2876 int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
2890 2877
@@ -3166,21 +3153,21 @@ void ieee80211_free_hw(struct ieee80211_hw *hw);
3166 */ 3153 */
3167void ieee80211_restart_hw(struct ieee80211_hw *hw); 3154void ieee80211_restart_hw(struct ieee80211_hw *hw);
3168 3155
3169/** ieee80211_napi_schedule - schedule NAPI poll 3156/**
3170 * 3157 * ieee80211_napi_add - initialize mac80211 NAPI context
3171 * Use this function to schedule NAPI polling on a device. 3158 * @hw: the hardware to initialize the NAPI context on
3172 * 3159 * @napi: the NAPI context to initialize
3173 * @hw: the hardware to start polling 3160 * @napi_dev: dummy NAPI netdevice, here to not waste the space if the
3174 */ 3161 * driver doesn't use NAPI
3175void ieee80211_napi_schedule(struct ieee80211_hw *hw); 3162 * @poll: poll function
3176 3163 * @weight: default weight
3177/** ieee80211_napi_complete - complete NAPI polling
3178 *
3179 * Use this function to finish NAPI polling on a device.
3180 * 3164 *
3181 * @hw: the hardware to stop polling 3165 * See also netif_napi_add().
3182 */ 3166 */
3183void ieee80211_napi_complete(struct ieee80211_hw *hw); 3167void ieee80211_napi_add(struct ieee80211_hw *hw, struct napi_struct *napi,
3168 struct net_device *napi_dev,
3169 int (*poll)(struct napi_struct *, int),
3170 int weight);
3184 3171
3185/** 3172/**
3186 * ieee80211_rx - receive frame 3173 * ieee80211_rx - receive frame
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index a12e6cae5132..ff72cab3cd3a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -303,8 +303,9 @@
303 * passed, all channels allowed for the current regulatory domain 303 * passed, all channels allowed for the current regulatory domain
304 * are used. Extra IEs can also be passed from the userspace by 304 * are used. Extra IEs can also be passed from the userspace by
305 * using the %NL80211_ATTR_IE attribute. 305 * using the %NL80211_ATTR_IE attribute.
306 * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT 306 * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if
307 * if scheduled scan is not running. 307 * scheduled scan is not running. The caller may assume that as soon
308 * as the call returns, it is safe to start a new scheduled scan again.
308 * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan 309 * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan
309 * results available. 310 * results available.
310 * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has 311 * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has
@@ -1575,6 +1576,9 @@ enum nl80211_commands {
1575 * advertise values that cannot always be met. In such cases, an attempt 1576 * advertise values that cannot always be met. In such cases, an attempt
1576 * to add a new station entry with @NL80211_CMD_NEW_STATION may fail. 1577 * to add a new station entry with @NL80211_CMD_NEW_STATION may fail.
1577 * 1578 *
1579 * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32.
1580 * As specified in the &enum nl80211_tdls_peer_capability.
1581 *
1578 * @NL80211_ATTR_MAX: highest attribute number currently defined 1582 * @NL80211_ATTR_MAX: highest attribute number currently defined
1579 * @__NL80211_ATTR_AFTER_LAST: internal use 1583 * @__NL80211_ATTR_AFTER_LAST: internal use
1580 */ 1584 */
@@ -1908,6 +1912,8 @@ enum nl80211_attrs {
1908 1912
1909 NL80211_ATTR_MAX_AP_ASSOC_STA, 1913 NL80211_ATTR_MAX_AP_ASSOC_STA,
1910 1914
1915 NL80211_ATTR_TDLS_PEER_CAPABILITY,
1916
1911 /* add attributes here, update the policy in nl80211.c */ 1917 /* add attributes here, update the policy in nl80211.c */
1912 1918
1913 __NL80211_ATTR_AFTER_LAST, 1919 __NL80211_ATTR_AFTER_LAST,
@@ -2437,10 +2443,7 @@ enum nl80211_reg_type {
2437 * in KHz. This is not a center a frequency but an actual regulatory 2443 * in KHz. This is not a center a frequency but an actual regulatory
2438 * band edge. 2444 * band edge.
2439 * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this 2445 * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
2440 * frequency range, in KHz. If not present or 0, maximum available 2446 * frequency range, in KHz.
2441 * bandwidth should be calculated base on contiguous rules and wider
2442 * channels will be allowed to cross multiple contiguous/overlapping
2443 * frequency ranges.
2444 * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain 2447 * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
2445 * for a given frequency range. The value is in mBi (100 * dBi). 2448 * for a given frequency range. The value is in mBi (100 * dBi).
2446 * If you don't have one then don't send this. 2449 * If you don't have one then don't send this.
@@ -2511,6 +2514,9 @@ enum nl80211_sched_scan_match_attr {
2511 * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, 2514 * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
2512 * this includes probe requests or modes of operation that require 2515 * this includes probe requests or modes of operation that require
2513 * beaconing. 2516 * beaconing.
2517 * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated
2518 * base on contiguous rules and wider channels will be allowed to cross
2519 * multiple contiguous/overlapping frequency ranges.
2514 */ 2520 */
2515enum nl80211_reg_rule_flags { 2521enum nl80211_reg_rule_flags {
2516 NL80211_RRF_NO_OFDM = 1<<0, 2522 NL80211_RRF_NO_OFDM = 1<<0,
@@ -2522,6 +2528,7 @@ enum nl80211_reg_rule_flags {
2522 NL80211_RRF_PTMP_ONLY = 1<<6, 2528 NL80211_RRF_PTMP_ONLY = 1<<6,
2523 NL80211_RRF_NO_IR = 1<<7, 2529 NL80211_RRF_NO_IR = 1<<7,
2524 __NL80211_RRF_NO_IBSS = 1<<8, 2530 __NL80211_RRF_NO_IBSS = 1<<8,
2531 NL80211_RRF_AUTO_BW = 1<<11,
2525}; 2532};
2526 2533
2527#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR 2534#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
@@ -3843,11 +3850,6 @@ enum nl80211_ap_sme_features {
3843 * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested 3850 * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
3844 * to work properly to suppport receiving regulatory hints from 3851 * to work properly to suppport receiving regulatory hints from
3845 * cellular base stations. 3852 * cellular base stations.
3846 * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active
3847 * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel
3848 * in the interface combinations, even when it's only used for scan
3849 * and remain-on-channel. This could be due to, for example, the
3850 * remain-on-channel implementation requiring a channel context.
3851 * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of 3853 * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of
3852 * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station 3854 * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station
3853 * mode 3855 * mode
@@ -3889,7 +3891,7 @@ enum nl80211_feature_flags {
3889 NL80211_FEATURE_HT_IBSS = 1 << 1, 3891 NL80211_FEATURE_HT_IBSS = 1 << 1,
3890 NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, 3892 NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
3891 NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, 3893 NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3,
3892 NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, 3894 /* bit 4 is reserved - don't use */
3893 NL80211_FEATURE_SAE = 1 << 5, 3895 NL80211_FEATURE_SAE = 1 << 5,
3894 NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, 3896 NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6,
3895 NL80211_FEATURE_SCAN_FLUSH = 1 << 7, 3897 NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
@@ -4079,4 +4081,20 @@ struct nl80211_vendor_cmd_info {
4079 __u32 subcmd; 4081 __u32 subcmd;
4080}; 4082};
4081 4083
4084/**
4085 * enum nl80211_tdls_peer_capability - TDLS peer flags.
4086 *
4087 * Used by tdls_mgmt() to determine which conditional elements need
4088 * to be added to TDLS Setup frames.
4089 *
4090 * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
4091 * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
4092 * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
4093 */
4094enum nl80211_tdls_peer_capability {
4095 NL80211_TDLS_PEER_HT = 1<<0,
4096 NL80211_TDLS_PEER_VHT = 1<<1,
4097 NL80211_TDLS_PEER_WMM = 1<<2,
4098};
4099
4082#endif /* __LINUX_NL80211_H */ 4100#endif /* __LINUX_NL80211_H */
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index efcd108822c4..f986b9968bdb 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -235,7 +235,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
235 BT_DBG("chan %p state %s", chan, 235 BT_DBG("chan %p state %s", chan,
236 state_to_string(chan->state)); 236 state_to_string(chan->state));
237 237
238 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) 238 if (chan->scid == L2CAP_CID_A2MP)
239 continue; 239 continue;
240 240
241 l2cap_chan_lock(chan); 241 l2cap_chan_lock(chan);
@@ -726,7 +726,11 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
726 726
727 BT_DBG("chan %p", chan); 727 BT_DBG("chan %p", chan);
728 728
729 chan->chan_type = L2CAP_CHAN_CONN_FIX_A2MP; 729 chan->chan_type = L2CAP_CHAN_FIXED;
730 chan->scid = L2CAP_CID_A2MP;
731 chan->dcid = L2CAP_CID_A2MP;
732 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
733 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
730 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; 734 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
731 735
732 chan->ops = &a2mp_chan_ops; 736 chan->ops = &a2mp_chan_ops;
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 0c5866bb49b6..2021c481cdb6 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -31,7 +31,7 @@
31#include <net/bluetooth/bluetooth.h> 31#include <net/bluetooth/bluetooth.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33 33
34#define VERSION "2.18" 34#define VERSION "2.19"
35 35
36/* Bluetooth sockets */ 36/* Bluetooth sockets */
37#define BT_MAX_PROTO 8 37#define BT_MAX_PROTO 8
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ba5366c320da..7c713c4675ba 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -225,13 +225,13 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
225 cp.conn_interval_max = cpu_to_le16(max); 225 cp.conn_interval_max = cpu_to_le16(max);
226 cp.conn_latency = cpu_to_le16(latency); 226 cp.conn_latency = cpu_to_le16(latency);
227 cp.supervision_timeout = cpu_to_le16(to_multiplier); 227 cp.supervision_timeout = cpu_to_le16(to_multiplier);
228 cp.min_ce_len = __constant_cpu_to_le16(0x0001); 228 cp.min_ce_len = __constant_cpu_to_le16(0x0000);
229 cp.max_ce_len = __constant_cpu_to_le16(0x0001); 229 cp.max_ce_len = __constant_cpu_to_le16(0x0000);
230 230
231 hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp); 231 hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
232} 232}
233 233
234void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], 234void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
235 __u8 ltk[16]) 235 __u8 ltk[16])
236{ 236{
237 struct hci_dev *hdev = conn->hdev; 237 struct hci_dev *hdev = conn->hdev;
@@ -242,9 +242,9 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
242 memset(&cp, 0, sizeof(cp)); 242 memset(&cp, 0, sizeof(cp));
243 243
244 cp.handle = cpu_to_le16(conn->handle); 244 cp.handle = cpu_to_le16(conn->handle);
245 memcpy(cp.ltk, ltk, sizeof(cp.ltk)); 245 cp.rand = rand;
246 cp.ediv = ediv; 246 cp.ediv = ediv;
247 memcpy(cp.rand, rand, sizeof(cp.rand)); 247 memcpy(cp.ltk, ltk, sizeof(cp.ltk));
248 248
249 hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp); 249 hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
250} 250}
@@ -363,6 +363,16 @@ static void hci_conn_auto_accept(struct work_struct *work)
363 &conn->dst); 363 &conn->dst);
364} 364}
365 365
366static void le_conn_timeout(struct work_struct *work)
367{
368 struct hci_conn *conn = container_of(work, struct hci_conn,
369 le_conn_timeout.work);
370
371 BT_DBG("");
372
373 hci_le_create_connection_cancel(conn);
374}
375
366struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) 376struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
367{ 377{
368 struct hci_conn *conn; 378 struct hci_conn *conn;
@@ -410,6 +420,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
410 INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout); 420 INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout);
411 INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept); 421 INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept);
412 INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle); 422 INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle);
423 INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout);
413 424
414 atomic_set(&conn->refcnt, 0); 425 atomic_set(&conn->refcnt, 0);
415 426
@@ -442,6 +453,8 @@ int hci_conn_del(struct hci_conn *conn)
442 /* Unacked frames */ 453 /* Unacked frames */
443 hdev->acl_cnt += conn->sent; 454 hdev->acl_cnt += conn->sent;
444 } else if (conn->type == LE_LINK) { 455 } else if (conn->type == LE_LINK) {
456 cancel_delayed_work_sync(&conn->le_conn_timeout);
457
445 if (hdev->le_pkts) 458 if (hdev->le_pkts)
446 hdev->le_cnt += conn->sent; 459 hdev->le_cnt += conn->sent;
447 else 460 else
@@ -514,6 +527,26 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
514} 527}
515EXPORT_SYMBOL(hci_get_route); 528EXPORT_SYMBOL(hci_get_route);
516 529
530/* This function requires the caller holds hdev->lock */
531void hci_le_conn_failed(struct hci_conn *conn, u8 status)
532{
533 struct hci_dev *hdev = conn->hdev;
534
535 conn->state = BT_CLOSED;
536
537 mgmt_connect_failed(hdev, &conn->dst, conn->type, conn->dst_type,
538 status);
539
540 hci_proto_connect_cfm(conn, status);
541
542 hci_conn_del(conn);
543
544 /* Since we may have temporarily stopped the background scanning in
545 * favor of connection establishment, we should restart it.
546 */
547 hci_update_background_scan(hdev);
548}
549
517static void create_le_conn_complete(struct hci_dev *hdev, u8 status) 550static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
518{ 551{
519 struct hci_conn *conn; 552 struct hci_conn *conn;
@@ -530,55 +563,55 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
530 if (!conn) 563 if (!conn)
531 goto done; 564 goto done;
532 565
533 conn->state = BT_CLOSED; 566 hci_le_conn_failed(conn, status);
534
535 mgmt_connect_failed(hdev, &conn->dst, conn->type, conn->dst_type,
536 status);
537
538 hci_proto_connect_cfm(conn, status);
539
540 hci_conn_del(conn);
541 567
542done: 568done:
543 hci_dev_unlock(hdev); 569 hci_dev_unlock(hdev);
544} 570}
545 571
546static int hci_create_le_conn(struct hci_conn *conn) 572static void hci_req_add_le_create_conn(struct hci_request *req,
573 struct hci_conn *conn)
547{ 574{
548 struct hci_dev *hdev = conn->hdev;
549 struct hci_cp_le_create_conn cp; 575 struct hci_cp_le_create_conn cp;
550 struct hci_request req; 576 struct hci_dev *hdev = conn->hdev;
551 int err; 577 u8 own_addr_type;
552
553 hci_req_init(&req, hdev);
554 578
555 memset(&cp, 0, sizeof(cp)); 579 memset(&cp, 0, sizeof(cp));
580
581 /* Update random address, but set require_privacy to false so
582 * that we never connect with an unresolvable address.
583 */
584 if (hci_update_random_address(req, false, &own_addr_type))
585 return;
586
587 /* Save the address type used for this connnection attempt so we able
588 * to retrieve this information if we need it.
589 */
590 conn->src_type = own_addr_type;
591
556 cp.scan_interval = cpu_to_le16(hdev->le_scan_interval); 592 cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
557 cp.scan_window = cpu_to_le16(hdev->le_scan_window); 593 cp.scan_window = cpu_to_le16(hdev->le_scan_window);
558 bacpy(&cp.peer_addr, &conn->dst); 594 bacpy(&cp.peer_addr, &conn->dst);
559 cp.peer_addr_type = conn->dst_type; 595 cp.peer_addr_type = conn->dst_type;
560 cp.own_address_type = conn->src_type; 596 cp.own_address_type = own_addr_type;
561 cp.conn_interval_min = cpu_to_le16(hdev->le_conn_min_interval); 597 cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
562 cp.conn_interval_max = cpu_to_le16(hdev->le_conn_max_interval); 598 cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
563 cp.supervision_timeout = __constant_cpu_to_le16(0x002a); 599 cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
564 cp.min_ce_len = __constant_cpu_to_le16(0x0000); 600 cp.min_ce_len = __constant_cpu_to_le16(0x0000);
565 cp.max_ce_len = __constant_cpu_to_le16(0x0000); 601 cp.max_ce_len = __constant_cpu_to_le16(0x0000);
566 602
567 hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); 603 hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
568
569 err = hci_req_run(&req, create_le_conn_complete);
570 if (err) {
571 hci_conn_del(conn);
572 return err;
573 }
574 604
575 return 0; 605 conn->state = BT_CONNECT;
576} 606}
577 607
578static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, 608struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
579 u8 dst_type, u8 sec_level, u8 auth_type) 609 u8 dst_type, u8 sec_level, u8 auth_type)
580{ 610{
611 struct hci_conn_params *params;
581 struct hci_conn *conn; 612 struct hci_conn *conn;
613 struct smp_irk *irk;
614 struct hci_request req;
582 int err; 615 int err;
583 616
584 if (test_bit(HCI_ADVERTISING, &hdev->flags)) 617 if (test_bit(HCI_ADVERTISING, &hdev->flags))
@@ -607,35 +640,74 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
607 if (conn) 640 if (conn)
608 return ERR_PTR(-EBUSY); 641 return ERR_PTR(-EBUSY);
609 642
643 /* When given an identity address with existing identity
644 * resolving key, the connection needs to be established
645 * to a resolvable random address.
646 *
647 * This uses the cached random resolvable address from
648 * a previous scan. When no cached address is available,
649 * try connecting to the identity address instead.
650 *
651 * Storing the resolvable random address is required here
652 * to handle connection failures. The address will later
653 * be resolved back into the original identity address
654 * from the connect request.
655 */
656 irk = hci_find_irk_by_addr(hdev, dst, dst_type);
657 if (irk && bacmp(&irk->rpa, BDADDR_ANY)) {
658 dst = &irk->rpa;
659 dst_type = ADDR_LE_DEV_RANDOM;
660 }
661
610 conn = hci_conn_add(hdev, LE_LINK, dst); 662 conn = hci_conn_add(hdev, LE_LINK, dst);
611 if (!conn) 663 if (!conn)
612 return ERR_PTR(-ENOMEM); 664 return ERR_PTR(-ENOMEM);
613 665
614 if (dst_type == BDADDR_LE_PUBLIC) 666 conn->dst_type = dst_type;
615 conn->dst_type = ADDR_LE_DEV_PUBLIC;
616 else
617 conn->dst_type = ADDR_LE_DEV_RANDOM;
618
619 conn->src_type = hdev->own_addr_type;
620 667
621 conn->state = BT_CONNECT;
622 conn->out = true; 668 conn->out = true;
623 conn->link_mode |= HCI_LM_MASTER; 669 conn->link_mode |= HCI_LM_MASTER;
624 conn->sec_level = BT_SECURITY_LOW; 670 conn->sec_level = BT_SECURITY_LOW;
625 conn->pending_sec_level = sec_level; 671 conn->pending_sec_level = sec_level;
626 conn->auth_type = auth_type; 672 conn->auth_type = auth_type;
627 673
628 err = hci_create_le_conn(conn); 674 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
629 if (err) 675 if (params) {
676 conn->le_conn_min_interval = params->conn_min_interval;
677 conn->le_conn_max_interval = params->conn_max_interval;
678 } else {
679 conn->le_conn_min_interval = hdev->le_conn_min_interval;
680 conn->le_conn_max_interval = hdev->le_conn_max_interval;
681 }
682
683 hci_req_init(&req, hdev);
684
685 /* If controller is scanning, we stop it since some controllers are
686 * not able to scan and connect at the same time. Also set the
687 * HCI_LE_SCAN_INTERRUPTED flag so that the command complete
688 * handler for scan disabling knows to set the correct discovery
689 * state.
690 */
691 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
692 hci_req_add_le_scan_disable(&req);
693 set_bit(HCI_LE_SCAN_INTERRUPTED, &hdev->dev_flags);
694 }
695
696 hci_req_add_le_create_conn(&req, conn);
697
698 err = hci_req_run(&req, create_le_conn_complete);
699 if (err) {
700 hci_conn_del(conn);
630 return ERR_PTR(err); 701 return ERR_PTR(err);
702 }
631 703
632done: 704done:
633 hci_conn_hold(conn); 705 hci_conn_hold(conn);
634 return conn; 706 return conn;
635} 707}
636 708
637static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, 709struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
638 u8 sec_level, u8 auth_type) 710 u8 sec_level, u8 auth_type)
639{ 711{
640 struct hci_conn *acl; 712 struct hci_conn *acl;
641 713
@@ -704,22 +776,6 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
704 return sco; 776 return sco;
705} 777}
706 778
707/* Create SCO, ACL or LE connection. */
708struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
709 __u8 dst_type, __u8 sec_level, __u8 auth_type)
710{
711 BT_DBG("%s dst %pMR type 0x%x", hdev->name, dst, type);
712
713 switch (type) {
714 case LE_LINK:
715 return hci_connect_le(hdev, dst, dst_type, sec_level, auth_type);
716 case ACL_LINK:
717 return hci_connect_acl(hdev, dst, sec_level, auth_type);
718 }
719
720 return ERR_PTR(-EINVAL);
721}
722
723/* Check link security requirement */ 779/* Check link security requirement */
724int hci_conn_check_link_mode(struct hci_conn *conn) 780int hci_conn_check_link_mode(struct hci_conn *conn)
725{ 781{
@@ -800,14 +856,23 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
800 if (!(conn->link_mode & HCI_LM_AUTH)) 856 if (!(conn->link_mode & HCI_LM_AUTH))
801 goto auth; 857 goto auth;
802 858
803 /* An authenticated combination key has sufficient security for any 859 /* An authenticated FIPS approved combination key has sufficient
804 security level. */ 860 * security for security level 4. */
805 if (conn->key_type == HCI_LK_AUTH_COMBINATION) 861 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256 &&
862 sec_level == BT_SECURITY_FIPS)
863 goto encrypt;
864
865 /* An authenticated combination key has sufficient security for
866 security level 3. */
867 if ((conn->key_type == HCI_LK_AUTH_COMBINATION_P192 ||
868 conn->key_type == HCI_LK_AUTH_COMBINATION_P256) &&
869 sec_level == BT_SECURITY_HIGH)
806 goto encrypt; 870 goto encrypt;
807 871
808 /* An unauthenticated combination key has sufficient security for 872 /* An unauthenticated combination key has sufficient security for
809 security level 1 and 2. */ 873 security level 1 and 2. */
810 if (conn->key_type == HCI_LK_UNAUTH_COMBINATION && 874 if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 ||
875 conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) &&
811 (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) 876 (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW))
812 goto encrypt; 877 goto encrypt;
813 878
@@ -816,7 +881,8 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
816 is generated using maximum PIN code length (16). 881 is generated using maximum PIN code length (16).
817 For pre 2.1 units. */ 882 For pre 2.1 units. */
818 if (conn->key_type == HCI_LK_COMBINATION && 883 if (conn->key_type == HCI_LK_COMBINATION &&
819 (sec_level != BT_SECURITY_HIGH || conn->pin_length == 16)) 884 (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW ||
885 conn->pin_length == 16))
820 goto encrypt; 886 goto encrypt;
821 887
822auth: 888auth:
@@ -840,13 +906,17 @@ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
840{ 906{
841 BT_DBG("hcon %p", conn); 907 BT_DBG("hcon %p", conn);
842 908
843 if (sec_level != BT_SECURITY_HIGH) 909 /* Accept if non-secure or higher security level is required */
844 return 1; /* Accept if non-secure is required */ 910 if (sec_level != BT_SECURITY_HIGH && sec_level != BT_SECURITY_FIPS)
911 return 1;
845 912
846 if (conn->sec_level == BT_SECURITY_HIGH) 913 /* Accept if secure or higher security level is already present */
914 if (conn->sec_level == BT_SECURITY_HIGH ||
915 conn->sec_level == BT_SECURITY_FIPS)
847 return 1; 916 return 1;
848 917
849 return 0; /* Reject not secure link */ 918 /* Reject not secure link */
919 return 0;
850} 920}
851EXPORT_SYMBOL(hci_conn_check_secure); 921EXPORT_SYMBOL(hci_conn_check_secure);
852 922
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5e8663c194c1..8bbfdea9cbec 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -29,11 +29,14 @@
29#include <linux/idr.h> 29#include <linux/idr.h>
30#include <linux/rfkill.h> 30#include <linux/rfkill.h>
31#include <linux/debugfs.h> 31#include <linux/debugfs.h>
32#include <linux/crypto.h>
32#include <asm/unaligned.h> 33#include <asm/unaligned.h>
33 34
34#include <net/bluetooth/bluetooth.h> 35#include <net/bluetooth/bluetooth.h>
35#include <net/bluetooth/hci_core.h> 36#include <net/bluetooth/hci_core.h>
36 37
38#include "smp.h"
39
37static void hci_rx_work(struct work_struct *work); 40static void hci_rx_work(struct work_struct *work);
38static void hci_cmd_work(struct work_struct *work); 41static void hci_cmd_work(struct work_struct *work);
39static void hci_tx_work(struct work_struct *work); 42static void hci_tx_work(struct work_struct *work);
@@ -285,24 +288,6 @@ static const struct file_operations link_keys_fops = {
285 .release = single_release, 288 .release = single_release,
286}; 289};
287 290
288static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf,
289 size_t count, loff_t *ppos)
290{
291 struct hci_dev *hdev = file->private_data;
292 char buf[3];
293
294 buf[0] = test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) ? 'Y': 'N';
295 buf[1] = '\n';
296 buf[2] = '\0';
297 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
298}
299
300static const struct file_operations use_debug_keys_fops = {
301 .open = simple_open,
302 .read = use_debug_keys_read,
303 .llseek = default_llseek,
304};
305
306static int dev_class_show(struct seq_file *f, void *ptr) 291static int dev_class_show(struct seq_file *f, void *ptr)
307{ 292{
308 struct hci_dev *hdev = f->private; 293 struct hci_dev *hdev = f->private;
@@ -415,6 +400,70 @@ static int ssp_debug_mode_get(void *data, u64 *val)
415DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get, 400DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
416 ssp_debug_mode_set, "%llu\n"); 401 ssp_debug_mode_set, "%llu\n");
417 402
403static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
404 size_t count, loff_t *ppos)
405{
406 struct hci_dev *hdev = file->private_data;
407 char buf[3];
408
409 buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N';
410 buf[1] = '\n';
411 buf[2] = '\0';
412 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
413}
414
415static ssize_t force_sc_support_write(struct file *file,
416 const char __user *user_buf,
417 size_t count, loff_t *ppos)
418{
419 struct hci_dev *hdev = file->private_data;
420 char buf[32];
421 size_t buf_size = min(count, (sizeof(buf)-1));
422 bool enable;
423
424 if (test_bit(HCI_UP, &hdev->flags))
425 return -EBUSY;
426
427 if (copy_from_user(buf, user_buf, buf_size))
428 return -EFAULT;
429
430 buf[buf_size] = '\0';
431 if (strtobool(buf, &enable))
432 return -EINVAL;
433
434 if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags))
435 return -EALREADY;
436
437 change_bit(HCI_FORCE_SC, &hdev->dev_flags);
438
439 return count;
440}
441
442static const struct file_operations force_sc_support_fops = {
443 .open = simple_open,
444 .read = force_sc_support_read,
445 .write = force_sc_support_write,
446 .llseek = default_llseek,
447};
448
449static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
450 size_t count, loff_t *ppos)
451{
452 struct hci_dev *hdev = file->private_data;
453 char buf[3];
454
455 buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
456 buf[1] = '\n';
457 buf[2] = '\0';
458 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
459}
460
461static const struct file_operations sc_only_mode_fops = {
462 .open = simple_open,
463 .read = sc_only_mode_read,
464 .llseek = default_llseek,
465};
466
418static int idle_timeout_set(void *data, u64 val) 467static int idle_timeout_set(void *data, u64 val)
419{ 468{
420 struct hci_dev *hdev = data; 469 struct hci_dev *hdev = data;
@@ -443,6 +492,37 @@ static int idle_timeout_get(void *data, u64 *val)
443DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, 492DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
444 idle_timeout_set, "%llu\n"); 493 idle_timeout_set, "%llu\n");
445 494
495static int rpa_timeout_set(void *data, u64 val)
496{
497 struct hci_dev *hdev = data;
498
499 /* Require the RPA timeout to be at least 30 seconds and at most
500 * 24 hours.
501 */
502 if (val < 30 || val > (60 * 60 * 24))
503 return -EINVAL;
504
505 hci_dev_lock(hdev);
506 hdev->rpa_timeout = val;
507 hci_dev_unlock(hdev);
508
509 return 0;
510}
511
512static int rpa_timeout_get(void *data, u64 *val)
513{
514 struct hci_dev *hdev = data;
515
516 hci_dev_lock(hdev);
517 *val = hdev->rpa_timeout;
518 hci_dev_unlock(hdev);
519
520 return 0;
521}
522
523DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
524 rpa_timeout_set, "%llu\n");
525
446static int sniff_min_interval_set(void *data, u64 val) 526static int sniff_min_interval_set(void *data, u64 val)
447{ 527{
448 struct hci_dev *hdev = data; 528 struct hci_dev *hdev = data;
@@ -499,6 +579,59 @@ static int sniff_max_interval_get(void *data, u64 *val)
499DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 579DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
500 sniff_max_interval_set, "%llu\n"); 580 sniff_max_interval_set, "%llu\n");
501 581
582static int identity_show(struct seq_file *f, void *p)
583{
584 struct hci_dev *hdev = f->private;
585 bdaddr_t addr;
586 u8 addr_type;
587
588 hci_dev_lock(hdev);
589
590 hci_copy_identity_address(hdev, &addr, &addr_type);
591
592 seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
593 16, hdev->irk, &hdev->rpa);
594
595 hci_dev_unlock(hdev);
596
597 return 0;
598}
599
600static int identity_open(struct inode *inode, struct file *file)
601{
602 return single_open(file, identity_show, inode->i_private);
603}
604
605static const struct file_operations identity_fops = {
606 .open = identity_open,
607 .read = seq_read,
608 .llseek = seq_lseek,
609 .release = single_release,
610};
611
612static int random_address_show(struct seq_file *f, void *p)
613{
614 struct hci_dev *hdev = f->private;
615
616 hci_dev_lock(hdev);
617 seq_printf(f, "%pMR\n", &hdev->random_addr);
618 hci_dev_unlock(hdev);
619
620 return 0;
621}
622
623static int random_address_open(struct inode *inode, struct file *file)
624{
625 return single_open(file, random_address_show, inode->i_private);
626}
627
628static const struct file_operations random_address_fops = {
629 .open = random_address_open,
630 .read = seq_read,
631 .llseek = seq_lseek,
632 .release = single_release,
633};
634
502static int static_address_show(struct seq_file *f, void *p) 635static int static_address_show(struct seq_file *f, void *p)
503{ 636{
504 struct hci_dev *hdev = f->private; 637 struct hci_dev *hdev = f->private;
@@ -522,33 +655,107 @@ static const struct file_operations static_address_fops = {
522 .release = single_release, 655 .release = single_release,
523}; 656};
524 657
525static int own_address_type_set(void *data, u64 val) 658static ssize_t force_static_address_read(struct file *file,
659 char __user *user_buf,
660 size_t count, loff_t *ppos)
526{ 661{
527 struct hci_dev *hdev = data; 662 struct hci_dev *hdev = file->private_data;
663 char buf[3];
528 664
529 if (val != 0 && val != 1) 665 buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ? 'Y': 'N';
666 buf[1] = '\n';
667 buf[2] = '\0';
668 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
669}
670
671static ssize_t force_static_address_write(struct file *file,
672 const char __user *user_buf,
673 size_t count, loff_t *ppos)
674{
675 struct hci_dev *hdev = file->private_data;
676 char buf[32];
677 size_t buf_size = min(count, (sizeof(buf)-1));
678 bool enable;
679
680 if (test_bit(HCI_UP, &hdev->flags))
681 return -EBUSY;
682
683 if (copy_from_user(buf, user_buf, buf_size))
684 return -EFAULT;
685
686 buf[buf_size] = '\0';
687 if (strtobool(buf, &enable))
530 return -EINVAL; 688 return -EINVAL;
531 689
690 if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags))
691 return -EALREADY;
692
693 change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags);
694
695 return count;
696}
697
698static const struct file_operations force_static_address_fops = {
699 .open = simple_open,
700 .read = force_static_address_read,
701 .write = force_static_address_write,
702 .llseek = default_llseek,
703};
704
705static int white_list_show(struct seq_file *f, void *ptr)
706{
707 struct hci_dev *hdev = f->private;
708 struct bdaddr_list *b;
709
532 hci_dev_lock(hdev); 710 hci_dev_lock(hdev);
533 hdev->own_addr_type = val; 711 list_for_each_entry(b, &hdev->le_white_list, list)
712 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
534 hci_dev_unlock(hdev); 713 hci_dev_unlock(hdev);
535 714
536 return 0; 715 return 0;
537} 716}
538 717
539static int own_address_type_get(void *data, u64 *val) 718static int white_list_open(struct inode *inode, struct file *file)
540{ 719{
541 struct hci_dev *hdev = data; 720 return single_open(file, white_list_show, inode->i_private);
721}
722
723static const struct file_operations white_list_fops = {
724 .open = white_list_open,
725 .read = seq_read,
726 .llseek = seq_lseek,
727 .release = single_release,
728};
729
730static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
731{
732 struct hci_dev *hdev = f->private;
733 struct list_head *p, *n;
542 734
543 hci_dev_lock(hdev); 735 hci_dev_lock(hdev);
544 *val = hdev->own_addr_type; 736 list_for_each_safe(p, n, &hdev->identity_resolving_keys) {
737 struct smp_irk *irk = list_entry(p, struct smp_irk, list);
738 seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
739 &irk->bdaddr, irk->addr_type,
740 16, irk->val, &irk->rpa);
741 }
545 hci_dev_unlock(hdev); 742 hci_dev_unlock(hdev);
546 743
547 return 0; 744 return 0;
548} 745}
549 746
550DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get, 747static int identity_resolving_keys_open(struct inode *inode, struct file *file)
551 own_address_type_set, "%llu\n"); 748{
749 return single_open(file, identity_resolving_keys_show,
750 inode->i_private);
751}
752
753static const struct file_operations identity_resolving_keys_fops = {
754 .open = identity_resolving_keys_open,
755 .read = seq_read,
756 .llseek = seq_lseek,
757 .release = single_release,
758};
552 759
553static int long_term_keys_show(struct seq_file *f, void *ptr) 760static int long_term_keys_show(struct seq_file *f, void *ptr)
554{ 761{
@@ -556,12 +763,12 @@ static int long_term_keys_show(struct seq_file *f, void *ptr)
556 struct list_head *p, *n; 763 struct list_head *p, *n;
557 764
558 hci_dev_lock(hdev); 765 hci_dev_lock(hdev);
559 list_for_each_safe(p, n, &hdev->link_keys) { 766 list_for_each_safe(p, n, &hdev->long_term_keys) {
560 struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 767 struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
561 seq_printf(f, "%pMR (type %u) %u %u %u %.4x %*phN %*phN\\n", 768 seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
562 &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated, 769 &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
563 ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 770 ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
564 8, ltk->rand, 16, ltk->val); 771 __le64_to_cpu(ltk->rand), 16, ltk->val);
565 } 772 }
566 hci_dev_unlock(hdev); 773 hci_dev_unlock(hdev);
567 774
@@ -636,6 +843,34 @@ static int conn_max_interval_get(void *data, u64 *val)
636DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 843DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
637 conn_max_interval_set, "%llu\n"); 844 conn_max_interval_set, "%llu\n");
638 845
846static int adv_channel_map_set(void *data, u64 val)
847{
848 struct hci_dev *hdev = data;
849
850 if (val < 0x01 || val > 0x07)
851 return -EINVAL;
852
853 hci_dev_lock(hdev);
854 hdev->le_adv_channel_map = val;
855 hci_dev_unlock(hdev);
856
857 return 0;
858}
859
860static int adv_channel_map_get(void *data, u64 *val)
861{
862 struct hci_dev *hdev = data;
863
864 hci_dev_lock(hdev);
865 *val = hdev->le_adv_channel_map;
866 hci_dev_unlock(hdev);
867
868 return 0;
869}
870
871DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
872 adv_channel_map_set, "%llu\n");
873
639static ssize_t lowpan_read(struct file *file, char __user *user_buf, 874static ssize_t lowpan_read(struct file *file, char __user *user_buf,
640 size_t count, loff_t *ppos) 875 size_t count, loff_t *ppos)
641{ 876{
@@ -679,6 +914,115 @@ static const struct file_operations lowpan_debugfs_fops = {
679 .llseek = default_llseek, 914 .llseek = default_llseek,
680}; 915};
681 916
917static int le_auto_conn_show(struct seq_file *sf, void *ptr)
918{
919 struct hci_dev *hdev = sf->private;
920 struct hci_conn_params *p;
921
922 hci_dev_lock(hdev);
923
924 list_for_each_entry(p, &hdev->le_conn_params, list) {
925 seq_printf(sf, "%pMR %u %u\n", &p->addr, p->addr_type,
926 p->auto_connect);
927 }
928
929 hci_dev_unlock(hdev);
930
931 return 0;
932}
933
934static int le_auto_conn_open(struct inode *inode, struct file *file)
935{
936 return single_open(file, le_auto_conn_show, inode->i_private);
937}
938
939static ssize_t le_auto_conn_write(struct file *file, const char __user *data,
940 size_t count, loff_t *offset)
941{
942 struct seq_file *sf = file->private_data;
943 struct hci_dev *hdev = sf->private;
944 u8 auto_connect = 0;
945 bdaddr_t addr;
946 u8 addr_type;
947 char *buf;
948 int err = 0;
949 int n;
950
951 /* Don't allow partial write */
952 if (*offset != 0)
953 return -EINVAL;
954
955 if (count < 3)
956 return -EINVAL;
957
958 buf = kzalloc(count, GFP_KERNEL);
959 if (!buf)
960 return -ENOMEM;
961
962 if (copy_from_user(buf, data, count)) {
963 err = -EFAULT;
964 goto done;
965 }
966
967 if (memcmp(buf, "add", 3) == 0) {
968 n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu %hhu",
969 &addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2],
970 &addr.b[1], &addr.b[0], &addr_type,
971 &auto_connect);
972
973 if (n < 7) {
974 err = -EINVAL;
975 goto done;
976 }
977
978 hci_dev_lock(hdev);
979 err = hci_conn_params_add(hdev, &addr, addr_type, auto_connect,
980 hdev->le_conn_min_interval,
981 hdev->le_conn_max_interval);
982 hci_dev_unlock(hdev);
983
984 if (err)
985 goto done;
986 } else if (memcmp(buf, "del", 3) == 0) {
987 n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
988 &addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2],
989 &addr.b[1], &addr.b[0], &addr_type);
990
991 if (n < 7) {
992 err = -EINVAL;
993 goto done;
994 }
995
996 hci_dev_lock(hdev);
997 hci_conn_params_del(hdev, &addr, addr_type);
998 hci_dev_unlock(hdev);
999 } else if (memcmp(buf, "clr", 3) == 0) {
1000 hci_dev_lock(hdev);
1001 hci_conn_params_clear(hdev);
1002 hci_pend_le_conns_clear(hdev);
1003 hci_update_background_scan(hdev);
1004 hci_dev_unlock(hdev);
1005 } else {
1006 err = -EINVAL;
1007 }
1008
1009done:
1010 kfree(buf);
1011
1012 if (err)
1013 return err;
1014 else
1015 return count;
1016}
1017
1018static const struct file_operations le_auto_conn_fops = {
1019 .open = le_auto_conn_open,
1020 .read = seq_read,
1021 .write = le_auto_conn_write,
1022 .llseek = seq_lseek,
1023 .release = single_release,
1024};
1025
682/* ---- HCI requests ---- */ 1026/* ---- HCI requests ---- */
683 1027
684static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 1028static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
@@ -1027,14 +1371,17 @@ static void le_setup(struct hci_request *req)
1027 /* Read LE Local Supported Features */ 1371 /* Read LE Local Supported Features */
1028 hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 1372 hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
1029 1373
1374 /* Read LE Supported States */
1375 hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1376
1030 /* Read LE Advertising Channel TX Power */ 1377 /* Read LE Advertising Channel TX Power */
1031 hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 1378 hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
1032 1379
1033 /* Read LE White List Size */ 1380 /* Read LE White List Size */
1034 hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 1381 hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
1035 1382
1036 /* Read LE Supported States */ 1383 /* Clear LE White List */
1037 hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 1384 hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
1038 1385
1039 /* LE-only controllers have LE implicitly enabled */ 1386 /* LE-only controllers have LE implicitly enabled */
1040 if (!lmp_bredr_capable(hdev)) 1387 if (!lmp_bredr_capable(hdev))
@@ -1288,6 +1635,10 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
1288 events[2] |= 0x08; /* Truncated Page Complete */ 1635 events[2] |= 0x08; /* Truncated Page Complete */
1289 } 1636 }
1290 1637
1638 /* Enable Authenticated Payload Timeout Expired event if supported */
1639 if (lmp_ping_capable(hdev))
1640 events[2] |= 0x80;
1641
1291 hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1642 hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1292} 1643}
1293 1644
@@ -1322,21 +1673,8 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
1322 if (hdev->commands[5] & 0x10) 1673 if (hdev->commands[5] & 0x10)
1323 hci_setup_link_policy(req); 1674 hci_setup_link_policy(req);
1324 1675
1325 if (lmp_le_capable(hdev)) { 1676 if (lmp_le_capable(hdev))
1326 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
1327 /* If the controller has a public BD_ADDR, then
1328 * by default use that one. If this is a LE only
1329 * controller without a public address, default
1330 * to the random address.
1331 */
1332 if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1333 hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
1334 else
1335 hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
1336 }
1337
1338 hci_set_le_support(req); 1677 hci_set_le_support(req);
1339 }
1340 1678
1341 /* Read features beyond page 1 if available */ 1679 /* Read features beyond page 1 if available */
1342 for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1680 for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
@@ -1359,6 +1697,15 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
1359 /* Check for Synchronization Train support */ 1697 /* Check for Synchronization Train support */
1360 if (lmp_sync_train_capable(hdev)) 1698 if (lmp_sync_train_capable(hdev))
1361 hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1699 hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1700
1701 /* Enable Secure Connections if supported and configured */
1702 if ((lmp_sc_capable(hdev) ||
1703 test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
1704 test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
1705 u8 support = 0x01;
1706 hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1707 sizeof(support), &support);
1708 }
1362} 1709}
1363 1710
1364static int __hci_init(struct hci_dev *hdev) 1711static int __hci_init(struct hci_dev *hdev)
@@ -1417,8 +1764,6 @@ static int __hci_init(struct hci_dev *hdev)
1417 hdev, &inquiry_cache_fops); 1764 hdev, &inquiry_cache_fops);
1418 debugfs_create_file("link_keys", 0400, hdev->debugfs, 1765 debugfs_create_file("link_keys", 0400, hdev->debugfs,
1419 hdev, &link_keys_fops); 1766 hdev, &link_keys_fops);
1420 debugfs_create_file("use_debug_keys", 0444, hdev->debugfs,
1421 hdev, &use_debug_keys_fops);
1422 debugfs_create_file("dev_class", 0444, hdev->debugfs, 1767 debugfs_create_file("dev_class", 0444, hdev->debugfs,
1423 hdev, &dev_class_fops); 1768 hdev, &dev_class_fops);
1424 debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1769 debugfs_create_file("voice_setting", 0444, hdev->debugfs,
@@ -1430,6 +1775,10 @@ static int __hci_init(struct hci_dev *hdev)
1430 hdev, &auto_accept_delay_fops); 1775 hdev, &auto_accept_delay_fops);
1431 debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs, 1776 debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
1432 hdev, &ssp_debug_mode_fops); 1777 hdev, &ssp_debug_mode_fops);
1778 debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
1779 hdev, &force_sc_support_fops);
1780 debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1781 hdev, &sc_only_mode_fops);
1433 } 1782 }
1434 1783
1435 if (lmp_sniff_capable(hdev)) { 1784 if (lmp_sniff_capable(hdev)) {
@@ -1442,20 +1791,43 @@ static int __hci_init(struct hci_dev *hdev)
1442 } 1791 }
1443 1792
1444 if (lmp_le_capable(hdev)) { 1793 if (lmp_le_capable(hdev)) {
1794 debugfs_create_file("identity", 0400, hdev->debugfs,
1795 hdev, &identity_fops);
1796 debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
1797 hdev, &rpa_timeout_fops);
1798 debugfs_create_file("random_address", 0444, hdev->debugfs,
1799 hdev, &random_address_fops);
1800 debugfs_create_file("static_address", 0444, hdev->debugfs,
1801 hdev, &static_address_fops);
1802
1803 /* For controllers with a public address, provide a debug
1804 * option to force the usage of the configured static
1805 * address. By default the public address is used.
1806 */
1807 if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1808 debugfs_create_file("force_static_address", 0644,
1809 hdev->debugfs, hdev,
1810 &force_static_address_fops);
1811
1445 debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1812 debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1446 &hdev->le_white_list_size); 1813 &hdev->le_white_list_size);
1447 debugfs_create_file("static_address", 0444, hdev->debugfs, 1814 debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
1448 hdev, &static_address_fops); 1815 &white_list_fops);
1449 debugfs_create_file("own_address_type", 0644, hdev->debugfs, 1816 debugfs_create_file("identity_resolving_keys", 0400,
1450 hdev, &own_address_type_fops); 1817 hdev->debugfs, hdev,
1818 &identity_resolving_keys_fops);
1451 debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 1819 debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
1452 hdev, &long_term_keys_fops); 1820 hdev, &long_term_keys_fops);
1453 debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 1821 debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
1454 hdev, &conn_min_interval_fops); 1822 hdev, &conn_min_interval_fops);
1455 debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 1823 debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
1456 hdev, &conn_max_interval_fops); 1824 hdev, &conn_max_interval_fops);
1825 debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
1826 hdev, &adv_channel_map_fops);
1457 debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev, 1827 debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
1458 &lowpan_debugfs_fops); 1828 &lowpan_debugfs_fops);
1829 debugfs_create_file("le_auto_conn", 0644, hdev->debugfs, hdev,
1830 &le_auto_conn_fops);
1459 } 1831 }
1460 1832
1461 return 0; 1833 return 0;
@@ -1548,6 +1920,8 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
1548 1920
1549 switch (state) { 1921 switch (state) {
1550 case DISCOVERY_STOPPED: 1922 case DISCOVERY_STOPPED:
1923 hci_update_background_scan(hdev);
1924
1551 if (hdev->discovery.state != DISCOVERY_STARTING) 1925 if (hdev->discovery.state != DISCOVERY_STARTING)
1552 mgmt_discovering(hdev, 0); 1926 mgmt_discovering(hdev, 0);
1553 break; 1927 break;
@@ -1876,10 +2250,15 @@ static int hci_dev_do_open(struct hci_dev *hdev)
1876 * be able to determine if there is a public address 2250 * be able to determine if there is a public address
1877 * or not. 2251 * or not.
1878 * 2252 *
2253 * In case of user channel usage, it is not important
2254 * if a public address or static random address is
2255 * available.
2256 *
1879 * This check is only valid for BR/EDR controllers 2257 * This check is only valid for BR/EDR controllers
1880 * since AMP controllers do not have an address. 2258 * since AMP controllers do not have an address.
1881 */ 2259 */
1882 if (hdev->dev_type == HCI_BREDR && 2260 if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
2261 hdev->dev_type == HCI_BREDR &&
1883 !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2262 !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1884 !bacmp(&hdev->static_addr, BDADDR_ANY)) { 2263 !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1885 ret = -EADDRNOTAVAIL; 2264 ret = -EADDRNOTAVAIL;
@@ -1916,6 +2295,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
1916 2295
1917 if (!ret) { 2296 if (!ret) {
1918 hci_dev_hold(hdev); 2297 hci_dev_hold(hdev);
2298 set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
1919 set_bit(HCI_UP, &hdev->flags); 2299 set_bit(HCI_UP, &hdev->flags);
1920 hci_notify(hdev, HCI_DEV_UP); 2300 hci_notify(hdev, HCI_DEV_UP);
1921 if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 2301 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
@@ -2014,9 +2394,13 @@ static int hci_dev_do_close(struct hci_dev *hdev)
2014 2394
2015 cancel_delayed_work_sync(&hdev->le_scan_disable); 2395 cancel_delayed_work_sync(&hdev->le_scan_disable);
2016 2396
2397 if (test_bit(HCI_MGMT, &hdev->dev_flags))
2398 cancel_delayed_work_sync(&hdev->rpa_expired);
2399
2017 hci_dev_lock(hdev); 2400 hci_dev_lock(hdev);
2018 hci_inquiry_cache_flush(hdev); 2401 hci_inquiry_cache_flush(hdev);
2019 hci_conn_hash_flush(hdev); 2402 hci_conn_hash_flush(hdev);
2403 hci_pend_le_conns_clear(hdev);
2020 hci_dev_unlock(hdev); 2404 hci_dev_unlock(hdev);
2021 2405
2022 hci_notify(hdev, HCI_DEV_DOWN); 2406 hci_notify(hdev, HCI_DEV_DOWN);
@@ -2074,6 +2458,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
2074 2458
2075 memset(hdev->eir, 0, sizeof(hdev->eir)); 2459 memset(hdev->eir, 0, sizeof(hdev->eir));
2076 memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 2460 memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
2461 bacpy(&hdev->random_addr, BDADDR_ANY);
2077 2462
2078 hci_req_unlock(hdev); 2463 hci_req_unlock(hdev);
2079 2464
@@ -2437,7 +2822,7 @@ static void hci_discov_off(struct work_struct *work)
2437 mgmt_discoverable_timeout(hdev); 2822 mgmt_discoverable_timeout(hdev);
2438} 2823}
2439 2824
2440int hci_uuids_clear(struct hci_dev *hdev) 2825void hci_uuids_clear(struct hci_dev *hdev)
2441{ 2826{
2442 struct bt_uuid *uuid, *tmp; 2827 struct bt_uuid *uuid, *tmp;
2443 2828
@@ -2445,11 +2830,9 @@ int hci_uuids_clear(struct hci_dev *hdev)
2445 list_del(&uuid->list); 2830 list_del(&uuid->list);
2446 kfree(uuid); 2831 kfree(uuid);
2447 } 2832 }
2448
2449 return 0;
2450} 2833}
2451 2834
2452int hci_link_keys_clear(struct hci_dev *hdev) 2835void hci_link_keys_clear(struct hci_dev *hdev)
2453{ 2836{
2454 struct list_head *p, *n; 2837 struct list_head *p, *n;
2455 2838
@@ -2461,11 +2844,9 @@ int hci_link_keys_clear(struct hci_dev *hdev)
2461 list_del(p); 2844 list_del(p);
2462 kfree(key); 2845 kfree(key);
2463 } 2846 }
2464
2465 return 0;
2466} 2847}
2467 2848
2468int hci_smp_ltks_clear(struct hci_dev *hdev) 2849void hci_smp_ltks_clear(struct hci_dev *hdev)
2469{ 2850{
2470 struct smp_ltk *k, *tmp; 2851 struct smp_ltk *k, *tmp;
2471 2852
@@ -2473,8 +2854,16 @@ int hci_smp_ltks_clear(struct hci_dev *hdev)
2473 list_del(&k->list); 2854 list_del(&k->list);
2474 kfree(k); 2855 kfree(k);
2475 } 2856 }
2857}
2476 2858
2477 return 0; 2859void hci_smp_irks_clear(struct hci_dev *hdev)
2860{
2861 struct smp_irk *k, *tmp;
2862
2863 list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
2864 list_del(&k->list);
2865 kfree(k);
2866 }
2478} 2867}
2479 2868
2480struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 2869struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
@@ -2524,13 +2913,24 @@ static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2524 return false; 2913 return false;
2525} 2914}
2526 2915
2527struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 2916static bool ltk_type_master(u8 type)
2917{
2918 if (type == HCI_SMP_STK || type == HCI_SMP_LTK)
2919 return true;
2920
2921 return false;
2922}
2923
2924struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
2925 bool master)
2528{ 2926{
2529 struct smp_ltk *k; 2927 struct smp_ltk *k;
2530 2928
2531 list_for_each_entry(k, &hdev->long_term_keys, list) { 2929 list_for_each_entry(k, &hdev->long_term_keys, list) {
2532 if (k->ediv != ediv || 2930 if (k->ediv != ediv || k->rand != rand)
2533 memcmp(rand, k->rand, sizeof(k->rand))) 2931 continue;
2932
2933 if (ltk_type_master(k->type) != master)
2534 continue; 2934 continue;
2535 2935
2536 return k; 2936 return k;
@@ -2540,18 +2940,56 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
2540} 2940}
2541 2941
2542struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2942struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2543 u8 addr_type) 2943 u8 addr_type, bool master)
2544{ 2944{
2545 struct smp_ltk *k; 2945 struct smp_ltk *k;
2546 2946
2547 list_for_each_entry(k, &hdev->long_term_keys, list) 2947 list_for_each_entry(k, &hdev->long_term_keys, list)
2548 if (addr_type == k->bdaddr_type && 2948 if (addr_type == k->bdaddr_type &&
2549 bacmp(bdaddr, &k->bdaddr) == 0) 2949 bacmp(bdaddr, &k->bdaddr) == 0 &&
2950 ltk_type_master(k->type) == master)
2550 return k; 2951 return k;
2551 2952
2552 return NULL; 2953 return NULL;
2553} 2954}
2554 2955
2956struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2957{
2958 struct smp_irk *irk;
2959
2960 list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2961 if (!bacmp(&irk->rpa, rpa))
2962 return irk;
2963 }
2964
2965 list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2966 if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) {
2967 bacpy(&irk->rpa, rpa);
2968 return irk;
2969 }
2970 }
2971
2972 return NULL;
2973}
2974
2975struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2976 u8 addr_type)
2977{
2978 struct smp_irk *irk;
2979
2980 /* Identity Address must be public or static random */
2981 if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
2982 return NULL;
2983
2984 list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2985 if (addr_type == irk->addr_type &&
2986 bacmp(bdaddr, &irk->bdaddr) == 0)
2987 return irk;
2988 }
2989
2990 return NULL;
2991}
2992
2555int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 2993int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
2556 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 2994 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
2557{ 2995{
@@ -2565,7 +3003,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
2565 key = old_key; 3003 key = old_key;
2566 } else { 3004 } else {
2567 old_key_type = conn ? conn->key_type : 0xff; 3005 old_key_type = conn ? conn->key_type : 0xff;
2568 key = kzalloc(sizeof(*key), GFP_ATOMIC); 3006 key = kzalloc(sizeof(*key), GFP_KERNEL);
2569 if (!key) 3007 if (!key)
2570 return -ENOMEM; 3008 return -ENOMEM;
2571 list_add(&key->list, &hdev->link_keys); 3009 list_add(&key->list, &hdev->link_keys);
@@ -2605,22 +3043,20 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
2605 return 0; 3043 return 0;
2606} 3044}
2607 3045
2608int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 3046struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2609 int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 3047 u8 addr_type, u8 type, u8 authenticated,
2610 ediv, u8 rand[8]) 3048 u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
2611{ 3049{
2612 struct smp_ltk *key, *old_key; 3050 struct smp_ltk *key, *old_key;
3051 bool master = ltk_type_master(type);
2613 3052
2614 if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 3053 old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
2615 return 0;
2616
2617 old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
2618 if (old_key) 3054 if (old_key)
2619 key = old_key; 3055 key = old_key;
2620 else { 3056 else {
2621 key = kzalloc(sizeof(*key), GFP_ATOMIC); 3057 key = kzalloc(sizeof(*key), GFP_KERNEL);
2622 if (!key) 3058 if (!key)
2623 return -ENOMEM; 3059 return NULL;
2624 list_add(&key->list, &hdev->long_term_keys); 3060 list_add(&key->list, &hdev->long_term_keys);
2625 } 3061 }
2626 3062
@@ -2629,17 +3065,34 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
2629 memcpy(key->val, tk, sizeof(key->val)); 3065 memcpy(key->val, tk, sizeof(key->val));
2630 key->authenticated = authenticated; 3066 key->authenticated = authenticated;
2631 key->ediv = ediv; 3067 key->ediv = ediv;
3068 key->rand = rand;
2632 key->enc_size = enc_size; 3069 key->enc_size = enc_size;
2633 key->type = type; 3070 key->type = type;
2634 memcpy(key->rand, rand, sizeof(key->rand));
2635 3071
2636 if (!new_key) 3072 return key;
2637 return 0; 3073}
3074
3075struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
3076 u8 addr_type, u8 val[16], bdaddr_t *rpa)
3077{
3078 struct smp_irk *irk;
2638 3079
2639 if (type & HCI_SMP_LTK) 3080 irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2640 mgmt_new_ltk(hdev, key, 1); 3081 if (!irk) {
3082 irk = kzalloc(sizeof(*irk), GFP_KERNEL);
3083 if (!irk)
3084 return NULL;
2641 3085
2642 return 0; 3086 bacpy(&irk->bdaddr, bdaddr);
3087 irk->addr_type = addr_type;
3088
3089 list_add(&irk->list, &hdev->identity_resolving_keys);
3090 }
3091
3092 memcpy(irk->val, val, 16);
3093 bacpy(&irk->rpa, rpa);
3094
3095 return irk;
2643} 3096}
2644 3097
2645int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 3098int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
@@ -2658,21 +3111,38 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
2658 return 0; 3111 return 0;
2659} 3112}
2660 3113
2661int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 3114int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2662{ 3115{
2663 struct smp_ltk *k, *tmp; 3116 struct smp_ltk *k, *tmp;
3117 int removed = 0;
2664 3118
2665 list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 3119 list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2666 if (bacmp(bdaddr, &k->bdaddr)) 3120 if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2667 continue; 3121 continue;
2668 3122
2669 BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3123 BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2670 3124
2671 list_del(&k->list); 3125 list_del(&k->list);
2672 kfree(k); 3126 kfree(k);
3127 removed++;
2673 } 3128 }
2674 3129
2675 return 0; 3130 return removed ? 0 : -ENOENT;
3131}
3132
3133void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
3134{
3135 struct smp_irk *k, *tmp;
3136
3137 list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
3138 if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
3139 continue;
3140
3141 BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3142
3143 list_del(&k->list);
3144 kfree(k);
3145 }
2676} 3146}
2677 3147
2678/* HCI command timer function */ 3148/* HCI command timer function */
@@ -2721,7 +3191,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
2721 return 0; 3191 return 0;
2722} 3192}
2723 3193
2724int hci_remote_oob_data_clear(struct hci_dev *hdev) 3194void hci_remote_oob_data_clear(struct hci_dev *hdev)
2725{ 3195{
2726 struct oob_data *data, *n; 3196 struct oob_data *data, *n;
2727 3197
@@ -2729,19 +3199,43 @@ int hci_remote_oob_data_clear(struct hci_dev *hdev)
2729 list_del(&data->list); 3199 list_del(&data->list);
2730 kfree(data); 3200 kfree(data);
2731 } 3201 }
3202}
3203
3204int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
3205 u8 *hash, u8 *randomizer)
3206{
3207 struct oob_data *data;
3208
3209 data = hci_find_remote_oob_data(hdev, bdaddr);
3210 if (!data) {
3211 data = kmalloc(sizeof(*data), GFP_KERNEL);
3212 if (!data)
3213 return -ENOMEM;
3214
3215 bacpy(&data->bdaddr, bdaddr);
3216 list_add(&data->list, &hdev->remote_oob_data);
3217 }
3218
3219 memcpy(data->hash192, hash, sizeof(data->hash192));
3220 memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
3221
3222 memset(data->hash256, 0, sizeof(data->hash256));
3223 memset(data->randomizer256, 0, sizeof(data->randomizer256));
3224
3225 BT_DBG("%s for %pMR", hdev->name, bdaddr);
2732 3226
2733 return 0; 3227 return 0;
2734} 3228}
2735 3229
2736int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 3230int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
2737 u8 *randomizer) 3231 u8 *hash192, u8 *randomizer192,
3232 u8 *hash256, u8 *randomizer256)
2738{ 3233{
2739 struct oob_data *data; 3234 struct oob_data *data;
2740 3235
2741 data = hci_find_remote_oob_data(hdev, bdaddr); 3236 data = hci_find_remote_oob_data(hdev, bdaddr);
2742
2743 if (!data) { 3237 if (!data) {
2744 data = kmalloc(sizeof(*data), GFP_ATOMIC); 3238 data = kmalloc(sizeof(*data), GFP_KERNEL);
2745 if (!data) 3239 if (!data)
2746 return -ENOMEM; 3240 return -ENOMEM;
2747 3241
@@ -2749,8 +3243,11 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
2749 list_add(&data->list, &hdev->remote_oob_data); 3243 list_add(&data->list, &hdev->remote_oob_data);
2750 } 3244 }
2751 3245
2752 memcpy(data->hash, hash, sizeof(data->hash)); 3246 memcpy(data->hash192, hash192, sizeof(data->hash192));
2753 memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 3247 memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
3248
3249 memcpy(data->hash256, hash256, sizeof(data->hash256));
3250 memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
2754 3251
2755 BT_DBG("%s for %pMR", hdev->name, bdaddr); 3252 BT_DBG("%s for %pMR", hdev->name, bdaddr);
2756 3253
@@ -2770,7 +3267,7 @@ struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
2770 return NULL; 3267 return NULL;
2771} 3268}
2772 3269
2773int hci_blacklist_clear(struct hci_dev *hdev) 3270static void hci_blacklist_clear(struct hci_dev *hdev)
2774{ 3271{
2775 struct list_head *p, *n; 3272 struct list_head *p, *n;
2776 3273
@@ -2780,8 +3277,6 @@ int hci_blacklist_clear(struct hci_dev *hdev)
2780 list_del(p); 3277 list_del(p);
2781 kfree(b); 3278 kfree(b);
2782 } 3279 }
2783
2784 return 0;
2785} 3280}
2786 3281
2787int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3282int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
@@ -2810,8 +3305,10 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2810{ 3305{
2811 struct bdaddr_list *entry; 3306 struct bdaddr_list *entry;
2812 3307
2813 if (!bacmp(bdaddr, BDADDR_ANY)) 3308 if (!bacmp(bdaddr, BDADDR_ANY)) {
2814 return hci_blacklist_clear(hdev); 3309 hci_blacklist_clear(hdev);
3310 return 0;
3311 }
2815 3312
2816 entry = hci_blacklist_lookup(hdev, bdaddr, type); 3313 entry = hci_blacklist_lookup(hdev, bdaddr, type);
2817 if (!entry) 3314 if (!entry)
@@ -2823,6 +3320,262 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2823 return mgmt_device_unblocked(hdev, bdaddr, type); 3320 return mgmt_device_unblocked(hdev, bdaddr, type);
2824} 3321}
2825 3322
3323struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev,
3324 bdaddr_t *bdaddr, u8 type)
3325{
3326 struct bdaddr_list *b;
3327
3328 list_for_each_entry(b, &hdev->le_white_list, list) {
3329 if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3330 return b;
3331 }
3332
3333 return NULL;
3334}
3335
3336void hci_white_list_clear(struct hci_dev *hdev)
3337{
3338 struct list_head *p, *n;
3339
3340 list_for_each_safe(p, n, &hdev->le_white_list) {
3341 struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3342
3343 list_del(p);
3344 kfree(b);
3345 }
3346}
3347
3348int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3349{
3350 struct bdaddr_list *entry;
3351
3352 if (!bacmp(bdaddr, BDADDR_ANY))
3353 return -EBADF;
3354
3355 entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
3356 if (!entry)
3357 return -ENOMEM;
3358
3359 bacpy(&entry->bdaddr, bdaddr);
3360 entry->bdaddr_type = type;
3361
3362 list_add(&entry->list, &hdev->le_white_list);
3363
3364 return 0;
3365}
3366
3367int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3368{
3369 struct bdaddr_list *entry;
3370
3371 if (!bacmp(bdaddr, BDADDR_ANY))
3372 return -EBADF;
3373
3374 entry = hci_white_list_lookup(hdev, bdaddr, type);
3375 if (!entry)
3376 return -ENOENT;
3377
3378 list_del(&entry->list);
3379 kfree(entry);
3380
3381 return 0;
3382}
3383
3384/* This function requires the caller holds hdev->lock */
3385struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
3386 bdaddr_t *addr, u8 addr_type)
3387{
3388 struct hci_conn_params *params;
3389
3390 list_for_each_entry(params, &hdev->le_conn_params, list) {
3391 if (bacmp(&params->addr, addr) == 0 &&
3392 params->addr_type == addr_type) {
3393 return params;
3394 }
3395 }
3396
3397 return NULL;
3398}
3399
3400static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
3401{
3402 struct hci_conn *conn;
3403
3404 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
3405 if (!conn)
3406 return false;
3407
3408 if (conn->dst_type != type)
3409 return false;
3410
3411 if (conn->state != BT_CONNECTED)
3412 return false;
3413
3414 return true;
3415}
3416
3417static bool is_identity_address(bdaddr_t *addr, u8 addr_type)
3418{
3419 if (addr_type == ADDR_LE_DEV_PUBLIC)
3420 return true;
3421
3422 /* Check for Random Static address type */
3423 if ((addr->b[5] & 0xc0) == 0xc0)
3424 return true;
3425
3426 return false;
3427}
3428
3429/* This function requires the caller holds hdev->lock */
3430int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
3431 u8 auto_connect, u16 conn_min_interval,
3432 u16 conn_max_interval)
3433{
3434 struct hci_conn_params *params;
3435
3436 if (!is_identity_address(addr, addr_type))
3437 return -EINVAL;
3438
3439 params = hci_conn_params_lookup(hdev, addr, addr_type);
3440 if (params)
3441 goto update;
3442
3443 params = kzalloc(sizeof(*params), GFP_KERNEL);
3444 if (!params) {
3445 BT_ERR("Out of memory");
3446 return -ENOMEM;
3447 }
3448
3449 bacpy(&params->addr, addr);
3450 params->addr_type = addr_type;
3451
3452 list_add(&params->list, &hdev->le_conn_params);
3453
3454update:
3455 params->conn_min_interval = conn_min_interval;
3456 params->conn_max_interval = conn_max_interval;
3457 params->auto_connect = auto_connect;
3458
3459 switch (auto_connect) {
3460 case HCI_AUTO_CONN_DISABLED:
3461 case HCI_AUTO_CONN_LINK_LOSS:
3462 hci_pend_le_conn_del(hdev, addr, addr_type);
3463 break;
3464 case HCI_AUTO_CONN_ALWAYS:
3465 if (!is_connected(hdev, addr, addr_type))
3466 hci_pend_le_conn_add(hdev, addr, addr_type);
3467 break;
3468 }
3469
3470 BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x "
3471 "conn_max_interval 0x%.4x", addr, addr_type, auto_connect,
3472 conn_min_interval, conn_max_interval);
3473
3474 return 0;
3475}
3476
3477/* This function requires the caller holds hdev->lock */
3478void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
3479{
3480 struct hci_conn_params *params;
3481
3482 params = hci_conn_params_lookup(hdev, addr, addr_type);
3483 if (!params)
3484 return;
3485
3486 hci_pend_le_conn_del(hdev, addr, addr_type);
3487
3488 list_del(&params->list);
3489 kfree(params);
3490
3491 BT_DBG("addr %pMR (type %u)", addr, addr_type);
3492}
3493
3494/* This function requires the caller holds hdev->lock */
3495void hci_conn_params_clear(struct hci_dev *hdev)
3496{
3497 struct hci_conn_params *params, *tmp;
3498
3499 list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
3500 list_del(&params->list);
3501 kfree(params);
3502 }
3503
3504 BT_DBG("All LE connection parameters were removed");
3505}
3506
3507/* This function requires the caller holds hdev->lock */
3508struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
3509 bdaddr_t *addr, u8 addr_type)
3510{
3511 struct bdaddr_list *entry;
3512
3513 list_for_each_entry(entry, &hdev->pend_le_conns, list) {
3514 if (bacmp(&entry->bdaddr, addr) == 0 &&
3515 entry->bdaddr_type == addr_type)
3516 return entry;
3517 }
3518
3519 return NULL;
3520}
3521
3522/* This function requires the caller holds hdev->lock */
3523void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
3524{
3525 struct bdaddr_list *entry;
3526
3527 entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
3528 if (entry)
3529 goto done;
3530
3531 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
3532 if (!entry) {
3533 BT_ERR("Out of memory");
3534 return;
3535 }
3536
3537 bacpy(&entry->bdaddr, addr);
3538 entry->bdaddr_type = addr_type;
3539
3540 list_add(&entry->list, &hdev->pend_le_conns);
3541
3542 BT_DBG("addr %pMR (type %u)", addr, addr_type);
3543
3544done:
3545 hci_update_background_scan(hdev);
3546}
3547
3548/* This function requires the caller holds hdev->lock */
3549void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
3550{
3551 struct bdaddr_list *entry;
3552
3553 entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
3554 if (!entry)
3555 goto done;
3556
3557 list_del(&entry->list);
3558 kfree(entry);
3559
3560 BT_DBG("addr %pMR (type %u)", addr, addr_type);
3561
3562done:
3563 hci_update_background_scan(hdev);
3564}
3565
3566/* This function requires the caller holds hdev->lock */
3567void hci_pend_le_conns_clear(struct hci_dev *hdev)
3568{
3569 struct bdaddr_list *entry, *tmp;
3570
3571 list_for_each_entry_safe(entry, tmp, &hdev->pend_le_conns, list) {
3572 list_del(&entry->list);
3573 kfree(entry);
3574 }
3575
3576 BT_DBG("All LE pending connections cleared");
3577}
3578
2826static void inquiry_complete(struct hci_dev *hdev, u8 status) 3579static void inquiry_complete(struct hci_dev *hdev, u8 status)
2827{ 3580{
2828 if (status) { 3581 if (status) {
@@ -2882,7 +3635,6 @@ static void le_scan_disable_work(struct work_struct *work)
2882{ 3635{
2883 struct hci_dev *hdev = container_of(work, struct hci_dev, 3636 struct hci_dev *hdev = container_of(work, struct hci_dev,
2884 le_scan_disable.work); 3637 le_scan_disable.work);
2885 struct hci_cp_le_set_scan_enable cp;
2886 struct hci_request req; 3638 struct hci_request req;
2887 int err; 3639 int err;
2888 3640
@@ -2890,15 +3642,128 @@ static void le_scan_disable_work(struct work_struct *work)
2890 3642
2891 hci_req_init(&req, hdev); 3643 hci_req_init(&req, hdev);
2892 3644
2893 memset(&cp, 0, sizeof(cp)); 3645 hci_req_add_le_scan_disable(&req);
2894 cp.enable = LE_SCAN_DISABLE;
2895 hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
2896 3646
2897 err = hci_req_run(&req, le_scan_disable_work_complete); 3647 err = hci_req_run(&req, le_scan_disable_work_complete);
2898 if (err) 3648 if (err)
2899 BT_ERR("Disable LE scanning request failed: err %d", err); 3649 BT_ERR("Disable LE scanning request failed: err %d", err);
2900} 3650}
2901 3651
3652static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
3653{
3654 struct hci_dev *hdev = req->hdev;
3655
3656 /* If we're advertising or initiating an LE connection we can't
3657 * go ahead and change the random address at this time. This is
3658 * because the eventual initiator address used for the
3659 * subsequently created connection will be undefined (some
3660 * controllers use the new address and others the one we had
3661 * when the operation started).
3662 *
3663 * In this kind of scenario skip the update and let the random
3664 * address be updated at the next cycle.
3665 */
3666 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) ||
3667 hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
3668 BT_DBG("Deferring random address update");
3669 return;
3670 }
3671
3672 hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa);
3673}
3674
3675int hci_update_random_address(struct hci_request *req, bool require_privacy,
3676 u8 *own_addr_type)
3677{
3678 struct hci_dev *hdev = req->hdev;
3679 int err;
3680
3681 /* If privacy is enabled use a resolvable private address. If
3682 * current RPA has expired or there is something else than
3683 * the current RPA in use, then generate a new one.
3684 */
3685 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3686 int to;
3687
3688 *own_addr_type = ADDR_LE_DEV_RANDOM;
3689
3690 if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) &&
3691 !bacmp(&hdev->random_addr, &hdev->rpa))
3692 return 0;
3693
3694 err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa);
3695 if (err < 0) {
3696 BT_ERR("%s failed to generate new RPA", hdev->name);
3697 return err;
3698 }
3699
3700 set_random_addr(req, &hdev->rpa);
3701
3702 to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
3703 queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);
3704
3705 return 0;
3706 }
3707
3708 /* In case of required privacy without resolvable private address,
3709 * use an unresolvable private address. This is useful for active
3710 * scanning and non-connectable advertising.
3711 */
3712 if (require_privacy) {
3713 bdaddr_t urpa;
3714
3715 get_random_bytes(&urpa, 6);
3716 urpa.b[5] &= 0x3f; /* Clear two most significant bits */
3717
3718 *own_addr_type = ADDR_LE_DEV_RANDOM;
3719 set_random_addr(req, &urpa);
3720 return 0;
3721 }
3722
3723 /* If forcing static address is in use or there is no public
3724 * address use the static address as random address (but skip
3725 * the HCI command if the current random address is already the
3726 * static one.
3727 */
3728 if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
3729 !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3730 *own_addr_type = ADDR_LE_DEV_RANDOM;
3731 if (bacmp(&hdev->static_addr, &hdev->random_addr))
3732 hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
3733 &hdev->static_addr);
3734 return 0;
3735 }
3736
3737 /* Neither privacy nor static address is being used so use a
3738 * public address.
3739 */
3740 *own_addr_type = ADDR_LE_DEV_PUBLIC;
3741
3742 return 0;
3743}
3744
3745/* Copy the Identity Address of the controller.
3746 *
3747 * If the controller has a public BD_ADDR, then by default use that one.
3748 * If this is a LE only controller without a public address, default to
3749 * the static random address.
3750 *
3751 * For debugging purposes it is possible to force controllers with a
3752 * public address to use the static random address instead.
3753 */
3754void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3755 u8 *bdaddr_type)
3756{
3757 if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
3758 !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3759 bacpy(bdaddr, &hdev->static_addr);
3760 *bdaddr_type = ADDR_LE_DEV_RANDOM;
3761 } else {
3762 bacpy(bdaddr, &hdev->bdaddr);
3763 *bdaddr_type = ADDR_LE_DEV_PUBLIC;
3764 }
3765}
3766
2902/* Alloc HCI device */ 3767/* Alloc HCI device */
2903struct hci_dev *hci_alloc_dev(void) 3768struct hci_dev *hci_alloc_dev(void)
2904{ 3769{
@@ -2919,11 +3784,14 @@ struct hci_dev *hci_alloc_dev(void)
2919 hdev->sniff_max_interval = 800; 3784 hdev->sniff_max_interval = 800;
2920 hdev->sniff_min_interval = 80; 3785 hdev->sniff_min_interval = 80;
2921 3786
3787 hdev->le_adv_channel_map = 0x07;
2922 hdev->le_scan_interval = 0x0060; 3788 hdev->le_scan_interval = 0x0060;
2923 hdev->le_scan_window = 0x0030; 3789 hdev->le_scan_window = 0x0030;
2924 hdev->le_conn_min_interval = 0x0028; 3790 hdev->le_conn_min_interval = 0x0028;
2925 hdev->le_conn_max_interval = 0x0038; 3791 hdev->le_conn_max_interval = 0x0038;
2926 3792
3793 hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3794
2927 mutex_init(&hdev->lock); 3795 mutex_init(&hdev->lock);
2928 mutex_init(&hdev->req_lock); 3796 mutex_init(&hdev->req_lock);
2929 3797
@@ -2932,7 +3800,11 @@ struct hci_dev *hci_alloc_dev(void)
2932 INIT_LIST_HEAD(&hdev->uuids); 3800 INIT_LIST_HEAD(&hdev->uuids);
2933 INIT_LIST_HEAD(&hdev->link_keys); 3801 INIT_LIST_HEAD(&hdev->link_keys);
2934 INIT_LIST_HEAD(&hdev->long_term_keys); 3802 INIT_LIST_HEAD(&hdev->long_term_keys);
3803 INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2935 INIT_LIST_HEAD(&hdev->remote_oob_data); 3804 INIT_LIST_HEAD(&hdev->remote_oob_data);
3805 INIT_LIST_HEAD(&hdev->le_white_list);
3806 INIT_LIST_HEAD(&hdev->le_conn_params);
3807 INIT_LIST_HEAD(&hdev->pend_le_conns);
2936 INIT_LIST_HEAD(&hdev->conn_hash.list); 3808 INIT_LIST_HEAD(&hdev->conn_hash.list);
2937 3809
2938 INIT_WORK(&hdev->rx_work, hci_rx_work); 3810 INIT_WORK(&hdev->rx_work, hci_rx_work);
@@ -3017,9 +3889,18 @@ int hci_register_dev(struct hci_dev *hdev)
3017 3889
3018 dev_set_name(&hdev->dev, "%s", hdev->name); 3890 dev_set_name(&hdev->dev, "%s", hdev->name);
3019 3891
3892 hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
3893 CRYPTO_ALG_ASYNC);
3894 if (IS_ERR(hdev->tfm_aes)) {
3895 BT_ERR("Unable to create crypto context");
3896 error = PTR_ERR(hdev->tfm_aes);
3897 hdev->tfm_aes = NULL;
3898 goto err_wqueue;
3899 }
3900
3020 error = device_add(&hdev->dev); 3901 error = device_add(&hdev->dev);
3021 if (error < 0) 3902 if (error < 0)
3022 goto err_wqueue; 3903 goto err_tfm;
3023 3904
3024 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3905 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3025 RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3906 RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
@@ -3055,6 +3936,8 @@ int hci_register_dev(struct hci_dev *hdev)
3055 3936
3056 return id; 3937 return id;
3057 3938
3939err_tfm:
3940 crypto_free_blkcipher(hdev->tfm_aes);
3058err_wqueue: 3941err_wqueue:
3059 destroy_workqueue(hdev->workqueue); 3942 destroy_workqueue(hdev->workqueue);
3060 destroy_workqueue(hdev->req_workqueue); 3943 destroy_workqueue(hdev->req_workqueue);
@@ -3105,6 +3988,9 @@ void hci_unregister_dev(struct hci_dev *hdev)
3105 rfkill_destroy(hdev->rfkill); 3988 rfkill_destroy(hdev->rfkill);
3106 } 3989 }
3107 3990
3991 if (hdev->tfm_aes)
3992 crypto_free_blkcipher(hdev->tfm_aes);
3993
3108 device_del(&hdev->dev); 3994 device_del(&hdev->dev);
3109 3995
3110 debugfs_remove_recursive(hdev->debugfs); 3996 debugfs_remove_recursive(hdev->debugfs);
@@ -3117,7 +4003,11 @@ void hci_unregister_dev(struct hci_dev *hdev)
3117 hci_uuids_clear(hdev); 4003 hci_uuids_clear(hdev);
3118 hci_link_keys_clear(hdev); 4004 hci_link_keys_clear(hdev);
3119 hci_smp_ltks_clear(hdev); 4005 hci_smp_ltks_clear(hdev);
4006 hci_smp_irks_clear(hdev);
3120 hci_remote_oob_data_clear(hdev); 4007 hci_remote_oob_data_clear(hdev);
4008 hci_white_list_clear(hdev);
4009 hci_conn_params_clear(hdev);
4010 hci_pend_le_conns_clear(hdev);
3121 hci_dev_unlock(hdev); 4011 hci_dev_unlock(hdev);
3122 4012
3123 hci_dev_put(hdev); 4013 hci_dev_put(hdev);
@@ -4345,3 +5235,102 @@ static void hci_cmd_work(struct work_struct *work)
4345 } 5235 }
4346 } 5236 }
4347} 5237}
5238
5239void hci_req_add_le_scan_disable(struct hci_request *req)
5240{
5241 struct hci_cp_le_set_scan_enable cp;
5242
5243 memset(&cp, 0, sizeof(cp));
5244 cp.enable = LE_SCAN_DISABLE;
5245 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
5246}
5247
5248void hci_req_add_le_passive_scan(struct hci_request *req)
5249{
5250 struct hci_cp_le_set_scan_param param_cp;
5251 struct hci_cp_le_set_scan_enable enable_cp;
5252 struct hci_dev *hdev = req->hdev;
5253 u8 own_addr_type;
5254
5255 /* Set require_privacy to true to avoid identification from
5256 * unknown peer devices. Since this is passive scanning, no
5257 * SCAN_REQ using the local identity should be sent. Mandating
5258 * privacy is just an extra precaution.
5259 */
5260 if (hci_update_random_address(req, true, &own_addr_type))
5261 return;
5262
5263 memset(&param_cp, 0, sizeof(param_cp));
5264 param_cp.type = LE_SCAN_PASSIVE;
5265 param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
5266 param_cp.window = cpu_to_le16(hdev->le_scan_window);
5267 param_cp.own_address_type = own_addr_type;
5268 hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
5269 &param_cp);
5270
5271 memset(&enable_cp, 0, sizeof(enable_cp));
5272 enable_cp.enable = LE_SCAN_ENABLE;
5273 enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
5274 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
5275 &enable_cp);
5276}
5277
5278static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
5279{
5280 if (status)
5281 BT_DBG("HCI request failed to update background scanning: "
5282 "status 0x%2.2x", status);
5283}
5284
5285/* This function controls the background scanning based on hdev->pend_le_conns
5286 * list. If there are pending LE connection we start the background scanning,
5287 * otherwise we stop it.
5288 *
5289 * This function requires the caller holds hdev->lock.
5290 */
5291void hci_update_background_scan(struct hci_dev *hdev)
5292{
5293 struct hci_request req;
5294 struct hci_conn *conn;
5295 int err;
5296
5297 hci_req_init(&req, hdev);
5298
5299 if (list_empty(&hdev->pend_le_conns)) {
5300 /* If there is no pending LE connections, we should stop
5301 * the background scanning.
5302 */
5303
5304 /* If controller is not scanning we are done. */
5305 if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
5306 return;
5307
5308 hci_req_add_le_scan_disable(&req);
5309
5310 BT_DBG("%s stopping background scanning", hdev->name);
5311 } else {
5312 /* If there is at least one pending LE connection, we should
5313 * keep the background scan running.
5314 */
5315
5316 /* If controller is already scanning we are done. */
5317 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
5318 return;
5319
5320 /* If controller is connecting, we should not start scanning
5321 * since some controllers are not able to scan and connect at
5322 * the same time.
5323 */
5324 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
5325 if (conn)
5326 return;
5327
5328 hci_req_add_le_passive_scan(&req);
5329
5330 BT_DBG("%s starting background scanning", hdev->name);
5331 }
5332
5333 err = hci_req_run(&req, update_background_scan_complete);
5334 if (err)
5335 BT_ERR("Failed to run HCI request: err %d", err);
5336}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 5f812455a450..c3b0a08f5ab4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -461,6 +461,34 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
461 } 461 }
462} 462}
463 463
464static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
465{
466 u8 status = *((u8 *) skb->data);
467 struct hci_cp_write_sc_support *sent;
468
469 BT_DBG("%s status 0x%2.2x", hdev->name, status);
470
471 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
472 if (!sent)
473 return;
474
475 if (!status) {
476 if (sent->support)
477 hdev->features[1][0] |= LMP_HOST_SC;
478 else
479 hdev->features[1][0] &= ~LMP_HOST_SC;
480 }
481
482 if (test_bit(HCI_MGMT, &hdev->dev_flags))
483 mgmt_sc_enable_complete(hdev, sent->support, status);
484 else if (!status) {
485 if (sent->support)
486 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
487 else
488 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
489 }
490}
491
464static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 492static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
465{ 493{
466 struct hci_rp_read_local_version *rp = (void *) skb->data; 494 struct hci_rp_read_local_version *rp = (void *) skb->data;
@@ -904,16 +932,50 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
904 hci_dev_unlock(hdev); 932 hci_dev_unlock(hdev);
905} 933}
906 934
907static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, 935static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
908 struct sk_buff *skb) 936 struct sk_buff *skb)
909{ 937{
910 struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 938 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
911 939
912 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 940 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
913 941
914 hci_dev_lock(hdev); 942 hci_dev_lock(hdev);
915 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, 943 mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
916 rp->randomizer, rp->status); 944 NULL, NULL, rp->status);
945 hci_dev_unlock(hdev);
946}
947
948static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
949 struct sk_buff *skb)
950{
951 struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
952
953 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
954
955 hci_dev_lock(hdev);
956 mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
957 rp->hash256, rp->randomizer256,
958 rp->status);
959 hci_dev_unlock(hdev);
960}
961
962
963static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
964{
965 __u8 status = *((__u8 *) skb->data);
966 bdaddr_t *sent;
967
968 BT_DBG("%s status 0x%2.2x", hdev->name, status);
969
970 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
971 if (!sent)
972 return;
973
974 hci_dev_lock(hdev);
975
976 if (!status)
977 bacpy(&hdev->random_addr, sent);
978
917 hci_dev_unlock(hdev); 979 hci_dev_unlock(hdev);
918} 980}
919 981
@@ -929,12 +991,8 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
929 991
930 hci_dev_lock(hdev); 992 hci_dev_lock(hdev);
931 993
932 if (!status) { 994 if (!status)
933 if (*sent) 995 mgmt_advertising(hdev, *sent);
934 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
935 else
936 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
937 }
938 996
939 hci_dev_unlock(hdev); 997 hci_dev_unlock(hdev);
940} 998}
@@ -960,7 +1018,19 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
960 break; 1018 break;
961 1019
962 case LE_SCAN_DISABLE: 1020 case LE_SCAN_DISABLE:
1021 /* Cancel this timer so that we don't try to disable scanning
1022 * when it's already disabled.
1023 */
1024 cancel_delayed_work(&hdev->le_scan_disable);
1025
963 clear_bit(HCI_LE_SCAN, &hdev->dev_flags); 1026 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1027 /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
1028 * interrupted scanning due to a connect request. Mark
1029 * therefore discovery as stopped.
1030 */
1031 if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
1032 &hdev->dev_flags))
1033 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
964 break; 1034 break;
965 1035
966 default: 1036 default:
@@ -980,6 +1050,49 @@ static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
980 hdev->le_white_list_size = rp->size; 1050 hdev->le_white_list_size = rp->size;
981} 1051}
982 1052
1053static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
1054 struct sk_buff *skb)
1055{
1056 __u8 status = *((__u8 *) skb->data);
1057
1058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1059
1060 if (!status)
1061 hci_white_list_clear(hdev);
1062}
1063
1064static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
1065 struct sk_buff *skb)
1066{
1067 struct hci_cp_le_add_to_white_list *sent;
1068 __u8 status = *((__u8 *) skb->data);
1069
1070 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1071
1072 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
1073 if (!sent)
1074 return;
1075
1076 if (!status)
1077 hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
1078}
1079
1080static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
1081 struct sk_buff *skb)
1082{
1083 struct hci_cp_le_del_from_white_list *sent;
1084 __u8 status = *((__u8 *) skb->data);
1085
1086 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1087
1088 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
1089 if (!sent)
1090 return;
1091
1092 if (!status)
1093 hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
1094}
1095
983static void hci_cc_le_read_supported_states(struct hci_dev *hdev, 1096static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
984 struct sk_buff *skb) 1097 struct sk_buff *skb)
985{ 1098{
@@ -1020,6 +1133,25 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1020 } 1133 }
1021} 1134}
1022 1135
1136static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1137{
1138 struct hci_cp_le_set_adv_param *cp;
1139 u8 status = *((u8 *) skb->data);
1140
1141 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1142
1143 if (status)
1144 return;
1145
1146 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1147 if (!cp)
1148 return;
1149
1150 hci_dev_lock(hdev);
1151 hdev->adv_addr_type = cp->own_address_type;
1152 hci_dev_unlock(hdev);
1153}
1154
1023static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, 1155static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1024 struct sk_buff *skb) 1156 struct sk_buff *skb)
1025{ 1157{
@@ -1185,9 +1317,12 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
1185 return 0; 1317 return 0;
1186 1318
1187 /* Only request authentication for SSP connections or non-SSP 1319 /* Only request authentication for SSP connections or non-SSP
1188 * devices with sec_level HIGH or if MITM protection is requested */ 1320 * devices with sec_level MEDIUM or HIGH or if MITM protection
1321 * is requested.
1322 */
1189 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 1323 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1190 conn->pending_sec_level != BT_SECURITY_HIGH) 1324 conn->pending_sec_level != BT_SECURITY_HIGH &&
1325 conn->pending_sec_level != BT_SECURITY_MEDIUM)
1191 return 0; 1326 return 0;
1192 1327
1193 return 1; 1328 return 1;
@@ -1518,6 +1653,57 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1518 amp_write_remote_assoc(hdev, cp->phy_handle); 1653 amp_write_remote_assoc(hdev, cp->phy_handle);
1519} 1654}
1520 1655
1656static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1657{
1658 struct hci_cp_le_create_conn *cp;
1659 struct hci_conn *conn;
1660
1661 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1662
1663 /* All connection failure handling is taken care of by the
1664 * hci_le_conn_failed function which is triggered by the HCI
1665 * request completion callbacks used for connecting.
1666 */
1667 if (status)
1668 return;
1669
1670 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1671 if (!cp)
1672 return;
1673
1674 hci_dev_lock(hdev);
1675
1676 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1677 if (!conn)
1678 goto unlock;
1679
1680 /* Store the initiator and responder address information which
1681 * is needed for SMP. These values will not change during the
1682 * lifetime of the connection.
1683 */
1684 conn->init_addr_type = cp->own_address_type;
1685 if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1686 bacpy(&conn->init_addr, &hdev->random_addr);
1687 else
1688 bacpy(&conn->init_addr, &hdev->bdaddr);
1689
1690 conn->resp_addr_type = cp->peer_addr_type;
1691 bacpy(&conn->resp_addr, &cp->peer_addr);
1692
1693 /* We don't want the connection attempt to stick around
1694 * indefinitely since LE doesn't have a page timeout concept
1695 * like BR/EDR. Set a timer for any connection that doesn't use
1696 * the white list for connecting.
1697 */
1698 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1699 queue_delayed_work(conn->hdev->workqueue,
1700 &conn->le_conn_timeout,
1701 HCI_LE_CONN_TIMEOUT);
1702
1703unlock:
1704 hci_dev_unlock(hdev);
1705}
1706
1521static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1707static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1522{ 1708{
1523 __u8 status = *((__u8 *) skb->data); 1709 __u8 status = *((__u8 *) skb->data);
@@ -1659,7 +1845,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1659 } else { 1845 } else {
1660 conn->state = BT_CLOSED; 1846 conn->state = BT_CLOSED;
1661 if (conn->type == ACL_LINK) 1847 if (conn->type == ACL_LINK)
1662 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, 1848 mgmt_connect_failed(hdev, &conn->dst, conn->type,
1663 conn->dst_type, ev->status); 1849 conn->dst_type, ev->status);
1664 } 1850 }
1665 1851
@@ -1780,7 +1966,9 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1780{ 1966{
1781 struct hci_ev_disconn_complete *ev = (void *) skb->data; 1967 struct hci_ev_disconn_complete *ev = (void *) skb->data;
1782 u8 reason = hci_to_mgmt_reason(ev->reason); 1968 u8 reason = hci_to_mgmt_reason(ev->reason);
1969 struct hci_conn_params *params;
1783 struct hci_conn *conn; 1970 struct hci_conn *conn;
1971 bool mgmt_connected;
1784 u8 type; 1972 u8 type;
1785 1973
1786 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 1974 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
@@ -1799,13 +1987,30 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1799 1987
1800 conn->state = BT_CLOSED; 1988 conn->state = BT_CLOSED;
1801 1989
1802 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 1990 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
1803 mgmt_device_disconnected(hdev, &conn->dst, conn->type, 1991 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
1804 conn->dst_type, reason); 1992 reason, mgmt_connected);
1805 1993
1806 if (conn->type == ACL_LINK && conn->flush_key) 1994 if (conn->type == ACL_LINK && conn->flush_key)
1807 hci_remove_link_key(hdev, &conn->dst); 1995 hci_remove_link_key(hdev, &conn->dst);
1808 1996
1997 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
1998 if (params) {
1999 switch (params->auto_connect) {
2000 case HCI_AUTO_CONN_LINK_LOSS:
2001 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2002 break;
2003 /* Fall through */
2004
2005 case HCI_AUTO_CONN_ALWAYS:
2006 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
2007 break;
2008
2009 default:
2010 break;
2011 }
2012 }
2013
1809 type = conn->type; 2014 type = conn->type;
1810 2015
1811 hci_proto_disconn_cfm(conn, ev->reason); 2016 hci_proto_disconn_cfm(conn, ev->reason);
@@ -1943,35 +2148,46 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1943 hci_dev_lock(hdev); 2148 hci_dev_lock(hdev);
1944 2149
1945 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2150 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1946 if (conn) { 2151 if (!conn)
1947 if (!ev->status) { 2152 goto unlock;
1948 if (ev->encrypt) {
1949 /* Encryption implies authentication */
1950 conn->link_mode |= HCI_LM_AUTH;
1951 conn->link_mode |= HCI_LM_ENCRYPT;
1952 conn->sec_level = conn->pending_sec_level;
1953 } else
1954 conn->link_mode &= ~HCI_LM_ENCRYPT;
1955 }
1956 2153
1957 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2154 if (!ev->status) {
2155 if (ev->encrypt) {
2156 /* Encryption implies authentication */
2157 conn->link_mode |= HCI_LM_AUTH;
2158 conn->link_mode |= HCI_LM_ENCRYPT;
2159 conn->sec_level = conn->pending_sec_level;
1958 2160
1959 if (ev->status && conn->state == BT_CONNECTED) { 2161 /* P-256 authentication key implies FIPS */
1960 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 2162 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
1961 hci_conn_drop(conn); 2163 conn->link_mode |= HCI_LM_FIPS;
1962 goto unlock; 2164
2165 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2166 conn->type == LE_LINK)
2167 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2168 } else {
2169 conn->link_mode &= ~HCI_LM_ENCRYPT;
2170 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
1963 } 2171 }
2172 }
1964 2173
1965 if (conn->state == BT_CONFIG) { 2174 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
1966 if (!ev->status)
1967 conn->state = BT_CONNECTED;
1968 2175
1969 hci_proto_connect_cfm(conn, ev->status); 2176 if (ev->status && conn->state == BT_CONNECTED) {
1970 hci_conn_drop(conn); 2177 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
1971 } else 2178 hci_conn_drop(conn);
1972 hci_encrypt_cfm(conn, ev->status, ev->encrypt); 2179 goto unlock;
1973 } 2180 }
1974 2181
2182 if (conn->state == BT_CONFIG) {
2183 if (!ev->status)
2184 conn->state = BT_CONNECTED;
2185
2186 hci_proto_connect_cfm(conn, ev->status);
2187 hci_conn_drop(conn);
2188 } else
2189 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2190
1975unlock: 2191unlock:
1976 hci_dev_unlock(hdev); 2192 hci_dev_unlock(hdev);
1977} 2193}
@@ -2144,6 +2360,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2144 hci_cc_write_ssp_mode(hdev, skb); 2360 hci_cc_write_ssp_mode(hdev, skb);
2145 break; 2361 break;
2146 2362
2363 case HCI_OP_WRITE_SC_SUPPORT:
2364 hci_cc_write_sc_support(hdev, skb);
2365 break;
2366
2147 case HCI_OP_READ_LOCAL_VERSION: 2367 case HCI_OP_READ_LOCAL_VERSION:
2148 hci_cc_read_local_version(hdev, skb); 2368 hci_cc_read_local_version(hdev, skb);
2149 break; 2369 break;
@@ -2213,7 +2433,11 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2213 break; 2433 break;
2214 2434
2215 case HCI_OP_READ_LOCAL_OOB_DATA: 2435 case HCI_OP_READ_LOCAL_OOB_DATA:
2216 hci_cc_read_local_oob_data_reply(hdev, skb); 2436 hci_cc_read_local_oob_data(hdev, skb);
2437 break;
2438
2439 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2440 hci_cc_read_local_oob_ext_data(hdev, skb);
2217 break; 2441 break;
2218 2442
2219 case HCI_OP_LE_READ_BUFFER_SIZE: 2443 case HCI_OP_LE_READ_BUFFER_SIZE:
@@ -2244,6 +2468,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2244 hci_cc_user_passkey_neg_reply(hdev, skb); 2468 hci_cc_user_passkey_neg_reply(hdev, skb);
2245 break; 2469 break;
2246 2470
2471 case HCI_OP_LE_SET_RANDOM_ADDR:
2472 hci_cc_le_set_random_addr(hdev, skb);
2473 break;
2474
2247 case HCI_OP_LE_SET_ADV_ENABLE: 2475 case HCI_OP_LE_SET_ADV_ENABLE:
2248 hci_cc_le_set_adv_enable(hdev, skb); 2476 hci_cc_le_set_adv_enable(hdev, skb);
2249 break; 2477 break;
@@ -2256,6 +2484,18 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2256 hci_cc_le_read_white_list_size(hdev, skb); 2484 hci_cc_le_read_white_list_size(hdev, skb);
2257 break; 2485 break;
2258 2486
2487 case HCI_OP_LE_CLEAR_WHITE_LIST:
2488 hci_cc_le_clear_white_list(hdev, skb);
2489 break;
2490
2491 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2492 hci_cc_le_add_to_white_list(hdev, skb);
2493 break;
2494
2495 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2496 hci_cc_le_del_from_white_list(hdev, skb);
2497 break;
2498
2259 case HCI_OP_LE_READ_SUPPORTED_STATES: 2499 case HCI_OP_LE_READ_SUPPORTED_STATES:
2260 hci_cc_le_read_supported_states(hdev, skb); 2500 hci_cc_le_read_supported_states(hdev, skb);
2261 break; 2501 break;
@@ -2264,6 +2504,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2264 hci_cc_write_le_host_supported(hdev, skb); 2504 hci_cc_write_le_host_supported(hdev, skb);
2265 break; 2505 break;
2266 2506
2507 case HCI_OP_LE_SET_ADV_PARAM:
2508 hci_cc_set_adv_param(hdev, skb);
2509 break;
2510
2267 case HCI_OP_WRITE_REMOTE_AMP_ASSOC: 2511 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2268 hci_cc_write_remote_amp_assoc(hdev, skb); 2512 hci_cc_write_remote_amp_assoc(hdev, skb);
2269 break; 2513 break;
@@ -2351,6 +2595,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2351 hci_cs_accept_phylink(hdev, ev->status); 2595 hci_cs_accept_phylink(hdev, ev->status);
2352 break; 2596 break;
2353 2597
2598 case HCI_OP_LE_CREATE_CONN:
2599 hci_cs_le_create_conn(hdev, ev->status);
2600 break;
2601
2354 default: 2602 default:
2355 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2603 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
2356 break; 2604 break;
@@ -2630,7 +2878,8 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2630 2878
2631 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2879 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2632 if (conn) { 2880 if (conn) {
2633 if (key->type == HCI_LK_UNAUTH_COMBINATION && 2881 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2882 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
2634 conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 2883 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
2635 BT_DBG("%s ignoring unauthenticated key", hdev->name); 2884 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2636 goto not_found; 2885 goto not_found;
@@ -2844,6 +3093,9 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2844 * features do not indicate SSP support */ 3093 * features do not indicate SSP support */
2845 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3094 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2846 } 3095 }
3096
3097 if (ev->features[0] & LMP_HOST_SC)
3098 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
2847 } 3099 }
2848 3100
2849 if (conn->state != BT_CONFIG) 3101 if (conn->state != BT_CONFIG)
@@ -3337,20 +3589,36 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3337 3589
3338 data = hci_find_remote_oob_data(hdev, &ev->bdaddr); 3590 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3339 if (data) { 3591 if (data) {
3340 struct hci_cp_remote_oob_data_reply cp; 3592 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3593 struct hci_cp_remote_oob_ext_data_reply cp;
3341 3594
3342 bacpy(&cp.bdaddr, &ev->bdaddr); 3595 bacpy(&cp.bdaddr, &ev->bdaddr);
3343 memcpy(cp.hash, data->hash, sizeof(cp.hash)); 3596 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3344 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer)); 3597 memcpy(cp.randomizer192, data->randomizer192,
3598 sizeof(cp.randomizer192));
3599 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3600 memcpy(cp.randomizer256, data->randomizer256,
3601 sizeof(cp.randomizer256));
3602
3603 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3604 sizeof(cp), &cp);
3605 } else {
3606 struct hci_cp_remote_oob_data_reply cp;
3607
3608 bacpy(&cp.bdaddr, &ev->bdaddr);
3609 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3610 memcpy(cp.randomizer, data->randomizer192,
3611 sizeof(cp.randomizer));
3345 3612
3346 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp), 3613 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3347 &cp); 3614 sizeof(cp), &cp);
3615 }
3348 } else { 3616 } else {
3349 struct hci_cp_remote_oob_data_neg_reply cp; 3617 struct hci_cp_remote_oob_data_neg_reply cp;
3350 3618
3351 bacpy(&cp.bdaddr, &ev->bdaddr); 3619 bacpy(&cp.bdaddr, &ev->bdaddr);
3352 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp), 3620 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3353 &cp); 3621 sizeof(cp), &cp);
3354 } 3622 }
3355 3623
3356unlock: 3624unlock:
@@ -3484,6 +3752,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3484{ 3752{
3485 struct hci_ev_le_conn_complete *ev = (void *) skb->data; 3753 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3486 struct hci_conn *conn; 3754 struct hci_conn *conn;
3755 struct smp_irk *irk;
3487 3756
3488 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3757 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3489 3758
@@ -3514,19 +3783,70 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3514 conn->out = true; 3783 conn->out = true;
3515 conn->link_mode |= HCI_LM_MASTER; 3784 conn->link_mode |= HCI_LM_MASTER;
3516 } 3785 }
3786
3787 /* If we didn't have a hci_conn object previously
3788 * but we're in master role this must be something
3789 * initiated using a white list. Since white list based
3790 * connections are not "first class citizens" we don't
3791 * have full tracking of them. Therefore, we go ahead
3792 * with a "best effort" approach of determining the
3793 * initiator address based on the HCI_PRIVACY flag.
3794 */
3795 if (conn->out) {
3796 conn->resp_addr_type = ev->bdaddr_type;
3797 bacpy(&conn->resp_addr, &ev->bdaddr);
3798 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3799 conn->init_addr_type = ADDR_LE_DEV_RANDOM;
3800 bacpy(&conn->init_addr, &hdev->rpa);
3801 } else {
3802 hci_copy_identity_address(hdev,
3803 &conn->init_addr,
3804 &conn->init_addr_type);
3805 }
3806 } else {
3807 /* Set the responder (our side) address type based on
3808 * the advertising address type.
3809 */
3810 conn->resp_addr_type = hdev->adv_addr_type;
3811 if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
3812 bacpy(&conn->resp_addr, &hdev->random_addr);
3813 else
3814 bacpy(&conn->resp_addr, &hdev->bdaddr);
3815
3816 conn->init_addr_type = ev->bdaddr_type;
3817 bacpy(&conn->init_addr, &ev->bdaddr);
3818 }
3819 } else {
3820 cancel_delayed_work(&conn->le_conn_timeout);
3821 }
3822
3823 /* Ensure that the hci_conn contains the identity address type
3824 * regardless of which address the connection was made with.
3825 */
3826 hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
3827
3828 /* Lookup the identity address from the stored connection
3829 * address and address type.
3830 *
3831 * When establishing connections to an identity address, the
3832 * connection procedure will store the resolvable random
3833 * address first. Now if it can be converted back into the
3834 * identity address, start using the identity address from
3835 * now on.
3836 */
3837 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
3838 if (irk) {
3839 bacpy(&conn->dst, &irk->bdaddr);
3840 conn->dst_type = irk->addr_type;
3517 } 3841 }
3518 3842
3519 if (ev->status) { 3843 if (ev->status) {
3520 mgmt_connect_failed(hdev, &conn->dst, conn->type, 3844 hci_le_conn_failed(conn, ev->status);
3521 conn->dst_type, ev->status);
3522 hci_proto_connect_cfm(conn, ev->status);
3523 conn->state = BT_CLOSED;
3524 hci_conn_del(conn);
3525 goto unlock; 3845 goto unlock;
3526 } 3846 }
3527 3847
3528 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 3848 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3529 mgmt_device_connected(hdev, &ev->bdaddr, conn->type, 3849 mgmt_device_connected(hdev, &conn->dst, conn->type,
3530 conn->dst_type, 0, NULL, 0, NULL); 3850 conn->dst_type, 0, NULL, 0, NULL);
3531 3851
3532 conn->sec_level = BT_SECURITY_LOW; 3852 conn->sec_level = BT_SECURITY_LOW;
@@ -3540,25 +3860,73 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3540 3860
3541 hci_proto_connect_cfm(conn, ev->status); 3861 hci_proto_connect_cfm(conn, ev->status);
3542 3862
3863 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3864
3543unlock: 3865unlock:
3544 hci_dev_unlock(hdev); 3866 hci_dev_unlock(hdev);
3545} 3867}
3546 3868
3869/* This function requires the caller holds hdev->lock */
3870static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3871 u8 addr_type)
3872{
3873 struct hci_conn *conn;
3874 struct smp_irk *irk;
3875
3876 /* If this is a resolvable address, we should resolve it and then
3877 * update address and address type variables.
3878 */
3879 irk = hci_get_irk(hdev, addr, addr_type);
3880 if (irk) {
3881 addr = &irk->bdaddr;
3882 addr_type = irk->addr_type;
3883 }
3884
3885 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
3886 return;
3887
3888 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
3889 HCI_AT_NO_BONDING);
3890 if (!IS_ERR(conn))
3891 return;
3892
3893 switch (PTR_ERR(conn)) {
3894 case -EBUSY:
3895 /* If hci_connect() returns -EBUSY it means there is already
3896 * an LE connection attempt going on. Since controllers don't
3897 * support more than one connection attempt at the time, we
3898 * don't consider this an error case.
3899 */
3900 break;
3901 default:
3902 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
3903 }
3904}
3905
3547static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 3906static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
3548{ 3907{
3549 u8 num_reports = skb->data[0]; 3908 u8 num_reports = skb->data[0];
3550 void *ptr = &skb->data[1]; 3909 void *ptr = &skb->data[1];
3551 s8 rssi; 3910 s8 rssi;
3552 3911
3912 hci_dev_lock(hdev);
3913
3553 while (num_reports--) { 3914 while (num_reports--) {
3554 struct hci_ev_le_advertising_info *ev = ptr; 3915 struct hci_ev_le_advertising_info *ev = ptr;
3555 3916
3917 if (ev->evt_type == LE_ADV_IND ||
3918 ev->evt_type == LE_ADV_DIRECT_IND)
3919 check_pending_le_conn(hdev, &ev->bdaddr,
3920 ev->bdaddr_type);
3921
3556 rssi = ev->data[ev->length]; 3922 rssi = ev->data[ev->length];
3557 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, 3923 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3558 NULL, rssi, 0, 1, ev->data, ev->length); 3924 NULL, rssi, 0, 1, ev->data, ev->length);
3559 3925
3560 ptr += sizeof(*ev) + ev->length + 1; 3926 ptr += sizeof(*ev) + ev->length + 1;
3561 } 3927 }
3928
3929 hci_dev_unlock(hdev);
3562} 3930}
3563 3931
3564static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 3932static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -3577,7 +3945,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3577 if (conn == NULL) 3945 if (conn == NULL)
3578 goto not_found; 3946 goto not_found;
3579 3947
3580 ltk = hci_find_ltk(hdev, ev->ediv, ev->random); 3948 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
3581 if (ltk == NULL) 3949 if (ltk == NULL)
3582 goto not_found; 3950 goto not_found;
3583 3951
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 7552f9e3089c..68e51a84e72d 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -716,6 +716,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
716 err = hci_dev_open(hdev->id); 716 err = hci_dev_open(hdev->id);
717 if (err) { 717 if (err) {
718 clear_bit(HCI_USER_CHANNEL, &hdev->dev_flags); 718 clear_bit(HCI_USER_CHANNEL, &hdev->dev_flags);
719 mgmt_index_added(hdev);
719 hci_dev_put(hdev); 720 hci_dev_put(hdev);
720 goto done; 721 goto done;
721 } 722 }
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 0b61250cfdf9..555982a78a58 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -49,14 +49,7 @@ static struct attribute *bt_link_attrs[] = {
49 NULL 49 NULL
50}; 50};
51 51
52static struct attribute_group bt_link_group = { 52ATTRIBUTE_GROUPS(bt_link);
53 .attrs = bt_link_attrs,
54};
55
56static const struct attribute_group *bt_link_groups[] = {
57 &bt_link_group,
58 NULL
59};
60 53
61static void bt_link_release(struct device *dev) 54static void bt_link_release(struct device *dev)
62{ 55{
@@ -182,14 +175,7 @@ static struct attribute *bt_host_attrs[] = {
182 NULL 175 NULL
183}; 176};
184 177
185static struct attribute_group bt_host_group = { 178ATTRIBUTE_GROUPS(bt_host);
186 .attrs = bt_host_attrs,
187};
188
189static const struct attribute_group *bt_host_groups[] = {
190 &bt_host_group,
191 NULL
192};
193 179
194static void bt_host_release(struct device *dev) 180static void bt_host_release(struct device *dev)
195{ 181{
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b0ad2c752d73..9ed2168fa59f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -42,6 +42,8 @@
42#include "amp.h" 42#include "amp.h"
43#include "6lowpan.h" 43#include "6lowpan.h"
44 44
45#define LE_FLOWCTL_MAX_CREDITS 65535
46
45bool disable_ertm; 47bool disable_ertm;
46 48
47static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD; 49static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
@@ -330,44 +332,20 @@ static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
330 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR; 332 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
331} 333}
332 334
333static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq) 335static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
334{ 336{
337 u16 seq = seq_list->head;
335 u16 mask = seq_list->mask; 338 u16 mask = seq_list->mask;
336 339
337 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) { 340 seq_list->head = seq_list->list[seq & mask];
338 /* In case someone tries to pop the head of an empty list */ 341 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
339 return L2CAP_SEQ_LIST_CLEAR;
340 } else if (seq_list->head == seq) {
341 /* Head can be removed in constant time */
342 seq_list->head = seq_list->list[seq & mask];
343 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
344
345 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
346 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
347 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
348 }
349 } else {
350 /* Walk the list to find the sequence number */
351 u16 prev = seq_list->head;
352 while (seq_list->list[prev & mask] != seq) {
353 prev = seq_list->list[prev & mask];
354 if (prev == L2CAP_SEQ_LIST_TAIL)
355 return L2CAP_SEQ_LIST_CLEAR;
356 }
357 342
358 /* Unlink the number from the list and clear it */ 343 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
359 seq_list->list[prev & mask] = seq_list->list[seq & mask]; 344 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
360 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR; 345 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
361 if (seq_list->tail == seq)
362 seq_list->tail = prev;
363 } 346 }
364 return seq;
365}
366 347
367static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list) 348 return seq;
368{
369 /* Remove the head in constant time */
370 return l2cap_seq_list_remove(seq_list, seq_list->head);
371} 349}
372 350
373static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list) 351static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
@@ -506,7 +484,7 @@ static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
506 chan->sdu_len = 0; 484 chan->sdu_len = 0;
507 chan->tx_credits = 0; 485 chan->tx_credits = 0;
508 chan->rx_credits = le_max_credits; 486 chan->rx_credits = le_max_credits;
509 chan->mps = min_t(u16, chan->imtu, L2CAP_LE_DEFAULT_MPS); 487 chan->mps = min_t(u16, chan->imtu, le_default_mps);
510 488
511 skb_queue_head_init(&chan->tx_q); 489 skb_queue_head_init(&chan->tx_q);
512} 490}
@@ -522,18 +500,10 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
522 500
523 switch (chan->chan_type) { 501 switch (chan->chan_type) {
524 case L2CAP_CHAN_CONN_ORIENTED: 502 case L2CAP_CHAN_CONN_ORIENTED:
525 if (conn->hcon->type == LE_LINK) { 503 /* Alloc CID for connection-oriented socket */
526 if (chan->dcid == L2CAP_CID_ATT) { 504 chan->scid = l2cap_alloc_cid(conn);
527 chan->omtu = L2CAP_DEFAULT_MTU; 505 if (conn->hcon->type == ACL_LINK)
528 chan->scid = L2CAP_CID_ATT;
529 } else {
530 chan->scid = l2cap_alloc_cid(conn);
531 }
532 } else {
533 /* Alloc CID for connection-oriented socket */
534 chan->scid = l2cap_alloc_cid(conn);
535 chan->omtu = L2CAP_DEFAULT_MTU; 506 chan->omtu = L2CAP_DEFAULT_MTU;
536 }
537 break; 507 break;
538 508
539 case L2CAP_CHAN_CONN_LESS: 509 case L2CAP_CHAN_CONN_LESS:
@@ -543,11 +513,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
543 chan->omtu = L2CAP_DEFAULT_MTU; 513 chan->omtu = L2CAP_DEFAULT_MTU;
544 break; 514 break;
545 515
546 case L2CAP_CHAN_CONN_FIX_A2MP: 516 case L2CAP_CHAN_FIXED:
547 chan->scid = L2CAP_CID_A2MP; 517 /* Caller will set CID and CID specific MTU values */
548 chan->dcid = L2CAP_CID_A2MP;
549 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
550 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
551 break; 518 break;
552 519
553 default: 520 default:
@@ -595,7 +562,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
595 562
596 chan->conn = NULL; 563 chan->conn = NULL;
597 564
598 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP) 565 if (chan->scid != L2CAP_CID_A2MP)
599 hci_conn_drop(conn->hcon); 566 hci_conn_drop(conn->hcon);
600 567
601 if (mgr && mgr->bredr_chan == chan) 568 if (mgr && mgr->bredr_chan == chan)
@@ -642,6 +609,23 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
642 return; 609 return;
643} 610}
644 611
612void l2cap_conn_update_id_addr(struct hci_conn *hcon)
613{
614 struct l2cap_conn *conn = hcon->l2cap_data;
615 struct l2cap_chan *chan;
616
617 mutex_lock(&conn->chan_lock);
618
619 list_for_each_entry(chan, &conn->chan_l, list) {
620 l2cap_chan_lock(chan);
621 bacpy(&chan->dst, &hcon->dst);
622 chan->dst_type = bdaddr_type(hcon, hcon->dst_type);
623 l2cap_chan_unlock(chan);
624 }
625
626 mutex_unlock(&conn->chan_lock);
627}
628
645static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan) 629static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
646{ 630{
647 struct l2cap_conn *conn = chan->conn; 631 struct l2cap_conn *conn = chan->conn;
@@ -699,10 +683,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
699 683
700 case BT_CONNECTED: 684 case BT_CONNECTED:
701 case BT_CONFIG: 685 case BT_CONFIG:
702 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also 686 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
703 * check for chan->psm.
704 */
705 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
706 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan)); 687 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
707 l2cap_send_disconn_req(chan, reason); 688 l2cap_send_disconn_req(chan, reason);
708 } else 689 } else
@@ -737,6 +718,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
737 case L2CAP_CHAN_RAW: 718 case L2CAP_CHAN_RAW:
738 switch (chan->sec_level) { 719 switch (chan->sec_level) {
739 case BT_SECURITY_HIGH: 720 case BT_SECURITY_HIGH:
721 case BT_SECURITY_FIPS:
740 return HCI_AT_DEDICATED_BONDING_MITM; 722 return HCI_AT_DEDICATED_BONDING_MITM;
741 case BT_SECURITY_MEDIUM: 723 case BT_SECURITY_MEDIUM:
742 return HCI_AT_DEDICATED_BONDING; 724 return HCI_AT_DEDICATED_BONDING;
@@ -749,7 +731,8 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
749 if (chan->sec_level == BT_SECURITY_LOW) 731 if (chan->sec_level == BT_SECURITY_LOW)
750 chan->sec_level = BT_SECURITY_SDP; 732 chan->sec_level = BT_SECURITY_SDP;
751 } 733 }
752 if (chan->sec_level == BT_SECURITY_HIGH) 734 if (chan->sec_level == BT_SECURITY_HIGH ||
735 chan->sec_level == BT_SECURITY_FIPS)
753 return HCI_AT_NO_BONDING_MITM; 736 return HCI_AT_NO_BONDING_MITM;
754 else 737 else
755 return HCI_AT_NO_BONDING; 738 return HCI_AT_NO_BONDING;
@@ -759,7 +742,8 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
759 if (chan->sec_level == BT_SECURITY_LOW) 742 if (chan->sec_level == BT_SECURITY_LOW)
760 chan->sec_level = BT_SECURITY_SDP; 743 chan->sec_level = BT_SECURITY_SDP;
761 744
762 if (chan->sec_level == BT_SECURITY_HIGH) 745 if (chan->sec_level == BT_SECURITY_HIGH ||
746 chan->sec_level == BT_SECURITY_FIPS)
763 return HCI_AT_NO_BONDING_MITM; 747 return HCI_AT_NO_BONDING_MITM;
764 else 748 else
765 return HCI_AT_NO_BONDING; 749 return HCI_AT_NO_BONDING;
@@ -768,6 +752,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
768 default: 752 default:
769 switch (chan->sec_level) { 753 switch (chan->sec_level) {
770 case BT_SECURITY_HIGH: 754 case BT_SECURITY_HIGH:
755 case BT_SECURITY_FIPS:
771 return HCI_AT_GENERAL_BONDING_MITM; 756 return HCI_AT_GENERAL_BONDING_MITM;
772 case BT_SECURITY_MEDIUM: 757 case BT_SECURITY_MEDIUM:
773 return HCI_AT_GENERAL_BONDING; 758 return HCI_AT_GENERAL_BONDING;
@@ -1330,7 +1315,7 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
1330 __clear_ack_timer(chan); 1315 __clear_ack_timer(chan);
1331 } 1316 }
1332 1317
1333 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { 1318 if (chan->scid == L2CAP_CID_A2MP) {
1334 l2cap_state_change(chan, BT_DISCONN); 1319 l2cap_state_change(chan, BT_DISCONN);
1335 return; 1320 return;
1336 } 1321 }
@@ -1493,8 +1478,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1493 if (!chan) 1478 if (!chan)
1494 goto clean; 1479 goto clean;
1495 1480
1496 chan->dcid = L2CAP_CID_ATT;
1497
1498 bacpy(&chan->src, &hcon->src); 1481 bacpy(&chan->src, &hcon->src);
1499 bacpy(&chan->dst, &hcon->dst); 1482 bacpy(&chan->dst, &hcon->dst);
1500 chan->src_type = bdaddr_type(hcon, hcon->src_type); 1483 chan->src_type = bdaddr_type(hcon, hcon->src_type);
@@ -1528,7 +1511,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
1528 1511
1529 l2cap_chan_lock(chan); 1512 l2cap_chan_lock(chan);
1530 1513
1531 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { 1514 if (chan->scid == L2CAP_CID_A2MP) {
1532 l2cap_chan_unlock(chan); 1515 l2cap_chan_unlock(chan);
1533 continue; 1516 continue;
1534 } 1517 }
@@ -1546,6 +1529,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
1546 } 1529 }
1547 1530
1548 mutex_unlock(&conn->chan_lock); 1531 mutex_unlock(&conn->chan_lock);
1532
1533 queue_work(hcon->hdev->workqueue, &conn->pending_rx_work);
1549} 1534}
1550 1535
1551/* Notify sockets that we cannot guaranty reliability anymore */ 1536/* Notify sockets that we cannot guaranty reliability anymore */
@@ -1671,6 +1656,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
1671 1656
1672 kfree_skb(conn->rx_skb); 1657 kfree_skb(conn->rx_skb);
1673 1658
1659 skb_queue_purge(&conn->pending_rx);
1660 flush_work(&conn->pending_rx_work);
1661
1674 l2cap_unregister_all_users(conn); 1662 l2cap_unregister_all_users(conn);
1675 1663
1676 mutex_lock(&conn->chan_lock); 1664 mutex_lock(&conn->chan_lock);
@@ -1718,66 +1706,6 @@ static void security_timeout(struct work_struct *work)
1718 } 1706 }
1719} 1707}
1720 1708
1721static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
1722{
1723 struct l2cap_conn *conn = hcon->l2cap_data;
1724 struct hci_chan *hchan;
1725
1726 if (conn)
1727 return conn;
1728
1729 hchan = hci_chan_create(hcon);
1730 if (!hchan)
1731 return NULL;
1732
1733 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
1734 if (!conn) {
1735 hci_chan_del(hchan);
1736 return NULL;
1737 }
1738
1739 kref_init(&conn->ref);
1740 hcon->l2cap_data = conn;
1741 conn->hcon = hcon;
1742 hci_conn_get(conn->hcon);
1743 conn->hchan = hchan;
1744
1745 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
1746
1747 switch (hcon->type) {
1748 case LE_LINK:
1749 if (hcon->hdev->le_mtu) {
1750 conn->mtu = hcon->hdev->le_mtu;
1751 break;
1752 }
1753 /* fall through */
1754 default:
1755 conn->mtu = hcon->hdev->acl_mtu;
1756 break;
1757 }
1758
1759 conn->feat_mask = 0;
1760
1761 if (hcon->type == ACL_LINK)
1762 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1763 &hcon->hdev->dev_flags);
1764
1765 spin_lock_init(&conn->lock);
1766 mutex_init(&conn->chan_lock);
1767
1768 INIT_LIST_HEAD(&conn->chan_l);
1769 INIT_LIST_HEAD(&conn->users);
1770
1771 if (hcon->type == LE_LINK)
1772 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
1773 else
1774 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
1775
1776 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
1777
1778 return conn;
1779}
1780
1781static void l2cap_conn_free(struct kref *ref) 1709static void l2cap_conn_free(struct kref *ref)
1782{ 1710{
1783 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref); 1711 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
@@ -1848,154 +1776,6 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1848 return c1; 1776 return c1;
1849} 1777}
1850 1778
1851static bool is_valid_psm(u16 psm, u8 dst_type)
1852{
1853 if (!psm)
1854 return false;
1855
1856 if (bdaddr_type_is_le(dst_type))
1857 return (psm <= 0x00ff);
1858
1859 /* PSM must be odd and lsb of upper byte must be 0 */
1860 return ((psm & 0x0101) == 0x0001);
1861}
1862
1863int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1864 bdaddr_t *dst, u8 dst_type)
1865{
1866 struct l2cap_conn *conn;
1867 struct hci_conn *hcon;
1868 struct hci_dev *hdev;
1869 __u8 auth_type;
1870 int err;
1871
1872 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
1873 dst_type, __le16_to_cpu(psm));
1874
1875 hdev = hci_get_route(dst, &chan->src);
1876 if (!hdev)
1877 return -EHOSTUNREACH;
1878
1879 hci_dev_lock(hdev);
1880
1881 l2cap_chan_lock(chan);
1882
1883 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
1884 chan->chan_type != L2CAP_CHAN_RAW) {
1885 err = -EINVAL;
1886 goto done;
1887 }
1888
1889 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1890 err = -EINVAL;
1891 goto done;
1892 }
1893
1894 switch (chan->mode) {
1895 case L2CAP_MODE_BASIC:
1896 break;
1897 case L2CAP_MODE_LE_FLOWCTL:
1898 l2cap_le_flowctl_init(chan);
1899 break;
1900 case L2CAP_MODE_ERTM:
1901 case L2CAP_MODE_STREAMING:
1902 if (!disable_ertm)
1903 break;
1904 /* fall through */
1905 default:
1906 err = -ENOTSUPP;
1907 goto done;
1908 }
1909
1910 switch (chan->state) {
1911 case BT_CONNECT:
1912 case BT_CONNECT2:
1913 case BT_CONFIG:
1914 /* Already connecting */
1915 err = 0;
1916 goto done;
1917
1918 case BT_CONNECTED:
1919 /* Already connected */
1920 err = -EISCONN;
1921 goto done;
1922
1923 case BT_OPEN:
1924 case BT_BOUND:
1925 /* Can connect */
1926 break;
1927
1928 default:
1929 err = -EBADFD;
1930 goto done;
1931 }
1932
1933 /* Set destination address and psm */
1934 bacpy(&chan->dst, dst);
1935 chan->dst_type = dst_type;
1936
1937 chan->psm = psm;
1938 chan->dcid = cid;
1939
1940 auth_type = l2cap_get_auth_type(chan);
1941
1942 if (bdaddr_type_is_le(dst_type))
1943 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
1944 chan->sec_level, auth_type);
1945 else
1946 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
1947 chan->sec_level, auth_type);
1948
1949 if (IS_ERR(hcon)) {
1950 err = PTR_ERR(hcon);
1951 goto done;
1952 }
1953
1954 conn = l2cap_conn_add(hcon);
1955 if (!conn) {
1956 hci_conn_drop(hcon);
1957 err = -ENOMEM;
1958 goto done;
1959 }
1960
1961 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1962 hci_conn_drop(hcon);
1963 err = -EBUSY;
1964 goto done;
1965 }
1966
1967 /* Update source addr of the socket */
1968 bacpy(&chan->src, &hcon->src);
1969 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1970
1971 l2cap_chan_unlock(chan);
1972 l2cap_chan_add(conn, chan);
1973 l2cap_chan_lock(chan);
1974
1975 /* l2cap_chan_add takes its own ref so we can drop this one */
1976 hci_conn_drop(hcon);
1977
1978 l2cap_state_change(chan, BT_CONNECT);
1979 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
1980
1981 if (hcon->state == BT_CONNECTED) {
1982 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
1983 __clear_chan_timer(chan);
1984 if (l2cap_chan_check_security(chan))
1985 l2cap_state_change(chan, BT_CONNECTED);
1986 } else
1987 l2cap_do_start(chan);
1988 }
1989
1990 err = 0;
1991
1992done:
1993 l2cap_chan_unlock(chan);
1994 hci_dev_unlock(hdev);
1995 hci_dev_put(hdev);
1996 return err;
1997}
1998
1999static void l2cap_monitor_timeout(struct work_struct *work) 1779static void l2cap_monitor_timeout(struct work_struct *work)
2000{ 1780{
2001 struct l2cap_chan *chan = container_of(work, struct l2cap_chan, 1781 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
@@ -2654,6 +2434,14 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2654 if (IS_ERR(skb)) 2434 if (IS_ERR(skb))
2655 return PTR_ERR(skb); 2435 return PTR_ERR(skb);
2656 2436
2437 /* Channel lock is released before requesting new skb and then
2438 * reacquired thus we need to recheck channel state.
2439 */
2440 if (chan->state != BT_CONNECTED) {
2441 kfree_skb(skb);
2442 return -ENOTCONN;
2443 }
2444
2657 l2cap_do_send(chan, skb); 2445 l2cap_do_send(chan, skb);
2658 return len; 2446 return len;
2659 } 2447 }
@@ -2703,6 +2491,14 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2703 if (IS_ERR(skb)) 2491 if (IS_ERR(skb))
2704 return PTR_ERR(skb); 2492 return PTR_ERR(skb);
2705 2493
2494 /* Channel lock is released before requesting new skb and then
2495 * reacquired thus we need to recheck channel state.
2496 */
2497 if (chan->state != BT_CONNECTED) {
2498 kfree_skb(skb);
2499 return -ENOTCONN;
2500 }
2501
2706 l2cap_do_send(chan, skb); 2502 l2cap_do_send(chan, skb);
2707 err = len; 2503 err = len;
2708 break; 2504 break;
@@ -5709,7 +5505,7 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
5709{ 5505{
5710 struct l2cap_le_credits *pkt; 5506 struct l2cap_le_credits *pkt;
5711 struct l2cap_chan *chan; 5507 struct l2cap_chan *chan;
5712 u16 cid, credits; 5508 u16 cid, credits, max_credits;
5713 5509
5714 if (cmd_len != sizeof(*pkt)) 5510 if (cmd_len != sizeof(*pkt))
5715 return -EPROTO; 5511 return -EPROTO;
@@ -5724,6 +5520,17 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
5724 if (!chan) 5520 if (!chan)
5725 return -EBADSLT; 5521 return -EBADSLT;
5726 5522
5523 max_credits = LE_FLOWCTL_MAX_CREDITS - chan->tx_credits;
5524 if (credits > max_credits) {
5525 BT_ERR("LE credits overflow");
5526 l2cap_send_disconn_req(chan, ECONNRESET);
5527
5528 /* Return 0 so that we don't trigger an unnecessary
5529 * command reject packet.
5530 */
5531 return 0;
5532 }
5533
5727 chan->tx_credits += credits; 5534 chan->tx_credits += credits;
5728 5535
5729 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) { 5536 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
@@ -5770,17 +5577,6 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
5770{ 5577{
5771 int err = 0; 5578 int err = 0;
5772 5579
5773 if (!enable_lecoc) {
5774 switch (cmd->code) {
5775 case L2CAP_LE_CONN_REQ:
5776 case L2CAP_LE_CONN_RSP:
5777 case L2CAP_LE_CREDITS:
5778 case L2CAP_DISCONN_REQ:
5779 case L2CAP_DISCONN_RSP:
5780 return -EINVAL;
5781 }
5782 }
5783
5784 switch (cmd->code) { 5580 switch (cmd->code) {
5785 case L2CAP_COMMAND_REJ: 5581 case L2CAP_COMMAND_REJ:
5786 l2cap_le_command_rej(conn, cmd, cmd_len, data); 5582 l2cap_le_command_rej(conn, cmd, cmd_len, data);
@@ -6871,6 +6667,7 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6871 6667
6872 if (!chan->rx_credits) { 6668 if (!chan->rx_credits) {
6873 BT_ERR("No credits to receive LE L2CAP data"); 6669 BT_ERR("No credits to receive LE L2CAP data");
6670 l2cap_send_disconn_req(chan, ECONNRESET);
6874 return -ENOBUFS; 6671 return -ENOBUFS;
6875 } 6672 }
6876 6673
@@ -6995,8 +6792,10 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6995 * But we don't have any other choice. L2CAP doesn't 6792 * But we don't have any other choice. L2CAP doesn't
6996 * provide flow control mechanism. */ 6793 * provide flow control mechanism. */
6997 6794
6998 if (chan->imtu < skb->len) 6795 if (chan->imtu < skb->len) {
6796 BT_ERR("Dropping L2CAP data: receive buffer overflow");
6999 goto drop; 6797 goto drop;
6798 }
7000 6799
7001 if (!chan->ops->recv(chan, skb)) 6800 if (!chan->ops->recv(chan, skb))
7002 goto done; 6801 goto done;
@@ -7084,9 +6883,16 @@ drop:
7084static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) 6883static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
7085{ 6884{
7086 struct l2cap_hdr *lh = (void *) skb->data; 6885 struct l2cap_hdr *lh = (void *) skb->data;
6886 struct hci_conn *hcon = conn->hcon;
7087 u16 cid, len; 6887 u16 cid, len;
7088 __le16 psm; 6888 __le16 psm;
7089 6889
6890 if (hcon->state != BT_CONNECTED) {
6891 BT_DBG("queueing pending rx skb");
6892 skb_queue_tail(&conn->pending_rx, skb);
6893 return;
6894 }
6895
7090 skb_pull(skb, L2CAP_HDR_SIZE); 6896 skb_pull(skb, L2CAP_HDR_SIZE);
7091 cid = __le16_to_cpu(lh->cid); 6897 cid = __le16_to_cpu(lh->cid);
7092 len = __le16_to_cpu(lh->len); 6898 len = __le16_to_cpu(lh->len);
@@ -7132,6 +6938,247 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
7132 } 6938 }
7133} 6939}
7134 6940
6941static void process_pending_rx(struct work_struct *work)
6942{
6943 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
6944 pending_rx_work);
6945 struct sk_buff *skb;
6946
6947 BT_DBG("");
6948
6949 while ((skb = skb_dequeue(&conn->pending_rx)))
6950 l2cap_recv_frame(conn, skb);
6951}
6952
6953static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
6954{
6955 struct l2cap_conn *conn = hcon->l2cap_data;
6956 struct hci_chan *hchan;
6957
6958 if (conn)
6959 return conn;
6960
6961 hchan = hci_chan_create(hcon);
6962 if (!hchan)
6963 return NULL;
6964
6965 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
6966 if (!conn) {
6967 hci_chan_del(hchan);
6968 return NULL;
6969 }
6970
6971 kref_init(&conn->ref);
6972 hcon->l2cap_data = conn;
6973 conn->hcon = hcon;
6974 hci_conn_get(conn->hcon);
6975 conn->hchan = hchan;
6976
6977 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
6978
6979 switch (hcon->type) {
6980 case LE_LINK:
6981 if (hcon->hdev->le_mtu) {
6982 conn->mtu = hcon->hdev->le_mtu;
6983 break;
6984 }
6985 /* fall through */
6986 default:
6987 conn->mtu = hcon->hdev->acl_mtu;
6988 break;
6989 }
6990
6991 conn->feat_mask = 0;
6992
6993 if (hcon->type == ACL_LINK)
6994 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
6995 &hcon->hdev->dev_flags);
6996
6997 spin_lock_init(&conn->lock);
6998 mutex_init(&conn->chan_lock);
6999
7000 INIT_LIST_HEAD(&conn->chan_l);
7001 INIT_LIST_HEAD(&conn->users);
7002
7003 if (hcon->type == LE_LINK)
7004 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
7005 else
7006 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
7007
7008 skb_queue_head_init(&conn->pending_rx);
7009 INIT_WORK(&conn->pending_rx_work, process_pending_rx);
7010
7011 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
7012
7013 return conn;
7014}
7015
7016static bool is_valid_psm(u16 psm, u8 dst_type) {
7017 if (!psm)
7018 return false;
7019
7020 if (bdaddr_type_is_le(dst_type))
7021 return (psm <= 0x00ff);
7022
7023 /* PSM must be odd and lsb of upper byte must be 0 */
7024 return ((psm & 0x0101) == 0x0001);
7025}
7026
7027int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
7028 bdaddr_t *dst, u8 dst_type)
7029{
7030 struct l2cap_conn *conn;
7031 struct hci_conn *hcon;
7032 struct hci_dev *hdev;
7033 __u8 auth_type;
7034 int err;
7035
7036 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
7037 dst_type, __le16_to_cpu(psm));
7038
7039 hdev = hci_get_route(dst, &chan->src);
7040 if (!hdev)
7041 return -EHOSTUNREACH;
7042
7043 hci_dev_lock(hdev);
7044
7045 l2cap_chan_lock(chan);
7046
7047 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
7048 chan->chan_type != L2CAP_CHAN_RAW) {
7049 err = -EINVAL;
7050 goto done;
7051 }
7052
7053 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !psm) {
7054 err = -EINVAL;
7055 goto done;
7056 }
7057
7058 if (chan->chan_type == L2CAP_CHAN_FIXED && !cid) {
7059 err = -EINVAL;
7060 goto done;
7061 }
7062
7063 switch (chan->mode) {
7064 case L2CAP_MODE_BASIC:
7065 break;
7066 case L2CAP_MODE_LE_FLOWCTL:
7067 l2cap_le_flowctl_init(chan);
7068 break;
7069 case L2CAP_MODE_ERTM:
7070 case L2CAP_MODE_STREAMING:
7071 if (!disable_ertm)
7072 break;
7073 /* fall through */
7074 default:
7075 err = -ENOTSUPP;
7076 goto done;
7077 }
7078
7079 switch (chan->state) {
7080 case BT_CONNECT:
7081 case BT_CONNECT2:
7082 case BT_CONFIG:
7083 /* Already connecting */
7084 err = 0;
7085 goto done;
7086
7087 case BT_CONNECTED:
7088 /* Already connected */
7089 err = -EISCONN;
7090 goto done;
7091
7092 case BT_OPEN:
7093 case BT_BOUND:
7094 /* Can connect */
7095 break;
7096
7097 default:
7098 err = -EBADFD;
7099 goto done;
7100 }
7101
7102 /* Set destination address and psm */
7103 bacpy(&chan->dst, dst);
7104 chan->dst_type = dst_type;
7105
7106 chan->psm = psm;
7107 chan->dcid = cid;
7108
7109 auth_type = l2cap_get_auth_type(chan);
7110
7111 if (bdaddr_type_is_le(dst_type)) {
7112 /* Convert from L2CAP channel address type to HCI address type
7113 */
7114 if (dst_type == BDADDR_LE_PUBLIC)
7115 dst_type = ADDR_LE_DEV_PUBLIC;
7116 else
7117 dst_type = ADDR_LE_DEV_RANDOM;
7118
7119 hcon = hci_connect_le(hdev, dst, dst_type, chan->sec_level,
7120 auth_type);
7121 } else {
7122 hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
7123 }
7124
7125 if (IS_ERR(hcon)) {
7126 err = PTR_ERR(hcon);
7127 goto done;
7128 }
7129
7130 conn = l2cap_conn_add(hcon);
7131 if (!conn) {
7132 hci_conn_drop(hcon);
7133 err = -ENOMEM;
7134 goto done;
7135 }
7136
7137 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
7138 hci_conn_drop(hcon);
7139 err = -EBUSY;
7140 goto done;
7141 }
7142
7143 /* Update source addr of the socket */
7144 bacpy(&chan->src, &hcon->src);
7145 chan->src_type = bdaddr_type(hcon, hcon->src_type);
7146
7147 l2cap_chan_unlock(chan);
7148 l2cap_chan_add(conn, chan);
7149 l2cap_chan_lock(chan);
7150
7151 /* l2cap_chan_add takes its own ref so we can drop this one */
7152 hci_conn_drop(hcon);
7153
7154 l2cap_state_change(chan, BT_CONNECT);
7155 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
7156
7157 /* Release chan->sport so that it can be reused by other
7158 * sockets (as it's only used for listening sockets).
7159 */
7160 write_lock(&chan_list_lock);
7161 chan->sport = 0;
7162 write_unlock(&chan_list_lock);
7163
7164 if (hcon->state == BT_CONNECTED) {
7165 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
7166 __clear_chan_timer(chan);
7167 if (l2cap_chan_check_security(chan))
7168 l2cap_state_change(chan, BT_CONNECTED);
7169 } else
7170 l2cap_do_start(chan);
7171 }
7172
7173 err = 0;
7174
7175done:
7176 l2cap_chan_unlock(chan);
7177 hci_dev_unlock(hdev);
7178 hci_dev_put(hdev);
7179 return err;
7180}
7181
7135/* ---- L2CAP interface with lower layer (HCI) ---- */ 7182/* ---- L2CAP interface with lower layer (HCI) ---- */
7136 7183
7137int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) 7184int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
@@ -7206,7 +7253,8 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
7206 if (encrypt == 0x00) { 7253 if (encrypt == 0x00) {
7207 if (chan->sec_level == BT_SECURITY_MEDIUM) { 7254 if (chan->sec_level == BT_SECURITY_MEDIUM) {
7208 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT); 7255 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
7209 } else if (chan->sec_level == BT_SECURITY_HIGH) 7256 } else if (chan->sec_level == BT_SECURITY_HIGH ||
7257 chan->sec_level == BT_SECURITY_FIPS)
7210 l2cap_chan_close(chan, ECONNREFUSED); 7258 l2cap_chan_close(chan, ECONNREFUSED);
7211 } else { 7259 } else {
7212 if (chan->sec_level == BT_SECURITY_MEDIUM) 7260 if (chan->sec_level == BT_SECURITY_MEDIUM)
@@ -7226,7 +7274,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
7226 7274
7227 if (hcon->type == LE_LINK) { 7275 if (hcon->type == LE_LINK) {
7228 if (!status && encrypt) 7276 if (!status && encrypt)
7229 smp_distribute_keys(conn, 0); 7277 smp_distribute_keys(conn);
7230 cancel_delayed_work(&conn->security_timer); 7278 cancel_delayed_work(&conn->security_timer);
7231 } 7279 }
7232 7280
@@ -7238,7 +7286,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
7238 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid, 7286 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7239 state_to_string(chan->state)); 7287 state_to_string(chan->state));
7240 7288
7241 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { 7289 if (chan->scid == L2CAP_CID_A2MP) {
7242 l2cap_chan_unlock(chan); 7290 l2cap_chan_unlock(chan);
7243 continue; 7291 continue;
7244 } 7292 }
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index d58f76bcebd1..b247f9d27fed 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -36,8 +36,6 @@
36 36
37#include "smp.h" 37#include "smp.h"
38 38
39bool enable_lecoc;
40
41static struct bt_sock_list l2cap_sk_list = { 39static struct bt_sock_list l2cap_sk_list = {
42 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) 40 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
43}; 41};
@@ -101,9 +99,16 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
101 if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) 99 if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
102 return -EINVAL; 100 return -EINVAL;
103 101
102 if (la.l2_cid) {
103 /* When the socket gets created it defaults to
104 * CHAN_CONN_ORIENTED, so we need to overwrite the
105 * default here.
106 */
107 chan->chan_type = L2CAP_CHAN_FIXED;
108 chan->omtu = L2CAP_DEFAULT_MTU;
109 }
110
104 if (bdaddr_type_is_le(la.l2_bdaddr_type)) { 111 if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
105 if (!enable_lecoc && la.l2_psm)
106 return -EINVAL;
107 /* We only allow ATT user space socket */ 112 /* We only allow ATT user space socket */
108 if (la.l2_cid && 113 if (la.l2_cid &&
109 la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) 114 la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT))
@@ -220,8 +225,6 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
220 return -EINVAL; 225 return -EINVAL;
221 226
222 if (bdaddr_type_is_le(la.l2_bdaddr_type)) { 227 if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
223 if (!enable_lecoc && la.l2_psm)
224 return -EINVAL;
225 /* We only allow ATT user space socket */ 228 /* We only allow ATT user space socket */
226 if (la.l2_cid && 229 if (la.l2_cid &&
227 la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) 230 la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT))
@@ -357,17 +360,20 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
357 360
358 BT_DBG("sock %p, sk %p", sock, sk); 361 BT_DBG("sock %p, sk %p", sock, sk);
359 362
363 if (peer && sk->sk_state != BT_CONNECTED)
364 return -ENOTCONN;
365
360 memset(la, 0, sizeof(struct sockaddr_l2)); 366 memset(la, 0, sizeof(struct sockaddr_l2));
361 addr->sa_family = AF_BLUETOOTH; 367 addr->sa_family = AF_BLUETOOTH;
362 *len = sizeof(struct sockaddr_l2); 368 *len = sizeof(struct sockaddr_l2);
363 369
370 la->l2_psm = chan->psm;
371
364 if (peer) { 372 if (peer) {
365 la->l2_psm = chan->psm;
366 bacpy(&la->l2_bdaddr, &chan->dst); 373 bacpy(&la->l2_bdaddr, &chan->dst);
367 la->l2_cid = cpu_to_le16(chan->dcid); 374 la->l2_cid = cpu_to_le16(chan->dcid);
368 la->l2_bdaddr_type = chan->dst_type; 375 la->l2_bdaddr_type = chan->dst_type;
369 } else { 376 } else {
370 la->l2_psm = chan->sport;
371 bacpy(&la->l2_bdaddr, &chan->src); 377 bacpy(&la->l2_bdaddr, &chan->src);
372 la->l2_cid = cpu_to_le16(chan->scid); 378 la->l2_cid = cpu_to_le16(chan->scid);
373 la->l2_bdaddr_type = chan->src_type; 379 la->l2_bdaddr_type = chan->src_type;
@@ -432,6 +438,10 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
432 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | 438 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
433 L2CAP_LM_SECURE; 439 L2CAP_LM_SECURE;
434 break; 440 break;
441 case BT_SECURITY_FIPS:
442 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
443 L2CAP_LM_SECURE | L2CAP_LM_FIPS;
444 break;
435 default: 445 default:
436 opt = 0; 446 opt = 0;
437 break; 447 break;
@@ -445,6 +455,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
445 455
446 if (put_user(opt, (u32 __user *) optval)) 456 if (put_user(opt, (u32 __user *) optval))
447 err = -EFAULT; 457 err = -EFAULT;
458
448 break; 459 break;
449 460
450 case L2CAP_CONNINFO: 461 case L2CAP_CONNINFO:
@@ -499,6 +510,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
499 switch (optname) { 510 switch (optname) {
500 case BT_SECURITY: 511 case BT_SECURITY:
501 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && 512 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
513 chan->chan_type != L2CAP_CHAN_FIXED &&
502 chan->chan_type != L2CAP_CHAN_RAW) { 514 chan->chan_type != L2CAP_CHAN_RAW) {
503 err = -EINVAL; 515 err = -EINVAL;
504 break; 516 break;
@@ -560,11 +572,6 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
560 break; 572 break;
561 573
562 case BT_SNDMTU: 574 case BT_SNDMTU:
563 if (!enable_lecoc) {
564 err = -EPROTONOSUPPORT;
565 break;
566 }
567
568 if (!bdaddr_type_is_le(chan->src_type)) { 575 if (!bdaddr_type_is_le(chan->src_type)) {
569 err = -EINVAL; 576 err = -EINVAL;
570 break; 577 break;
@@ -580,11 +587,6 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
580 break; 587 break;
581 588
582 case BT_RCVMTU: 589 case BT_RCVMTU:
583 if (!enable_lecoc) {
584 err = -EPROTONOSUPPORT;
585 break;
586 }
587
588 if (!bdaddr_type_is_le(chan->src_type)) { 590 if (!bdaddr_type_is_le(chan->src_type)) {
589 err = -EINVAL; 591 err = -EINVAL;
590 break; 592 break;
@@ -699,6 +701,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
699 break; 701 break;
700 } 702 }
701 703
704 if (opt & L2CAP_LM_FIPS) {
705 err = -EINVAL;
706 break;
707 }
708
702 if (opt & L2CAP_LM_AUTH) 709 if (opt & L2CAP_LM_AUTH)
703 chan->sec_level = BT_SECURITY_LOW; 710 chan->sec_level = BT_SECURITY_LOW;
704 if (opt & L2CAP_LM_ENCRYPT) 711 if (opt & L2CAP_LM_ENCRYPT)
@@ -750,6 +757,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
750 switch (optname) { 757 switch (optname) {
751 case BT_SECURITY: 758 case BT_SECURITY:
752 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && 759 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
760 chan->chan_type != L2CAP_CHAN_FIXED &&
753 chan->chan_type != L2CAP_CHAN_RAW) { 761 chan->chan_type != L2CAP_CHAN_RAW) {
754 err = -EINVAL; 762 err = -EINVAL;
755 break; 763 break;
@@ -895,11 +903,6 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
895 break; 903 break;
896 904
897 case BT_SNDMTU: 905 case BT_SNDMTU:
898 if (!enable_lecoc) {
899 err = -EPROTONOSUPPORT;
900 break;
901 }
902
903 if (!bdaddr_type_is_le(chan->src_type)) { 906 if (!bdaddr_type_is_le(chan->src_type)) {
904 err = -EINVAL; 907 err = -EINVAL;
905 break; 908 break;
@@ -912,11 +915,6 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
912 break; 915 break;
913 916
914 case BT_RCVMTU: 917 case BT_RCVMTU:
915 if (!enable_lecoc) {
916 err = -EPROTONOSUPPORT;
917 break;
918 }
919
920 if (!bdaddr_type_is_le(chan->src_type)) { 918 if (!bdaddr_type_is_le(chan->src_type)) {
921 err = -EINVAL; 919 err = -EINVAL;
922 break; 920 break;
@@ -1449,6 +1447,11 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
1449 chan->tx_credits = pchan->tx_credits; 1447 chan->tx_credits = pchan->tx_credits;
1450 chan->rx_credits = pchan->rx_credits; 1448 chan->rx_credits = pchan->rx_credits;
1451 1449
1450 if (chan->chan_type == L2CAP_CHAN_FIXED) {
1451 chan->scid = pchan->scid;
1452 chan->dcid = pchan->scid;
1453 }
1454
1452 security_sk_clone(parent, sk); 1455 security_sk_clone(parent, sk);
1453 } else { 1456 } else {
1454 switch (sk->sk_type) { 1457 switch (sk->sk_type) {
@@ -1614,6 +1617,3 @@ void l2cap_cleanup_sockets(void)
1614 bt_sock_unregister(BTPROTO_L2CAP); 1617 bt_sock_unregister(BTPROTO_L2CAP);
1615 proto_unregister(&l2cap_proto); 1618 proto_unregister(&l2cap_proto);
1616} 1619}
1617
1618module_param(enable_lecoc, bool, 0644);
1619MODULE_PARM_DESC(enable_lecoc, "Enable support for LE CoC");
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a03ca3ca91bf..98e9df3556e7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -34,7 +34,7 @@
34#include "smp.h" 34#include "smp.h"
35 35
36#define MGMT_VERSION 1 36#define MGMT_VERSION 1
37#define MGMT_REVISION 4 37#define MGMT_REVISION 5
38 38
39static const u16 mgmt_commands[] = { 39static const u16 mgmt_commands[] = {
40 MGMT_OP_READ_INDEX_LIST, 40 MGMT_OP_READ_INDEX_LIST,
@@ -79,6 +79,10 @@ static const u16 mgmt_commands[] = {
79 MGMT_OP_SET_BREDR, 79 MGMT_OP_SET_BREDR,
80 MGMT_OP_SET_STATIC_ADDRESS, 80 MGMT_OP_SET_STATIC_ADDRESS,
81 MGMT_OP_SET_SCAN_PARAMS, 81 MGMT_OP_SET_SCAN_PARAMS,
82 MGMT_OP_SET_SECURE_CONN,
83 MGMT_OP_SET_DEBUG_KEYS,
84 MGMT_OP_SET_PRIVACY,
85 MGMT_OP_LOAD_IRKS,
82}; 86};
83 87
84static const u16 mgmt_events[] = { 88static const u16 mgmt_events[] = {
@@ -103,6 +107,7 @@ static const u16 mgmt_events[] = {
103 MGMT_EV_DEVICE_UNBLOCKED, 107 MGMT_EV_DEVICE_UNBLOCKED,
104 MGMT_EV_DEVICE_UNPAIRED, 108 MGMT_EV_DEVICE_UNPAIRED,
105 MGMT_EV_PASSKEY_NOTIFY, 109 MGMT_EV_PASSKEY_NOTIFY,
110 MGMT_EV_NEW_IRK,
106}; 111};
107 112
108#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) 113#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
@@ -127,7 +132,7 @@ static u8 mgmt_status_table[] = {
127 MGMT_STATUS_FAILED, /* Hardware Failure */ 132 MGMT_STATUS_FAILED, /* Hardware Failure */
128 MGMT_STATUS_CONNECT_FAILED, /* Page Timeout */ 133 MGMT_STATUS_CONNECT_FAILED, /* Page Timeout */
129 MGMT_STATUS_AUTH_FAILED, /* Authentication Failed */ 134 MGMT_STATUS_AUTH_FAILED, /* Authentication Failed */
130 MGMT_STATUS_NOT_PAIRED, /* PIN or Key Missing */ 135 MGMT_STATUS_AUTH_FAILED, /* PIN or Key Missing */
131 MGMT_STATUS_NO_RESOURCES, /* Memory Full */ 136 MGMT_STATUS_NO_RESOURCES, /* Memory Full */
132 MGMT_STATUS_TIMEOUT, /* Connection Timeout */ 137 MGMT_STATUS_TIMEOUT, /* Connection Timeout */
133 MGMT_STATUS_NO_RESOURCES, /* Max Number of Connections */ 138 MGMT_STATUS_NO_RESOURCES, /* Max Number of Connections */
@@ -363,6 +368,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
363 368
364 settings |= MGMT_SETTING_POWERED; 369 settings |= MGMT_SETTING_POWERED;
365 settings |= MGMT_SETTING_PAIRABLE; 370 settings |= MGMT_SETTING_PAIRABLE;
371 settings |= MGMT_SETTING_DEBUG_KEYS;
366 372
367 if (lmp_bredr_capable(hdev)) { 373 if (lmp_bredr_capable(hdev)) {
368 settings |= MGMT_SETTING_CONNECTABLE; 374 settings |= MGMT_SETTING_CONNECTABLE;
@@ -376,11 +382,16 @@ static u32 get_supported_settings(struct hci_dev *hdev)
376 settings |= MGMT_SETTING_SSP; 382 settings |= MGMT_SETTING_SSP;
377 settings |= MGMT_SETTING_HS; 383 settings |= MGMT_SETTING_HS;
378 } 384 }
385
386 if (lmp_sc_capable(hdev) ||
387 test_bit(HCI_FORCE_SC, &hdev->dev_flags))
388 settings |= MGMT_SETTING_SECURE_CONN;
379 } 389 }
380 390
381 if (lmp_le_capable(hdev)) { 391 if (lmp_le_capable(hdev)) {
382 settings |= MGMT_SETTING_LE; 392 settings |= MGMT_SETTING_LE;
383 settings |= MGMT_SETTING_ADVERTISING; 393 settings |= MGMT_SETTING_ADVERTISING;
394 settings |= MGMT_SETTING_PRIVACY;
384 } 395 }
385 396
386 return settings; 397 return settings;
@@ -423,6 +434,15 @@ static u32 get_current_settings(struct hci_dev *hdev)
423 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) 434 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
424 settings |= MGMT_SETTING_ADVERTISING; 435 settings |= MGMT_SETTING_ADVERTISING;
425 436
437 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
438 settings |= MGMT_SETTING_SECURE_CONN;
439
440 if (test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags))
441 settings |= MGMT_SETTING_DEBUG_KEYS;
442
443 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
444 settings |= MGMT_SETTING_PRIVACY;
445
426 return settings; 446 return settings;
427} 447}
428 448
@@ -629,14 +649,8 @@ static u8 create_adv_data(struct hci_dev *hdev, u8 *ptr)
629 649
630 flags |= get_adv_discov_flags(hdev); 650 flags |= get_adv_discov_flags(hdev);
631 651
632 if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 652 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
633 if (lmp_le_br_capable(hdev))
634 flags |= LE_AD_SIM_LE_BREDR_CTRL;
635 if (lmp_host_le_br_capable(hdev))
636 flags |= LE_AD_SIM_LE_BREDR_HOST;
637 } else {
638 flags |= LE_AD_NO_BREDR; 653 flags |= LE_AD_NO_BREDR;
639 }
640 654
641 if (flags) { 655 if (flags) {
642 BT_DBG("adv flags 0x%02x", flags); 656 BT_DBG("adv flags 0x%02x", flags);
@@ -803,6 +817,64 @@ static void update_class(struct hci_request *req)
803 hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); 817 hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
804} 818}
805 819
820static bool get_connectable(struct hci_dev *hdev)
821{
822 struct pending_cmd *cmd;
823
824 /* If there's a pending mgmt command the flag will not yet have
825 * it's final value, so check for this first.
826 */
827 cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
828 if (cmd) {
829 struct mgmt_mode *cp = cmd->param;
830 return cp->val;
831 }
832
833 return test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
834}
835
836static void enable_advertising(struct hci_request *req)
837{
838 struct hci_dev *hdev = req->hdev;
839 struct hci_cp_le_set_adv_param cp;
840 u8 own_addr_type, enable = 0x01;
841 bool connectable;
842
843 /* Clear the HCI_ADVERTISING bit temporarily so that the
844 * hci_update_random_address knows that it's safe to go ahead
845 * and write a new random address. The flag will be set back on
846 * as soon as the SET_ADV_ENABLE HCI command completes.
847 */
848 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
849
850 connectable = get_connectable(hdev);
851
852 /* Set require_privacy to true only when non-connectable
853 * advertising is used. In that case it is fine to use a
854 * non-resolvable private address.
855 */
856 if (hci_update_random_address(req, !connectable, &own_addr_type) < 0)
857 return;
858
859 memset(&cp, 0, sizeof(cp));
860 cp.min_interval = __constant_cpu_to_le16(0x0800);
861 cp.max_interval = __constant_cpu_to_le16(0x0800);
862 cp.type = connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND;
863 cp.own_address_type = own_addr_type;
864 cp.channel_map = hdev->le_adv_channel_map;
865
866 hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
867
868 hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
869}
870
871static void disable_advertising(struct hci_request *req)
872{
873 u8 enable = 0x00;
874
875 hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
876}
877
806static void service_cache_off(struct work_struct *work) 878static void service_cache_off(struct work_struct *work)
807{ 879{
808 struct hci_dev *hdev = container_of(work, struct hci_dev, 880 struct hci_dev *hdev = container_of(work, struct hci_dev,
@@ -824,12 +896,39 @@ static void service_cache_off(struct work_struct *work)
824 hci_req_run(&req, NULL); 896 hci_req_run(&req, NULL);
825} 897}
826 898
899static void rpa_expired(struct work_struct *work)
900{
901 struct hci_dev *hdev = container_of(work, struct hci_dev,
902 rpa_expired.work);
903 struct hci_request req;
904
905 BT_DBG("");
906
907 set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
908
909 if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags) ||
910 hci_conn_num(hdev, LE_LINK) > 0)
911 return;
912
913 /* The generation of a new RPA and programming it into the
914 * controller happens in the enable_advertising() function.
915 */
916
917 hci_req_init(&req, hdev);
918
919 disable_advertising(&req);
920 enable_advertising(&req);
921
922 hci_req_run(&req, NULL);
923}
924
827static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev) 925static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
828{ 926{
829 if (test_and_set_bit(HCI_MGMT, &hdev->dev_flags)) 927 if (test_and_set_bit(HCI_MGMT, &hdev->dev_flags))
830 return; 928 return;
831 929
832 INIT_DELAYED_WORK(&hdev->service_cache, service_cache_off); 930 INIT_DELAYED_WORK(&hdev->service_cache, service_cache_off);
931 INIT_DELAYED_WORK(&hdev->rpa_expired, rpa_expired);
833 932
834 /* Non-mgmt controlled devices get this bit set 933 /* Non-mgmt controlled devices get this bit set
835 * implicitly so that pairing works for them, however 934 * implicitly so that pairing works for them, however
@@ -935,6 +1034,71 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
935 sizeof(settings)); 1034 sizeof(settings));
936} 1035}
937 1036
1037static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
1038{
1039 BT_DBG("%s status 0x%02x", hdev->name, status);
1040
1041 if (hci_conn_count(hdev) == 0) {
1042 cancel_delayed_work(&hdev->power_off);
1043 queue_work(hdev->req_workqueue, &hdev->power_off.work);
1044 }
1045}
1046
1047static int clean_up_hci_state(struct hci_dev *hdev)
1048{
1049 struct hci_request req;
1050 struct hci_conn *conn;
1051
1052 hci_req_init(&req, hdev);
1053
1054 if (test_bit(HCI_ISCAN, &hdev->flags) ||
1055 test_bit(HCI_PSCAN, &hdev->flags)) {
1056 u8 scan = 0x00;
1057 hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
1058 }
1059
1060 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
1061 disable_advertising(&req);
1062
1063 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
1064 hci_req_add_le_scan_disable(&req);
1065 }
1066
1067 list_for_each_entry(conn, &hdev->conn_hash.list, list) {
1068 struct hci_cp_disconnect dc;
1069 struct hci_cp_reject_conn_req rej;
1070
1071 switch (conn->state) {
1072 case BT_CONNECTED:
1073 case BT_CONFIG:
1074 dc.handle = cpu_to_le16(conn->handle);
1075 dc.reason = 0x15; /* Terminated due to Power Off */
1076 hci_req_add(&req, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1077 break;
1078 case BT_CONNECT:
1079 if (conn->type == LE_LINK)
1080 hci_req_add(&req, HCI_OP_LE_CREATE_CONN_CANCEL,
1081 0, NULL);
1082 else if (conn->type == ACL_LINK)
1083 hci_req_add(&req, HCI_OP_CREATE_CONN_CANCEL,
1084 6, &conn->dst);
1085 break;
1086 case BT_CONNECT2:
1087 bacpy(&rej.bdaddr, &conn->dst);
1088 rej.reason = 0x15; /* Terminated due to Power Off */
1089 if (conn->type == ACL_LINK)
1090 hci_req_add(&req, HCI_OP_REJECT_CONN_REQ,
1091 sizeof(rej), &rej);
1092 else if (conn->type == SCO_LINK)
1093 hci_req_add(&req, HCI_OP_REJECT_SYNC_CONN_REQ,
1094 sizeof(rej), &rej);
1095 break;
1096 }
1097 }
1098
1099 return hci_req_run(&req, clean_up_hci_complete);
1100}
1101
938static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, 1102static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
939 u16 len) 1103 u16 len)
940{ 1104{
@@ -978,12 +1142,23 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
978 goto failed; 1142 goto failed;
979 } 1143 }
980 1144
981 if (cp->val) 1145 if (cp->val) {
982 queue_work(hdev->req_workqueue, &hdev->power_on); 1146 queue_work(hdev->req_workqueue, &hdev->power_on);
983 else 1147 err = 0;
984 queue_work(hdev->req_workqueue, &hdev->power_off.work); 1148 } else {
985 1149 /* Disconnect connections, stop scans, etc */
986 err = 0; 1150 err = clean_up_hci_state(hdev);
1151 if (!err)
1152 queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
1153 HCI_POWER_OFF_TIMEOUT);
1154
1155 /* ENODATA means there were no HCI commands queued */
1156 if (err == -ENODATA) {
1157 cancel_delayed_work(&hdev->power_off);
1158 queue_work(hdev->req_workqueue, &hdev->power_off.work);
1159 err = 0;
1160 }
1161 }
987 1162
988failed: 1163failed:
989 hci_dev_unlock(hdev); 1164 hci_dev_unlock(hdev);
@@ -1336,50 +1511,6 @@ static void write_fast_connectable(struct hci_request *req, bool enable)
1336 hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type); 1511 hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
1337} 1512}
1338 1513
1339static u8 get_adv_type(struct hci_dev *hdev)
1340{
1341 struct pending_cmd *cmd;
1342 bool connectable;
1343
1344 /* If there's a pending mgmt command the flag will not yet have
1345 * it's final value, so check for this first.
1346 */
1347 cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
1348 if (cmd) {
1349 struct mgmt_mode *cp = cmd->param;
1350 connectable = !!cp->val;
1351 } else {
1352 connectable = test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
1353 }
1354
1355 return connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND;
1356}
1357
1358static void enable_advertising(struct hci_request *req)
1359{
1360 struct hci_dev *hdev = req->hdev;
1361 struct hci_cp_le_set_adv_param cp;
1362 u8 enable = 0x01;
1363
1364 memset(&cp, 0, sizeof(cp));
1365 cp.min_interval = __constant_cpu_to_le16(0x0800);
1366 cp.max_interval = __constant_cpu_to_le16(0x0800);
1367 cp.type = get_adv_type(hdev);
1368 cp.own_address_type = hdev->own_addr_type;
1369 cp.channel_map = 0x07;
1370
1371 hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
1372
1373 hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
1374}
1375
1376static void disable_advertising(struct hci_request *req)
1377{
1378 u8 enable = 0x00;
1379
1380 hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
1381}
1382
1383static void set_connectable_complete(struct hci_dev *hdev, u8 status) 1514static void set_connectable_complete(struct hci_dev *hdev, u8 status)
1384{ 1515{
1385 struct pending_cmd *cmd; 1516 struct pending_cmd *cmd;
@@ -2065,7 +2196,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
2065 } 2196 }
2066 2197
2067 if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { 2198 if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
2068 err = hci_uuids_clear(hdev); 2199 hci_uuids_clear(hdev);
2069 2200
2070 if (enable_service_cache(hdev)) { 2201 if (enable_service_cache(hdev)) {
2071 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 2202 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID,
@@ -2205,6 +2336,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
2205{ 2336{
2206 struct mgmt_cp_load_link_keys *cp = data; 2337 struct mgmt_cp_load_link_keys *cp = data;
2207 u16 key_count, expected_len; 2338 u16 key_count, expected_len;
2339 bool changed;
2208 int i; 2340 int i;
2209 2341
2210 BT_DBG("request for %s", hdev->name); 2342 BT_DBG("request for %s", hdev->name);
@@ -2234,7 +2366,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
2234 for (i = 0; i < key_count; i++) { 2366 for (i = 0; i < key_count; i++) {
2235 struct mgmt_link_key_info *key = &cp->keys[i]; 2367 struct mgmt_link_key_info *key = &cp->keys[i];
2236 2368
2237 if (key->addr.type != BDADDR_BREDR) 2369 if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
2238 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 2370 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
2239 MGMT_STATUS_INVALID_PARAMS); 2371 MGMT_STATUS_INVALID_PARAMS);
2240 } 2372 }
@@ -2244,9 +2376,12 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
2244 hci_link_keys_clear(hdev); 2376 hci_link_keys_clear(hdev);
2245 2377
2246 if (cp->debug_keys) 2378 if (cp->debug_keys)
2247 set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); 2379 changed = !test_and_set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
2248 else 2380 else
2249 clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); 2381 changed = test_and_clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
2382
2383 if (changed)
2384 new_settings(hdev, NULL);
2250 2385
2251 for (i = 0; i < key_count; i++) { 2386 for (i = 0; i < key_count; i++) {
2252 struct mgmt_link_key_info *key = &cp->keys[i]; 2387 struct mgmt_link_key_info *key = &cp->keys[i];
@@ -2306,10 +2441,22 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
2306 goto unlock; 2441 goto unlock;
2307 } 2442 }
2308 2443
2309 if (cp->addr.type == BDADDR_BREDR) 2444 if (cp->addr.type == BDADDR_BREDR) {
2310 err = hci_remove_link_key(hdev, &cp->addr.bdaddr); 2445 err = hci_remove_link_key(hdev, &cp->addr.bdaddr);
2311 else 2446 } else {
2312 err = hci_remove_ltk(hdev, &cp->addr.bdaddr); 2447 u8 addr_type;
2448
2449 if (cp->addr.type == BDADDR_LE_PUBLIC)
2450 addr_type = ADDR_LE_DEV_PUBLIC;
2451 else
2452 addr_type = ADDR_LE_DEV_RANDOM;
2453
2454 hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type);
2455
2456 hci_conn_params_del(hdev, &cp->addr.bdaddr, addr_type);
2457
2458 err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type);
2459 }
2313 2460
2314 if (err < 0) { 2461 if (err < 0) {
2315 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 2462 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
@@ -2633,6 +2780,16 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
2633 mgmt_pending_remove(cmd); 2780 mgmt_pending_remove(cmd);
2634} 2781}
2635 2782
2783void mgmt_smp_complete(struct hci_conn *conn, bool complete)
2784{
2785 u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED;
2786 struct pending_cmd *cmd;
2787
2788 cmd = find_pairing(conn);
2789 if (cmd)
2790 pairing_complete(cmd, status);
2791}
2792
2636static void pairing_complete_cb(struct hci_conn *conn, u8 status) 2793static void pairing_complete_cb(struct hci_conn *conn, u8 status)
2637{ 2794{
2638 struct pending_cmd *cmd; 2795 struct pending_cmd *cmd;
@@ -2646,7 +2803,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
2646 pairing_complete(cmd, mgmt_status(status)); 2803 pairing_complete(cmd, mgmt_status(status));
2647} 2804}
2648 2805
2649static void le_connect_complete_cb(struct hci_conn *conn, u8 status) 2806static void le_pairing_complete_cb(struct hci_conn *conn, u8 status)
2650{ 2807{
2651 struct pending_cmd *cmd; 2808 struct pending_cmd *cmd;
2652 2809
@@ -2697,12 +2854,22 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
2697 else 2854 else
2698 auth_type = HCI_AT_DEDICATED_BONDING_MITM; 2855 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
2699 2856
2700 if (cp->addr.type == BDADDR_BREDR) 2857 if (cp->addr.type == BDADDR_BREDR) {
2701 conn = hci_connect(hdev, ACL_LINK, &cp->addr.bdaddr, 2858 conn = hci_connect_acl(hdev, &cp->addr.bdaddr, sec_level,
2702 cp->addr.type, sec_level, auth_type); 2859 auth_type);
2703 else 2860 } else {
2704 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr, 2861 u8 addr_type;
2705 cp->addr.type, sec_level, auth_type); 2862
2863 /* Convert from L2CAP channel address type to HCI address type
2864 */
2865 if (cp->addr.type == BDADDR_LE_PUBLIC)
2866 addr_type = ADDR_LE_DEV_PUBLIC;
2867 else
2868 addr_type = ADDR_LE_DEV_RANDOM;
2869
2870 conn = hci_connect_le(hdev, &cp->addr.bdaddr, addr_type,
2871 sec_level, auth_type);
2872 }
2706 2873
2707 if (IS_ERR(conn)) { 2874 if (IS_ERR(conn)) {
2708 int status; 2875 int status;
@@ -2733,13 +2900,16 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
2733 } 2900 }
2734 2901
2735 /* For LE, just connecting isn't a proof that the pairing finished */ 2902 /* For LE, just connecting isn't a proof that the pairing finished */
2736 if (cp->addr.type == BDADDR_BREDR) 2903 if (cp->addr.type == BDADDR_BREDR) {
2737 conn->connect_cfm_cb = pairing_complete_cb; 2904 conn->connect_cfm_cb = pairing_complete_cb;
2738 else 2905 conn->security_cfm_cb = pairing_complete_cb;
2739 conn->connect_cfm_cb = le_connect_complete_cb; 2906 conn->disconn_cfm_cb = pairing_complete_cb;
2907 } else {
2908 conn->connect_cfm_cb = le_pairing_complete_cb;
2909 conn->security_cfm_cb = le_pairing_complete_cb;
2910 conn->disconn_cfm_cb = le_pairing_complete_cb;
2911 }
2740 2912
2741 conn->security_cfm_cb = pairing_complete_cb;
2742 conn->disconn_cfm_cb = pairing_complete_cb;
2743 conn->io_capability = cp->io_cap; 2913 conn->io_capability = cp->io_cap;
2744 cmd->user_data = conn; 2914 cmd->user_data = conn;
2745 2915
@@ -3071,7 +3241,12 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
3071 goto unlock; 3241 goto unlock;
3072 } 3242 }
3073 3243
3074 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); 3244 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
3245 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_EXT_DATA,
3246 0, NULL);
3247 else
3248 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
3249
3075 if (err < 0) 3250 if (err < 0)
3076 mgmt_pending_remove(cmd); 3251 mgmt_pending_remove(cmd);
3077 3252
@@ -3083,23 +3258,46 @@ unlock:
3083static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, 3258static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
3084 void *data, u16 len) 3259 void *data, u16 len)
3085{ 3260{
3086 struct mgmt_cp_add_remote_oob_data *cp = data;
3087 u8 status;
3088 int err; 3261 int err;
3089 3262
3090 BT_DBG("%s ", hdev->name); 3263 BT_DBG("%s ", hdev->name);
3091 3264
3092 hci_dev_lock(hdev); 3265 hci_dev_lock(hdev);
3093 3266
3094 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash, 3267 if (len == MGMT_ADD_REMOTE_OOB_DATA_SIZE) {
3095 cp->randomizer); 3268 struct mgmt_cp_add_remote_oob_data *cp = data;
3096 if (err < 0) 3269 u8 status;
3097 status = MGMT_STATUS_FAILED;
3098 else
3099 status = MGMT_STATUS_SUCCESS;
3100 3270
3101 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status, 3271 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr,
3102 &cp->addr, sizeof(cp->addr)); 3272 cp->hash, cp->randomizer);
3273 if (err < 0)
3274 status = MGMT_STATUS_FAILED;
3275 else
3276 status = MGMT_STATUS_SUCCESS;
3277
3278 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
3279 status, &cp->addr, sizeof(cp->addr));
3280 } else if (len == MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE) {
3281 struct mgmt_cp_add_remote_oob_ext_data *cp = data;
3282 u8 status;
3283
3284 err = hci_add_remote_oob_ext_data(hdev, &cp->addr.bdaddr,
3285 cp->hash192,
3286 cp->randomizer192,
3287 cp->hash256,
3288 cp->randomizer256);
3289 if (err < 0)
3290 status = MGMT_STATUS_FAILED;
3291 else
3292 status = MGMT_STATUS_SUCCESS;
3293
3294 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
3295 status, &cp->addr, sizeof(cp->addr));
3296 } else {
3297 BT_ERR("add_remote_oob_data: invalid length of %u bytes", len);
3298 err = cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
3299 MGMT_STATUS_INVALID_PARAMS);
3300 }
3103 3301
3104 hci_dev_unlock(hdev); 3302 hci_dev_unlock(hdev);
3105 return err; 3303 return err;
@@ -3195,7 +3393,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
3195 struct hci_request req; 3393 struct hci_request req;
3196 /* General inquiry access code (GIAC) */ 3394 /* General inquiry access code (GIAC) */
3197 u8 lap[3] = { 0x33, 0x8b, 0x9e }; 3395 u8 lap[3] = { 0x33, 0x8b, 0x9e };
3198 u8 status; 3396 u8 status, own_addr_type;
3199 int err; 3397 int err;
3200 3398
3201 BT_DBG("%s", hdev->name); 3399 BT_DBG("%s", hdev->name);
@@ -3280,18 +3478,31 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
3280 goto failed; 3478 goto failed;
3281 } 3479 }
3282 3480
3283 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) { 3481 /* If controller is scanning, it means the background scanning
3482 * is running. Thus, we should temporarily stop it in order to
3483 * set the discovery scanning parameters.
3484 */
3485 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
3486 hci_req_add_le_scan_disable(&req);
3487
3488 memset(&param_cp, 0, sizeof(param_cp));
3489
3490 /* All active scans will be done with either a resolvable
3491 * private address (when privacy feature has been enabled)
3492 * or unresolvable private address.
3493 */
3494 err = hci_update_random_address(&req, true, &own_addr_type);
3495 if (err < 0) {
3284 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3496 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
3285 MGMT_STATUS_BUSY); 3497 MGMT_STATUS_FAILED);
3286 mgmt_pending_remove(cmd); 3498 mgmt_pending_remove(cmd);
3287 goto failed; 3499 goto failed;
3288 } 3500 }
3289 3501
3290 memset(&param_cp, 0, sizeof(param_cp));
3291 param_cp.type = LE_SCAN_ACTIVE; 3502 param_cp.type = LE_SCAN_ACTIVE;
3292 param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); 3503 param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
3293 param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); 3504 param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
3294 param_cp.own_address_type = hdev->own_addr_type; 3505 param_cp.own_address_type = own_addr_type;
3295 hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), 3506 hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
3296 &param_cp); 3507 &param_cp);
3297 3508
@@ -3361,7 +3572,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
3361 struct hci_cp_remote_name_req_cancel cp; 3572 struct hci_cp_remote_name_req_cancel cp;
3362 struct inquiry_entry *e; 3573 struct inquiry_entry *e;
3363 struct hci_request req; 3574 struct hci_request req;
3364 struct hci_cp_le_set_scan_enable enable_cp;
3365 int err; 3575 int err;
3366 3576
3367 BT_DBG("%s", hdev->name); 3577 BT_DBG("%s", hdev->name);
@@ -3397,10 +3607,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
3397 } else { 3607 } else {
3398 cancel_delayed_work(&hdev->le_scan_disable); 3608 cancel_delayed_work(&hdev->le_scan_disable);
3399 3609
3400 memset(&enable_cp, 0, sizeof(enable_cp)); 3610 hci_req_add_le_scan_disable(&req);
3401 enable_cp.enable = LE_SCAN_DISABLE;
3402 hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE,
3403 sizeof(enable_cp), &enable_cp);
3404 } 3611 }
3405 3612
3406 break; 3613 break;
@@ -3457,15 +3664,17 @@ static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data,
3457 hci_dev_lock(hdev); 3664 hci_dev_lock(hdev);
3458 3665
3459 if (!hci_discovery_active(hdev)) { 3666 if (!hci_discovery_active(hdev)) {
3460 err = cmd_status(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 3667 err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME,
3461 MGMT_STATUS_FAILED); 3668 MGMT_STATUS_FAILED, &cp->addr,
3669 sizeof(cp->addr));
3462 goto failed; 3670 goto failed;
3463 } 3671 }
3464 3672
3465 e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr); 3673 e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr);
3466 if (!e) { 3674 if (!e) {
3467 err = cmd_status(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 3675 err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME,
3468 MGMT_STATUS_INVALID_PARAMS); 3676 MGMT_STATUS_INVALID_PARAMS, &cp->addr,
3677 sizeof(cp->addr));
3469 goto failed; 3678 goto failed;
3470 } 3679 }
3471 3680
@@ -3754,6 +3963,21 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
3754 3963
3755 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0, NULL, 0); 3964 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0, NULL, 0);
3756 3965
3966 /* If background scan is running, restart it so new parameters are
3967 * loaded.
3968 */
3969 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
3970 hdev->discovery.state == DISCOVERY_STOPPED) {
3971 struct hci_request req;
3972
3973 hci_req_init(&req, hdev);
3974
3975 hci_req_add_le_scan_disable(&req);
3976 hci_req_add_le_passive_scan(&req);
3977
3978 hci_req_run(&req, NULL);
3979 }
3980
3757 hci_dev_unlock(hdev); 3981 hci_dev_unlock(hdev);
3758 3982
3759 return err; 3983 return err;
@@ -3999,15 +4223,269 @@ unlock:
3999 return err; 4223 return err;
4000} 4224}
4001 4225
4226static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
4227 void *data, u16 len)
4228{
4229 struct mgmt_mode *cp = data;
4230 struct pending_cmd *cmd;
4231 u8 val, status;
4232 int err;
4233
4234 BT_DBG("request for %s", hdev->name);
4235
4236 status = mgmt_bredr_support(hdev);
4237 if (status)
4238 return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
4239 status);
4240
4241 if (!lmp_sc_capable(hdev) &&
4242 !test_bit(HCI_FORCE_SC, &hdev->dev_flags))
4243 return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
4244 MGMT_STATUS_NOT_SUPPORTED);
4245
4246 if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
4247 return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
4248 MGMT_STATUS_INVALID_PARAMS);
4249
4250 hci_dev_lock(hdev);
4251
4252 if (!hdev_is_powered(hdev)) {
4253 bool changed;
4254
4255 if (cp->val) {
4256 changed = !test_and_set_bit(HCI_SC_ENABLED,
4257 &hdev->dev_flags);
4258 if (cp->val == 0x02)
4259 set_bit(HCI_SC_ONLY, &hdev->dev_flags);
4260 else
4261 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
4262 } else {
4263 changed = test_and_clear_bit(HCI_SC_ENABLED,
4264 &hdev->dev_flags);
4265 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
4266 }
4267
4268 err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
4269 if (err < 0)
4270 goto failed;
4271
4272 if (changed)
4273 err = new_settings(hdev, sk);
4274
4275 goto failed;
4276 }
4277
4278 if (mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) {
4279 err = cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
4280 MGMT_STATUS_BUSY);
4281 goto failed;
4282 }
4283
4284 val = !!cp->val;
4285
4286 if (val == test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
4287 (cp->val == 0x02) == test_bit(HCI_SC_ONLY, &hdev->dev_flags)) {
4288 err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
4289 goto failed;
4290 }
4291
4292 cmd = mgmt_pending_add(sk, MGMT_OP_SET_SECURE_CONN, hdev, data, len);
4293 if (!cmd) {
4294 err = -ENOMEM;
4295 goto failed;
4296 }
4297
4298 err = hci_send_cmd(hdev, HCI_OP_WRITE_SC_SUPPORT, 1, &val);
4299 if (err < 0) {
4300 mgmt_pending_remove(cmd);
4301 goto failed;
4302 }
4303
4304 if (cp->val == 0x02)
4305 set_bit(HCI_SC_ONLY, &hdev->dev_flags);
4306 else
4307 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
4308
4309failed:
4310 hci_dev_unlock(hdev);
4311 return err;
4312}
4313
4314static int set_debug_keys(struct sock *sk, struct hci_dev *hdev,
4315 void *data, u16 len)
4316{
4317 struct mgmt_mode *cp = data;
4318 bool changed;
4319 int err;
4320
4321 BT_DBG("request for %s", hdev->name);
4322
4323 if (cp->val != 0x00 && cp->val != 0x01)
4324 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS,
4325 MGMT_STATUS_INVALID_PARAMS);
4326
4327 hci_dev_lock(hdev);
4328
4329 if (cp->val)
4330 changed = !test_and_set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
4331 else
4332 changed = test_and_clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
4333
4334 err = send_settings_rsp(sk, MGMT_OP_SET_DEBUG_KEYS, hdev);
4335 if (err < 0)
4336 goto unlock;
4337
4338 if (changed)
4339 err = new_settings(hdev, sk);
4340
4341unlock:
4342 hci_dev_unlock(hdev);
4343 return err;
4344}
4345
4346static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data,
4347 u16 len)
4348{
4349 struct mgmt_cp_set_privacy *cp = cp_data;
4350 bool changed;
4351 int err;
4352
4353 BT_DBG("request for %s", hdev->name);
4354
4355 if (!lmp_le_capable(hdev))
4356 return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
4357 MGMT_STATUS_NOT_SUPPORTED);
4358
4359 if (cp->privacy != 0x00 && cp->privacy != 0x01)
4360 return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
4361 MGMT_STATUS_INVALID_PARAMS);
4362
4363 if (hdev_is_powered(hdev))
4364 return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
4365 MGMT_STATUS_REJECTED);
4366
4367 hci_dev_lock(hdev);
4368
4369 /* If user space supports this command it is also expected to
4370 * handle IRKs. Therefore, set the HCI_RPA_RESOLVING flag.
4371 */
4372 set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags);
4373
4374 if (cp->privacy) {
4375 changed = !test_and_set_bit(HCI_PRIVACY, &hdev->dev_flags);
4376 memcpy(hdev->irk, cp->irk, sizeof(hdev->irk));
4377 set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
4378 } else {
4379 changed = test_and_clear_bit(HCI_PRIVACY, &hdev->dev_flags);
4380 memset(hdev->irk, 0, sizeof(hdev->irk));
4381 clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
4382 }
4383
4384 err = send_settings_rsp(sk, MGMT_OP_SET_PRIVACY, hdev);
4385 if (err < 0)
4386 goto unlock;
4387
4388 if (changed)
4389 err = new_settings(hdev, sk);
4390
4391unlock:
4392 hci_dev_unlock(hdev);
4393 return err;
4394}
4395
4396static bool irk_is_valid(struct mgmt_irk_info *irk)
4397{
4398 switch (irk->addr.type) {
4399 case BDADDR_LE_PUBLIC:
4400 return true;
4401
4402 case BDADDR_LE_RANDOM:
4403 /* Two most significant bits shall be set */
4404 if ((irk->addr.bdaddr.b[5] & 0xc0) != 0xc0)
4405 return false;
4406 return true;
4407 }
4408
4409 return false;
4410}
4411
4412static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
4413 u16 len)
4414{
4415 struct mgmt_cp_load_irks *cp = cp_data;
4416 u16 irk_count, expected_len;
4417 int i, err;
4418
4419 BT_DBG("request for %s", hdev->name);
4420
4421 if (!lmp_le_capable(hdev))
4422 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
4423 MGMT_STATUS_NOT_SUPPORTED);
4424
4425 irk_count = __le16_to_cpu(cp->irk_count);
4426
4427 expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info);
4428 if (expected_len != len) {
4429 BT_ERR("load_irks: expected %u bytes, got %u bytes",
4430 len, expected_len);
4431 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
4432 MGMT_STATUS_INVALID_PARAMS);
4433 }
4434
4435 BT_DBG("%s irk_count %u", hdev->name, irk_count);
4436
4437 for (i = 0; i < irk_count; i++) {
4438 struct mgmt_irk_info *key = &cp->irks[i];
4439
4440 if (!irk_is_valid(key))
4441 return cmd_status(sk, hdev->id,
4442 MGMT_OP_LOAD_IRKS,
4443 MGMT_STATUS_INVALID_PARAMS);
4444 }
4445
4446 hci_dev_lock(hdev);
4447
4448 hci_smp_irks_clear(hdev);
4449
4450 for (i = 0; i < irk_count; i++) {
4451 struct mgmt_irk_info *irk = &cp->irks[i];
4452 u8 addr_type;
4453
4454 if (irk->addr.type == BDADDR_LE_PUBLIC)
4455 addr_type = ADDR_LE_DEV_PUBLIC;
4456 else
4457 addr_type = ADDR_LE_DEV_RANDOM;
4458
4459 hci_add_irk(hdev, &irk->addr.bdaddr, addr_type, irk->val,
4460 BDADDR_ANY);
4461 }
4462
4463 set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags);
4464
4465 err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0);
4466
4467 hci_dev_unlock(hdev);
4468
4469 return err;
4470}
4471
4002static bool ltk_is_valid(struct mgmt_ltk_info *key) 4472static bool ltk_is_valid(struct mgmt_ltk_info *key)
4003{ 4473{
4004 if (key->authenticated != 0x00 && key->authenticated != 0x01)
4005 return false;
4006 if (key->master != 0x00 && key->master != 0x01) 4474 if (key->master != 0x00 && key->master != 0x01)
4007 return false; 4475 return false;
4008 if (!bdaddr_type_is_le(key->addr.type)) 4476
4009 return false; 4477 switch (key->addr.type) {
4010 return true; 4478 case BDADDR_LE_PUBLIC:
4479 return true;
4480
4481 case BDADDR_LE_RANDOM:
4482 /* Two most significant bits shall be set */
4483 if ((key->addr.bdaddr.b[5] & 0xc0) != 0xc0)
4484 return false;
4485 return true;
4486 }
4487
4488 return false;
4011} 4489}
4012 4490
4013static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, 4491static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
@@ -4063,9 +4541,9 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
4063 else 4541 else
4064 type = HCI_SMP_LTK_SLAVE; 4542 type = HCI_SMP_LTK_SLAVE;
4065 4543
4066 hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, 4544 hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type,
4067 type, 0, key->authenticated, key->val, 4545 key->type, key->val, key->enc_size, key->ediv,
4068 key->enc_size, key->ediv, key->rand); 4546 key->rand);
4069 } 4547 }
4070 4548
4071 err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0, 4549 err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0,
@@ -4115,7 +4593,7 @@ static const struct mgmt_handler {
4115 { user_passkey_reply, false, MGMT_USER_PASSKEY_REPLY_SIZE }, 4593 { user_passkey_reply, false, MGMT_USER_PASSKEY_REPLY_SIZE },
4116 { user_passkey_neg_reply, false, MGMT_USER_PASSKEY_NEG_REPLY_SIZE }, 4594 { user_passkey_neg_reply, false, MGMT_USER_PASSKEY_NEG_REPLY_SIZE },
4117 { read_local_oob_data, false, MGMT_READ_LOCAL_OOB_DATA_SIZE }, 4595 { read_local_oob_data, false, MGMT_READ_LOCAL_OOB_DATA_SIZE },
4118 { add_remote_oob_data, false, MGMT_ADD_REMOTE_OOB_DATA_SIZE }, 4596 { add_remote_oob_data, true, MGMT_ADD_REMOTE_OOB_DATA_SIZE },
4119 { remove_remote_oob_data, false, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE }, 4597 { remove_remote_oob_data, false, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE },
4120 { start_discovery, false, MGMT_START_DISCOVERY_SIZE }, 4598 { start_discovery, false, MGMT_START_DISCOVERY_SIZE },
4121 { stop_discovery, false, MGMT_STOP_DISCOVERY_SIZE }, 4599 { stop_discovery, false, MGMT_STOP_DISCOVERY_SIZE },
@@ -4127,6 +4605,10 @@ static const struct mgmt_handler {
4127 { set_bredr, false, MGMT_SETTING_SIZE }, 4605 { set_bredr, false, MGMT_SETTING_SIZE },
4128 { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE }, 4606 { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE },
4129 { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE }, 4607 { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE },
4608 { set_secure_conn, false, MGMT_SETTING_SIZE },
4609 { set_debug_keys, false, MGMT_SETTING_SIZE },
4610 { set_privacy, false, MGMT_SET_PRIVACY_SIZE },
4611 { load_irks, true, MGMT_LOAD_IRKS_SIZE },
4130}; 4612};
4131 4613
4132 4614
@@ -4243,6 +4725,17 @@ void mgmt_index_removed(struct hci_dev *hdev)
4243 mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); 4725 mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
4244} 4726}
4245 4727
4728/* This function requires the caller holds hdev->lock */
4729static void restart_le_auto_conns(struct hci_dev *hdev)
4730{
4731 struct hci_conn_params *p;
4732
4733 list_for_each_entry(p, &hdev->le_conn_params, list) {
4734 if (p->auto_connect == HCI_AUTO_CONN_ALWAYS)
4735 hci_pend_le_conn_add(hdev, &p->addr, p->addr_type);
4736 }
4737}
4738
4246static void powered_complete(struct hci_dev *hdev, u8 status) 4739static void powered_complete(struct hci_dev *hdev, u8 status)
4247{ 4740{
4248 struct cmd_lookup match = { NULL, hdev }; 4741 struct cmd_lookup match = { NULL, hdev };
@@ -4251,6 +4744,8 @@ static void powered_complete(struct hci_dev *hdev, u8 status)
4251 4744
4252 hci_dev_lock(hdev); 4745 hci_dev_lock(hdev);
4253 4746
4747 restart_le_auto_conns(hdev);
4748
4254 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); 4749 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
4255 4750
4256 new_settings(hdev, match.sk); 4751 new_settings(hdev, match.sk);
@@ -4292,11 +4787,6 @@ static int powered_update_hci(struct hci_dev *hdev)
4292 } 4787 }
4293 4788
4294 if (lmp_le_capable(hdev)) { 4789 if (lmp_le_capable(hdev)) {
4295 /* Set random address to static address if configured */
4296 if (bacmp(&hdev->static_addr, BDADDR_ANY))
4297 hci_req_add(&req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
4298 &hdev->static_addr);
4299
4300 /* Make sure the controller has a good default for 4790 /* Make sure the controller has a good default for
4301 * advertising data. This also applies to the case 4791 * advertising data. This also applies to the case
4302 * where BR/EDR was toggled during the AUTO_OFF phase. 4792 * where BR/EDR was toggled during the AUTO_OFF phase.
@@ -4422,6 +4912,10 @@ void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
4422 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev)) 4912 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
4423 return; 4913 return;
4424 4914
4915 /* Powering off may clear the scan mode - don't let that interfere */
4916 if (!discoverable && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
4917 return;
4918
4425 if (discoverable) { 4919 if (discoverable) {
4426 changed = !test_and_set_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 4920 changed = !test_and_set_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
4427 } else { 4921 } else {
@@ -4455,6 +4949,10 @@ void mgmt_connectable(struct hci_dev *hdev, u8 connectable)
4455 if (mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) 4949 if (mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
4456 return; 4950 return;
4457 4951
4952 /* Powering off may clear the scan mode - don't let that interfere */
4953 if (!connectable && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
4954 return;
4955
4458 if (connectable) 4956 if (connectable)
4459 changed = !test_and_set_bit(HCI_CONNECTABLE, &hdev->dev_flags); 4957 changed = !test_and_set_bit(HCI_CONNECTABLE, &hdev->dev_flags);
4460 else 4958 else
@@ -4464,6 +4962,18 @@ void mgmt_connectable(struct hci_dev *hdev, u8 connectable)
4464 new_settings(hdev, NULL); 4962 new_settings(hdev, NULL);
4465} 4963}
4466 4964
4965void mgmt_advertising(struct hci_dev *hdev, u8 advertising)
4966{
4967 /* Powering off may stop advertising - don't let that interfere */
4968 if (!advertising && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
4969 return;
4970
4971 if (advertising)
4972 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
4973 else
4974 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
4975}
4976
4467void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) 4977void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
4468{ 4978{
4469 u8 mgmt_err = mgmt_status(status); 4979 u8 mgmt_err = mgmt_status(status);
@@ -4494,28 +5004,74 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
4494 mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); 5004 mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
4495} 5005}
4496 5006
4497void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent) 5007void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key)
4498{ 5008{
4499 struct mgmt_ev_new_long_term_key ev; 5009 struct mgmt_ev_new_long_term_key ev;
4500 5010
4501 memset(&ev, 0, sizeof(ev)); 5011 memset(&ev, 0, sizeof(ev));
4502 5012
4503 ev.store_hint = persistent; 5013 /* Devices using resolvable or non-resolvable random addresses
5014 * without providing an indentity resolving key don't require
5015 * to store long term keys. Their addresses will change the
5016 * next time around.
5017 *
5018 * Only when a remote device provides an identity address
5019 * make sure the long term key is stored. If the remote
5020 * identity is known, the long term keys are internally
5021 * mapped to the identity address. So allow static random
5022 * and public addresses here.
5023 */
5024 if (key->bdaddr_type == ADDR_LE_DEV_RANDOM &&
5025 (key->bdaddr.b[5] & 0xc0) != 0xc0)
5026 ev.store_hint = 0x00;
5027 else
5028 ev.store_hint = 0x01;
5029
4504 bacpy(&ev.key.addr.bdaddr, &key->bdaddr); 5030 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
4505 ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); 5031 ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
4506 ev.key.authenticated = key->authenticated; 5032 ev.key.type = key->authenticated;
4507 ev.key.enc_size = key->enc_size; 5033 ev.key.enc_size = key->enc_size;
4508 ev.key.ediv = key->ediv; 5034 ev.key.ediv = key->ediv;
5035 ev.key.rand = key->rand;
4509 5036
4510 if (key->type == HCI_SMP_LTK) 5037 if (key->type == HCI_SMP_LTK)
4511 ev.key.master = 1; 5038 ev.key.master = 1;
4512 5039
4513 memcpy(ev.key.rand, key->rand, sizeof(key->rand));
4514 memcpy(ev.key.val, key->val, sizeof(key->val)); 5040 memcpy(ev.key.val, key->val, sizeof(key->val));
4515 5041
4516 mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL); 5042 mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL);
4517} 5043}
4518 5044
5045void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk)
5046{
5047 struct mgmt_ev_new_irk ev;
5048
5049 memset(&ev, 0, sizeof(ev));
5050
5051 /* For identity resolving keys from devices that are already
5052 * using a public address or static random address, do not
5053 * ask for storing this key. The identity resolving key really
5054 * is only mandatory for devices using resovlable random
5055 * addresses.
5056 *
5057 * Storing all identity resolving keys has the downside that
5058 * they will be also loaded on next boot of they system. More
5059 * identity resolving keys, means more time during scanning is
5060 * needed to actually resolve these addresses.
5061 */
5062 if (bacmp(&irk->rpa, BDADDR_ANY))
5063 ev.store_hint = 0x01;
5064 else
5065 ev.store_hint = 0x00;
5066
5067 bacpy(&ev.rpa, &irk->rpa);
5068 bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
5069 ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
5070 memcpy(ev.irk.val, irk->val, sizeof(irk->val));
5071
5072 mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
5073}
5074
4519static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, 5075static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
4520 u8 data_len) 5076 u8 data_len)
4521{ 5077{
@@ -4590,11 +5146,29 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
4590} 5146}
4591 5147
4592void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, 5148void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
4593 u8 link_type, u8 addr_type, u8 reason) 5149 u8 link_type, u8 addr_type, u8 reason,
5150 bool mgmt_connected)
4594{ 5151{
4595 struct mgmt_ev_device_disconnected ev; 5152 struct mgmt_ev_device_disconnected ev;
5153 struct pending_cmd *power_off;
4596 struct sock *sk = NULL; 5154 struct sock *sk = NULL;
4597 5155
5156 power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
5157 if (power_off) {
5158 struct mgmt_mode *cp = power_off->param;
5159
5160 /* The connection is still in hci_conn_hash so test for 1
5161 * instead of 0 to know if this is the last one.
5162 */
5163 if (!cp->val && hci_conn_count(hdev) == 1) {
5164 cancel_delayed_work(&hdev->power_off);
5165 queue_work(hdev->req_workqueue, &hdev->power_off.work);
5166 }
5167 }
5168
5169 if (!mgmt_connected)
5170 return;
5171
4598 if (link_type != ACL_LINK && link_type != LE_LINK) 5172 if (link_type != ACL_LINK && link_type != LE_LINK)
4599 return; 5173 return;
4600 5174
@@ -4649,6 +5223,20 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
4649 u8 addr_type, u8 status) 5223 u8 addr_type, u8 status)
4650{ 5224{
4651 struct mgmt_ev_connect_failed ev; 5225 struct mgmt_ev_connect_failed ev;
5226 struct pending_cmd *power_off;
5227
5228 power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
5229 if (power_off) {
5230 struct mgmt_mode *cp = power_off->param;
5231
5232 /* The connection is still in hci_conn_hash so test for 1
5233 * instead of 0 to know if this is the last one.
5234 */
5235 if (!cp->val && hci_conn_count(hdev) == 1) {
5236 cancel_delayed_work(&hdev->power_off);
5237 queue_work(hdev->req_workqueue, &hdev->power_off.work);
5238 }
5239 }
4652 5240
4653 bacpy(&ev.addr.bdaddr, bdaddr); 5241 bacpy(&ev.addr.bdaddr, bdaddr);
4654 ev.addr.type = link_to_bdaddr(link_type, addr_type); 5242 ev.addr.type = link_to_bdaddr(link_type, addr_type);
@@ -4910,6 +5498,43 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
4910 hci_req_run(&req, NULL); 5498 hci_req_run(&req, NULL);
4911} 5499}
4912 5500
5501void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
5502{
5503 struct cmd_lookup match = { NULL, hdev };
5504 bool changed = false;
5505
5506 if (status) {
5507 u8 mgmt_err = mgmt_status(status);
5508
5509 if (enable) {
5510 if (test_and_clear_bit(HCI_SC_ENABLED,
5511 &hdev->dev_flags))
5512 new_settings(hdev, NULL);
5513 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
5514 }
5515
5516 mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev,
5517 cmd_status_rsp, &mgmt_err);
5518 return;
5519 }
5520
5521 if (enable) {
5522 changed = !test_and_set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
5523 } else {
5524 changed = test_and_clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
5525 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
5526 }
5527
5528 mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev,
5529 settings_rsp, &match);
5530
5531 if (changed)
5532 new_settings(hdev, match.sk);
5533
5534 if (match.sk)
5535 sock_put(match.sk);
5536}
5537
4913static void sk_lookup(struct pending_cmd *cmd, void *data) 5538static void sk_lookup(struct pending_cmd *cmd, void *data)
4914{ 5539{
4915 struct cmd_lookup *match = data; 5540 struct cmd_lookup *match = data;
@@ -4964,8 +5589,9 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
4964 cmd ? cmd->sk : NULL); 5589 cmd ? cmd->sk : NULL);
4965} 5590}
4966 5591
4967void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, 5592void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
4968 u8 *randomizer, u8 status) 5593 u8 *randomizer192, u8 *hash256,
5594 u8 *randomizer256, u8 status)
4969{ 5595{
4970 struct pending_cmd *cmd; 5596 struct pending_cmd *cmd;
4971 5597
@@ -4979,13 +5605,32 @@ void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
4979 cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, 5605 cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
4980 mgmt_status(status)); 5606 mgmt_status(status));
4981 } else { 5607 } else {
4982 struct mgmt_rp_read_local_oob_data rp; 5608 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
5609 hash256 && randomizer256) {
5610 struct mgmt_rp_read_local_oob_ext_data rp;
5611
5612 memcpy(rp.hash192, hash192, sizeof(rp.hash192));
5613 memcpy(rp.randomizer192, randomizer192,
5614 sizeof(rp.randomizer192));
5615
5616 memcpy(rp.hash256, hash256, sizeof(rp.hash256));
5617 memcpy(rp.randomizer256, randomizer256,
5618 sizeof(rp.randomizer256));
5619
5620 cmd_complete(cmd->sk, hdev->id,
5621 MGMT_OP_READ_LOCAL_OOB_DATA, 0,
5622 &rp, sizeof(rp));
5623 } else {
5624 struct mgmt_rp_read_local_oob_data rp;
4983 5625
4984 memcpy(rp.hash, hash, sizeof(rp.hash)); 5626 memcpy(rp.hash, hash192, sizeof(rp.hash));
4985 memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); 5627 memcpy(rp.randomizer, randomizer192,
5628 sizeof(rp.randomizer));
4986 5629
4987 cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, 5630 cmd_complete(cmd->sk, hdev->id,
4988 0, &rp, sizeof(rp)); 5631 MGMT_OP_READ_LOCAL_OOB_DATA, 0,
5632 &rp, sizeof(rp));
5633 }
4989 } 5634 }
4990 5635
4991 mgmt_pending_remove(cmd); 5636 mgmt_pending_remove(cmd);
@@ -4997,6 +5642,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
4997{ 5642{
4998 char buf[512]; 5643 char buf[512];
4999 struct mgmt_ev_device_found *ev = (void *) buf; 5644 struct mgmt_ev_device_found *ev = (void *) buf;
5645 struct smp_irk *irk;
5000 size_t ev_size; 5646 size_t ev_size;
5001 5647
5002 if (!hci_discovery_active(hdev)) 5648 if (!hci_discovery_active(hdev))
@@ -5008,8 +5654,15 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
5008 5654
5009 memset(buf, 0, sizeof(buf)); 5655 memset(buf, 0, sizeof(buf));
5010 5656
5011 bacpy(&ev->addr.bdaddr, bdaddr); 5657 irk = hci_get_irk(hdev, bdaddr, addr_type);
5012 ev->addr.type = link_to_bdaddr(link_type, addr_type); 5658 if (irk) {
5659 bacpy(&ev->addr.bdaddr, &irk->bdaddr);
5660 ev->addr.type = link_to_bdaddr(link_type, irk->addr_type);
5661 } else {
5662 bacpy(&ev->addr.bdaddr, bdaddr);
5663 ev->addr.type = link_to_bdaddr(link_type, addr_type);
5664 }
5665
5013 ev->rssi = rssi; 5666 ev->rssi = rssi;
5014 if (cfm_name) 5667 if (cfm_name)
5015 ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); 5668 ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index facd8a79c038..21e15318937c 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -216,6 +216,7 @@ static int rfcomm_check_security(struct rfcomm_dlc *d)
216 216
217 switch (d->sec_level) { 217 switch (d->sec_level) {
218 case BT_SECURITY_HIGH: 218 case BT_SECURITY_HIGH:
219 case BT_SECURITY_FIPS:
219 auth_type = HCI_AT_GENERAL_BONDING_MITM; 220 auth_type = HCI_AT_GENERAL_BONDING_MITM;
220 break; 221 break;
221 case BT_SECURITY_MEDIUM: 222 case BT_SECURITY_MEDIUM:
@@ -359,6 +360,11 @@ static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
359 return NULL; 360 return NULL;
360} 361}
361 362
363static int rfcomm_check_channel(u8 channel)
364{
365 return channel < 1 || channel > 30;
366}
367
362static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel) 368static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
363{ 369{
364 struct rfcomm_session *s; 370 struct rfcomm_session *s;
@@ -368,7 +374,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
368 BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d", 374 BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
369 d, d->state, src, dst, channel); 375 d, d->state, src, dst, channel);
370 376
371 if (channel < 1 || channel > 30) 377 if (rfcomm_check_channel(channel))
372 return -EINVAL; 378 return -EINVAL;
373 379
374 if (d->state != BT_OPEN && d->state != BT_CLOSED) 380 if (d->state != BT_OPEN && d->state != BT_CLOSED)
@@ -425,6 +431,20 @@ int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 chann
425 return r; 431 return r;
426} 432}
427 433
434static void __rfcomm_dlc_disconn(struct rfcomm_dlc *d)
435{
436 struct rfcomm_session *s = d->session;
437
438 d->state = BT_DISCONN;
439 if (skb_queue_empty(&d->tx_queue)) {
440 rfcomm_send_disc(s, d->dlci);
441 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
442 } else {
443 rfcomm_queue_disc(d);
444 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
445 }
446}
447
428static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) 448static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
429{ 449{
430 struct rfcomm_session *s = d->session; 450 struct rfcomm_session *s = d->session;
@@ -437,32 +457,29 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
437 switch (d->state) { 457 switch (d->state) {
438 case BT_CONNECT: 458 case BT_CONNECT:
439 case BT_CONFIG: 459 case BT_CONFIG:
460 case BT_OPEN:
461 case BT_CONNECT2:
440 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { 462 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
441 set_bit(RFCOMM_AUTH_REJECT, &d->flags); 463 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
442 rfcomm_schedule(); 464 rfcomm_schedule();
443 break; 465 return 0;
444 } 466 }
445 /* Fall through */ 467 }
446 468
469 switch (d->state) {
470 case BT_CONNECT:
447 case BT_CONNECTED: 471 case BT_CONNECTED:
448 d->state = BT_DISCONN; 472 __rfcomm_dlc_disconn(d);
449 if (skb_queue_empty(&d->tx_queue)) {
450 rfcomm_send_disc(s, d->dlci);
451 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
452 } else {
453 rfcomm_queue_disc(d);
454 rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
455 }
456 break; 473 break;
457 474
458 case BT_OPEN: 475 case BT_CONFIG:
459 case BT_CONNECT2: 476 if (s->state != BT_BOUND) {
460 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { 477 __rfcomm_dlc_disconn(d);
461 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
462 rfcomm_schedule();
463 break; 478 break;
464 } 479 }
465 /* Fall through */ 480 /* if closing a dlc in a session that hasn't been started,
481 * just close and unlink the dlc
482 */
466 483
467 default: 484 default:
468 rfcomm_dlc_clear_timer(d); 485 rfcomm_dlc_clear_timer(d);
@@ -513,6 +530,25 @@ no_session:
513 return r; 530 return r;
514} 531}
515 532
533struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel)
534{
535 struct rfcomm_session *s;
536 struct rfcomm_dlc *dlc = NULL;
537 u8 dlci;
538
539 if (rfcomm_check_channel(channel))
540 return ERR_PTR(-EINVAL);
541
542 rfcomm_lock();
543 s = rfcomm_session_get(src, dst);
544 if (s) {
545 dlci = __dlci(!s->initiator, channel);
546 dlc = rfcomm_dlc_get(s, dlci);
547 }
548 rfcomm_unlock();
549 return dlc;
550}
551
516int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) 552int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
517{ 553{
518 int len = skb->len; 554 int len = skb->len;
@@ -533,6 +569,20 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
533 return len; 569 return len;
534} 570}
535 571
572void rfcomm_dlc_send_noerror(struct rfcomm_dlc *d, struct sk_buff *skb)
573{
574 int len = skb->len;
575
576 BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
577
578 rfcomm_make_uih(skb, d->addr);
579 skb_queue_tail(&d->tx_queue, skb);
580
581 if (d->state == BT_CONNECTED &&
582 !test_bit(RFCOMM_TX_THROTTLED, &d->flags))
583 rfcomm_schedule();
584}
585
536void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) 586void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
537{ 587{
538 BT_DBG("dlc %p state %ld", d, d->state); 588 BT_DBG("dlc %p state %ld", d, d->state);
@@ -1943,12 +1993,11 @@ static void rfcomm_process_sessions(void)
1943 continue; 1993 continue;
1944 } 1994 }
1945 1995
1946 if (s->state == BT_LISTEN) { 1996 switch (s->state) {
1997 case BT_LISTEN:
1947 rfcomm_accept_connection(s); 1998 rfcomm_accept_connection(s);
1948 continue; 1999 continue;
1949 }
1950 2000
1951 switch (s->state) {
1952 case BT_BOUND: 2001 case BT_BOUND:
1953 s = rfcomm_check_connection(s); 2002 s = rfcomm_check_connection(s);
1954 break; 2003 break;
@@ -2085,7 +2134,8 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2085 set_bit(RFCOMM_SEC_PENDING, &d->flags); 2134 set_bit(RFCOMM_SEC_PENDING, &d->flags);
2086 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); 2135 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
2087 continue; 2136 continue;
2088 } else if (d->sec_level == BT_SECURITY_HIGH) { 2137 } else if (d->sec_level == BT_SECURITY_HIGH ||
2138 d->sec_level == BT_SECURITY_FIPS) {
2089 set_bit(RFCOMM_ENC_DROP, &d->flags); 2139 set_bit(RFCOMM_ENC_DROP, &d->flags);
2090 continue; 2140 continue;
2091 } 2141 }
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 3c2d3e4aa2f5..c024e715512f 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -105,13 +105,18 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
105} 105}
106 106
107/* ---- Socket functions ---- */ 107/* ---- Socket functions ---- */
108static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) 108static struct sock *__rfcomm_get_listen_sock_by_addr(u8 channel, bdaddr_t *src)
109{ 109{
110 struct sock *sk = NULL; 110 struct sock *sk = NULL;
111 111
112 sk_for_each(sk, &rfcomm_sk_list.head) { 112 sk_for_each(sk, &rfcomm_sk_list.head) {
113 if (rfcomm_pi(sk)->channel == channel && 113 if (rfcomm_pi(sk)->channel != channel)
114 !bacmp(&rfcomm_pi(sk)->src, src)) 114 continue;
115
116 if (bacmp(&rfcomm_pi(sk)->src, src))
117 continue;
118
119 if (sk->sk_state == BT_BOUND || sk->sk_state == BT_LISTEN)
115 break; 120 break;
116 } 121 }
117 122
@@ -331,6 +336,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
331{ 336{
332 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; 337 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
333 struct sock *sk = sock->sk; 338 struct sock *sk = sock->sk;
339 int chan = sa->rc_channel;
334 int err = 0; 340 int err = 0;
335 341
336 BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr); 342 BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr);
@@ -352,12 +358,12 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
352 358
353 write_lock(&rfcomm_sk_list.lock); 359 write_lock(&rfcomm_sk_list.lock);
354 360
355 if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) { 361 if (chan && __rfcomm_get_listen_sock_by_addr(chan, &sa->rc_bdaddr)) {
356 err = -EADDRINUSE; 362 err = -EADDRINUSE;
357 } else { 363 } else {
358 /* Save source address */ 364 /* Save source address */
359 bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr); 365 bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr);
360 rfcomm_pi(sk)->channel = sa->rc_channel; 366 rfcomm_pi(sk)->channel = chan;
361 sk->sk_state = BT_BOUND; 367 sk->sk_state = BT_BOUND;
362 } 368 }
363 369
@@ -439,7 +445,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
439 write_lock(&rfcomm_sk_list.lock); 445 write_lock(&rfcomm_sk_list.lock);
440 446
441 for (channel = 1; channel < 31; channel++) 447 for (channel = 1; channel < 31; channel++)
442 if (!__rfcomm_get_sock_by_addr(channel, src)) { 448 if (!__rfcomm_get_listen_sock_by_addr(channel, src)) {
443 rfcomm_pi(sk)->channel = channel; 449 rfcomm_pi(sk)->channel = channel;
444 err = 0; 450 err = 0;
445 break; 451 break;
@@ -528,6 +534,9 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *
528 534
529 BT_DBG("sock %p, sk %p", sock, sk); 535 BT_DBG("sock %p, sk %p", sock, sk);
530 536
537 if (peer && sk->sk_state != BT_CONNECTED)
538 return -ENOTCONN;
539
531 memset(sa, 0, sizeof(*sa)); 540 memset(sa, 0, sizeof(*sa));
532 sa->rc_family = AF_BLUETOOTH; 541 sa->rc_family = AF_BLUETOOTH;
533 sa->rc_channel = rfcomm_pi(sk)->channel; 542 sa->rc_channel = rfcomm_pi(sk)->channel;
@@ -648,6 +657,11 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
648 break; 657 break;
649 } 658 }
650 659
660 if (opt & RFCOMM_LM_FIPS) {
661 err = -EINVAL;
662 break;
663 }
664
651 if (opt & RFCOMM_LM_AUTH) 665 if (opt & RFCOMM_LM_AUTH)
652 rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW; 666 rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW;
653 if (opt & RFCOMM_LM_ENCRYPT) 667 if (opt & RFCOMM_LM_ENCRYPT)
@@ -762,7 +776,11 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
762 break; 776 break;
763 case BT_SECURITY_HIGH: 777 case BT_SECURITY_HIGH:
764 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT | 778 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
765 RFCOMM_LM_SECURE; 779 RFCOMM_LM_SECURE;
780 break;
781 case BT_SECURITY_FIPS:
782 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
783 RFCOMM_LM_SECURE | RFCOMM_LM_FIPS;
766 break; 784 break;
767 default: 785 default:
768 opt = 0; 786 opt = 0;
@@ -774,6 +792,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
774 792
775 if (put_user(opt, (u32 __user *) optval)) 793 if (put_user(opt, (u32 __user *) optval))
776 err = -EFAULT; 794 err = -EFAULT;
795
777 break; 796 break;
778 797
779 case RFCOMM_CONNINFO: 798 case RFCOMM_CONNINFO:
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index f9c0980abeea..403ec09f480a 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -40,6 +40,7 @@
40#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */ 40#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
41#define RFCOMM_TTY_MINOR 0 41#define RFCOMM_TTY_MINOR 0
42 42
43static DEFINE_MUTEX(rfcomm_ioctl_mutex);
43static struct tty_driver *rfcomm_tty_driver; 44static struct tty_driver *rfcomm_tty_driver;
44 45
45struct rfcomm_dev { 46struct rfcomm_dev {
@@ -51,6 +52,8 @@ struct rfcomm_dev {
51 unsigned long flags; 52 unsigned long flags;
52 int err; 53 int err;
53 54
55 unsigned long status; /* don't export to userspace */
56
54 bdaddr_t src; 57 bdaddr_t src;
55 bdaddr_t dst; 58 bdaddr_t dst;
56 u8 channel; 59 u8 channel;
@@ -58,7 +61,6 @@ struct rfcomm_dev {
58 uint modem_status; 61 uint modem_status;
59 62
60 struct rfcomm_dlc *dlc; 63 struct rfcomm_dlc *dlc;
61 wait_queue_head_t conn_wait;
62 64
63 struct device *tty_dev; 65 struct device *tty_dev;
64 66
@@ -83,10 +85,6 @@ static void rfcomm_dev_destruct(struct tty_port *port)
83 85
84 BT_DBG("dev %p dlc %p", dev, dlc); 86 BT_DBG("dev %p dlc %p", dev, dlc);
85 87
86 spin_lock(&rfcomm_dev_lock);
87 list_del(&dev->list);
88 spin_unlock(&rfcomm_dev_lock);
89
90 rfcomm_dlc_lock(dlc); 88 rfcomm_dlc_lock(dlc);
91 /* Detach DLC if it's owned by this dev */ 89 /* Detach DLC if it's owned by this dev */
92 if (dlc->owner == dev) 90 if (dlc->owner == dev)
@@ -95,7 +93,12 @@ static void rfcomm_dev_destruct(struct tty_port *port)
95 93
96 rfcomm_dlc_put(dlc); 94 rfcomm_dlc_put(dlc);
97 95
98 tty_unregister_device(rfcomm_tty_driver, dev->id); 96 if (dev->tty_dev)
97 tty_unregister_device(rfcomm_tty_driver, dev->id);
98
99 spin_lock(&rfcomm_dev_lock);
100 list_del(&dev->list);
101 spin_unlock(&rfcomm_dev_lock);
99 102
100 kfree(dev); 103 kfree(dev);
101 104
@@ -104,60 +107,24 @@ static void rfcomm_dev_destruct(struct tty_port *port)
104 module_put(THIS_MODULE); 107 module_put(THIS_MODULE);
105} 108}
106 109
107static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
108{
109 struct hci_dev *hdev;
110 struct hci_conn *conn;
111
112 hdev = hci_get_route(&dev->dst, &dev->src);
113 if (!hdev)
114 return NULL;
115
116 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
117
118 hci_dev_put(hdev);
119
120 return conn ? &conn->dev : NULL;
121}
122
123/* device-specific initialization: open the dlc */ 110/* device-specific initialization: open the dlc */
124static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty) 111static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty)
125{ 112{
126 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); 113 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
127 DEFINE_WAIT(wait);
128 int err; 114 int err;
129 115
130 err = rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel); 116 err = rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel);
131 if (err) 117 if (err)
132 return err; 118 set_bit(TTY_IO_ERROR, &tty->flags);
133 119 return err;
134 while (1) { 120}
135 prepare_to_wait(&dev->conn_wait, &wait, TASK_INTERRUPTIBLE);
136
137 if (dev->dlc->state == BT_CLOSED) {
138 err = -dev->err;
139 break;
140 }
141
142 if (dev->dlc->state == BT_CONNECTED)
143 break;
144
145 if (signal_pending(current)) {
146 err = -ERESTARTSYS;
147 break;
148 }
149
150 tty_unlock(tty);
151 schedule();
152 tty_lock(tty);
153 }
154 finish_wait(&dev->conn_wait, &wait);
155 121
156 if (!err) 122/* we block the open until the dlc->state becomes BT_CONNECTED */
157 device_move(dev->tty_dev, rfcomm_get_device(dev), 123static int rfcomm_dev_carrier_raised(struct tty_port *port)
158 DPM_ORDER_DEV_AFTER_PARENT); 124{
125 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
159 126
160 return err; 127 return (dev->dlc->state == BT_CONNECTED);
161} 128}
162 129
163/* device-specific cleanup: close the dlc */ 130/* device-specific cleanup: close the dlc */
@@ -176,9 +143,10 @@ static const struct tty_port_operations rfcomm_port_ops = {
176 .destruct = rfcomm_dev_destruct, 143 .destruct = rfcomm_dev_destruct,
177 .activate = rfcomm_dev_activate, 144 .activate = rfcomm_dev_activate,
178 .shutdown = rfcomm_dev_shutdown, 145 .shutdown = rfcomm_dev_shutdown,
146 .carrier_raised = rfcomm_dev_carrier_raised,
179}; 147};
180 148
181static struct rfcomm_dev *__rfcomm_dev_get(int id) 149static struct rfcomm_dev *__rfcomm_dev_lookup(int id)
182{ 150{
183 struct rfcomm_dev *dev; 151 struct rfcomm_dev *dev;
184 152
@@ -195,20 +163,41 @@ static struct rfcomm_dev *rfcomm_dev_get(int id)
195 163
196 spin_lock(&rfcomm_dev_lock); 164 spin_lock(&rfcomm_dev_lock);
197 165
198 dev = __rfcomm_dev_get(id); 166 dev = __rfcomm_dev_lookup(id);
199 167
200 if (dev) { 168 if (dev && !tty_port_get(&dev->port))
201 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) 169 dev = NULL;
202 dev = NULL;
203 else
204 tty_port_get(&dev->port);
205 }
206 170
207 spin_unlock(&rfcomm_dev_lock); 171 spin_unlock(&rfcomm_dev_lock);
208 172
209 return dev; 173 return dev;
210} 174}
211 175
176static void rfcomm_reparent_device(struct rfcomm_dev *dev)
177{
178 struct hci_dev *hdev;
179 struct hci_conn *conn;
180
181 hdev = hci_get_route(&dev->dst, &dev->src);
182 if (!hdev)
183 return;
184
185 /* The lookup results are unsafe to access without the
186 * hci device lock (FIXME: why is this not documented?)
187 */
188 hci_dev_lock(hdev);
189 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
190
191 /* Just because the acl link is in the hash table is no
192 * guarantee the sysfs device has been added ...
193 */
194 if (conn && device_is_registered(&conn->dev))
195 device_move(dev->tty_dev, &conn->dev, DPM_ORDER_DEV_AFTER_PARENT);
196
197 hci_dev_unlock(hdev);
198 hci_dev_put(hdev);
199}
200
212static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) 201static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
213{ 202{
214 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); 203 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
@@ -224,17 +213,16 @@ static ssize_t show_channel(struct device *tty_dev, struct device_attribute *att
224static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); 213static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
225static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); 214static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
226 215
227static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) 216static struct rfcomm_dev *__rfcomm_dev_add(struct rfcomm_dev_req *req,
217 struct rfcomm_dlc *dlc)
228{ 218{
229 struct rfcomm_dev *dev, *entry; 219 struct rfcomm_dev *dev, *entry;
230 struct list_head *head = &rfcomm_dev_list; 220 struct list_head *head = &rfcomm_dev_list;
231 int err = 0; 221 int err = 0;
232 222
233 BT_DBG("id %d channel %d", req->dev_id, req->channel);
234
235 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL); 223 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
236 if (!dev) 224 if (!dev)
237 return -ENOMEM; 225 return ERR_PTR(-ENOMEM);
238 226
239 spin_lock(&rfcomm_dev_lock); 227 spin_lock(&rfcomm_dev_lock);
240 228
@@ -282,7 +270,6 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
282 270
283 tty_port_init(&dev->port); 271 tty_port_init(&dev->port);
284 dev->port.ops = &rfcomm_port_ops; 272 dev->port.ops = &rfcomm_port_ops;
285 init_waitqueue_head(&dev->conn_wait);
286 273
287 skb_queue_head_init(&dev->pending); 274 skb_queue_head_init(&dev->pending);
288 275
@@ -318,22 +305,37 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
318 holds reference to this module. */ 305 holds reference to this module. */
319 __module_get(THIS_MODULE); 306 __module_get(THIS_MODULE);
320 307
308 spin_unlock(&rfcomm_dev_lock);
309 return dev;
310
321out: 311out:
322 spin_unlock(&rfcomm_dev_lock); 312 spin_unlock(&rfcomm_dev_lock);
313 kfree(dev);
314 return ERR_PTR(err);
315}
316
317static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
318{
319 struct rfcomm_dev *dev;
320 struct device *tty;
321
322 BT_DBG("id %d channel %d", req->dev_id, req->channel);
323 323
324 if (err < 0) 324 dev = __rfcomm_dev_add(req, dlc);
325 goto free; 325 if (IS_ERR(dev)) {
326 rfcomm_dlc_put(dlc);
327 return PTR_ERR(dev);
328 }
326 329
327 dev->tty_dev = tty_port_register_device(&dev->port, rfcomm_tty_driver, 330 tty = tty_port_register_device(&dev->port, rfcomm_tty_driver,
328 dev->id, NULL); 331 dev->id, NULL);
329 if (IS_ERR(dev->tty_dev)) { 332 if (IS_ERR(tty)) {
330 err = PTR_ERR(dev->tty_dev); 333 tty_port_put(&dev->port);
331 spin_lock(&rfcomm_dev_lock); 334 return PTR_ERR(tty);
332 list_del(&dev->list);
333 spin_unlock(&rfcomm_dev_lock);
334 goto free;
335 } 335 }
336 336
337 dev->tty_dev = tty;
338 rfcomm_reparent_device(dev);
337 dev_set_drvdata(dev->tty_dev, dev); 339 dev_set_drvdata(dev->tty_dev, dev);
338 340
339 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0) 341 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
@@ -343,24 +345,23 @@ out:
343 BT_ERR("Failed to create channel attribute"); 345 BT_ERR("Failed to create channel attribute");
344 346
345 return dev->id; 347 return dev->id;
346
347free:
348 kfree(dev);
349 return err;
350} 348}
351 349
352/* ---- Send buffer ---- */ 350/* ---- Send buffer ---- */
353static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc) 351static inline unsigned int rfcomm_room(struct rfcomm_dev *dev)
354{ 352{
355 /* We can't let it be zero, because we don't get a callback 353 struct rfcomm_dlc *dlc = dev->dlc;
356 when tx_credits becomes nonzero, hence we'd never wake up */ 354
357 return dlc->mtu * (dlc->tx_credits?:1); 355 /* Limit the outstanding number of packets not yet sent to 40 */
356 int pending = 40 - atomic_read(&dev->wmem_alloc);
357
358 return max(0, pending) * dlc->mtu;
358} 359}
359 360
360static void rfcomm_wfree(struct sk_buff *skb) 361static void rfcomm_wfree(struct sk_buff *skb)
361{ 362{
362 struct rfcomm_dev *dev = (void *) skb->sk; 363 struct rfcomm_dev *dev = (void *) skb->sk;
363 atomic_sub(skb->truesize, &dev->wmem_alloc); 364 atomic_dec(&dev->wmem_alloc);
364 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) 365 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
365 tty_port_tty_wakeup(&dev->port); 366 tty_port_tty_wakeup(&dev->port);
366 tty_port_put(&dev->port); 367 tty_port_put(&dev->port);
@@ -369,28 +370,24 @@ static void rfcomm_wfree(struct sk_buff *skb)
369static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev) 370static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
370{ 371{
371 tty_port_get(&dev->port); 372 tty_port_get(&dev->port);
372 atomic_add(skb->truesize, &dev->wmem_alloc); 373 atomic_inc(&dev->wmem_alloc);
373 skb->sk = (void *) dev; 374 skb->sk = (void *) dev;
374 skb->destructor = rfcomm_wfree; 375 skb->destructor = rfcomm_wfree;
375} 376}
376 377
377static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority) 378static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
378{ 379{
379 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) { 380 struct sk_buff *skb = alloc_skb(size, priority);
380 struct sk_buff *skb = alloc_skb(size, priority); 381 if (skb)
381 if (skb) { 382 rfcomm_set_owner_w(skb, dev);
382 rfcomm_set_owner_w(skb, dev); 383 return skb;
383 return skb;
384 }
385 }
386 return NULL;
387} 384}
388 385
389/* ---- Device IOCTLs ---- */ 386/* ---- Device IOCTLs ---- */
390 387
391#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP)) 388#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
392 389
393static int rfcomm_create_dev(struct sock *sk, void __user *arg) 390static int __rfcomm_create_dev(struct sock *sk, void __user *arg)
394{ 391{
395 struct rfcomm_dev_req req; 392 struct rfcomm_dev_req req;
396 struct rfcomm_dlc *dlc; 393 struct rfcomm_dlc *dlc;
@@ -412,16 +409,22 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg)
412 dlc = rfcomm_pi(sk)->dlc; 409 dlc = rfcomm_pi(sk)->dlc;
413 rfcomm_dlc_hold(dlc); 410 rfcomm_dlc_hold(dlc);
414 } else { 411 } else {
412 /* Validate the channel is unused */
413 dlc = rfcomm_dlc_exists(&req.src, &req.dst, req.channel);
414 if (IS_ERR(dlc))
415 return PTR_ERR(dlc);
416 else if (dlc) {
417 rfcomm_dlc_put(dlc);
418 return -EBUSY;
419 }
415 dlc = rfcomm_dlc_alloc(GFP_KERNEL); 420 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
416 if (!dlc) 421 if (!dlc)
417 return -ENOMEM; 422 return -ENOMEM;
418 } 423 }
419 424
420 id = rfcomm_dev_add(&req, dlc); 425 id = rfcomm_dev_add(&req, dlc);
421 if (id < 0) { 426 if (id < 0)
422 rfcomm_dlc_put(dlc);
423 return id; 427 return id;
424 }
425 428
426 if (req.flags & (1 << RFCOMM_REUSE_DLC)) { 429 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
427 /* DLC is now used by device. 430 /* DLC is now used by device.
@@ -432,7 +435,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg)
432 return id; 435 return id;
433} 436}
434 437
435static int rfcomm_release_dev(void __user *arg) 438static int __rfcomm_release_dev(void __user *arg)
436{ 439{
437 struct rfcomm_dev_req req; 440 struct rfcomm_dev_req req;
438 struct rfcomm_dev *dev; 441 struct rfcomm_dev *dev;
@@ -452,6 +455,12 @@ static int rfcomm_release_dev(void __user *arg)
452 return -EPERM; 455 return -EPERM;
453 } 456 }
454 457
458 /* only release once */
459 if (test_and_set_bit(RFCOMM_DEV_RELEASED, &dev->status)) {
460 tty_port_put(&dev->port);
461 return -EALREADY;
462 }
463
455 if (req.flags & (1 << RFCOMM_HANGUP_NOW)) 464 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
456 rfcomm_dlc_close(dev->dlc, 0); 465 rfcomm_dlc_close(dev->dlc, 0);
457 466
@@ -462,14 +471,35 @@ static int rfcomm_release_dev(void __user *arg)
462 tty_kref_put(tty); 471 tty_kref_put(tty);
463 } 472 }
464 473
465 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) && 474 if (!test_bit(RFCOMM_TTY_OWNED, &dev->status))
466 !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags))
467 tty_port_put(&dev->port); 475 tty_port_put(&dev->port);
468 476
469 tty_port_put(&dev->port); 477 tty_port_put(&dev->port);
470 return 0; 478 return 0;
471} 479}
472 480
481static int rfcomm_create_dev(struct sock *sk, void __user *arg)
482{
483 int ret;
484
485 mutex_lock(&rfcomm_ioctl_mutex);
486 ret = __rfcomm_create_dev(sk, arg);
487 mutex_unlock(&rfcomm_ioctl_mutex);
488
489 return ret;
490}
491
492static int rfcomm_release_dev(void __user *arg)
493{
494 int ret;
495
496 mutex_lock(&rfcomm_ioctl_mutex);
497 ret = __rfcomm_release_dev(arg);
498 mutex_unlock(&rfcomm_ioctl_mutex);
499
500 return ret;
501}
502
473static int rfcomm_get_dev_list(void __user *arg) 503static int rfcomm_get_dev_list(void __user *arg)
474{ 504{
475 struct rfcomm_dev *dev; 505 struct rfcomm_dev *dev;
@@ -497,7 +527,7 @@ static int rfcomm_get_dev_list(void __user *arg)
497 spin_lock(&rfcomm_dev_lock); 527 spin_lock(&rfcomm_dev_lock);
498 528
499 list_for_each_entry(dev, &rfcomm_dev_list, list) { 529 list_for_each_entry(dev, &rfcomm_dev_list, list) {
500 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) 530 if (!tty_port_get(&dev->port))
501 continue; 531 continue;
502 (di + n)->id = dev->id; 532 (di + n)->id = dev->id;
503 (di + n)->flags = dev->flags; 533 (di + n)->flags = dev->flags;
@@ -505,6 +535,7 @@ static int rfcomm_get_dev_list(void __user *arg)
505 (di + n)->channel = dev->channel; 535 (di + n)->channel = dev->channel;
506 bacpy(&(di + n)->src, &dev->src); 536 bacpy(&(di + n)->src, &dev->src);
507 bacpy(&(di + n)->dst, &dev->dst); 537 bacpy(&(di + n)->dst, &dev->dst);
538 tty_port_put(&dev->port);
508 if (++n >= dev_num) 539 if (++n >= dev_num)
509 break; 540 break;
510 } 541 }
@@ -601,9 +632,11 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
601 BT_DBG("dlc %p dev %p err %d", dlc, dev, err); 632 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
602 633
603 dev->err = err; 634 dev->err = err;
604 wake_up_interruptible(&dev->conn_wait); 635 if (dlc->state == BT_CONNECTED) {
636 rfcomm_reparent_device(dev);
605 637
606 if (dlc->state == BT_CLOSED) 638 wake_up_interruptible(&dev->port.open_wait);
639 } else if (dlc->state == BT_CLOSED)
607 tty_port_tty_hangup(&dev->port, false); 640 tty_port_tty_hangup(&dev->port, false);
608} 641}
609 642
@@ -703,8 +736,10 @@ static int rfcomm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
703 * when the last process closes the tty. The behaviour is expected by 736 * when the last process closes the tty. The behaviour is expected by
704 * userspace. 737 * userspace.
705 */ 738 */
706 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) 739 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
740 set_bit(RFCOMM_TTY_OWNED, &dev->status);
707 tty_port_put(&dev->port); 741 tty_port_put(&dev->port);
742 }
708 743
709 return 0; 744 return 0;
710} 745}
@@ -750,7 +785,7 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
750 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 785 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
751 struct rfcomm_dlc *dlc = dev->dlc; 786 struct rfcomm_dlc *dlc = dev->dlc;
752 struct sk_buff *skb; 787 struct sk_buff *skb;
753 int err = 0, sent = 0, size; 788 int sent = 0, size;
754 789
755 BT_DBG("tty %p count %d", tty, count); 790 BT_DBG("tty %p count %d", tty, count);
756 791
@@ -758,7 +793,6 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
758 size = min_t(uint, count, dlc->mtu); 793 size = min_t(uint, count, dlc->mtu);
759 794
760 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC); 795 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
761
762 if (!skb) 796 if (!skb)
763 break; 797 break;
764 798
@@ -766,32 +800,24 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
766 800
767 memcpy(skb_put(skb, size), buf + sent, size); 801 memcpy(skb_put(skb, size), buf + sent, size);
768 802
769 err = rfcomm_dlc_send(dlc, skb); 803 rfcomm_dlc_send_noerror(dlc, skb);
770 if (err < 0) {
771 kfree_skb(skb);
772 break;
773 }
774 804
775 sent += size; 805 sent += size;
776 count -= size; 806 count -= size;
777 } 807 }
778 808
779 return sent ? sent : err; 809 return sent;
780} 810}
781 811
782static int rfcomm_tty_write_room(struct tty_struct *tty) 812static int rfcomm_tty_write_room(struct tty_struct *tty)
783{ 813{
784 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 814 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
785 int room; 815 int room = 0;
786 816
787 BT_DBG("tty %p", tty); 817 if (dev && dev->dlc)
788 818 room = rfcomm_room(dev);
789 if (!dev || !dev->dlc)
790 return 0;
791 819
792 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc); 820 BT_DBG("tty %p room %d", tty, room);
793 if (room < 0)
794 room = 0;
795 821
796 return room; 822 return room;
797} 823}
@@ -1125,7 +1151,7 @@ int __init rfcomm_init_ttys(void)
1125 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; 1151 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
1126 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 1152 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
1127 rfcomm_tty_driver->init_termios = tty_std_termios; 1153 rfcomm_tty_driver->init_termios = tty_std_termios;
1128 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 1154 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
1129 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; 1155 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
1130 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); 1156 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1131 1157
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 45007362683b..f886bcae1b7e 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -78,6 +78,70 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
78 return err; 78 return err;
79} 79}
80 80
81static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
82{
83 u8 _res[16], k[16];
84 int err;
85
86 /* r' = padding || r */
87 memset(_res, 0, 13);
88 _res[13] = r[2];
89 _res[14] = r[1];
90 _res[15] = r[0];
91
92 swap128(irk, k);
93 err = smp_e(tfm, k, _res);
94 if (err) {
95 BT_ERR("Encrypt error");
96 return err;
97 }
98
99 /* The output of the random address function ah is:
100 * ah(h, r) = e(k, r') mod 2^24
101 * The output of the security function e is then truncated to 24 bits
102 * by taking the least significant 24 bits of the output of e as the
103 * result of ah.
104 */
105 res[0] = _res[15];
106 res[1] = _res[14];
107 res[2] = _res[13];
108
109 return 0;
110}
111
112bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
113 bdaddr_t *bdaddr)
114{
115 u8 hash[3];
116 int err;
117
118 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
119
120 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
121 if (err)
122 return false;
123
124 return !memcmp(bdaddr->b, hash, 3);
125}
126
127int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
128{
129 int err;
130
131 get_random_bytes(&rpa->b[3], 3);
132
133 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
134 rpa->b[5] |= 0x40; /* Set second most significant bit */
135
136 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
137 if (err < 0)
138 return err;
139
140 BT_DBG("RPA %pMR", rpa);
141
142 return 0;
143}
144
81static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], 145static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
82 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, 146 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
83 u8 _rat, bdaddr_t *ra, u8 res[16]) 147 u8 _rat, bdaddr_t *ra, u8 res[16])
@@ -203,31 +267,45 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
203 struct smp_cmd_pairing *req, 267 struct smp_cmd_pairing *req,
204 struct smp_cmd_pairing *rsp, __u8 authreq) 268 struct smp_cmd_pairing *rsp, __u8 authreq)
205{ 269{
206 u8 dist_keys = 0; 270 struct smp_chan *smp = conn->smp_chan;
271 struct hci_conn *hcon = conn->hcon;
272 struct hci_dev *hdev = hcon->hdev;
273 u8 local_dist = 0, remote_dist = 0;
207 274
208 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) { 275 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
209 dist_keys = SMP_DIST_ENC_KEY; 276 local_dist = SMP_DIST_ENC_KEY;
277 remote_dist = SMP_DIST_ENC_KEY;
210 authreq |= SMP_AUTH_BONDING; 278 authreq |= SMP_AUTH_BONDING;
211 } else { 279 } else {
212 authreq &= ~SMP_AUTH_BONDING; 280 authreq &= ~SMP_AUTH_BONDING;
213 } 281 }
214 282
283 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
284 remote_dist |= SMP_DIST_ID_KEY;
285
286 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
287 local_dist |= SMP_DIST_ID_KEY;
288
215 if (rsp == NULL) { 289 if (rsp == NULL) {
216 req->io_capability = conn->hcon->io_capability; 290 req->io_capability = conn->hcon->io_capability;
217 req->oob_flag = SMP_OOB_NOT_PRESENT; 291 req->oob_flag = SMP_OOB_NOT_PRESENT;
218 req->max_key_size = SMP_MAX_ENC_KEY_SIZE; 292 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
219 req->init_key_dist = 0; 293 req->init_key_dist = local_dist;
220 req->resp_key_dist = dist_keys; 294 req->resp_key_dist = remote_dist;
221 req->auth_req = (authreq & AUTH_REQ_MASK); 295 req->auth_req = (authreq & AUTH_REQ_MASK);
296
297 smp->remote_key_dist = remote_dist;
222 return; 298 return;
223 } 299 }
224 300
225 rsp->io_capability = conn->hcon->io_capability; 301 rsp->io_capability = conn->hcon->io_capability;
226 rsp->oob_flag = SMP_OOB_NOT_PRESENT; 302 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
227 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; 303 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
228 rsp->init_key_dist = 0; 304 rsp->init_key_dist = req->init_key_dist & remote_dist;
229 rsp->resp_key_dist = req->resp_key_dist & dist_keys; 305 rsp->resp_key_dist = req->resp_key_dist & local_dist;
230 rsp->auth_req = (authreq & AUTH_REQ_MASK); 306 rsp->auth_req = (authreq & AUTH_REQ_MASK);
307
308 smp->remote_key_dist = rsp->init_key_dist;
231} 309}
232 310
233static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) 311static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
@@ -356,29 +434,23 @@ static void confirm_work(struct work_struct *work)
356{ 434{
357 struct smp_chan *smp = container_of(work, struct smp_chan, confirm); 435 struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
358 struct l2cap_conn *conn = smp->conn; 436 struct l2cap_conn *conn = smp->conn;
359 struct crypto_blkcipher *tfm; 437 struct hci_dev *hdev = conn->hcon->hdev;
438 struct crypto_blkcipher *tfm = hdev->tfm_aes;
360 struct smp_cmd_pairing_confirm cp; 439 struct smp_cmd_pairing_confirm cp;
361 int ret; 440 int ret;
362 u8 res[16], reason; 441 u8 res[16], reason;
363 442
364 BT_DBG("conn %p", conn); 443 BT_DBG("conn %p", conn);
365 444
366 tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); 445 /* Prevent mutual access to hdev->tfm_aes */
367 if (IS_ERR(tfm)) { 446 hci_dev_lock(hdev);
368 reason = SMP_UNSPECIFIED;
369 goto error;
370 }
371 447
372 smp->tfm = tfm; 448 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
449 conn->hcon->init_addr_type, &conn->hcon->init_addr,
450 conn->hcon->resp_addr_type, &conn->hcon->resp_addr, res);
451
452 hci_dev_unlock(hdev);
373 453
374 if (conn->hcon->out)
375 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
376 conn->hcon->src_type, &conn->hcon->src,
377 conn->hcon->dst_type, &conn->hcon->dst, res);
378 else
379 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
380 conn->hcon->dst_type, &conn->hcon->dst,
381 conn->hcon->src_type, &conn->hcon->src, res);
382 if (ret) { 454 if (ret) {
383 reason = SMP_UNSPECIFIED; 455 reason = SMP_UNSPECIFIED;
384 goto error; 456 goto error;
@@ -400,7 +472,8 @@ static void random_work(struct work_struct *work)
400 struct smp_chan *smp = container_of(work, struct smp_chan, random); 472 struct smp_chan *smp = container_of(work, struct smp_chan, random);
401 struct l2cap_conn *conn = smp->conn; 473 struct l2cap_conn *conn = smp->conn;
402 struct hci_conn *hcon = conn->hcon; 474 struct hci_conn *hcon = conn->hcon;
403 struct crypto_blkcipher *tfm = smp->tfm; 475 struct hci_dev *hdev = hcon->hdev;
476 struct crypto_blkcipher *tfm = hdev->tfm_aes;
404 u8 reason, confirm[16], res[16], key[16]; 477 u8 reason, confirm[16], res[16], key[16];
405 int ret; 478 int ret;
406 479
@@ -411,14 +484,15 @@ static void random_work(struct work_struct *work)
411 484
412 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 485 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
413 486
414 if (hcon->out) 487 /* Prevent mutual access to hdev->tfm_aes */
415 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 488 hci_dev_lock(hdev);
416 hcon->src_type, &hcon->src, 489
417 hcon->dst_type, &hcon->dst, res); 490 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
418 else 491 hcon->init_addr_type, &hcon->init_addr,
419 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 492 hcon->resp_addr_type, &hcon->resp_addr, res);
420 hcon->dst_type, &hcon->dst, 493
421 hcon->src_type, &hcon->src, res); 494 hci_dev_unlock(hdev);
495
422 if (ret) { 496 if (ret) {
423 reason = SMP_UNSPECIFIED; 497 reason = SMP_UNSPECIFIED;
424 goto error; 498 goto error;
@@ -433,11 +507,9 @@ static void random_work(struct work_struct *work)
433 } 507 }
434 508
435 if (hcon->out) { 509 if (hcon->out) {
436 u8 stk[16], rand[8]; 510 u8 stk[16];
437 __le16 ediv; 511 __le64 rand = 0;
438 512 __le16 ediv = 0;
439 memset(rand, 0, sizeof(rand));
440 ediv = 0;
441 513
442 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key); 514 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key);
443 swap128(key, stk); 515 swap128(key, stk);
@@ -453,11 +525,9 @@ static void random_work(struct work_struct *work)
453 hci_le_start_enc(hcon, ediv, rand, stk); 525 hci_le_start_enc(hcon, ediv, rand, stk);
454 hcon->enc_key_size = smp->enc_key_size; 526 hcon->enc_key_size = smp->enc_key_size;
455 } else { 527 } else {
456 u8 stk[16], r[16], rand[8]; 528 u8 stk[16], r[16];
457 __le16 ediv; 529 __le64 rand = 0;
458 530 __le16 ediv = 0;
459 memset(rand, 0, sizeof(rand));
460 ediv = 0;
461 531
462 swap128(smp->prnd, r); 532 swap128(smp->prnd, r);
463 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r); 533 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
@@ -469,7 +539,7 @@ static void random_work(struct work_struct *work)
469 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); 539 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
470 540
471 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 541 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
472 HCI_SMP_STK_SLAVE, 0, 0, stk, smp->enc_key_size, 542 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
473 ediv, rand); 543 ediv, rand);
474 } 544 }
475 545
@@ -479,6 +549,20 @@ error:
479 smp_failure(conn, reason); 549 smp_failure(conn, reason);
480} 550}
481 551
552static void smp_reencrypt(struct work_struct *work)
553{
554 struct smp_chan *smp = container_of(work, struct smp_chan,
555 reencrypt.work);
556 struct l2cap_conn *conn = smp->conn;
557 struct hci_conn *hcon = conn->hcon;
558 struct smp_ltk *ltk = smp->ltk;
559
560 BT_DBG("");
561
562 hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
563 hcon->enc_key_size = ltk->enc_size;
564}
565
482static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) 566static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
483{ 567{
484 struct smp_chan *smp; 568 struct smp_chan *smp;
@@ -489,6 +573,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
489 573
490 INIT_WORK(&smp->confirm, confirm_work); 574 INIT_WORK(&smp->confirm, confirm_work);
491 INIT_WORK(&smp->random, random_work); 575 INIT_WORK(&smp->random, random_work);
576 INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
492 577
493 smp->conn = conn; 578 smp->conn = conn;
494 conn->smp_chan = smp; 579 conn->smp_chan = smp;
@@ -502,11 +587,32 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
502void smp_chan_destroy(struct l2cap_conn *conn) 587void smp_chan_destroy(struct l2cap_conn *conn)
503{ 588{
504 struct smp_chan *smp = conn->smp_chan; 589 struct smp_chan *smp = conn->smp_chan;
590 bool complete;
505 591
506 BUG_ON(!smp); 592 BUG_ON(!smp);
507 593
508 if (smp->tfm) 594 cancel_delayed_work_sync(&smp->reencrypt);
509 crypto_free_blkcipher(smp->tfm); 595
596 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
597 mgmt_smp_complete(conn->hcon, complete);
598
599 /* If pairing failed clean up any keys we might have */
600 if (!complete) {
601 if (smp->ltk) {
602 list_del(&smp->ltk->list);
603 kfree(smp->ltk);
604 }
605
606 if (smp->slave_ltk) {
607 list_del(&smp->slave_ltk->list);
608 kfree(smp->slave_ltk);
609 }
610
611 if (smp->remote_irk) {
612 list_del(&smp->remote_irk->list);
613 kfree(smp->remote_irk);
614 }
615 }
510 616
511 kfree(smp); 617 kfree(smp);
512 conn->smp_chan = NULL; 618 conn->smp_chan = NULL;
@@ -565,6 +671,9 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
565 671
566 BT_DBG("conn %p", conn); 672 BT_DBG("conn %p", conn);
567 673
674 if (skb->len < sizeof(*req))
675 return SMP_UNSPECIFIED;
676
568 if (conn->hcon->link_mode & HCI_LM_MASTER) 677 if (conn->hcon->link_mode & HCI_LM_MASTER)
569 return SMP_CMD_NOTSUPP; 678 return SMP_CMD_NOTSUPP;
570 679
@@ -617,6 +726,9 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
617 726
618 BT_DBG("conn %p", conn); 727 BT_DBG("conn %p", conn);
619 728
729 if (skb->len < sizeof(*rsp))
730 return SMP_UNSPECIFIED;
731
620 if (!(conn->hcon->link_mode & HCI_LM_MASTER)) 732 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
621 return SMP_CMD_NOTSUPP; 733 return SMP_CMD_NOTSUPP;
622 734
@@ -661,6 +773,9 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
661 773
662 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 774 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
663 775
776 if (skb->len < sizeof(smp->pcnf))
777 return SMP_UNSPECIFIED;
778
664 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); 779 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
665 skb_pull(skb, sizeof(smp->pcnf)); 780 skb_pull(skb, sizeof(smp->pcnf));
666 781
@@ -686,6 +801,9 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
686 801
687 BT_DBG("conn %p", conn); 802 BT_DBG("conn %p", conn);
688 803
804 if (skb->len < sizeof(smp->rrnd))
805 return SMP_UNSPECIFIED;
806
689 swap128(skb->data, smp->rrnd); 807 swap128(skb->data, smp->rrnd);
690 skb_pull(skb, sizeof(smp->rrnd)); 808 skb_pull(skb, sizeof(smp->rrnd));
691 809
@@ -699,7 +817,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
699 struct smp_ltk *key; 817 struct smp_ltk *key;
700 struct hci_conn *hcon = conn->hcon; 818 struct hci_conn *hcon = conn->hcon;
701 819
702 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type); 820 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
821 hcon->out);
703 if (!key) 822 if (!key)
704 return 0; 823 return 0;
705 824
@@ -724,6 +843,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
724 843
725 BT_DBG("conn %p", conn); 844 BT_DBG("conn %p", conn);
726 845
846 if (skb->len < sizeof(*rp))
847 return SMP_UNSPECIFIED;
848
727 if (!(conn->hcon->link_mode & HCI_LM_MASTER)) 849 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
728 return SMP_CMD_NOTSUPP; 850 return SMP_CMD_NOTSUPP;
729 851
@@ -813,6 +935,15 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
813 struct smp_cmd_encrypt_info *rp = (void *) skb->data; 935 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
814 struct smp_chan *smp = conn->smp_chan; 936 struct smp_chan *smp = conn->smp_chan;
815 937
938 BT_DBG("conn %p", conn);
939
940 if (skb->len < sizeof(*rp))
941 return SMP_UNSPECIFIED;
942
943 /* Ignore this PDU if it wasn't requested */
944 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
945 return 0;
946
816 skb_pull(skb, sizeof(*rp)); 947 skb_pull(skb, sizeof(*rp));
817 948
818 memcpy(smp->tk, rp->ltk, sizeof(smp->tk)); 949 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
@@ -826,21 +957,114 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
826 struct smp_chan *smp = conn->smp_chan; 957 struct smp_chan *smp = conn->smp_chan;
827 struct hci_dev *hdev = conn->hcon->hdev; 958 struct hci_dev *hdev = conn->hcon->hdev;
828 struct hci_conn *hcon = conn->hcon; 959 struct hci_conn *hcon = conn->hcon;
960 struct smp_ltk *ltk;
829 u8 authenticated; 961 u8 authenticated;
830 962
963 BT_DBG("conn %p", conn);
964
965 if (skb->len < sizeof(*rp))
966 return SMP_UNSPECIFIED;
967
968 /* Ignore this PDU if it wasn't requested */
969 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
970 return 0;
971
972 /* Mark the information as received */
973 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
974
831 skb_pull(skb, sizeof(*rp)); 975 skb_pull(skb, sizeof(*rp));
832 976
833 hci_dev_lock(hdev); 977 hci_dev_lock(hdev);
834 authenticated = (hcon->sec_level == BT_SECURITY_HIGH); 978 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
835 hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK, 1, 979 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
836 authenticated, smp->tk, smp->enc_key_size, 980 authenticated, smp->tk, smp->enc_key_size,
837 rp->ediv, rp->rand); 981 rp->ediv, rp->rand);
838 smp_distribute_keys(conn, 1); 982 smp->ltk = ltk;
983 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
984 smp_distribute_keys(conn);
839 hci_dev_unlock(hdev); 985 hci_dev_unlock(hdev);
840 986
841 return 0; 987 return 0;
842} 988}
843 989
990static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
991{
992 struct smp_cmd_ident_info *info = (void *) skb->data;
993 struct smp_chan *smp = conn->smp_chan;
994
995 BT_DBG("");
996
997 if (skb->len < sizeof(*info))
998 return SMP_UNSPECIFIED;
999
1000 /* Ignore this PDU if it wasn't requested */
1001 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1002 return 0;
1003
1004 skb_pull(skb, sizeof(*info));
1005
1006 memcpy(smp->irk, info->irk, 16);
1007
1008 return 0;
1009}
1010
1011static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1012 struct sk_buff *skb)
1013{
1014 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1015 struct smp_chan *smp = conn->smp_chan;
1016 struct hci_conn *hcon = conn->hcon;
1017 bdaddr_t rpa;
1018
1019 BT_DBG("");
1020
1021 if (skb->len < sizeof(*info))
1022 return SMP_UNSPECIFIED;
1023
1024 /* Ignore this PDU if it wasn't requested */
1025 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1026 return 0;
1027
1028 /* Mark the information as received */
1029 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1030
1031 skb_pull(skb, sizeof(*info));
1032
1033 /* Strictly speaking the Core Specification (4.1) allows sending
1034 * an empty address which would force us to rely on just the IRK
1035 * as "identity information". However, since such
1036 * implementations are not known of and in order to not over
1037 * complicate our implementation, simply pretend that we never
1038 * received an IRK for such a device.
1039 */
1040 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1041 BT_ERR("Ignoring IRK with no identity address");
1042 smp_distribute_keys(conn);
1043 return 0;
1044 }
1045
1046 bacpy(&smp->id_addr, &info->bdaddr);
1047 smp->id_addr_type = info->addr_type;
1048
1049 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1050 bacpy(&rpa, &hcon->dst);
1051 else
1052 bacpy(&rpa, BDADDR_ANY);
1053
1054 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1055 smp->id_addr_type, smp->irk, &rpa);
1056
1057 /* Track the connection based on the Identity Address from now on */
1058 bacpy(&hcon->dst, &smp->id_addr);
1059 hcon->dst_type = smp->id_addr_type;
1060
1061 l2cap_conn_update_id_addr(hcon);
1062
1063 smp_distribute_keys(conn);
1064
1065 return 0;
1066}
1067
844int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) 1068int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
845{ 1069{
846 struct hci_conn *hcon = conn->hcon; 1070 struct hci_conn *hcon = conn->hcon;
@@ -915,7 +1139,13 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
915 break; 1139 break;
916 1140
917 case SMP_CMD_IDENT_INFO: 1141 case SMP_CMD_IDENT_INFO:
1142 reason = smp_cmd_ident_info(conn, skb);
1143 break;
1144
918 case SMP_CMD_IDENT_ADDR_INFO: 1145 case SMP_CMD_IDENT_ADDR_INFO:
1146 reason = smp_cmd_ident_addr_info(conn, skb);
1147 break;
1148
919 case SMP_CMD_SIGN_INFO: 1149 case SMP_CMD_SIGN_INFO:
920 /* Just ignored */ 1150 /* Just ignored */
921 reason = 0; 1151 reason = 0;
@@ -937,26 +1167,51 @@ done:
937 return err; 1167 return err;
938} 1168}
939 1169
940int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) 1170static void smp_notify_keys(struct l2cap_conn *conn)
1171{
1172 struct smp_chan *smp = conn->smp_chan;
1173 struct hci_conn *hcon = conn->hcon;
1174 struct hci_dev *hdev = hcon->hdev;
1175
1176 if (smp->remote_irk)
1177 mgmt_new_irk(hdev, smp->remote_irk);
1178
1179 if (smp->ltk) {
1180 smp->ltk->bdaddr_type = hcon->dst_type;
1181 bacpy(&smp->ltk->bdaddr, &hcon->dst);
1182 mgmt_new_ltk(hdev, smp->ltk);
1183 }
1184
1185 if (smp->slave_ltk) {
1186 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1187 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
1188 mgmt_new_ltk(hdev, smp->slave_ltk);
1189 }
1190}
1191
1192int smp_distribute_keys(struct l2cap_conn *conn)
941{ 1193{
942 struct smp_cmd_pairing *req, *rsp; 1194 struct smp_cmd_pairing *req, *rsp;
943 struct smp_chan *smp = conn->smp_chan; 1195 struct smp_chan *smp = conn->smp_chan;
1196 struct hci_conn *hcon = conn->hcon;
1197 struct hci_dev *hdev = hcon->hdev;
1198 bool ltk_encrypt;
944 __u8 *keydist; 1199 __u8 *keydist;
945 1200
946 BT_DBG("conn %p force %d", conn, force); 1201 BT_DBG("conn %p", conn);
947 1202
948 if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) 1203 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
949 return 0; 1204 return 0;
950 1205
951 rsp = (void *) &smp->prsp[1]; 1206 rsp = (void *) &smp->prsp[1];
952 1207
953 /* The responder sends its keys first */ 1208 /* The responder sends its keys first */
954 if (!force && conn->hcon->out && (rsp->resp_key_dist & 0x07)) 1209 if (hcon->out && (smp->remote_key_dist & 0x07))
955 return 0; 1210 return 0;
956 1211
957 req = (void *) &smp->preq[1]; 1212 req = (void *) &smp->preq[1];
958 1213
959 if (conn->hcon->out) { 1214 if (hcon->out) {
960 keydist = &rsp->init_key_dist; 1215 keydist = &rsp->init_key_dist;
961 *keydist &= req->init_key_dist; 1216 *keydist &= req->init_key_dist;
962 } else { 1217 } else {
@@ -964,28 +1219,30 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
964 *keydist &= req->resp_key_dist; 1219 *keydist &= req->resp_key_dist;
965 } 1220 }
966 1221
967
968 BT_DBG("keydist 0x%x", *keydist); 1222 BT_DBG("keydist 0x%x", *keydist);
969 1223
970 if (*keydist & SMP_DIST_ENC_KEY) { 1224 if (*keydist & SMP_DIST_ENC_KEY) {
971 struct smp_cmd_encrypt_info enc; 1225 struct smp_cmd_encrypt_info enc;
972 struct smp_cmd_master_ident ident; 1226 struct smp_cmd_master_ident ident;
973 struct hci_conn *hcon = conn->hcon; 1227 struct smp_ltk *ltk;
974 u8 authenticated; 1228 u8 authenticated;
975 __le16 ediv; 1229 __le16 ediv;
1230 __le64 rand;
976 1231
977 get_random_bytes(enc.ltk, sizeof(enc.ltk)); 1232 get_random_bytes(enc.ltk, sizeof(enc.ltk));
978 get_random_bytes(&ediv, sizeof(ediv)); 1233 get_random_bytes(&ediv, sizeof(ediv));
979 get_random_bytes(ident.rand, sizeof(ident.rand)); 1234 get_random_bytes(&rand, sizeof(rand));
980 1235
981 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); 1236 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
982 1237
983 authenticated = hcon->sec_level == BT_SECURITY_HIGH; 1238 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
984 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 1239 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
985 HCI_SMP_LTK_SLAVE, 1, authenticated, 1240 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
986 enc.ltk, smp->enc_key_size, ediv, ident.rand); 1241 smp->enc_key_size, ediv, rand);
1242 smp->slave_ltk = ltk;
987 1243
988 ident.ediv = ediv; 1244 ident.ediv = ediv;
1245 ident.rand = rand;
989 1246
990 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); 1247 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
991 1248
@@ -996,14 +1253,18 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
996 struct smp_cmd_ident_addr_info addrinfo; 1253 struct smp_cmd_ident_addr_info addrinfo;
997 struct smp_cmd_ident_info idinfo; 1254 struct smp_cmd_ident_info idinfo;
998 1255
999 /* Send a dummy key */ 1256 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
1000 get_random_bytes(idinfo.irk, sizeof(idinfo.irk));
1001 1257
1002 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); 1258 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1003 1259
1004 /* Just public address */ 1260 /* The hci_conn contains the local identity address
1005 memset(&addrinfo, 0, sizeof(addrinfo)); 1261 * after the connection has been established.
1006 bacpy(&addrinfo.bdaddr, &conn->hcon->src); 1262 *
1263 * This is true even when the connection has been
1264 * established using a resolvable random address.
1265 */
1266 bacpy(&addrinfo.bdaddr, &hcon->src);
1267 addrinfo.addr_type = hcon->src_type;
1007 1268
1008 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), 1269 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
1009 &addrinfo); 1270 &addrinfo);
@@ -1022,9 +1283,34 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
1022 *keydist &= ~SMP_DIST_SIGN; 1283 *keydist &= ~SMP_DIST_SIGN;
1023 } 1284 }
1024 1285
1025 if (conn->hcon->out || force) { 1286 /* If there are still keys to be received wait for them */
1026 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags); 1287 if ((smp->remote_key_dist & 0x07))
1288 return 0;
1289
1290 /* Check if we should try to re-encrypt the link with the LTK.
1291 * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
1292 * already tried this (in which case we shouldn't try again).
1293 *
1294 * The request will trigger an encryption key refresh event
1295 * which will cause a call to auth_cfm and eventually lead to
1296 * l2cap_core.c calling this smp_distribute_keys function again
1297 * and thereby completing the process.
1298 */
1299 if (smp->ltk)
1300 ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
1301 &smp->smp_flags);
1302 else
1303 ltk_encrypt = false;
1304
1305 /* Re-encrypt the link with LTK if possible */
1306 if (ltk_encrypt && hcon->out) {
1307 queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
1308 SMP_REENCRYPT_TIMEOUT);
1309 } else {
1310 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1027 cancel_delayed_work_sync(&conn->security_timer); 1311 cancel_delayed_work_sync(&conn->security_timer);
1312 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1313 smp_notify_keys(conn);
1028 smp_chan_destroy(conn); 1314 smp_chan_destroy(conn);
1029 } 1315 }
1030 1316
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index a700bcb490d7..f55d83617218 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -78,7 +78,7 @@ struct smp_cmd_encrypt_info {
78#define SMP_CMD_MASTER_IDENT 0x07 78#define SMP_CMD_MASTER_IDENT 0x07
79struct smp_cmd_master_ident { 79struct smp_cmd_master_ident {
80 __le16 ediv; 80 __le16 ediv;
81 __u8 rand[8]; 81 __le64 rand;
82} __packed; 82} __packed;
83 83
84#define SMP_CMD_IDENT_INFO 0x08 84#define SMP_CMD_IDENT_INFO 0x08
@@ -118,6 +118,10 @@ struct smp_cmd_security_req {
118#define SMP_FLAG_TK_VALID 1 118#define SMP_FLAG_TK_VALID 1
119#define SMP_FLAG_CFM_PENDING 2 119#define SMP_FLAG_CFM_PENDING 2
120#define SMP_FLAG_MITM_AUTH 3 120#define SMP_FLAG_MITM_AUTH 3
121#define SMP_FLAG_LTK_ENCRYPT 4
122#define SMP_FLAG_COMPLETE 5
123
124#define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(250)
121 125
122struct smp_chan { 126struct smp_chan {
123 struct l2cap_conn *conn; 127 struct l2cap_conn *conn;
@@ -128,20 +132,30 @@ struct smp_chan {
128 u8 pcnf[16]; /* SMP Pairing Confirm */ 132 u8 pcnf[16]; /* SMP Pairing Confirm */
129 u8 tk[16]; /* SMP Temporary Key */ 133 u8 tk[16]; /* SMP Temporary Key */
130 u8 enc_key_size; 134 u8 enc_key_size;
135 u8 remote_key_dist;
136 bdaddr_t id_addr;
137 u8 id_addr_type;
138 u8 irk[16];
139 struct smp_ltk *ltk;
140 struct smp_ltk *slave_ltk;
141 struct smp_irk *remote_irk;
131 unsigned long smp_flags; 142 unsigned long smp_flags;
132 struct crypto_blkcipher *tfm;
133 struct work_struct confirm; 143 struct work_struct confirm;
134 struct work_struct random; 144 struct work_struct random;
135 145 struct delayed_work reencrypt;
136}; 146};
137 147
138/* SMP Commands */ 148/* SMP Commands */
139bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); 149bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level);
140int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); 150int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
141int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); 151int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
142int smp_distribute_keys(struct l2cap_conn *conn, __u8 force); 152int smp_distribute_keys(struct l2cap_conn *conn);
143int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); 153int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
144 154
145void smp_chan_destroy(struct l2cap_conn *conn); 155void smp_chan_destroy(struct l2cap_conn *conn);
146 156
157bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
158 bdaddr_t *bdaddr);
159int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa);
160
147#endif /* __SMP_H */ 161#endif /* __SMP_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 363d19b5d5c8..1acb29109b45 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1347,9 +1347,6 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1347 params->vht_capa, sta); 1347 params->vht_capa, sta);
1348 1348
1349 if (params->opmode_notif_used) { 1349 if (params->opmode_notif_used) {
1350 enum ieee80211_band band =
1351 ieee80211_get_sdata_band(sdata);
1352
1353 /* returned value is only needed for rc update, but the 1350 /* returned value is only needed for rc update, but the
1354 * rc isn't initialized here yet, so ignore it 1351 * rc isn't initialized here yet, so ignore it
1355 */ 1352 */
@@ -3647,8 +3644,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
3647 3644
3648static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, 3645static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
3649 u8 *peer, u8 action_code, u8 dialog_token, 3646 u8 *peer, u8 action_code, u8 dialog_token,
3650 u16 status_code, const u8 *extra_ies, 3647 u16 status_code, u32 peer_capability,
3651 size_t extra_ies_len) 3648 const u8 *extra_ies, size_t extra_ies_len)
3652{ 3649{
3653 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3650 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3654 struct ieee80211_local *local = sdata->local; 3651 struct ieee80211_local *local = sdata->local;
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index ebf80f3abd83..40a648938985 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -358,6 +358,18 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
358} 358}
359IEEE80211_IF_FILE_W(tkip_mic_test); 359IEEE80211_IF_FILE_W(tkip_mic_test);
360 360
361static ssize_t ieee80211_if_parse_beacon_loss(
362 struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
363{
364 if (!ieee80211_sdata_running(sdata) || !sdata->vif.bss_conf.assoc)
365 return -ENOTCONN;
366
367 ieee80211_beacon_loss(&sdata->vif);
368
369 return buflen;
370}
371IEEE80211_IF_FILE_W(beacon_loss);
372
361static ssize_t ieee80211_if_fmt_uapsd_queues( 373static ssize_t ieee80211_if_fmt_uapsd_queues(
362 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) 374 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
363{ 375{
@@ -569,6 +581,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
569 DEBUGFS_ADD(beacon_timeout); 581 DEBUGFS_ADD(beacon_timeout);
570 DEBUGFS_ADD_MODE(smps, 0600); 582 DEBUGFS_ADD_MODE(smps, 0600);
571 DEBUGFS_ADD_MODE(tkip_mic_test, 0200); 583 DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
584 DEBUGFS_ADD_MODE(beacon_loss, 0200);
572 DEBUGFS_ADD_MODE(uapsd_queues, 0600); 585 DEBUGFS_ADD_MODE(uapsd_queues, 0600);
573 DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); 586 DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
574} 587}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index ef8b385eff04..fc689f5d971e 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -354,16 +354,20 @@ drv_sched_scan_start(struct ieee80211_local *local,
354 return ret; 354 return ret;
355} 355}
356 356
357static inline void drv_sched_scan_stop(struct ieee80211_local *local, 357static inline int drv_sched_scan_stop(struct ieee80211_local *local,
358 struct ieee80211_sub_if_data *sdata) 358 struct ieee80211_sub_if_data *sdata)
359{ 359{
360 int ret;
361
360 might_sleep(); 362 might_sleep();
361 363
362 check_sdata_in_driver(sdata); 364 check_sdata_in_driver(sdata);
363 365
364 trace_drv_sched_scan_stop(local, sdata); 366 trace_drv_sched_scan_stop(local, sdata);
365 local->ops->sched_scan_stop(&local->hw, &sdata->vif); 367 ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif);
366 trace_drv_return_void(local); 368 trace_drv_return_int(local, ret);
369
370 return ret;
367} 371}
368 372
369static inline void drv_sw_scan_start(struct ieee80211_local *local) 373static inline void drv_sw_scan_start(struct ieee80211_local *local)
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index afbe2b203c3e..c150b68436d7 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -482,8 +482,6 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
482 return; 482 return;
483 483
484 if (vif->type == NL80211_IFTYPE_STATION) { 484 if (vif->type == NL80211_IFTYPE_STATION) {
485 if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
486 smps_mode = IEEE80211_SMPS_AUTOMATIC;
487 if (sdata->u.mgd.driver_smps_mode == smps_mode) 485 if (sdata->u.mgd.driver_smps_mode == smps_mode)
488 return; 486 return;
489 sdata->u.mgd.driver_smps_mode = smps_mode; 487 sdata->u.mgd.driver_smps_mode = smps_mode;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 4453e2725e40..e458ca0dffec 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -283,6 +283,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
283 283
284 err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, 284 err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
285 &chandef); 285 &chandef);
286 if (err < 0) {
287 sdata_info(sdata,
288 "Failed to join IBSS, invalid chandef\n");
289 return;
290 }
286 if (err > 0) { 291 if (err > 0) {
287 if (!ifibss->userspace_handles_dfs) { 292 if (!ifibss->userspace_handles_dfs) {
288 sdata_info(sdata, 293 sdata_info(sdata,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 906e211b1dd1..0d1a0f801b94 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1242,6 +1242,8 @@ struct ieee80211_local {
1242 1242
1243 struct ieee80211_sub_if_data __rcu *p2p_sdata; 1243 struct ieee80211_sub_if_data __rcu *p2p_sdata;
1244 1244
1245 struct napi_struct *napi;
1246
1245 /* virtual monitor interface */ 1247 /* virtual monitor interface */
1246 struct ieee80211_sub_if_data __rcu *monitor_sdata; 1248 struct ieee80211_sub_if_data __rcu *monitor_sdata;
1247 struct cfg80211_chan_def monitor_chandef; 1249 struct cfg80211_chan_def monitor_chandef;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 088111af6c7c..b8d331e7d883 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -101,9 +101,8 @@ static u32 __ieee80211_idle_on(struct ieee80211_local *local)
101static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, 101static u32 __ieee80211_recalc_idle(struct ieee80211_local *local,
102 bool force_active) 102 bool force_active)
103{ 103{
104 bool working = false, scanning, active; 104 bool working, scanning, active;
105 unsigned int led_trig_start = 0, led_trig_stop = 0; 105 unsigned int led_trig_start = 0, led_trig_stop = 0;
106 struct ieee80211_roc_work *roc;
107 106
108 lockdep_assert_held(&local->mtx); 107 lockdep_assert_held(&local->mtx);
109 108
@@ -111,12 +110,8 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local,
111 !list_empty(&local->chanctx_list) || 110 !list_empty(&local->chanctx_list) ||
112 local->monitors; 111 local->monitors;
113 112
114 if (!local->ops->remain_on_channel) { 113 working = !local->ops->remain_on_channel &&
115 list_for_each_entry(roc, &local->roc_list, list) { 114 !list_empty(&local->roc_list);
116 working = true;
117 break;
118 }
119 }
120 115
121 scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || 116 scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
122 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); 117 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 1f7d8422d62d..b055f6a55c68 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1076,6 +1076,18 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1076} 1076}
1077EXPORT_SYMBOL(ieee80211_register_hw); 1077EXPORT_SYMBOL(ieee80211_register_hw);
1078 1078
1079void ieee80211_napi_add(struct ieee80211_hw *hw, struct napi_struct *napi,
1080 struct net_device *napi_dev,
1081 int (*poll)(struct napi_struct *, int),
1082 int weight)
1083{
1084 struct ieee80211_local *local = hw_to_local(hw);
1085
1086 netif_napi_add(napi_dev, napi, poll, weight);
1087 local->napi = napi;
1088}
1089EXPORT_SYMBOL_GPL(ieee80211_napi_add);
1090
1079void ieee80211_unregister_hw(struct ieee80211_hw *hw) 1091void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1080{ 1092{
1081 struct ieee80211_local *local = hw_to_local(hw); 1093 struct ieee80211_local *local = hw_to_local(hw);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4bc227550f25..94f0af29b742 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -131,13 +131,13 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
131 if (unlikely(!sdata->u.mgd.associated)) 131 if (unlikely(!sdata->u.mgd.associated))
132 return; 132 return;
133 133
134 ifmgd->probe_send_count = 0;
135
134 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) 136 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
135 return; 137 return;
136 138
137 mod_timer(&sdata->u.mgd.conn_mon_timer, 139 mod_timer(&sdata->u.mgd.conn_mon_timer,
138 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); 140 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
139
140 ifmgd->probe_send_count = 0;
141} 141}
142 142
143static int ecw2cw(int ecw) 143static int ecw2cw(int ecw)
@@ -2272,6 +2272,62 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2272 /* ignore frame -- wait for timeout */ 2272 /* ignore frame -- wait for timeout */
2273} 2273}
2274 2274
2275#define case_WLAN(type) \
2276 case WLAN_REASON_##type: return #type
2277
2278static const char *ieee80211_get_reason_code_string(u16 reason_code)
2279{
2280 switch (reason_code) {
2281 case_WLAN(UNSPECIFIED);
2282 case_WLAN(PREV_AUTH_NOT_VALID);
2283 case_WLAN(DEAUTH_LEAVING);
2284 case_WLAN(DISASSOC_DUE_TO_INACTIVITY);
2285 case_WLAN(DISASSOC_AP_BUSY);
2286 case_WLAN(CLASS2_FRAME_FROM_NONAUTH_STA);
2287 case_WLAN(CLASS3_FRAME_FROM_NONASSOC_STA);
2288 case_WLAN(DISASSOC_STA_HAS_LEFT);
2289 case_WLAN(STA_REQ_ASSOC_WITHOUT_AUTH);
2290 case_WLAN(DISASSOC_BAD_POWER);
2291 case_WLAN(DISASSOC_BAD_SUPP_CHAN);
2292 case_WLAN(INVALID_IE);
2293 case_WLAN(MIC_FAILURE);
2294 case_WLAN(4WAY_HANDSHAKE_TIMEOUT);
2295 case_WLAN(GROUP_KEY_HANDSHAKE_TIMEOUT);
2296 case_WLAN(IE_DIFFERENT);
2297 case_WLAN(INVALID_GROUP_CIPHER);
2298 case_WLAN(INVALID_PAIRWISE_CIPHER);
2299 case_WLAN(INVALID_AKMP);
2300 case_WLAN(UNSUPP_RSN_VERSION);
2301 case_WLAN(INVALID_RSN_IE_CAP);
2302 case_WLAN(IEEE8021X_FAILED);
2303 case_WLAN(CIPHER_SUITE_REJECTED);
2304 case_WLAN(DISASSOC_UNSPECIFIED_QOS);
2305 case_WLAN(DISASSOC_QAP_NO_BANDWIDTH);
2306 case_WLAN(DISASSOC_LOW_ACK);
2307 case_WLAN(DISASSOC_QAP_EXCEED_TXOP);
2308 case_WLAN(QSTA_LEAVE_QBSS);
2309 case_WLAN(QSTA_NOT_USE);
2310 case_WLAN(QSTA_REQUIRE_SETUP);
2311 case_WLAN(QSTA_TIMEOUT);
2312 case_WLAN(QSTA_CIPHER_NOT_SUPP);
2313 case_WLAN(MESH_PEER_CANCELED);
2314 case_WLAN(MESH_MAX_PEERS);
2315 case_WLAN(MESH_CONFIG);
2316 case_WLAN(MESH_CLOSE);
2317 case_WLAN(MESH_MAX_RETRIES);
2318 case_WLAN(MESH_CONFIRM_TIMEOUT);
2319 case_WLAN(MESH_INVALID_GTK);
2320 case_WLAN(MESH_INCONSISTENT_PARAM);
2321 case_WLAN(MESH_INVALID_SECURITY);
2322 case_WLAN(MESH_PATH_ERROR);
2323 case_WLAN(MESH_PATH_NOFORWARD);
2324 case_WLAN(MESH_PATH_DEST_UNREACHABLE);
2325 case_WLAN(MAC_EXISTS_IN_MBSS);
2326 case_WLAN(MESH_CHAN_REGULATORY);
2327 case_WLAN(MESH_CHAN);
2328 default: return "<unknown>";
2329 }
2330}
2275 2331
2276static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 2332static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2277 struct ieee80211_mgmt *mgmt, size_t len) 2333 struct ieee80211_mgmt *mgmt, size_t len)
@@ -2293,8 +2349,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2293 2349
2294 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 2350 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
2295 2351
2296 sdata_info(sdata, "deauthenticated from %pM (Reason: %u)\n", 2352 sdata_info(sdata, "deauthenticated from %pM (Reason: %u=%s)\n",
2297 bssid, reason_code); 2353 bssid, reason_code, ieee80211_get_reason_code_string(reason_code));
2298 2354
2299 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2355 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2300 2356
@@ -4364,8 +4420,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4364 bool report_frame = false; 4420 bool report_frame = false;
4365 4421
4366 sdata_info(sdata, 4422 sdata_info(sdata,
4367 "deauthenticating from %pM by local choice (reason=%d)\n", 4423 "deauthenticating from %pM by local choice (Reason: %u=%s)\n",
4368 req->bssid, req->reason_code); 4424 req->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code));
4369 4425
4370 if (ifmgd->auth_data) { 4426 if (ifmgd->auth_data) {
4371 drv_mgd_prepare_tx(sdata->local, sdata); 4427 drv_mgd_prepare_tx(sdata->local, sdata);
@@ -4411,8 +4467,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4411 return -ENOLINK; 4467 return -ENOLINK;
4412 4468
4413 sdata_info(sdata, 4469 sdata_info(sdata,
4414 "disassociating from %pM by local choice (reason=%d)\n", 4470 "disassociating from %pM by local choice (Reason: %u=%s)\n",
4415 req->bss->bssid, req->reason_code); 4471 req->bss->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code));
4416 4472
4417 memcpy(bssid, req->bss->bssid, ETH_ALEN); 4473 memcpy(bssid, req->bss->bssid, ETH_ALEN);
4418 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, 4474 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 282440216a87..5b617660b0ba 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1961,7 +1961,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1961 /* deliver to local stack */ 1961 /* deliver to local stack */
1962 skb->protocol = eth_type_trans(skb, dev); 1962 skb->protocol = eth_type_trans(skb, dev);
1963 memset(skb->cb, 0, sizeof(skb->cb)); 1963 memset(skb->cb, 0, sizeof(skb->cb));
1964 netif_receive_skb(skb); 1964 if (rx->local->napi)
1965 napi_gro_receive(rx->local->napi, skb);
1966 else
1967 netif_receive_skb(skb);
1965 } 1968 }
1966 1969
1967 if (xmit_skb) { 1970 if (xmit_skb) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 88c81616f8f7..836f500dfbf3 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -472,9 +472,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
472 if (local->ops->hw_scan) { 472 if (local->ops->hw_scan) {
473 u8 *ies; 473 u8 *ies;
474 474
475 local->hw_scan_ies_bufsize = 2 + IEEE80211_MAX_SSID_LEN + 475 local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len;
476 local->scan_ies_len +
477 req->ie_len;
478 local->hw_scan_req = kmalloc( 476 local->hw_scan_req = kmalloc(
479 sizeof(*local->hw_scan_req) + 477 sizeof(*local->hw_scan_req) +
480 req->n_channels * sizeof(req->channels[0]) + 478 req->n_channels * sizeof(req->channels[0]) +
@@ -979,8 +977,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
979 struct cfg80211_chan_def chandef; 977 struct cfg80211_chan_def chandef;
980 int ret, i, iebufsz; 978 int ret, i, iebufsz;
981 979
982 iebufsz = 2 + IEEE80211_MAX_SSID_LEN + 980 iebufsz = local->scan_ies_len + req->ie_len;
983 local->scan_ies_len + req->ie_len;
984 981
985 lockdep_assert_held(&local->mtx); 982 lockdep_assert_held(&local->mtx);
986 983
@@ -1059,7 +1056,7 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
1059 local->sched_scan_req = NULL; 1056 local->sched_scan_req = NULL;
1060 1057
1061 if (rcu_access_pointer(local->sched_scan_sdata)) 1058 if (rcu_access_pointer(local->sched_scan_sdata))
1062 drv_sched_scan_stop(local, sdata); 1059 ret = drv_sched_scan_stop(local, sdata);
1063 1060
1064out: 1061out:
1065 mutex_unlock(&local->mtx); 1062 mutex_unlock(&local->mtx);
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 2d4268c5529d..cd10c1985074 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -705,12 +705,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
705 case NL80211_IFTYPE_MONITOR: 705 case NL80211_IFTYPE_MONITOR:
706 case NL80211_IFTYPE_AP_VLAN: 706 case NL80211_IFTYPE_AP_VLAN:
707 case NL80211_IFTYPE_WDS: 707 case NL80211_IFTYPE_WDS:
708 /* these interface types don't really have a channel */
709 return;
710 case NL80211_IFTYPE_P2P_DEVICE: 708 case NL80211_IFTYPE_P2P_DEVICE:
711 if (wdev->wiphy->features & 709 /* these interface types don't really have a channel */
712 NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL)
713 *chanmode = CHAN_MODE_EXCLUSIVE;
714 return; 710 return;
715 case NL80211_IFTYPE_UNSPECIFIED: 711 case NL80211_IFTYPE_UNSPECIFIED:
716 case NUM_NL80211_IFTYPES: 712 case NUM_NL80211_IFTYPES:
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
index 9a8217d2a908..fdfd3f063a9b 100644
--- a/net/wireless/genregdb.awk
+++ b/net/wireless/genregdb.awk
@@ -105,6 +105,8 @@ function parse_reg_rule()
105 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 105 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
106 } else if (flagarray[arg] == "NO-IR") { 106 } else if (flagarray[arg] == "NO-IR") {
107 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 107 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
108 } else if (flagarray[arg] == "AUTO-BW") {
109 flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | "
108 } 110 }
109 111
110 } 112 }
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 1470b90e438f..349db9ddc0d1 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -128,12 +128,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
128#endif 128#endif
129 check_chan = params->chandef.chan; 129 check_chan = params->chandef.chan;
130 if (params->userspace_handles_dfs) { 130 if (params->userspace_handles_dfs) {
131 /* use channel NULL to check for radar even if the current 131 /* Check for radar even if the current channel is not
132 * channel is not a radar channel - it might decide to change 132 * a radar channel - it might decide to change to DFS
133 * to DFS channel later. 133 * channel later.
134 */ 134 */
135 radar_detect_width = BIT(params->chandef.width); 135 radar_detect_width = BIT(params->chandef.width);
136 check_chan = NULL;
137 } 136 }
138 137
139 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 138 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index d42a3fcb2f67..5af5cc6b2c4c 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -236,6 +236,12 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
236 if (!netif_running(wdev->netdev)) 236 if (!netif_running(wdev->netdev))
237 return -ENETDOWN; 237 return -ENETDOWN;
238 238
239 /* cfg80211_can_use_chan() calls
240 * cfg80211_can_use_iftype_chan() with no radar
241 * detection, so if we're trying to use a radar
242 * channel here, something is wrong.
243 */
244 WARN_ON_ONCE(chandef->chan->flags & IEEE80211_CHAN_RADAR);
239 err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, 245 err = cfg80211_can_use_chan(rdev, wdev, chandef->chan,
240 CHAN_MODE_SHARED); 246 CHAN_MODE_SHARED);
241 if (err) 247 if (err)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8e6b6a2d35cb..2c38b28a85b9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -384,6 +384,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
384 .len = IEEE80211_QOS_MAP_LEN_MAX }, 384 .len = IEEE80211_QOS_MAP_LEN_MAX },
385 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, 385 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
386 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, 386 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
387 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
387}; 388};
388 389
389/* policy for the key attributes */ 390/* policy for the key attributes */
@@ -4627,6 +4628,8 @@ static int parse_reg_rule(struct nlattr *tb[],
4627 return -EINVAL; 4628 return -EINVAL;
4628 if (!tb[NL80211_ATTR_FREQ_RANGE_END]) 4629 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
4629 return -EINVAL; 4630 return -EINVAL;
4631 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
4632 return -EINVAL;
4630 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) 4633 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
4631 return -EINVAL; 4634 return -EINVAL;
4632 4635
@@ -4636,9 +4639,8 @@ static int parse_reg_rule(struct nlattr *tb[],
4636 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); 4639 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
4637 freq_range->end_freq_khz = 4640 freq_range->end_freq_khz =
4638 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); 4641 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
4639 if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) 4642 freq_range->max_bandwidth_khz =
4640 freq_range->max_bandwidth_khz = 4643 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
4641 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
4642 4644
4643 power_rule->max_eirp = 4645 power_rule->max_eirp =
4644 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); 4646 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
@@ -5710,8 +5712,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5710 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF; 5712 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
5711 } 5713 }
5712 5714
5713 if (info->attrs[NL80211_ATTR_IE]) { 5715 if (ie_len) {
5714 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 5716 request->ie_len = ie_len;
5715 memcpy((void *)request->ie, 5717 memcpy((void *)request->ie,
5716 nla_data(info->attrs[NL80211_ATTR_IE]), 5718 nla_data(info->attrs[NL80211_ATTR_IE]),
5717 request->ie_len); 5719 request->ie_len);
@@ -5911,17 +5913,22 @@ skip_beacons:
5911 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef)) 5913 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
5912 return -EINVAL; 5914 return -EINVAL;
5913 5915
5914 if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP || 5916 switch (dev->ieee80211_ptr->iftype) {
5915 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO || 5917 case NL80211_IFTYPE_AP:
5916 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_ADHOC) { 5918 case NL80211_IFTYPE_P2P_GO:
5919 case NL80211_IFTYPE_ADHOC:
5920 case NL80211_IFTYPE_MESH_POINT:
5917 err = cfg80211_chandef_dfs_required(wdev->wiphy, 5921 err = cfg80211_chandef_dfs_required(wdev->wiphy,
5918 &params.chandef); 5922 &params.chandef);
5919 if (err < 0) { 5923 if (err < 0)
5920 return err; 5924 return err;
5921 } else if (err) { 5925 if (err) {
5922 radar_detect_width = BIT(params.chandef.width); 5926 radar_detect_width = BIT(params.chandef.width);
5923 params.radar_required = true; 5927 params.radar_required = true;
5924 } 5928 }
5929 break;
5930 default:
5931 break;
5925 } 5932 }
5926 5933
5927 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 5934 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
@@ -7269,6 +7276,7 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
7269 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 7276 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7270 struct net_device *dev = info->user_ptr[1]; 7277 struct net_device *dev = info->user_ptr[1];
7271 u8 action_code, dialog_token; 7278 u8 action_code, dialog_token;
7279 u32 peer_capability = 0;
7272 u16 status_code; 7280 u16 status_code;
7273 u8 *peer; 7281 u8 *peer;
7274 7282
@@ -7287,9 +7295,12 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
7287 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); 7295 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
7288 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); 7296 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
7289 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); 7297 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
7298 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
7299 peer_capability =
7300 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
7290 7301
7291 return rdev_tdls_mgmt(rdev, dev, peer, action_code, 7302 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
7292 dialog_token, status_code, 7303 dialog_token, status_code, peer_capability,
7293 nla_data(info->attrs[NL80211_ATTR_IE]), 7304 nla_data(info->attrs[NL80211_ATTR_IE]),
7294 nla_len(info->attrs[NL80211_ATTR_IE])); 7305 nla_len(info->attrs[NL80211_ATTR_IE]));
7295} 7306}
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index c8e225947adb..74d97d33c938 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -769,13 +769,16 @@ static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev,
769static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, 769static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev,
770 struct net_device *dev, u8 *peer, 770 struct net_device *dev, u8 *peer,
771 u8 action_code, u8 dialog_token, 771 u8 action_code, u8 dialog_token,
772 u16 status_code, const u8 *buf, size_t len) 772 u16 status_code, u32 peer_capability,
773 const u8 *buf, size_t len)
773{ 774{
774 int ret; 775 int ret;
775 trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, 776 trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
776 dialog_token, status_code, buf, len); 777 dialog_token, status_code, peer_capability,
778 buf, len);
777 ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, 779 ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
778 dialog_token, status_code, buf, len); 780 dialog_token, status_code, peer_capability,
781 buf, len);
779 trace_rdev_return_int(&rdev->wiphy, ret); 782 trace_rdev_return_int(&rdev->wiphy, ret);
780 return ret; 783 return ret;
781} 784}
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 24c257cd706b..90b82e08ae69 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
563 if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz) 563 if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz)
564 break; 564 break;
565 565
566 if (freq_range_tmp->max_bandwidth_khz)
567 break;
568
569 freq_range = freq_range_tmp; 566 freq_range = freq_range_tmp;
570 } 567 }
571 568
@@ -582,9 +579,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
582 if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz) 579 if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz)
583 break; 580 break;
584 581
585 if (freq_range_tmp->max_bandwidth_khz)
586 break;
587
588 freq_range = freq_range_tmp; 582 freq_range = freq_range_tmp;
589 } 583 }
590 584
@@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
729 max_bandwidth1 = freq_range1->max_bandwidth_khz; 723 max_bandwidth1 = freq_range1->max_bandwidth_khz;
730 max_bandwidth2 = freq_range2->max_bandwidth_khz; 724 max_bandwidth2 = freq_range2->max_bandwidth_khz;
731 725
732 /* 726 if (rule1->flags & NL80211_RRF_AUTO_BW)
733 * In case max_bandwidth1 == 0 and max_bandwith2 == 0 set 727 max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
734 * output bandwidth as 0 (auto calculation). Next we will 728 if (rule2->flags & NL80211_RRF_AUTO_BW)
735 * calculate this correctly in handle_channel function. 729 max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);
736 * In other case calculate output bandwidth here.
737 */
738 if (max_bandwidth1 || max_bandwidth2) {
739 if (!max_bandwidth1)
740 max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
741 if (!max_bandwidth2)
742 max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);
743 }
744 730
745 freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2); 731 freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2);
746 732
733 intersected_rule->flags = rule1->flags | rule2->flags;
734
735 /*
736 * In case NL80211_RRF_AUTO_BW requested for both rules
737 * set AUTO_BW in intersected rule also. Next we will
738 * calculate BW correctly in handle_channel function.
739 * In other case remove AUTO_BW flag while we calculate
740 * maximum bandwidth correctly and auto calculation is
741 * not required.
742 */
743 if ((rule1->flags & NL80211_RRF_AUTO_BW) &&
744 (rule2->flags & NL80211_RRF_AUTO_BW))
745 intersected_rule->flags |= NL80211_RRF_AUTO_BW;
746 else
747 intersected_rule->flags &= ~NL80211_RRF_AUTO_BW;
748
747 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; 749 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
748 if (freq_range->max_bandwidth_khz > freq_diff) 750 if (freq_range->max_bandwidth_khz > freq_diff)
749 freq_range->max_bandwidth_khz = freq_diff; 751 freq_range->max_bandwidth_khz = freq_diff;
@@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
753 power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, 755 power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
754 power_rule2->max_antenna_gain); 756 power_rule2->max_antenna_gain);
755 757
756 intersected_rule->flags = rule1->flags | rule2->flags;
757
758 if (!is_valid_reg_rule(intersected_rule)) 758 if (!is_valid_reg_rule(intersected_rule))
759 return -EINVAL; 759 return -EINVAL;
760 760
@@ -938,31 +938,42 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
938EXPORT_SYMBOL(reg_initiator_name); 938EXPORT_SYMBOL(reg_initiator_name);
939 939
940#ifdef CONFIG_CFG80211_REG_DEBUG 940#ifdef CONFIG_CFG80211_REG_DEBUG
941static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, 941static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
942 struct ieee80211_channel *chan,
942 const struct ieee80211_reg_rule *reg_rule) 943 const struct ieee80211_reg_rule *reg_rule)
943{ 944{
944 const struct ieee80211_power_rule *power_rule; 945 const struct ieee80211_power_rule *power_rule;
945 const struct ieee80211_freq_range *freq_range; 946 const struct ieee80211_freq_range *freq_range;
946 char max_antenna_gain[32]; 947 char max_antenna_gain[32], bw[32];
947 948
948 power_rule = &reg_rule->power_rule; 949 power_rule = &reg_rule->power_rule;
949 freq_range = &reg_rule->freq_range; 950 freq_range = &reg_rule->freq_range;
950 951
951 if (!power_rule->max_antenna_gain) 952 if (!power_rule->max_antenna_gain)
952 snprintf(max_antenna_gain, 32, "N/A"); 953 snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A");
953 else 954 else
954 snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain); 955 snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d",
956 power_rule->max_antenna_gain);
957
958 if (reg_rule->flags & NL80211_RRF_AUTO_BW)
959 snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO",
960 freq_range->max_bandwidth_khz,
961 reg_get_max_bandwidth(regd, reg_rule));
962 else
963 snprintf(bw, sizeof(bw), "%d KHz",
964 freq_range->max_bandwidth_khz);
955 965
956 REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n", 966 REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n",
957 chan->center_freq); 967 chan->center_freq);
958 968
959 REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n", 969 REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n",
960 freq_range->start_freq_khz, freq_range->end_freq_khz, 970 freq_range->start_freq_khz, freq_range->end_freq_khz,
961 freq_range->max_bandwidth_khz, max_antenna_gain, 971 bw, max_antenna_gain,
962 power_rule->max_eirp); 972 power_rule->max_eirp);
963} 973}
964#else 974#else
965static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, 975static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
976 struct ieee80211_channel *chan,
966 const struct ieee80211_reg_rule *reg_rule) 977 const struct ieee80211_reg_rule *reg_rule)
967{ 978{
968 return; 979 return;
@@ -1022,17 +1033,16 @@ static void handle_channel(struct wiphy *wiphy,
1022 return; 1033 return;
1023 } 1034 }
1024 1035
1025 chan_reg_rule_print_dbg(chan, reg_rule); 1036 regd = reg_get_regdomain(wiphy);
1037 chan_reg_rule_print_dbg(regd, chan, reg_rule);
1026 1038
1027 power_rule = &reg_rule->power_rule; 1039 power_rule = &reg_rule->power_rule;
1028 freq_range = &reg_rule->freq_range; 1040 freq_range = &reg_rule->freq_range;
1029 1041
1030 max_bandwidth_khz = freq_range->max_bandwidth_khz; 1042 max_bandwidth_khz = freq_range->max_bandwidth_khz;
1031 /* Check if auto calculation requested */ 1043 /* Check if auto calculation requested */
1032 if (!max_bandwidth_khz) { 1044 if (reg_rule->flags & NL80211_RRF_AUTO_BW)
1033 regd = reg_get_regdomain(wiphy);
1034 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); 1045 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
1035 }
1036 1046
1037 if (max_bandwidth_khz < MHZ_TO_KHZ(40)) 1047 if (max_bandwidth_khz < MHZ_TO_KHZ(40))
1038 bw_flags = IEEE80211_CHAN_NO_HT40; 1048 bw_flags = IEEE80211_CHAN_NO_HT40;
@@ -1437,14 +1447,14 @@ static void handle_channel_custom(struct wiphy *wiphy,
1437 return; 1447 return;
1438 } 1448 }
1439 1449
1440 chan_reg_rule_print_dbg(chan, reg_rule); 1450 chan_reg_rule_print_dbg(regd, chan, reg_rule);
1441 1451
1442 power_rule = &reg_rule->power_rule; 1452 power_rule = &reg_rule->power_rule;
1443 freq_range = &reg_rule->freq_range; 1453 freq_range = &reg_rule->freq_range;
1444 1454
1445 max_bandwidth_khz = freq_range->max_bandwidth_khz; 1455 max_bandwidth_khz = freq_range->max_bandwidth_khz;
1446 /* Check if auto calculation requested */ 1456 /* Check if auto calculation requested */
1447 if (!max_bandwidth_khz) 1457 if (reg_rule->flags & NL80211_RRF_AUTO_BW)
1448 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); 1458 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
1449 1459
1450 if (max_bandwidth_khz < MHZ_TO_KHZ(40)) 1460 if (max_bandwidth_khz < MHZ_TO_KHZ(40))
@@ -2254,11 +2264,12 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
2254 freq_range = &reg_rule->freq_range; 2264 freq_range = &reg_rule->freq_range;
2255 power_rule = &reg_rule->power_rule; 2265 power_rule = &reg_rule->power_rule;
2256 2266
2257 if (!freq_range->max_bandwidth_khz) 2267 if (reg_rule->flags & NL80211_RRF_AUTO_BW)
2258 snprintf(bw, 32, "%d KHz, AUTO", 2268 snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO",
2269 freq_range->max_bandwidth_khz,
2259 reg_get_max_bandwidth(rd, reg_rule)); 2270 reg_get_max_bandwidth(rd, reg_rule));
2260 else 2271 else
2261 snprintf(bw, 32, "%d KHz", 2272 snprintf(bw, sizeof(bw), "%d KHz",
2262 freq_range->max_bandwidth_khz); 2273 freq_range->max_bandwidth_khz);
2263 2274
2264 /* 2275 /*
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 5eaeed59db07..aabccf13e07b 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1468,9 +1468,10 @@ TRACE_EVENT(rdev_sched_scan_start,
1468TRACE_EVENT(rdev_tdls_mgmt, 1468TRACE_EVENT(rdev_tdls_mgmt,
1469 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 1469 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
1470 u8 *peer, u8 action_code, u8 dialog_token, 1470 u8 *peer, u8 action_code, u8 dialog_token,
1471 u16 status_code, const u8 *buf, size_t len), 1471 u16 status_code, u32 peer_capability,
1472 const u8 *buf, size_t len),
1472 TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, 1473 TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code,
1473 buf, len), 1474 peer_capability, buf, len),
1474 TP_STRUCT__entry( 1475 TP_STRUCT__entry(
1475 WIPHY_ENTRY 1476 WIPHY_ENTRY
1476 NETDEV_ENTRY 1477 NETDEV_ENTRY
@@ -1478,6 +1479,7 @@ TRACE_EVENT(rdev_tdls_mgmt,
1478 __field(u8, action_code) 1479 __field(u8, action_code)
1479 __field(u8, dialog_token) 1480 __field(u8, dialog_token)
1480 __field(u16, status_code) 1481 __field(u16, status_code)
1482 __field(u32, peer_capability)
1481 __dynamic_array(u8, buf, len) 1483 __dynamic_array(u8, buf, len)
1482 ), 1484 ),
1483 TP_fast_assign( 1485 TP_fast_assign(
@@ -1487,13 +1489,15 @@ TRACE_EVENT(rdev_tdls_mgmt,
1487 __entry->action_code = action_code; 1489 __entry->action_code = action_code;
1488 __entry->dialog_token = dialog_token; 1490 __entry->dialog_token = dialog_token;
1489 __entry->status_code = status_code; 1491 __entry->status_code = status_code;
1492 __entry->peer_capability = peer_capability;
1490 memcpy(__get_dynamic_array(buf), buf, len); 1493 memcpy(__get_dynamic_array(buf), buf, len);
1491 ), 1494 ),
1492 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, " 1495 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, "
1493 "dialog_token: %u, status_code: %u, buf: %#.2x ", 1496 "dialog_token: %u, status_code: %u, peer_capability: %u buf: %#.2x ",
1494 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), 1497 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
1495 __entry->action_code, __entry->dialog_token, 1498 __entry->action_code, __entry->dialog_token,
1496 __entry->status_code, ((u8 *)__get_dynamic_array(buf))[0]) 1499 __entry->status_code, __entry->peer_capability,
1500 ((u8 *)__get_dynamic_array(buf))[0])
1497); 1501);
1498 1502
1499TRACE_EVENT(rdev_dump_survey, 1503TRACE_EVENT(rdev_dump_survey,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index ad03af385556..2bb685f3e8fc 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1285,7 +1285,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1285 enum cfg80211_chan_mode chmode; 1285 enum cfg80211_chan_mode chmode;
1286 int num_different_channels = 0; 1286 int num_different_channels = 0;
1287 int total = 1; 1287 int total = 1;
1288 bool radar_required = false;
1289 int i, j; 1288 int i, j;
1290 1289
1291 ASSERT_RTNL(); 1290 ASSERT_RTNL();
@@ -1293,35 +1292,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1293 if (WARN_ON(hweight32(radar_detect) > 1)) 1292 if (WARN_ON(hweight32(radar_detect) > 1))
1294 return -EINVAL; 1293 return -EINVAL;
1295 1294
1296 switch (iftype) { 1295 if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
1297 case NL80211_IFTYPE_ADHOC:
1298 case NL80211_IFTYPE_AP:
1299 case NL80211_IFTYPE_AP_VLAN:
1300 case NL80211_IFTYPE_MESH_POINT:
1301 case NL80211_IFTYPE_P2P_GO:
1302 case NL80211_IFTYPE_WDS:
1303 /* if the interface could potentially choose a DFS channel,
1304 * then mark DFS as required.
1305 */
1306 if (!chan) {
1307 if (chanmode != CHAN_MODE_UNDEFINED && radar_detect)
1308 radar_required = true;
1309 break;
1310 }
1311 radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR);
1312 break;
1313 case NL80211_IFTYPE_P2P_CLIENT:
1314 case NL80211_IFTYPE_STATION:
1315 case NL80211_IFTYPE_P2P_DEVICE:
1316 case NL80211_IFTYPE_MONITOR:
1317 break;
1318 case NUM_NL80211_IFTYPES:
1319 case NL80211_IFTYPE_UNSPECIFIED:
1320 default:
1321 return -EINVAL;
1322 }
1323
1324 if (radar_required && !radar_detect)
1325 return -EINVAL; 1296 return -EINVAL;
1326 1297
1327 /* Always allow software iftypes */ 1298 /* Always allow software iftypes */